Merge branch 'vitorpamplona:main' into labeled-bookmarks
This commit is contained in:
@@ -33,6 +33,7 @@ import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.DEFAULT_MEDIA_SERVERS
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerName
|
||||
import com.vitorpamplona.quartz.experimental.ephemChat.list.EphemeralChatListEvent
|
||||
import com.vitorpamplona.quartz.experimental.trustedAssertions.list.TrustProviderListEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.JsonMapper
|
||||
@@ -110,6 +111,7 @@ private object PrefKeys {
|
||||
const val LATEST_HASHTAG_LIST = "latestHashtagList"
|
||||
const val LATEST_GEOHASH_LIST = "latestGeohashList"
|
||||
const val LATEST_EPHEMERAL_LIST = "latestEphemeralChatList"
|
||||
const val LATEST_TRUST_PROVIDER_LIST = "latestTrustProviderList"
|
||||
const val HIDE_DELETE_REQUEST_DIALOG = "hide_delete_request_dialog"
|
||||
const val HIDE_BLOCK_ALERT_DIALOG = "hide_block_alert_dialog"
|
||||
const val HIDE_NIP_17_WARNING_DIALOG = "hide_nip24_warning_dialog" // delete later
|
||||
@@ -354,6 +356,7 @@ object LocalPreferences {
|
||||
putOrRemove(PrefKeys.LATEST_HASHTAG_LIST, settings.backupHashtagList)
|
||||
putOrRemove(PrefKeys.LATEST_GEOHASH_LIST, settings.backupGeohashList)
|
||||
putOrRemove(PrefKeys.LATEST_EPHEMERAL_LIST, settings.backupEphemeralChatList)
|
||||
putOrRemove(PrefKeys.LATEST_TRUST_PROVIDER_LIST, settings.backupTrustProviderList)
|
||||
|
||||
putBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, settings.hideDeleteRequestDialog)
|
||||
putBoolean(PrefKeys.HIDE_NIP_17_WARNING_DIALOG, settings.hideNIP17WarningDialog)
|
||||
@@ -482,6 +485,7 @@ object LocalPreferences {
|
||||
val latestHashtagList = parseEventOrNull<HashtagListEvent>(PrefKeys.LATEST_HASHTAG_LIST)
|
||||
val latestGeohashList = parseEventOrNull<GeohashListEvent>(PrefKeys.LATEST_GEOHASH_LIST)
|
||||
val latestEphemeralList = parseEventOrNull<EphemeralChatListEvent>(PrefKeys.LATEST_EPHEMERAL_LIST)
|
||||
val latestTrustProviderList = parseEventOrNull<TrustProviderListEvent>(PrefKeys.LATEST_TRUST_PROVIDER_LIST)
|
||||
|
||||
val hideDeleteRequestDialog = getBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, false)
|
||||
val hideBlockAlertDialog = getBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, false)
|
||||
@@ -525,6 +529,7 @@ object LocalPreferences {
|
||||
backupHashtagList = latestHashtagList,
|
||||
backupGeohashList = latestGeohashList,
|
||||
backupEphemeralChatList = latestEphemeralList,
|
||||
backupTrustProviderList = latestTrustProviderList,
|
||||
lastReadPerRoute = MutableStateFlow(lastReadPerRoute),
|
||||
hasDonatedInVersion = MutableStateFlow(hasDonatedInVersion),
|
||||
pendingAttestations = MutableStateFlow(pendingAttestations),
|
||||
|
||||
@@ -93,6 +93,8 @@ import com.vitorpamplona.amethyst.model.topNavFeeds.FeedDecryptionCaches
|
||||
import com.vitorpamplona.amethyst.model.topNavFeeds.FeedTopNavFilterState
|
||||
import com.vitorpamplona.amethyst.model.topNavFeeds.IFeedTopNavFilter
|
||||
import com.vitorpamplona.amethyst.model.topNavFeeds.OutboxLoaderState
|
||||
import com.vitorpamplona.amethyst.model.trustedAssertions.TrustProviderListDecryptionCache
|
||||
import com.vitorpamplona.amethyst.model.trustedAssertions.TrustProviderListState
|
||||
import com.vitorpamplona.amethyst.service.location.LocationState
|
||||
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc.NWCPaymentFilterAssembler
|
||||
import com.vitorpamplona.amethyst.service.uploads.FileHeader
|
||||
@@ -284,6 +286,9 @@ class Account(
|
||||
val muteListDecryptionCache = MuteListDecryptionCache(signer)
|
||||
val muteList = MuteListState(signer, cache, muteListDecryptionCache, scope, settings)
|
||||
|
||||
val trustProviderListDecryptionCache = TrustProviderListDecryptionCache(signer)
|
||||
val trustProviderList = TrustProviderListState(signer, cache, trustProviderListDecryptionCache, scope, settings)
|
||||
|
||||
val peopleListDecryptionCache = PeopleListDecryptionCache(signer)
|
||||
val blockPeopleList = BlockPeopleListState(signer, cache, peopleListDecryptionCache, scope)
|
||||
val peopleLists = PeopleListsState(signer, cache, peopleListDecryptionCache, scope)
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.vitorpamplona.amethyst.ui.actions.mediaServers.DEFAULT_MEDIA_SERVERS
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerName
|
||||
import com.vitorpamplona.amethyst.ui.screen.FeedDefinition
|
||||
import com.vitorpamplona.quartz.experimental.ephemChat.list.EphemeralChatListEvent
|
||||
import com.vitorpamplona.quartz.experimental.trustedAssertions.list.TrustProviderListEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
@@ -138,6 +139,7 @@ class AccountSettings(
|
||||
var backupHashtagList: HashtagListEvent? = null,
|
||||
var backupGeohashList: GeohashListEvent? = null,
|
||||
var backupEphemeralChatList: EphemeralChatListEvent? = null,
|
||||
var backupTrustProviderList: TrustProviderListEvent? = null,
|
||||
val lastReadPerRoute: MutableStateFlow<Map<String, MutableStateFlow<Long>>> = MutableStateFlow(mapOf()),
|
||||
var hasDonatedInVersion: MutableStateFlow<Set<String>> = MutableStateFlow(setOf<String>()),
|
||||
val pendingAttestations: MutableStateFlow<Map<HexKey, String>> = MutableStateFlow<Map<HexKey, String>>(mapOf()),
|
||||
@@ -437,6 +439,16 @@ class AccountSettings(
|
||||
}
|
||||
}
|
||||
|
||||
fun updateTrustProviderListTo(trustProviderList: TrustProviderListEvent?) {
|
||||
if (trustProviderList == null || trustProviderList.tags.isEmpty()) return
|
||||
|
||||
// Events might be different objects, we have to compare their ids.
|
||||
if (backupTrustProviderList?.id != trustProviderList.id) {
|
||||
backupTrustProviderList = trustProviderList
|
||||
saveAccountSettings()
|
||||
}
|
||||
}
|
||||
|
||||
fun updateMuteList(newMuteList: MuteListEvent?) {
|
||||
if (newMuteList == null || newMuteList.tags.isEmpty()) return
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ import com.vitorpamplona.quartz.experimental.nns.NNSEvent
|
||||
import com.vitorpamplona.quartz.experimental.profileGallery.ProfileGalleryEntryEvent
|
||||
import com.vitorpamplona.quartz.experimental.publicMessages.PublicMessageEvent
|
||||
import com.vitorpamplona.quartz.experimental.relationshipStatus.ContactCardEvent
|
||||
import com.vitorpamplona.quartz.experimental.trustedAssertions.list.TrustProviderListEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Address
|
||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
@@ -971,6 +972,12 @@ object LocalCache : ILocalCache {
|
||||
wasVerified: Boolean,
|
||||
) = consumeBaseReplaceable(event, relay, wasVerified)
|
||||
|
||||
private fun consume(
|
||||
event: TrustProviderListEvent,
|
||||
relay: NormalizedRelayUrl?,
|
||||
wasVerified: Boolean,
|
||||
) = consumeBaseReplaceable(event, relay, wasVerified)
|
||||
|
||||
private fun consume(
|
||||
event: ProxyRelayListEvent,
|
||||
relay: NormalizedRelayUrl?,
|
||||
@@ -2856,6 +2863,7 @@ object LocalCache : ILocalCache {
|
||||
is TorrentEvent -> consume(event, relay, wasVerified)
|
||||
is TorrentCommentEvent -> consume(event, relay, wasVerified)
|
||||
is TrustedRelayListEvent -> consume(event, relay, wasVerified)
|
||||
is TrustProviderListEvent -> consume(event, relay, wasVerified)
|
||||
is VideoHorizontalEvent -> consume(event, relay, wasVerified)
|
||||
is VideoNormalEvent -> consume(event, relay, wasVerified)
|
||||
is VideoVerticalEvent -> consume(event, relay, wasVerified)
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.model.trustedAssertions
|
||||
|
||||
import com.vitorpamplona.quartz.experimental.trustedAssertions.list.TrustProviderListEvent
|
||||
import com.vitorpamplona.quartz.experimental.trustedAssertions.list.serviceProviderSet
|
||||
import com.vitorpamplona.quartz.experimental.trustedAssertions.list.serviceProviders
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEventCache
|
||||
|
||||
class TrustProviderListDecryptionCache(
|
||||
val signer: NostrSigner,
|
||||
) {
|
||||
val cachedPrivateLists = PrivateTagArrayEventCache<TrustProviderListEvent>(signer)
|
||||
|
||||
fun cachedServiceProviders(event: TrustProviderListEvent) = cachedPrivateLists.mergeTagListPrecached(event).serviceProviders()
|
||||
|
||||
fun cachedServiceProviderSet(event: TrustProviderListEvent) = cachedPrivateLists.mergeTagListPrecached(event).serviceProviderSet()
|
||||
|
||||
suspend fun serviceProviders(event: TrustProviderListEvent) = cachedPrivateLists.mergeTagList(event).serviceProviders()
|
||||
|
||||
suspend fun serviceProviderSet(event: TrustProviderListEvent) = cachedPrivateLists.mergeTagList(event).serviceProviderSet()
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.model.trustedAssertions
|
||||
|
||||
import com.vitorpamplona.amethyst.model.AccountSettings
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.NoteState
|
||||
import com.vitorpamplona.quartz.experimental.trustedAssertions.list.TrustProviderListEvent
|
||||
import com.vitorpamplona.quartz.experimental.trustedAssertions.list.tags.ServiceProviderTag
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.transformLatest
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class TrustProviderListState(
|
||||
val signer: NostrSigner,
|
||||
val cache: LocalCache,
|
||||
val decryptionCache: TrustProviderListDecryptionCache,
|
||||
val scope: CoroutineScope,
|
||||
val settings: AccountSettings,
|
||||
) {
|
||||
// Creates a long-term reference for this note so that the GC doesn't collect the note it self
|
||||
val trustProviderListNote = cache.getOrCreateAddressableNote(getTrustProviderListAddress())
|
||||
|
||||
fun getTrustProviderListAddress() = TrustProviderListEvent.createAddress(signer.pubKey)
|
||||
|
||||
fun getTrustProviderListFlow(): StateFlow<NoteState> = trustProviderListNote.flow().metadata.stateFlow
|
||||
|
||||
fun getTrustProviderList(): TrustProviderListEvent? = trustProviderListNote.event as? TrustProviderListEvent
|
||||
|
||||
suspend fun trustProviderListWithBackup(note: Note): Set<ServiceProviderTag> {
|
||||
val event = note.event as? TrustProviderListEvent ?: settings.backupTrustProviderList
|
||||
return event?.let { decryptionCache.serviceProviderSet(it) } ?: emptySet()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
val liveTrustProviderList: StateFlow<Set<ServiceProviderTag>> =
|
||||
getTrustProviderListFlow()
|
||||
.transformLatest { noteState ->
|
||||
emit(trustProviderListWithBackup(noteState.note))
|
||||
}.onStart {
|
||||
emit(trustProviderListWithBackup(trustProviderListNote))
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
emptySet(),
|
||||
)
|
||||
|
||||
init {
|
||||
settings.backupTrustProviderList?.let { event ->
|
||||
Log.d("AccountRegisterObservers", "Loading saved ephemeral chat list")
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
LocalCache.justConsumeMyOwnEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "TrustProviderList Collector Start")
|
||||
getTrustProviderListFlow().collect { noteState ->
|
||||
Log.d("AccountRegisterObservers", "TrustProviderList List for ${signer.pubKey}")
|
||||
(noteState.note.event as? TrustProviderListEvent)?.let {
|
||||
settings.updateTrustProviderListTo(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -37,7 +37,9 @@ class AuthCoordinator(
|
||||
scope: CoroutineScope,
|
||||
) {
|
||||
private val authWithAccounts = ListWithUniqueSetCache<ScreenAuthAccount, Account> { it.account }
|
||||
private val tempAccount = NostrSignerSync()
|
||||
private val tempAccount by lazy {
|
||||
NostrSignerSync()
|
||||
}
|
||||
|
||||
val receiver =
|
||||
RelayAuthenticator(
|
||||
|
||||
@@ -123,12 +123,17 @@ fun WatchAndRenderRelay(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val relay by baseNote
|
||||
.flow()
|
||||
.relays.stateFlow
|
||||
.mapNotNull {
|
||||
it.note.relays.getOrNull(relayIndex)
|
||||
}.collectAsStateWithLifecycle(baseNote.relays.getOrNull(relayIndex))
|
||||
val flow =
|
||||
remember(baseNote, relayIndex) {
|
||||
baseNote
|
||||
.flow()
|
||||
.relays.stateFlow
|
||||
.mapNotNull {
|
||||
it.note.relays.getOrNull(relayIndex)
|
||||
}
|
||||
}
|
||||
|
||||
val relay by flow.collectAsStateWithLifecycle(baseNote.relays.getOrNull(relayIndex))
|
||||
|
||||
CrossfadeIfEnabled(targetState = relay, label = "RenderRelay", modifier = Size17Modifier, accountViewModel = accountViewModel) {
|
||||
if (it != null) {
|
||||
|
||||
@@ -38,7 +38,6 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.vitorpamplona.amethyst.model.AddressableNote
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote
|
||||
@@ -113,7 +112,7 @@ fun DisplayHighlightPreview() {
|
||||
makeItShort = false,
|
||||
canPreview = true,
|
||||
quotesLeft = 3,
|
||||
backgroundColor = mutableStateOf(Color.White),
|
||||
backgroundColor = remember { mutableStateOf(Color.White) },
|
||||
accountViewModel = mockAccountViewModel(),
|
||||
nav = EmptyNav(),
|
||||
)
|
||||
@@ -137,7 +136,7 @@ fun DisplayHighlightPreviewNewLine() {
|
||||
makeItShort = false,
|
||||
canPreview = true,
|
||||
quotesLeft = 3,
|
||||
backgroundColor = mutableStateOf(Color.White),
|
||||
backgroundColor = remember { mutableStateOf(Color.White) },
|
||||
accountViewModel = mockAccountViewModel(),
|
||||
nav = EmptyNav(),
|
||||
)
|
||||
@@ -239,7 +238,7 @@ private fun DisplayQuoteAuthor(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
var userBase by remember { mutableStateOf<User?>(authorHex?.let { accountViewModel.getUserIfExists(it) }) }
|
||||
var userBase by remember { mutableStateOf(authorHex?.let { accountViewModel.getUserIfExists(it) }) }
|
||||
|
||||
if (userBase == null && authorHex != null) {
|
||||
LaunchedEffect(authorHex) {
|
||||
@@ -248,7 +247,7 @@ private fun DisplayQuoteAuthor(
|
||||
}
|
||||
|
||||
var addressable by remember {
|
||||
mutableStateOf<AddressableNote?>(postAddress?.let { accountViewModel.getAddressableNoteIfExists(it) })
|
||||
mutableStateOf(postAddress?.let { accountViewModel.getAddressableNoteIfExists(it) })
|
||||
}
|
||||
|
||||
if (addressable == null && postAddress != null) {
|
||||
@@ -264,7 +263,7 @@ private fun DisplayQuoteAuthor(
|
||||
}
|
||||
|
||||
var version by remember {
|
||||
mutableStateOf<Note?>(postVersion?.let { accountViewModel.getNoteIfExists(it.eventId) })
|
||||
mutableStateOf(postVersion?.let { accountViewModel.getNoteIfExists(it.eventId) })
|
||||
}
|
||||
|
||||
if (version == null && postVersion != null) {
|
||||
@@ -324,7 +323,7 @@ fun DisplayEntryForNote(
|
||||
) {
|
||||
val noteState by observeNote(note, accountViewModel)
|
||||
|
||||
val author = userBase ?: noteState?.note?.author
|
||||
val author = userBase ?: noteState.note.author
|
||||
|
||||
if (author != null) {
|
||||
RenderUserAsClickableText(author, null, accountViewModel, nav)
|
||||
@@ -361,7 +360,7 @@ fun DisplayEntryForAUrl(
|
||||
remember {
|
||||
try {
|
||||
URL(url)
|
||||
} catch (e: Exception) {
|
||||
} catch (_: Exception) {
|
||||
Log.w("Note Compose", "Invalid URI: $url")
|
||||
null
|
||||
}
|
||||
|
||||
+9
-13
@@ -65,7 +65,6 @@ import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -85,17 +84,14 @@ class AccountStateViewModel : ViewModel() {
|
||||
fun loginWithDefaultAccountIfLoggedOff() {
|
||||
// pulls account from storage.
|
||||
if (_accountContent.value !is AccountState.LoggedIn) {
|
||||
viewModelScope.launch {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
loginWithDefaultAccount()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun loginWithDefaultAccount(route: Route? = null) {
|
||||
val accountSettings =
|
||||
withContext(Dispatchers.IO) {
|
||||
LocalPreferences.loadAccountConfigFromEncryptedStorage()
|
||||
}
|
||||
val accountSettings = LocalPreferences.loadAccountConfigFromEncryptedStorage()
|
||||
|
||||
if (accountSettings != null) {
|
||||
startUI(accountSettings, route)
|
||||
@@ -135,7 +131,7 @@ class AccountStateViewModel : ViewModel() {
|
||||
throw Exception("Invalid key while trying to login with external signer")
|
||||
}
|
||||
|
||||
val account =
|
||||
val accountSettings =
|
||||
if (loginWithExternalSigner) {
|
||||
AccountSettings(
|
||||
keyPair = KeyPair(pubKey = pubKeyParsed),
|
||||
@@ -164,18 +160,18 @@ class AccountStateViewModel : ViewModel() {
|
||||
)
|
||||
}
|
||||
|
||||
LocalPreferences.setDefaultAccount(account)
|
||||
LocalPreferences.setDefaultAccount(accountSettings)
|
||||
|
||||
startUI(account)
|
||||
startUI(accountSettings)
|
||||
}
|
||||
|
||||
@OptIn(FlowPreview::class)
|
||||
suspend fun startUI(
|
||||
fun startUI(
|
||||
accountSettings: AccountSettings,
|
||||
route: Route? = null,
|
||||
) = withContext(Dispatchers.Main) {
|
||||
) {
|
||||
val account = Amethyst.instance.accountsCache.loadAccount(accountSettings)
|
||||
_accountContent.update {
|
||||
AccountState.LoggedIn(Amethyst.instance.accountsCache.loadAccount(accountSettings), route)
|
||||
AccountState.LoggedIn(account, route)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user