mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-08 23:54:39 +00:00
Merge branch 'main' into image-gallery-improve-layout
This commit is contained in:
+2
-1
@@ -8,7 +8,8 @@ trim_trailing_whitespace = true
|
||||
max_line_length = 5000
|
||||
ij_kotlin_allow_trailing_comma=true
|
||||
ij_kotlin_allow_trailing_comma_on_call_site=true
|
||||
ktlint_function_naming_ignore_when_annotated_with=Composable, Test
|
||||
ktlint_function_naming_ignore_when_annotated_with=Composable
|
||||
ktlint_standard_no-unused-imports=enabled
|
||||
|
||||
[*.gradle]
|
||||
indent_size = 4
|
||||
@@ -86,7 +86,7 @@ class AppModules(
|
||||
}
|
||||
|
||||
val applicationIOScope = CoroutineScope(Dispatchers.IO + SupervisorJob() + exceptionHandler)
|
||||
val applicationDefaultScope = CoroutineScope(Dispatchers.Default + SupervisorJob() + exceptionHandler)
|
||||
val applicationDefaultScope = CoroutineScope(Dispatchers.IO + SupervisorJob() + exceptionHandler)
|
||||
|
||||
// Blocking load of UI Preferences to avoid theme/language blinking
|
||||
val uiPrefs by lazy {
|
||||
|
||||
@@ -38,8 +38,8 @@ import com.vitorpamplona.amethyst.model.nip01UserMetadata.UserMetadataState
|
||||
import com.vitorpamplona.amethyst.model.nip02FollowLists.DeclaredFollowsPerOutboxRelay
|
||||
import com.vitorpamplona.amethyst.model.nip02FollowLists.FollowListOutboxOrProxyRelays
|
||||
import com.vitorpamplona.amethyst.model.nip02FollowLists.FollowListReusedOutboxOrProxyRelays
|
||||
import com.vitorpamplona.amethyst.model.nip02FollowLists.FollowListState
|
||||
import com.vitorpamplona.amethyst.model.nip02FollowLists.FollowsPerOutboxRelay
|
||||
import com.vitorpamplona.amethyst.model.nip02FollowLists.Kind3FollowListState
|
||||
import com.vitorpamplona.amethyst.model.nip03Timestamp.OtsState
|
||||
import com.vitorpamplona.amethyst.model.nip17Dms.DmInboxRelayState
|
||||
import com.vitorpamplona.amethyst.model.nip17Dms.DmRelayListState
|
||||
@@ -205,6 +205,7 @@ import com.vitorpamplona.quartz.nip98HttpAuth.HTTPAuthorizationEvent
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.VoiceEvent
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.VoiceReplyEvent
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import com.vitorpamplona.quartz.utils.containsAny
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -265,7 +266,7 @@ class Account(
|
||||
val blockedRelayListDecryptionCache = BlockedRelayListDecryptionCache(signer)
|
||||
val blockedRelayList = BlockedRelayListState(signer, cache, blockedRelayListDecryptionCache, scope, settings)
|
||||
|
||||
val kind3FollowList = FollowListState(signer, cache, scope, settings)
|
||||
val kind3FollowList = Kind3FollowListState(signer, cache, scope, settings)
|
||||
val followSetsState = FollowSetState(signer, cache, scope)
|
||||
|
||||
val ephemeralChatListDecryptionCache = EphemeralChatListDecryptionCache(signer)
|
||||
@@ -1677,6 +1678,16 @@ class Account(
|
||||
note.countReportAuthorsBy(followingKeySet()) < 5 // if it has 5 reports by reliable users
|
||||
}
|
||||
|
||||
fun isDecryptedContentHidden(noteEvent: PrivateDmEvent): Boolean =
|
||||
if (hiddenUsers.flow.value.hiddenWordsCase
|
||||
.isNotEmpty()
|
||||
) {
|
||||
val decrypted = privateDMDecryptionCache.cachedDM(noteEvent)
|
||||
decrypted?.containsAny(hiddenUsers.flow.value.hiddenWordsCase) == true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
fun isFollowing(user: User): Boolean = user.pubkeyHex in followingKeySet()
|
||||
|
||||
fun isFollowing(user: HexKey): Boolean = user in followingKeySet()
|
||||
@@ -1761,7 +1772,7 @@ class Account(
|
||||
fun observeDonatedInThisVersion() =
|
||||
settings
|
||||
.observeDonatedInVersion(BuildConfig.VERSION_NAME)
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(scope, SharingStarted.Eagerly, hasDonatedInThisVersion())
|
||||
|
||||
fun markDonatedInThisVersion() = settings.markDonatedInThisVersion(BuildConfig.VERSION_NAME)
|
||||
|
||||
@@ -1962,7 +1962,7 @@ object LocalCache : ILocalCache {
|
||||
|
||||
requestNote?.let { request -> zappedNote?.addZapPayment(request, note) }
|
||||
|
||||
GlobalScope.launch(Dispatchers.Default) {
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
responseCallback(event)
|
||||
}
|
||||
|
||||
@@ -2913,10 +2913,10 @@ class LocalCacheFlow {
|
||||
val deletedEventBundles = _deletedEventBundles.asSharedFlow() // read-only public view
|
||||
|
||||
// Refreshes observers in batches.
|
||||
private val bundler = BundledInsert<Note>(1000, Dispatchers.Default)
|
||||
private val bundler = BundledInsert<Note>(1000, Dispatchers.IO)
|
||||
|
||||
// Refreshes observers in batches.
|
||||
private val bundler2 = BundledInsert<Note>(1000, Dispatchers.Default)
|
||||
private val bundler2 = BundledInsert<Note>(1000, Dispatchers.IO)
|
||||
|
||||
fun newNote(newNote: Note) {
|
||||
bundler.invalidateList(newNote) { bundledNewNotes ->
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ class AccountCacheState(
|
||||
client = client,
|
||||
scope =
|
||||
CoroutineScope(
|
||||
Dispatchers.Default +
|
||||
Dispatchers.IO +
|
||||
SupervisorJob() +
|
||||
CoroutineExceptionHandler { _, throwable ->
|
||||
Log.e("AccountCacheState", "Account ${signer.pubKey} caught exception: ${throwable.message}", throwable)
|
||||
|
||||
+2
-2
@@ -66,7 +66,7 @@ class PrivateStorageRelayListState(
|
||||
.map { normalizePrivateOutboxRelayListWithBackup(it.note) }
|
||||
.onStart {
|
||||
emit(normalizePrivateOutboxRelayListWithBackup(privateOutboxListNote))
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -99,7 +99,7 @@ class PrivateStorageRelayListState(
|
||||
}
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "Private Home Relay List Collector Start")
|
||||
getPrivateOutboxRelayListFlow().collect { noteState ->
|
||||
Log.d("AccountRegisterObservers", "Updating Private Home Relay List for ${signer.pubKey}")
|
||||
|
||||
+2
-2
@@ -69,7 +69,7 @@ class EphemeralChatListState(
|
||||
emit(ephemeralChatListWithBackup(noteState.note))
|
||||
}.onStart {
|
||||
emit(ephemeralChatListWithBackup(ephemeralChatListNote))
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -117,7 +117,7 @@ class EphemeralChatListState(
|
||||
}
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "EphemeralChatList Collector Start")
|
||||
getEphemeralChatListFlow().collect { noteState ->
|
||||
Log.d("AccountRegisterObservers", "EphemeralChatList List for ${signer.pubKey}")
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ class LocalRelayListState(
|
||||
val flow =
|
||||
settings.localRelayServers
|
||||
.map { normalizeLocalRelayListWithBackup(it) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ class AccountHomeRelayState(
|
||||
local.flow,
|
||||
) { nip65Outbox, privateOutBox, localRelays ->
|
||||
nip65Outbox + privateOutBox + localRelays
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ class AccountOutboxRelayState(
|
||||
broadcast.flow,
|
||||
) { nip65Outbox, privateOutBox, localRelays, broadcastRelays ->
|
||||
nip65Outbox + privateOutBox + localRelays + broadcastRelays
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ class NotificationInboxRelayState(
|
||||
localRelayList.flow,
|
||||
) { nip65Inbox, localRelays ->
|
||||
nip65Inbox + localRelays
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+6
-6
@@ -22,7 +22,6 @@ package com.vitorpamplona.amethyst.model.nip01UserMetadata
|
||||
|
||||
import com.vitorpamplona.amethyst.model.AccountSettings
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.model.UserState
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
@@ -40,13 +39,14 @@ class UserMetadataState(
|
||||
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 user = cache.getOrCreateUser(signer.pubKey)
|
||||
|
||||
// fun getEphemeralChatListAddress() = cache.getOrCreateUser(signer.pubKey)
|
||||
|
||||
fun getUserMetadataUser(): User = cache.getOrCreateUser(signer.pubKey)
|
||||
fun getUserMetadataFlow(): StateFlow<UserState> = user.flow().metadata.stateFlow
|
||||
|
||||
fun getUserMetadataFlow(): StateFlow<UserState> = getUserMetadataUser().flow().metadata.stateFlow
|
||||
|
||||
fun getUserMetadataEvent(): MetadataEvent? = getUserMetadataUser().latestMetadata
|
||||
fun getUserMetadataEvent(): MetadataEvent? = user.latestMetadata
|
||||
|
||||
suspend fun sendNewUserMetadata(
|
||||
name: String? = null,
|
||||
@@ -112,7 +112,7 @@ class UserMetadataState(
|
||||
}
|
||||
|
||||
// saves contact list for the next time.
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "Kind 0 Collector Start")
|
||||
getUserMetadataFlow().collect {
|
||||
Log.d("AccountRegisterObservers", "Updating Kind 0 ${it.user.toBestDisplayName()}")
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.transformLatest
|
||||
|
||||
class DeclaredFollowsPerOutboxRelay(
|
||||
kind3Follows: FollowListState,
|
||||
kind3Follows: Kind3FollowListState,
|
||||
val cache: LocalCache,
|
||||
scope: CoroutineScope,
|
||||
) {
|
||||
@@ -55,7 +55,7 @@ class DeclaredFollowsPerOutboxRelay(
|
||||
calculator.authorsPerRelaySnapshot(kind3Follows.flow.value.authors, cache) { it },
|
||||
)
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+5
-5
@@ -42,7 +42,7 @@ import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.transformLatest
|
||||
|
||||
class FollowListOutboxOrProxyRelays(
|
||||
kind3Follows: FollowListState,
|
||||
kind3Follows: Kind3FollowListState,
|
||||
blockedRelayList: BlockedRelayListState,
|
||||
proxyRelayList: ProxyRelayListState,
|
||||
val cache: LocalCache,
|
||||
@@ -60,7 +60,7 @@ class FollowListOutboxOrProxyRelays(
|
||||
OutboxRelayLoader(true).authorsPerRelaySnapshot(kind3Follows.flow.value.authors, cache) { it.keys },
|
||||
)
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -72,7 +72,7 @@ class FollowListOutboxOrProxyRelays(
|
||||
followList.minus(blockedRelays)
|
||||
}.onStart {
|
||||
emit(outboxRelayFlow.value.minus(blockedRelayList.flow.value.toSet()))
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -94,7 +94,7 @@ class FollowListOutboxOrProxyRelays(
|
||||
outboxRelayMinusBlockedFlow.value
|
||||
},
|
||||
)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -108,7 +108,7 @@ class FollowListOutboxOrProxyRelays(
|
||||
relayList.mapTo(mutableSetOf()) { it.url }
|
||||
}.onStart {
|
||||
emit(flow.value.mapTo(mutableSetOf()) { it.url })
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+5
-5
@@ -42,7 +42,7 @@ import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.transformLatest
|
||||
|
||||
class FollowListReusedOutboxOrProxyRelays(
|
||||
kind3Follows: FollowListState,
|
||||
kind3Follows: Kind3FollowListState,
|
||||
blockedRelayList: BlockedRelayListState,
|
||||
proxyRelayList: ProxyRelayListState,
|
||||
val cache: LocalCache,
|
||||
@@ -78,7 +78,7 @@ class FollowListReusedOutboxOrProxyRelays(
|
||||
},
|
||||
)
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -90,7 +90,7 @@ class FollowListReusedOutboxOrProxyRelays(
|
||||
followList.minus(blockedRelays)
|
||||
}.onStart {
|
||||
emit(outboxRelayFlow.value.minus(blockedRelayList.flow.value.toSet()))
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -112,7 +112,7 @@ class FollowListReusedOutboxOrProxyRelays(
|
||||
outboxRelayMinusBlockedFlow.value
|
||||
},
|
||||
)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -126,7 +126,7 @@ class FollowListReusedOutboxOrProxyRelays(
|
||||
relayList.mapTo(mutableSetOf()) { it.url }
|
||||
}.onStart {
|
||||
emit(flow.value.mapTo(mutableSetOf()) { it.url })
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+4
-4
@@ -42,7 +42,7 @@ import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.transformLatest
|
||||
|
||||
class FollowsPerOutboxRelay(
|
||||
kind3Follows: FollowListState,
|
||||
kind3Follows: Kind3FollowListState,
|
||||
blockedRelayList: BlockedRelayListState,
|
||||
proxyRelayList: ProxyRelayListState,
|
||||
val cache: LocalCache,
|
||||
@@ -60,7 +60,7 @@ class FollowsPerOutboxRelay(
|
||||
OutboxRelayLoader().authorsPerRelaySnapshot(kind3Follows.flow.value.authors, cache) { it },
|
||||
)
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -72,7 +72,7 @@ class FollowsPerOutboxRelay(
|
||||
followList.minus(blockedRelays)
|
||||
}.onStart {
|
||||
emit(outboxPerRelayFlow.value.minus(blockedRelayList.flow.value.toSet()))
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -96,7 +96,7 @@ class FollowsPerOutboxRelay(
|
||||
} else {
|
||||
emit(proxyRelayList.flow.value.associateWith { kind3Follows.flow.value.authors })
|
||||
}
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+10
-31
@@ -25,12 +25,10 @@ import com.vitorpamplona.amethyst.model.AccountSettings
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.model.UserState
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashes
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip02FollowList.tags.ContactTag
|
||||
import com.vitorpamplona.quartz.nip73ExternalIds.location.GeohashId
|
||||
import com.vitorpamplona.quartz.nip73ExternalIds.topics.HashtagId
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
@@ -45,7 +43,7 @@ import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.transformLatest
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class FollowListState(
|
||||
class Kind3FollowListState(
|
||||
val signer: NostrSigner,
|
||||
val cache: LocalCache,
|
||||
val scope: CoroutineScope,
|
||||
@@ -66,7 +64,7 @@ class FollowListState(
|
||||
|
||||
val flow =
|
||||
innerFlow
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -77,11 +75,11 @@ class FollowListState(
|
||||
// Creates a long-term reference for all follows of a user
|
||||
val userList =
|
||||
flow
|
||||
.map {
|
||||
it.authors.mapNotNull {
|
||||
.map { kind3Follows ->
|
||||
kind3Follows.authors.mapNotNull {
|
||||
cache.checkGetOrCreateUser(it)
|
||||
}
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -96,15 +94,9 @@ class FollowListState(
|
||||
*/
|
||||
@Immutable
|
||||
class Kind3Follows(
|
||||
val authors: Set<String> = emptySet(),
|
||||
val authorsPlusMe: Set<String>,
|
||||
val hashtags: Set<String> = emptySet(),
|
||||
val geotags: Set<String> = emptySet(),
|
||||
val communities: Set<String> = emptySet(),
|
||||
) {
|
||||
val geotagScopes: Set<String> = geotags.mapTo(mutableSetOf<String>()) { GeohashId.toScope(it) }
|
||||
val hashtagScopes: Set<String> = hashtags.mapTo(mutableSetOf<String>()) { HashtagId.toScope(it) }
|
||||
}
|
||||
val authors: Set<HexKey> = emptySet(),
|
||||
val authorsPlusMe: Set<HexKey>,
|
||||
)
|
||||
|
||||
fun buildKind3Follows(latestContactList: ContactListEvent?): Kind3Follows {
|
||||
// makes sure the output include only valid p tags
|
||||
@@ -113,19 +105,6 @@ class FollowListState(
|
||||
return Kind3Follows(
|
||||
authors = verifiedFollowingUsers,
|
||||
authorsPlusMe = verifiedFollowingUsers + signer.pubKey,
|
||||
hashtags =
|
||||
latestContactList
|
||||
?.unverifiedFollowTagSet()
|
||||
?.map { it.lowercase() }
|
||||
?.toSet() ?: emptySet(),
|
||||
geotags =
|
||||
latestContactList
|
||||
?.geohashes()
|
||||
?.toSet() ?: emptySet(),
|
||||
communities =
|
||||
latestContactList
|
||||
?.verifiedFollowAddressSet()
|
||||
?.toSet() ?: emptySet(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -166,7 +145,7 @@ class FollowListState(
|
||||
}
|
||||
|
||||
// saves contact list for the next time.
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "Kind 3 Collector Start")
|
||||
getFollowListFlow().collect {
|
||||
Log.d("AccountRegisterObservers", "Updating Kind 3 ${signer.pubKey}")
|
||||
+1
-1
@@ -42,7 +42,7 @@ class IncomingOtsEventVerifier(
|
||||
newNotes.forEach {
|
||||
consume(it)
|
||||
}
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ class DmInboxRelayState(
|
||||
localRelayList.flow,
|
||||
) { nip65Inbox, dmRelayList, privateOutBox, localRelays ->
|
||||
nip65Inbox + dmRelayList + privateOutBox + localRelays
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+2
-2
@@ -64,7 +64,7 @@ class DmRelayListState(
|
||||
getDMRelayListFlow()
|
||||
.map { normalizeDMRelayListWithBackup(it.note) }
|
||||
.onStart { emit(normalizeDMRelayListWithBackup(dmListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -96,7 +96,7 @@ class DmRelayListState(
|
||||
}
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "NIP-17 Relay List Collector Start")
|
||||
getDMRelayListFlow().collect {
|
||||
Log.d("AccountRegisterObservers", "Updating DM Relay List for ${signer.pubKey}")
|
||||
|
||||
+3
-3
@@ -71,7 +71,7 @@ class PublicChatListState(
|
||||
emit(publicChatListWithBackup(noteState.note))
|
||||
}.onStart {
|
||||
emit(publicChatListWithBackup(publicChatListNote))
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -85,7 +85,7 @@ class PublicChatListState(
|
||||
it.mapTo(mutableSetOf()) { it.eventId }
|
||||
}.onStart {
|
||||
emit(flow.value.mapTo(mutableSetOf()) { it.eventId })
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -132,7 +132,7 @@ class PublicChatListState(
|
||||
}
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "Channel List Collector Start")
|
||||
getChannelListFlow().collect {
|
||||
Log.d("AccountRegisterObservers", "Channel List for ${signer.pubKey}")
|
||||
|
||||
+2
-2
@@ -75,7 +75,7 @@ class EmojiPackState(
|
||||
emit(convertEmojiSelectionPack(it.note.event as? EmojiPackSelectionEvent))
|
||||
}.onStart {
|
||||
emit(convertEmojiSelectionPack(getEmojiPackSelection()))
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -120,7 +120,7 @@ class EmojiPackState(
|
||||
)?.map { it.value }?.toTypedArray() ?: emptyArray(),
|
||||
),
|
||||
)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+3
-3
@@ -76,7 +76,7 @@ class NwcSignerState(
|
||||
settings.zapPaymentRequest
|
||||
.map {
|
||||
buildSigner(it) ?: signer
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -91,7 +91,7 @@ class NwcSignerState(
|
||||
nip47Signer
|
||||
.map {
|
||||
NostrWalletConnectRequestCache(it)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(scope, SharingStarted.Eagerly, NostrWalletConnectRequestCache(nip47Signer.value))
|
||||
|
||||
/**
|
||||
@@ -102,7 +102,7 @@ class NwcSignerState(
|
||||
nip47Signer
|
||||
.map {
|
||||
NostrWalletConnectResponseCache(it)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(scope, SharingStarted.Eagerly, NostrWalletConnectResponseCache(nip47Signer.value))
|
||||
|
||||
fun buildSigner(uri: Nip47WalletConnect.Nip47URINorm?) =
|
||||
|
||||
+7
-7
@@ -78,7 +78,7 @@ class BookmarkListState(
|
||||
}.onStart {
|
||||
emit(publicBookmarks(bookmarkList))
|
||||
}.debounce(100)
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -93,7 +93,7 @@ class BookmarkListState(
|
||||
}.onStart {
|
||||
emit(privateBookmarks(bookmarkList))
|
||||
}.debounce(100)
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -107,7 +107,7 @@ class BookmarkListState(
|
||||
.mapNotNull {
|
||||
if (it is EventBookmark) it.eventId else null
|
||||
}.toSet()
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -121,7 +121,7 @@ class BookmarkListState(
|
||||
.mapNotNull {
|
||||
if (it is AddressBookmark) it.address else null
|
||||
}.toSet()
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -135,7 +135,7 @@ class BookmarkListState(
|
||||
.mapNotNull {
|
||||
if (it is EventBookmark) it.eventId else null
|
||||
}.toSet()
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -149,7 +149,7 @@ class BookmarkListState(
|
||||
.mapNotNull {
|
||||
if (it is AddressBookmark) it.address else null
|
||||
}.toSet()
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -185,7 +185,7 @@ class BookmarkListState(
|
||||
emit(bookmarkList(private, public))
|
||||
}.onStart {
|
||||
emit(bookmarkList(privateBookmarks.value, publicBookmarks.value))
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -93,7 +93,7 @@ class HiddenUsersState(
|
||||
settings.syncedSettings.security.showSensitiveContent.value,
|
||||
),
|
||||
)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ class BlockPeopleListState(
|
||||
getBlockListFlow()
|
||||
.map { blockListWithBackup(it.note) }
|
||||
.onStart { emit(blockListWithBackup(blockListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+2
-2
@@ -67,7 +67,7 @@ class BlockedRelayListState(
|
||||
.map {
|
||||
normalizeBlockedRelayListWithBackup(it.note)
|
||||
}.onStart { emit(normalizeBlockedRelayListWithBackup(blockedListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -99,7 +99,7 @@ class BlockedRelayListState(
|
||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsumeMyOwnEvent(it) }
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "Blocked Relay List Collector Start")
|
||||
getBlockedRelayListFlow().collect {
|
||||
Log.d("AccountRegisterObservers", "Updating Blocked Relay List for ${signer.pubKey}")
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ class BroadcastRelayListState(
|
||||
getBroadcastRelayListFlow()
|
||||
.map { normalizeBroadcastRelayListWithBackup(it.note) }
|
||||
.onStart { emit(normalizeBroadcastRelayListWithBackup(broadcastListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -72,5 +72,5 @@ class GeohashListDecryptionCache(
|
||||
emit(EmptyGeohashListCard)
|
||||
}
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
+3
-3
@@ -58,7 +58,7 @@ class GeohashListState(
|
||||
|
||||
suspend fun geohashListWithBackup(note: Note): Set<String> {
|
||||
val event = note.event as? GeohashListEvent ?: settings.backupGeohashList
|
||||
return event?.let { decryptionCache.geohashes(it) } ?: emptySet()
|
||||
return event?.let { decryptionCache.geohashes(it).mapTo(mutableSetOf()) { it.lowercase() } } ?: emptySet()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@@ -68,7 +68,7 @@ class GeohashListState(
|
||||
emit(geohashListWithBackup(noteState.note))
|
||||
}.onStart {
|
||||
emit(geohashListWithBackup(geohashListNote))
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -114,7 +114,7 @@ class GeohashListState(
|
||||
}
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "Geohash List Collector Start")
|
||||
getGeohashListFlow().collect { noteState ->
|
||||
Log.d("AccountRegisterObservers", "Geohash List for ${signer.pubKey}")
|
||||
|
||||
+9
-9
@@ -58,7 +58,7 @@ class HashtagListState(
|
||||
|
||||
suspend fun hashtagListWithBackup(note: Note): Set<String> {
|
||||
val event = note.event as? HashtagListEvent ?: settings.backupHashtagList
|
||||
return event?.let { decryptionCache.hashtags(it) } ?: emptySet()
|
||||
return event?.let { decryptionCache.hashtags(it).mapTo(mutableSetOf()) { it.lowercase() } } ?: emptySet()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@@ -68,10 +68,10 @@ class HashtagListState(
|
||||
emit(hashtagListWithBackup(noteState.note))
|
||||
}.onStart {
|
||||
emit(hashtagListWithBackup(hashtagListNote))
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Companion.Eagerly,
|
||||
SharingStarted.Eagerly,
|
||||
emptySet(),
|
||||
)
|
||||
|
||||
@@ -79,9 +79,9 @@ class HashtagListState(
|
||||
val hashtagList = getHashtagList()
|
||||
|
||||
return if (hashtagList == null) {
|
||||
HashtagListEvent.Companion.create(hashtags, true, signer)
|
||||
HashtagListEvent.create(hashtags, true, signer)
|
||||
} else {
|
||||
HashtagListEvent.Companion.add(hashtagList, hashtags, true, signer)
|
||||
HashtagListEvent.add(hashtagList, hashtags, true, signer)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,9 +89,9 @@ class HashtagListState(
|
||||
val hashtagList = getHashtagList()
|
||||
|
||||
return if (hashtagList == null) {
|
||||
HashtagListEvent.Companion.create(hashtag, true, signer)
|
||||
HashtagListEvent.create(hashtag, true, signer)
|
||||
} else {
|
||||
HashtagListEvent.Companion.add(hashtagList, hashtag, true, signer)
|
||||
HashtagListEvent.add(hashtagList, hashtag, true, signer)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ class HashtagListState(
|
||||
val hashtagList = getHashtagList()
|
||||
|
||||
return if (hashtagList != null) {
|
||||
HashtagListEvent.Companion.remove(hashtagList, hashtag, signer)
|
||||
HashtagListEvent.remove(hashtagList, hashtag, signer)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@@ -114,7 +114,7 @@ class HashtagListState(
|
||||
}
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "Hashtag List Collector Start")
|
||||
getHashtagListFlow().collect {
|
||||
Log.d("AccountRegisterObservers", "Hashtag List for ${signer.pubKey}")
|
||||
|
||||
+3
-3
@@ -67,7 +67,7 @@ class IndexerRelayListState(
|
||||
getIndexerRelayListFlow()
|
||||
.map { normalizeIndexerRelayListWithBackup(it.note) }
|
||||
.onStart { emit(normalizeIndexerRelayListWithBackup(indexerListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -78,7 +78,7 @@ class IndexerRelayListState(
|
||||
getIndexerRelayListFlow()
|
||||
.map { normalizeIndexerRelayListWithBackupNoDefaults(it.note) }
|
||||
.onStart { emit(normalizeIndexerRelayListWithBackupNoDefaults(indexerListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -109,7 +109,7 @@ class IndexerRelayListState(
|
||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsumeMyOwnEvent(it) }
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "Index Relay List Collector Start")
|
||||
getIndexerRelayListFlow().collect {
|
||||
Log.d("AccountRegisterObservers", "Updating Index Relay List for ${signer.pubKey}")
|
||||
|
||||
+2
-2
@@ -67,7 +67,7 @@ class MuteListState(
|
||||
getMuteListFlow()
|
||||
.map { muteListWithBackup(it.note) }
|
||||
.onStart { emit(muteListWithBackup(muteListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -149,7 +149,7 @@ class MuteListState(
|
||||
}
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "Mute List Collector Start")
|
||||
getMuteListFlow().collect {
|
||||
Log.d("AccountRegisterObservers", "Updating Mute List for ${signer.pubKey}")
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ class ProxyRelayListState(
|
||||
getProxyRelayListFlow()
|
||||
.map { normalizeProxyRelayListWithBackup(it.note) }
|
||||
.onStart { emit(normalizeProxyRelayListWithBackup(proxyListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -72,5 +72,5 @@ open class GenericRelayListCache<T : PrivateTagArrayEvent>(
|
||||
emit(EmptyRelayListCard)
|
||||
}
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
+3
-3
@@ -67,7 +67,7 @@ class SearchRelayListState(
|
||||
getSearchRelayListFlow()
|
||||
.map { normalizeSearchRelayListWithBackup(it.note) }
|
||||
.onStart { emit(normalizeSearchRelayListWithBackup(searchListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Companion.Eagerly,
|
||||
@@ -78,7 +78,7 @@ class SearchRelayListState(
|
||||
getSearchRelayListFlow()
|
||||
.map { normalizeSearchRelayListWithBackupNoDefaults(it.note) }
|
||||
.onStart { emit(normalizeSearchRelayListWithBackupNoDefaults(searchListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -109,7 +109,7 @@ class SearchRelayListState(
|
||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsumeMyOwnEvent(it) }
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "Search Relay List Collector Start")
|
||||
getSearchRelayListFlow().collect {
|
||||
Log.d("AccountRegisterObservers", "Updating Search Relay List for ${signer.pubKey}")
|
||||
|
||||
+2
-2
@@ -65,7 +65,7 @@ class TrustedRelayListState(
|
||||
getTrustedRelayListFlow()
|
||||
.map { normalizeTrustedRelayListWithBackup(it.note) }
|
||||
.onStart { emit(normalizeTrustedRelayListWithBackup(trustedListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Companion.Eagerly,
|
||||
@@ -96,7 +96,7 @@ class TrustedRelayListState(
|
||||
GlobalScope.launch(Dispatchers.IO) { cache.justConsumeMyOwnEvent(it) }
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "Trusted Relay List Collector Start")
|
||||
getTrustedRelayListFlow().collect {
|
||||
Log.d("AccountRegisterObservers", "Updating Trusted Relay List for ${signer.pubKey}")
|
||||
|
||||
+4
-4
@@ -71,7 +71,7 @@ class Nip65RelayListState(
|
||||
getNIP65RelayListFlow()
|
||||
.map { normalizeNIP65WriteRelayListWithBackup(it.note) }
|
||||
.onStart { emit(normalizeNIP65ReadRelayListWithBackup(nip65ListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -82,7 +82,7 @@ class Nip65RelayListState(
|
||||
getNIP65RelayListFlow()
|
||||
.map { normalizeNIP65ReadRelayListWithBackup(it.note) }
|
||||
.onStart { emit(normalizeNIP65ReadRelayListWithBackup(nip65ListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -93,7 +93,7 @@ class Nip65RelayListState(
|
||||
getNIP65RelayListFlow()
|
||||
.map { normalizeNIP65AllRelayListWithBackupNoDefaults(it.note) }
|
||||
.onStart { emit(normalizeNIP65AllRelayListWithBackupNoDefaults(nip65ListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -124,7 +124,7 @@ class Nip65RelayListState(
|
||||
GlobalScope.launch(Dispatchers.IO) { cache.justConsumeMyOwnEvent(it) }
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "NIP-65 Relay List Collector Start")
|
||||
getNIP65RelayListFlow().collect {
|
||||
Log.d("AccountRegisterObservers", "Updating NIP-65 List for ${signer.pubKey}")
|
||||
|
||||
+3
-3
@@ -72,7 +72,7 @@ class CommunityListState(
|
||||
emit(communityListWithBackup(noteState.note))
|
||||
}.onStart {
|
||||
emit(communityListWithBackup(communityListNote))
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -86,7 +86,7 @@ class CommunityListState(
|
||||
hint.mapTo(mutableSetOf()) { it.address.toValue() }
|
||||
}.onStart {
|
||||
emit(flow.value.mapTo(mutableSetOf()) { it.address.toValue() })
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -147,7 +147,7 @@ class CommunityListState(
|
||||
}
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "Community List Collector Start")
|
||||
getCommunityListFlow().collect {
|
||||
Log.d("AccountRegisterObservers", "Community List for ${signer.pubKey}")
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ class AppSpecificState(
|
||||
}
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d("AccountRegisterObservers", "AppSpecificData Collector Start")
|
||||
getAppSpecificDataFlow().collect {
|
||||
try {
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ class FileStorageServerListState(
|
||||
getFileServersListFlow()
|
||||
.map { normalizeServers(it.note) }
|
||||
.onStart { emit(normalizeServers(fileStorageListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ class BlossomServerListState(
|
||||
getBlossomServersListFlow()
|
||||
.map { normalizeServers(it.note) }
|
||||
.onStart { emit(normalizeServers(blossomListNote)) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ class UpdatablePropertyFlow<T>(
|
||||
) {
|
||||
val stateFlow =
|
||||
flow
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope = scope,
|
||||
started = SharingStarted.Eagerly,
|
||||
|
||||
+37
-16
@@ -20,12 +20,15 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.model.serverList
|
||||
|
||||
import com.vitorpamplona.amethyst.model.nip02FollowLists.FollowListState
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.amethyst.model.nip02FollowLists.Kind3FollowListState
|
||||
import com.vitorpamplona.amethyst.model.nip51Lists.followSets.FollowSetState
|
||||
import com.vitorpamplona.amethyst.model.nip51Lists.geohashLists.GeohashListState
|
||||
import com.vitorpamplona.amethyst.model.nip51Lists.hashtagLists.HashtagListState
|
||||
import com.vitorpamplona.amethyst.model.nip72Communities.CommunityListState
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.follow.tags.CommunityTag
|
||||
import com.vitorpamplona.quartz.nip73ExternalIds.location.GeohashId
|
||||
import com.vitorpamplona.quartz.nip73ExternalIds.topics.HashtagId
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
@@ -37,38 +40,50 @@ import kotlinx.coroutines.flow.sample
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
|
||||
class MergedFollowListsState(
|
||||
val kind3List: FollowListState,
|
||||
val kind3List: Kind3FollowListState,
|
||||
val followSetList: FollowSetState,
|
||||
val hashtagList: HashtagListState,
|
||||
val geohashList: GeohashListState,
|
||||
val communityList: CommunityListState,
|
||||
val scope: CoroutineScope,
|
||||
) {
|
||||
/**
|
||||
This contains a big OR of everything the user wants to see in the a single feed.
|
||||
*/
|
||||
@Immutable
|
||||
class AllFollows(
|
||||
val authors: Set<String> = emptySet(),
|
||||
val hashtags: Set<String> = emptySet(),
|
||||
val geotags: Set<String> = emptySet(),
|
||||
val communities: Set<String> = emptySet(),
|
||||
) {
|
||||
val geotagScopes: Set<String> = geotags.mapTo(mutableSetOf<String>()) { GeohashId.toScope(it) }
|
||||
val hashtagScopes: Set<String> = hashtags.mapTo(mutableSetOf<String>()) { HashtagId.toScope(it) }
|
||||
}
|
||||
|
||||
fun mergeLists(
|
||||
kind3: FollowListState.Kind3Follows,
|
||||
kind3: Kind3FollowListState.Kind3Follows,
|
||||
followSetProfiles: Set<String>,
|
||||
hashtags: Set<String>,
|
||||
geohashes: Set<String>,
|
||||
community: Set<CommunityTag>,
|
||||
): FollowListState.Kind3Follows =
|
||||
FollowListState.Kind3Follows(
|
||||
kind3.authors + followSetProfiles,
|
||||
kind3.authorsPlusMe,
|
||||
kind3.hashtags + hashtags,
|
||||
kind3.geotags + geohashes,
|
||||
kind3.communities + community.map { it.address.toValue() },
|
||||
): AllFollows =
|
||||
AllFollows(
|
||||
authors = kind3.authors + followSetProfiles,
|
||||
hashtags = hashtags,
|
||||
geotags = geohashes,
|
||||
communities = community.mapTo(mutableSetOf()) { it.address.toValue() },
|
||||
)
|
||||
|
||||
val flow: StateFlow<FollowListState.Kind3Follows> =
|
||||
val flow: StateFlow<AllFollows> =
|
||||
combine(
|
||||
kind3List.flow,
|
||||
followSetList.profilesFlow,
|
||||
hashtagList.flow,
|
||||
geohashList.flow,
|
||||
communityList.flow,
|
||||
) { kind3, followSet, hashtag, geohash, community ->
|
||||
mergeLists(kind3, followSet, hashtag, geohash, community)
|
||||
}.onStart {
|
||||
::mergeLists,
|
||||
).onStart {
|
||||
emit(
|
||||
mergeLists(
|
||||
kind3List.flow.value,
|
||||
@@ -79,10 +94,16 @@ class MergedFollowListsState(
|
||||
),
|
||||
)
|
||||
}.sample(200)
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
kind3List.flow.value,
|
||||
mergeLists(
|
||||
kind3List.flow.value,
|
||||
followSetList.profilesFlow.value,
|
||||
hashtagList.flow.value,
|
||||
geohashList.flow.value,
|
||||
communityList.flow.value,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ class MergedFollowPlusMineRelayListsState(
|
||||
),
|
||||
),
|
||||
)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ class MergedFollowPlusMineWithIndexRelayListsState(
|
||||
),
|
||||
),
|
||||
)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ class MergedFollowPlusMineWithSearchRelayListsState(
|
||||
),
|
||||
),
|
||||
)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ class MergedServerListState(
|
||||
mergeServerList(nip96s, blossoms)
|
||||
}.onStart {
|
||||
emit(mergeServerList(fileServers.flow.value, blossomServers.flow.value))
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@ class TrustedRelayListsState(
|
||||
),
|
||||
),
|
||||
)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+3
-3
@@ -25,7 +25,7 @@ import com.vitorpamplona.amethyst.model.ALL_USER_FOLLOWS
|
||||
import com.vitorpamplona.amethyst.model.AROUND_ME
|
||||
import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.nip02FollowLists.FollowListState
|
||||
import com.vitorpamplona.amethyst.model.serverList.MergedFollowListsState
|
||||
import com.vitorpamplona.amethyst.model.topNavFeeds.allFollows.AllFollowsFeedFlow
|
||||
import com.vitorpamplona.amethyst.model.topNavFeeds.allUserFollows.AllUserFollowsFeedFlow
|
||||
import com.vitorpamplona.amethyst.model.topNavFeeds.aroundMe.AroundMeFeedFlow
|
||||
@@ -49,7 +49,7 @@ import kotlinx.coroutines.flow.transformLatest
|
||||
|
||||
class FeedTopNavFilterState(
|
||||
val feedFilterListName: MutableStateFlow<String>,
|
||||
val allFollows: StateFlow<FollowListState.Kind3Follows>,
|
||||
val allFollows: StateFlow<MergedFollowListsState.AllFollows>,
|
||||
val locationFlow: StateFlow<LocationState.LocationResult>,
|
||||
val followsRelays: StateFlow<Set<NormalizedRelayUrl>>,
|
||||
val blockedRelays: StateFlow<Set<NormalizedRelayUrl>>,
|
||||
@@ -81,7 +81,7 @@ class FeedTopNavFilterState(
|
||||
emitAll(loadFlowsFor(listName).flow())
|
||||
}.onStart {
|
||||
loadFlowsFor(feedFilterListName.value).startValue(this)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ class MergedTopFeedAuthorListsState(
|
||||
notificationNavFilter.value,
|
||||
),
|
||||
)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ class OutboxLoaderState(
|
||||
emitAll(filterSettings.toPerRelayFlow(cache))
|
||||
}.onStart {
|
||||
emit(topNavFilter.value.startValue(cache))
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Companion.Eagerly,
|
||||
|
||||
+12
-12
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.model.topNavFeeds.allFollows
|
||||
|
||||
import com.vitorpamplona.amethyst.model.nip02FollowLists.FollowListState
|
||||
import com.vitorpamplona.amethyst.model.serverList.MergedFollowListsState
|
||||
import com.vitorpamplona.amethyst.model.topNavFeeds.IFeedFlowsType
|
||||
import com.vitorpamplona.amethyst.model.topNavFeeds.IFeedTopNavFilter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
@@ -29,31 +29,31 @@ import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
|
||||
class AllFollowsFeedFlow(
|
||||
val allFollows: StateFlow<FollowListState.Kind3Follows?>,
|
||||
val allFollows: StateFlow<MergedFollowListsState.AllFollows?>,
|
||||
val followsRelays: StateFlow<Set<NormalizedRelayUrl>>,
|
||||
val blockedRelays: StateFlow<Set<NormalizedRelayUrl>>,
|
||||
val proxyRelays: StateFlow<Set<NormalizedRelayUrl>>,
|
||||
) : IFeedFlowsType {
|
||||
fun convert(
|
||||
kind3: FollowListState.Kind3Follows?,
|
||||
allFollows: MergedFollowListsState.AllFollows?,
|
||||
proxyRelays: Set<NormalizedRelayUrl>,
|
||||
): IFeedTopNavFilter =
|
||||
if (kind3 != null) {
|
||||
if (allFollows != null) {
|
||||
if (proxyRelays.isEmpty()) {
|
||||
AllFollowsByOutboxTopNavFilter(
|
||||
authors = kind3.authors,
|
||||
hashtags = kind3.hashtags,
|
||||
geotags = kind3.geotags,
|
||||
communities = kind3.communities,
|
||||
authors = allFollows.authors,
|
||||
hashtags = allFollows.hashtags,
|
||||
geotags = allFollows.geotags,
|
||||
communities = allFollows.communities,
|
||||
defaultRelays = followsRelays,
|
||||
blockedRelays = blockedRelays,
|
||||
)
|
||||
} else {
|
||||
AllFollowsByProxyTopNavFilter(
|
||||
authors = kind3.authors,
|
||||
hashtags = kind3.hashtags,
|
||||
geotags = kind3.geotags,
|
||||
communities = kind3.communities,
|
||||
authors = allFollows.authors,
|
||||
hashtags = allFollows.hashtags,
|
||||
geotags = allFollows.geotags,
|
||||
communities = allFollows.communities,
|
||||
proxyRelays = proxyRelays,
|
||||
)
|
||||
}
|
||||
|
||||
+6
-6
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.model.topNavFeeds.allUserFollows
|
||||
|
||||
import com.vitorpamplona.amethyst.model.nip02FollowLists.FollowListState
|
||||
import com.vitorpamplona.amethyst.model.serverList.MergedFollowListsState
|
||||
import com.vitorpamplona.amethyst.model.topNavFeeds.IFeedFlowsType
|
||||
import com.vitorpamplona.amethyst.model.topNavFeeds.IFeedTopNavFilter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
@@ -29,25 +29,25 @@ import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
|
||||
class AllUserFollowsFeedFlow(
|
||||
val allFollows: StateFlow<FollowListState.Kind3Follows?>,
|
||||
val allFollows: StateFlow<MergedFollowListsState.AllFollows?>,
|
||||
val followsRelays: StateFlow<Set<NormalizedRelayUrl>>,
|
||||
val blockedRelays: StateFlow<Set<NormalizedRelayUrl>>,
|
||||
val proxyRelays: StateFlow<Set<NormalizedRelayUrl>>,
|
||||
) : IFeedFlowsType {
|
||||
fun convert(
|
||||
kind3: FollowListState.Kind3Follows?,
|
||||
allFollows: MergedFollowListsState.AllFollows?,
|
||||
proxyRelays: Set<NormalizedRelayUrl>,
|
||||
): IFeedTopNavFilter =
|
||||
if (kind3 != null) {
|
||||
if (allFollows != null) {
|
||||
if (proxyRelays.isEmpty()) {
|
||||
AllUserFollowsByOutboxTopNavFilter(
|
||||
authors = kind3.authors,
|
||||
authors = allFollows.authors,
|
||||
defaultRelays = followsRelays,
|
||||
blockedRelays = blockedRelays,
|
||||
)
|
||||
} else {
|
||||
AllUserFollowsByProxyTopNavFilter(
|
||||
authors = kind3.authors,
|
||||
authors = allFollows.authors,
|
||||
proxyRelays = proxyRelays,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ class TorRelayState(
|
||||
trustedRelaysViaTor = torSettingsFlow.trustedRelaysViaTor.value,
|
||||
),
|
||||
)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
@@ -108,7 +108,7 @@ class TorRelayState(
|
||||
dmRelayList = dmRelays.value,
|
||||
),
|
||||
)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.Eagerly,
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ class PokeyReceiver : BroadcastReceiver() {
|
||||
Log.e("AmethystCoroutine", "Caught exception: ${throwable.message}", throwable)
|
||||
}
|
||||
|
||||
val scope = CoroutineScope(Dispatchers.Default + SupervisorJob() + exceptionHandler)
|
||||
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob() + exceptionHandler)
|
||||
|
||||
fun register(app: Context) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
|
||||
@@ -76,7 +76,7 @@ class OkHttpWebSocket(
|
||||
inner class OkHttpWebsocketListener(
|
||||
val out: WebSocketListener,
|
||||
) : okhttp3.WebSocketListener() {
|
||||
val scope = CoroutineScope(Dispatchers.Default + exceptionHandler)
|
||||
val scope = CoroutineScope(Dispatchers.IO + exceptionHandler)
|
||||
val incomingMessages: Channel<String> = Channel(Channel.UNLIMITED)
|
||||
val job = // Launch a coroutine to process messages from the channel.
|
||||
scope.launch {
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ fun MuteButton(
|
||||
}
|
||||
|
||||
LaunchedEffect(key1 = controllerVisible) {
|
||||
launch(Dispatchers.Default) {
|
||||
launch(Dispatchers.IO) {
|
||||
delay(2000)
|
||||
holdOn.value = false
|
||||
}
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ abstract class BaseEoseManager<T>(
|
||||
fun dismissSubscription(subId: String) = orchestrator.dismissSubscription(subId)
|
||||
|
||||
// Refreshes observers in batches.
|
||||
private val bundler = BundledUpdate(sampleTime, Dispatchers.Default)
|
||||
private val bundler = BundledUpdate(sampleTime, Dispatchers.IO)
|
||||
|
||||
override fun invalidateFilters(ignoreIfDoing: Boolean) {
|
||||
bundler.invalidate(ignoreIfDoing, ::forceInvalidate)
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ class AccountDraftsEoseManager(
|
||||
userJobMap[user]?.forEach { it.cancel() }
|
||||
userJobMap[user] =
|
||||
listOf(
|
||||
key.account.scope.launch(Dispatchers.Default) {
|
||||
key.account.scope.launch(Dispatchers.IO) {
|
||||
relayFlow(key).collectLatest {
|
||||
invalidateFilters()
|
||||
}
|
||||
|
||||
+2
-2
@@ -67,7 +67,7 @@ class AccountFollowsLoaderSubAssembler(
|
||||
private val orchestrator = SubscriptionController(client)
|
||||
|
||||
// Refreshes observers in batches of 500ms
|
||||
private val bundler = BundledUpdate(500, Dispatchers.Default)
|
||||
private val bundler = BundledUpdate(500, Dispatchers.IO)
|
||||
|
||||
/**
|
||||
* This assembler saves the EOSE per user key. That EOSE includes their metadata, etc
|
||||
@@ -203,7 +203,7 @@ class AccountFollowsLoaderSubAssembler(
|
||||
) {
|
||||
accountUpdatesJobMap[user]?.cancel()
|
||||
accountUpdatesJobMap[user] =
|
||||
scope.launch(Dispatchers.Default) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
followList.sample(1000).collectLatest {
|
||||
invalidateFilters(true)
|
||||
}
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ class AccountMetadataEoseManager(
|
||||
userJobMap[user]?.forEach { it.cancel() }
|
||||
userJobMap[user] =
|
||||
listOf(
|
||||
key.account.scope.launch(Dispatchers.Default) {
|
||||
key.account.scope.launch(Dispatchers.IO) {
|
||||
relayFlow(key).collectLatest {
|
||||
invalidateFilters()
|
||||
}
|
||||
|
||||
+2
-2
@@ -71,12 +71,12 @@ class AccountNotificationsEoseFromInboxRelaysManager(
|
||||
userJobMap[user]?.forEach { it.cancel() }
|
||||
userJobMap[user] =
|
||||
listOf(
|
||||
key.account.scope.launch(Dispatchers.Default) {
|
||||
key.account.scope.launch(Dispatchers.IO) {
|
||||
key.account.notificationRelays.flow.sample(1000).collectLatest {
|
||||
invalidateFilters()
|
||||
}
|
||||
},
|
||||
key.account.scope.launch(Dispatchers.Default) {
|
||||
key.account.scope.launch(Dispatchers.IO) {
|
||||
key.feedContentStates.notifications.lastNoteCreatedAtWhenFullyLoaded.sample(5000).collectLatest {
|
||||
invalidateFilters()
|
||||
}
|
||||
|
||||
+2
-2
@@ -67,13 +67,13 @@ class AccountNotificationsEoseFromRandomRelaysManager(
|
||||
userJobMap[user]?.forEach { it.cancel() }
|
||||
userJobMap[user] =
|
||||
listOf(
|
||||
key.account.scope.launch(Dispatchers.Default) {
|
||||
key.account.scope.launch(Dispatchers.IO) {
|
||||
// no need to hurry here. we can wait the app stabilize
|
||||
key.account.followsPerRelay.debounce(5000).collectLatest {
|
||||
invalidateFilters()
|
||||
}
|
||||
},
|
||||
key.account.scope.launch(Dispatchers.Default) {
|
||||
key.account.scope.launch(Dispatchers.IO) {
|
||||
key.feedContentStates.notifications.lastNoteCreatedAtWhenFullyLoaded.sample(5000).collectLatest {
|
||||
invalidateFilters()
|
||||
}
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ class AccountGiftWrapsEoseManager(
|
||||
userJobMap[user]?.forEach { it.cancel() }
|
||||
userJobMap[user] =
|
||||
listOf(
|
||||
key.account.scope.launch(Dispatchers.Default) {
|
||||
key.account.scope.launch(Dispatchers.IO) {
|
||||
key.account.dmRelays.flow.collectLatest {
|
||||
invalidateFilters()
|
||||
}
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@ fun observeChannelNoteAuthors(
|
||||
channelToParticipatingUsers(baseChannel, accountViewModel),
|
||||
)
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
return flow.collectAsStateWithLifecycle(persistentListOf())
|
||||
|
||||
+5
-5
@@ -97,7 +97,7 @@ fun <T> observeNoteAndMap(
|
||||
.metadata.stateFlow
|
||||
.mapLatest { map(it.note) }
|
||||
.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
// Subscribe in the LocalCache for changes that arrive in the device
|
||||
@@ -123,7 +123,7 @@ fun <T, U> observeNoteEventAndMap(
|
||||
.metadata.stateFlow
|
||||
.mapLatest { (it.note.event as? T)?.let { map(it) } }
|
||||
.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
// Subscribe in the LocalCache for changes that arrive in the device
|
||||
@@ -223,7 +223,7 @@ fun observeNoteReactionCount(
|
||||
.sample(200)
|
||||
.mapLatest { it.note.countReactions() }
|
||||
.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
// Subscribe in the LocalCache for changes that arrive in the device
|
||||
@@ -278,7 +278,7 @@ fun observeNoteRepostsBy(
|
||||
.boosts.stateFlow
|
||||
.mapLatest { it.note.isBoostedBy(user) }
|
||||
.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
return flow.collectAsStateWithLifecycle(note.isBoostedBy(user))
|
||||
@@ -401,7 +401,7 @@ fun observeCommunityApprovalNeedStatus(
|
||||
}
|
||||
}
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
// Subscribe in the LocalCache for changes that arrive in the device
|
||||
|
||||
+4
@@ -32,6 +32,10 @@ import com.vitorpamplona.quartz.utils.mapOfSet
|
||||
fun potentialRelaysToFindAddress(note: AddressableNote): Set<NormalizedRelayUrl> {
|
||||
val set = mutableSetOf<NormalizedRelayUrl>()
|
||||
|
||||
LocalCache.getOrCreateUser(note.address.pubKeyHex).outboxRelays()?.let {
|
||||
set.addAll(it)
|
||||
}
|
||||
|
||||
set.addAll(LocalCache.relayHints.hintsForAddress(note.idHex))
|
||||
|
||||
LocalCache.getAnyChannel(note)?.relays()?.let { set.addAll(it) }
|
||||
|
||||
+13
-13
@@ -253,7 +253,7 @@ fun observeUserFollowCount(
|
||||
.mapLatest { userState ->
|
||||
userState.user.transientFollowCount() ?: 0
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
return flow.collectAsStateWithLifecycle(0)
|
||||
@@ -281,7 +281,7 @@ fun observeUserTagFollowCount(
|
||||
}.onStart {
|
||||
emit((accountViewModel.hashtagFollows(user).event as? HashtagListEvent)?.let { accountViewModel.account.hashtagListDecryptionCache.hashtags(it) }?.size ?: 0)
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
return flow.collectAsStateWithLifecycle(0)
|
||||
@@ -309,7 +309,7 @@ fun observeUserTagFollows(
|
||||
}.onStart {
|
||||
emit((accountViewModel.hashtagFollows(user).event as? HashtagListEvent)?.let { accountViewModel.account.hashtagListDecryptionCache.hashtags(it) }?.sorted() ?: emptyList())
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
return flow.collectAsStateWithLifecycle(emptyList())
|
||||
@@ -356,7 +356,7 @@ fun observeUserBookmarkCount(
|
||||
.mapLatest { noteState ->
|
||||
(noteState.note.event as? BookmarkListEvent)?.countBookmarks() ?: 0
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
return flow.collectAsStateWithLifecycle(0)
|
||||
@@ -396,7 +396,7 @@ fun observeUserFollowerCount(
|
||||
.mapLatest { userState ->
|
||||
userState.user.transientFollowerCount()
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
return flow.collectAsStateWithLifecycle(0)
|
||||
@@ -426,7 +426,7 @@ fun observeUserIsFollowing(
|
||||
.mapLatest { userState ->
|
||||
userState.user.isFollowing(user2) || isUserInFollowSets
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
return flow.collectAsStateWithLifecycle(
|
||||
@@ -450,7 +450,7 @@ fun observeUserIsFollowingHashtag(
|
||||
}.onStart {
|
||||
emit(hashtag in accountViewModel.account.hashtagList.flow.value)
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
return flow.collectAsStateWithLifecycle(hashtag in accountViewModel.account.hashtagList.flow.value)
|
||||
@@ -471,7 +471,7 @@ fun observeUserIsFollowingGeohash(
|
||||
}.onStart {
|
||||
emit(geohash in accountViewModel.account.geohashList.flow.value)
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
return flow.collectAsStateWithLifecycle(geohash in accountViewModel.account.geohashList.flow.value)
|
||||
@@ -496,7 +496,7 @@ fun observeUserIsFollowingChannel(
|
||||
.mapLatest { followingChannels ->
|
||||
channel.idHex in followingChannels
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
@SuppressLint("StateFlowValueCalledInComposition")
|
||||
@@ -522,7 +522,7 @@ fun observeUserIsFollowingChannel(
|
||||
.mapLatest { followingChannels ->
|
||||
channel.roomId in followingChannels
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
@SuppressLint("StateFlowValueCalledInComposition")
|
||||
@@ -563,7 +563,7 @@ fun observeUserZapAmount(
|
||||
.mapLatest { userState ->
|
||||
userState.user.zappedAmount()
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
return flow.collectAsStateWithLifecycle(BigDecimal.ZERO)
|
||||
@@ -630,7 +630,7 @@ fun observeUserStatuses(
|
||||
.mapLatest { userState ->
|
||||
LocalCache.findStatusesForUser(userState.user)
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
return flow.collectAsStateWithLifecycle(persistentListOf())
|
||||
@@ -649,7 +649,7 @@ fun observeUserRelayIntoList(
|
||||
.mapLatest { relays ->
|
||||
relayUrl in relays
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
return flow.collectAsStateWithLifecycle(false)
|
||||
|
||||
+27
-19
@@ -72,7 +72,7 @@ fun filterUserMetadataForKey(
|
||||
|
||||
users.forEach { user ->
|
||||
val time = since.since(user)?.get(relay)?.time
|
||||
if (time == null) {
|
||||
if (time == null || user.latestMetadata == null) {
|
||||
firstTimers.add(user.pubkeyHex)
|
||||
} else {
|
||||
updates.add(user.pubkeyHex)
|
||||
@@ -82,24 +82,32 @@ fun filterUserMetadataForKey(
|
||||
}
|
||||
}
|
||||
|
||||
listOf(
|
||||
RelayBasedFilter(
|
||||
relay = relay,
|
||||
filter =
|
||||
Filter(
|
||||
kinds = UserMetadataForKeyKinds,
|
||||
authors = firstTimers.sorted(),
|
||||
),
|
||||
),
|
||||
RelayBasedFilter(
|
||||
relay = relay,
|
||||
filter =
|
||||
Filter(
|
||||
kinds = UserMetadataForKeyKinds,
|
||||
authors = updates.sorted(),
|
||||
since = minimumTime,
|
||||
),
|
||||
),
|
||||
listOfNotNull(
|
||||
if (firstTimers.isNotEmpty()) {
|
||||
RelayBasedFilter(
|
||||
relay = relay,
|
||||
filter =
|
||||
Filter(
|
||||
kinds = UserMetadataForKeyKinds,
|
||||
authors = firstTimers.sorted(),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
if (updates.isNotEmpty()) {
|
||||
RelayBasedFilter(
|
||||
relay = relay,
|
||||
filter =
|
||||
Filter(
|
||||
kinds = UserMetadataForKeyKinds,
|
||||
authors = updates.sorted(),
|
||||
since = minimumTime,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
)
|
||||
}.flatten()
|
||||
}
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ class UserReportsSubAssembler(
|
||||
|
||||
val trustedAccounts =
|
||||
mapOfSet {
|
||||
accounts.map { it.followsPerRelay.value }.forEach {
|
||||
accounts.map { it.declaredFollowsPerRelay.value }.forEach {
|
||||
add(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
// Graph doesn't completely clear.
|
||||
// @OptIn(DelicateCoroutinesApi::class)
|
||||
// GlobalScope.launch(Dispatchers.Default) {
|
||||
// GlobalScope.launch(Dispatchers.IO) {
|
||||
// serviceManager.trimMemory()
|
||||
// }
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ fun CashuPreview(
|
||||
initialValue = CachedCashuParser.cached(cashutoken),
|
||||
key1 = cashutoken,
|
||||
) {
|
||||
val newToken = withContext(Dispatchers.Default) { CachedCashuParser.parse(cashutoken) }
|
||||
val newToken = withContext(Dispatchers.IO) { CachedCashuParser.parse(cashutoken) }
|
||||
if (value != newToken) {
|
||||
value = newToken
|
||||
}
|
||||
|
||||
@@ -583,7 +583,7 @@ fun DisplaySecretEmoji(
|
||||
|
||||
if (secretContent == null) {
|
||||
LaunchedEffect(segment) {
|
||||
launch(Dispatchers.Default) {
|
||||
launch(Dispatchers.IO) {
|
||||
secretContent =
|
||||
CachedRichTextParser.parseText(
|
||||
EmojiCoder.decode(segment.segmentText),
|
||||
|
||||
+1
-1
@@ -150,7 +150,7 @@ private fun DialogContent(
|
||||
pagerState.scrollToPage(page)
|
||||
}
|
||||
}
|
||||
launch(Dispatchers.Default) {
|
||||
launch(Dispatchers.IO) {
|
||||
delay(2000)
|
||||
withContext(Dispatchers.Main) {
|
||||
controllerVisible.value = false
|
||||
|
||||
+3
-3
@@ -68,7 +68,7 @@ class ChannelFeedContentState(
|
||||
}
|
||||
|
||||
private fun refresh() {
|
||||
viewModelScope.launch(Dispatchers.Default) { refreshSuspended() }
|
||||
viewModelScope.launch(Dispatchers.IO) { refreshSuspended() }
|
||||
}
|
||||
|
||||
fun refreshSuspended() {
|
||||
@@ -135,8 +135,8 @@ class ChannelFeedContentState(
|
||||
}
|
||||
}
|
||||
|
||||
private val bundler = BundledUpdate(250, Dispatchers.Default)
|
||||
private val bundlerInsert = BundledInsert<Set<Note>>(250, Dispatchers.Default)
|
||||
private val bundler = BundledUpdate(250, Dispatchers.IO)
|
||||
private val bundlerInsert = BundledInsert<Set<Note>>(250, Dispatchers.IO)
|
||||
|
||||
override fun invalidateData(ignoreIfDoing: Boolean) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
|
||||
@@ -71,7 +71,7 @@ class FeedContentState(
|
||||
}
|
||||
|
||||
private fun refresh() {
|
||||
viewModelScope.launch(Dispatchers.Default) { refreshSuspended() }
|
||||
viewModelScope.launch(Dispatchers.IO) { refreshSuspended() }
|
||||
}
|
||||
|
||||
fun visibleNotes(): List<Note> {
|
||||
|
||||
@@ -134,7 +134,7 @@ fun LoadOts(
|
||||
|
||||
LaunchedEffect(key1 = noteStatus) {
|
||||
val newOts =
|
||||
withContext(Dispatchers.Default) {
|
||||
withContext(Dispatchers.IO) {
|
||||
LocalCache.findEarliestOtsForNote(
|
||||
note = noteStatus?.note ?: note,
|
||||
otsVerifCache = Amethyst.instance.otsVerifCache,
|
||||
|
||||
@@ -260,7 +260,7 @@ fun DisplaySecretEmojiAsReaction(
|
||||
|
||||
if (secretContent == null) {
|
||||
LaunchedEffect(reaction) {
|
||||
launch(Dispatchers.Default) {
|
||||
launch(Dispatchers.IO) {
|
||||
secretContent =
|
||||
CachedRichTextParser.parseText(
|
||||
EmojiCoder.decode(reaction),
|
||||
|
||||
@@ -100,7 +100,7 @@ class PollNoteViewModel : ViewModel() {
|
||||
}
|
||||
|
||||
fun refreshTallies() {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
totalZapped = totalZapped()
|
||||
wasZappedByLoggedInAccount = false
|
||||
wasZappedByLoggedInAccount = account.calculateIfNoteWasZappedByAccount(pollNote, 0)
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ class EmojiSuggestionState(
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
|
||||
fun reset() {
|
||||
if (search.value.isNotEmpty()) {
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ fun LoadValueFromInvoice(
|
||||
@Suppress("ProduceStateDoesNotAssignValue")
|
||||
val lnInvoice by
|
||||
produceState(initialValue = CachedLnInvoiceParser.cached(lnbcWord), key1 = lnbcWord) {
|
||||
val newLnInvoice = withContext(Dispatchers.Default) { CachedLnInvoiceParser.parse(lnbcWord) }
|
||||
val newLnInvoice = withContext(Dispatchers.IO) { CachedLnInvoiceParser.parse(lnbcWord) }
|
||||
if (value != newLnInvoice) {
|
||||
value = newLnInvoice
|
||||
}
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ class PreviewState {
|
||||
.debounce(500)
|
||||
.map { CachedUrlParser.parseValidUrls(it.text) }
|
||||
.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
|
||||
fun reset() {
|
||||
source.tryEmit(TextFieldValue(""))
|
||||
|
||||
+2
-2
@@ -64,12 +64,12 @@ fun ShowUserSuggestionList(
|
||||
AnimateOnNewSearch(userSuggestions, listState)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
launch(Dispatchers.Default) {
|
||||
launch(Dispatchers.IO) {
|
||||
LocalCache.live.newEventBundles.collect {
|
||||
userSuggestions.invalidateData()
|
||||
}
|
||||
}
|
||||
launch(Dispatchers.Default) {
|
||||
launch(Dispatchers.IO) {
|
||||
LocalCache.live.deletedEventBundles.collect {
|
||||
userSuggestions.invalidateData()
|
||||
}
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ class UserSuggestionState(
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
|
||||
fun reset() {
|
||||
currentWord.tryEmit("")
|
||||
|
||||
+13
-24
@@ -22,14 +22,12 @@ package com.vitorpamplona.amethyst.ui.note.elements
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.components.buildLinkString
|
||||
import com.vitorpamplona.amethyst.ui.components.ClickableTextColor
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
@@ -53,29 +51,20 @@ private fun DisplayCommunity(
|
||||
note: Note,
|
||||
nav: INav,
|
||||
) {
|
||||
val communityTag =
|
||||
remember(note) { note.event?.communityAddress() } ?: return
|
||||
val communityTag = note.event?.communityAddress() ?: return
|
||||
|
||||
val displayTag =
|
||||
remember(note) {
|
||||
buildLinkString(
|
||||
getCommunityShortName(communityTag),
|
||||
) {
|
||||
nav.nav(Route.Community(communityTag.kind, communityTag.pubKeyHex, communityTag.dTag))
|
||||
ClickableTextColor(
|
||||
getCommunityShortName(communityTag),
|
||||
linkColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.52f),
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
) {
|
||||
nav.nav {
|
||||
note.event?.communityAddress()?.let { communityTag ->
|
||||
Route.Community(communityTag.kind, communityTag.pubKeyHex, communityTag.dTag)
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
text = displayTag,
|
||||
style =
|
||||
LocalTextStyle.current.copy(
|
||||
color =
|
||||
MaterialTheme.colorScheme.primary.copy(
|
||||
alpha = 0.52f,
|
||||
),
|
||||
),
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun getCommunityShortName(communityAddress: Address): String {
|
||||
|
||||
+7
-12
@@ -23,9 +23,7 @@ package com.vitorpamplona.amethyst.ui.note.elements
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -36,7 +34,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.components.buildLinkString
|
||||
import com.vitorpamplona.amethyst.ui.components.ClickableTextColor
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
@@ -82,15 +80,12 @@ private fun DisplayTagList(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
Text(
|
||||
text =
|
||||
remember(firstTag) {
|
||||
buildLinkString(" #$firstTag") {
|
||||
nav.nav(Route.Hashtag(firstTag))
|
||||
}
|
||||
},
|
||||
style = LocalTextStyle.current.copy(MaterialTheme.colorScheme.primary.copy(alpha = 0.52f)),
|
||||
ClickableTextColor(
|
||||
"#$firstTag",
|
||||
linkColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.52f),
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
)
|
||||
) {
|
||||
nav.nav(Route.Hashtag(firstTag))
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -323,7 +323,7 @@ open class CommentPostViewModel :
|
||||
cancel()
|
||||
|
||||
accountViewModel.account.signAndComputeBroadcast(template, extraNotesToBroadcast)
|
||||
accountViewModel.viewModelScope.launch(Dispatchers.Default) {
|
||||
accountViewModel.viewModelScope.launch(Dispatchers.IO) {
|
||||
accountViewModel.account.deleteDraftIgnoreErrors(version)
|
||||
}
|
||||
}
|
||||
@@ -465,7 +465,7 @@ open class CommentPostViewModel :
|
||||
onError: (title: String, message: String) -> Unit,
|
||||
context: Context,
|
||||
) {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val myMultiOrchestrator = multiOrchestrator ?: return@launch
|
||||
|
||||
isUploadingImage = true
|
||||
@@ -673,7 +673,7 @@ open class CommentPostViewModel :
|
||||
}
|
||||
|
||||
override fun updateZapFromText() {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val tagger =
|
||||
NewMessageTagger(message.text, emptyList(), emptyList(), accountViewModel)
|
||||
tagger.run()
|
||||
|
||||
@@ -88,7 +88,7 @@ fun RenderAppDefinition(
|
||||
var metadata by remember { mutableStateOf<AppMetadata?>(null) }
|
||||
|
||||
LaunchedEffect(key1 = noteEvent) {
|
||||
withContext(Dispatchers.Default) { metadata = noteEvent.appMetaData() }
|
||||
withContext(Dispatchers.IO) { metadata = noteEvent.appMetaData() }
|
||||
}
|
||||
|
||||
metadata?.let { theAppMetadata ->
|
||||
|
||||
@@ -185,7 +185,7 @@ fun RenderFhirResource(
|
||||
fun RenderFhirResource(event: FhirResourceEvent) {
|
||||
@Suppress("ProduceStateDoesNotAssignValue")
|
||||
val state by produceState(initialValue = FhirElementDatabase(), key1 = event) {
|
||||
withContext(Dispatchers.Default) {
|
||||
withContext(Dispatchers.IO) {
|
||||
parseResourceBundleOrNull(event.content)?.let {
|
||||
value = it
|
||||
}
|
||||
|
||||
@@ -49,14 +49,14 @@ abstract class FeedViewModel(
|
||||
|
||||
init {
|
||||
Log.d("Init", "Starting new Model: ${this.javaClass.simpleName}")
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
LocalCache.live.newEventBundles.collect { newNotes ->
|
||||
Log.d("Rendering Metrics", "Update feeds: ${this@FeedViewModel.javaClass.simpleName} with ${newNotes.size}")
|
||||
feedState.updateFeedWith(newNotes)
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
LocalCache.live.deletedEventBundles.collect { newNotes ->
|
||||
Log.d("Rendering Metrics", "Delete from feeds: ${this@FeedViewModel.javaClass.simpleName} with ${newNotes.size}")
|
||||
feedState.deleteFromFeed(newNotes)
|
||||
|
||||
@@ -253,11 +253,11 @@ class FollowListState(
|
||||
|
||||
val kind3GlobalPeopleRoutes =
|
||||
_kind3GlobalPeopleRoutes
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(viewModelScope, SharingStarted.Eagerly, defaultLists)
|
||||
val kind3GlobalPeople =
|
||||
_kind3GlobalPeople
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(viewModelScope, SharingStarted.Eagerly, defaultLists)
|
||||
|
||||
suspend fun initializeSuspend() {
|
||||
|
||||
@@ -49,7 +49,7 @@ open class UserFeedViewModel(
|
||||
val feedContent = _feedContent.asStateFlow()
|
||||
|
||||
private fun refresh() {
|
||||
viewModelScope.launch(Dispatchers.Default) { refreshSuspended() }
|
||||
viewModelScope.launch(Dispatchers.IO) { refreshSuspended() }
|
||||
}
|
||||
|
||||
override val isRefreshing: MutableState<Boolean> = mutableStateOf(false)
|
||||
@@ -100,14 +100,14 @@ open class UserFeedViewModel(
|
||||
|
||||
init {
|
||||
Log.d("Init", "${this.javaClass.simpleName}")
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
LocalCache.live.newEventBundles.collect { newNotes ->
|
||||
Log.d("Rendering Metrics", "Update feeds: ${this@UserFeedViewModel.javaClass.simpleName} with ${newNotes.size}")
|
||||
invalidateData()
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
LocalCache.live.deletedEventBundles.collect { newNotes ->
|
||||
Log.d("Rendering Metrics", "Delete from feeds: ${this@UserFeedViewModel.javaClass.simpleName} with ${newNotes.size}")
|
||||
invalidateData()
|
||||
|
||||
+20
-16
@@ -106,6 +106,7 @@ import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PubKeyReferenceTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.EmptyOtsResolverBuilder
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
||||
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
@@ -202,7 +203,7 @@ class AccountViewModel(
|
||||
|
||||
val notificationHasNewItemsFlow =
|
||||
notificationHasNewItems
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(30000), false)
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@@ -251,7 +252,7 @@ class AccountViewModel(
|
||||
|
||||
val messagesHasNewItemsFlow =
|
||||
messagesHasNewItems
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(30000), false)
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@@ -284,7 +285,7 @@ class AccountViewModel(
|
||||
|
||||
val homeHasNewItemsFlow =
|
||||
homeHasNewItems
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(30000), false)
|
||||
|
||||
val hasNewItems =
|
||||
@@ -348,7 +349,10 @@ class AccountViewModel(
|
||||
val isPostHidden = note.isHiddenFor(accountChoices)
|
||||
val isHiddenAuthor = note.author?.let { account.isHidden(it) } == true
|
||||
|
||||
return if (isPostHidden) {
|
||||
val noteEvent = note.event
|
||||
val isDecryptedPostHidden = if (noteEvent is PrivateDmEvent) account.isDecryptedContentHidden(noteEvent) else false
|
||||
|
||||
return if (isPostHidden || isDecryptedPostHidden) {
|
||||
// Spam + Blocked Users + Hidden Words + Sensitive Content
|
||||
NoteComposeReportState(isPostHidden, false, false, isHiddenAuthor)
|
||||
} else if (isFromLoggedIn || isFromLoggedInFollow) {
|
||||
@@ -394,7 +398,7 @@ class AccountViewModel(
|
||||
account.kind3FollowList.flow.value.authors,
|
||||
),
|
||||
)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
viewModelScope,
|
||||
SharingStarted.WhileSubscribed(10000, 10000),
|
||||
@@ -412,7 +416,7 @@ class AccountViewModel(
|
||||
.relays
|
||||
.stateFlow
|
||||
.map { it.note.relays.size > 3 }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(
|
||||
viewModelScope,
|
||||
SharingStarted.WhileSubscribed(10000, 10000),
|
||||
@@ -431,7 +435,7 @@ class AccountViewModel(
|
||||
|
||||
suspend fun calculateZapAmount(zappedNote: Note): String =
|
||||
if (zappedNote.zapPayments.isNotEmpty()) {
|
||||
withContext(Dispatchers.Default) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val it = account.calculateZappedAmount(zappedNote)
|
||||
showAmount(it)
|
||||
}
|
||||
@@ -442,7 +446,7 @@ class AccountViewModel(
|
||||
suspend fun calculateZapraiser(zappedNote: Note): ZapraiserStatus {
|
||||
val zapraiserAmount = zappedNote.event?.zapraiserAmount() ?: 0
|
||||
return if (zappedNote.zapPayments.isNotEmpty()) {
|
||||
withContext(Dispatchers.Default) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val newZapAmount = account.calculateZappedAmount(zappedNote)
|
||||
var percentage = newZapAmount.div(zapraiserAmount.toBigDecimal()).toFloat()
|
||||
|
||||
@@ -1027,7 +1031,7 @@ class AccountViewModel(
|
||||
fun cachedModificationEventsForNote(note: Note) = LocalCache.cachedModificationEventsForNote(note)
|
||||
|
||||
suspend fun findModificationEventsForNote(note: Note): List<Note> =
|
||||
withContext(Dispatchers.Default) {
|
||||
withContext(Dispatchers.IO) {
|
||||
LocalCache.findLatestModificationForNote(note)
|
||||
}
|
||||
|
||||
@@ -1067,7 +1071,7 @@ class AccountViewModel(
|
||||
hexList: List<String>,
|
||||
onReady: (ImmutableList<User>) -> Unit,
|
||||
) {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
onReady(loadUsersSync(hexList).toImmutableList())
|
||||
}
|
||||
}
|
||||
@@ -1094,7 +1098,7 @@ class AccountViewModel(
|
||||
val onIsNew = createdAt > lastTime
|
||||
|
||||
if (onIsNew) {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
account.markAsRead(routeForLastRead, createdAt)
|
||||
}
|
||||
}
|
||||
@@ -1142,7 +1146,7 @@ class AccountViewModel(
|
||||
|
||||
init {
|
||||
Log.d("Init", "AccountViewModel")
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
feedStates.init()
|
||||
// awaits for init to finish before starting to capture new events.
|
||||
LocalCache.live.newEventBundles.collect { newNotes ->
|
||||
@@ -1152,7 +1156,7 @@ class AccountViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
LocalCache.live.deletedEventBundles.collect { newNotes ->
|
||||
logTime("AccountViewModel deletedEventBundle Update with ${newNotes.size} new notes") {
|
||||
feedStates.deleteNotes(newNotes)
|
||||
@@ -1602,7 +1606,7 @@ class AccountViewModel(
|
||||
val accountViewModel: AccountViewModel,
|
||||
) : GenericBaseCache<String, LoadedBechLink>(20) {
|
||||
override suspend fun compute(key: String): LoadedBechLink? =
|
||||
withContext(Dispatchers.Default) {
|
||||
withContext(Dispatchers.IO) {
|
||||
Nip19Parser.uriToRoute(key)?.let {
|
||||
var returningNote: Note? = null
|
||||
|
||||
@@ -1621,10 +1625,10 @@ class AccountViewModel(
|
||||
}
|
||||
}
|
||||
is NEmbed ->
|
||||
withContext(Dispatchers.Default) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val baseNote = LocalCache.getOrCreateNote(parsed.event)
|
||||
if (baseNote.event == null) {
|
||||
launch(Dispatchers.Default) {
|
||||
launch(Dispatchers.IO) {
|
||||
LocalCache.justConsume(parsed.event, null, false)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ abstract class ListChangeFeedViewModel(
|
||||
|
||||
init {
|
||||
Log.d("Init", "Starting new Model: ${this.javaClass.simpleName}")
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
localFilter.changesFlow().collect {
|
||||
Log.d("Init", "Collecting changes to: ${this@ListChangeFeedViewModel.javaClass.simpleName}")
|
||||
when (it) {
|
||||
|
||||
+3
-3
@@ -361,7 +361,7 @@ class ChatNewMessageViewModel :
|
||||
val version = draftTag.current
|
||||
innerSendPost(null)
|
||||
cancel()
|
||||
accountViewModel.viewModelScope.launch(Dispatchers.Default) {
|
||||
accountViewModel.viewModelScope.launch(Dispatchers.IO) {
|
||||
accountViewModel.account.deleteDraftIgnoreErrors(version)
|
||||
}
|
||||
}
|
||||
@@ -594,7 +594,7 @@ class ChatNewMessageViewModel :
|
||||
}
|
||||
|
||||
fun updateRoomFromUsersInput() {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
delay(300)
|
||||
val toUsersTagger = NewMessageTagger(toUsers.text, null, null, accountViewModel)
|
||||
toUsersTagger.run()
|
||||
@@ -717,7 +717,7 @@ class ChatNewMessageViewModel :
|
||||
}
|
||||
|
||||
override fun updateZapFromText() {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val tagger = NewMessageTagger(message.text, emptyList(), emptyList(), accountViewModel)
|
||||
tagger.run()
|
||||
tagger.pTags?.forEach { taggedUser ->
|
||||
|
||||
+3
-3
@@ -277,7 +277,7 @@ open class ChannelNewMessageViewModel :
|
||||
cancel()
|
||||
|
||||
accountViewModel.account.signAndSendPrivately(template, channelRelays)
|
||||
accountViewModel.viewModelScope.launch(Dispatchers.Default) {
|
||||
accountViewModel.viewModelScope.launch(Dispatchers.IO) {
|
||||
accountViewModel.account.deleteDraftIgnoreErrors(version)
|
||||
}
|
||||
}
|
||||
@@ -319,7 +319,7 @@ open class ChannelNewMessageViewModel :
|
||||
context: Context,
|
||||
onceUploaded: suspend () -> Unit,
|
||||
) {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val uploadState = uploadState ?: return@launch
|
||||
|
||||
val myMultiOrchestrator = uploadState.multiOrchestrator ?: return@launch
|
||||
@@ -630,7 +630,7 @@ open class ChannelNewMessageViewModel :
|
||||
}
|
||||
|
||||
fun updateZapFromText() {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val tagger = NewMessageTagger(message.text, emptyList(), emptyList(), accountViewModel)
|
||||
tagger.run()
|
||||
tagger.pTags?.forEach { taggedUser ->
|
||||
|
||||
+2
-2
@@ -61,12 +61,12 @@ class DMsFromUserFilterSubAssembler(
|
||||
userJobMap[user]?.forEach { it.cancel() }
|
||||
userJobMap[user] =
|
||||
listOf(
|
||||
key.account.scope.launch(Dispatchers.Default) {
|
||||
key.account.scope.launch(Dispatchers.IO) {
|
||||
key.account.homeRelays.flow.collectLatest {
|
||||
invalidateFilters()
|
||||
}
|
||||
},
|
||||
key.account.scope.launch(Dispatchers.Default) {
|
||||
key.account.scope.launch(Dispatchers.IO) {
|
||||
key.account.dmRelays.flow.collectLatest {
|
||||
invalidateFilters()
|
||||
}
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ class FollowingEphemeralChatSubAssembler(
|
||||
userJobMap[key.account.userProfile()]?.forEach { it.cancel() }
|
||||
userJobMap[key.account.userProfile()] =
|
||||
listOf(
|
||||
key.account.scope.launch(Dispatchers.Default) {
|
||||
key.account.scope.launch(Dispatchers.IO) {
|
||||
key.account.ephemeralChatList.liveEphemeralChatList.sample(500).collectLatest {
|
||||
invalidateFilters()
|
||||
}
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ class FollowingPublicChatSubAssembler(
|
||||
userJobMap[key.account.userProfile()]?.forEach { it.cancel() }
|
||||
userJobMap[key.account.userProfile()] =
|
||||
listOf(
|
||||
key.account.scope.launch(Dispatchers.Default) {
|
||||
key.account.scope.launch(Dispatchers.IO) {
|
||||
key.account.publicChatList.flowSet.sample(500).collectLatest {
|
||||
invalidateFilters()
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user