From 7dcd55ee0846bcdbf09743643ad31318c05caacc Mon Sep 17 00:00:00 2001 From: hayaksi1 <193020925+hayaksi1@users.noreply.github.com> Date: Mon, 17 Aug 2026 03:55:09 +0300 Subject: [PATCH] Hide the encryption badge when key storage is set up on the server The settings badge was shown for every unknown backup state, so a session whose key backup lives on the server but has not been reported by the SDK kept a red dot next to Encryption while the Encryption screen itself showed nothing to do. Resolve an unknown backup state the way the Encryption screen already does, by asking whether a backup exists on the server, and only badge the entry when there is none. --- .../indicator/impl/DefaultIndicatorService.kt | 14 ++++++++--- .../impl/DefaultIndicatorServiceTest.kt | 24 +++++++++++++++++-- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/libraries/indicator/impl/src/main/kotlin/io/element/android/libraries/indicator/impl/DefaultIndicatorService.kt b/libraries/indicator/impl/src/main/kotlin/io/element/android/libraries/indicator/impl/DefaultIndicatorService.kt index 0629799c74..1dd2a4c64c 100644 --- a/libraries/indicator/impl/src/main/kotlin/io/element/android/libraries/indicator/impl/DefaultIndicatorService.kt +++ b/libraries/indicator/impl/src/main/kotlin/io/element/android/libraries/indicator/impl/DefaultIndicatorService.kt @@ -9,11 +9,14 @@ package io.element.android.libraries.indicator.impl import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import dev.zacsweers.metro.ContributesBinding import io.element.android.libraries.di.SessionScope import io.element.android.libraries.indicator.api.IndicatorService @@ -43,12 +46,17 @@ class DefaultIndicatorService( override fun showSettingChatBackupIndicator(): State { val backupState by encryptionService.backupStateStateFlow.collectAsState() val recoveryState by encryptionService.recoveryStateStateFlow.collectAsState() + var doesBackupExistOnServer by remember { mutableStateOf(null) } + + LaunchedEffect(backupState) { + if (backupState == BackupState.UNKNOWN) { + doesBackupExistOnServer = encryptionService.doesBackupExistOnServer().getOrNull() + } + } return remember { derivedStateOf { - val showForBackup = backupState in listOf( - BackupState.UNKNOWN, - ) + val showForBackup = backupState == BackupState.UNKNOWN && doesBackupExistOnServer != true val showForRecovery = recoveryState in listOf( RecoveryState.DISABLED, RecoveryState.INCOMPLETE, diff --git a/libraries/indicator/impl/src/test/kotlin/io/element/android/libraries/indicator/impl/DefaultIndicatorServiceTest.kt b/libraries/indicator/impl/src/test/kotlin/io/element/android/libraries/indicator/impl/DefaultIndicatorServiceTest.kt index cd861ef530..3782e2c9f1 100644 --- a/libraries/indicator/impl/src/test/kotlin/io/element/android/libraries/indicator/impl/DefaultIndicatorServiceTest.kt +++ b/libraries/indicator/impl/src/test/kotlin/io/element/android/libraries/indicator/impl/DefaultIndicatorServiceTest.kt @@ -42,8 +42,10 @@ class DefaultIndicatorServiceTest { } @Test - fun `test - showSettingChatBackupIndicator is true when BackupState is UNKNOWN`() = runTest { - val encryptionService = FakeEncryptionService() + fun `test - showSettingChatBackupIndicator is true when BackupState is UNKNOWN and no backup exists on the server`() = runTest { + val encryptionService = FakeEncryptionService().apply { + givenDoesBackupExistOnServerResult(Result.success(false)) + } val sessionVerificationService = FakeSessionVerificationService() val sut = DefaultIndicatorService( sessionVerificationService = sessionVerificationService, @@ -61,6 +63,24 @@ class DefaultIndicatorServiceTest { } } + @Test + fun `test - showSettingChatBackupIndicator is false when BackupState is UNKNOWN but a backup exists on the server`() = runTest { + val encryptionService = FakeEncryptionService().apply { + givenDoesBackupExistOnServerResult(Result.success(true)) + } + val sessionVerificationService = FakeSessionVerificationService() + val sut = DefaultIndicatorService( + sessionVerificationService = sessionVerificationService, + encryptionService = encryptionService, + ) + moleculeFlow(RecompositionMode.Immediate) { + sut.showSettingChatBackupIndicator().value + }.test { + assertThat(awaitItem()).isTrue() + assertThat(awaitItem()).isFalse() + } + } + @Test fun `test - showSettingChatBackupIndicator is true when recoveryState is DISABLED`() = runTest { val encryptionService = FakeEncryptionService()