feat(cache): wire State classes on DesktopIAccount for GC retention
- Add BookmarkListState, Kind3FollowListState, Nip65RelayListState to DesktopIAccount — pins important AddressableNotes via strong refs - Create stub Kind3FollowListRepository + Nip65RelayListRepository (no persistence yet, null backups) - Update followingKeySet() to read from Kind3FollowListState.flow - Revert accidental long-form branch changes in DeckColumnContainer
This commit is contained in:
@@ -153,6 +153,7 @@ sealed class DesktopScreen {
|
|||||||
) : DesktopScreen()
|
) : DesktopScreen()
|
||||||
|
|
||||||
data object Drafts : DesktopScreen()
|
data object Drafts : DesktopScreen()
|
||||||
|
|
||||||
data object Settings : DesktopScreen()
|
data object Settings : DesktopScreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+41
-1
@@ -24,6 +24,11 @@ import com.vitorpamplona.amethyst.commons.model.IAccount
|
|||||||
import com.vitorpamplona.amethyst.commons.model.INwcSignerState
|
import com.vitorpamplona.amethyst.commons.model.INwcSignerState
|
||||||
import com.vitorpamplona.amethyst.commons.model.Note
|
import com.vitorpamplona.amethyst.commons.model.Note
|
||||||
import com.vitorpamplona.amethyst.commons.model.User
|
import com.vitorpamplona.amethyst.commons.model.User
|
||||||
|
import com.vitorpamplona.amethyst.commons.model.nip02FollowList.Kind3FollowListRepository
|
||||||
|
import com.vitorpamplona.amethyst.commons.model.nip02FollowList.Kind3FollowListState
|
||||||
|
import com.vitorpamplona.amethyst.commons.model.nip51Lists.BookmarkListState
|
||||||
|
import com.vitorpamplona.amethyst.commons.model.nip65RelayList.Nip65RelayListRepository
|
||||||
|
import com.vitorpamplona.amethyst.commons.model.nip65RelayList.Nip65RelayListState
|
||||||
import com.vitorpamplona.amethyst.commons.model.privateChats.ChatroomList
|
import com.vitorpamplona.amethyst.commons.model.privateChats.ChatroomList
|
||||||
import com.vitorpamplona.amethyst.desktop.account.AccountState
|
import com.vitorpamplona.amethyst.desktop.account.AccountState
|
||||||
import com.vitorpamplona.amethyst.desktop.cache.DesktopLocalCache
|
import com.vitorpamplona.amethyst.desktop.cache.DesktopLocalCache
|
||||||
@@ -31,6 +36,7 @@ import com.vitorpamplona.amethyst.desktop.network.RelayConnectionManager
|
|||||||
import com.vitorpamplona.amethyst.desktop.ui.chats.DmSendTracker
|
import com.vitorpamplona.amethyst.desktop.ui.chats.DmSendTracker
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||||
|
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||||
import com.vitorpamplona.quartz.nip17Dm.NIP17Factory
|
import com.vitorpamplona.quartz.nip17Dm.NIP17Factory
|
||||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||||
@@ -42,6 +48,7 @@ import com.vitorpamplona.quartz.nip47WalletConnect.rpc.Response
|
|||||||
import com.vitorpamplona.quartz.nip57Zaps.IPrivateZapsDecryptionCache
|
import com.vitorpamplona.quartz.nip57Zaps.IPrivateZapsDecryptionCache
|
||||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
||||||
|
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||||
import com.vitorpamplona.quartz.nip89AppHandlers.clientTag.NostrSignerWithClientTag
|
import com.vitorpamplona.quartz.nip89AppHandlers.clientTag.NostrSignerWithClientTag
|
||||||
import com.vitorpamplona.quartz.utils.DualCase
|
import com.vitorpamplona.quartz.utils.DualCase
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@@ -67,6 +74,39 @@ class DesktopIAccount(
|
|||||||
|
|
||||||
override val pubKey: String = accountState.pubKeyHex
|
override val pubKey: String = accountState.pubKeyHex
|
||||||
|
|
||||||
|
// ----- State Classes (pin important notes via strong refs for GC retention) -----
|
||||||
|
|
||||||
|
val bookmarkState = BookmarkListState(signer, localCache, scope)
|
||||||
|
|
||||||
|
val kind3FollowList =
|
||||||
|
Kind3FollowListState(
|
||||||
|
signer,
|
||||||
|
localCache,
|
||||||
|
scope,
|
||||||
|
object : Kind3FollowListRepository {
|
||||||
|
override val backupContactList: ContactListEvent? = null
|
||||||
|
|
||||||
|
override fun updateContactListTo(event: ContactListEvent) { /* no persistence yet */ }
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
val nip65RelayList =
|
||||||
|
Nip65RelayListState(
|
||||||
|
signer,
|
||||||
|
localCache,
|
||||||
|
scope,
|
||||||
|
object : Nip65RelayListRepository {
|
||||||
|
override val backupNIP65RelayList: AdvertisedRelayListEvent? = null
|
||||||
|
|
||||||
|
override fun updateNIP65RelayList(event: AdvertisedRelayListEvent) { /* no persistence yet */ }
|
||||||
|
|
||||||
|
override val defaultOutboxRelays = relayManager.connectedRelays.value
|
||||||
|
override val defaultInboxRelays = relayManager.connectedRelays.value
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
|
||||||
override val showSensitiveContent: Boolean? = null
|
override val showSensitiveContent: Boolean? = null
|
||||||
|
|
||||||
override val hiddenWordsCase: List<DualCase> = emptyList()
|
override val hiddenWordsCase: List<DualCase> = emptyList()
|
||||||
@@ -97,7 +137,7 @@ class DesktopIAccount(
|
|||||||
|
|
||||||
override fun isWriteable(): Boolean = !accountState.isReadOnly
|
override fun isWriteable(): Boolean = !accountState.isReadOnly
|
||||||
|
|
||||||
override fun followingKeySet(): Set<String> = emptySet()
|
override fun followingKeySet(): Set<String> = kind3FollowList.flow.value.authors
|
||||||
|
|
||||||
override fun isHidden(user: User): Boolean = false
|
override fun isHidden(user: User): Boolean = false
|
||||||
|
|
||||||
|
|||||||
+46
-7
@@ -45,6 +45,7 @@ import com.vitorpamplona.amethyst.desktop.chess.ChessScreen
|
|||||||
import com.vitorpamplona.amethyst.desktop.model.DesktopIAccount
|
import com.vitorpamplona.amethyst.desktop.model.DesktopIAccount
|
||||||
import com.vitorpamplona.amethyst.desktop.network.DesktopRelayConnectionManager
|
import com.vitorpamplona.amethyst.desktop.network.DesktopRelayConnectionManager
|
||||||
import com.vitorpamplona.amethyst.desktop.service.drafts.DesktopDraftStore
|
import com.vitorpamplona.amethyst.desktop.service.drafts.DesktopDraftStore
|
||||||
|
import com.vitorpamplona.amethyst.desktop.service.highlights.DesktopHighlightStore
|
||||||
import com.vitorpamplona.amethyst.desktop.subscriptions.DesktopRelaySubscriptionsCoordinator
|
import com.vitorpamplona.amethyst.desktop.subscriptions.DesktopRelaySubscriptionsCoordinator
|
||||||
import com.vitorpamplona.amethyst.desktop.subscriptions.FeedMode
|
import com.vitorpamplona.amethyst.desktop.subscriptions.FeedMode
|
||||||
import com.vitorpamplona.amethyst.desktop.ui.ArticleEditorScreen
|
import com.vitorpamplona.amethyst.desktop.ui.ArticleEditorScreen
|
||||||
@@ -96,6 +97,8 @@ fun DeckColumnContainer(
|
|||||||
iAccount: DesktopIAccount,
|
iAccount: DesktopIAccount,
|
||||||
nwcConnection: Nip47URINorm?,
|
nwcConnection: Nip47URINorm?,
|
||||||
subscriptionsCoordinator: DesktopRelaySubscriptionsCoordinator,
|
subscriptionsCoordinator: DesktopRelaySubscriptionsCoordinator,
|
||||||
|
highlightStore: DesktopHighlightStore,
|
||||||
|
draftStore: DesktopDraftStore,
|
||||||
appScope: CoroutineScope,
|
appScope: CoroutineScope,
|
||||||
onShowComposeDialog: () -> Unit,
|
onShowComposeDialog: () -> Unit,
|
||||||
onShowReplyDialog: (com.vitorpamplona.quartz.nip01Core.core.Event) -> Unit,
|
onShowReplyDialog: (com.vitorpamplona.quartz.nip01Core.core.Event) -> Unit,
|
||||||
@@ -136,6 +139,8 @@ fun DeckColumnContainer(
|
|||||||
iAccount = iAccount,
|
iAccount = iAccount,
|
||||||
nwcConnection = nwcConnection,
|
nwcConnection = nwcConnection,
|
||||||
subscriptionsCoordinator = subscriptionsCoordinator,
|
subscriptionsCoordinator = subscriptionsCoordinator,
|
||||||
|
highlightStore = highlightStore,
|
||||||
|
draftStore = draftStore,
|
||||||
appScope = appScope,
|
appScope = appScope,
|
||||||
compactMode = true,
|
compactMode = true,
|
||||||
onShowComposeDialog = onShowComposeDialog,
|
onShowComposeDialog = onShowComposeDialog,
|
||||||
@@ -144,6 +149,7 @@ fun DeckColumnContainer(
|
|||||||
onNavigateToProfile = { navState.push(DesktopScreen.UserProfile(it)) },
|
onNavigateToProfile = { navState.push(DesktopScreen.UserProfile(it)) },
|
||||||
onNavigateToThread = { navState.push(DesktopScreen.Thread(it)) },
|
onNavigateToThread = { navState.push(DesktopScreen.Thread(it)) },
|
||||||
onNavigateToArticle = { navState.push(DesktopScreen.Article(it)) },
|
onNavigateToArticle = { navState.push(DesktopScreen.Article(it)) },
|
||||||
|
onNavigateToEditor = { navState.push(DesktopScreen.Editor(it)) },
|
||||||
)
|
)
|
||||||
if (currentOverlay != null) {
|
if (currentOverlay != null) {
|
||||||
Surface(
|
Surface(
|
||||||
@@ -157,11 +163,14 @@ fun DeckColumnContainer(
|
|||||||
account = account,
|
account = account,
|
||||||
nwcConnection = nwcConnection,
|
nwcConnection = nwcConnection,
|
||||||
subscriptionsCoordinator = subscriptionsCoordinator,
|
subscriptionsCoordinator = subscriptionsCoordinator,
|
||||||
|
highlightStore = highlightStore,
|
||||||
|
draftStore = draftStore,
|
||||||
onShowComposeDialog = onShowComposeDialog,
|
onShowComposeDialog = onShowComposeDialog,
|
||||||
onShowReplyDialog = onShowReplyDialog,
|
onShowReplyDialog = onShowReplyDialog,
|
||||||
onZapFeedback = onZapFeedback,
|
onZapFeedback = onZapFeedback,
|
||||||
onNavigateToProfile = { navState.push(DesktopScreen.UserProfile(it)) },
|
onNavigateToProfile = { navState.push(DesktopScreen.UserProfile(it)) },
|
||||||
onNavigateToThread = { navState.push(DesktopScreen.Thread(it)) },
|
onNavigateToThread = { navState.push(DesktopScreen.Thread(it)) },
|
||||||
|
onNavigateToArticle = { navState.push(DesktopScreen.Article(it)) },
|
||||||
onBack = { navState.pop() },
|
onBack = { navState.pop() },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -180,6 +189,8 @@ internal fun RootContent(
|
|||||||
iAccount: DesktopIAccount,
|
iAccount: DesktopIAccount,
|
||||||
nwcConnection: Nip47URINorm?,
|
nwcConnection: Nip47URINorm?,
|
||||||
subscriptionsCoordinator: DesktopRelaySubscriptionsCoordinator,
|
subscriptionsCoordinator: DesktopRelaySubscriptionsCoordinator,
|
||||||
|
highlightStore: DesktopHighlightStore? = null,
|
||||||
|
draftStore: DesktopDraftStore? = null,
|
||||||
appScope: CoroutineScope,
|
appScope: CoroutineScope,
|
||||||
compactMode: Boolean = false,
|
compactMode: Boolean = false,
|
||||||
onShowComposeDialog: () -> Unit,
|
onShowComposeDialog: () -> Unit,
|
||||||
@@ -188,6 +199,7 @@ internal fun RootContent(
|
|||||||
onNavigateToProfile: (String) -> Unit,
|
onNavigateToProfile: (String) -> Unit,
|
||||||
onNavigateToThread: (String) -> Unit,
|
onNavigateToThread: (String) -> Unit,
|
||||||
onNavigateToArticle: (String) -> Unit = {},
|
onNavigateToArticle: (String) -> Unit = {},
|
||||||
|
onNavigateToEditor: (String?) -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
@@ -237,8 +249,11 @@ internal fun RootContent(
|
|||||||
relayManager = relayManager,
|
relayManager = relayManager,
|
||||||
localCache = localCache,
|
localCache = localCache,
|
||||||
account = account,
|
account = account,
|
||||||
|
nwcConnection = nwcConnection,
|
||||||
onNavigateToProfile = onNavigateToProfile,
|
onNavigateToProfile = onNavigateToProfile,
|
||||||
onNavigateToArticle = onNavigateToArticle,
|
onNavigateToArticle = onNavigateToArticle,
|
||||||
|
onNavigateToThread = onNavigateToThread,
|
||||||
|
onZapFeedback = onZapFeedback,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,6 +296,7 @@ internal fun RootContent(
|
|||||||
onBack = {},
|
onBack = {},
|
||||||
onCompose = onShowComposeDialog,
|
onCompose = onShowComposeDialog,
|
||||||
onNavigateToProfile = onNavigateToProfile,
|
onNavigateToProfile = onNavigateToProfile,
|
||||||
|
onNavigateToArticle = onNavigateToArticle,
|
||||||
onZapFeedback = onZapFeedback,
|
onZapFeedback = onZapFeedback,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -336,16 +352,16 @@ internal fun RootContent(
|
|||||||
localCache = localCache,
|
localCache = localCache,
|
||||||
account = account,
|
account = account,
|
||||||
subscriptionsCoordinator = subscriptionsCoordinator,
|
subscriptionsCoordinator = subscriptionsCoordinator,
|
||||||
|
highlightStore = highlightStore,
|
||||||
onBack = {},
|
onBack = {},
|
||||||
onNavigateToProfile = onNavigateToProfile,
|
onNavigateToProfile = onNavigateToProfile,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
DeckColumnType.Editor -> {
|
is DeckColumnType.Editor -> {
|
||||||
val draftStore = remember { DesktopDraftStore(scope) }
|
|
||||||
ArticleEditorScreen(
|
ArticleEditorScreen(
|
||||||
draftSlug = null,
|
draftSlug = columnType.draftSlug,
|
||||||
draftStore = draftStore,
|
draftStore = draftStore ?: remember { DesktopDraftStore(scope) },
|
||||||
account = account,
|
account = account,
|
||||||
relayManager = relayManager,
|
relayManager = relayManager,
|
||||||
onBack = {},
|
onBack = {},
|
||||||
@@ -354,10 +370,16 @@ internal fun RootContent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
DeckColumnType.Drafts -> {
|
DeckColumnType.Drafts -> {
|
||||||
val draftStore = remember { DesktopDraftStore(scope) }
|
|
||||||
DraftsScreen(
|
DraftsScreen(
|
||||||
draftStore = draftStore,
|
draftStore = draftStore ?: remember { DesktopDraftStore(scope) },
|
||||||
onOpenEditor = {},
|
onOpenEditor = { slug -> onNavigateToEditor(slug) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
DeckColumnType.MyHighlights -> {
|
||||||
|
com.vitorpamplona.amethyst.desktop.ui.highlights.MyHighlightsScreen(
|
||||||
|
highlightStore = highlightStore ?: remember { DesktopHighlightStore(scope) },
|
||||||
|
onNavigateToArticle = onNavigateToArticle,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,11 +404,14 @@ internal fun OverlayContent(
|
|||||||
account: AccountState.LoggedIn,
|
account: AccountState.LoggedIn,
|
||||||
nwcConnection: Nip47URINorm?,
|
nwcConnection: Nip47URINorm?,
|
||||||
subscriptionsCoordinator: DesktopRelaySubscriptionsCoordinator,
|
subscriptionsCoordinator: DesktopRelaySubscriptionsCoordinator,
|
||||||
|
highlightStore: DesktopHighlightStore? = null,
|
||||||
|
draftStore: DesktopDraftStore? = null,
|
||||||
onShowComposeDialog: () -> Unit,
|
onShowComposeDialog: () -> Unit,
|
||||||
onShowReplyDialog: (com.vitorpamplona.quartz.nip01Core.core.Event) -> Unit,
|
onShowReplyDialog: (com.vitorpamplona.quartz.nip01Core.core.Event) -> Unit,
|
||||||
onZapFeedback: (ZapFeedback) -> Unit,
|
onZapFeedback: (ZapFeedback) -> Unit,
|
||||||
onNavigateToProfile: (String) -> Unit,
|
onNavigateToProfile: (String) -> Unit,
|
||||||
onNavigateToThread: (String) -> Unit,
|
onNavigateToThread: (String) -> Unit,
|
||||||
|
onNavigateToArticle: (String) -> Unit = {},
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
) {
|
) {
|
||||||
when (screen) {
|
when (screen) {
|
||||||
@@ -401,6 +426,7 @@ internal fun OverlayContent(
|
|||||||
onBack = onBack,
|
onBack = onBack,
|
||||||
onCompose = onShowComposeDialog,
|
onCompose = onShowComposeDialog,
|
||||||
onNavigateToProfile = onNavigateToProfile,
|
onNavigateToProfile = onNavigateToProfile,
|
||||||
|
onNavigateToArticle = onNavigateToArticle,
|
||||||
onZapFeedback = onZapFeedback,
|
onZapFeedback = onZapFeedback,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -428,11 +454,24 @@ internal fun OverlayContent(
|
|||||||
localCache = localCache,
|
localCache = localCache,
|
||||||
account = account,
|
account = account,
|
||||||
subscriptionsCoordinator = subscriptionsCoordinator,
|
subscriptionsCoordinator = subscriptionsCoordinator,
|
||||||
|
highlightStore = highlightStore,
|
||||||
onBack = onBack,
|
onBack = onBack,
|
||||||
onNavigateToProfile = onNavigateToProfile,
|
onNavigateToProfile = onNavigateToProfile,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is DesktopScreen.Editor -> {
|
||||||
|
val overlayScope = androidx.compose.runtime.rememberCoroutineScope()
|
||||||
|
ArticleEditorScreen(
|
||||||
|
draftSlug = screen.draftSlug,
|
||||||
|
draftStore = draftStore ?: remember { DesktopDraftStore(overlayScope) },
|
||||||
|
account = account,
|
||||||
|
relayManager = relayManager,
|
||||||
|
onBack = onBack,
|
||||||
|
onPublished = onBack,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
androidx.compose.material3.Text(
|
androidx.compose.material3.Text(
|
||||||
"Unsupported screen type",
|
"Unsupported screen type",
|
||||||
|
|||||||
Vendored
+2
@@ -79,6 +79,8 @@ class CoordinatorPipelineTest {
|
|||||||
|
|
||||||
override fun disconnect() {}
|
override fun disconnect() {}
|
||||||
|
|
||||||
|
override fun close() {}
|
||||||
|
|
||||||
override fun reconnect(
|
override fun reconnect(
|
||||||
onlyIfChanged: Boolean,
|
onlyIfChanged: Boolean,
|
||||||
ignoreRetryDelays: Boolean,
|
ignoreRetryDelays: Boolean,
|
||||||
|
|||||||
Reference in New Issue
Block a user