Skip to content
This repository was archived by the owner on May 30, 2025. It is now read-only.

Commit 87c37df

Browse files
committed
insert replied directly below status
closes #558
1 parent 7fb0944 commit 87c37df

File tree

2 files changed

+69
-14
lines changed

2 files changed

+69
-14
lines changed

mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,10 +337,60 @@ public void onAnimationFinished(@NonNull RecyclerView.ViewHolder viewHolder) {
337337
}
338338

339339
protected void onStatusCreated(StatusCreatedEvent ev){
340-
if(ev.status.inReplyToId!=null && getStatusByID(ev.status.inReplyToId)!=null){
341-
data.add(ev.status);
342-
onAppendItems(Collections.singletonList(ev.status));
340+
if (ev.status.inReplyToId == null) return;
341+
Status repliedToStatus = getStatusByID(ev.status.inReplyToId);
342+
if (repliedToStatus == null) return;
343+
NeighborAncestryInfo ancestry = ancestryMap.get(repliedToStatus.id);
344+
345+
int nextDisplayItemsIndex = -1, indexOfPreviousDisplayItem = -1;
346+
347+
for (int i = 0; i < displayItems.size(); i++) {
348+
StatusDisplayItem item = displayItems.get(i);
349+
if (repliedToStatus.id.equals(item.parentID)) {
350+
// saving the replied-to status' display items index to eventually reach the last one
351+
indexOfPreviousDisplayItem = i;
352+
item.hasDescendantNeighbor = true;
353+
} else if (indexOfPreviousDisplayItem >= 0 && nextDisplayItemsIndex == -1) {
354+
// previous display item was the replied-to status' display items
355+
nextDisplayItemsIndex = i;
356+
// nothing left to do if there's no other reply to that status
357+
if (ancestry.descendantNeighbor == null) break;
358+
}
359+
if (ancestry.descendantNeighbor != null && item.parentID.equals(ancestry.descendantNeighbor.id)) {
360+
// existing reply shall no longer have the replied-to status as its neighbor
361+
item.hasAncestoringNeighbor = false;
362+
}
343363
}
364+
365+
// fall back to inserting the item at the end
366+
nextDisplayItemsIndex = nextDisplayItemsIndex >= 0 ? nextDisplayItemsIndex : displayItems.size();
367+
int nextDataIndex = data.indexOf(repliedToStatus) + 1;
368+
369+
// if replied-to status already has another reply...
370+
if (ancestry.descendantNeighbor != null) {
371+
// update the reply's ancestry to remove its ancestoring neighbor (as we did above)
372+
ancestryMap.get(ancestry.descendantNeighbor.id).ancestoringNeighbor = null;
373+
// make sure the existing reply has a reply line
374+
if (nextDataIndex < data.size() &&
375+
!(displayItems.get(nextDisplayItemsIndex) instanceof ReblogOrReplyLineStatusDisplayItem)) {
376+
Status nextStatus = data.get(nextDataIndex);
377+
if (!nextStatus.account.id.equals(repliedToStatus.account.id)) {
378+
// create reply line manually since we're not building that status' items
379+
displayItems.add(nextDisplayItemsIndex, StatusDisplayItem.buildReplyLine(
380+
this, nextStatus, accountID, nextStatus, repliedToStatus.account, false
381+
));
382+
}
383+
}
384+
}
385+
386+
// update replied-to status' ancestry
387+
ancestry.descendantNeighbor = ev.status;
388+
389+
// add ancestry for newly created status before building its display items
390+
ancestryMap.put(ev.status.id, new NeighborAncestryInfo(ev.status, null, repliedToStatus));
391+
displayItems.addAll(nextDisplayItemsIndex, buildDisplayItems(ev.status));
392+
data.add(nextDataIndex, ev.status);
393+
adapter.notifyDataSetChanged();
344394
}
345395

346396
@Override

mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,21 @@ public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?>
105105
return buildItems(fragment, status, accountID, parentObject, knownAccounts, inset, addFooter, notification, false, filterContext);
106106
}
107107

108+
public static ReblogOrReplyLineStatusDisplayItem buildReplyLine(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parent, Account account, boolean threadReply) {
109+
String parentID = parent.getID();
110+
String text = threadReply ? fragment.getString(R.string.sk_show_thread)
111+
: account == null ? fragment.getString(R.string.sk_in_reply)
112+
: GlobalUserPreferences.compactReblogReplyLine && status.reblog != null ? account.displayName
113+
: fragment.getString(R.string.in_reply_to, account.displayName);
114+
String fullText = threadReply ? fragment.getString(R.string.sk_show_thread)
115+
: account == null ? fragment.getString(R.string.sk_in_reply)
116+
: fragment.getString(R.string.in_reply_to, account.displayName);
117+
return new ReblogOrReplyLineStatusDisplayItem(
118+
parentID, fragment, text, account == null ? List.of() : account.emojis,
119+
R.drawable.ic_fluent_arrow_reply_20sp_filled, null, null, fullText
120+
);
121+
}
122+
108123
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter, Notification notification, boolean disableTranslate, Filter.FilterContext filterContext){
109124
String parentID=parentObject.getID();
110125
ArrayList<StatusDisplayItem> items=new ArrayList<>();
@@ -120,17 +135,7 @@ public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?>
120135

121136
if(statusForContent.inReplyToAccountId!=null && !(threadReply && fragment instanceof ThreadFragment)){
122137
Account account = knownAccounts.get(statusForContent.inReplyToAccountId);
123-
String text = threadReply ? fragment.getString(R.string.sk_show_thread)
124-
: account == null ? fragment.getString(R.string.sk_in_reply)
125-
: GlobalUserPreferences.compactReblogReplyLine && status.reblog != null ? account.displayName
126-
: fragment.getString(R.string.in_reply_to, account.displayName);
127-
String fullText = threadReply ? fragment.getString(R.string.sk_show_thread)
128-
: account == null ? fragment.getString(R.string.sk_in_reply)
129-
: fragment.getString(R.string.in_reply_to, account.displayName);
130-
replyLine = new ReblogOrReplyLineStatusDisplayItem(
131-
parentID, fragment, text, account == null ? List.of() : account.emojis,
132-
R.drawable.ic_fluent_arrow_reply_20sp_filled, null, null, fullText
133-
);
138+
replyLine = buildReplyLine(fragment, status, accountID, parentObject, account, threadReply);
134139
}
135140

136141
if(status.reblog!=null){

0 commit comments

Comments
 (0)