From 3e32a91e34691fccc29107d1bbd23fda64bbaa67 Mon Sep 17 00:00:00 2001 From: maxmoney21m Date: Sat, 4 Mar 2023 03:02:04 +0800 Subject: [PATCH] Move nsec backup to Drawer and Dialog, organize Drawer --- .../amethyst/ui/navigation/DrawerContent.kt | 182 ++++++++++-------- .../amethyst/ui/navigation/Routes.kt | 2 +- .../ui/screen/loggedIn/AccountBackupDialog.kt | 123 ++++++++++++ .../ui/screen/loggedIn/ProfileScreen.kt | 39 ---- app/src/main/res/drawable-anydpi/ic_key.xml | 11 ++ .../main/res/drawable-anydpi/ic_logout.xml | 12 ++ .../main/res/drawable-anydpi/ic_security.xml | 11 ++ app/src/main/res/drawable-hdpi/ic_key.png | Bin 0 -> 380 bytes app/src/main/res/drawable-hdpi/ic_logout.png | Bin 0 -> 326 bytes .../main/res/drawable-hdpi/ic_security.png | Bin 0 -> 510 bytes app/src/main/res/drawable-mdpi/ic_key.png | Bin 0 -> 250 bytes app/src/main/res/drawable-mdpi/ic_logout.png | Bin 0 -> 199 bytes .../main/res/drawable-mdpi/ic_security.png | Bin 0 -> 339 bytes app/src/main/res/drawable-xhdpi/ic_key.png | Bin 0 -> 443 bytes app/src/main/res/drawable-xhdpi/ic_logout.png | Bin 0 -> 361 bytes .../main/res/drawable-xhdpi/ic_security.png | Bin 0 -> 662 bytes app/src/main/res/drawable-xxhdpi/ic_key.png | Bin 0 -> 675 bytes .../main/res/drawable-xxhdpi/ic_logout.png | Bin 0 -> 509 bytes .../main/res/drawable-xxhdpi/ic_security.png | Bin 0 -> 991 bytes app/src/main/res/values/strings.xml | 10 +- 20 files changed, 271 insertions(+), 119 deletions(-) create mode 100644 app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountBackupDialog.kt create mode 100644 app/src/main/res/drawable-anydpi/ic_key.xml create mode 100644 app/src/main/res/drawable-anydpi/ic_logout.xml create mode 100644 app/src/main/res/drawable-anydpi/ic_security.xml create mode 100644 app/src/main/res/drawable-hdpi/ic_key.png create mode 100644 app/src/main/res/drawable-hdpi/ic_logout.png create mode 100644 app/src/main/res/drawable-hdpi/ic_security.png create mode 100644 app/src/main/res/drawable-mdpi/ic_key.png create mode 100644 app/src/main/res/drawable-mdpi/ic_logout.png create mode 100644 app/src/main/res/drawable-mdpi/ic_security.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_key.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_logout.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_security.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_key.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_logout.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_security.png 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 acdc717d0..5964847c8 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 @@ -7,12 +7,13 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width -import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.Divider import androidx.compose.material.Icon @@ -36,8 +37,8 @@ import androidx.compose.ui.graphics.painter.BitmapPainter 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.font.FontWeight.Companion.W500 import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavController @@ -45,14 +46,14 @@ import androidx.navigation.NavHostController import com.vitorpamplona.amethyst.BuildConfig import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.RoboHashCache +import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.ui.components.AsyncImageProxy import com.vitorpamplona.amethyst.ui.components.ResizeImage import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel +import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountBackupDialog import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.launch -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.platform.LocalContext @Composable fun DrawerContent(navController: NavHostController, @@ -88,7 +89,8 @@ fun DrawerContent(navController: NavHostController, modifier = Modifier .fillMaxWidth() .weight(1F), - accountStateViewModel + accountStateViewModel, + account, ) BottomContent(account.userProfile(), scaffoldState, navController) @@ -155,38 +157,44 @@ fun ProfileContent(baseAccountUser: User, modifier: Modifier = Modifier, scaffol if (accountUser.bestDisplayName() != null) { Text( accountUser.bestDisplayName() ?: "", - modifier = Modifier.padding(top = 7.dp).clickable(onClick = { - accountUser.let { - navController.navigate("User/${it.pubkeyHex}") - } - coroutineScope.launch { - scaffoldState.drawerState.close() - } - }), + modifier = Modifier + .padding(top = 7.dp) + .clickable(onClick = { + accountUser.let { + navController.navigate("User/${it.pubkeyHex}") + } + coroutineScope.launch { + scaffoldState.drawerState.close() + } + }), fontWeight = FontWeight.Bold, fontSize = 18.sp ) } if (accountUser.bestUsername() != null) { Text(" @${accountUser.bestUsername()}", color = Color.LightGray, - modifier = Modifier.padding(top = 15.dp).clickable(onClick = { - accountUser.let { - navController.navigate("User/${it.pubkeyHex}") - } - coroutineScope.launch { - scaffoldState.drawerState.close() - } - }) + modifier = Modifier + .padding(top = 15.dp) + .clickable(onClick = { + accountUser.let { + navController.navigate("User/${it.pubkeyHex}") + } + coroutineScope.launch { + scaffoldState.drawerState.close() + } + }) ) } - Row(modifier = Modifier.padding(top = 15.dp).clickable(onClick = { - accountUser.let { - navController.navigate("User/${it.pubkeyHex}") - } - coroutineScope.launch { - scaffoldState.drawerState.close() - } - })) { + Row(modifier = Modifier + .padding(top = 15.dp) + .clickable(onClick = { + accountUser.let { + navController.navigate("User/${it.pubkeyHex}") + } + coroutineScope.launch { + scaffoldState.drawerState.close() + } + })) { Row() { Text("${accountUserFollows.follows.size}", fontWeight = FontWeight.Bold) Text(stringResource(R.string.following)) @@ -206,66 +214,84 @@ fun ListContent( navController: NavHostController, scaffoldState: ScaffoldState, modifier: Modifier, - accountViewModel: AccountStateViewModel + accountViewModel: AccountStateViewModel, + account: Account, ) { val coroutineScope = rememberCoroutineScope() + var backupDialogOpen by remember { mutableStateOf(false) } - Column(modifier = modifier) { - LazyColumn() { - item { - if (accountUser != null) - NavigationRow(navController, - scaffoldState, - "User/${accountUser.pubkeyHex}", - Route.Profile.icon, - stringResource(R.string.profile) - ) + Column(modifier = modifier.fillMaxHeight()) { + if (accountUser != null) + NavigationRow( + title = stringResource(R.string.profile), + icon = Route.Profile.icon, + tint = MaterialTheme.colors.primary, + navController = navController, + scaffoldState = scaffoldState, + route = "User/${accountUser.pubkeyHex}", + ) - Divider( - modifier = Modifier.padding(bottom = 15.dp), - thickness = 0.25.dp - ) - Column(modifier = modifier.padding(horizontal = 25.dp)) { - Row(modifier = Modifier.clickable(onClick = { - navController.navigate(Route.Filters.route) - coroutineScope.launch { - scaffoldState.drawerState.close() - } - })) { - Text( - text = stringResource(R.string.security_filters), - fontSize = 18.sp, - fontWeight = W500 - ) - } - Row(modifier = Modifier.clickable(onClick = { accountViewModel.logOff() })) { - Text( - text = stringResource(R.string.log_out), - modifier = Modifier.padding(vertical = 15.dp), - fontSize = 18.sp, - fontWeight = W500 - ) - } - } - } - } + Divider(thickness = 0.25.dp) + + NavigationRow( + title = stringResource(R.string.security_filters), + icon = Route.Filters.icon, + tint = MaterialTheme.colors.onBackground, + navController = navController, + scaffoldState = scaffoldState, + route = Route.Filters.route, + ) + + Divider(thickness = 0.25.dp) + + IconRow( + title = "Backup Keys", + icon = R.drawable.ic_key, + tint = MaterialTheme.colors.onBackground, + onClick = { backupDialogOpen = true } + ) + + Spacer(modifier = Modifier.weight(1f)) + + IconRow( + "Logout", + R.drawable.ic_logout, + MaterialTheme.colors.onBackground, + onClick = { accountViewModel.logOff() } + ) + } + + if (backupDialogOpen) { + AccountBackupDialog(account, onClose = { backupDialogOpen = false }) } } @Composable -fun NavigationRow(navController: NavHostController, scaffoldState: ScaffoldState, route: String, icon: Int, title: String) { +fun NavigationRow( + title: String, + icon: Int, + tint: Color, + navController: NavHostController, + scaffoldState: ScaffoldState, + route: String, +) { val coroutineScope = rememberCoroutineScope() val currentRoute = currentRoute(navController) + IconRow(title, icon, tint, onClick = { + if (currentRoute != route) { + navController.navigate(route) + } + coroutineScope.launch { + scaffoldState.drawerState.close() + } + }) +} + +@Composable +fun IconRow(title: String, icon: Int, tint: Color, onClick: () -> Unit) { Row(modifier = Modifier .fillMaxWidth() - .clickable(onClick = { - if (currentRoute != route) { - navController.navigate(route) - } - coroutineScope.launch { - scaffoldState.drawerState.close() - } - }) + .clickable(onClick = onClick) ) { Row( modifier = Modifier @@ -276,7 +302,7 @@ fun NavigationRow(navController: NavHostController, scaffoldState: ScaffoldState Icon( painter = painterResource(icon), null, modifier = Modifier.size(22.dp), - tint = MaterialTheme.colors.primary + tint = tint ) Text( modifier = Modifier.padding(start = 16.dp), diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt index 12595420b..94fc1b4ff 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt @@ -53,7 +53,7 @@ sealed class Route( buildScreen = { acc, accSt, nav -> { _ -> ChatroomListScreen(acc, nav) }} ) - object Filters : Route("Filters", R.drawable.ic_dm, + object Filters : Route("Filters", R.drawable.ic_security, buildScreen = { acc, accSt, nav -> { _ -> FiltersScreen(acc, nav) }} ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountBackupDialog.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountBackupDialog.kt new file mode 100644 index 000000000..e56431e08 --- /dev/null +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountBackupDialog.kt @@ -0,0 +1,123 @@ +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 +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Button +import androidx.compose.material.ButtonDefaults +import androidx.compose.material.Icon +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Surface +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Key +import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalClipboardManager +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties +import com.halilibo.richtext.markdown.Markdown +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 kotlinx.coroutines.launch +import nostr.postr.toNsec + +@Composable +fun AccountBackupDialog(account: Account, onClose: () -> Unit) { + Dialog( + onDismissRequest = onClose, + properties = DialogProperties(usePlatformDefaultWidth = false), + ) { + Surface(modifier = Modifier.fillMaxSize()) { + Column( + modifier = Modifier + .background(MaterialTheme.colors.background) + .fillMaxSize(), + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(10.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + CloseButton(onCancel = onClose) + } + + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + MaterialRichText( + style = RichTextStyle().resolveDefaults(), + ) { + Markdown( + content = stringResource(R.string.account_backup_tips_md), + ) + } + + Spacer(modifier = Modifier.height(15.dp)) + + NSecCopyButton(account) + } + } + } + } +} + +@Composable +private fun NSecCopyButton( + account: Account +) { + val clipboardManager = LocalClipboardManager.current + val context = LocalContext.current + val scope = rememberCoroutineScope() + + Button( + modifier = Modifier.padding(horizontal = 3.dp), + onClick = { + account.loggedIn.privKey?.let { + clipboardManager.setText(AnnotatedString(it.toNsec())) + scope.launch { + Toast.makeText( + context, + context.getString(R.string.secret_key_copied_to_clipboard), + Toast.LENGTH_SHORT + ).show() + } + } + }, + shape = RoundedCornerShape(20.dp), colors = ButtonDefaults.buttonColors( + backgroundColor = MaterialTheme.colors.primary + ) + ) { + Icon( + tint = Color.White, + imageVector = Icons.Default.Key, + contentDescription = stringResource(R.string.copies_the_nsec_id_your_password_to_the_clipboard_for_backup) + ) + Text("Copy Secret Key", color = MaterialTheme.colors.onPrimary) + } +} diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt index b16677610..df52949e4 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt @@ -10,7 +10,6 @@ import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Bolt import androidx.compose.material.icons.filled.EditNote -import androidx.compose.material.icons.filled.Key import androidx.compose.material.icons.filled.Link import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.filled.Share @@ -78,7 +77,6 @@ import com.vitorpamplona.amethyst.ui.screen.UserFeedView import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import nostr.postr.toNsec @OptIn(ExperimentalPagerApi::class) @Composable @@ -337,10 +335,6 @@ private fun ProfileHeader( .padding(bottom = 3.dp)) { MessageButton(baseUser, navController) - if (accountUser == baseUser && account.isWriteable()) { - NSecCopyButton(account) - } - NPubCopyButton(baseUser) if (accountUser == baseUser) { @@ -637,40 +631,7 @@ fun TabRelays(user: User, accountViewModel: AccountViewModel, navController: Nav } } -@Composable -private fun NSecCopyButton( - account: Account -) { - val clipboardManager = LocalClipboardManager.current - var popupExpanded by remember { mutableStateOf(false) } - Button( - modifier = Modifier - .padding(horizontal = 3.dp) - .width(50.dp), - onClick = { popupExpanded = true }, - shape = RoundedCornerShape(20.dp), - colors = ButtonDefaults - .buttonColors( - backgroundColor = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) - ) - ) { - Icon( - tint = Color.White, - imageVector = Icons.Default.Key, - contentDescription = stringResource(R.string.copies_the_nsec_id_your_password_to_the_clipboard_for_backup) - ) - - DropdownMenu( - expanded = popupExpanded, - onDismissRequest = { popupExpanded = false } - ) { - DropdownMenuItem(onClick = { account.loggedIn.privKey?.let { clipboardManager.setText(AnnotatedString(it.toNsec())) }; popupExpanded = false }) { - Text(stringResource(R.string.copy_private_key_to_the_clipboard)) - } - } - } -} @Composable private fun NPubCopyButton( diff --git a/app/src/main/res/drawable-anydpi/ic_key.xml b/app/src/main/res/drawable-anydpi/ic_key.xml new file mode 100644 index 000000000..0db74fa0d --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_key.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable-anydpi/ic_logout.xml b/app/src/main/res/drawable-anydpi/ic_logout.xml new file mode 100644 index 000000000..6555606de --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_logout.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/drawable-anydpi/ic_security.xml b/app/src/main/res/drawable-anydpi/ic_security.xml new file mode 100644 index 000000000..717b89c05 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_security.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable-hdpi/ic_key.png b/app/src/main/res/drawable-hdpi/ic_key.png new file mode 100644 index 0000000000000000000000000000000000000000..81ef03db80d47008d6b2394c207b9644fa73f7c2 GIT binary patch literal 380 zcmV-?0fYXDP)H_=P_mn#{ia_i^rzhvE$s2q08I;pvB^JE57@K<~WY? a&)flbHGXVp^eyB70000C9@!Z5gW-(B?BUa%rd}RXps!?7LvhtW*Oiu1oE(-sbxTf z5P%dPt0GFs%ufsPJ~S8ZazS3vYbm7(cex-BUn^2i9;_zZ>p zX5RSTV2D91=c`7N?j+$e3*|!2B6z?|@EBXpQQv3WADkTH+Mj(aTij&ND$5B-c;TH-*I_R#T84kYTZih4Nnu^0*e{ zaV^N>&lQwD4_lL9&p3}oJ3cWKe}+cDiNzwuc`Rh-e^qgQL4d^~#yLvxF@?uXtn<&D zagGwQT>HTv8a!?yfd>}!jB}LG4+;$)H^EVZ1wG>&OrqY5o+7@Wx4|`zXJ~d#Jnph| zmN;I+E#MvYOeE2fg)QUQ0m-pV>PQ^g3@xzEIFz$^$v75pJgyh_4udCbX1=?uf^yu8 zDh6lsE&ElG0=u{NZ_8gUv0XU|MCN8H`(Rc^n`)jJ|8u8?ELiL*y*%n3zHHZ7CJQuW zL1=>Px#07*qoM6N<$f?1a0 ATmS$7 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_key.png b/app/src/main/res/drawable-mdpi/ic_key.png new file mode 100644 index 0000000000000000000000000000000000000000..67341e7e157c2f11d8be2af586be98c575ceabe4 GIT binary patch literal 250 zcmV<22B6FRNAPjStw zNsXuvnLwH>&6$6qA~j|vI~jaNDI=N^?H7I+QNAZ#GT!|qE}3U-CX+ZwTz&+N&vc3P zZ=)b_S)AbP*G!lz?PoK1i)e)J9h_Hh*3q#$p5XwkU-a+l?EnA(07*qoM6N<$f}&1p A^Z)<= literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_logout.png b/app/src/main/res/drawable-mdpi/ic_logout.png new file mode 100644 index 0000000000000000000000000000000000000000..dc2dabde5eb1761a359e093eca5b725b84facc11 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjeV#6kAr*0Nryk^OP~dTuJR~d8 zP*liXRv>jg?(Vg32UuI{ygTG7Je@CH_&-VRz)nss!Jh($&ON`ms)&z`^Sw|Bd&ZwI zf#f?&PW|KUZg~IOX1SLRQ)6?uN0KPVge7Vx{+fT)`03MdVXG3aM$86|AC-{{3Jxj> xSXiul*c8fO9CP5e&88)xPi1&|{}rg2>XmQlFWYosMGVko44$rjF6*2UngCdjO`HG# literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_security.png b/app/src/main/res/drawable-mdpi/ic_security.png new file mode 100644 index 0000000000000000000000000000000000000000..3dc8abccedc4ff47494f035b24b59a6f4bcbb6be GIT binary patch literal 339 zcmV-Z0j&OsP)$-K$ z^8ff9+oDYcDinybh_A<6f zG~6IEcx{^b1{Mp~In5Z^6QP3K<8s&#*%MI|n16$kz%0GN(2ixYM}d`xIx@HxA?yCc zflT%&uo+QD2G=5Rws0VmJqkSmkioSGeasx$1Ejv(CVisxnph8r=ZISN^(abD!Fn09 zS}V?8Av4)?@K6IBhCUqW@T9dO^iN|Zb*vf38uj@Bm3K5JTiJecAv3002ovPDHLkV1oa-mAwD} literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_key.png b/app/src/main/res/drawable-xhdpi/ic_key.png new file mode 100644 index 0000000000000000000000000000000000000000..79ffc2e6744e9fb3ea053e9da09d10c587150232 GIT binary patch literal 443 zcmV;s0Yv_ZP)Tog4284qI@{bK63ixBF4ApthIX4R-S)QeQ*FsL^9NyoO8%s$pxA~tKQKO>9LI4S z$8nr2UDusM2m}3okUsmq|AFZGf&VymwspJ1#^1$oNyw#|H+!F5ATw7oHCmGu8mabX z@3$#15HU7OyA6V8eqv~eHXj7`e7|hlq%>~&PLy6)#7P&Gf2pZak7x(a{=@)8v2ShM zf*5jaovLsDi6s+*eXuBJUO^(_<~giR9Jyb`v)g+lCnp)K@f6FK>4TWD$?{F9eBZXSf=e@4^hLGB>ye>=?N zAlQ7e1>v?l*&t%&3h}&op|l0~L5o|7n8}KGoq2$n%C!V@g?rg%PMg%`6Y+ZULRhz* zzS{c(7>k(~I6mLJ5L?Q*dda{VVD^@5C+=MLH81ejBm0tSA=mEtL%;(WNOyf=)Aa-Y lA+|}+?>LU*IF94|;R$kXlb_%7NR$8o002ovPDHLkV1iw>(m((J literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_logout.png b/app/src/main/res/drawable-xhdpi/ic_logout.png new file mode 100644 index 0000000000000000000000000000000000000000..10fd5751c309573eb28cddc24d880b0cc876a40f GIT binary patch literal 361 zcmV-v0ha!WP)b;@6ht{hT2A40Lz_dSrA-b(3oWRvolzLj8CVcD2lgZ znx>DK@0eR_?b$Q*PDkP6;5&nC9r~v;&+`vM^bGyeX~uV7L;rMk570{$*qbV_f%xXT zYWVslMi)@<*IAYlBMU^}FP_(3f`-(cMA&ou@;`WHR|%R?cVjO>BkCDgOVEUR7Pb;J zpq`1P1UFMBT%R?oOK>A~!u6T6ssuMtCtRO7hc2)xyx>Oandn2@7H+6khZo#TJqt^C zK?CX;*uo2%PTP z-Wn;)6e~W|DfnKw|_}Wv6si=@mKl#d^jB5>ga#A?UM7(PATfD6n9$+ePQ8^ zylAZE(6c$Em|ZF6zENZ-Hg`wwr!)083u2-Nx5+wL>TeYDTE_jJdY#*s@+s>i+TXVG z8_wsrV8++UA=uy6O0#{;@x4i}6N(s#BWH;7vZ2?70)_n@fsSnGb)lfu-x27^hF+Ip zfk96;^tucS40^Jm*JW5>(31_lF2e$Yo^0rK85S7yWJ9mZu)v@v8+u)a1qMCY(CacR zFzCsKUYB8kK~FaHx(o{pda|L{h0p!m9)*QuqFU&6vB%^Ovfj`eK~K50L$z>>%Q+9A zJUITS9jOB-k~%sn4dOkqC zqfC6FtT%Le=v#?;zG~o@FqCCNrw1?Js)1v|=&dVxWl=q$a|wNHt>Gqk3e6_L^ z`j%*%{dC}VuT~oFeUiPg z(NohZUP;}!B4idc9TQgkAC6yT;V!Z7e8}T`p~cxc^Kx_S>e!hJ-=R6*TJghI^>VJ> z_jB|dL^Vfez4`8KTKt4|7+DkE&rx!0UVP2S^U~0B&YGw_N-=*~;9N9TbLcrcrMTTv wyV$n=pNqD}-Vy!UsKxnYufN_I|7HdL0m}ayRE`W09smFU07*qoM6N<$f__X;)Bpeg literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_key.png b/app/src/main/res/drawable-xxhdpi/ic_key.png new file mode 100644 index 0000000000000000000000000000000000000000..e0cdfef0ab6512e256235cec672d450d15b7766c GIT binary patch literal 675 zcmV;U0$lxxP)8qv5QJU3PV4&G10)@gJV@N8joY+w>v!@Svy90G*ja4%wt6k6B?=CQNu7!6i zp^sgfwB^cS!6fd#YH&RBB(_%S^OeU@C26oH9{dee|LGRpT6TZ)Bk3jQz-Rn#My|TI z8gArx&_ha-d2bz895E^OgWHd2GUwg!UU8TcIeF|vgrWcCVqpy2z6vl29&DeY=48yI z$V%E&IEZ+Rqo8JRk^#-$0%+Tl?`{g2l!D(l0c(xr@7>0?lG`NDz_H4>U6jB|y_sAl zHIB!M@+hARa&X=nG-(ny=o7b@3+Jsxqb6~1pSaCjIBzW)Eg_!!l!I@vVROKP7wPGF zJ@7F5xr42RK6xA^<)p{V$x!@y=47JVV~KKMo&po~n3J*i z_00ix@=QK{EEW2QoQPFnCT+HokbAf0lx$IxrfSaaXxIDsi|cjKZb?`E+&La>SuhuE zIp1MH?XXkg&1%WDpf|-&@DS5H(ogV&5JCtcgb+dqA%qYQ%0Ff(uFsf>j7I?ac{IX@Wu?lY^}{h|ihs9aQ=!VBLy-cQ4JQQ-ZwGXFva0EYUW< zQ0D(SxqG>Hn?41yUT(9F2=86|kZ+ss~*9(4X}fZf`{lDPTXeN=eOTPL_W#-U|I&Ww${b~W&lJ+MxZ;Iu!>Ixh{xWv0qk%Se zBv;6|e`E?@pl8uF-GZs~aNwR3A}jd&9;NmeC+}n z!SR@9iP((wMl!Av2rIat2FFUNcZs(z=Bup-(bu+r00!ck*B>K~$gYX5zZcYX oL^f~YzB{WHRFp%aVcK8jR<)bS-%Pre0i%_{)78&qol`;+0QG9&hX4Qo literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_security.png b/app/src/main/res/drawable-xxhdpi/ic_security.png new file mode 100644 index 0000000000000000000000000000000000000000..dba255c73a9a08bbb1d8a13f0e8abae84f49d4d3 GIT binary patch literal 991 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2U|#0w;uum9_jdOF{>u&mZo$i! zE%oabu@>4Ae%YzoR9AP)mU7+yy1xaZqiid$e|zI2q+WSRJz&$k=XY-;$Jf0n^Pgu^ z$>O*C^7F?Ze*|Cr|MQRYB(dcC-~W35`tEfn~pI zS7pD@ugrf~oLyX8d+JvFCA0ULM)!ZNDxPB+{x(?mZ|b`If|~4SHS4x~o4)0(_%)R~ z=L`#LR~5g~_kQqAFmkv5<^Y4~LG_VL*{*GQ#yT-w$A6xiHF4o>9&Tgr-=~Eltc^-$ zCq6WM_x#hkH(eZe(;{xfPH=Qjd0}?=(7PrcD<$Xcl451zDHjAKcb(m^VYfna--!#k zZLN1%B}-gD2ENfdu|OGQMq;@mn=IJi-P}emI(TScRLGZomUq*>Ow(cwT)11bw!oo% zk!9hUnY#J`_rK475fCG;;khqJKy+8M=G)zJ&m)X~X|y-3xNz6&<%{pXM4s8Nyy4EZ z$f;cW*P1>)*WyPv)HFJ{_Uc}Vi|ET;RCX;)TzBP(+`@d_t#K=BpI4M;Sw9f`buH+Xtye^`+C+E3*z6TwPjt)JDp#on z-P36Z=>J7KH4{L;=T{zMcFSRz208Aw6CbfVwaQ*clj#ah3TAIgX4Zn z)IHUjSoYw6Y! z#ilmD1+)DFUt69E{q4s&_qE*gx@%`8<2qhlTvfZH>b~Z~jUH<(FU`NdZ^oYUlEs(1 zjW6x;SW|9ue@a-tRH`tLyU8QDH}9zbhAYKpn=O=`_ecC?yZu4W#m& znxC^>bn8p*B$JuVe$0LsW-XlddVSBjK0oHWH;Xo9FP55ZxAfVC(9F!wM-T1EioUix zx~=un#Q>YHZL23AvpILj=i*%bm%juz{ByamXvN0+;r*4Lo}3i<&+x2NQS!l?6`(B4 N;OXk;vd$@?2>|%H?qmP} literal 0 HcmV?d00001 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 952cd426c..0871a623f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -118,7 +118,7 @@ Website Lightning Address Copies the Nsec ID (your password) to the clipboard for backup - Copy Private Key to the Clipboard + Copy Secret Key to the Clipboard Copies the public key to the clipboard for sharing Copy Public Key (NPub) to the Clipboard Send a Direct Message @@ -177,4 +177,12 @@ Report Hateful speech Report Nudity / Porn others + + ## Key Backup and Safety Tips + \n\nYour account is secured by a secret key. The key is long random string starting with **nsec1**. Anyone who has access to your secret key can publish content using your identity. + \n\n- Do **not** put your secret key in any website or software you do not trust. + \n- Amethyst developers will **never** ask you for your secret key. + \n- **Do** keep a secure backup of your secret key for account recovery. We recommend using a password manager. + + Secret key (nsec) copied to clipboard \ No newline at end of file