show orbot dialog at login

This commit is contained in:
greenart7c3 2023-05-08 10:45:10 -03:00
parent 28521c1a60
commit a503a1b218
6 changed files with 72 additions and 33 deletions

View File

@ -56,6 +56,7 @@ private object PrefKeys {
const val HIDE_DELETE_REQUEST_DIALOG = "hide_delete_request_dialog" const val HIDE_DELETE_REQUEST_DIALOG = "hide_delete_request_dialog"
const val HIDE_BLOCK_ALERT_DIALOG = "hide_block_alert_dialog" const val HIDE_BLOCK_ALERT_DIALOG = "hide_block_alert_dialog"
const val USE_PROXY = "use_proxy" const val USE_PROXY = "use_proxy"
const val PROXY_PORT = "proxy_port"
val LAST_READ: (String) -> String = { route -> "last_read_route_$route" } 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)) putString(PrefKeys.LATEST_CONTACT_LIST, Event.gson.toJson(account.backupContactList))
putBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, account.hideDeleteRequestDialog) putBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, account.hideDeleteRequestDialog)
putBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, account.hideBlockAlertDialog) putBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, account.hideBlockAlertDialog)
println(account.proxy != null)
putBoolean(PrefKeys.USE_PROXY, account.proxy != null) putBoolean(PrefKeys.USE_PROXY, account.proxy != null)
putInt(PrefKeys.PROXY_PORT, account.proxyPort)
}.apply() }.apply()
} }
@ -279,7 +280,8 @@ object LocalPreferences {
val hideDeleteRequestDialog = getBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, false) val hideDeleteRequestDialog = getBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, false)
val hideBlockAlertDialog = getBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, false) val hideBlockAlertDialog = getBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, false)
val useProxy = getBoolean(PrefKeys.USE_PROXY, 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( val a = Account(
Persona(privKey = privKey?.toByteArray(), pubKey = pubKey.toByteArray()), Persona(privKey = privKey?.toByteArray(), pubKey = pubKey.toByteArray()),
@ -298,7 +300,8 @@ object LocalPreferences {
hideDeleteRequestDialog, hideDeleteRequestDialog,
hideBlockAlertDialog, hideBlockAlertDialog,
latestContactList, latestContactList,
proxy proxy,
proxyPort
) )
return a return a

View File

@ -60,7 +60,8 @@ class Account(
var hideDeleteRequestDialog: Boolean = false, var hideDeleteRequestDialog: Boolean = false,
var hideBlockAlertDialog: Boolean = false, var hideBlockAlertDialog: Boolean = false,
var backupContactList: ContactListEvent? = null, var backupContactList: ContactListEvent? = null,
var proxy: Proxy? var proxy: Proxy?,
var proxyPort: Int
) { ) {
var transientHiddenUsers: Set<String> = setOf() var transientHiddenUsers: Set<String> = setOf()

View File

@ -27,6 +27,7 @@ import androidx.compose.material.Surface
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.material.TextButton import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -241,6 +242,7 @@ fun ListContent(
var checked by remember { mutableStateOf(account.proxy != null) } var checked by remember { mutableStateOf(account.proxy != null) }
val openDialog = remember { mutableStateOf(false) } val openDialog = remember { mutableStateOf(false) }
var conectOrbotDialogOpen by remember { mutableStateOf(false) } var conectOrbotDialogOpen by remember { mutableStateOf(false) }
var proxyPort = remember { mutableStateOf(account.proxyPort.toString()) }
Column(modifier = modifier.fillMaxHeight()) { Column(modifier = modifier.fillMaxHeight()) {
if (accountUser != null) { if (accountUser != null) {
@ -310,14 +312,14 @@ fun ListContent(
if (conectOrbotDialogOpen) { if (conectOrbotDialogOpen) {
ConnectOrbotDialog( ConnectOrbotDialog(
account = account,
onClose = { conectOrbotDialogOpen = false }, onClose = { conectOrbotDialogOpen = false },
onPost = { onPost = {
conectOrbotDialogOpen = false conectOrbotDialogOpen = false
openDialog.value = false openDialog.value = false
checked = true checked = true
enableTor(account, true) enableTor(account, true, proxyPort)
} },
proxyPort
) )
} }
@ -330,7 +332,7 @@ fun ListContent(
onClick = { onClick = {
openDialog.value = false openDialog.value = false
checked = false checked = false
enableTor(account, false) enableTor(account, false, proxyPort)
} }
) { ) {
Text(text = stringResource(R.string.yes)) Text(text = stringResource(R.string.yes))
@ -351,9 +353,11 @@ fun ListContent(
private fun enableTor( private fun enableTor(
account: Account, account: Account,
checked: Boolean checked: Boolean,
portNumber: MutableState<String>
) { ) {
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) LocalPreferences.saveToEncryptedStorage(account)
ServiceManager.pause() ServiceManager.pause()
ServiceManager.start() ServiceManager.start()

View File

@ -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 pattern = Pattern.compile(".+@.+\\.[a-z]+")
val parsed = Nip19.uriToRoute(key) val parsed = Nip19.uriToRoute(key)
val pubKeyParsed = parsed?.hex?.toByteArray() 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 = val account =
if (key.startsWith("nsec")) { if (key.startsWith("nsec")) {
Account(Persona(privKey = key.bechToBytes()), proxy = proxy) Account(Persona(privKey = key.bechToBytes()), proxy = proxy, proxyPort = proxyPort)
} else if (pubKeyParsed != null) { } else if (pubKeyParsed != null) {
Account(Persona(pubKey = pubKeyParsed), proxy = proxy) Account(Persona(pubKey = pubKeyParsed), proxy = proxy, proxyPort = proxyPort)
} else if (pattern.matcher(key).matches()) { } else if (pattern.matcher(key).matches()) {
// Evaluate NIP-5 // Evaluate NIP-5
Account(Persona(), proxy = proxy) Account(Persona(), proxy = proxy, proxyPort = proxyPort)
} else { } else {
Account(Persona(Hex.decode(key)), proxy = proxy) Account(Persona(Hex.decode(key)), proxy = proxy, proxyPort = proxyPort)
} }
LocalPreferences.updatePrefsForLogin(account) LocalPreferences.updatePrefsForLogin(account)
@ -68,9 +68,9 @@ class AccountStateViewModel() : ViewModel() {
tryLoginExistingAccount() tryLoginExistingAccount()
} }
fun newKey(useProxy: Boolean) { fun newKey(useProxy: Boolean, proxyPort: Int) {
var proxy = HttpClient.initProxy(useProxy, "127.0.0.1", 9050) val proxy = HttpClient.initProxy(useProxy, "127.0.0.1", proxyPort)
val account = Account(Persona(), proxy = proxy) val account = Account(Persona(), proxy = proxy, proxyPort = proxyPort)
// saves to local preferences // saves to local preferences
LocalPreferences.updatePrefsForLogin(account) LocalPreferences.updatePrefsForLogin(account)
startUI(account) startUI(account)

View File

@ -1,5 +1,6 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn package com.vitorpamplona.amethyst.ui.screen.loggedIn
import android.widget.Toast
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -15,12 +16,11 @@ import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Surface import androidx.compose.material.Surface
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType 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.material.MaterialRichText
import com.halilibo.richtext.ui.resolveDefaults import com.halilibo.richtext.ui.resolveDefaults
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.ui.actions.CloseButton import com.vitorpamplona.amethyst.ui.actions.CloseButton
import com.vitorpamplona.amethyst.ui.actions.PostButton import com.vitorpamplona.amethyst.ui.actions.PostButton
import kotlinx.coroutines.launch
@Composable @Composable
fun ConnectOrbotDialog(account: Account, onClose: () -> Unit, onPost: () -> Unit) { fun ConnectOrbotDialog(onClose: () -> Unit, onPost: () -> Unit, portNumber: MutableState<String>) {
var portNumber by remember { mutableStateOf("9050") } val context = LocalContext.current
val scope = rememberCoroutineScope()
Dialog( Dialog(
onDismissRequest = onClose, onDismissRequest = onClose,
properties = DialogProperties(usePlatformDefaultWidth = false) properties = DialogProperties(usePlatformDefaultWidth = false)
@ -62,6 +62,19 @@ fun ConnectOrbotDialog(account: Account, onClose: () -> Unit, onPost: () -> Unit
PostButton( PostButton(
onPost = { onPost = {
try {
Integer.parseInt(portNumber.value)
} catch (_: Exception) {
scope.launch {
Toast.makeText(
context,
"Invalid port number",
Toast.LENGTH_LONG
).show()
}
return@PostButton
}
onPost() onPost()
}, },
isActive = true isActive = true
@ -84,8 +97,8 @@ fun ConnectOrbotDialog(account: Account, onClose: () -> Unit, onPost: () -> Unit
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
OutlinedTextField( OutlinedTextField(
value = portNumber, value = portNumber.value,
onValueChange = { portNumber = it }, onValueChange = { portNumber.value = it },
keyboardOptions = KeyboardOptions.Default.copy( keyboardOptions = KeyboardOptions.Default.copy(
capitalization = KeyboardCapitalization.None, capitalization = KeyboardCapitalization.None,
keyboardType = KeyboardType.Number keyboardType = KeyboardType.Number

View File

@ -39,6 +39,7 @@ import androidx.compose.ui.unit.sp
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.qrcode.SimpleQrCodeScanner import com.vitorpamplona.amethyst.ui.qrcode.SimpleQrCodeScanner
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ConnectOrbotDialog
import java.util.* import java.util.*
@OptIn(ExperimentalComposeUiApi::class) @OptIn(ExperimentalComposeUiApi::class)
@ -57,6 +58,8 @@ fun LoginPage(
mutableStateOf(false) mutableStateOf(false)
} }
val useProxy = remember { mutableStateOf(false) } val useProxy = remember { mutableStateOf(false) }
val proxyPort = remember { mutableStateOf("9050") }
var connectOrbotDialogOpen by remember { mutableStateOf(false) }
Column( Column(
modifier = Modifier modifier = Modifier
@ -160,7 +163,7 @@ fun LoginPage(
keyboardActions = KeyboardActions( keyboardActions = KeyboardActions(
onGo = { onGo = {
try { try {
accountViewModel.startUI(key.value.text, useProxy.value) accountViewModel.startUI(key.value.text, useProxy.value, proxyPort.value.toInt())
} catch (e: Exception) { } catch (e: Exception) {
errorMessage = context.getString(R.string.invalid_key) errorMessage = context.getString(R.string.invalid_key)
} }
@ -227,11 +230,26 @@ fun LoginPage(
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox( Checkbox(
checked = useProxy.value, checked = useProxy.value,
onCheckedChange = { useProxy.value = it } onCheckedChange = {
if (it) {
connectOrbotDialogOpen = true
}
}
) )
Text(stringResource(R.string.connect_via_tor)) 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)) Spacer(modifier = Modifier.height(20.dp))
@ -250,7 +268,7 @@ fun LoginPage(
if (acceptedTerms.value && key.value.text.isNotBlank()) { if (acceptedTerms.value && key.value.text.isNotBlank()) {
try { try {
accountViewModel.startUI(key.value.text, useProxy.value) accountViewModel.startUI(key.value.text, useProxy.value, proxyPort.value.toInt())
} catch (e: Exception) { } catch (e: Exception) {
errorMessage = context.getString(R.string.invalid_key) errorMessage = context.getString(R.string.invalid_key)
} }
@ -278,7 +296,7 @@ fun LoginPage(
.fillMaxWidth(), .fillMaxWidth(),
onClick = { onClick = {
if (acceptedTerms.value) { if (acceptedTerms.value) {
accountViewModel.newKey(useProxy.value) accountViewModel.newKey(useProxy.value, proxyPort.value.toInt())
} else { } else {
termsAcceptanceIsRequired = termsAcceptanceIsRequired =
context.getString(R.string.acceptance_of_terms_is_required) context.getString(R.string.acceptance_of_terms_is_required)