diff --git a/src/main/kotlin/org/briarproject/briar/desktop/BriarService.kt b/src/main/kotlin/org/briarproject/briar/desktop/BriarService.kt index aa277f516012bf86ff48aa06a690f7e91a95dabe..afb54a129da15b10530a3b8bcc37e32172b4356e 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/BriarService.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/BriarService.kt @@ -1,6 +1,16 @@ package org.briarproject.briar.desktop +import androidx.compose.desktop.Window +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import org.briarproject.bramble.api.account.AccountManager +import org.briarproject.bramble.api.crypto.DecryptionException import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator import org.briarproject.bramble.api.lifecycle.LifecycleManager import org.briarproject.briar.desktop.dialogs.Login @@ -8,8 +18,14 @@ import org.briarproject.briar.desktop.dialogs.Registration import javax.annotation.concurrent.Immutable import javax.inject.Inject import javax.inject.Singleton +import androidx.compose.runtime.getValue +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp interface BriarService { + @Composable fun start() fun stop() } @@ -24,6 +40,7 @@ constructor( private val passwordStrengthEstimator: PasswordStrengthEstimator ) : BriarService { + @Composable override fun start() { if (!accountManager.accountExists()) { createAccount() @@ -42,7 +59,39 @@ constructor( Registration("Briar", accountManager, lifecycleManager) } + @Composable private fun login() { - Login("Briar", accountManager, lifecycleManager) + val title = "Briar Desktop" + var screenState by remember { mutableStateOf<Screen>(Screen.Login) } + Window(title = title) { + when (val screen = screenState) { + is Screen.Login -> + Login("Briar", onResult = { + try { + accountManager.signIn(it) + signedIn() + screenState = Screen.Main + } catch (e: DecryptionException) { + // failure, try again + } + }) + + is Screen.Main -> + Column( + modifier = Modifier.padding(16.dp).fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text("Welcome to Briar") + } + } + } } + + private fun signedIn() { + val dbKey = accountManager.databaseKey ?: throw AssertionError() + lifecycleManager.startServices(dbKey) + lifecycleManager.waitForStartup() + } + } diff --git a/src/main/kotlin/org/briarproject/briar/desktop/Main.kt b/src/main/kotlin/org/briarproject/briar/desktop/Main.kt index a7006b69f91abe67c0470fb6e070d1628bd57f16..50c7cec8a88a86e1c964b00398ca47883aa52ba7 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/Main.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/Main.kt @@ -1,5 +1,8 @@ package org.briarproject.briar.desktop +import androidx.compose.runtime.Composable +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.window.application import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.parameters.options.counted import com.github.ajalt.clikt.parameters.options.default @@ -38,7 +41,8 @@ private class Main : CliktCommand( envvar = "BRIAR_DATA_DIR" ).default(DEFAULT_DATA_DIR) - override fun run() { + @OptIn(ExperimentalComposeUiApi::class) + override fun run() = application { val level = if (debug) ALL else when (verbosity) { 0 -> WARNING 1 -> INFO @@ -58,7 +62,6 @@ private class Main : CliktCommand( BriarCoreEagerSingletons.Helper.injectEagerSingletons(app) app.getUI().startBriar() - app.getUI().startUI() } private fun getDataDir(): File { diff --git a/src/main/kotlin/org/briarproject/briar/desktop/MainUI.kt b/src/main/kotlin/org/briarproject/briar/desktop/MainUI.kt deleted file mode 100644 index 1c4e79540233f55da682bbf752d06511a088ca2a..0000000000000000000000000000000000000000 --- a/src/main/kotlin/org/briarproject/briar/desktop/MainUI.kt +++ /dev/null @@ -1,37 +0,0 @@ -package org.briarproject.briar.desktop - -import org.briarproject.bramble.api.account.AccountManager -import org.briarproject.bramble.api.contact.ContactManager -import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator -import org.briarproject.bramble.api.event.EventBus -import org.briarproject.briar.api.conversation.ConversationManager -import org.briarproject.briar.api.introduction.IntroductionManager -import org.briarproject.briar.api.messaging.MessagingManager -import org.briarproject.briar.api.messaging.PrivateMessageFactory - -class MainUI( - private val briarService: BriarService, - val accountManager: AccountManager, - val contactManager: ContactManager, - private val conversationManager: ConversationManager, - private val messagingManager: MessagingManager, - private val introductionManager: IntroductionManager, - private val privateMessageFactory: PrivateMessageFactory, - private val eventBus: EventBus, - val passwordStrengthEstimator: PasswordStrengthEstimator -) { - - init { - // Should be shown only when logged in -// val title = "Briar Desktop" -// Window (title = title) { -// Column( -// modifier = Modifier.padding(16.dp).fillMaxSize(), -// verticalArrangement = Arrangement.Center, -// horizontalAlignment = Alignment.CenterHorizontally -// ) { -// Text("Welcome to Briar") -// } -// } - } -} diff --git a/src/main/kotlin/org/briarproject/briar/desktop/Screen.kt b/src/main/kotlin/org/briarproject/briar/desktop/Screen.kt new file mode 100644 index 0000000000000000000000000000000000000000..61e48461ac303609e9532d52677151e28a8fa3f0 --- /dev/null +++ b/src/main/kotlin/org/briarproject/briar/desktop/Screen.kt @@ -0,0 +1,6 @@ +package org.briarproject.briar.desktop + +sealed class Screen { + object Login: Screen() + object Main: Screen() +} diff --git a/src/main/kotlin/org/briarproject/briar/desktop/UI.kt b/src/main/kotlin/org/briarproject/briar/desktop/UI.kt index 957e2d004a6100a36fb83800b95f5d6705ff9e04..71d4dc59cace507092df430208fa5482accb95e5 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/UI.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/UI.kt @@ -1,5 +1,6 @@ package org.briarproject.briar.desktop +import androidx.compose.runtime.Composable import org.briarproject.bramble.api.account.AccountManager import org.briarproject.bramble.api.contact.ContactManager import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator @@ -31,24 +32,11 @@ constructor( private val logger = getLogger(UI::javaClass.name) + @Composable internal fun startBriar() { briarService.start(); } - internal fun startUI() { - MainUI( - briarService, - accountManager, - contactManager, - conversationManager, - messagingManager, - introductionManager, - privateMessageFactory, - eventBus, - passwordStrengthEstimator - ) - } - internal fun getContactManager(): ContactManager { return contactManager } diff --git a/src/main/kotlin/org/briarproject/briar/desktop/dialogs/Login.kt b/src/main/kotlin/org/briarproject/briar/desktop/dialogs/Login.kt index 24c8546caa630a47f9bd27b6d2ad99b49ec6373c..49942296d8913dc63929df8c9d2a7a44a82e3fe4 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/dialogs/Login.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/dialogs/Login.kt @@ -13,21 +13,21 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.svgResource import androidx.compose.ui.unit.dp -import org.briarproject.bramble.api.account.AccountManager -import org.briarproject.bramble.api.lifecycle.LifecycleManager // TODO: Error handling -fun Login(title: String, accountManager: AccountManager, lifecycleManager: LifecycleManager) = - Window(title = title) { - Column( - modifier = Modifier.padding(16.dp).fillMaxSize(), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - ) { - TheImage() - Spacer(Modifier.height(32.dp)) - TheTextField(accountManager, lifecycleManager) - } +@Composable +fun Login( + title: String, + onResult: (result: String) -> Unit +) = + Column( + modifier = Modifier.padding(16.dp).fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + TheImage() + Spacer(Modifier.height(32.dp)) + TheTextField(onResult) } @Composable @@ -42,16 +42,12 @@ private fun TheImage() { } @Composable -private fun TheTextField(accountManager: AccountManager, lifecycleManager: LifecycleManager) { +private fun TheTextField(onResult: (result: String) -> Unit) { var password by remember { mutableStateOf("") } OutlinedTextField(password, { password = it }, label = { Text("Password") }) Spacer(Modifier.height(16.dp)) Button(onClick = { - accountManager.signIn(password) - - val dbKey = accountManager.databaseKey ?: throw AssertionError() - lifecycleManager.startServices(dbKey) - lifecycleManager.waitForStartup() + onResult.invoke(password) }) { Text("Login") }