Loading app/src/main/java/app/fedilab/android/mastodon/helper/CommentDecorationHelper.java +43 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } } } } app/src/main/java/app/fedilab/android/mastodon/ui/fragment/timeline/FragmentMastodonContext.java +9 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading app/src/main/java/app/fedilab/android/mastodon/ui/fragment/timeline/FragmentMastodonDirectMessage.java +9 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); } Loading Loading
app/src/main/java/app/fedilab/android/mastodon/helper/CommentDecorationHelper.java +43 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } } } }
app/src/main/java/app/fedilab/android/mastodon/ui/fragment/timeline/FragmentMastodonContext.java +9 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading
app/src/main/java/app/fedilab/android/mastodon/ui/fragment/timeline/FragmentMastodonDirectMessage.java +9 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); } Loading