From a503a1b21877776dc81bad9af5eff041c349fb31 Mon Sep 17 00:00:00 2001 From: greenart7c3 <115044884+greenart7c3@users.noreply.github.com> Date: Mon, 8 May 2023 10:45:10 -0300 Subject: [PATCH] show orbot dialog at login --- .../amethyst/LocalPreferences.kt | 9 +++-- .../vitorpamplona/amethyst/model/Account.kt | 3 +- .../amethyst/ui/navigation/DrawerContent.kt | 16 +++++---- .../ui/screen/AccountStateViewModel.kt | 18 +++++----- .../ui/screen/loggedIn/ConnectOrbotDialog.kt | 33 +++++++++++++------ .../ui/screen/loggedOff/LoginScreen.kt | 26 ++++++++++++--- 6 files changed, 72 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt b/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt index 25522fbf7..624d1bb2e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt @@ -56,6 +56,7 @@ private object PrefKeys { const val HIDE_DELETE_REQUEST_DIALOG = "hide_delete_request_dialog" const val HIDE_BLOCK_ALERT_DIALOG = "hide_block_alert_dialog" const val USE_PROXY = "use_proxy" + const val PROXY_PORT = "proxy_port" val LAST_READ: (String) -> String = { route -> "last_read_route_$route" } } @@ -209,8 +210,8 @@ object LocalPreferences { putString(PrefKeys.LATEST_CONTACT_LIST, Event.gson.toJson(account.backupContactList)) putBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, account.hideDeleteRequestDialog) putBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, account.hideBlockAlertDialog) - println(account.proxy != null) putBoolean(PrefKeys.USE_PROXY, account.proxy != null) + putInt(PrefKeys.PROXY_PORT, account.proxyPort) }.apply() } @@ -279,7 +280,8 @@ object LocalPreferences { val hideDeleteRequestDialog = getBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, false) val hideBlockAlertDialog = getBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, false) val useProxy = getBoolean(PrefKeys.USE_PROXY, false) - val proxy = HttpClient.initProxy(useProxy, "127.0.0.1", 9050) + val proxyPort = getInt(PrefKeys.PROXY_PORT, 9050) + val proxy = HttpClient.initProxy(useProxy, "127.0.0.1", proxyPort) val a = Account( Persona(privKey = privKey?.toByteArray(), pubKey = pubKey.toByteArray()), @@ -298,7 +300,8 @@ object LocalPreferences { hideDeleteRequestDialog, hideBlockAlertDialog, latestContactList, - proxy + proxy, + proxyPort ) return a diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 841853286..7444b899d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -60,7 +60,8 @@ class Account( var hideDeleteRequestDialog: Boolean = false, var hideBlockAlertDialog: Boolean = false, var backupContactList: ContactListEvent? = null, - var proxy: Proxy? + var proxy: Proxy?, + var proxyPort: Int ) { var transientHiddenUsers: Set = setOf() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt index d2828ef6f..7fc79e207 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt @@ -27,6 +27,7 @@ import androidx.compose.material.Surface import androidx.compose.material.Text import androidx.compose.material.TextButton import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf @@ -241,6 +242,7 @@ fun ListContent( var checked by remember { mutableStateOf(account.proxy != null) } val openDialog = remember { mutableStateOf(false) } var conectOrbotDialogOpen by remember { mutableStateOf(false) } + var proxyPort = remember { mutableStateOf(account.proxyPort.toString()) } Column(modifier = modifier.fillMaxHeight()) { if (accountUser != null) { @@ -310,14 +312,14 @@ fun ListContent( if (conectOrbotDialogOpen) { ConnectOrbotDialog( - account = account, onClose = { conectOrbotDialogOpen = false }, onPost = { conectOrbotDialogOpen = false openDialog.value = false checked = true - enableTor(account, true) - } + enableTor(account, true, proxyPort) + }, + proxyPort ) } @@ -330,7 +332,7 @@ fun ListContent( onClick = { openDialog.value = false checked = false - enableTor(account, false) + enableTor(account, false, proxyPort) } ) { Text(text = stringResource(R.string.yes)) @@ -351,9 +353,11 @@ fun ListContent( private fun enableTor( account: Account, - checked: Boolean + checked: Boolean, + portNumber: MutableState ) { - account.proxy = HttpClient.initProxy(checked, "127.0.0.1", 9050) + account.proxyPort = portNumber.value.toInt() + account.proxy = HttpClient.initProxy(checked, "127.0.0.1", account.proxyPort) LocalPreferences.saveToEncryptedStorage(account) ServiceManager.pause() ServiceManager.start() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt index 79e306176..7bee6e873 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt @@ -40,22 +40,22 @@ class AccountStateViewModel() : ViewModel() { } } - fun startUI(key: String, useProxy: Boolean) { + fun startUI(key: String, useProxy: Boolean, proxyPort: Int) { val pattern = Pattern.compile(".+@.+\\.[a-z]+") val parsed = Nip19.uriToRoute(key) val pubKeyParsed = parsed?.hex?.toByteArray() - val proxy = HttpClient.initProxy(useProxy, "127.0.0.1", 9050) + val proxy = HttpClient.initProxy(useProxy, "127.0.0.1", proxyPort) val account = if (key.startsWith("nsec")) { - Account(Persona(privKey = key.bechToBytes()), proxy = proxy) + Account(Persona(privKey = key.bechToBytes()), proxy = proxy, proxyPort = proxyPort) } else if (pubKeyParsed != null) { - Account(Persona(pubKey = pubKeyParsed), proxy = proxy) + Account(Persona(pubKey = pubKeyParsed), proxy = proxy, proxyPort = proxyPort) } else if (pattern.matcher(key).matches()) { // Evaluate NIP-5 - Account(Persona(), proxy = proxy) + Account(Persona(), proxy = proxy, proxyPort = proxyPort) } else { - Account(Persona(Hex.decode(key)), proxy = proxy) + Account(Persona(Hex.decode(key)), proxy = proxy, proxyPort = proxyPort) } LocalPreferences.updatePrefsForLogin(account) @@ -68,9 +68,9 @@ class AccountStateViewModel() : ViewModel() { tryLoginExistingAccount() } - fun newKey(useProxy: Boolean) { - var proxy = HttpClient.initProxy(useProxy, "127.0.0.1", 9050) - val account = Account(Persona(), proxy = proxy) + fun newKey(useProxy: Boolean, proxyPort: Int) { + val proxy = HttpClient.initProxy(useProxy, "127.0.0.1", proxyPort) + val account = Account(Persona(), proxy = proxy, proxyPort = proxyPort) // saves to local preferences LocalPreferences.updatePrefsForLogin(account) startUI(account) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ConnectOrbotDialog.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ConnectOrbotDialog.kt index 2e2655e0e..2bf827831 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ConnectOrbotDialog.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ConnectOrbotDialog.kt @@ -1,5 +1,6 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn +import android.widget.Toast import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -15,12 +16,11 @@ import androidx.compose.material.OutlinedTextField import androidx.compose.material.Surface import androidx.compose.material.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.KeyboardType @@ -32,14 +32,14 @@ import com.halilibo.richtext.ui.RichTextStyle import com.halilibo.richtext.ui.material.MaterialRichText import com.halilibo.richtext.ui.resolveDefaults import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.ui.actions.CloseButton import com.vitorpamplona.amethyst.ui.actions.PostButton +import kotlinx.coroutines.launch @Composable -fun ConnectOrbotDialog(account: Account, onClose: () -> Unit, onPost: () -> Unit) { - var portNumber by remember { mutableStateOf("9050") } - +fun ConnectOrbotDialog(onClose: () -> Unit, onPost: () -> Unit, portNumber: MutableState) { + val context = LocalContext.current + val scope = rememberCoroutineScope() Dialog( onDismissRequest = onClose, properties = DialogProperties(usePlatformDefaultWidth = false) @@ -62,6 +62,19 @@ fun ConnectOrbotDialog(account: Account, onClose: () -> Unit, onPost: () -> Unit PostButton( onPost = { + try { + Integer.parseInt(portNumber.value) + } catch (_: Exception) { + scope.launch { + Toast.makeText( + context, + "Invalid port number", + Toast.LENGTH_LONG + ).show() + } + return@PostButton + } + onPost() }, isActive = true @@ -84,8 +97,8 @@ fun ConnectOrbotDialog(account: Account, onClose: () -> Unit, onPost: () -> Unit Spacer(modifier = Modifier.height(10.dp)) OutlinedTextField( - value = portNumber, - onValueChange = { portNumber = it }, + value = portNumber.value, + onValueChange = { portNumber.value = it }, keyboardOptions = KeyboardOptions.Default.copy( capitalization = KeyboardCapitalization.None, keyboardType = KeyboardType.Number diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt index d8b66015d..450b14777 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt @@ -39,6 +39,7 @@ import androidx.compose.ui.unit.sp import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.qrcode.SimpleQrCodeScanner import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel +import com.vitorpamplona.amethyst.ui.screen.loggedIn.ConnectOrbotDialog import java.util.* @OptIn(ExperimentalComposeUiApi::class) @@ -57,6 +58,8 @@ fun LoginPage( mutableStateOf(false) } val useProxy = remember { mutableStateOf(false) } + val proxyPort = remember { mutableStateOf("9050") } + var connectOrbotDialogOpen by remember { mutableStateOf(false) } Column( modifier = Modifier @@ -160,7 +163,7 @@ fun LoginPage( keyboardActions = KeyboardActions( onGo = { try { - accountViewModel.startUI(key.value.text, useProxy.value) + accountViewModel.startUI(key.value.text, useProxy.value, proxyPort.value.toInt()) } catch (e: Exception) { errorMessage = context.getString(R.string.invalid_key) } @@ -227,11 +230,26 @@ fun LoginPage( Row(verticalAlignment = Alignment.CenterVertically) { Checkbox( checked = useProxy.value, - onCheckedChange = { useProxy.value = it } + onCheckedChange = { + if (it) { + connectOrbotDialogOpen = true + } + } ) Text(stringResource(R.string.connect_via_tor)) } + + if (connectOrbotDialogOpen) { + ConnectOrbotDialog( + onClose = { connectOrbotDialogOpen = false }, + onPost = { + connectOrbotDialogOpen = false + useProxy.value = true + }, + proxyPort + ) + } } Spacer(modifier = Modifier.height(20.dp)) @@ -250,7 +268,7 @@ fun LoginPage( if (acceptedTerms.value && key.value.text.isNotBlank()) { try { - accountViewModel.startUI(key.value.text, useProxy.value) + accountViewModel.startUI(key.value.text, useProxy.value, proxyPort.value.toInt()) } catch (e: Exception) { errorMessage = context.getString(R.string.invalid_key) } @@ -278,7 +296,7 @@ fun LoginPage( .fillMaxWidth(), onClick = { if (acceptedTerms.value) { - accountViewModel.newKey(useProxy.value) + accountViewModel.newKey(useProxy.value, proxyPort.value.toInt()) } else { termsAcceptanceIsRequired = context.getString(R.string.acceptance_of_terms_is_required)