Populate RecoveryPasswordActivity

This commit is contained in:
andrew 2023-10-20 01:45:33 +10:30
parent ef045b7e2b
commit ea0bcbe7c5
9 changed files with 185 additions and 68 deletions

View File

@ -157,7 +157,7 @@
android:label="@string/activity_edit_closed_group_title"
android:screenOrientation="portrait" />
<activity
android:name="org.thoughtcrime.securesms.onboarding.RecoveryPasswordActivity"
android:name="org.thoughtcrime.securesms.onboarding.recoverypassword.RecoveryPasswordActivity"
android:screenOrientation="portrait" />
<activity
android:name="org.thoughtcrime.securesms.contacts.SelectContactsActivity"

View File

@ -162,7 +162,7 @@ import org.thoughtcrime.securesms.mms.MediaConstraints
import org.thoughtcrime.securesms.mms.Slide
import org.thoughtcrime.securesms.mms.SlideDeck
import org.thoughtcrime.securesms.mms.VideoSlide
import org.thoughtcrime.securesms.onboarding.startRecoveryPasswordActivity
import org.thoughtcrime.securesms.onboarding.recoverypassword.startRecoveryPasswordActivity
import org.thoughtcrime.securesms.permissions.Permissions
import org.thoughtcrime.securesms.reactions.ReactionsDialogFragment
import org.thoughtcrime.securesms.reactions.any.ReactWithAnyEmojiDialogFragment

View File

@ -362,7 +362,7 @@ fun FileDetails(fileDetails: List<TitledText>) {
fun TitledErrorText(titledText: TitledText?) {
TitledText(
titledText,
valueStyle = LocalTextStyle.current.copy(color = colorDestructive)
style = LocalTextStyle.current.copy(color = colorDestructive)
)
}
@ -370,7 +370,7 @@ fun TitledErrorText(titledText: TitledText?) {
fun TitledMonospaceText(titledText: TitledText?) {
TitledText(
titledText,
valueStyle = LocalTextStyle.current.copy(fontFamily = FontFamily.Monospace)
style = LocalTextStyle.current.copy(fontFamily = FontFamily.Monospace)
)
}
@ -378,11 +378,11 @@ fun TitledMonospaceText(titledText: TitledText?) {
fun TitledText(
titledText: TitledText?,
modifier: Modifier = Modifier,
valueStyle: TextStyle = LocalTextStyle.current,
style: TextStyle = LocalTextStyle.current,
) {
titledText?.apply {
TitledView(title, modifier) {
Text(text, style = valueStyle, modifier = Modifier.fillMaxWidth())
Text(text, style = style, modifier = Modifier.fillMaxWidth())
}
}
}

View File

@ -93,7 +93,7 @@ import org.thoughtcrime.securesms.messagerequests.MessageRequestsActivity
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.notifications.PushRegistry
import org.thoughtcrime.securesms.onboarding.startRecoveryPasswordActivity
import org.thoughtcrime.securesms.onboarding.recoverypassword.startRecoveryPasswordActivity
import org.thoughtcrime.securesms.permissions.Permissions
import org.thoughtcrime.securesms.preferences.SettingsActivity
import org.thoughtcrime.securesms.showMuteDialog
@ -101,6 +101,7 @@ import org.thoughtcrime.securesms.showSessionDialog
import org.thoughtcrime.securesms.ui.AppTheme
import org.thoughtcrime.securesms.ui.OutlineButton
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.SessionShieldIcon
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
import org.thoughtcrime.securesms.ui.h8
import org.thoughtcrime.securesms.ui.small
@ -365,12 +366,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
Row {
Text("Save your recovery password", style = MaterialTheme.typography.h8)
Spacer(Modifier.requiredWidth(8.dp))
Icon(
painter = painterResource(R.drawable.session_shield),
contentDescription = null,
modifier = Modifier.align(Alignment.CenterVertically)
.wrapContentSize(unbounded = true)
)
SessionShieldIcon()
}
Text("Save your recovery password to make sure you don't lose access to your account.", style = MaterialTheme.typography.small)
}

View File

@ -1,50 +0,0 @@
package org.thoughtcrime.securesms.onboarding
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import network.loki.messenger.R
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsignal.crypto.MnemonicCodec
import org.session.libsignal.utilities.hexEncodedPrivateKey
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
import org.thoughtcrime.securesms.crypto.MnemonicUtilities
class RecoveryPasswordActivity : BaseActionBarActivity() {
private val seed by lazy {
var hexEncodedSeed = IdentityKeyUtil.retrieve(this, IdentityKeyUtil.LOKI_SEED)
if (hexEncodedSeed == null) {
hexEncodedSeed = IdentityKeyUtil.getIdentityKeyPair(this).hexEncodedPrivateKey // Legacy account
}
val loadFileContents: (String) -> String = { fileName ->
MnemonicUtilities.loadFileContents(this, fileName)
}
MnemonicCodec(loadFileContents).encode(hexEncodedSeed!!, MnemonicCodec.Language.Configuration.english)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportActionBar!!.title = resources.getString(R.string.activity_recovery_password)
}
private fun revealSeed() {
TextSecurePreferences.setHasViewedSeed(this, true)
}
private fun copySeed() {
revealSeed()
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("Seed", seed)
clipboard.setPrimaryClip(clip)
Toast.makeText(this, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show()
}
}
fun Context.startRecoveryPasswordActivity() {
Intent(this, RecoveryPasswordActivity::class.java).also(::startActivity)
}

View File

@ -0,0 +1,154 @@
package org.thoughtcrime.securesms.onboarding.recoverypassword
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.compose.foundation.border
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.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import network.loki.messenger.R
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsignal.crypto.MnemonicCodec
import org.session.libsignal.utilities.hexEncodedPrivateKey
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
import org.thoughtcrime.securesms.crypto.MnemonicUtilities
import org.thoughtcrime.securesms.ui.AppTheme
import org.thoughtcrime.securesms.ui.CellWithPaddingAndMargin
import org.thoughtcrime.securesms.ui.OutlineButton
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.SessionShieldIcon
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
import org.thoughtcrime.securesms.ui.classicDarkColors
import org.thoughtcrime.securesms.ui.colorDestructive
import org.thoughtcrime.securesms.ui.extraSmall
import org.thoughtcrime.securesms.ui.h8
class RecoveryPasswordActivity : BaseActionBarActivity() {
private val seed by lazy {
var hexEncodedSeed = IdentityKeyUtil.retrieve(this, IdentityKeyUtil.LOKI_SEED)
if (hexEncodedSeed == null) {
hexEncodedSeed = IdentityKeyUtil.getIdentityKeyPair(this).hexEncodedPrivateKey // Legacy account
}
val loadFileContents: (String) -> String = { fileName ->
MnemonicUtilities.loadFileContents(this, fileName)
}
MnemonicCodec(loadFileContents).encode(hexEncodedSeed!!, MnemonicCodec.Language.Configuration.english)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportActionBar!!.title = resources.getString(R.string.activity_recovery_password)
ComposeView(this)
.apply { setContent { RecoveryPassword() } }
.let(::setContentView)
}
private fun revealSeed() {
TextSecurePreferences.setHasViewedSeed(this, true)
}
private fun copySeed() {
revealSeed()
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("Seed", seed)
clipboard.setPrimaryClip(clip)
Toast.makeText(this, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show()
}
}
@Preview
@Composable
fun PreviewMessageDetails(
@PreviewParameter(ThemeResPreviewParameterProvider::class) themeResId: Int
) {
PreviewTheme(themeResId) {
RecoveryPassword()
}
}
@Composable
fun RecoveryPassword() {
AppTheme {
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
RecoveryPasswordCell()
HideRecoveryPasswordCell()
}
}
}
@Composable
fun RecoveryPasswordCell() {
CellWithPaddingAndMargin {
Column {
Row {
Text("Recovery Password")
Spacer(Modifier.width(8.dp))
SessionShieldIcon()
}
Text("Use your recovery password to load your account on new devices.\n\nYour account cannot be recovered without your recovery password. Make sure it's stored somewhere safe and secure — and don't share it with anyone.")
Text(
"Voyage urban toyed maverick peculiar tuxedo penguin tree grass building listen speak withdraw terminal plane",
modifier = Modifier
.padding(vertical = 24.dp)
.border(
width = 1.dp,
color = classicDarkColors[3],
shape = RoundedCornerShape(11.dp)
)
.padding(24.dp),
style = MaterialTheme.typography.extraSmall.copy(fontFamily = FontFamily.Monospace)
)
Row(horizontalArrangement = Arrangement.spacedBy(32.dp)) {
OutlineButton(text = stringResource(R.string.copy), modifier = Modifier.weight(1f), color = MaterialTheme.colors.onPrimary) {}
OutlineButton(text = "View QR", modifier = Modifier.weight(1f), color = MaterialTheme.colors.onPrimary) {}
}
}
}
}
@Composable
fun HideRecoveryPasswordCell() {
CellWithPaddingAndMargin {
Row {
Column(Modifier.weight(1f)) {
Text(text = "Hide Recovery Password", style = MaterialTheme.typography.h8)
Text(text = "Permanently hide your recovery password on this device.")
}
OutlineButton(
"Hide",
modifier = Modifier.align(Alignment.CenterVertically),
color = colorDestructive
) {}
}
}
}
fun Context.startRecoveryPasswordActivity() {
Intent(this, RecoveryPasswordActivity::class.java).also(::startActivity)
}

View File

@ -44,7 +44,7 @@ import org.thoughtcrime.securesms.home.PathActivity
import org.thoughtcrime.securesms.messagerequests.MessageRequestsActivity
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.onboarding.startRecoveryPasswordActivity
import org.thoughtcrime.securesms.onboarding.recoverypassword.startRecoveryPasswordActivity
import org.thoughtcrime.securesms.permissions.Permissions
import org.thoughtcrime.securesms.preferences.appearance.AppearanceSettingsActivity
import org.thoughtcrime.securesms.profiles.ProfileMediaConstraints

View File

@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ButtonColors
@ -50,14 +51,19 @@ import org.thoughtcrime.securesms.components.ProfilePictureView
import kotlin.math.roundToInt
@Composable
fun OutlineButton(text: String, modifier: Modifier = Modifier, onClick: () -> Unit) {
fun OutlineButton(
text: String,
modifier: Modifier = Modifier,
color: Color = LocalExtraColors.current.prominentButtonColor,
onClick: () -> Unit
) {
OutlinedButton(
modifier = modifier.size(108.dp, 34.dp),
modifier = modifier,
onClick = onClick,
border = BorderStroke(1.dp, LocalExtraColors.current.prominentButtonColor),
border = BorderStroke(1.dp, color),
shape = RoundedCornerShape(50), // = 50% percent
colors = ButtonDefaults.outlinedButtonColors(
contentColor = LocalExtraColors.current.prominentButtonColor,
contentColor = color,
backgroundColor = Color.Unspecified
)
) {
@ -294,3 +300,13 @@ fun Arc(
)
}
}
@Composable
fun RowScope.SessionShieldIcon() {
Icon(
painter = painterResource(R.drawable.session_shield),
contentDescription = null,
modifier = Modifier.align(Alignment.CenterVertically)
.wrapContentSize(unbounded = true)
)
}

View File

@ -111,6 +111,7 @@ val sessionTypography = Typography(
val Typography.base get() = defaultStyle(14.sp)
val Typography.baseBold get() = boldStyle(14.sp)
val Typography.small get() = defaultStyle(12.sp)
val Typography.extraSmall get() = defaultStyle(11.sp)
val Typography.h7 get() = boldStyle(18.sp)
val Typography.h8 get() = boldStyle(16.sp)