mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2024-09-29 08:20:51 +00:00
Add account, switch account, and logout flows
This commit is contained in:
parent
9561261bf4
commit
b40bde10a0
@ -80,18 +80,27 @@ object LocalPreferences {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clearEncryptedStorage(npub: String? = null) {
|
fun clearEncryptedStorage(npub: String) {
|
||||||
val encPrefs = encryptedPreferences(npub)
|
val userPrefs = encryptedPreferences(npub)
|
||||||
encPrefs.edit().apply {
|
userPrefs.edit().clear().apply()
|
||||||
encPrefs.all.keys.forEach {
|
removeAccount(npub)
|
||||||
remove(it)
|
|
||||||
|
if (savedAccounts.isEmpty()) {
|
||||||
|
val appPrefs = encryptedPreferences()
|
||||||
|
appPrefs.edit().clear().apply()
|
||||||
|
} else if (currentAccount == npub) {
|
||||||
|
currentAccount = savedAccounts.elementAt(0)
|
||||||
}
|
}
|
||||||
|
// encPrefs.edit().apply {
|
||||||
|
// encPrefs.all.keys.forEach {
|
||||||
|
// remove(it)
|
||||||
|
// }
|
||||||
// encryptedPreferences.all.keys.filter {
|
// encryptedPreferences.all.keys.filter {
|
||||||
// it.startsWith(npub)
|
// it.startsWith(npub)
|
||||||
// }.forEach {
|
// }.forEach {
|
||||||
// remove(it)
|
// remove(it)
|
||||||
// }
|
// }
|
||||||
}.apply()
|
// }.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findAllLocalAccounts(): List<AccountInfo> {
|
fun findAllLocalAccounts(): List<AccountInfo> {
|
||||||
@ -132,6 +141,11 @@ object LocalPreferences {
|
|||||||
}.apply()
|
}.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun login(account: Account) {
|
||||||
|
setCurrentAccount(account)
|
||||||
|
saveToEncryptedStorage(account)
|
||||||
|
}
|
||||||
|
|
||||||
fun loadFromEncryptedStorage(): Account? {
|
fun loadFromEncryptedStorage(): Account? {
|
||||||
encryptedPreferences(currentAccount).apply {
|
encryptedPreferences(currentAccount).apply {
|
||||||
val pubKey = getString(PrefKeys.NOSTR_PUBKEY, null) ?: return null
|
val pubKey = getString(PrefKeys.NOSTR_PUBKEY, null) ?: return null
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.navigation
|
package com.vitorpamplona.amethyst.ui.navigation
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
@ -12,8 +13,12 @@ import androidx.compose.foundation.layout.height
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.text.ClickableText
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
import androidx.compose.material.Button
|
||||||
|
import androidx.compose.material.ButtonDefaults
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.IconButton
|
import androidx.compose.material.IconButton
|
||||||
@ -48,13 +53,18 @@ import androidx.compose.ui.platform.LocalAutofill
|
|||||||
import androidx.compose.ui.platform.LocalAutofillTree
|
import androidx.compose.ui.platform.LocalAutofillTree
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.text.input.VisualTransformation
|
import androidx.compose.ui.text.input.VisualTransformation
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.text.style.TextDecoration
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
import androidx.compose.ui.window.DialogProperties
|
import androidx.compose.ui.window.DialogProperties
|
||||||
import com.vitorpamplona.amethyst.LocalPreferences
|
import com.vitorpamplona.amethyst.LocalPreferences
|
||||||
@ -103,6 +113,11 @@ fun AccountSwitchBottomSheet(
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(32.dp, 16.dp),
|
.padding(32.dp, 16.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.clickable {
|
||||||
|
accountStateViewModel.login(acc.npub)
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
AsyncImageProxy(
|
AsyncImageProxy(
|
||||||
model = ResizeImage(acc.profilePicture, 64.dp),
|
model = ResizeImage(acc.profilePicture, 64.dp),
|
||||||
@ -127,7 +142,11 @@ fun AccountSwitchBottomSheet(
|
|||||||
Text("✓")
|
Text("✓")
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
IconButton(onClick = { /*TODO*/ }) {
|
}
|
||||||
|
|
||||||
|
IconButton(
|
||||||
|
onClick = { accountStateViewModel.logOff(acc.npub) }
|
||||||
|
) {
|
||||||
Icon(imageVector = Icons.Default.Logout, "Logout")
|
Icon(imageVector = Icons.Default.Logout, "Logout")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -229,6 +248,49 @@ fun AccountSwitchBottomSheet(
|
|||||||
style = MaterialTheme.typography.caption
|
style = MaterialTheme.typography.caption
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
if (key.value.text.isBlank()) {
|
||||||
|
errorMessage = context.getString(R.string.key_is_required)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
accountStateViewModel.login(key.value.text)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
errorMessage = context.getString(R.string.invalid_key)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
shape = RoundedCornerShape(35.dp),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(50.dp),
|
||||||
|
colors = ButtonDefaults
|
||||||
|
.buttonColors(
|
||||||
|
backgroundColor = MaterialTheme.colors.primary
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(text = stringResource(R.string.login))
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
ClickableText(
|
||||||
|
text = AnnotatedString(stringResource(R.string.generate_a_new_key)),
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(20.dp)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
onClick = {
|
||||||
|
accountStateViewModel.newKey()
|
||||||
|
},
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 14.sp,
|
||||||
|
textDecoration = TextDecoration.Underline,
|
||||||
|
color = MaterialTheme.colors.primary,
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,14 @@ class AccountStateViewModel() : ViewModel() {
|
|||||||
|
|
||||||
// Keeps it in the the UI thread to void blinking the login page.
|
// Keeps it in the the UI thread to void blinking the login page.
|
||||||
// viewModelScope.launch(Dispatchers.IO) {
|
// viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
tryLoginExistingAccount()
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun tryLoginExistingAccount() {
|
||||||
LocalPreferences.loadFromEncryptedStorage()?.let {
|
LocalPreferences.loadFromEncryptedStorage()?.let {
|
||||||
login(it)
|
login(it)
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun login(key: String) {
|
fun login(key: String) {
|
||||||
@ -47,18 +51,18 @@ class AccountStateViewModel() : ViewModel() {
|
|||||||
Account(Persona(Hex.decode(key)))
|
Account(Persona(Hex.decode(key)))
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalPreferences.saveToEncryptedStorage(account)
|
LocalPreferences.login(account)
|
||||||
login(account)
|
login(account)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun newKey() {
|
fun newKey() {
|
||||||
val account = Account(Persona())
|
val account = Account(Persona())
|
||||||
LocalPreferences.saveToEncryptedStorage(account)
|
LocalPreferences.login(account)
|
||||||
login(account)
|
login(account)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun login(account: Account) {
|
fun login(account: Account) {
|
||||||
LocalPreferences.setCurrentAccount(account)
|
LocalPreferences.login(account)
|
||||||
|
|
||||||
if (account.loggedIn.privKey != null) {
|
if (account.loggedIn.privKey != null) {
|
||||||
_accountContent.update { AccountState.LoggedIn(account) }
|
_accountContent.update { AccountState.LoggedIn(account) }
|
||||||
@ -82,7 +86,7 @@ class AccountStateViewModel() : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun logOff() {
|
fun logOff(npub: String) {
|
||||||
val state = accountContent.value
|
val state = accountContent.value
|
||||||
|
|
||||||
when (state) {
|
when (state) {
|
||||||
@ -101,6 +105,7 @@ class AccountStateViewModel() : ViewModel() {
|
|||||||
|
|
||||||
_accountContent.update { AccountState.LoggedOff }
|
_accountContent.update { AccountState.LoggedOff }
|
||||||
|
|
||||||
LocalPreferences.clearEncryptedStorage()
|
LocalPreferences.clearEncryptedStorage(npub)
|
||||||
|
tryLoginExistingAccount()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user