Simplifying observables
This commit is contained in:
@@ -449,10 +449,12 @@ private fun ObserveNIP19Event(
|
||||
var baseNote by remember(it) { mutableStateOf<Note?>(null) }
|
||||
|
||||
LaunchedEffect(key1 = it.hex) {
|
||||
launch(Dispatchers.IO) {
|
||||
if (it.type == Nip19.Type.NOTE || it.type == Nip19.Type.EVENT || it.type == Nip19.Type.ADDRESS) {
|
||||
LocalCache.checkGetOrCreateNote(it.hex)?.let { note ->
|
||||
baseNote = note
|
||||
if (baseNote == null) {
|
||||
launch(Dispatchers.IO) {
|
||||
if (it.type == Nip19.Type.NOTE || it.type == Nip19.Type.EVENT || it.type == Nip19.Type.ADDRESS) {
|
||||
LocalCache.checkGetOrCreateNote(it.hex)?.let { note ->
|
||||
baseNote = note
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -479,10 +481,12 @@ private fun ObserveNIP19User(
|
||||
var baseUser by remember(it) { mutableStateOf<User?>(null) }
|
||||
|
||||
LaunchedEffect(key1 = it.hex) {
|
||||
launch(Dispatchers.IO) {
|
||||
if (it.type == Nip19.Type.USER) {
|
||||
LocalCache.checkGetOrCreateUser(it.hex)?.let { user ->
|
||||
baseUser = user
|
||||
if (baseUser == null) {
|
||||
launch(Dispatchers.IO) {
|
||||
if (it.type == Nip19.Type.USER) {
|
||||
LocalCache.checkGetOrCreateUser(it.hex)?.let { user ->
|
||||
baseUser = user
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -782,27 +786,29 @@ fun TagLink(word: String, tags: List<List<String>>, canPreview: Boolean, backgro
|
||||
var baseNotePair by remember { mutableStateOf<Pair<Note, String?>?>(null) }
|
||||
|
||||
LaunchedEffect(key1 = word) {
|
||||
launch(Dispatchers.IO) {
|
||||
val matcher = tagIndex.matcher(word)
|
||||
val (index, suffix) = try {
|
||||
matcher.find()
|
||||
Pair(matcher.group(1)?.toInt(), matcher.group(2) ?: "")
|
||||
} catch (e: Exception) {
|
||||
Log.w("Tag Parser", "Couldn't link tag $word", e)
|
||||
Pair(null, null)
|
||||
}
|
||||
if (baseUserPair == null && baseNotePair == null) {
|
||||
launch(Dispatchers.IO) {
|
||||
val matcher = tagIndex.matcher(word)
|
||||
val (index, suffix) = try {
|
||||
matcher.find()
|
||||
Pair(matcher.group(1)?.toInt(), matcher.group(2) ?: "")
|
||||
} catch (e: Exception) {
|
||||
Log.w("Tag Parser", "Couldn't link tag $word", e)
|
||||
Pair(null, null)
|
||||
}
|
||||
|
||||
if (index != null && index >= 0 && index < tags.size) {
|
||||
val tag = tags[index]
|
||||
if (index != null && index >= 0 && index < tags.size) {
|
||||
val tag = tags[index]
|
||||
|
||||
if (tag.size > 1) {
|
||||
if (tag[0] == "p") {
|
||||
LocalCache.checkGetOrCreateUser(tag[1])?.let {
|
||||
baseUserPair = Pair(it, suffix)
|
||||
}
|
||||
} else if (tag[0] == "e" || tag[0] == "a") {
|
||||
LocalCache.checkGetOrCreateNote(tag[1])?.let {
|
||||
baseNotePair = Pair(it, suffix)
|
||||
if (tag.size > 1) {
|
||||
if (tag[0] == "p") {
|
||||
LocalCache.checkGetOrCreateUser(tag[1])?.let {
|
||||
baseUserPair = Pair(it, suffix)
|
||||
}
|
||||
} else if (tag[0] == "e" || tag[0] == "a") {
|
||||
LocalCache.checkGetOrCreateNote(tag[1])?.let {
|
||||
baseNotePair = Pair(it, suffix)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,31 +110,11 @@ private fun RowScope.HasNewItemsIcon(
|
||||
accountViewModel: AccountViewModel,
|
||||
navController: NavHostController
|
||||
) {
|
||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||
val account = remember(accountState) { accountState?.account } ?: return
|
||||
var hasNewItems by remember { mutableStateOf(false) }
|
||||
|
||||
val notifState by NotificationCache.live.observeAsState()
|
||||
val notif = remember(notifState) { notifState?.cache } ?: return
|
||||
|
||||
var hasNewItems by remember { mutableStateOf<Boolean>(false) }
|
||||
|
||||
LaunchedEffect(key1 = notifState, key2 = accountState) {
|
||||
launch(Dispatchers.IO) {
|
||||
val newHasNewItems = route.hasNewItems(account, notif, emptySet())
|
||||
if (newHasNewItems != hasNewItems) {
|
||||
hasNewItems = newHasNewItems
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
launch(Dispatchers.IO) {
|
||||
LocalCache.live.newEventBundles.collect {
|
||||
val newHasNewItems = route.hasNewItems(account, notif, it)
|
||||
if (newHasNewItems != hasNewItems) {
|
||||
hasNewItems = newHasNewItems
|
||||
}
|
||||
}
|
||||
WatchPossibleNotificationChanges(route, accountViewModel) {
|
||||
if (it != hasNewItems) {
|
||||
hasNewItems = it
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,6 +147,33 @@ private fun RowScope.HasNewItemsIcon(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun WatchPossibleNotificationChanges(
|
||||
route: Route,
|
||||
accountViewModel: AccountViewModel,
|
||||
onChange: (Boolean) -> Unit
|
||||
) {
|
||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||
val account = remember(accountState) { accountState?.account } ?: return
|
||||
|
||||
val notifState by NotificationCache.live.observeAsState()
|
||||
val notif = remember(notifState) { notifState?.cache } ?: return
|
||||
|
||||
LaunchedEffect(key1 = notifState, key2 = accountState) {
|
||||
launch(Dispatchers.IO) {
|
||||
onChange(route.hasNewItems(account, notif, emptySet()))
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
launch(Dispatchers.IO) {
|
||||
LocalCache.live.newEventBundles.collect {
|
||||
onChange(route.hasNewItems(account, notif, it))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RowScope.BottomIcon(
|
||||
icon: Int,
|
||||
|
||||
@@ -54,7 +54,6 @@ import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS
|
||||
import com.vitorpamplona.amethyst.model.KIND3_FOLLOWS
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.service.NostrAccountDataSource
|
||||
import com.vitorpamplona.amethyst.service.NostrChannelDataSource
|
||||
import com.vitorpamplona.amethyst.service.NostrChatroomDataSource
|
||||
@@ -103,16 +102,20 @@ fun AppTopBar(followLists: FollowListViewModel, navController: NavHostController
|
||||
fun StoriesTopBar(followLists: FollowListViewModel, scaffoldState: ScaffoldState, accountViewModel: AccountViewModel) {
|
||||
GenericTopBar(scaffoldState, accountViewModel) { accountViewModel ->
|
||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||
accountState?.account?.let { account ->
|
||||
FollowList(
|
||||
followLists,
|
||||
account.defaultStoriesFollowList,
|
||||
account.userProfile(),
|
||||
true
|
||||
) { listName ->
|
||||
account.changeDefaultStoriesFollowList(listName)
|
||||
|
||||
val list by remember(accountState) {
|
||||
derivedStateOf {
|
||||
accountState?.account?.defaultStoriesFollowList ?: GLOBAL_FOLLOWS
|
||||
}
|
||||
}
|
||||
|
||||
FollowList(
|
||||
followLists,
|
||||
list,
|
||||
true
|
||||
) { listName ->
|
||||
accountViewModel.account.changeDefaultStoriesFollowList(listName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,16 +123,20 @@ fun StoriesTopBar(followLists: FollowListViewModel, scaffoldState: ScaffoldState
|
||||
fun HomeTopBar(followLists: FollowListViewModel, scaffoldState: ScaffoldState, accountViewModel: AccountViewModel) {
|
||||
GenericTopBar(scaffoldState, accountViewModel) { accountViewModel ->
|
||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||
accountState?.account?.let { account ->
|
||||
FollowList(
|
||||
followLists,
|
||||
account.defaultHomeFollowList,
|
||||
account.userProfile(),
|
||||
false
|
||||
) { listName ->
|
||||
account.changeDefaultHomeFollowList(listName)
|
||||
|
||||
val list by remember(accountState) {
|
||||
derivedStateOf {
|
||||
accountState?.account?.defaultHomeFollowList ?: GLOBAL_FOLLOWS
|
||||
}
|
||||
}
|
||||
|
||||
FollowList(
|
||||
followLists,
|
||||
list,
|
||||
false
|
||||
) { listName ->
|
||||
accountViewModel.account.changeDefaultHomeFollowList(listName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,16 +144,20 @@ fun HomeTopBar(followLists: FollowListViewModel, scaffoldState: ScaffoldState, a
|
||||
fun NotificationTopBar(followLists: FollowListViewModel, scaffoldState: ScaffoldState, accountViewModel: AccountViewModel) {
|
||||
GenericTopBar(scaffoldState, accountViewModel) { accountViewModel ->
|
||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||
accountState?.account?.let { account ->
|
||||
FollowList(
|
||||
followLists,
|
||||
account.defaultNotificationFollowList,
|
||||
account.userProfile(),
|
||||
true
|
||||
) { listName ->
|
||||
account.changeDefaultNotificationFollowList(listName)
|
||||
|
||||
val list by remember(accountState) {
|
||||
derivedStateOf {
|
||||
accountState?.account?.defaultNotificationFollowList ?: GLOBAL_FOLLOWS
|
||||
}
|
||||
}
|
||||
|
||||
FollowList(
|
||||
followLists,
|
||||
list,
|
||||
true
|
||||
) { listName ->
|
||||
accountViewModel.account.changeDefaultNotificationFollowList(listName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,7 +307,7 @@ private fun LoggedInUserPictureDrawer(
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun FollowList(followListsModel: FollowListViewModel, listName: String, loggedIn: User, withGlobal: Boolean, onChange: (String) -> Unit) {
|
||||
fun FollowList(followListsModel: FollowListViewModel, listName: String, withGlobal: Boolean, onChange: (String) -> Unit) {
|
||||
val kind3Follow = Pair(KIND3_FOLLOWS, stringResource(id = R.string.follow_list_kind3follows))
|
||||
val globalFollow = Pair(GLOBAL_FOLLOWS, stringResource(id = R.string.follow_list_global))
|
||||
|
||||
@@ -339,7 +350,10 @@ class FollowListViewModel(val account: Account) : ViewModel() {
|
||||
val newFollowLists = LocalCache.addressables.mapNotNull {
|
||||
val event = (it.value.event as? PeopleListEvent)
|
||||
// Has to have an list
|
||||
if (event != null && event.pubKey == account.userProfile().pubkeyHex && (event.tags.size > 1 || event.content.length > 50)) {
|
||||
if (event != null &&
|
||||
event.pubKey == account.userProfile().pubkeyHex &&
|
||||
(event.tags.size > 1 || event.content.length > 50)
|
||||
) {
|
||||
Pair(event.dTag(), event.dTag())
|
||||
} else {
|
||||
null
|
||||
|
||||
@@ -76,16 +76,13 @@ fun DrawerContent(
|
||||
sheetState: ModalBottomSheetState,
|
||||
accountViewModel: AccountViewModel
|
||||
) {
|
||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||
val account = accountState?.account ?: return
|
||||
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
color = MaterialTheme.colors.background
|
||||
) {
|
||||
Column() {
|
||||
ProfileContent(
|
||||
account.userProfile(),
|
||||
accountViewModel.account.userProfile(),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 25.dp)
|
||||
@@ -98,17 +95,16 @@ fun DrawerContent(
|
||||
modifier = Modifier.padding(top = 20.dp)
|
||||
)
|
||||
ListContent(
|
||||
account.userProfile().pubkeyHex,
|
||||
nav,
|
||||
scaffoldState,
|
||||
sheetState,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f),
|
||||
account
|
||||
accountViewModel
|
||||
)
|
||||
|
||||
BottomContent(account.userProfile(), scaffoldState, nav)
|
||||
BottomContent(accountViewModel.account.userProfile(), scaffoldState, nav)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,13 +261,15 @@ private fun FollowingAndFollowerCounts(baseAccountUser: User) {
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun ListContent(
|
||||
accountUserPubKey: String?,
|
||||
nav: (String) -> Unit,
|
||||
scaffoldState: ScaffoldState,
|
||||
sheetState: ModalBottomSheetState,
|
||||
modifier: Modifier,
|
||||
account: Account
|
||||
accountViewModel: AccountViewModel
|
||||
) {
|
||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||
val account = remember(accountState) { accountState?.account } ?: return
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
var backupDialogOpen by remember { mutableStateOf(false) }
|
||||
var checked by remember { mutableStateOf(account.proxy != null) }
|
||||
@@ -284,25 +282,23 @@ fun ListContent(
|
||||
.fillMaxHeight()
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
if (accountUserPubKey != null) {
|
||||
NavigationRow(
|
||||
title = stringResource(R.string.profile),
|
||||
icon = Route.Profile.icon,
|
||||
tint = MaterialTheme.colors.primary,
|
||||
nav = nav,
|
||||
scaffoldState = scaffoldState,
|
||||
route = "User/$accountUserPubKey"
|
||||
)
|
||||
NavigationRow(
|
||||
title = stringResource(R.string.profile),
|
||||
icon = Route.Profile.icon,
|
||||
tint = MaterialTheme.colors.primary,
|
||||
nav = nav,
|
||||
scaffoldState = scaffoldState,
|
||||
route = "User/${account.userProfile().pubkeyHex}"
|
||||
)
|
||||
|
||||
NavigationRow(
|
||||
title = stringResource(R.string.bookmarks),
|
||||
icon = Route.Bookmarks.icon,
|
||||
tint = MaterialTheme.colors.onBackground,
|
||||
nav = nav,
|
||||
scaffoldState = scaffoldState,
|
||||
route = Route.Bookmarks.route
|
||||
)
|
||||
}
|
||||
NavigationRow(
|
||||
title = stringResource(R.string.bookmarks),
|
||||
icon = Route.Bookmarks.icon,
|
||||
tint = MaterialTheme.colors.onBackground,
|
||||
nav = nav,
|
||||
scaffoldState = scaffoldState,
|
||||
route = Route.Bookmarks.route
|
||||
)
|
||||
|
||||
NavigationRow(
|
||||
title = stringResource(R.string.security_filters),
|
||||
|
||||
@@ -65,9 +65,6 @@ fun MultiSetCompose(multiSetCard: MultiSetCard, routeForLastRead: String, accoun
|
||||
val noteState by baseNote.live().metadata.observeAsState()
|
||||
val note = remember(noteState) { noteState?.note } ?: return
|
||||
|
||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||
val loggedIn = remember(accountState) { accountState?.account?.userProfile() } ?: return
|
||||
|
||||
var popupExpanded by remember { mutableStateOf(false) }
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
@@ -108,7 +105,7 @@ fun MultiSetCompose(multiSetCard: MultiSetCard, routeForLastRead: String, accoun
|
||||
.combinedClickable(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
routeFor(baseNote, loggedIn)?.let { nav(it) }
|
||||
routeFor(baseNote, accountViewModel.userProfile())?.let { nav(it) }
|
||||
}
|
||||
},
|
||||
onLongClick = { popupExpanded = true }
|
||||
|
||||
@@ -15,6 +15,7 @@ import androidx.compose.material.icons.filled.Report
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@@ -97,11 +98,14 @@ fun nip05VerificationAsAState(user: UserMetadata, pubkeyHex: String): State<Bool
|
||||
@Composable
|
||||
fun ObserveDisplayNip05Status(baseNote: Note, columnModifier: Modifier = Modifier) {
|
||||
val noteState by baseNote.live().metadata.observeAsState()
|
||||
val note = noteState?.note ?: return
|
||||
val author by remember(noteState) {
|
||||
derivedStateOf {
|
||||
noteState?.note?.author
|
||||
}
|
||||
}
|
||||
|
||||
val author = note.author
|
||||
if (author != null) {
|
||||
ObserveDisplayNip05Status(author, columnModifier)
|
||||
author?.let {
|
||||
ObserveDisplayNip05Status(it, columnModifier)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -269,19 +269,18 @@ fun ZapVote(
|
||||
nonClickablePrepend: @Composable () -> Unit,
|
||||
clickablePrepend: @Composable () -> Unit
|
||||
) {
|
||||
val zapsState by baseNote.live().zaps.observeAsState()
|
||||
val zappedNote = zapsState?.note ?: return
|
||||
val isLoggedUser by remember {
|
||||
derivedStateOf {
|
||||
accountViewModel.isLoggedUser(baseNote.author)
|
||||
}
|
||||
}
|
||||
|
||||
var wantsToZap by remember { mutableStateOf(false) }
|
||||
var zappingProgress by remember { mutableStateOf(0f) }
|
||||
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
var zappingProgress by remember { mutableStateOf(0f) }
|
||||
|
||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||
val account = accountState?.account ?: return
|
||||
|
||||
nonClickablePrepend()
|
||||
|
||||
Row(
|
||||
@@ -311,7 +310,7 @@ fun ZapVote(
|
||||
)
|
||||
.show()
|
||||
}
|
||||
} else if (accountViewModel.isLoggedUser(zappedNote.author)) {
|
||||
} else if (isLoggedUser) {
|
||||
scope.launch {
|
||||
Toast
|
||||
.makeText(
|
||||
@@ -333,11 +332,13 @@ fun ZapVote(
|
||||
.show()
|
||||
}
|
||||
return@combinedClickable
|
||||
} else if (account.zapAmountChoices.size == 1 && pollViewModel.isValidInputVoteAmount(account.zapAmountChoices.first())) {
|
||||
} else if (accountViewModel.account.zapAmountChoices.size == 1 &&
|
||||
pollViewModel.isValidInputVoteAmount(accountViewModel.account.zapAmountChoices.first())
|
||||
) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
accountViewModel.zap(
|
||||
baseNote,
|
||||
account.zapAmountChoices.first() * 1000,
|
||||
accountViewModel.account.zapAmountChoices.first() * 1000,
|
||||
poolOption.option,
|
||||
"",
|
||||
context,
|
||||
@@ -354,7 +355,7 @@ fun ZapVote(
|
||||
zappingProgress = it
|
||||
}
|
||||
},
|
||||
zapType = account.defaultZapType
|
||||
zapType = accountViewModel.account.defaultZapType
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -519,10 +519,8 @@ private fun ZapIcon(
|
||||
var wasZappedByLoggedInUser by remember { mutableStateOf(false) }
|
||||
val zapsState by baseNote.live().zaps.observeAsState()
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
LaunchedEffect(key1 = zapsState) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
launch(Dispatchers.IO) {
|
||||
zapsState?.note?.let {
|
||||
if (!wasZappedByLoggedInUser) {
|
||||
val newWasZapped = accountViewModel.calculateIfNoteWasZappedByAccount(it)
|
||||
@@ -559,17 +557,16 @@ private fun ZapAmountText(
|
||||
accountViewModel: AccountViewModel
|
||||
) {
|
||||
val zapsState by baseNote.live().zaps.observeAsState()
|
||||
val zappedNote = remember(zapsState) { zapsState?.note } ?: return
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
var zapAmountTxt by remember { mutableStateOf("") }
|
||||
|
||||
LaunchedEffect(key1 = zapsState) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
val newZapAmount = showAmount(accountViewModel.calculateZapAmount(zappedNote))
|
||||
if (newZapAmount != zapAmountTxt) {
|
||||
zapAmountTxt = newZapAmount
|
||||
launch(Dispatchers.IO) {
|
||||
zapsState?.note?.let {
|
||||
val newZapAmount = showAmount(accountViewModel.calculateZapAmount(it))
|
||||
if (newZapAmount != zapAmountTxt) {
|
||||
zapAmountTxt = newZapAmount
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,11 +307,13 @@ private fun ReportsTabHeader(baseUser: User) {
|
||||
var userReports by remember { mutableStateOf(0) }
|
||||
|
||||
LaunchedEffect(key1 = userState) {
|
||||
UserProfileReportsFeedFilter.user = baseUser
|
||||
val newSize = UserProfileReportsFeedFilter.feed().size
|
||||
launch(Dispatchers.IO) {
|
||||
UserProfileReportsFeedFilter.user = baseUser
|
||||
val newSize = UserProfileReportsFeedFilter.feed().size
|
||||
|
||||
if (newSize != userReports) {
|
||||
userReports = newSize
|
||||
if (newSize != userReports) {
|
||||
userReports = newSize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,12 +323,19 @@ private fun ReportsTabHeader(baseUser: User) {
|
||||
@Composable
|
||||
private fun BookmarkTabHeader(baseUser: User) {
|
||||
val userState by baseUser.live().bookmarks.observeAsState()
|
||||
val userBookmarks = remember(userState) {
|
||||
val bookmarkList = userState?.user?.latestBookmarkList
|
||||
(bookmarkList?.taggedEvents()?.count() ?: 0) + (
|
||||
bookmarkList?.taggedAddresses()?.count()
|
||||
?: 0
|
||||
)
|
||||
|
||||
var userBookmarks by remember { mutableStateOf(0) }
|
||||
|
||||
LaunchedEffect(key1 = userState) {
|
||||
launch(Dispatchers.IO) {
|
||||
val bookmarkList = userState?.user?.latestBookmarkList
|
||||
|
||||
val newBookmarks = (bookmarkList?.taggedEvents()?.count() ?: 0) + (bookmarkList?.taggedAddresses()?.count() ?: 0)
|
||||
|
||||
if (newBookmarks != userBookmarks) {
|
||||
userBookmarks = newBookmarks
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text(text = "$userBookmarks ${stringResource(R.string.bookmarks)}")
|
||||
|
||||
Reference in New Issue
Block a user