Fix conversation jumping when loading at last scroll position.
parent
cf98a22269
commit
f2fe81d9b5
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue