From 8c4678aba57623b268675884d42f09009a413bdd Mon Sep 17 00:00:00 2001 From: sk Date: Mon, 5 Jun 2023 16:05:58 +0200 Subject: [PATCH] fix updated main status not being applied --- .../android/fragments/ThreadFragmentTest.java | 12 +++++-- .../android/fragments/ThreadFragment.java | 32 ++++++++++++------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/mastodon/src/androidTest/java/org/joinmastodon/android/fragments/ThreadFragmentTest.java b/mastodon/src/androidTest/java/org/joinmastodon/android/fragments/ThreadFragmentTest.java index 4e17aceb4..38a2a489c 100644 --- a/mastodon/src/androidTest/java/org/joinmastodon/android/fragments/ThreadFragmentTest.java +++ b/mastodon/src/androidTest/java/org/joinmastodon/android/fragments/ThreadFragmentTest.java @@ -53,24 +53,30 @@ public class ThreadFragmentTest { } @Test - public void updateMainStatus() { + public void maybeApplyMainStatus() { ThreadFragment fragment = new ThreadFragment(); + fragment.contextInitiallyRendered = true; fragment.mainStatus = Status.ofFake("123456", "original text", Instant.EPOCH); Status update1 = Status.ofFake("123456", "updated text", Instant.EPOCH); update1.editedAt = Instant.ofEpochSecond(1); fragment.updatedStatus = update1; - StatusUpdatedEvent event1 = (StatusUpdatedEvent) fragment.updateMainStatus(); + StatusUpdatedEvent event1 = (StatusUpdatedEvent) fragment.maybeApplyMainStatus(); assertEquals("fired update event", update1, event1.status); assertEquals("updated main status", update1, fragment.mainStatus); Status update2 = Status.ofFake("123456", "updated text", Instant.EPOCH); update2.favouritesCount = 123; fragment.updatedStatus = update2; - StatusCountersUpdatedEvent event2 = (StatusCountersUpdatedEvent) fragment.updateMainStatus(); + StatusCountersUpdatedEvent event2 = (StatusCountersUpdatedEvent) fragment.maybeApplyMainStatus(); assertEquals("only fired counter update event", update2.id, event2.id); assertEquals("updated counter is correct", 123, event2.favorites); assertEquals("updated main status", update2, fragment.mainStatus); + + Status update3 = Status.ofFake("123456", "whatever", Instant.EPOCH); + fragment.contextInitiallyRendered = false; + fragment.updatedStatus = update3; + assertNull("no update when context hasn't been rendered", fragment.maybeApplyMainStatus()); } @Test diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java index 9eeee22b8..15ebb3de0 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java @@ -49,7 +49,7 @@ import me.grishka.appkit.utils.V; public class ThreadFragment extends StatusListFragment implements ProvidesAssistContent { protected Status mainStatus, updatedStatus; private final HashMap ancestryMap = new HashMap<>(); - private boolean initialAnimationFinished; + protected boolean contextInitiallyRendered; @Override public void onCreate(Bundle savedInstanceState){ @@ -111,7 +111,7 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist @Override protected void doLoadData(int offset, int count){ - refreshMainStatus(); + loadMainStatus(); currentRequest=new GetStatusContext(mainStatus.id) .setCallback(new SimpleCallback<>(this){ @Override @@ -155,21 +155,28 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist adapter.notifyDataSetChanged(); } list.scrollToPosition(displayItems.size()-count); + + // no animation is going to happen, so proceeding to apply right now + if (data.size() == 1) { + contextInitiallyRendered = true; + // for the case that the main status has already finished loading + maybeApplyMainStatus(); + } } }) .exec(accountID); } - private void refreshMainStatus() { + private void loadMainStatus() { new GetStatusByID(mainStatus.id) .setCallback(new Callback<>() { @Override public void onSuccess(Status status) { if (getContext() == null || status == null) return; updatedStatus = status; - // only update main status if the initial animation is already finished. - // otherwise, the animator will call it in onAnimationFinished - if (initialAnimationFinished || data.size() == 1) updateMainStatus(); + // for the case that the context has already loaded (and the animation has + // already finished), falling back to applying it ourselves: + maybeApplyMainStatus(); } @Override @@ -177,7 +184,9 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist }).exec(accountID); } - protected Object updateMainStatus() { + protected Object maybeApplyMainStatus() { + if (updatedStatus == null || !contextInitiallyRendered) return null; + // returning fired event object to facilitate testing Object event; if (updatedStatus.editedAt != null && @@ -288,15 +297,14 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist showContent(); if(!loaded) footerProgress.setVisibility(View.VISIBLE); + list.setItemAnimator(new BetterItemAnimator() { @Override public void onAnimationFinished(@NonNull RecyclerView.ViewHolder viewHolder) { super.onAnimationFinished(viewHolder); - // in case someone else is about to call updateMainStatus faster... - initialAnimationFinished = true; - // ...if not (someone did fetch it but the animation wasn't finished yet), - // call it now - if (updatedStatus != null) updateMainStatus(); + contextInitiallyRendered = true; + // for the case that both requests are already done (and thus won't apply it) + maybeApplyMainStatus(); } }); }