Fix stale thread id when a conversation is deleted.
This commit is contained in:
parent
fba4c882cb
commit
c741e32824
3 changed files with 45 additions and 31 deletions
|
@ -109,6 +109,7 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor
|
||||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs;
|
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs;
|
||||||
import org.thoughtcrime.securesms.conversation.quotes.MessageQuotesBottomSheet;
|
import org.thoughtcrime.securesms.conversation.quotes.MessageQuotesBottomSheet;
|
||||||
import org.thoughtcrime.securesms.conversation.ui.error.EnableCallNotificationSettingsDialog;
|
import org.thoughtcrime.securesms.conversation.ui.error.EnableCallNotificationSettingsDialog;
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseObserver;
|
||||||
import org.thoughtcrime.securesms.database.MessageTable;
|
import org.thoughtcrime.securesms.database.MessageTable;
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||||
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord;
|
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord;
|
||||||
|
@ -264,6 +265,8 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||||
private @Nullable ConversationData conversationData;
|
private @Nullable ConversationData conversationData;
|
||||||
private @Nullable ChatWallpaper chatWallpaper;
|
private @Nullable ChatWallpaper chatWallpaper;
|
||||||
|
|
||||||
|
private final DatabaseObserver.Observer threadDeletedObserver = this::onThreadDelete;
|
||||||
|
|
||||||
public static void prepare(@NonNull Context context) {
|
public static void prepare(@NonNull Context context) {
|
||||||
FrameLayout parent = new FrameLayout(context);
|
FrameLayout parent = new FrameLayout(context);
|
||||||
parent.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));
|
parent.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));
|
||||||
|
@ -526,26 +529,6 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||||
updateToolbarDependentMargins();
|
updateToolbarDependentMargins();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onNewIntent() {
|
|
||||||
Log.d(TAG, "[onNewIntent]");
|
|
||||||
|
|
||||||
if (actionMode != null) {
|
|
||||||
actionMode.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
long oldThreadId = threadId;
|
|
||||||
|
|
||||||
initializeResources();
|
|
||||||
messageRequestViewModel.setConversationInfo(recipient.getId(), threadId);
|
|
||||||
|
|
||||||
int startingPosition = getStartPosition();
|
|
||||||
if (startingPosition != -1 && oldThreadId == threadId) {
|
|
||||||
list.post(() -> moveToPosition(startingPosition, () -> Log.w(TAG, "Could not scroll to requested message.")));
|
|
||||||
} else {
|
|
||||||
initializeListAdapter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void moveToLastSeen() {
|
public void moveToLastSeen() {
|
||||||
int lastSeenPosition = conversationData != null ? conversationData.getLastSeenPosition() : 0;
|
int lastSeenPosition = conversationData != null ? conversationData.getLastSeenPosition() : 0;
|
||||||
if (lastSeenPosition <= 0) {
|
if (lastSeenPosition <= 0) {
|
||||||
|
@ -697,8 +680,8 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||||
long oldThreadId = threadId;
|
long oldThreadId = threadId;
|
||||||
int startingPosition = getStartPosition();
|
int startingPosition = getStartPosition();
|
||||||
|
|
||||||
this.recipient = Recipient.live(conversationViewModel.getArgs().getRecipientId());
|
this.recipient = Recipient.live(conversationViewModel.getArgs().getRecipientId());
|
||||||
this.threadId = conversationViewModel.getArgs().getThreadId();
|
setThreadId(conversationViewModel.getArgs().getThreadId());
|
||||||
this.markReadHelper = new MarkReadHelper(ConversationId.forConversation(threadId), requireContext(), getViewLifecycleOwner());
|
this.markReadHelper = new MarkReadHelper(ConversationId.forConversation(threadId), requireContext(), getViewLifecycleOwner());
|
||||||
|
|
||||||
conversationViewModel.onConversationDataAvailable(recipient.getId(), threadId, startingPosition);
|
conversationViewModel.onConversationDataAvailable(recipient.getId(), threadId, startingPosition);
|
||||||
|
@ -718,6 +701,12 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setThreadId(long threadId) {
|
||||||
|
this.threadId = threadId;
|
||||||
|
ApplicationDependencies.getDatabaseObserver().unregisterObserver(threadDeletedObserver);
|
||||||
|
ApplicationDependencies.getDatabaseObserver().registerConversationDeleteObserver(this.threadId, threadDeletedObserver);
|
||||||
|
}
|
||||||
|
|
||||||
private void initializeListAdapter() {
|
private void initializeListAdapter() {
|
||||||
if (this.recipient != null) {
|
if (this.recipient != null) {
|
||||||
if (getListAdapter() != null && getListAdapter().isForRecipientId(this.recipient.getId())) {
|
if (getListAdapter() != null && getListAdapter().isForRecipientId(this.recipient.getId())) {
|
||||||
|
@ -945,7 +934,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||||
if (this.threadId != threadId) {
|
if (this.threadId != threadId) {
|
||||||
Log.i(TAG, "ThreadId changed from " + this.threadId + " to " + threadId + ". Recipient was " + this.recipient.getId() + " and is now " + recipient.getId());
|
Log.i(TAG, "ThreadId changed from " + this.threadId + " to " + threadId + ". Recipient was " + this.recipient.getId() + " and is now " + recipient.getId());
|
||||||
|
|
||||||
this.threadId = threadId;
|
setThreadId(threadId);
|
||||||
messageRequestViewModel.setConversationInfo(recipient.getId(), threadId);
|
messageRequestViewModel.setConversationInfo(recipient.getId(), threadId);
|
||||||
|
|
||||||
snapToTopDataObserver.requestScrollPosition(0);
|
snapToTopDataObserver.requestScrollPosition(0);
|
||||||
|
@ -1060,14 +1049,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... voids) {
|
protected Void doInBackground(Void... voids) {
|
||||||
for (MessageRecord messageRecord : messageRecords) {
|
for (MessageRecord messageRecord : messageRecords) {
|
||||||
boolean threadDeleted = SignalDatabase.messages().deleteMessage(messageRecord.getId());
|
SignalDatabase.messages().deleteMessage(messageRecord.getId());
|
||||||
|
|
||||||
if (threadDeleted) {
|
|
||||||
threadId = -1;
|
|
||||||
conversationViewModel.clearThreadId();
|
|
||||||
messageCountsViewModel.clearThreadId();
|
|
||||||
listener.setThreadId(threadId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -1085,6 +1067,13 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onThreadDelete() {
|
||||||
|
setThreadId(-1);
|
||||||
|
conversationViewModel.clearThreadId();
|
||||||
|
messageCountsViewModel.clearThreadId();
|
||||||
|
listener.setThreadId(threadId);
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isNoteToSelfDelete(Set<MessageRecord> messageRecords) {
|
private static boolean isNoteToSelfDelete(Set<MessageRecord> messageRecords) {
|
||||||
return messageRecords.stream().allMatch(messageRecord -> messageRecord.isOutgoing() && messageRecord.getRecipient().isSelf());
|
return messageRecords.stream().allMatch(messageRecord -> messageRecord.isOutgoing() && messageRecord.getRecipient().isSelf());
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ public class DatabaseObserver {
|
||||||
private static final String KEY_RECIPIENT = "Recipient";
|
private static final String KEY_RECIPIENT = "Recipient";
|
||||||
private static final String KEY_STORY_OBSERVER = "Story";
|
private static final String KEY_STORY_OBSERVER = "Story";
|
||||||
private static final String KEY_SCHEDULED_MESSAGES = "ScheduledMessages";
|
private static final String KEY_SCHEDULED_MESSAGES = "ScheduledMessages";
|
||||||
|
private static final String KEY_CONVERSATION_DELETES = "ConversationDeletes";
|
||||||
|
|
||||||
private final Application application;
|
private final Application application;
|
||||||
private final Executor executor;
|
private final Executor executor;
|
||||||
|
@ -50,6 +51,7 @@ public class DatabaseObserver {
|
||||||
private final Set<Observer> conversationListObservers;
|
private final Set<Observer> conversationListObservers;
|
||||||
private final Map<Long, Set<Observer>> conversationObservers;
|
private final Map<Long, Set<Observer>> conversationObservers;
|
||||||
private final Map<Long, Set<Observer>> verboseConversationObservers;
|
private final Map<Long, Set<Observer>> verboseConversationObservers;
|
||||||
|
private final Map<Long, Set<Observer>> conversationDeleteObservers;
|
||||||
private final Map<UUID, Set<Observer>> paymentObservers;
|
private final Map<UUID, Set<Observer>> paymentObservers;
|
||||||
private final Map<Long, Set<Observer>> scheduledMessageObservers;
|
private final Map<Long, Set<Observer>> scheduledMessageObservers;
|
||||||
private final Set<Observer> allPaymentsObservers;
|
private final Set<Observer> allPaymentsObservers;
|
||||||
|
@ -68,6 +70,7 @@ public class DatabaseObserver {
|
||||||
this.conversationListObservers = new HashSet<>();
|
this.conversationListObservers = new HashSet<>();
|
||||||
this.conversationObservers = new HashMap<>();
|
this.conversationObservers = new HashMap<>();
|
||||||
this.verboseConversationObservers = new HashMap<>();
|
this.verboseConversationObservers = new HashMap<>();
|
||||||
|
this.conversationDeleteObservers = new HashMap<>();
|
||||||
this.paymentObservers = new HashMap<>();
|
this.paymentObservers = new HashMap<>();
|
||||||
this.allPaymentsObservers = new HashSet<>();
|
this.allPaymentsObservers = new HashSet<>();
|
||||||
this.chatColorsObservers = new HashSet<>();
|
this.chatColorsObservers = new HashSet<>();
|
||||||
|
@ -99,6 +102,12 @@ public class DatabaseObserver {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void registerConversationDeleteObserver(long threadId, @NonNull Observer listener) {
|
||||||
|
executor.execute(() -> {
|
||||||
|
registerMapped(conversationDeleteObservers, threadId, listener);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void registerPaymentObserver(@NonNull UUID paymentId, @NonNull Observer listener) {
|
public void registerPaymentObserver(@NonNull UUID paymentId, @NonNull Observer listener) {
|
||||||
executor.execute(() -> {
|
executor.execute(() -> {
|
||||||
registerMapped(paymentObservers, paymentId, listener);
|
registerMapped(paymentObservers, paymentId, listener);
|
||||||
|
@ -181,6 +190,7 @@ public class DatabaseObserver {
|
||||||
notificationProfileObservers.remove(listener);
|
notificationProfileObservers.remove(listener);
|
||||||
unregisterMapped(storyObservers, listener);
|
unregisterMapped(storyObservers, listener);
|
||||||
unregisterMapped(scheduledMessageObservers, listener);
|
unregisterMapped(scheduledMessageObservers, listener);
|
||||||
|
unregisterMapped(conversationDeleteObservers, listener);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,6 +222,18 @@ public class DatabaseObserver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void notifyConversationDeleteListeners(Set<Long> threadIds) {
|
||||||
|
for (long threadId : threadIds) {
|
||||||
|
notifyConversationDeleteListeners(threadId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyConversationDeleteListeners(long threadId) {
|
||||||
|
runPostSuccessfulTransaction(KEY_CONVERSATION_DELETES + threadId, () -> {
|
||||||
|
notifyMapped(conversationDeleteObservers, threadId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void notifyConversationListListeners() {
|
public void notifyConversationListListeners() {
|
||||||
runPostSuccessfulTransaction(KEY_CONVERSATION_LIST, () -> {
|
runPostSuccessfulTransaction(KEY_CONVERSATION_LIST, () -> {
|
||||||
for (Observer listener : conversationListObservers) {
|
for (Observer listener : conversationListObservers) {
|
||||||
|
|
|
@ -43,6 +43,7 @@ import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||||
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
|
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
|
||||||
import org.thoughtcrime.securesms.database.model.serialize
|
import org.thoughtcrime.securesms.database.model.serialize
|
||||||
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||||
import org.thoughtcrime.securesms.groups.BadGroupIdException
|
import org.thoughtcrime.securesms.groups.BadGroupIdException
|
||||||
import org.thoughtcrime.securesms.groups.GroupId
|
import org.thoughtcrime.securesms.groups.GroupId
|
||||||
import org.thoughtcrime.securesms.jobs.OptimizeMessageSearchIndexJob
|
import org.thoughtcrime.securesms.jobs.OptimizeMessageSearchIndexJob
|
||||||
|
@ -1040,6 +1041,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
||||||
|
|
||||||
notifyConversationListListeners()
|
notifyConversationListListeners()
|
||||||
notifyConversationListeners(threadId)
|
notifyConversationListeners(threadId)
|
||||||
|
ApplicationDependencies.getDatabaseObserver().notifyConversationDeleteListeners(threadId)
|
||||||
ConversationUtil.clearShortcuts(context, setOf(recipientIdForThreadId))
|
ConversationUtil.clearShortcuts(context, setOf(recipientIdForThreadId))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1056,6 +1058,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
||||||
|
|
||||||
notifyConversationListListeners()
|
notifyConversationListListeners()
|
||||||
notifyConversationListeners(selectedConversations)
|
notifyConversationListeners(selectedConversations)
|
||||||
|
ApplicationDependencies.getDatabaseObserver().notifyConversationDeleteListeners(selectedConversations)
|
||||||
ConversationUtil.clearShortcuts(context, recipientIdsForThreadIds)
|
ConversationUtil.clearShortcuts(context, recipientIdsForThreadIds)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue