From aadbcf36d0a164060dbd16ef9debbdd5bb7ec312 Mon Sep 17 00:00:00 2001 From: 0x330a <92654767+0x330a@users.noreply.github.com> Date: Fri, 24 Mar 2023 11:18:14 +1100 Subject: [PATCH] feat: add in activity finish if recipient no longer exists (deleted thread) from sync --- .../conversation/v2/ConversationActivityV2.kt | 6 ++++- .../conversation/v2/ConversationViewModel.kt | 26 ++++++++++++++++--- .../sending_receiving/pollers/Poller.kt | 8 +----- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 4468c36665..ae830deb07 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -241,7 +241,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } } ?: finish() } - viewModelFactory.create(threadId, MessagingModuleConfiguration.shared.getUserED25519KeyPair()) + viewModelFactory.create(threadId, MessagingModuleConfiguration.shared.getUserED25519KeyPair(), contentResolver) } private var actionMode: ActionMode? = null private var unreadCount = 0 @@ -665,6 +665,10 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe if (uiState.isMessageRequestAccepted == true) { binding?.messageRequestBar?.visibility = View.GONE } + if (!uiState.conversationExists && !isFinishing) { + // Conversation should be deleted now, just go back + finish() + } } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt index 9a56108969..c7fc4d0056 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt @@ -1,8 +1,10 @@ package org.thoughtcrime.securesms.conversation.v2 +import android.content.ContentResolver import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope +import app.cash.copper.flow.observeQuery import com.goterl.lazysodium.utils.KeyPair import dagger.assisted.Assisted import dagger.assisted.AssistedInject @@ -19,6 +21,7 @@ import org.session.libsession.messaging.utilities.SodiumUtilities import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.IdPrefix import org.session.libsignal.utilities.Log +import org.thoughtcrime.securesms.database.DatabaseContentProviders import org.thoughtcrime.securesms.database.Storage import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.repository.ConversationRepository @@ -27,11 +30,12 @@ import java.util.UUID class ConversationViewModel( val threadId: Long, val edKeyPair: KeyPair?, + private val contentResolver: ContentResolver, private val repository: ConversationRepository, private val storage: Storage ) : ViewModel() { - private val _uiState = MutableStateFlow(ConversationUiState()) + private val _uiState = MutableStateFlow(ConversationUiState(conversationExists = recipient != null)) val uiState: StateFlow = _uiState val recipient: Recipient? @@ -49,6 +53,18 @@ class ConversationViewModel( ?.let { SessionId(IdPrefix.BLINDED, it) }?.hexString } + init { + viewModelScope.launch(Dispatchers.IO) { + contentResolver.observeQuery(DatabaseContentProviders.Conversation.getUriForThread(threadId)) + .collect { + val recipientExists = storage.getRecipientForThread(threadId) != null + if (!recipientExists && _uiState.value.conversationExists) { + _uiState.update { it.copy(conversationExists = false) } + } + } + } + } + fun saveDraft(text: String) { GlobalScope.launch(Dispatchers.IO) { repository.saveDraft(threadId, text) @@ -172,19 +188,20 @@ class ConversationViewModel( @dagger.assisted.AssistedFactory interface AssistedFactory { - fun create(threadId: Long, edKeyPair: KeyPair?): Factory + fun create(threadId: Long, edKeyPair: KeyPair?, contentResolver: ContentResolver): Factory } @Suppress("UNCHECKED_CAST") class Factory @AssistedInject constructor( @Assisted private val threadId: Long, @Assisted private val edKeyPair: KeyPair?, + @Assisted private val contentResolver: ContentResolver, private val repository: ConversationRepository, private val storage: Storage ) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { - return ConversationViewModel(threadId, edKeyPair, repository, storage) as T + return ConversationViewModel(threadId, edKeyPair, contentResolver, repository, storage) as T } } } @@ -193,5 +210,6 @@ data class UiMessage(val id: Long, val message: String) data class ConversationUiState( val uiMessages: List = emptyList(), - val isMessageRequestAccepted: Boolean? = null + val isMessageRequestAccepted: Boolean? = null, + val conversationExists: Boolean ) diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt index 09c3645721..224bfbeeaa 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt @@ -138,7 +138,7 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti namespace, updateLatestHash = true, updateStoredHashes = true, - ) // TODO: might not be needed anymore .filter { (_, hash) -> !forConfigObject.currentHashes().contains(hash) } + ) if (messages.isEmpty()) { // no new messages to process @@ -186,12 +186,6 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti requestSparseArray[request.namespace!!] = request } - if (requestSparseArray.size() == 1) { - // only one (the personal messages) - Log.d("Loki-DBG", "Not building requests for the configs, current config state:") - Log.d("Loki-DBG", "${listOf(configFactory.user, configFactory.contacts, configFactory.convoVolatile)}") - } - val requests = requestSparseArray.valueIterator().asSequence().toList() SnodeAPI.getRawBatchResponse(snode, userPublicKey, requests).bind { rawResponses ->