diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxScreen.kt index d457ee74aaa89f7fe8d7243278e42f5b0e8e7469..27b2a02a586f9ee9d4dec822a8e62c30b6dae949 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxScreen.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxScreen.kt @@ -45,10 +45,18 @@ fun MailboxScreen(viewModel: MailboxViewModel = viewModel()) { is InvalidQrCode, is MailboxAlreadyPaired, is ConnectionError, is UnexpectedError -> { MailboxSetupScreen(viewModel, true) } - is Paired -> MailboxStatusScreen(viewModel.status.value) + is Paired -> MailboxStatusScreen( + status = viewModel.status.value, + isCheckingConnection = false, // we just paired, there was no time to trigger a connection check + onCheckConnection = viewModel::checkConnection, + ) } OfflineWhenPairing -> MailboxSetupScreen(viewModel, true) - is IsPaired -> MailboxStatusScreen(viewModel.status.value) + is IsPaired -> MailboxStatusScreen( + status = viewModel.status.value, + isCheckingConnection = state.connectionCheckRunning, + onCheckConnection = viewModel::checkConnection, + ) is WasUnpaired -> UiPlaceholder() // TODO } } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxStatusScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxStatusScreen.kt index 3205dbe2ec7fb378d595b5e18bab70f22ce3cd38..7464fa46015f6300d3964207dee5f7b874f9c47e 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxStatusScreen.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxStatusScreen.kt @@ -23,6 +23,9 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material.Button +import androidx.compose.material.CircularProgressIndicator import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme import androidx.compose.material.OutlinedButton @@ -55,9 +58,10 @@ import org.briarproject.briar.desktop.utils.TimeUtils.getFormattedTimestamp @Suppress("HardCodedStringLiteral") fun main() = preview( "status" to DropDownValues( - 0, + 4, listOf("error", "problem", "mailbox too old", "briar too old", "ok") - ) + ), + "isCheckingConnection" to false, ) { val now = System.currentTimeMillis() val status = when (getStringParameter("status")) { @@ -67,11 +71,15 @@ fun main() = preview( "briar too old" -> MailboxStatus(now, now, 0, listOf(MailboxVersion(42, 0))) else -> MailboxStatus(now, now - 18_354, 0, CLIENT_SUPPORTS) } - MailboxStatusScreen(status) + MailboxStatusScreen(status, getBooleanParameter("isCheckingConnection")) {} } @Composable -fun MailboxStatusScreen(status: MailboxStatus?) { +fun MailboxStatusScreen( + status: MailboxStatus?, + isCheckingConnection: Boolean, + onCheckConnection: () -> Unit, +) { if (status == null) return // not expected to happen (for a noticeable amount of time) Column( verticalArrangement = spacedBy(16.dp), @@ -119,6 +127,14 @@ fun MailboxStatusScreen(status: MailboxStatus?) { lastSuccess = status.timeOfLastSuccess, ) } + if (isCheckingConnection) CircularProgressIndicator() + else Button( + onClick = onCheckConnection + ) { + Text( + text = i18n("mailbox.status.check.connection.button"), + ) + } Spacer(modifier = Modifier.weight(1f)) OutlinedButton( onClick = { /* TODO */ }, @@ -141,6 +157,7 @@ private fun MailboxStatusView( imageVector = icon, contentDescription = "", // not important, we have a title tint = iconTint, + modifier = Modifier.size(64.dp) ) Text( text = title, diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxViewModel.kt index bbf739b8e815676885c1f1da0a314e6f18d4f9f4..8e293a210cf0f570ece116259ebf013b305d2ec3 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxViewModel.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxViewModel.kt @@ -42,6 +42,8 @@ import org.briarproject.briar.desktop.mailbox.MailboxPairingUiState.Pairing import org.briarproject.briar.desktop.mailbox.MailboxPairingUiState.Unknown import org.briarproject.briar.desktop.threading.BriarExecutors import org.briarproject.briar.desktop.threading.UiExecutor +import org.briarproject.briar.desktop.utils.KLoggerUtils.i +import org.briarproject.briar.desktop.utils.KLoggerUtils.w import org.briarproject.briar.desktop.viewmodel.EventListenerDbViewModel import org.briarproject.briar.desktop.viewmodel.asState import javax.inject.Inject @@ -51,7 +53,7 @@ sealed class MailboxPairingUiState { object NotSetup : MailboxPairingUiState() class Pairing(val pairingState: MailboxPairingState) : MailboxPairingUiState() object OfflineWhenPairing : MailboxPairingUiState() - class IsPaired(val isOnline: Boolean) : MailboxPairingUiState() + class IsPaired(val connectionCheckRunning: Boolean) : MailboxPairingUiState() class WasUnpaired(val tellUserToWipeMailbox: Boolean) : MailboxPairingUiState() } @@ -90,9 +92,8 @@ class MailboxViewModel @Inject constructor( val isPaired = mailboxManager.isPaired(txn) if (isPaired) { val mailboxStatus = mailboxManager.getMailboxStatus(txn) - val isOnline = isTorActive() briarExecutors.onUiThread { - _pairingState.value = IsPaired(isOnline) + _pairingState.value = IsPaired(false) _status.value = mailboxStatus } } else briarExecutors.onUiThread { @@ -116,10 +117,7 @@ class MailboxViewModel @Inject constructor( @UiExecutor private fun onTorInactive() { val lastState = _pairingState.value - if (lastState is IsPaired) { - // we are already paired, so use IsPaired state - _pairingState.value = IsPaired(false) - } else if (lastState is Pairing) { + if (lastState is Pairing) { // check that we not just finished pairing (showing success screen) if (lastState.pairingState !is Paired) _pairingState.value = OfflineWhenPairing // else ignore offline event as user will be leaving UI flow anyway @@ -128,8 +126,7 @@ class MailboxViewModel @Inject constructor( @UiExecutor override fun accept(t: MailboxPairingState) { - @Suppress("HardCodedStringLiteral") - LOG.info { "New pairing state: ${t::class.simpleName}" } + LOG.i { "New pairing state: ${t::class.simpleName}" } _pairingState.value = Pairing(t) } @@ -159,4 +156,20 @@ class MailboxViewModel @Inject constructor( fun onPairingErrorSeen() { _pairingState.value = NotSetup } + + @UiExecutor + fun checkConnection() { + // we can only check the connection when we are already paired (or just finished pairing) + _pairingState.value = IsPaired(true) + briarExecutors.onIoThread { + // this check updates _status state via an Event + val success = mailboxManager.checkConnection() + LOG.i { "Got result from connection check: $success" } + briarExecutors.onUiThread { + val s = pairingState.value + if (s is IsPaired) _pairingState.value = IsPaired(false) + else LOG.w { "Unexpected state: ${s::class.simpleName}" } + } + } + } } diff --git a/briar-desktop/src/main/resources/strings/BriarDesktop.properties b/briar-desktop/src/main/resources/strings/BriarDesktop.properties index febaeb7d7db12fac87953c29d57db6d2f3edbc95..58fd1974211169486caa894c92a8b0c79fec231a 100644 --- a/briar-desktop/src/main/resources/strings/BriarDesktop.properties +++ b/briar-desktop/src/main/resources/strings/BriarDesktop.properties @@ -268,6 +268,7 @@ mailbox.status.app_too_old.message=Update Briar to the latest version of the app mailbox.status.mailbox_too_old.title=Mailbox is too old mailbox.status.mailbox_too_old.message=Update your Mailbox to the latest version of the app and try again. mailbox.status.connected.title=Mailbox is running +mailbox.status.check.connection.button=Check Connection mailbox.status.unlink.button=Unlink mailbox.status.last.connection=Last connection: {0}