From 4913edccde9fbdb8bea9682e4d2ea77c093c61e8 Mon Sep 17 00:00:00 2001 From: SessionHero01 <180888785+SessionHero01@users.noreply.github.com> Date: Mon, 24 Mar 2025 11:52:05 +1100 Subject: [PATCH 1/5] Catch the crash on home screen (#1049) --- .../org/thoughtcrime/securesms/home/HomeViewModel.kt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/HomeViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/home/HomeViewModel.kt index 67d80da4f3..b2a702e33d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeViewModel.kt @@ -14,6 +14,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.distinctUntilChanged @@ -23,11 +24,13 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.merge +import kotlinx.coroutines.flow.onErrorResume import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn import network.loki.messenger.libsession_util.ConfigBase.Companion.PRIORITY_HIDDEN import org.session.libsession.utilities.ConfigUpdateNotification import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsignal.utilities.Log import org.thoughtcrime.securesms.database.DatabaseContentProviders import org.thoughtcrime.securesms.database.ThreadDatabase import org.thoughtcrime.securesms.database.model.ThreadRecord @@ -78,9 +81,11 @@ class HomeViewModel @Inject constructor( ) } } - ) - } - .stateIn(viewModelScope, SharingStarted.Eagerly, null) + ) as? Data? + }.catch { err -> + Log.e("HomeViewModel", "Error loading conversation list", err) + emit(null) + }.stateIn(viewModelScope, SharingStarted.Eagerly, null) private fun hasHiddenMessageRequests() = TextSecurePreferences.events .filter { it == TextSecurePreferences.HAS_HIDDEN_MESSAGE_REQUESTS } From 362f37b01da41994bc96241e97acf6869c8955be Mon Sep 17 00:00:00 2001 From: SessionHero01 <180888785+SessionHero01@users.noreply.github.com> Date: Mon, 24 Mar 2025 16:16:51 +1100 Subject: [PATCH 2/5] Revert "Moving db calls out of the main thread" This reverts commit e404fb964f1d5c9001463703913eff90b873217b. --- app/build.gradle | 4 ++-- .../conversation/v2/ConversationActivityV2.kt | 16 ++++------------ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0c5eb7e40c..65560ec860 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,8 +15,8 @@ configurations.configureEach { exclude module: "commons-logging" } -def canonicalVersionCode = 399 -def canonicalVersionName = "1.21.3" +def canonicalVersionCode = 398 +def canonicalVersionName = "1.21.2" def postFixSize = 10 def abiPostFix = ['armeabi-v7a' : 1, 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 e453ade6f5..a8512df14d 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 @@ -641,11 +641,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe if (author != null && messageTimestamp >= 0) { jumpToMessage(author, messageTimestamp, firstLoad.get(), null) } else { - if (firstLoad.getAndSet(false)) { - lifecycleScope.launch(Dispatchers.Main) { - scrollToFirstUnreadMessageIfNeeded(true) - } - } + if (firstLoad.getAndSet(false)) scrollToFirstUnreadMessageIfNeeded(true) handleRecyclerViewScrolled() } } @@ -976,13 +972,9 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } } - private suspend fun scrollToFirstUnreadMessageIfNeeded(isFirstLoad: Boolean = false, shouldHighlight: Boolean = false): Int { - val lastSeenItemPosition = withContext(Dispatchers.Default) { - val lastSeenTimestamp = threadDb.getLastSeenAndHasSent(viewModel.threadId).first() - adapter.findLastSeenItemPosition(lastSeenTimestamp) - } - - if(lastSeenItemPosition == null) return -1 + private fun scrollToFirstUnreadMessageIfNeeded(isFirstLoad: Boolean = false, shouldHighlight: Boolean = false): Int { + val lastSeenTimestamp = threadDb.getLastSeenAndHasSent(viewModel.threadId).first() + val lastSeenItemPosition = adapter.findLastSeenItemPosition(lastSeenTimestamp) ?: return -1 // If this is triggered when first opening a conversation then we want to position the top // of the first unread message in the middle of the screen From a1692197ac05fbf2338d82514c1ce6765c32aa08 Mon Sep 17 00:00:00 2001 From: SessionHero01 <180888785+SessionHero01@users.noreply.github.com> Date: Mon, 24 Mar 2025 16:17:17 +1100 Subject: [PATCH 3/5] Bump version code to 400 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 65560ec860..f59d6a6365 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,8 +15,8 @@ configurations.configureEach { exclude module: "commons-logging" } -def canonicalVersionCode = 398 -def canonicalVersionName = "1.21.2" +def canonicalVersionCode = 400 +def canonicalVersionName = "1.21.3" def postFixSize = 10 def abiPostFix = ['armeabi-v7a' : 1, From 95975c79bdc3482e714beb9cc4a1d9201a569330 Mon Sep 17 00:00:00 2001 From: SessionHero01 <180888785+SessionHero01@users.noreply.github.com> Date: Tue, 25 Mar 2025 10:50:24 +1100 Subject: [PATCH 4/5] [ses-3567] - fix error sending group invite (#1052) --- .../securesms/groups/GroupManagerV2Impl.kt | 2 ++ .../messaging/jobs/InviteContactsJob.kt | 18 ++++++++++++++++-- .../sending_receiving/MessageSender.kt | 8 ++++---- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt index dc1ea686f5..440f67dbcb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt @@ -299,6 +299,8 @@ class GroupManagerV2Impl @Inject constructor( configs.groupInfo.getName().orEmpty() } + Log.w(TAG, "Failed to invite members to group $group", e) + throw GroupInviteException( isPromotion = false, inviteeAccountIds = newMembers.map { it.hexString }, diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/InviteContactsJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/InviteContactsJob.kt index a76101450e..ef4f591e5d 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/InviteContactsJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/InviteContactsJob.kt @@ -21,6 +21,7 @@ import org.session.libsession.utilities.getGroup import org.session.libsignal.protos.SignalServiceProtos.DataMessage.GroupUpdateInviteMessage import org.session.libsignal.protos.SignalServiceProtos.DataMessage.GroupUpdateMessage import org.session.libsignal.utilities.AccountId +import org.session.libsignal.utilities.Log class InviteContactsJob(val groupSessionId: String, val memberSessionIds: Array) : Job { @@ -100,7 +101,11 @@ class InviteContactsJob(val groupSessionId: String, val memberSessionIds: Array< val groupName = configs.withGroupConfigs(sessionId) { it.groupInfo.getName() } ?: configs.getGroup(sessionId)?.name - val failures = results.filter { it.second.isFailure } + // Gather all the exceptions, while keeping track of the invitee account IDs + val failures = results.mapNotNull { (id, result) -> + result.exceptionOrNull()?.let { err -> id to err } + } + // if there are failed invites, display a message // assume job "success" even if we fail, the state of invites is tracked outside of this job if (failures.isNotEmpty()) { @@ -108,11 +113,20 @@ class InviteContactsJob(val groupSessionId: String, val memberSessionIds: Array< val storage = MessagingModuleConfiguration.shared.storage val toaster = MessagingModuleConfiguration.shared.toaster + val (_, firstError) = failures.first() + + // Add the rest of the exceptions as suppressed + for ((_, suppressed) in failures.asSequence().drop(1)) { + firstError.addSuppressed(suppressed) + } + + Log.w("InviteContactsJob", "Failed to invite contacts", firstError) + GroupInviteException( isPromotion = false, inviteeAccountIds = failures.map { it.first }, groupName = groupName.orEmpty(), - underlying = failures.first().second.exceptionOrNull()!!, + underlying = firstError, ).format(MessagingModuleConfiguration.shared.context, storage).let { withContext(Dispatchers.Main) { toaster.toast(it, Toast.LENGTH_LONG) diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt index ae083f26f1..52a00e119a 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt @@ -430,7 +430,7 @@ object MessageSender { // Result Handling fun handleSuccessfulMessageSend(message: Message, destination: Destination, isSyncMessage: Boolean = false, openGroupSentTimestamp: Long = -1) { - val threadId = message.threadID!! + val threadId by lazy { requireNotNull(message.threadID) { "threadID for the message is null" } } if (message is VisibleMessage) MessagingModuleConfiguration.shared.lastSentTimestampCache.submitTimestamp(threadId, openGroupSentTimestamp) val storage = MessagingModuleConfiguration.shared.storage val userPublicKey = storage.getUserPublicKey()!! @@ -473,9 +473,9 @@ object MessageSender { } } val encoded = GroupUtil.getEncodedOpenGroupID("$server.$room".toByteArray()) - val threadID = storage.getThreadId(Address.fromSerialized(encoded)) - if (threadID != null && threadID >= 0) { - storage.setOpenGroupServerMessageID(messageID, message.openGroupServerMessageID!!, threadID, !(message as VisibleMessage).isMediaMessage()) + val communityThreadID = storage.getThreadId(Address.fromSerialized(encoded)) + if (communityThreadID != null && communityThreadID >= 0) { + storage.setOpenGroupServerMessageID(messageID, message.openGroupServerMessageID!!, communityThreadID, !(message as VisibleMessage).isMediaMessage()) } } From 5699be96cce87daebf592cf7716462316481dcb5 Mon Sep 17 00:00:00 2001 From: SessionHero01 <180888785+SessionHero01@users.noreply.github.com> Date: Tue, 25 Mar 2025 10:54:15 +1100 Subject: [PATCH 5/5] Bump version code to 401 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index f59d6a6365..31b4de65cb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,7 @@ configurations.configureEach { exclude module: "commons-logging" } -def canonicalVersionCode = 400 +def canonicalVersionCode = 401 def canonicalVersionName = "1.21.3" def postFixSize = 10