mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-26 03:40:56 +01:00
Migrate ConversationList to paging library and apply abstractions to conversation.
This commit is contained in:
committed by
Greyson Parrelli
parent
ce940235b0
commit
49f75d7036
@@ -479,7 +479,7 @@ public class ConversationAdapter<V extends View & BindableConversationItem>
|
||||
return headerView != null;
|
||||
}
|
||||
|
||||
private boolean hasFooter() {
|
||||
public boolean hasFooter() {
|
||||
return footerView != null;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ final class ConversationData {
|
||||
private final boolean isMessageRequestAccepted;
|
||||
private final boolean hasPreMessageRequestMessages;
|
||||
private final int jumpToPosition;
|
||||
private final int threadSize;
|
||||
|
||||
ConversationData(long threadId,
|
||||
long lastSeen,
|
||||
@@ -20,7 +21,8 @@ final class ConversationData {
|
||||
boolean hasSent,
|
||||
boolean isMessageRequestAccepted,
|
||||
boolean hasPreMessageRequestMessages,
|
||||
int jumpToPosition)
|
||||
int jumpToPosition,
|
||||
int threadSize)
|
||||
{
|
||||
this.threadId = threadId;
|
||||
this.lastSeen = lastSeen;
|
||||
@@ -30,6 +32,7 @@ final class ConversationData {
|
||||
this.isMessageRequestAccepted = isMessageRequestAccepted;
|
||||
this.hasPreMessageRequestMessages = hasPreMessageRequestMessages;
|
||||
this.jumpToPosition = jumpToPosition;
|
||||
this.threadSize = threadSize;
|
||||
}
|
||||
|
||||
public long getThreadId() {
|
||||
@@ -71,4 +74,8 @@ final class ConversationData {
|
||||
int getJumpToPosition() {
|
||||
return jumpToPosition;
|
||||
}
|
||||
|
||||
int getThreadSize() {
|
||||
return threadSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||
import org.thoughtcrime.securesms.util.paging.Invalidator;
|
||||
import org.thoughtcrime.securesms.util.paging.SizeFixResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -76,9 +78,9 @@ class ConversationDataSource extends PositionalDataSource<MessageRecord> {
|
||||
}
|
||||
|
||||
if (!isInvalid()) {
|
||||
SizeFixResult result = ensureMultipleOfPageSize(records, params.requestedStartPosition, params.pageSize, totalCount);
|
||||
SizeFixResult<MessageRecord> result = SizeFixResult.ensureMultipleOfPageSize(records, params.requestedStartPosition, params.pageSize, totalCount);
|
||||
|
||||
callback.onResult(result.messages, params.requestedStartPosition, result.total);
|
||||
callback.onResult(result.getItems(), params.requestedStartPosition, result.getTotal());
|
||||
}
|
||||
|
||||
Log.d(TAG, "[Initial Load] " + (System.currentTimeMillis() - start) + " ms" + (isInvalid() ? " -- invalidated" : ""));
|
||||
@@ -103,54 +105,6 @@ class ConversationDataSource extends PositionalDataSource<MessageRecord> {
|
||||
Log.d(TAG, "[Update] " + (System.currentTimeMillis() - start) + " ms" + (isInvalid() ? " -- invalidated" : ""));
|
||||
}
|
||||
|
||||
private static @NonNull SizeFixResult ensureMultipleOfPageSize(@NonNull List<MessageRecord> records,
|
||||
int startPosition,
|
||||
int pageSize,
|
||||
int total)
|
||||
{
|
||||
if (records.size() + startPosition == total || (records.size() != 0 && records.size() % pageSize == 0)) {
|
||||
return new SizeFixResult(records, total);
|
||||
}
|
||||
|
||||
if (records.size() < pageSize) {
|
||||
Log.w(TAG, "Hit a miscalculation where we don't have the full dataset, but it's smaller than a page size. records: " + records.size() + ", startPosition: " + startPosition + ", pageSize: " + pageSize + ", total: " + total);
|
||||
return new SizeFixResult(records, records.size() + startPosition);
|
||||
}
|
||||
|
||||
Log.w(TAG, "Hit a miscalculation where our data size isn't a multiple of the page size. records: " + records.size() + ", startPosition: " + startPosition + ", pageSize: " + pageSize + ", total: " + total);
|
||||
int overflow = records.size() % pageSize;
|
||||
|
||||
return new SizeFixResult(records.subList(0, records.size() - overflow), total);
|
||||
}
|
||||
|
||||
private static class SizeFixResult {
|
||||
final List<MessageRecord> messages;
|
||||
final int total;
|
||||
|
||||
private SizeFixResult(@NonNull List<MessageRecord> messages, int total) {
|
||||
this.messages = messages;
|
||||
this.total = total;
|
||||
}
|
||||
}
|
||||
|
||||
interface DataUpdatedCallback {
|
||||
void onDataUpdated();
|
||||
}
|
||||
|
||||
static class Invalidator {
|
||||
private Runnable callback;
|
||||
|
||||
synchronized void invalidate() {
|
||||
if (callback != null) {
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void observe(@NonNull Runnable callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
}
|
||||
|
||||
static class Factory extends DataSource.Factory<Integer, MessageRecord> {
|
||||
|
||||
private final Context context;
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Rect;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
@@ -113,6 +112,7 @@ import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.HtmlUtil;
|
||||
import org.thoughtcrime.securesms.util.RemoteDeleteUtil;
|
||||
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
|
||||
import org.thoughtcrime.securesms.util.SnapToTopDataObserver;
|
||||
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
@@ -163,8 +163,7 @@ public class ConversationFragment extends Fragment {
|
||||
private ConversationBannerView emptyConversationBanner;
|
||||
private MessageRequestViewModel messageRequestViewModel;
|
||||
private ConversationViewModel conversationViewModel;
|
||||
|
||||
private Deferred deferred = new Deferred();
|
||||
private SnapToTopDataObserver snapToTopDataObserver;
|
||||
|
||||
public static void prepare(@NonNull Context context) {
|
||||
FrameLayout parent = new FrameLayout(context);
|
||||
@@ -198,6 +197,8 @@ public class ConversationFragment extends Fragment {
|
||||
list.setLayoutManager(layoutManager);
|
||||
list.setItemAnimator(null);
|
||||
|
||||
snapToTopDataObserver = new ConversationSnapToTopDataObserver(list, new ConversationScrollRequestValidator());
|
||||
|
||||
if (FeatureFlags.messageRequests()) {
|
||||
conversationBanner = (ConversationBannerView) inflater.inflate(R.layout.conversation_item_banner, container, false);
|
||||
}
|
||||
@@ -226,7 +227,7 @@ public class ConversationFragment extends Fragment {
|
||||
Log.i(TAG, "submitList skipped an invalid list");
|
||||
}
|
||||
});
|
||||
conversationViewModel.getConversationMetadata().observe(this, data -> deferred.defer(() -> presentConversationMetadata(data)));
|
||||
conversationViewModel.getConversationMetadata().observe(this, this::presentConversationMetadata);
|
||||
|
||||
return view;
|
||||
}
|
||||
@@ -329,7 +330,7 @@ public class ConversationFragment extends Fragment {
|
||||
}
|
||||
|
||||
int position = getListAdapter().getAdapterPositionForMessagePosition(conversationViewModel.getLastSeenPosition());
|
||||
scrollToPosition(position);
|
||||
snapToTopDataObserver.requestScrollPosition(position);
|
||||
}
|
||||
|
||||
private void initializeMessageRequestViewModel() {
|
||||
@@ -423,7 +424,7 @@ 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()));
|
||||
|
||||
deferred.setDeferred(true);
|
||||
snapToTopDataObserver.requestScrollPosition(startingPosition);
|
||||
conversationViewModel.onConversationDataAvailable(threadId, startingPosition);
|
||||
|
||||
OnScrollListener scrollListener = new ConversationScrollListener(getActivity());
|
||||
@@ -442,7 +443,7 @@ public class ConversationFragment extends Fragment {
|
||||
list.addItemDecoration(new StickyHeaderDecoration(adapter, false, false));
|
||||
ConversationAdapter.initializePool(list.getRecycledViewPool());
|
||||
|
||||
adapter.registerAdapterDataObserver(new DataObserver());
|
||||
adapter.registerAdapterDataObserver(snapToTopDataObserver);
|
||||
|
||||
setLastSeen(conversationViewModel.getLastSeen());
|
||||
|
||||
@@ -563,7 +564,7 @@ public class ConversationFragment extends Fragment {
|
||||
this.threadId = threadId;
|
||||
messageRequestViewModel.setConversationInfo(recipient.getId(), threadId);
|
||||
|
||||
deferred.setDeferred(true);
|
||||
snapToTopDataObserver.requestScrollPosition(0);
|
||||
conversationViewModel.onConversationDataAvailable(threadId, -1);
|
||||
initializeListAdapter();
|
||||
}
|
||||
@@ -883,48 +884,52 @@ public class ConversationFragment extends Fragment {
|
||||
return;
|
||||
}
|
||||
|
||||
if (FeatureFlags.messageRequests()) {
|
||||
adapter.setFooterView(conversationBanner);
|
||||
} else {
|
||||
adapter.setFooterView(null);
|
||||
}
|
||||
|
||||
setLastSeen(conversation.getLastSeen());
|
||||
|
||||
if (FeatureFlags.messageRequests() && !conversation.hasPreMessageRequestMessages()) {
|
||||
clearHeaderIfNotTyping(adapter);
|
||||
} else {
|
||||
if (!conversation.hasSent() && !recipient.get().isSystemContact() && !recipient.get().isGroup() && recipient.get().getRegistered() == RecipientDatabase.RegisteredState.REGISTERED) {
|
||||
adapter.setHeaderView(unknownSenderView);
|
||||
Runnable afterScroll = () -> {
|
||||
if (FeatureFlags.messageRequests()) {
|
||||
adapter.setFooterView(conversationBanner);
|
||||
if (!conversation.isMessageRequestAccepted()) {
|
||||
snapToTopDataObserver.requestScrollPosition(adapter.getItemCount() - 1);
|
||||
}
|
||||
} else {
|
||||
clearHeaderIfNotTyping(adapter);
|
||||
adapter.setFooterView(null);
|
||||
}
|
||||
}
|
||||
|
||||
listener.onCursorChanged();
|
||||
setLastSeen(conversation.getLastSeen());
|
||||
|
||||
if (FeatureFlags.messageRequests() && !conversation.hasPreMessageRequestMessages()) {
|
||||
clearHeaderIfNotTyping(adapter);
|
||||
} else {
|
||||
if (!conversation.hasSent() && !recipient.get().isSystemContact() && !recipient.get().isGroup() && recipient.get().getRegistered() == RecipientDatabase.RegisteredState.REGISTERED) {
|
||||
adapter.setHeaderView(unknownSenderView);
|
||||
} else {
|
||||
clearHeaderIfNotTyping(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
listener.onCursorChanged();
|
||||
};
|
||||
|
||||
int lastSeenPosition = adapter.getAdapterPositionForMessagePosition(conversation.getLastSeenPosition());
|
||||
int lastScrolledPosition = adapter.getAdapterPositionForMessagePosition(conversation.getLastScrolledPosition());
|
||||
|
||||
if (conversation.shouldJumpToMessage()) {
|
||||
scrollToStartingPosition(conversation.getJumpToPosition());
|
||||
if (conversation.getThreadSize() == 0) {
|
||||
afterScroll.run();
|
||||
} else if (conversation.shouldJumpToMessage()) {
|
||||
snapToTopDataObserver.buildScrollPosition(conversation.getJumpToPosition())
|
||||
.withOnScrollRequestComplete(() -> {
|
||||
afterScroll.run();
|
||||
getListAdapter().pulseHighlightItem(conversation.getJumpToPosition());
|
||||
})
|
||||
.submit();
|
||||
} else if (conversation.isMessageRequestAccepted()) {
|
||||
scrollToPosition(conversation.shouldScrollToLastSeen() ? lastSeenPosition : lastScrolledPosition);
|
||||
snapToTopDataObserver.buildScrollPosition(conversation.shouldScrollToLastSeen() ? lastSeenPosition : lastScrolledPosition)
|
||||
.withOnPerformScroll((layoutManager, position) -> layoutManager.scrollToPositionWithOffset(position, list.getHeight()))
|
||||
.withOnScrollRequestComplete(afterScroll)
|
||||
.submit();
|
||||
} else if (FeatureFlags.messageRequests()) {
|
||||
list.post(() -> getListLayoutManager().scrollToPosition(adapter.getItemCount() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
private void scrollToStartingPosition(int startingPosition) {
|
||||
list.post(() -> {
|
||||
list.getLayoutManager().scrollToPosition(startingPosition);
|
||||
getListAdapter().pulseHighlightItem(startingPosition);
|
||||
});
|
||||
}
|
||||
|
||||
private void scrollToPosition(int position) {
|
||||
if (position > 0) {
|
||||
list.post(() -> getListLayoutManager().scrollToPositionWithOffset(position, list.getHeight()));
|
||||
snapToTopDataObserver.buildScrollPosition(adapter.getItemCount() - 1)
|
||||
.withOnScrollRequestComplete(afterScroll)
|
||||
.submit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -959,22 +964,16 @@ public class ConversationFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void moveToMessagePosition(int position, @Nullable Runnable onMessageNotFound) {
|
||||
int itemCount = getListAdapter() != null ? getListAdapter().getItemCount() : 0;
|
||||
|
||||
if (position >= 0 && position < itemCount) {
|
||||
if (getListAdapter().getItem(position) == null) {
|
||||
conversationViewModel.onConversationDataAvailable(threadId, position);
|
||||
deferred.setDeferred(true);
|
||||
deferred.defer(() -> moveToMessagePosition(position, onMessageNotFound));
|
||||
} else {
|
||||
scrollToStartingPosition(position);
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "[moveToMessagePosition] Tried to navigate to message, but it wasn't found.");
|
||||
if (onMessageNotFound != null) {
|
||||
onMessageNotFound.run();
|
||||
}
|
||||
}
|
||||
conversationViewModel.onConversationDataAvailable(threadId, position);
|
||||
snapToTopDataObserver.buildScrollPosition(position)
|
||||
.withOnScrollRequestComplete(() -> getListAdapter().pulseHighlightItem(position))
|
||||
.withOnInvalidPosition(() -> {
|
||||
if (onMessageNotFound != null) {
|
||||
onMessageNotFound.run();
|
||||
}
|
||||
Log.w(TAG, "[moveToMessagePosition] Tried to navigate to message, but it wasn't found.");
|
||||
})
|
||||
.submit();
|
||||
}
|
||||
|
||||
private void maybeShowSwipeToReplyTooltip() {
|
||||
@@ -1074,44 +1073,6 @@ public class ConversationFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
|
||||
private class DataObserver extends RecyclerView.AdapterDataObserver {
|
||||
|
||||
private final Rect rect = new Rect();
|
||||
|
||||
@Override
|
||||
public void onItemRangeInserted(int positionStart, int itemCount) {
|
||||
if (deferred.isDeferred()) {
|
||||
deferred.setDeferred(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (positionStart == 0 && itemCount == 1 && isTypingIndicatorShowing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (list.getScrollState() == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
int firstVisibleItem = getListLayoutManager().findFirstVisibleItemPosition();
|
||||
|
||||
if (firstVisibleItem == 0) {
|
||||
View view = getListLayoutManager().findViewByPosition(0);
|
||||
if (view == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
view.getDrawingRect(rect);
|
||||
list.offsetDescendantRectToMyCoords(view, rect);
|
||||
|
||||
int bottom = rect.bottom;
|
||||
list.getDrawingRect(rect);
|
||||
|
||||
if (bottom <= rect.bottom) {
|
||||
getListLayoutManager().scrollToPosition(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ConversationFragmentItemClickListener implements ItemClickListener {
|
||||
|
||||
@Override
|
||||
@@ -1319,6 +1280,52 @@ public class ConversationFragment extends Fragment {
|
||||
actionMode = ((AppCompatActivity)getActivity()).startSupportActionMode(actionModeCallback);
|
||||
}
|
||||
|
||||
private final class ConversationSnapToTopDataObserver extends SnapToTopDataObserver {
|
||||
|
||||
public ConversationSnapToTopDataObserver(@NonNull RecyclerView recyclerView,
|
||||
@Nullable ScrollRequestValidator scrollRequestValidator)
|
||||
{
|
||||
super(recyclerView, scrollRequestValidator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeInserted(int positionStart, int itemCount) {
|
||||
if (positionStart == 0 && itemCount == 1 && isTypingIndicatorShowing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.onItemRangeInserted(positionStart, itemCount);
|
||||
}
|
||||
}
|
||||
|
||||
private final class ConversationScrollRequestValidator implements SnapToTopDataObserver.ScrollRequestValidator {
|
||||
|
||||
@Override
|
||||
public boolean isPositionStillValid(int position) {
|
||||
if (getListAdapter() == null) {
|
||||
return position >= 0;
|
||||
} else {
|
||||
return position >= 0 && position < getListAdapter().getItemCount();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemAtPositionLoaded(int position) {
|
||||
if (getListAdapter() == null) {
|
||||
return false;
|
||||
} else if (getListAdapter().hasFooter() && position == getListAdapter().getItemCount() - 1) {
|
||||
return true;
|
||||
} else {
|
||||
return getListAdapter().getItem(position) != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ReactionsToolbarListener implements Toolbar.OnMenuItemClickListener {
|
||||
|
||||
private final MessageRecord messageRecord;
|
||||
@@ -1465,33 +1472,4 @@ public class ConversationFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
|
||||
private static class Deferred {
|
||||
|
||||
private Runnable deferred;
|
||||
private boolean isDeferred;
|
||||
|
||||
public void defer(@Nullable Runnable deferred) {
|
||||
this.deferred = deferred;
|
||||
executeIfNecessary();
|
||||
}
|
||||
|
||||
public void setDeferred(boolean isDeferred) {
|
||||
this.isDeferred = isDeferred;
|
||||
executeIfNecessary();
|
||||
}
|
||||
|
||||
public boolean isDeferred() {
|
||||
return isDeferred;
|
||||
}
|
||||
|
||||
private void executeIfNecessary() {
|
||||
if (deferred != null && !isDeferred) {
|
||||
Runnable local = deferred;
|
||||
|
||||
deferred = null;
|
||||
|
||||
local.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@ class ConversationRepository {
|
||||
}
|
||||
|
||||
private @NonNull ConversationData getConversationDataInternal(long threadId, int jumpToPosition) {
|
||||
ThreadDatabase.ConversationMetadata metadata = DatabaseFactory.getThreadDatabase(context).getConversationMetadata(threadId);
|
||||
ThreadDatabase.ConversationMetadata metadata = DatabaseFactory.getThreadDatabase(context).getConversationMetadata(threadId);
|
||||
int threadSize = DatabaseFactory.getMmsSmsDatabase(context).getConversationCount(threadId);
|
||||
|
||||
long lastSeen = metadata.getLastSeen();
|
||||
boolean hasSent = metadata.hasSent();
|
||||
@@ -58,6 +59,6 @@ class ConversationRepository {
|
||||
lastScrolledPosition = DatabaseFactory.getMmsSmsDatabase(context).getMessagePositionOnOrAfterTimestamp(threadId, lastScrolled);
|
||||
}
|
||||
|
||||
return new ConversationData(threadId, lastSeen, lastSeenPosition, lastScrolledPosition, hasSent, isMessageRequestAccepted, hasPreMessageRequestMessages, jumpToPosition);
|
||||
return new ConversationData(threadId, lastSeen, lastSeenPosition, lastScrolledPosition, hasSent, isMessageRequestAccepted, hasPreMessageRequestMessages, jumpToPosition, threadSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,8 @@ package org.thoughtcrime.securesms.conversation;
|
||||
import android.app.Application;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.arch.core.util.Function;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MediatorLiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.Transformations;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
@@ -15,19 +12,15 @@ import androidx.paging.DataSource;
|
||||
import androidx.paging.LivePagedListBuilder;
|
||||
import androidx.paging.PagedList;
|
||||
|
||||
import org.thoughtcrime.securesms.conversation.ConversationDataSource.Invalidator;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
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.Util;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||
import org.thoughtcrime.securesms.util.paging.Invalidator;
|
||||
import org.whispersystems.libsignal.util.Pair;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
class ConversationViewModel extends ViewModel {
|
||||
|
||||
@@ -70,10 +63,12 @@ class ConversationViewModel extends ViewModel {
|
||||
final int startPosition;
|
||||
if (data.shouldJumpToMessage()) {
|
||||
startPosition = data.getJumpToPosition();
|
||||
} else if (data.shouldScrollToLastSeen()) {
|
||||
} else if (data.isMessageRequestAccepted() && data.shouldScrollToLastSeen()) {
|
||||
startPosition = data.getLastSeenPosition();
|
||||
} else {
|
||||
} else if (data.isMessageRequestAccepted()) {
|
||||
startPosition = data.getLastScrolledPosition();
|
||||
} else {
|
||||
startPosition = data.getThreadSize();
|
||||
}
|
||||
|
||||
Log.d(TAG, "Starting at position startPosition: " + startPosition + " jumpToPosition: " + jumpToPosition + " lastSeenPosition: " + data.getLastSeenPosition() + " lastScrolledPosition: " + data.getLastScrolledPosition());
|
||||
@@ -86,7 +81,7 @@ class ConversationViewModel extends ViewModel {
|
||||
|
||||
this.messages = Transformations.map(messagesForThreadId, Pair::second);
|
||||
|
||||
LiveData<Long> distinctThread = Transformations.distinctUntilChanged(threadId);
|
||||
LiveData<Long> distinctThread = Transformations.distinctUntilChanged(Transformations.map(messagesForThreadId, Pair::first));
|
||||
|
||||
conversationMetadata = Transformations.switchMap(distinctThread, thread -> metadata);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user