mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-10-10 21:04:22 +02:00
Reducing the use of Slow disk access of Local Preferences.
This commit is contained in:
@@ -27,10 +27,7 @@ private const val DEBUG_PREFERENCES_NAME = "debug_prefs"
|
|||||||
|
|
||||||
data class AccountInfo(
|
data class AccountInfo(
|
||||||
val npub: String,
|
val npub: String,
|
||||||
val hasPrivKey: Boolean,
|
val hasPrivKey: Boolean = false
|
||||||
val current: Boolean,
|
|
||||||
val displayName: String?,
|
|
||||||
val profilePicture: String?
|
|
||||||
)
|
)
|
||||||
|
|
||||||
private object PrefKeys {
|
private object PrefKeys {
|
||||||
@@ -38,8 +35,6 @@ private object PrefKeys {
|
|||||||
const val SAVED_ACCOUNTS = "all_saved_accounts"
|
const val SAVED_ACCOUNTS = "all_saved_accounts"
|
||||||
const val NOSTR_PRIVKEY = "nostr_privkey"
|
const val NOSTR_PRIVKEY = "nostr_privkey"
|
||||||
const val NOSTR_PUBKEY = "nostr_pubkey"
|
const val NOSTR_PUBKEY = "nostr_pubkey"
|
||||||
const val DISPLAY_NAME = "display_name"
|
|
||||||
const val PROFILE_PICTURE_URL = "profile_picture"
|
|
||||||
const val FOLLOWING_CHANNELS = "following_channels"
|
const val FOLLOWING_CHANNELS = "following_channels"
|
||||||
const val HIDDEN_USERS = "hidden_users"
|
const val HIDDEN_USERS = "hidden_users"
|
||||||
const val RELAYS = "relays"
|
const val RELAYS = "relays"
|
||||||
@@ -59,53 +54,73 @@ private val gson = GsonBuilder().create()
|
|||||||
object LocalPreferences {
|
object LocalPreferences {
|
||||||
private const val comma = ","
|
private const val comma = ","
|
||||||
|
|
||||||
private var currentAccount: String?
|
private var _currentAccount: String? = null
|
||||||
get() = encryptedPreferences().getString(PrefKeys.CURRENT_ACCOUNT, null)
|
|
||||||
set(npub) {
|
private fun currentAccount(): String? {
|
||||||
val prefs = encryptedPreferences()
|
if (_currentAccount == null) {
|
||||||
prefs.edit().apply {
|
_currentAccount = encryptedPreferences().getString(PrefKeys.CURRENT_ACCOUNT, null)
|
||||||
|
}
|
||||||
|
return _currentAccount
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateCurrentAccount(npub: String) {
|
||||||
|
if (_currentAccount != npub) {
|
||||||
|
_currentAccount = npub
|
||||||
|
|
||||||
|
encryptedPreferences().edit().apply {
|
||||||
putString(PrefKeys.CURRENT_ACCOUNT, npub)
|
putString(PrefKeys.CURRENT_ACCOUNT, npub)
|
||||||
}.apply()
|
}.apply()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val savedAccounts: List<String>
|
private var _savedAccounts: List<String>? = null
|
||||||
get() = encryptedPreferences()
|
|
||||||
.getString(PrefKeys.SAVED_ACCOUNTS, null)?.split(comma) ?: listOf()
|
private fun savedAccounts(): List<String> {
|
||||||
|
if (_savedAccounts == null) {
|
||||||
|
_savedAccounts = encryptedPreferences()
|
||||||
|
.getString(PrefKeys.SAVED_ACCOUNTS, null)?.split(comma) ?: listOf()
|
||||||
|
}
|
||||||
|
return _savedAccounts!!
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateSavedAccounts(accounts: List<String>) {
|
||||||
|
if (_savedAccounts != accounts) {
|
||||||
|
_savedAccounts = accounts
|
||||||
|
|
||||||
|
encryptedPreferences().edit().apply {
|
||||||
|
putString(PrefKeys.SAVED_ACCOUNTS, accounts.joinToString(comma).ifBlank { null })
|
||||||
|
}.apply()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val prefsDirPath: String
|
private val prefsDirPath: String
|
||||||
get() = "${Amethyst.instance.filesDir.parent}/shared_prefs/"
|
get() = "${Amethyst.instance.filesDir.parent}/shared_prefs/"
|
||||||
|
|
||||||
private fun addAccount(npub: String) {
|
private fun addAccount(npub: String) {
|
||||||
val accounts = savedAccounts.toMutableList()
|
val accounts = savedAccounts().toMutableList()
|
||||||
if (npub !in accounts) {
|
if (npub !in accounts) {
|
||||||
accounts.add(npub)
|
accounts.add(npub)
|
||||||
|
updateSavedAccounts(accounts)
|
||||||
}
|
}
|
||||||
val prefs = encryptedPreferences()
|
|
||||||
prefs.edit().apply {
|
|
||||||
putString(PrefKeys.SAVED_ACCOUNTS, accounts.joinToString(comma).ifBlank { null })
|
|
||||||
}.apply()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setCurrentAccount(account: Account) {
|
private fun setCurrentAccount(account: Account) {
|
||||||
val npub = account.userProfile().pubkeyNpub()
|
val npub = account.userProfile().pubkeyNpub()
|
||||||
currentAccount = npub
|
updateCurrentAccount(npub)
|
||||||
addAccount(npub)
|
addAccount(npub)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun switchToAccount(npub: String) {
|
fun switchToAccount(npub: String) {
|
||||||
currentAccount = npub
|
updateCurrentAccount(npub)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the account from the app level shared preferences
|
* Removes the account from the app level shared preferences
|
||||||
*/
|
*/
|
||||||
private fun removeAccount(npub: String) {
|
private fun removeAccount(npub: String) {
|
||||||
val accounts = savedAccounts.toMutableList()
|
val accounts = savedAccounts().toMutableList()
|
||||||
if (accounts.remove(npub)) {
|
if (accounts.remove(npub)) {
|
||||||
val prefs = encryptedPreferences()
|
updateSavedAccounts(accounts)
|
||||||
prefs.edit().apply {
|
|
||||||
putString(PrefKeys.SAVED_ACCOUNTS, accounts.joinToString(comma).ifBlank { null })
|
|
||||||
}.apply()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,11 +160,11 @@ object LocalPreferences {
|
|||||||
removeAccount(npub)
|
removeAccount(npub)
|
||||||
deleteUserPreferenceFile(npub)
|
deleteUserPreferenceFile(npub)
|
||||||
|
|
||||||
if (savedAccounts.isEmpty()) {
|
if (savedAccounts().isEmpty()) {
|
||||||
val appPrefs = encryptedPreferences()
|
val appPrefs = encryptedPreferences()
|
||||||
appPrefs.edit().clear().apply()
|
appPrefs.edit().clear().apply()
|
||||||
} else if (currentAccount == npub) {
|
} else if (currentAccount() == npub) {
|
||||||
currentAccount = savedAccounts.elementAt(0)
|
updateCurrentAccount(savedAccounts().elementAt(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,17 +174,8 @@ object LocalPreferences {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun allSavedAccounts(): List<AccountInfo> {
|
fun allSavedAccounts(): List<AccountInfo> {
|
||||||
return savedAccounts.map { npub ->
|
return savedAccounts().map { npub ->
|
||||||
val prefs = encryptedPreferences(npub)
|
AccountInfo(npub = npub)
|
||||||
val hasPrivKey = prefs.getString(PrefKeys.NOSTR_PRIVKEY, null) != null
|
|
||||||
|
|
||||||
AccountInfo(
|
|
||||||
npub = npub,
|
|
||||||
hasPrivKey = hasPrivKey,
|
|
||||||
current = npub == currentAccount,
|
|
||||||
displayName = prefs.getString(PrefKeys.DISPLAY_NAME, null),
|
|
||||||
profilePicture = prefs.getString(PrefKeys.PROFILE_PICTURE_URL, null)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,13 +195,11 @@ 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)
|
||||||
putString(PrefKeys.DISPLAY_NAME, account.userProfile().toBestDisplayName())
|
|
||||||
putString(PrefKeys.PROFILE_PICTURE_URL, account.userProfile().profilePicture())
|
|
||||||
}.apply()
|
}.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
val privKey = getString(PrefKeys.NOSTR_PRIVKEY, null)
|
val privKey = getString(PrefKeys.NOSTR_PRIVKEY, null)
|
||||||
val followingChannels = getStringSet(PrefKeys.FOLLOWING_CHANNELS, null) ?: setOf()
|
val followingChannels = getStringSet(PrefKeys.FOLLOWING_CHANNELS, null) ?: setOf()
|
||||||
@@ -247,7 +251,7 @@ 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)
|
||||||
|
|
||||||
return Account(
|
val a = Account(
|
||||||
Persona(privKey = privKey?.toByteArray(), pubKey = pubKey.toByteArray()),
|
Persona(privKey = privKey?.toByteArray(), pubKey = pubKey.toByteArray()),
|
||||||
followingChannels,
|
followingChannels,
|
||||||
hiddenUsers,
|
hiddenUsers,
|
||||||
@@ -261,23 +265,25 @@ object LocalPreferences {
|
|||||||
hideBlockAlertDialog,
|
hideBlockAlertDialog,
|
||||||
latestContactList
|
latestContactList
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun saveLastRead(route: String, timestampInSecs: Long) {
|
fun saveLastRead(route: String, timestampInSecs: Long) {
|
||||||
encryptedPreferences(currentAccount).edit().apply {
|
encryptedPreferences(currentAccount()).edit().apply {
|
||||||
putLong(PrefKeys.LAST_READ(route), timestampInSecs)
|
putLong(PrefKeys.LAST_READ(route), timestampInSecs)
|
||||||
}.apply()
|
}.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadLastRead(route: String): Long {
|
fun loadLastRead(route: String): Long {
|
||||||
encryptedPreferences(currentAccount).run {
|
encryptedPreferences(currentAccount()).run {
|
||||||
return getLong(PrefKeys.LAST_READ(route), 0)
|
return getLong(PrefKeys.LAST_READ(route), 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun migrateSingleUserPrefs() {
|
fun migrateSingleUserPrefs() {
|
||||||
if (currentAccount != null) return
|
if (currentAccount() != null) return
|
||||||
|
|
||||||
val pubkey = encryptedPreferences().getString(PrefKeys.NOSTR_PUBKEY, null) ?: return
|
val pubkey = encryptedPreferences().getString(PrefKeys.NOSTR_PUBKEY, null) ?: return
|
||||||
val npub = Hex.decode(pubkey).toNpub()
|
val npub = Hex.decode(pubkey).toNpub()
|
||||||
@@ -314,6 +320,6 @@ object LocalPreferences {
|
|||||||
|
|
||||||
encryptedPreferences().edit().clear().apply()
|
encryptedPreferences().edit().clear().apply()
|
||||||
addAccount(npub)
|
addAccount(npub)
|
||||||
currentAccount = npub
|
updateCurrentAccount(npub)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
@@ -24,10 +23,8 @@ import androidx.compose.material.TextButton
|
|||||||
import androidx.compose.material.TopAppBar
|
import androidx.compose.material.TopAppBar
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.ArrowBack
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
import androidx.compose.material.icons.filled.Key
|
|
||||||
import androidx.compose.material.icons.filled.Logout
|
import androidx.compose.material.icons.filled.Logout
|
||||||
import androidx.compose.material.icons.filled.RadioButtonChecked
|
import androidx.compose.material.icons.filled.RadioButtonChecked
|
||||||
import androidx.compose.material.icons.filled.Visibility
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
@@ -45,14 +42,15 @@ 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
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
|
import com.vitorpamplona.amethyst.model.decodePublicKey
|
||||||
|
import com.vitorpamplona.amethyst.model.toHexKey
|
||||||
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
||||||
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
|
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
|
||||||
import com.vitorpamplona.amethyst.ui.note.toShortenHex
|
import com.vitorpamplona.amethyst.ui.note.toShortenHex
|
||||||
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
|
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedOff.LoginPage
|
import com.vitorpamplona.amethyst.ui.screen.loggedOff.LoginPage
|
||||||
import nostr.postr.bechToBytes
|
|
||||||
import nostr.postr.toHex
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AccountSwitchBottomSheet(
|
fun AccountSwitchBottomSheet(
|
||||||
@@ -82,90 +80,101 @@ fun AccountSwitchBottomSheet(
|
|||||||
accounts.forEach { acc ->
|
accounts.forEach { acc ->
|
||||||
val current = accountUser.pubkeyNpub() == acc.npub
|
val current = accountUser.pubkeyNpub() == acc.npub
|
||||||
|
|
||||||
Row(
|
val baseUser = try {
|
||||||
modifier = Modifier.fillMaxWidth(),
|
LocalCache.getOrCreateUser(decodePublicKey(acc.npub).toHexKey())
|
||||||
verticalAlignment = Alignment.CenterVertically
|
} catch (e: Exception) {
|
||||||
) {
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (baseUser != null) {
|
||||||
|
val userState by baseUser.live().metadata.observeAsState()
|
||||||
|
val user = userState?.user ?: return
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier.fillMaxWidth(),
|
||||||
.weight(1f)
|
|
||||||
.clickable {
|
|
||||||
accountStateViewModel.switchUser(acc.npub)
|
|
||||||
},
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(16.dp, 16.dp)
|
.weight(1f)
|
||||||
.weight(1f),
|
.clickable {
|
||||||
|
accountStateViewModel.switchUser(acc.npub)
|
||||||
|
},
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
Box(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(55.dp)
|
.padding(16.dp, 16.dp)
|
||||||
.padding(0.dp)
|
.weight(1f),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
RobohashAsyncImageProxy(
|
|
||||||
robot = acc.npub.bechToBytes("npub").toHex(),
|
|
||||||
model = ResizeImage(acc.profilePicture, 55.dp),
|
|
||||||
contentDescription = stringResource(R.string.profile_image),
|
|
||||||
modifier = Modifier
|
|
||||||
.width(55.dp)
|
|
||||||
.height(55.dp)
|
|
||||||
.clip(shape = CircleShape)
|
|
||||||
)
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(20.dp)
|
.width(55.dp)
|
||||||
.align(Alignment.TopEnd)
|
.padding(0.dp)
|
||||||
) {
|
) {
|
||||||
if (acc.hasPrivKey) {
|
RobohashAsyncImageProxy(
|
||||||
|
robot = user.pubkeyHex,
|
||||||
|
model = ResizeImage(user.profilePicture(), 55.dp),
|
||||||
|
contentDescription = stringResource(R.string.profile_image),
|
||||||
|
modifier = Modifier
|
||||||
|
.width(55.dp)
|
||||||
|
.height(55.dp)
|
||||||
|
.clip(shape = CircleShape)
|
||||||
|
)/*
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(20.dp)
|
||||||
|
.align(Alignment.TopEnd)
|
||||||
|
) {
|
||||||
|
if (acc.hasPrivKey) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Key,
|
||||||
|
contentDescription = stringResource(R.string.account_switch_has_private_key),
|
||||||
|
modifier = Modifier.size(20.dp),
|
||||||
|
tint = MaterialTheme.colors.primary
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Visibility,
|
||||||
|
contentDescription = stringResource(R.string.account_switch_pubkey_only),
|
||||||
|
modifier = Modifier.size(20.dp),
|
||||||
|
tint = MaterialTheme.colors.primary
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
Column(modifier = Modifier.weight(1f)) {
|
||||||
|
val npubShortHex = acc.npub.toShortenHex()
|
||||||
|
|
||||||
|
user.bestDisplayName()?.let {
|
||||||
|
Text(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(npubShortHex)
|
||||||
|
}
|
||||||
|
Column(modifier = Modifier.width(32.dp)) {
|
||||||
|
if (current) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.Key,
|
imageVector = Icons.Default.RadioButtonChecked,
|
||||||
contentDescription = stringResource(R.string.account_switch_has_private_key),
|
contentDescription = stringResource(R.string.account_switch_active_account),
|
||||||
modifier = Modifier.size(20.dp),
|
tint = MaterialTheme.colors.secondary
|
||||||
tint = MaterialTheme.colors.primary
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.Visibility,
|
|
||||||
contentDescription = stringResource(R.string.account_switch_pubkey_only),
|
|
||||||
modifier = Modifier.size(20.dp),
|
|
||||||
tint = MaterialTheme.colors.primary
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.width(16.dp))
|
|
||||||
Column(modifier = Modifier.weight(1f)) {
|
|
||||||
val npubShortHex = acc.npub.toShortenHex()
|
|
||||||
|
|
||||||
if (acc.displayName != null && acc.displayName != npubShortHex) {
|
|
||||||
Text(acc.displayName)
|
|
||||||
}
|
|
||||||
|
|
||||||
Text(npubShortHex)
|
|
||||||
}
|
|
||||||
Column(modifier = Modifier.width(32.dp)) {
|
|
||||||
if (current) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.RadioButtonChecked,
|
|
||||||
contentDescription = stringResource(R.string.account_switch_active_account),
|
|
||||||
tint = MaterialTheme.colors.secondary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = { accountStateViewModel.logOff(acc.npub) }
|
onClick = { accountStateViewModel.logOff(acc.npub) }
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.Logout,
|
imageVector = Icons.Default.Logout,
|
||||||
contentDescription = stringResource(R.string.log_out),
|
contentDescription = stringResource(R.string.log_out),
|
||||||
tint = MaterialTheme.colors.onSurface
|
tint = MaterialTheme.colors.onSurface
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -35,11 +35,11 @@ class AccountStateViewModel() : ViewModel() {
|
|||||||
|
|
||||||
private fun tryLoginExistingAccount() {
|
private fun tryLoginExistingAccount() {
|
||||||
LocalPreferences.loadFromEncryptedStorage()?.let {
|
LocalPreferences.loadFromEncryptedStorage()?.let {
|
||||||
login(it)
|
startUI(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun login(key: String) {
|
fun startUI(key: String) {
|
||||||
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()
|
||||||
@@ -56,7 +56,8 @@ class AccountStateViewModel() : ViewModel() {
|
|||||||
Account(Persona(Hex.decode(key)))
|
Account(Persona(Hex.decode(key)))
|
||||||
}
|
}
|
||||||
|
|
||||||
login(account)
|
LocalPreferences.updatePrefsForLogin(account)
|
||||||
|
startUI(account)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun switchUser(npub: String) {
|
fun switchUser(npub: String) {
|
||||||
@@ -67,24 +68,22 @@ class AccountStateViewModel() : ViewModel() {
|
|||||||
|
|
||||||
fun newKey() {
|
fun newKey() {
|
||||||
val account = Account(Persona())
|
val account = Account(Persona())
|
||||||
login(account)
|
// saves to local preferences
|
||||||
|
LocalPreferences.updatePrefsForLogin(account)
|
||||||
|
startUI(account)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(DelicateCoroutinesApi::class)
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
fun login(account: Account) {
|
fun startUI(account: Account) {
|
||||||
LocalPreferences.updatePrefsForLogin(account)
|
|
||||||
|
|
||||||
if (account.loggedIn.privKey != null) {
|
if (account.loggedIn.privKey != null) {
|
||||||
_accountContent.update { AccountState.LoggedIn(account) }
|
_accountContent.update { AccountState.LoggedIn(account) }
|
||||||
} else {
|
} else {
|
||||||
_accountContent.update { AccountState.LoggedInViewOnly(account) }
|
_accountContent.update { AccountState.LoggedInViewOnly(account) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val scope = CoroutineScope(Job() + Dispatchers.IO)
|
val scope = CoroutineScope(Job() + Dispatchers.IO)
|
||||||
scope.launch {
|
scope.launch {
|
||||||
ServiceManager.start(account)
|
ServiceManager.start(account)
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalScope.launch(Dispatchers.Main) {
|
GlobalScope.launch(Dispatchers.Main) {
|
||||||
account.saveable.observeForever(saveListener)
|
account.saveable.observeForever(saveListener)
|
||||||
}
|
}
|
||||||
|
@@ -158,7 +158,7 @@ fun LoginPage(
|
|||||||
keyboardActions = KeyboardActions(
|
keyboardActions = KeyboardActions(
|
||||||
onGo = {
|
onGo = {
|
||||||
try {
|
try {
|
||||||
accountViewModel.login(key.value.text)
|
accountViewModel.startUI(key.value.text)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
errorMessage = context.getString(R.string.invalid_key)
|
errorMessage = context.getString(R.string.invalid_key)
|
||||||
}
|
}
|
||||||
@@ -237,7 +237,7 @@ fun LoginPage(
|
|||||||
|
|
||||||
if (acceptedTerms.value && key.value.text.isNotBlank()) {
|
if (acceptedTerms.value && key.value.text.isNotBlank()) {
|
||||||
try {
|
try {
|
||||||
accountViewModel.login(key.value.text)
|
accountViewModel.startUI(key.value.text)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
errorMessage = context.getString(R.string.invalid_key)
|
errorMessage = context.getString(R.string.invalid_key)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user