From 69c3c411965aa51da08582c852fd795ccec9130c Mon Sep 17 00:00:00 2001 From: greenart7c3 <115044884+greenart7c3@users.noreply.github.com> Date: Wed, 5 Jul 2023 17:32:50 -0300 Subject: [PATCH] move drawer options to settings screen --- .../amethyst/ui/navigation/DrawerContent.kt | 150 ------------------ .../ui/screen/loggedIn/SettingsScreen.kt | 148 ++++++++++++++++- 2 files changed, 144 insertions(+), 154 deletions(-) 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 b69c5d5c3..7018c4138 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 @@ -1,6 +1,5 @@ package com.vitorpamplona.amethyst.ui.navigation -import android.content.Context import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -20,7 +19,6 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.verticalScroll -import androidx.compose.material.AlertDialog import androidx.compose.material.Divider import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.Icon @@ -30,10 +28,8 @@ import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.ScaffoldState import androidx.compose.material.Surface import androidx.compose.material.Text -import androidx.compose.material.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.MutableState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState @@ -46,30 +42,21 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.lifecycle.viewmodel.compose.viewModel import coil.compose.AsyncImage import com.vitorpamplona.amethyst.BuildConfig -import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.ServiceManager -import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.HttpClient -import com.vitorpamplona.amethyst.ui.actions.NewRelayListView import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.screen.RelayPoolViewModel -import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountBackupDialog import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.amethyst.ui.screen.loggedIn.ConnectOrbotDialog import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer import com.vitorpamplona.amethyst.ui.theme.Size16dp import com.vitorpamplona.amethyst.ui.theme.placeholderText @@ -299,19 +286,7 @@ fun ListContent( ) { val accountState by accountViewModel.accountLiveData.observeAsState() val account = remember(accountState) { accountState?.account } ?: return - val coroutineScope = rememberCoroutineScope() - var backupDialogOpen by remember { mutableStateOf(false) } - var checked by remember { mutableStateOf(account.proxy != null) } - var disconnectTorDialog by remember { mutableStateOf(false) } - var conectOrbotDialogOpen by remember { mutableStateOf(false) } - var proxyPort = remember { mutableStateOf(account.proxyPort.toString()) } - - val relayViewModel: RelayPoolViewModel = viewModel { RelayPoolViewModel() } - - var wantsToEditRelays by remember { - mutableStateOf(false) - } Column( modifier = modifier @@ -336,25 +311,6 @@ fun ListContent( route = Route.Bookmarks.route ) - IconRowRelays( - relayViewModel = relayViewModel, - onClick = { - coroutineScope.launch { - scaffoldState.drawerState.close() - } - wantsToEditRelays = true - } - ) - - NavigationRow( - title = stringResource(R.string.security_filters), - icon = Route.BlockedUsers.icon, - tint = MaterialTheme.colors.onBackground, - nav = nav, - scaffoldState = scaffoldState, - route = Route.BlockedUsers.route - ) - NavigationRow( title = stringResource(R.string.settings), icon = Route.Settings.icon, @@ -364,42 +320,6 @@ fun ListContent( route = Route.Settings.route ) - IconRow( - title = stringResource(R.string.backup_keys), - icon = R.drawable.ic_key, - tint = MaterialTheme.colors.onBackground, - onClick = { - coroutineScope.launch { - scaffoldState.drawerState.close() - } - backupDialogOpen = true - } - ) - - val textTorProxy = if (checked) stringResource(R.string.disconnect_from_your_orbot_setup) else stringResource(R.string.connect_via_tor_short) - - IconRow( - title = textTorProxy, - icon = R.drawable.ic_tor, - tint = MaterialTheme.colors.onBackground, - onLongClick = { - coroutineScope.launch { - scaffoldState.drawerState.close() - } - conectOrbotDialogOpen = true - }, - onClick = { - if (checked) { - disconnectTorDialog = true - } else { - coroutineScope.launch { - scaffoldState.drawerState.close() - } - conectOrbotDialogOpen = true - } - } - ) - Spacer(modifier = Modifier.weight(1f)) IconRow( @@ -409,76 +329,6 @@ fun ListContent( onClick = { coroutineScope.launch { sheetState.show() } } ) } - - if (backupDialogOpen) { - AccountBackupDialog(account, onClose = { backupDialogOpen = false }) - } - - val context = LocalContext.current - - if (conectOrbotDialogOpen) { - ConnectOrbotDialog( - onClose = { conectOrbotDialogOpen = false }, - onPost = { - conectOrbotDialogOpen = false - disconnectTorDialog = false - checked = true - enableTor(account, true, proxyPort, context = context) - }, - proxyPort - ) - } - - if (disconnectTorDialog) { - AlertDialog( - title = { - Text(text = stringResource(R.string.do_you_really_want_to_disable_tor_title)) - }, - text = { - Text(text = stringResource(R.string.do_you_really_want_to_disable_tor_text)) - }, - onDismissRequest = { - disconnectTorDialog = false - }, - confirmButton = { - TextButton( - onClick = { - disconnectTorDialog = false - checked = false - enableTor(account, false, proxyPort, context) - } - ) { - Text(text = stringResource(R.string.yes)) - } - }, - dismissButton = { - TextButton( - onClick = { - disconnectTorDialog = false - } - ) { - Text(text = stringResource(R.string.no)) - } - } - ) - } - - if (wantsToEditRelays) { - NewRelayListView({ wantsToEditRelays = false }, accountViewModel, nav = nav) - } -} - -private fun enableTor( - account: Account, - checked: Boolean, - portNumber: MutableState, - context: Context -) { - account.proxyPort = portNumber.value.toInt() - account.proxy = HttpClient.initProxy(checked, "127.0.0.1", account.proxyPort) - LocalPreferences.saveToEncryptedStorage(account) - ServiceManager.pause() - ServiceManager.start(context) } @Composable diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SettingsScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SettingsScreen.kt index 9041276f1..218b80464 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SettingsScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SettingsScreen.kt @@ -8,12 +8,17 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.AlertDialog import androidx.compose.material.Button import androidx.compose.material.DropdownMenuItem import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ExposedDropdownMenuBox import androidx.compose.material.ExposedDropdownMenuDefaults +import androidx.compose.material.MaterialTheme import androidx.compose.material.Text +import androidx.compose.material.TextButton import androidx.compose.material.TextField import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState @@ -25,16 +30,26 @@ import androidx.compose.runtime.setValue 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.font.FontWeight import androidx.compose.ui.text.intl.Locale import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.core.os.LocaleListCompat +import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ServiceManager +import com.vitorpamplona.amethyst.model.Account +import com.vitorpamplona.amethyst.service.HttpClient +import com.vitorpamplona.amethyst.ui.actions.NewRelayListView +import com.vitorpamplona.amethyst.ui.navigation.IconRow +import com.vitorpamplona.amethyst.ui.navigation.IconRowRelays +import com.vitorpamplona.amethyst.ui.navigation.Route +import com.vitorpamplona.amethyst.ui.screen.RelayPoolViewModel import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer import com.vitorpamplona.amethyst.ui.theme.StdPadding +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.xmlpull.v1.XmlPullParser @@ -74,6 +89,13 @@ fun Context.getLangPreferenceDropdownEntries(): Map { return map } +fun getLanguageIndex(languageEntries: Map): Int { + var languageIndex = languageEntries.values.toTypedArray().indexOf(Locale.current.toLanguageTag()) + if (languageIndex == -1) languageIndex = languageEntries.values.toTypedArray().indexOf(Locale.current.language) + if (languageIndex == -1) languageIndex = languageEntries.values.toTypedArray().indexOf("en") + return languageIndex +} + @Composable fun SettingsScreen( accountViewModel: AccountViewModel, @@ -105,19 +127,69 @@ fun SettingsScreen( val languageEntries = context.getLangPreferenceDropdownEntries() val languageList = languageEntries.keys.toTypedArray() - var languageIndex = languageEntries.values.toTypedArray().indexOf(Locale.current.toLanguageTag()) - if (languageIndex == -1) languageIndex = languageEntries.values.toTypedArray().indexOf(Locale.current.language) - if (languageIndex == -1) languageIndex = languageEntries.values.toTypedArray().indexOf("en") + val languageIndex = getLanguageIndex(languageEntries) val selectedLanguage = remember { mutableStateOf(languageList[languageIndex]) } + val relayViewModel: RelayPoolViewModel = viewModel { RelayPoolViewModel() } + var wantsToEditRelays by remember { + mutableStateOf(false) + } + var backupDialogOpen by remember { mutableStateOf(false) } + var checked by remember { mutableStateOf(accountViewModel.account.proxy != null) } + var disconnectTorDialog by remember { mutableStateOf(false) } + var conectOrbotDialogOpen by remember { mutableStateOf(false) } + val proxyPort = remember { mutableStateOf(accountViewModel.account.proxyPort.toString()) } Column( - StdPadding, + StdPadding + .verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally ) { Section("Account preferences") + IconRowRelays( + relayViewModel = relayViewModel, + onClick = { + wantsToEditRelays = true + } + ) + + IconRow( + title = stringResource(R.string.security_filters), + icon = Route.BlockedUsers.icon, + tint = MaterialTheme.colors.onBackground, + onClick = { + nav(Route.BlockedUsers.route) + } + ) + + IconRow( + title = stringResource(R.string.backup_keys), + icon = R.drawable.ic_key, + tint = MaterialTheme.colors.onBackground, + onClick = { + backupDialogOpen = true + } + ) + + val textTorProxy = if (checked) stringResource(R.string.disconnect_from_your_orbot_setup) else stringResource(R.string.connect_via_tor_short) + IconRow( + title = textTorProxy, + icon = R.drawable.ic_tor, + tint = MaterialTheme.colors.onBackground, + onLongClick = { + conectOrbotDialogOpen = true + }, + onClick = { + if (checked) { + disconnectTorDialog = true + } else { + conectOrbotDialogOpen = true + } + } + ) + Section("Application preferences") DropDownSettings( @@ -177,6 +249,74 @@ fun SettingsScreen( } } } + if (wantsToEditRelays) { + NewRelayListView({ wantsToEditRelays = false }, accountViewModel, nav = nav) + } + if (backupDialogOpen) { + AccountBackupDialog(accountViewModel.account, onClose = { backupDialogOpen = false }) + } + if (conectOrbotDialogOpen) { + ConnectOrbotDialog( + onClose = { conectOrbotDialogOpen = false }, + onPost = { + conectOrbotDialogOpen = false + disconnectTorDialog = false + checked = true + enableTor(accountViewModel.account, true, proxyPort, context, scope) + }, + proxyPort + ) + } + + if (disconnectTorDialog) { + AlertDialog( + title = { + Text(text = stringResource(R.string.do_you_really_want_to_disable_tor_title)) + }, + text = { + Text(text = stringResource(R.string.do_you_really_want_to_disable_tor_text)) + }, + onDismissRequest = { + disconnectTorDialog = false + }, + confirmButton = { + TextButton( + onClick = { + disconnectTorDialog = false + checked = false + enableTor(accountViewModel.account, false, proxyPort, context, scope) + } + ) { + Text(text = stringResource(R.string.yes)) + } + }, + dismissButton = { + TextButton( + onClick = { + disconnectTorDialog = false + } + ) { + Text(text = stringResource(R.string.no)) + } + } + ) + } +} + +private fun enableTor( + account: Account, + checked: Boolean, + portNumber: MutableState, + context: Context, + scope: CoroutineScope +) { + account.proxyPort = portNumber.value.toInt() + account.proxy = HttpClient.initProxy(checked, "127.0.0.1", account.proxyPort) + scope.launch(Dispatchers.IO) { + LocalPreferences.saveToEncryptedStorage(account) + ServiceManager.pause() + ServiceManager.start(context) + } } @OptIn(ExperimentalMaterialApi::class)