Fix message jump-to-position.
This commit is contained in:
parent
bf40a07bb9
commit
e13f3254ad
3 changed files with 23 additions and 49 deletions
|
@ -30,16 +30,13 @@ class ConversationDataSource extends PositionalDataSource<MessageRecord> {
|
|||
|
||||
private final Context context;
|
||||
private final long threadId;
|
||||
private final DataUpdatedCallback dataUpdateCallback;
|
||||
|
||||
private ConversationDataSource(@NonNull Context context,
|
||||
long threadId,
|
||||
@NonNull Invalidator invalidator,
|
||||
@NonNull DataUpdatedCallback dataUpdateCallback)
|
||||
@NonNull Invalidator invalidator)
|
||||
{
|
||||
this.context = context;
|
||||
this.threadId = threadId;
|
||||
this.dataUpdateCallback = dataUpdateCallback;
|
||||
|
||||
ContentObserver contentObserver = new ContentObserver(null) {
|
||||
@Override
|
||||
|
@ -82,7 +79,6 @@ class ConversationDataSource extends PositionalDataSource<MessageRecord> {
|
|||
SizeFixResult result = ensureMultipleOfPageSize(records, params.requestedStartPosition, params.pageSize, totalCount);
|
||||
|
||||
callback.onResult(result.messages, params.requestedStartPosition, result.total);
|
||||
Util.runOnMain(dataUpdateCallback::onDataUpdated);
|
||||
}
|
||||
|
||||
Log.d(TAG, "[Initial Load] " + (System.currentTimeMillis() - start) + " ms" + (isInvalid() ? " -- invalidated" : ""));
|
||||
|
@ -104,10 +100,6 @@ class ConversationDataSource extends PositionalDataSource<MessageRecord> {
|
|||
|
||||
callback.onResult(records);
|
||||
|
||||
if (!isInvalid()) {
|
||||
Util.runOnMain(dataUpdateCallback::onDataUpdated);
|
||||
}
|
||||
|
||||
Log.d(TAG, "[Update] " + (System.currentTimeMillis() - start) + " ms" + (isInvalid() ? " -- invalidated" : ""));
|
||||
}
|
||||
|
||||
|
@ -164,18 +156,16 @@ class ConversationDataSource extends PositionalDataSource<MessageRecord> {
|
|||
private final Context context;
|
||||
private final long threadId;
|
||||
private final Invalidator invalidator;
|
||||
private final DataUpdatedCallback callback;
|
||||
|
||||
Factory(Context context, long threadId, @NonNull Invalidator invalidator, @NonNull DataUpdatedCallback callback) {
|
||||
Factory(Context context, long threadId, @NonNull Invalidator invalidator) {
|
||||
this.context = context;
|
||||
this.threadId = threadId;
|
||||
this.invalidator = invalidator;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull DataSource<Integer, MessageRecord> create() {
|
||||
return new ConversationDataSource(context, threadId, invalidator, callback);
|
||||
return new ConversationDataSource(context, threadId, invalidator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -941,17 +941,15 @@ public class ConversationFragment extends Fragment {
|
|||
}
|
||||
|
||||
private void moveToMessagePosition(int position, @Nullable Runnable onMessageNotFound) {
|
||||
if (position >= 0) {
|
||||
list.scrollToPosition(position);
|
||||
int itemCount = getListAdapter() != null ? getListAdapter().getItemCount() : 0;
|
||||
|
||||
if (getListAdapter() == null || getListAdapter().getItem(position) == null) {
|
||||
Log.i(TAG, "[moveToMessagePosition] Position " + position + " not currently populated. Scheduling a jump.");
|
||||
conversationViewModel.scheduleForNextMessageUpdate(() -> {
|
||||
list.scrollToPosition(position);
|
||||
getListAdapter().pulseHighlightItem(position);
|
||||
});
|
||||
if (position >= 0 && position < itemCount) {
|
||||
if (getListAdapter().getItem(position) == null) {
|
||||
conversationViewModel.onConversationDataAvailable(threadId, position);
|
||||
deferred.setDeferred(true);
|
||||
deferred.defer(() -> moveToMessagePosition(position, onMessageNotFound));
|
||||
} else {
|
||||
getListAdapter().pulseHighlightItem(position);
|
||||
scrollToStartingPosition(position);
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "[moveToMessagePosition] Tried to navigate to message, but it wasn't found.");
|
||||
|
|
|
@ -40,7 +40,6 @@ class ConversationViewModel extends ViewModel {
|
|||
private final MutableLiveData<Long> threadId;
|
||||
private final LiveData<PagedList<MessageRecord>> messages;
|
||||
private final LiveData<ConversationData> conversationMetadata;
|
||||
private final List<Runnable> onNextMessageLoad;
|
||||
private final Invalidator invalidator;
|
||||
|
||||
private int jumpToPosition;
|
||||
|
@ -51,28 +50,31 @@ class ConversationViewModel extends ViewModel {
|
|||
this.conversationRepository = new ConversationRepository();
|
||||
this.recentMedia = new MutableLiveData<>();
|
||||
this.threadId = new MutableLiveData<>();
|
||||
this.onNextMessageLoad = new CopyOnWriteArrayList<>();
|
||||
this.invalidator = new Invalidator();
|
||||
|
||||
LiveData<ConversationData> conversationDataForRequestedThreadId = Transformations.switchMap(threadId, thread -> {
|
||||
return conversationRepository.getConversationData(thread, jumpToPosition);
|
||||
LiveData<ConversationData> metadata = Transformations.switchMap(threadId, thread -> {
|
||||
LiveData<ConversationData> conversationData = conversationRepository.getConversationData(thread, jumpToPosition);
|
||||
|
||||
jumpToPosition = -1;
|
||||
|
||||
return conversationData;
|
||||
});
|
||||
|
||||
LiveData<Pair<Long, PagedList<MessageRecord>>> messagesForThreadId = Transformations.switchMap(conversationDataForRequestedThreadId, data -> {
|
||||
DataSource.Factory<Integer, MessageRecord> factory = new ConversationDataSource.Factory(context, data.getThreadId(), invalidator, this::onMessagesUpdated);
|
||||
LiveData<Pair<Long, PagedList<MessageRecord>>> messagesForThreadId = Transformations.switchMap(metadata, data -> {
|
||||
DataSource.Factory<Integer, MessageRecord> factory = new ConversationDataSource.Factory(context, data.getThreadId(), invalidator);
|
||||
PagedList.Config config = new PagedList.Config.Builder()
|
||||
.setPageSize(25)
|
||||
.setInitialLoadSizeHint(25)
|
||||
.build();
|
||||
|
||||
final int startPosition;
|
||||
if (jumpToPosition > 0) {
|
||||
startPosition = jumpToPosition;
|
||||
if (data.shouldJumpToMessage()) {
|
||||
startPosition = data.getJumpToPosition();
|
||||
} else {
|
||||
startPosition = data.getLastSeenPosition();
|
||||
}
|
||||
|
||||
Log.d(TAG, "Starting at position " + startPosition + " :: " + jumpToPosition + " :: " + data.getLastSeenPosition());
|
||||
Log.d(TAG, "Starting at position " + startPosition + " :: " + data.getJumpToPosition() + " :: " + data.getLastSeenPosition());
|
||||
|
||||
return Transformations.map(new LivePagedListBuilder<>(factory, config).setFetchExecutor(ConversationDataSource.EXECUTOR)
|
||||
.setInitialLoadKey(Math.max(startPosition, 0))
|
||||
|
@ -82,13 +84,9 @@ class ConversationViewModel extends ViewModel {
|
|||
|
||||
this.messages = Transformations.map(messagesForThreadId, Pair::second);
|
||||
|
||||
LiveData<Long> threadIdForLoadedMessages = Transformations.distinctUntilChanged(Transformations.map(messagesForThreadId, Pair::first));
|
||||
LiveData<Long> distinctThread = Transformations.distinctUntilChanged(threadId);
|
||||
|
||||
conversationMetadata = Transformations.switchMap(threadIdForLoadedMessages, m -> {
|
||||
LiveData<ConversationData> data = conversationRepository.getConversationData(m, jumpToPosition);
|
||||
jumpToPosition = -1;
|
||||
return data;
|
||||
});
|
||||
conversationMetadata = Transformations.switchMap(distinctThread, thread -> metadata);
|
||||
}
|
||||
|
||||
void onAttachmentKeyboardOpen() {
|
||||
|
@ -122,24 +120,12 @@ class ConversationViewModel extends ViewModel {
|
|||
return conversationMetadata.getValue() != null ? conversationMetadata.getValue().getLastSeenPosition() : 0;
|
||||
}
|
||||
|
||||
void scheduleForNextMessageUpdate(@NonNull Runnable runnable) {
|
||||
onNextMessageLoad.add(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
super.onCleared();
|
||||
invalidator.invalidate();
|
||||
}
|
||||
|
||||
private void onMessagesUpdated() {
|
||||
for (Runnable runnable : onNextMessageLoad) {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
onNextMessageLoad.clear();
|
||||
}
|
||||
|
||||
static class Factory extends ViewModelProvider.NewInstanceFactory {
|
||||
@Override
|
||||
public @NonNull<T extends ViewModel> T create(@NonNull Class<T> modelClass) {
|
||||
|
|
Loading…
Add table
Reference in a new issue