|
|
@ -18,18 +18,23 @@ package io.element.android.features.securebackup.impl.root |
|
|
|
|
|
|
|
|
|
|
|
import androidx.compose.runtime.Composable |
|
|
|
import androidx.compose.runtime.Composable |
|
|
|
import androidx.compose.runtime.LaunchedEffect |
|
|
|
import androidx.compose.runtime.LaunchedEffect |
|
|
|
|
|
|
|
import androidx.compose.runtime.MutableState |
|
|
|
import androidx.compose.runtime.collectAsState |
|
|
|
import androidx.compose.runtime.collectAsState |
|
|
|
import androidx.compose.runtime.getValue |
|
|
|
import androidx.compose.runtime.getValue |
|
|
|
import androidx.compose.runtime.mutableStateOf |
|
|
|
import androidx.compose.runtime.mutableStateOf |
|
|
|
import androidx.compose.runtime.remember |
|
|
|
import androidx.compose.runtime.remember |
|
|
|
import androidx.compose.runtime.setValue |
|
|
|
import androidx.compose.runtime.rememberCoroutineScope |
|
|
|
import io.element.android.features.securebackup.impl.loggerTagRoot |
|
|
|
import io.element.android.features.securebackup.impl.loggerTagRoot |
|
|
|
|
|
|
|
import io.element.android.libraries.architecture.Async |
|
|
|
import io.element.android.libraries.architecture.Presenter |
|
|
|
import io.element.android.libraries.architecture.Presenter |
|
|
|
|
|
|
|
import io.element.android.libraries.architecture.runCatchingUpdatingState |
|
|
|
import io.element.android.libraries.core.meta.BuildMeta |
|
|
|
import io.element.android.libraries.core.meta.BuildMeta |
|
|
|
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher |
|
|
|
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher |
|
|
|
import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState |
|
|
|
import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState |
|
|
|
import io.element.android.libraries.matrix.api.encryption.BackupState |
|
|
|
import io.element.android.libraries.matrix.api.encryption.BackupState |
|
|
|
import io.element.android.libraries.matrix.api.encryption.EncryptionService |
|
|
|
import io.element.android.libraries.matrix.api.encryption.EncryptionService |
|
|
|
|
|
|
|
import kotlinx.coroutines.CoroutineScope |
|
|
|
|
|
|
|
import kotlinx.coroutines.launch |
|
|
|
import timber.log.Timber |
|
|
|
import timber.log.Timber |
|
|
|
import javax.inject.Inject |
|
|
|
import javax.inject.Inject |
|
|
|
|
|
|
|
|
|
|
@ -41,6 +46,7 @@ class SecureBackupRootPresenter @Inject constructor( |
|
|
|
|
|
|
|
|
|
|
|
@Composable |
|
|
|
@Composable |
|
|
|
override fun present(): SecureBackupRootState { |
|
|
|
override fun present(): SecureBackupRootState { |
|
|
|
|
|
|
|
val localCoroutineScope = rememberCoroutineScope() |
|
|
|
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState() |
|
|
|
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState() |
|
|
|
|
|
|
|
|
|
|
|
val backupState by encryptionService.backupStateStateFlow.collectAsState() |
|
|
|
val backupState by encryptionService.backupStateStateFlow.collectAsState() |
|
|
@ -49,23 +55,33 @@ class SecureBackupRootPresenter @Inject constructor( |
|
|
|
Timber.tag(loggerTagRoot.value).d("backupState: $backupState") |
|
|
|
Timber.tag(loggerTagRoot.value).d("backupState: $backupState") |
|
|
|
Timber.tag(loggerTagRoot.value).d("recoveryState: $recoveryState") |
|
|
|
Timber.tag(loggerTagRoot.value).d("recoveryState: $recoveryState") |
|
|
|
|
|
|
|
|
|
|
|
var doesBackupExistOnServer: Boolean? by remember { mutableStateOf(null) } |
|
|
|
val doesBackupExistOnServerAction: MutableState<Async<Boolean>> = remember { mutableStateOf(Async.Uninitialized) } |
|
|
|
|
|
|
|
|
|
|
|
LaunchedEffect(backupState) { |
|
|
|
LaunchedEffect(backupState) { |
|
|
|
doesBackupExistOnServer = if (backupState == BackupState.UNKNOWN) { |
|
|
|
if (backupState == BackupState.UNKNOWN) { |
|
|
|
encryptionService.doesBackupExistOnServer().getOrNull() == true |
|
|
|
getKeyBackupStatus(doesBackupExistOnServerAction) |
|
|
|
} else { |
|
|
|
} |
|
|
|
// The value will not be used when the backupState is not UNKNOWN. |
|
|
|
} |
|
|
|
false |
|
|
|
|
|
|
|
|
|
|
|
fun handleEvents(event: SecureBackupRootEvents) { |
|
|
|
|
|
|
|
when (event) { |
|
|
|
|
|
|
|
SecureBackupRootEvents.RetryKeyBackupState -> localCoroutineScope.getKeyBackupStatus(doesBackupExistOnServerAction) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return SecureBackupRootState( |
|
|
|
return SecureBackupRootState( |
|
|
|
backupState = backupState, |
|
|
|
backupState = backupState, |
|
|
|
doesBackupExistOnServer = doesBackupExistOnServer, |
|
|
|
doesBackupExistOnServer = doesBackupExistOnServerAction.value, |
|
|
|
recoveryState = recoveryState, |
|
|
|
recoveryState = recoveryState, |
|
|
|
appName = buildMeta.applicationName, |
|
|
|
appName = buildMeta.applicationName, |
|
|
|
snackbarMessage = snackbarMessage, |
|
|
|
snackbarMessage = snackbarMessage, |
|
|
|
|
|
|
|
eventSink = ::handleEvents, |
|
|
|
) |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun CoroutineScope.getKeyBackupStatus(action: MutableState<Async<Boolean>>) = launch { |
|
|
|
|
|
|
|
suspend { |
|
|
|
|
|
|
|
encryptionService.doesBackupExistOnServer().getOrThrow() |
|
|
|
|
|
|
|
}.runCatchingUpdatingState(action) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|