Remove map in FollowSetFeedFilter, in favor of retrieving note from cache if modification is needed. Amend FollowSet to carry the address of the note. Add Refreshable for the Lists screen.
This commit is contained in:
@@ -22,7 +22,6 @@ package com.vitorpamplona.amethyst.ui.dal
|
||||
|
||||
import android.util.Log
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.AddressableNote
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.FollowSet
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
@@ -30,12 +29,10 @@ import kotlin.coroutines.cancellation.CancellationException
|
||||
class FollowSetFeedFilter(
|
||||
val account: Account,
|
||||
) : FeedFilter<FollowSet>() {
|
||||
private val followSetEventPairs: MutableMap<AddressableNote, FollowSet> = mutableMapOf()
|
||||
|
||||
override fun feedKey(): String = account.userProfile().pubkeyHex
|
||||
|
||||
override fun feed(): List<FollowSet> {
|
||||
val userFollowSets = account.userProfile().followSets
|
||||
val userFollowSets = account.userProfile().followSetNotes
|
||||
if (userFollowSets.isEmpty()) {
|
||||
account.scope.launch {
|
||||
try {
|
||||
@@ -47,14 +44,7 @@ class FollowSetFeedFilter(
|
||||
}
|
||||
}
|
||||
}
|
||||
updateFollowSetEventPairs(userFollowSets)
|
||||
return followSetEventPairs.values.toList()
|
||||
}
|
||||
|
||||
private fun updateFollowSetEventPairs(notes: Set<AddressableNote>) {
|
||||
notes.forEach { note ->
|
||||
val noteAndSetPair = note to account.mapNoteToFollowSet(note)
|
||||
followSetEventPairs.putIfAbsent(noteAndSetPair.first, noteAndSetPair.second)
|
||||
}
|
||||
val followSets = userFollowSets.map { account.mapNoteToFollowSet(it) }
|
||||
return followSets
|
||||
}
|
||||
}
|
||||
|
||||
+47
-7
@@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.lists
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@@ -42,6 +43,7 @@ import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@@ -60,6 +62,7 @@ import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty
|
||||
import com.vitorpamplona.amethyst.ui.feeds.FeedError
|
||||
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
|
||||
import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.TopBarWithBackButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.NostrUserFollowSetFeedViewModel
|
||||
@@ -71,6 +74,9 @@ import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
|
||||
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun ListsScreen(
|
||||
@@ -83,6 +89,7 @@ fun ListsScreen(
|
||||
factory = NostrUserFollowSetFeedViewModel.Factory(accountViewModel.account),
|
||||
)
|
||||
|
||||
val currentCoroutineScope = rememberCoroutineScope()
|
||||
val lifeCycleOwner = LocalLifecycleOwner.current
|
||||
|
||||
DisposableEffect(lifeCycleOwner) {
|
||||
@@ -109,6 +116,17 @@ fun ListsScreen(
|
||||
refresh = {
|
||||
followSetsViewModel.invalidateData()
|
||||
},
|
||||
openItem = {
|
||||
currentCoroutineScope.launch(Dispatchers.IO) {
|
||||
val note = followSetsViewModel.getFollowSetAddressable(it, accountViewModel.account)
|
||||
if (note != null) {
|
||||
val event = note.event as PeopleListEvent
|
||||
println("Found list, with title: ${event.nameOrTitle()}")
|
||||
} else {
|
||||
println("No corresponding note found for this list.")
|
||||
}
|
||||
}
|
||||
},
|
||||
accountViewModel,
|
||||
nav,
|
||||
)
|
||||
@@ -118,6 +136,7 @@ fun ListsScreen(
|
||||
fun CustomListsScreen(
|
||||
followSetState: FollowSetState,
|
||||
refresh: () -> Unit,
|
||||
openItem: (identifier: String) -> Unit,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
@@ -130,7 +149,11 @@ fun CustomListsScreen(
|
||||
TopBarWithBackButton(stringRes(R.string.my_lists), nav::popBack)
|
||||
},
|
||||
) {
|
||||
Column(Modifier.padding(it).fillMaxHeight()) {
|
||||
Column(
|
||||
Modifier
|
||||
.padding(it)
|
||||
.fillMaxHeight(),
|
||||
) {
|
||||
when (followSetState) {
|
||||
FollowSetState.Loading -> LoadingFeed()
|
||||
|
||||
@@ -139,6 +162,7 @@ fun CustomListsScreen(
|
||||
FollowListLoaded(
|
||||
loadedFeedState = followSetFeed,
|
||||
onRefresh = refresh,
|
||||
onItemClick = openItem,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -164,16 +188,26 @@ fun FollowListLoaded(
|
||||
modifier: Modifier = Modifier,
|
||||
loadedFeedState: List<FollowSet>,
|
||||
onRefresh: () -> Unit = {},
|
||||
onItemClick: (String) -> Unit = {},
|
||||
) {
|
||||
Log.d("FollowSetComposable", "FollowListLoaded: Follow Set size: ${loadedFeedState.size}")
|
||||
|
||||
val listState = rememberLazyListState()
|
||||
LazyColumn(
|
||||
state = listState,
|
||||
contentPadding = FeedPadding,
|
||||
RefresheableBox(
|
||||
onRefresh = onRefresh,
|
||||
) {
|
||||
itemsIndexed(loadedFeedState, key = { _, item -> item.title }) { index, set ->
|
||||
CustomListItem(followSet = set)
|
||||
LazyColumn(
|
||||
state = listState,
|
||||
contentPadding = FeedPadding,
|
||||
) {
|
||||
itemsIndexed(loadedFeedState, key = { _, item -> item.identifierTag }) { index, set ->
|
||||
CustomListItem(
|
||||
followSet = set,
|
||||
onFollowSetClick = {
|
||||
onItemClick(set.identifierTag)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,10 +216,12 @@ fun FollowListLoaded(
|
||||
fun CustomListItem(
|
||||
modifier: Modifier = Modifier,
|
||||
followSet: FollowSet,
|
||||
onFollowSetClick: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
modifier =
|
||||
modifier
|
||||
.clickable(onClick = onFollowSetClick)
|
||||
.border(
|
||||
width = Dp.Hairline,
|
||||
color = Color.Gray,
|
||||
@@ -261,15 +297,19 @@ fun CustomListItem(
|
||||
private fun ListItemPreview() {
|
||||
val sampleFollowSet =
|
||||
FollowSet(
|
||||
visibility = ListVisibility.Mixed,
|
||||
identifierTag = "00001-2222",
|
||||
title = "Sample List Title",
|
||||
description = "Sample List Description",
|
||||
visibility = ListVisibility.Mixed,
|
||||
emptySet(),
|
||||
)
|
||||
ThemeComparisonColumn {
|
||||
CustomListItem(
|
||||
modifier = Modifier,
|
||||
sampleFollowSet,
|
||||
onFollowSetClick = {
|
||||
println("follow set: ${sampleFollowSet.identifierTag}")
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+7
-3
@@ -26,9 +26,10 @@ import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||
|
||||
@Stable
|
||||
data class FollowSet(
|
||||
val visibility: ListVisibility,
|
||||
val identifierTag: String,
|
||||
val title: String,
|
||||
val description: String?,
|
||||
val visibility: ListVisibility,
|
||||
val profileList: Set<String>,
|
||||
) : NostrList(listVisibility = visibility, content = profileList) {
|
||||
companion object {
|
||||
@@ -36,6 +37,7 @@ data class FollowSet(
|
||||
event: PeopleListEvent,
|
||||
signer: NostrSigner,
|
||||
): FollowSet {
|
||||
val address = event.address()
|
||||
val dTag = event.dTag()
|
||||
val listTitle = event.nameOrTitle() ?: dTag
|
||||
val listDescription = event.description() ?: ""
|
||||
@@ -44,16 +46,18 @@ data class FollowSet(
|
||||
event.privateTaggedUsers(signer) { userList -> privateFollows.addAll(userList) }
|
||||
return if (publicFollows.isEmpty() && privateFollows.isNotEmpty()) {
|
||||
FollowSet(
|
||||
visibility = ListVisibility.Private,
|
||||
identifierTag = address.toValue(),
|
||||
title = listTitle,
|
||||
description = listDescription,
|
||||
visibility = ListVisibility.Private,
|
||||
profileList = privateFollows.toSet(),
|
||||
)
|
||||
} else if (publicFollows.isNotEmpty() && privateFollows.isEmpty()) {
|
||||
FollowSet(
|
||||
visibility = ListVisibility.Public,
|
||||
identifierTag = address.toValue(),
|
||||
title = listTitle,
|
||||
description = listDescription,
|
||||
visibility = ListVisibility.Public,
|
||||
profileList = publicFollows.toSet(),
|
||||
)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user