Commit 94b042d7 authored by Thomas's avatar Thomas
Browse files

- Fix #1348 thread reply ordering in conversation view

parent fd832bde
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -17,7 +17,10 @@ package app.fedilab.android.mastodon.helper;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import app.fedilab.android.mastodon.client.entities.api.Status;

@@ -68,4 +71,44 @@ public class CommentDecorationHelper {
        }
    }

    /**
     * Sort descendants into tree order (depth-first) so replies appear right after their parent
     *
     * @param descendants  List of descendants in chronological order from API
     * @param allParentIds List of all status IDs that can be parents (ancestors + focused)
     * @return List of descendants sorted in tree order
     */
    public static List<Status> sortDescendantsAsTree(List<Status> descendants, List<String> allParentIds) {
        if (descendants == null || descendants.isEmpty()) {
            return new ArrayList<>();
        }
        Map<String, List<Status>> repliesMap = new HashMap<>();
        for (Status status : descendants) {
            String replyToId = status.in_reply_to_id;
            if (replyToId != null) {
                if (!repliesMap.containsKey(replyToId)) {
                    repliesMap.put(replyToId, new ArrayList<>());
                }
                repliesMap.get(replyToId).add(status);
            }
        }
        List<Status> sorted = new ArrayList<>();
        for (String parentId : allParentIds) {
            addRepliesRecursively(sorted, parentId, repliesMap);
        }
        return sorted;
    }

    private static void addRepliesRecursively(List<Status> sorted, String parentId, Map<String, List<Status>> repliesMap) {
        List<Status> directReplies = repliesMap.get(parentId);
        if (directReplies != null) {
            for (Status reply : directReplies) {
                if (!sorted.contains(reply)) {
                    sorted.add(reply);
                    addRepliesRecursively(sorted, reply.id, repliesMap);
                }
            }
        }
    }

}
+9 −2
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import app.fedilab.android.mastodon.client.entities.api.Context;
import app.fedilab.android.mastodon.client.entities.api.Status;
import app.fedilab.android.mastodon.client.entities.app.CachedBundle;
import app.fedilab.android.mastodon.client.entities.app.Timeline;
import app.fedilab.android.mastodon.helper.CommentDecorationHelper;
import app.fedilab.android.mastodon.helper.DividerDecoration;
import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.mastodon.ui.drawer.StatusAdapter;
@@ -290,8 +291,14 @@ public class FragmentMastodonContext extends Fragment {
        //Build the array of statuses
        statuses.addAll(0, context.ancestors);
        statusAdapter.notifyItemRangeInserted(0, statusPosition);
        statuses.addAll(statusPosition + 1, context.descendants);
        statusAdapter.notifyItemRangeInserted(statusPosition + 1, context.descendants.size());
        List<String> allParentIds = new ArrayList<>();
        for (Status ancestor : context.ancestors) {
            allParentIds.add(ancestor.id);
        }
        allParentIds.add(focusedStatus.id);
        List<Status> sortedDescendants = CommentDecorationHelper.sortDescendantsAsTree(context.descendants, allParentIds);
        statuses.addAll(statusPosition + 1, sortedDescendants);
        statusAdapter.notifyItemRangeInserted(statusPosition + 1, sortedDescendants.size());
        if (binding.recyclerView.getItemDecorationCount() > 0) {
            for (int i = 0; i < binding.recyclerView.getItemDecorationCount(); i++) {
                binding.recyclerView.removeItemDecorationAt(i);
+9 −2
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ import app.fedilab.android.mastodon.client.entities.api.Status;
import app.fedilab.android.mastodon.client.entities.app.CachedBundle;
import app.fedilab.android.mastodon.client.entities.app.StatusDraft;
import app.fedilab.android.mastodon.exception.DBException;
import app.fedilab.android.mastodon.helper.CommentDecorationHelper;
import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.mastodon.helper.ThemeHelper;
import app.fedilab.android.mastodon.imageeditor.EditImageActivity;
@@ -945,8 +946,14 @@ public class FragmentMastodonDirectMessage extends Fragment {
        //Build the array of statuses
        statuses.addAll(0, context.ancestors);
        statusDirectMessageAdapter.notifyItemRangeInserted(0, statusPosition);
        statuses.addAll(statusPosition + 1, context.descendants);
        statusDirectMessageAdapter.notifyItemRangeInserted(statusPosition + 1, context.descendants.size());
        List<String> allParentIds = new ArrayList<>();
        for (Status ancestor : context.ancestors) {
            allParentIds.add(ancestor.id);
        }
        allParentIds.add(focusedStatus.id);
        List<Status> sortedDescendants = CommentDecorationHelper.sortDescendantsAsTree(context.descendants, allParentIds);
        statuses.addAll(statusPosition + 1, sortedDescendants);
        statusDirectMessageAdapter.notifyItemRangeInserted(statusPosition + 1, sortedDescendants.size());
        binding.swipeContainer.setRefreshing(false);
        initiliazeStatus();
    }