Fix conversation jumping when loading at last scroll position.

master
Alex Hart 2020-06-12 17:23:40 -03:00 committed by Greyson Parrelli
parent cf98a22269
commit f2fe81d9b5
3 changed files with 37 additions and 6 deletions

View File

@ -424,7 +424,6 @@ public class ConversationFragment extends Fragment {
this.threadId = this.getActivity().getIntent().getLongExtra(ConversationActivity.THREAD_ID_EXTRA, -1);
this.unknownSenderView = new UnknownSenderView(getActivity(), recipient.get(), threadId, () -> clearHeaderIfNotTyping(getListAdapter()));
snapToTopDataObserver.requestScrollPosition(startingPosition);
conversationViewModel.onConversationDataAvailable(threadId, startingPosition);
OnScrollListener scrollListener = new ConversationScrollListener(getActivity());
@ -966,7 +965,12 @@ public class ConversationFragment extends Fragment {
private void moveToMessagePosition(int position, @Nullable Runnable onMessageNotFound) {
conversationViewModel.onConversationDataAvailable(threadId, position);
snapToTopDataObserver.buildScrollPosition(position)
.withOnScrollRequestComplete(() -> getListAdapter().pulseHighlightItem(position))
.withOnPerformScroll(((layoutManager, p) ->
list.post(() -> {
layoutManager.scrollToPosition(p);
getListAdapter().pulseHighlightItem(position);
})
))
.withOnInvalidPosition(() -> {
if (onMessageNotFound != null) {
onMessageNotFound.run();

View File

@ -17,10 +17,12 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mediasend.Media;
import org.thoughtcrime.securesms.mediasend.MediaRepository;
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
import org.thoughtcrime.securesms.util.paging.Invalidator;
import org.whispersystems.libsignal.util.Pair;
import java.util.List;
import java.util.Objects;
class ConversationViewModel extends ViewModel {
@ -81,9 +83,11 @@ class ConversationViewModel extends ViewModel {
this.messages = Transformations.map(messagesForThreadId, Pair::second);
LiveData<Long> distinctThread = Transformations.distinctUntilChanged(Transformations.map(messagesForThreadId, Pair::first));
LiveData<DistinctConversationDataByThreadId> distinctData = LiveDataUtil.combineLatest(messagesForThreadId,
metadata,
(m, data) -> new DistinctConversationDataByThreadId(data));
conversationMetadata = Transformations.switchMap(distinctThread, thread -> metadata);
conversationMetadata = Transformations.map(Transformations.distinctUntilChanged(distinctData), DistinctConversationDataByThreadId::getConversationData);
}
void onAttachmentKeyboardOpen() {
@ -130,4 +134,29 @@ class ConversationViewModel extends ViewModel {
return modelClass.cast(new ConversationViewModel());
}
}
private static class DistinctConversationDataByThreadId {
private final ConversationData conversationData;
private DistinctConversationDataByThreadId(@NonNull ConversationData conversationData) {
this.conversationData = conversationData;
}
public @NonNull ConversationData getConversationData() {
return conversationData;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DistinctConversationDataByThreadId that = (DistinctConversationDataByThreadId) o;
return Objects.equals(conversationData.getThreadId(), that.conversationData.getThreadId());
}
@Override
public int hashCode() {
return Objects.hash(conversationData.getThreadId());
}
}
}

View File

@ -77,10 +77,8 @@ public class SnapToTopDataObserver extends RecyclerView.AdapterDataObserver {
if (!scrollRequestValidator.isPositionStillValid(position)) {
onInvalidPosition.run();
} else if (scrollRequestValidator.isItemAtPositionLoaded(position)) {
recyclerView.post(() -> {
onPerformScroll.onPerformScroll(layoutManager, position);
onScrollRequestComplete.run();
});
} else {
deferred.setDeferred(true);
deferred.defer(() -> requestScrollPositionInternal(position, onPerformScroll, onScrollRequestComplete, onInvalidPosition));