Fix jumping to last seen position.
This commit is contained in:
parent
1778c1ef7d
commit
53d122ed55
10 changed files with 81 additions and 89 deletions
|
@ -55,8 +55,8 @@ public class MainNavigator {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void goToConversation(@NonNull RecipientId recipientId, long threadId, int distributionType, long lastSeen, int startingPosition) {
|
public void goToConversation(@NonNull RecipientId recipientId, long threadId, int distributionType, int startingPosition) {
|
||||||
Intent intent = ConversationActivity.buildIntent(activity, recipientId, threadId, distributionType, lastSeen, startingPosition);
|
Intent intent = ConversationActivity.buildIntent(activity, recipientId, threadId, distributionType, startingPosition);
|
||||||
|
|
||||||
activity.startActivity(intent);
|
activity.startActivity(intent);
|
||||||
activity.overridePendingTransition(R.anim.slide_from_end, R.anim.fade_scale_out);
|
activity.overridePendingTransition(R.anim.slide_from_end, R.anim.fade_scale_out);
|
||||||
|
|
|
@ -281,12 +281,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||||
|
|
||||||
public static final String RECIPIENT_EXTRA = "recipient_id";
|
public static final String RECIPIENT_EXTRA = "recipient_id";
|
||||||
public static final String THREAD_ID_EXTRA = "thread_id";
|
public static final String THREAD_ID_EXTRA = "thread_id";
|
||||||
public static final String IS_ARCHIVED_EXTRA = "is_archived";
|
|
||||||
public static final String TEXT_EXTRA = "draft_text";
|
public static final String TEXT_EXTRA = "draft_text";
|
||||||
public static final String MEDIA_EXTRA = "media_list";
|
public static final String MEDIA_EXTRA = "media_list";
|
||||||
public static final String STICKER_EXTRA = "sticker_extra";
|
public static final String STICKER_EXTRA = "sticker_extra";
|
||||||
public static final String DISTRIBUTION_TYPE_EXTRA = "distribution_type";
|
public static final String DISTRIBUTION_TYPE_EXTRA = "distribution_type";
|
||||||
public static final String LAST_SEEN_EXTRA = "last_seen";
|
|
||||||
public static final String STARTING_POSITION_EXTRA = "starting_position";
|
public static final String STARTING_POSITION_EXTRA = "starting_position";
|
||||||
|
|
||||||
private static final int PICK_GALLERY = 1;
|
private static final int PICK_GALLERY = 1;
|
||||||
|
@ -342,12 +340,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||||
private LiveRecipient recipient;
|
private LiveRecipient recipient;
|
||||||
private long threadId;
|
private long threadId;
|
||||||
private int distributionType;
|
private int distributionType;
|
||||||
private boolean archived;
|
|
||||||
private boolean isSecureText;
|
private boolean isSecureText;
|
||||||
private boolean isDefaultSms = true;
|
private boolean isDefaultSms = true;
|
||||||
private boolean isMmsEnabled = true;
|
private boolean isMmsEnabled = true;
|
||||||
private boolean isSecurityInitialized = false;
|
private boolean isSecurityInitialized = false;
|
||||||
private boolean shouldDisplayMessageRequestUi = true;
|
|
||||||
|
|
||||||
private final IdentityRecordList identityRecords = new IdentityRecordList();
|
private final IdentityRecordList identityRecords = new IdentityRecordList();
|
||||||
private final DynamicTheme dynamicTheme = new DynamicDarkToolbarTheme();
|
private final DynamicTheme dynamicTheme = new DynamicDarkToolbarTheme();
|
||||||
|
@ -357,14 +353,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||||
@NonNull RecipientId recipientId,
|
@NonNull RecipientId recipientId,
|
||||||
long threadId,
|
long threadId,
|
||||||
int distributionType,
|
int distributionType,
|
||||||
long lastSeen,
|
|
||||||
int startingPosition)
|
int startingPosition)
|
||||||
{
|
{
|
||||||
Intent intent = new Intent(context, ConversationActivity.class);
|
Intent intent = new Intent(context, ConversationActivity.class);
|
||||||
intent.putExtra(ConversationActivity.RECIPIENT_EXTRA, recipientId);
|
intent.putExtra(ConversationActivity.RECIPIENT_EXTRA, recipientId);
|
||||||
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, threadId);
|
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, threadId);
|
||||||
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, distributionType);
|
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, distributionType);
|
||||||
intent.putExtra(ConversationActivity.LAST_SEEN_EXTRA, lastSeen);
|
|
||||||
intent.putExtra(ConversationActivity.STARTING_POSITION_EXTRA, startingPosition);
|
intent.putExtra(ConversationActivity.STARTING_POSITION_EXTRA, startingPosition);
|
||||||
|
|
||||||
return intent;
|
return intent;
|
||||||
|
@ -1739,7 +1733,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||||
|
|
||||||
recipient = Recipient.live(getIntent().getParcelableExtra(RECIPIENT_EXTRA));
|
recipient = Recipient.live(getIntent().getParcelableExtra(RECIPIENT_EXTRA));
|
||||||
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
|
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
|
||||||
archived = getIntent().getBooleanExtra(IS_ARCHIVED_EXTRA, false);
|
|
||||||
distributionType = getIntent().getIntExtra(DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
|
distributionType = getIntent().getIntExtra(DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
|
||||||
glideRequests = GlideApp.with(this);
|
glideRequests = GlideApp.with(this);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.AnyThread;
|
import androidx.annotation.AnyThread;
|
||||||
import androidx.annotation.LayoutRes;
|
import androidx.annotation.LayoutRes;
|
||||||
|
import androidx.annotation.MainThread;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.paging.PagedList;
|
import androidx.paging.PagedList;
|
||||||
|
@ -241,16 +242,17 @@ public class ConversationAdapter<V extends View & BindableConversationItem>
|
||||||
@Override
|
@Override
|
||||||
public void submitList(@Nullable PagedList<MessageRecord> pagedList) {
|
public void submitList(@Nullable PagedList<MessageRecord> pagedList) {
|
||||||
cleanFastRecords();
|
cleanFastRecords();
|
||||||
super.submitList(pagedList);
|
super.submitList(pagedList, this::notifyDataSetChanged);
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected @Nullable MessageRecord getItem(int position) {
|
protected @Nullable MessageRecord getItem(int position) {
|
||||||
|
position = hasHeader() ? position - 1 : position;
|
||||||
|
|
||||||
if (position < fastRecords.size()) {
|
if (position < fastRecords.size()) {
|
||||||
return fastRecords.get(position);
|
return fastRecords.get(position);
|
||||||
} else {
|
} else {
|
||||||
int correctedPosition = position - fastRecords.size() - (hasHeader() ? 1 : 0);
|
int correctedPosition = position - fastRecords.size();
|
||||||
return super.getItem(correctedPosition);
|
return super.getItem(correctedPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,31 +304,19 @@ public class ConversationAdapter<V extends View & BindableConversationItem>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a timestamp, this will return the position in the adapter of the message with the
|
* The presence of a header may throw off the position you'd like to jump to. This will return
|
||||||
* nearest received timestamp, or -1 if none is found.
|
* an adjusted message position based on adapter state.
|
||||||
*/
|
*/
|
||||||
int findLastSeenPosition(long lastSeen) {
|
@MainThread
|
||||||
if (lastSeen <= 0) {
|
int getAdapterPositionForMessagePosition(int messagePosition) {
|
||||||
return -1;
|
return hasHeader() ? messagePosition + 1 : messagePosition;
|
||||||
}
|
|
||||||
|
|
||||||
int count = getItemCount() - (hasFooter() ? 1 : 0);
|
|
||||||
|
|
||||||
for (int i = (hasHeader() ? 1 : 0); i < count; i++) {
|
|
||||||
MessageRecord messageRecord = getItem(i);
|
|
||||||
|
|
||||||
if (messageRecord == null || messageRecord.isOutgoing() || messageRecord.getDateReceived() <= lastSeen) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the received timestamp for the item at the requested adapter position. Will return 0 if
|
* Finds the received timestamp for the item at the requested adapter position. Will return 0 if
|
||||||
* the position doesn't refer to an incoming message.
|
* the position doesn't refer to an incoming message.
|
||||||
*/
|
*/
|
||||||
|
@MainThread
|
||||||
long getReceivedTimestamp(int position) {
|
long getReceivedTimestamp(int position) {
|
||||||
if (isHeaderPosition(position)) return 0;
|
if (isHeaderPosition(position)) return 0;
|
||||||
if (isFooterPosition(position)) return 0;
|
if (isFooterPosition(position)) return 0;
|
||||||
|
@ -385,8 +375,9 @@ public class ConversationAdapter<V extends View & BindableConversationItem>
|
||||||
* Adds a record to a memory cache to allow it to be rendered immediately, as opposed to waiting
|
* Adds a record to a memory cache to allow it to be rendered immediately, as opposed to waiting
|
||||||
* for a database change.
|
* for a database change.
|
||||||
*/
|
*/
|
||||||
|
@MainThread
|
||||||
void addFastRecord(MessageRecord record) {
|
void addFastRecord(MessageRecord record) {
|
||||||
fastRecords.add(record);
|
fastRecords.add(0, record);
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,6 +417,7 @@ public class ConversationAdapter<V extends View & BindableConversationItem>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@MainThread
|
||||||
private void cleanFastRecords() {
|
private void cleanFastRecords() {
|
||||||
synchronized (releasedFastRecords) {
|
synchronized (releasedFastRecords) {
|
||||||
Iterator<MessageRecord> recordIterator = fastRecords.iterator();
|
Iterator<MessageRecord> recordIterator = fastRecords.iterator();
|
||||||
|
|
|
@ -5,18 +5,21 @@ package org.thoughtcrime.securesms.conversation;
|
||||||
*/
|
*/
|
||||||
final class ConversationData {
|
final class ConversationData {
|
||||||
private final long lastSeen;
|
private final long lastSeen;
|
||||||
|
private final int lastSeenPosition;
|
||||||
private final boolean hasSent;
|
private final boolean hasSent;
|
||||||
private final boolean isMessageRequestAccepted;
|
private final boolean isMessageRequestAccepted;
|
||||||
private final boolean hasPreMessageRequestMessages;
|
private final boolean hasPreMessageRequestMessages;
|
||||||
private final int jumpToPosition;
|
private final int jumpToPosition;
|
||||||
|
|
||||||
ConversationData(long lastSeen,
|
ConversationData(long lastSeen,
|
||||||
|
int lastSeenPosition,
|
||||||
boolean hasSent,
|
boolean hasSent,
|
||||||
boolean isMessageRequestAccepted,
|
boolean isMessageRequestAccepted,
|
||||||
boolean hasPreMessageRequestMessages,
|
boolean hasPreMessageRequestMessages,
|
||||||
int jumpToPosition)
|
int jumpToPosition)
|
||||||
{
|
{
|
||||||
this.lastSeen = lastSeen;
|
this.lastSeen = lastSeen;
|
||||||
|
this.lastSeenPosition = lastSeenPosition;
|
||||||
this.hasSent = hasSent;
|
this.hasSent = hasSent;
|
||||||
this.isMessageRequestAccepted = isMessageRequestAccepted;
|
this.isMessageRequestAccepted = isMessageRequestAccepted;
|
||||||
this.hasPreMessageRequestMessages = hasPreMessageRequestMessages;
|
this.hasPreMessageRequestMessages = hasPreMessageRequestMessages;
|
||||||
|
@ -27,6 +30,10 @@ final class ConversationData {
|
||||||
return lastSeen;
|
return lastSeen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getLastSeenPosition() {
|
||||||
|
return lastSeenPosition;
|
||||||
|
}
|
||||||
|
|
||||||
boolean hasSent() {
|
boolean hasSent() {
|
||||||
return hasSent;
|
return hasSent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,7 +292,7 @@ public class ConversationFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void moveToLastSeen() {
|
public void moveToLastSeen() {
|
||||||
if (conversationViewModel.getLastSeen() <= 0) {
|
if (conversationViewModel.getLastSeenPosition() <= 0) {
|
||||||
Log.i(TAG, "No need to move to last seen.");
|
Log.i(TAG, "No need to move to last seen.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -302,7 +302,7 @@ public class ConversationFragment extends Fragment {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int position = getListAdapter().findLastSeenPosition(conversationViewModel.getLastSeen());
|
int position = getListAdapter().getAdapterPositionForMessagePosition(conversationViewModel.getLastSeenPosition());
|
||||||
scrollToLastSeenPosition(position);
|
scrollToLastSeenPosition(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,14 +391,13 @@ public class ConversationFragment extends Fragment {
|
||||||
private void initializeResources() {
|
private void initializeResources() {
|
||||||
long oldThreadId = threadId;
|
long oldThreadId = threadId;
|
||||||
|
|
||||||
long lastSeen = this.getActivity().getIntent().getLongExtra(ConversationActivity.LAST_SEEN_EXTRA, -1);
|
|
||||||
int startingPosition = this.getActivity().getIntent().getIntExtra(ConversationActivity.STARTING_POSITION_EXTRA, -1);
|
int startingPosition = this.getActivity().getIntent().getIntExtra(ConversationActivity.STARTING_POSITION_EXTRA, -1);
|
||||||
|
|
||||||
this.recipient = Recipient.live(getActivity().getIntent().getParcelableExtra(ConversationActivity.RECIPIENT_EXTRA));
|
this.recipient = Recipient.live(getActivity().getIntent().getParcelableExtra(ConversationActivity.RECIPIENT_EXTRA));
|
||||||
this.threadId = this.getActivity().getIntent().getLongExtra(ConversationActivity.THREAD_ID_EXTRA, -1);
|
this.threadId = this.getActivity().getIntent().getLongExtra(ConversationActivity.THREAD_ID_EXTRA, -1);
|
||||||
this.unknownSenderView = new UnknownSenderView(getActivity(), recipient.get(), threadId);
|
this.unknownSenderView = new UnknownSenderView(getActivity(), recipient.get(), threadId);
|
||||||
|
|
||||||
conversationViewModel.onConversationDataAvailable(threadId, lastSeen, startingPosition);
|
conversationViewModel.onConversationDataAvailable(threadId, startingPosition);
|
||||||
|
|
||||||
OnScrollListener scrollListener = new ConversationScrollListener(getActivity());
|
OnScrollListener scrollListener = new ConversationScrollListener(getActivity());
|
||||||
list.addOnScrollListener(scrollListener);
|
list.addOnScrollListener(scrollListener);
|
||||||
|
@ -538,6 +537,7 @@ public class ConversationFragment extends Fragment {
|
||||||
if (this.threadId != threadId) {
|
if (this.threadId != threadId) {
|
||||||
this.threadId = threadId;
|
this.threadId = threadId;
|
||||||
messageRequestViewModel.setConversationInfo(recipient.getId(), threadId);
|
messageRequestViewModel.setConversationInfo(recipient.getId(), threadId);
|
||||||
|
conversationViewModel.onConversationDataAvailable(threadId, -1);
|
||||||
initializeListAdapter();
|
initializeListAdapter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -551,8 +551,6 @@ public class ConversationFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastSeen(long lastSeen) {
|
public void setLastSeen(long lastSeen) {
|
||||||
conversationViewModel.onLastSeenChanged(lastSeen);
|
|
||||||
|
|
||||||
if (lastSeenDecoration != null) {
|
if (lastSeenDecoration != null) {
|
||||||
list.removeItemDecoration(lastSeenDecoration);
|
list.removeItemDecoration(lastSeenDecoration);
|
||||||
}
|
}
|
||||||
|
@ -864,9 +862,7 @@ public class ConversationFragment extends Fragment {
|
||||||
adapter.setFooterView(null);
|
adapter.setFooterView(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conversationViewModel.getLastSeen() == -1) {
|
|
||||||
setLastSeen(conversation.getLastSeen());
|
setLastSeen(conversation.getLastSeen());
|
||||||
}
|
|
||||||
|
|
||||||
if (FeatureFlags.messageRequests() && !conversation.hasPreMessageRequestMessages()) {
|
if (FeatureFlags.messageRequests() && !conversation.hasPreMessageRequestMessages()) {
|
||||||
clearHeaderIfNotTyping(adapter);
|
clearHeaderIfNotTyping(adapter);
|
||||||
|
@ -880,34 +876,25 @@ public class ConversationFragment extends Fragment {
|
||||||
|
|
||||||
listener.onCursorChanged();
|
listener.onCursorChanged();
|
||||||
|
|
||||||
list.post(() -> {
|
int lastSeenPosition = adapter.getAdapterPositionForMessagePosition(conversation.getLastSeenPosition());
|
||||||
|
|
||||||
int lastSeenPosition = adapter.findLastSeenPosition(conversationViewModel.getLastSeen());
|
|
||||||
|
|
||||||
if (isTypingIndicatorShowing()) {
|
|
||||||
lastSeenPosition = Math.max(lastSeenPosition - 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conversation.shouldJumpToMessage()) {
|
if (conversation.shouldJumpToMessage()) {
|
||||||
scrollToStartingPosition(conversation.getJumpToPosition());
|
scrollToStartingPosition(conversation.getJumpToPosition());
|
||||||
} else if (conversation.isMessageRequestAccepted()) {
|
} else if (conversation.isMessageRequestAccepted()) {
|
||||||
scrollToLastSeenPosition(lastSeenPosition);
|
scrollToLastSeenPosition(lastSeenPosition);
|
||||||
|
} else if (FeatureFlags.messageRequests()) {
|
||||||
|
list.post(() -> getListLayoutManager().scrollToPosition(adapter.getItemCount() - 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastSeenPosition <= 0) {
|
private void scrollToStartingPosition(int startingPosition) {
|
||||||
setLastSeen(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void scrollToStartingPosition(final int startingPosition) {
|
|
||||||
list.post(() -> {
|
list.post(() -> {
|
||||||
list.getLayoutManager().scrollToPosition(startingPosition);
|
list.getLayoutManager().scrollToPosition(startingPosition);
|
||||||
getListAdapter().pulseHighlightItem(startingPosition);
|
getListAdapter().pulseHighlightItem(startingPosition);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scrollToLastSeenPosition(final int lastSeenPosition) {
|
private void scrollToLastSeenPosition(int lastSeenPosition) {
|
||||||
if (lastSeenPosition > 0) {
|
if (lastSeenPosition > 0) {
|
||||||
list.post(() -> getListLayoutManager().scrollToPositionWithOffset(lastSeenPosition, list.getHeight()));
|
list.post(() -> getListLayoutManager().scrollToPositionWithOffset(lastSeenPosition, list.getHeight()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,28 +24,34 @@ class ConversationRepository {
|
||||||
this.executor = SignalExecutors.BOUNDED;
|
this.executor = SignalExecutors.BOUNDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
LiveData<ConversationData> getConversationData(long threadId, long lastSeen, int jumpToPosition) {
|
LiveData<ConversationData> getConversationData(long threadId, int jumpToPosition) {
|
||||||
MutableLiveData<ConversationData> liveData = new MutableLiveData<>();
|
MutableLiveData<ConversationData> liveData = new MutableLiveData<>();
|
||||||
|
|
||||||
executor.execute(() -> {
|
executor.execute(() -> {
|
||||||
liveData.postValue(getConversationDataInternal(threadId, lastSeen, jumpToPosition));
|
liveData.postValue(getConversationDataInternal(threadId, jumpToPosition));
|
||||||
});
|
});
|
||||||
|
|
||||||
return liveData;
|
return liveData;
|
||||||
}
|
}
|
||||||
|
|
||||||
private @NonNull ConversationData getConversationDataInternal(long threadId, long lastSeen, int jumpToPosition) {
|
private @NonNull ConversationData getConversationDataInternal(long threadId, int jumpToPosition) {
|
||||||
Pair<Long, Boolean> lastSeenAndHasSent = DatabaseFactory.getThreadDatabase(context).getLastSeenAndHasSent(threadId);
|
Pair<Long, Boolean> lastSeenAndHasSent = DatabaseFactory.getThreadDatabase(context).getLastSeenAndHasSent(threadId);
|
||||||
|
|
||||||
|
long lastSeen = lastSeenAndHasSent.first();
|
||||||
boolean hasSent = lastSeenAndHasSent.second();
|
boolean hasSent = lastSeenAndHasSent.second();
|
||||||
|
int lastSeenPosition = 0;
|
||||||
if (lastSeen == -1) {
|
|
||||||
lastSeen = lastSeenAndHasSent.first();
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isMessageRequestAccepted = RecipientUtil.isMessageRequestAccepted(context, threadId);
|
boolean isMessageRequestAccepted = RecipientUtil.isMessageRequestAccepted(context, threadId);
|
||||||
boolean hasPreMessageRequestMessages = RecipientUtil.isPreMessageRequestThread(context, threadId);
|
boolean hasPreMessageRequestMessages = RecipientUtil.isPreMessageRequestThread(context, threadId);
|
||||||
|
|
||||||
return new ConversationData(lastSeen, hasSent, isMessageRequestAccepted, hasPreMessageRequestMessages, jumpToPosition);
|
if (lastSeen > 0) {
|
||||||
|
lastSeenPosition = DatabaseFactory.getMmsSmsDatabase(context).getMessagePositionForLastSeen(threadId, lastSeen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastSeenPosition <= 0) {
|
||||||
|
lastSeen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ConversationData(lastSeen, lastSeenPosition, hasSent, isMessageRequestAccepted, hasPreMessageRequestMessages, jumpToPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,6 @@ class ConversationViewModel extends ViewModel {
|
||||||
private final LiveData<ConversationData> conversationMetadata;
|
private final LiveData<ConversationData> conversationMetadata;
|
||||||
|
|
||||||
private int jumpToPosition;
|
private int jumpToPosition;
|
||||||
private long lastSeen;
|
|
||||||
|
|
||||||
private ConversationViewModel() {
|
private ConversationViewModel() {
|
||||||
this.context = ApplicationDependencies.getApplication();
|
this.context = ApplicationDependencies.getApplication();
|
||||||
|
@ -56,7 +55,7 @@ class ConversationViewModel extends ViewModel {
|
||||||
});
|
});
|
||||||
|
|
||||||
conversationMetadata = Transformations.switchMap(threadId, thread -> {
|
conversationMetadata = Transformations.switchMap(threadId, thread -> {
|
||||||
LiveData<ConversationData> data = conversationRepository.getConversationData(thread, lastSeen, jumpToPosition);
|
LiveData<ConversationData> data = conversationRepository.getConversationData(thread, jumpToPosition);
|
||||||
jumpToPosition = -1;
|
jumpToPosition = -1;
|
||||||
return data;
|
return data;
|
||||||
});
|
});
|
||||||
|
@ -66,17 +65,13 @@ class ConversationViewModel extends ViewModel {
|
||||||
mediaRepository.getMediaInBucket(context, Media.ALL_MEDIA_BUCKET_ID, recentMedia::postValue);
|
mediaRepository.getMediaInBucket(context, Media.ALL_MEDIA_BUCKET_ID, recentMedia::postValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onConversationDataAvailable(long threadId, long lastSeen, int startingPosition) {
|
void onConversationDataAvailable(long threadId, int startingPosition) {
|
||||||
this.lastSeen = lastSeen;
|
Log.d(TAG, "[onConversationDataAvailable] threadId: " + threadId + ", startingPosition: " + startingPosition);
|
||||||
this.jumpToPosition = startingPosition;
|
this.jumpToPosition = startingPosition;
|
||||||
|
|
||||||
this.threadId.setValue(threadId);
|
this.threadId.setValue(threadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onLastSeenChanged(long lastSeen) {
|
|
||||||
this.lastSeen = lastSeen;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull LiveData<List<Media>> getRecentMedia() {
|
@NonNull LiveData<List<Media>> getRecentMedia() {
|
||||||
return recentMedia;
|
return recentMedia;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +85,11 @@ class ConversationViewModel extends ViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
long getLastSeen() {
|
long getLastSeen() {
|
||||||
return lastSeen;
|
return conversationMetadata.getValue() != null ? conversationMetadata.getValue().getLastSeen() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getLastSeenPosition() {
|
||||||
|
return conversationMetadata.getValue() != null ? conversationMetadata.getValue().getLastSeenPosition() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class Factory extends ViewModelProvider.NewInstanceFactory {
|
static class Factory extends ViewModelProvider.NewInstanceFactory {
|
||||||
|
|
|
@ -347,7 +347,6 @@ public class ConversationListFragment extends MainFragment implements LoaderMana
|
||||||
getNavigator().goToConversation(threadRecord.getRecipient().getId(),
|
getNavigator().goToConversation(threadRecord.getRecipient().getId(),
|
||||||
threadRecord.getThreadId(),
|
threadRecord.getThreadId(),
|
||||||
threadRecord.getDistributionType(),
|
threadRecord.getDistributionType(),
|
||||||
threadRecord.getLastSeen(),
|
|
||||||
-1);
|
-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +359,6 @@ public class ConversationListFragment extends MainFragment implements LoaderMana
|
||||||
getNavigator().goToConversation(contact.getId(),
|
getNavigator().goToConversation(contact.getId(),
|
||||||
threadId,
|
threadId,
|
||||||
ThreadDatabase.DistributionTypes.DEFAULT,
|
ThreadDatabase.DistributionTypes.DEFAULT,
|
||||||
-1,
|
|
||||||
-1);
|
-1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -375,7 +373,6 @@ public class ConversationListFragment extends MainFragment implements LoaderMana
|
||||||
getNavigator().goToConversation(message.conversationRecipient.getId(),
|
getNavigator().goToConversation(message.conversationRecipient.getId(),
|
||||||
message.threadId,
|
message.threadId,
|
||||||
ThreadDatabase.DistributionTypes.DEFAULT,
|
ThreadDatabase.DistributionTypes.DEFAULT,
|
||||||
-1,
|
|
||||||
startingPosition);
|
startingPosition);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -691,8 +688,8 @@ public class ConversationListFragment extends MainFragment implements LoaderMana
|
||||||
actionMode.setTitle(String.valueOf(defaultAdapter.getBatchSelections().size()));
|
actionMode.setTitle(String.valueOf(defaultAdapter.getBatchSelections().size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleCreateConversation(long threadId, Recipient recipient, int distributionType, long lastSeen) {
|
private void handleCreateConversation(long threadId, Recipient recipient, int distributionType) {
|
||||||
getNavigator().goToConversation(recipient.getId(), threadId, distributionType, lastSeen, -1);
|
getNavigator().goToConversation(recipient.getId(), threadId, distributionType, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -726,8 +723,7 @@ public class ConversationListFragment extends MainFragment implements LoaderMana
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(ConversationListItem item) {
|
public void onItemClick(ConversationListItem item) {
|
||||||
if (actionMode == null) {
|
if (actionMode == null) {
|
||||||
handleCreateConversation(item.getThreadId(), item.getRecipient(),
|
handleCreateConversation(item.getThreadId(), item.getRecipient(), item.getDistributionType());
|
||||||
item.getDistributionType(), item.getLastSeen());
|
|
||||||
} else {
|
} else {
|
||||||
ConversationListAdapter adapter = (ConversationListAdapter)list.getAdapter();
|
ConversationListAdapter adapter = (ConversationListAdapter)list.getAdapter();
|
||||||
adapter.toggleThreadInBatchSet(item.getThreadId());
|
adapter.toggleThreadInBatchSet(item.getThreadId());
|
||||||
|
|
|
@ -125,6 +125,18 @@ public class MmsSmsDatabase extends Database {
|
||||||
return new Pair<>(id, latestQuit);
|
return new Pair<>(id, latestQuit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getMessagePositionForLastSeen(long threadId, long lastSeen) {
|
||||||
|
String[] projection = new String[] { "COUNT(*)" };
|
||||||
|
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " > " + lastSeen;
|
||||||
|
|
||||||
|
try (Cursor cursor = queryTables(projection, selection, null, null)) {
|
||||||
|
if (cursor != null && cursor.moveToNext()) {
|
||||||
|
return cursor.getInt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
public @Nullable MessageRecord getMessageFor(long timestamp, RecipientId author) {
|
public @Nullable MessageRecord getMessageFor(long timestamp, RecipientId author) {
|
||||||
MmsSmsDatabase db = DatabaseFactory.getMmsSmsDatabase(context);
|
MmsSmsDatabase db = DatabaseFactory.getMmsSmsDatabase(context);
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ public class NotificationItem {
|
||||||
public PendingIntent getPendingIntent(Context context) {
|
public PendingIntent getPendingIntent(Context context) {
|
||||||
Recipient recipient = threadRecipient != null ? threadRecipient : conversationRecipient;
|
Recipient recipient = threadRecipient != null ? threadRecipient : conversationRecipient;
|
||||||
int startingPosition = jumpToMessage ? getStartingPosition(context, threadId, messageReceivedTimestamp) : -1;
|
int startingPosition = jumpToMessage ? getStartingPosition(context, threadId, messageReceivedTimestamp) : -1;
|
||||||
Intent intent = ConversationActivity.buildIntent(context, recipient.getId(), threadId, 0, -1, startingPosition);
|
Intent intent = ConversationActivity.buildIntent(context, recipient.getId(), threadId, 0, startingPosition);
|
||||||
|
|
||||||
makeIntentUniqueToPreventMerging(intent);
|
makeIntentUniqueToPreventMerging(intent);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue