mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-08-04 06:02:57 +02:00
Correctly logs off from the current account when creating new accounts from inside an existing account.
This commit is contained in:
@@ -270,7 +270,7 @@ object LocalPreferences {
|
||||
* deleted
|
||||
*/
|
||||
@SuppressLint("ApplySharedPref")
|
||||
suspend fun updatePrefsForLogout(accountInfo: AccountInfo) {
|
||||
suspend fun deleteAccount(accountInfo: AccountInfo) {
|
||||
Log.d("LocalPreferences", "Saving to encrypted storage updatePrefsForLogout ${accountInfo.npub}")
|
||||
withContext(Dispatchers.IO) {
|
||||
encryptedPreferences(accountInfo.npub).edit(commit = true) { clear() }
|
||||
@@ -285,7 +285,7 @@ object LocalPreferences {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun updatePrefsForLogin(accountSettings: AccountSettings) {
|
||||
suspend fun setDefaultAccount(accountSettings: AccountSettings) {
|
||||
setCurrentAccount(accountSettings)
|
||||
saveToEncryptedStorage(accountSettings)
|
||||
}
|
||||
|
@@ -76,7 +76,7 @@ class MainActivity : AppCompatActivity() {
|
||||
val accountStateViewModel: AccountStateViewModel = viewModel()
|
||||
|
||||
LaunchedEffect(key1 = Unit) {
|
||||
accountStateViewModel.tryLoginExistingAccountAsync()
|
||||
accountStateViewModel.loginWithDefaultAccountIfLoggedOff()
|
||||
}
|
||||
|
||||
AccountScreen(accountStateViewModel, sharedPreferencesViewModel)
|
||||
|
@@ -297,8 +297,8 @@ private fun NavigateIfIntentRequested(
|
||||
if (actionableNextPage != null) {
|
||||
actionableNextPage?.let { nextRoute ->
|
||||
val npub = runCatching { URI(intentNextPage.removePrefix("nostr:")).findParameterValue("account") }.getOrNull()
|
||||
if (npub != null && accountStateViewModel.currentAccount() != npub) {
|
||||
accountStateViewModel.switchUserSync(npub, nextRoute)
|
||||
if (npub != null && accountStateViewModel.currentAccountNPub() != npub) {
|
||||
accountStateViewModel.checkAndSwitchUserSync(npub, nextRoute)
|
||||
} else {
|
||||
val currentRoute = getRouteWithArguments(nav.controller)
|
||||
if (!isSameRoute(currentRoute, nextRoute)) {
|
||||
@@ -353,8 +353,8 @@ private fun NavigateIfIntentRequested(
|
||||
if (newPage != null) {
|
||||
scope.launch {
|
||||
val npub = runCatching { URI(uri.removePrefix("nostr:")).findParameterValue("account") }.getOrNull()
|
||||
if (npub != null && accountStateViewModel.currentAccount() != npub) {
|
||||
accountStateViewModel.switchUserSync(npub, newPage)
|
||||
if (npub != null && accountStateViewModel.currentAccountNPub() != npub) {
|
||||
accountStateViewModel.checkAndSwitchUserSync(npub, newPage)
|
||||
} else {
|
||||
val currentRoute = getRouteWithArguments(nav.controller)
|
||||
if (!isSameRoute(currentRoute, newPage)) {
|
||||
|
@@ -33,6 +33,7 @@ import com.vitorpamplona.amethyst.model.DefaultDMRelayList
|
||||
import com.vitorpamplona.amethyst.model.DefaultNIP65List
|
||||
import com.vitorpamplona.amethyst.model.DefaultNIP65RelaySet
|
||||
import com.vitorpamplona.amethyst.model.DefaultSearchRelayList
|
||||
import com.vitorpamplona.amethyst.model.preferences.AccountPreferenceStores.Companion.torSettings
|
||||
import com.vitorpamplona.amethyst.service.Nip05NostrAddressVerifier
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
import com.vitorpamplona.amethyst.ui.tor.TorSettings
|
||||
@@ -51,6 +52,7 @@ import com.vitorpamplona.quartz.nip19Bech32.bech32.bechToBytes
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NEmbed
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NNote
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NProfile
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NRelay
|
||||
@@ -85,16 +87,16 @@ class AccountStateViewModel : ViewModel() {
|
||||
|
||||
private var collectorJob: Job? = null
|
||||
|
||||
fun tryLoginExistingAccountAsync() {
|
||||
fun loginWithDefaultAccountIfLoggedOff() {
|
||||
// pulls account from storage.
|
||||
if (_accountContent.value !is AccountState.LoggedIn) {
|
||||
viewModelScope.launch {
|
||||
tryLoginExistingAccount()
|
||||
loginWithDefaultAccount()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun tryLoginExistingAccount(route: Route? = null) {
|
||||
private suspend fun loginWithDefaultAccount(route: Route? = null) {
|
||||
val accountSettings =
|
||||
withContext(Dispatchers.IO) {
|
||||
LocalPreferences.loadCurrentAccountFromEncryptedStorage()
|
||||
@@ -107,9 +109,7 @@ class AccountStateViewModel : ViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun requestLoginUI() {
|
||||
_accountContent.update { AccountState.LoggedOff }
|
||||
}
|
||||
private suspend fun requestLoginUI() = _accountContent.update { AccountState.LoggedOff }
|
||||
|
||||
suspend fun loginAndStartUI(
|
||||
key: String,
|
||||
@@ -124,7 +124,7 @@ class AccountStateViewModel : ViewModel() {
|
||||
is NSec -> null
|
||||
is NPub -> parsed.hex.hexToByteArray()
|
||||
is NProfile -> parsed.hex.hexToByteArray()
|
||||
is com.vitorpamplona.quartz.nip19Bech32.entities.NNote -> null
|
||||
is NNote -> null
|
||||
is NEvent -> null
|
||||
is NEmbed -> null
|
||||
is NRelay -> null
|
||||
@@ -175,7 +175,7 @@ class AccountStateViewModel : ViewModel() {
|
||||
)
|
||||
}
|
||||
|
||||
LocalPreferences.updatePrefsForLogin(account)
|
||||
LocalPreferences.setDefaultAccount(account)
|
||||
|
||||
startUI(account)
|
||||
}
|
||||
@@ -277,6 +277,9 @@ class AccountStateViewModel : ViewModel() {
|
||||
onError: (String) -> Unit,
|
||||
) {
|
||||
try {
|
||||
if (_accountContent.value is AccountState.LoggedIn) {
|
||||
prepareLogoutOrSwitch()
|
||||
}
|
||||
loginAndStartUI(key, torSettings, transientAccount, loginWithExternalSigner, packageName)
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
@@ -290,31 +293,15 @@ class AccountStateViewModel : ViewModel() {
|
||||
name: String? = null,
|
||||
) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
if (_accountContent.value is AccountState.LoggedIn) {
|
||||
prepareLogoutOrSwitch()
|
||||
}
|
||||
|
||||
_accountContent.update { AccountState.Loading }
|
||||
|
||||
val keyPair = KeyPair()
|
||||
val tempSigner = NostrSignerSync(keyPair)
|
||||
val accountSettings = createNewAccount(torSettings, name)
|
||||
|
||||
val accountSettings =
|
||||
AccountSettings(
|
||||
keyPair = keyPair,
|
||||
transientAccount = false,
|
||||
backupUserMetadata = tempSigner.sign(MetadataEvent.newUser(name)),
|
||||
backupContactList =
|
||||
ContactListEvent.createFromScratch(
|
||||
followUsers = listOf(ContactTag(keyPair.pubKey.toHexKey(), null, null)),
|
||||
relayUse = emptyMap(),
|
||||
signer = tempSigner,
|
||||
),
|
||||
backupNIP65RelayList = AdvertisedRelayListEvent.create(DefaultNIP65List, tempSigner),
|
||||
backupDMRelayList = ChatMessageRelayListEvent.create(DefaultDMRelayList, tempSigner),
|
||||
backupSearchRelayList = SearchRelayListEvent.create(DefaultSearchRelayList.toList(), tempSigner),
|
||||
backupChannelList = ChannelListEvent.create(emptyList(), DefaultChannels, tempSigner),
|
||||
torSettings = TorSettingsFlow.build(torSettings),
|
||||
)
|
||||
|
||||
// saves to local preferences
|
||||
LocalPreferences.updatePrefsForLogin(accountSettings)
|
||||
LocalPreferences.setDefaultAccount(accountSettings)
|
||||
|
||||
startUI(accountSettings)
|
||||
|
||||
@@ -333,13 +320,38 @@ class AccountStateViewModel : ViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
fun createNewAccount(
|
||||
torSettings: TorSettings,
|
||||
name: String? = null,
|
||||
): AccountSettings {
|
||||
val keyPair = KeyPair()
|
||||
val tempSigner = NostrSignerSync(keyPair)
|
||||
|
||||
return AccountSettings(
|
||||
keyPair = keyPair,
|
||||
transientAccount = false,
|
||||
backupUserMetadata = tempSigner.sign(MetadataEvent.newUser(name)),
|
||||
backupContactList =
|
||||
ContactListEvent.createFromScratch(
|
||||
followUsers = listOf(ContactTag(keyPair.pubKey.toHexKey(), null, null)),
|
||||
relayUse = emptyMap(),
|
||||
signer = tempSigner,
|
||||
),
|
||||
backupNIP65RelayList = AdvertisedRelayListEvent.create(DefaultNIP65List, tempSigner),
|
||||
backupDMRelayList = ChatMessageRelayListEvent.create(DefaultDMRelayList, tempSigner),
|
||||
backupSearchRelayList = SearchRelayListEvent.create(DefaultSearchRelayList.toList(), tempSigner),
|
||||
backupChannelList = ChannelListEvent.create(emptyList(), DefaultChannels, tempSigner),
|
||||
torSettings = TorSettingsFlow.build(torSettings),
|
||||
)
|
||||
}
|
||||
|
||||
fun switchUser(accountInfo: AccountInfo) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
switchUserSync(accountInfo)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun switchUserSync(
|
||||
suspend fun checkAndSwitchUserSync(
|
||||
npub: String,
|
||||
route: Route,
|
||||
): Boolean {
|
||||
@@ -353,34 +365,33 @@ class AccountStateViewModel : ViewModel() {
|
||||
return false
|
||||
}
|
||||
|
||||
suspend fun switchUserSync(
|
||||
private suspend fun switchUserSync(
|
||||
accountInfo: AccountInfo,
|
||||
route: Route? = null,
|
||||
) {
|
||||
prepareLogoutOrSwitch()
|
||||
LocalPreferences.switchToAccount(accountInfo)
|
||||
tryLoginExistingAccount(route)
|
||||
loginWithDefaultAccount(route)
|
||||
}
|
||||
|
||||
fun currentAccount() =
|
||||
fun currentAccountNPub() =
|
||||
when (val state = _accountContent.value) {
|
||||
is AccountState.LoggedIn ->
|
||||
state.accountSettings.keyPair.pubKey
|
||||
.toNpub()
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun logOff(accountInfo: AccountInfo) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
if (accountInfo.npub == currentAccount()) {
|
||||
if (accountInfo.npub == currentAccountNPub()) {
|
||||
// log off and relogin with the 0 account
|
||||
prepareLogoutOrSwitch()
|
||||
LocalPreferences.updatePrefsForLogout(accountInfo)
|
||||
tryLoginExistingAccount()
|
||||
LocalPreferences.deleteAccount(accountInfo)
|
||||
loginWithDefaultAccount()
|
||||
} else {
|
||||
// delete without login off
|
||||
LocalPreferences.updatePrefsForLogout(accountInfo)
|
||||
// delete without switching logins
|
||||
LocalPreferences.deleteAccount(accountInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user