Splits profile between new threads and replies
This commit is contained in:
+24
@@ -0,0 +1,24 @@
|
|||||||
|
package com.vitorpamplona.amethyst.ui.dal
|
||||||
|
|
||||||
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.amethyst.model.User
|
||||||
|
|
||||||
|
object UserProfileConversationsFeedFilter: FeedFilter<Note>() {
|
||||||
|
var account: Account? = null
|
||||||
|
var user: User? = null
|
||||||
|
|
||||||
|
fun loadUserProfile(accountLoggedIn: Account, userId: String) {
|
||||||
|
account = accountLoggedIn
|
||||||
|
user = LocalCache.checkGetOrCreateUser(userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun feed(): List<Note> {
|
||||||
|
return user?.notes
|
||||||
|
?.filter { account?.isAcceptable(it) == true && !it.isNewThread() }
|
||||||
|
?.sortedBy { it.event?.createdAt }
|
||||||
|
?.reversed()
|
||||||
|
?: emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -5,7 +5,7 @@ import com.vitorpamplona.amethyst.model.LocalCache
|
|||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
|
|
||||||
object UserProfileNoteFeedFilter: FeedFilter<Note>() {
|
object UserProfileNewThreadFeedFilter: FeedFilter<Note>() {
|
||||||
var account: Account? = null
|
var account: Account? = null
|
||||||
var user: User? = null
|
var user: User? = null
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ object UserProfileNoteFeedFilter: FeedFilter<Note>() {
|
|||||||
|
|
||||||
override fun feed(): List<Note> {
|
override fun feed(): List<Note> {
|
||||||
return user?.notes
|
return user?.notes
|
||||||
?.filter { account?.isAcceptable(it) == true }
|
?.filter { account?.isAcceptable(it) == true && it.isNewThread() }
|
||||||
?.sortedBy { it.event?.createdAt }
|
?.sortedBy { it.event?.createdAt }
|
||||||
?.reversed()
|
?.reversed()
|
||||||
?: emptyList()
|
?: emptyList()
|
||||||
@@ -14,7 +14,8 @@ import com.vitorpamplona.amethyst.ui.dal.GlobalFeedFilter
|
|||||||
import com.vitorpamplona.amethyst.ui.dal.HomeConversationsFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.HomeConversationsFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.dal.HomeNewThreadFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.HomeNewThreadFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.dal.ThreadFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.ThreadFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.dal.UserProfileNoteFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.UserProfileConversationsFeedFilter
|
||||||
|
import com.vitorpamplona.amethyst.ui.dal.UserProfileNewThreadFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.dal.UserProfileReportsFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.UserProfileReportsFeedFilter
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@@ -32,7 +33,8 @@ class NostrChannelFeedViewModel: FeedViewModel(ChannelFeedFilter)
|
|||||||
class NostrChatRoomFeedViewModel: FeedViewModel(ChatroomFeedFilter)
|
class NostrChatRoomFeedViewModel: FeedViewModel(ChatroomFeedFilter)
|
||||||
class NostrGlobalFeedViewModel: FeedViewModel(GlobalFeedFilter)
|
class NostrGlobalFeedViewModel: FeedViewModel(GlobalFeedFilter)
|
||||||
class NostrThreadFeedViewModel: FeedViewModel(ThreadFeedFilter)
|
class NostrThreadFeedViewModel: FeedViewModel(ThreadFeedFilter)
|
||||||
class NostrUserProfileFeedViewModel: FeedViewModel(UserProfileNoteFeedFilter)
|
class NostrUserProfileNewThreadsFeedViewModel: FeedViewModel(UserProfileNewThreadFeedFilter)
|
||||||
|
class NostrUserProfileConversationsFeedViewModel: FeedViewModel(UserProfileConversationsFeedFilter)
|
||||||
class NostrUserProfileReportFeedViewModel: FeedViewModel(UserProfileReportsFeedFilter)
|
class NostrUserProfileReportFeedViewModel: FeedViewModel(UserProfileReportsFeedFilter)
|
||||||
class NostrChatroomListKnownFeedViewModel: FeedViewModel(ChatroomListKnownFeedFilter)
|
class NostrChatroomListKnownFeedViewModel: FeedViewModel(ChatroomListKnownFeedFilter)
|
||||||
class NostrChatroomListNewFeedViewModel: FeedViewModel(ChatroomListNewFeedFilter)
|
class NostrChatroomListNewFeedViewModel: FeedViewModel(ChatroomListNewFeedFilter)
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ import com.vitorpamplona.amethyst.ui.actions.NewUserMetadataView
|
|||||||
import com.vitorpamplona.amethyst.ui.components.InvoiceRequest
|
import com.vitorpamplona.amethyst.ui.components.InvoiceRequest
|
||||||
import com.vitorpamplona.amethyst.ui.dal.UserProfileFollowersFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.UserProfileFollowersFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.dal.UserProfileFollowsFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.UserProfileFollowsFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.dal.UserProfileNoteFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.UserProfileConversationsFeedFilter
|
||||||
|
import com.vitorpamplona.amethyst.ui.dal.UserProfileNewThreadFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.dal.UserProfileReportsFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.UserProfileReportsFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.dal.UserProfileZapsFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.UserProfileZapsFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.note.UserPicture
|
import com.vitorpamplona.amethyst.ui.note.UserPicture
|
||||||
@@ -65,7 +66,6 @@ import com.vitorpamplona.amethyst.ui.note.showAmount
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import nostr.postr.toNpub
|
|
||||||
import nostr.postr.toNsec
|
import nostr.postr.toNsec
|
||||||
|
|
||||||
@OptIn(ExperimentalPagerApi::class)
|
@OptIn(ExperimentalPagerApi::class)
|
||||||
@@ -76,7 +76,8 @@ fun ProfileScreen(userId: String?, accountViewModel: AccountViewModel, navContro
|
|||||||
|
|
||||||
if (userId == null) return
|
if (userId == null) return
|
||||||
|
|
||||||
UserProfileNoteFeedFilter.loadUserProfile(account, userId)
|
UserProfileNewThreadFeedFilter.loadUserProfile(account, userId)
|
||||||
|
UserProfileConversationsFeedFilter.loadUserProfile(account, userId)
|
||||||
UserProfileFollowersFeedFilter.loadUserProfile(account, userId)
|
UserProfileFollowersFeedFilter.loadUserProfile(account, userId)
|
||||||
UserProfileFollowsFeedFilter.loadUserProfile(account, userId)
|
UserProfileFollowsFeedFilter.loadUserProfile(account, userId)
|
||||||
UserProfileZapsFeedFilter.loadUserProfile(userId)
|
UserProfileZapsFeedFilter.loadUserProfile(userId)
|
||||||
@@ -164,62 +165,38 @@ fun ProfileScreen(userId: String?, accountViewModel: AccountViewModel, navContro
|
|||||||
tabsSize = it
|
tabsSize = it
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Tab(
|
val tabs = listOf<@Composable() (() -> Unit)?>(
|
||||||
selected = pagerState.currentPage == 0,
|
{
|
||||||
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(0) } },
|
|
||||||
text = {
|
|
||||||
Text(text = "Notes")
|
Text(text = "Notes")
|
||||||
}
|
},
|
||||||
)
|
{
|
||||||
|
Text(text = "Replies")
|
||||||
Tab(
|
},
|
||||||
selected = pagerState.currentPage == 1,
|
{
|
||||||
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(1) } },
|
|
||||||
text = {
|
|
||||||
val userState by baseUser.live().follows.observeAsState()
|
val userState by baseUser.live().follows.observeAsState()
|
||||||
val userFollows = userState?.user?.follows?.size ?: "--"
|
val userFollows = userState?.user?.follows?.size ?: "--"
|
||||||
|
|
||||||
Text(text = "$userFollows Follows")
|
Text(text = "$userFollows Follows")
|
||||||
}
|
},
|
||||||
)
|
{
|
||||||
|
|
||||||
Tab(
|
|
||||||
selected = pagerState.currentPage == 2,
|
|
||||||
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(2) } },
|
|
||||||
text = {
|
|
||||||
val userState by baseUser.live().follows.observeAsState()
|
val userState by baseUser.live().follows.observeAsState()
|
||||||
val userFollows = userState?.user?.followers?.size ?: "--"
|
val userFollows = userState?.user?.followers?.size ?: "--"
|
||||||
|
|
||||||
Text(text = "$userFollows Followers")
|
Text(text = "$userFollows Followers")
|
||||||
}
|
},
|
||||||
)
|
{
|
||||||
|
|
||||||
Tab(
|
|
||||||
selected = pagerState.currentPage == 3,
|
|
||||||
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(3) } },
|
|
||||||
text = {
|
|
||||||
val userState by baseUser.live().zaps.observeAsState()
|
val userState by baseUser.live().zaps.observeAsState()
|
||||||
val userZaps = userState?.user?.zappedAmount()
|
val userZaps = userState?.user?.zappedAmount()
|
||||||
|
|
||||||
Text(text = "${showAmount(userZaps)} Zaps")
|
Text(text = "${showAmount(userZaps)} Zaps")
|
||||||
}
|
},
|
||||||
)
|
{
|
||||||
|
|
||||||
Tab(
|
|
||||||
selected = pagerState.currentPage == 4,
|
|
||||||
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(4) } },
|
|
||||||
text = {
|
|
||||||
val userState by baseUser.live().reports.observeAsState()
|
val userState by baseUser.live().reports.observeAsState()
|
||||||
val userReports = userState?.user?.reports?.values?.flatten()?.count()
|
val userReports = userState?.user?.reports?.values?.flatten()?.count()
|
||||||
|
|
||||||
Text(text = "${userReports} Reports")
|
Text(text = "${userReports} Reports")
|
||||||
}
|
},
|
||||||
)
|
{
|
||||||
|
|
||||||
Tab(
|
|
||||||
selected = pagerState.currentPage == 5,
|
|
||||||
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(5) } },
|
|
||||||
text = {
|
|
||||||
val userState by baseUser.live().relays.observeAsState()
|
val userState by baseUser.live().relays.observeAsState()
|
||||||
val userRelaysBeingUsed =
|
val userRelaysBeingUsed =
|
||||||
userState?.user?.relaysBeingUsed?.size ?: "--"
|
userState?.user?.relaysBeingUsed?.size ?: "--"
|
||||||
@@ -230,21 +207,30 @@ fun ProfileScreen(userId: String?, accountViewModel: AccountViewModel, navContro
|
|||||||
Text(text = "$userRelaysBeingUsed / $userRelays Relays")
|
Text(text = "$userRelaysBeingUsed / $userRelays Relays")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
tabs.forEachIndexed { index, function ->
|
||||||
|
Tab(
|
||||||
|
selected = pagerState.currentPage == index,
|
||||||
|
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(index) } },
|
||||||
|
text = function
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
count = 6,
|
count = 7,
|
||||||
state = pagerState,
|
state = pagerState,
|
||||||
modifier = with(LocalDensity.current) {
|
modifier = with(LocalDensity.current) {
|
||||||
Modifier.height((columnSize.height - tabsSize.height).toDp())
|
Modifier.height((columnSize.height - tabsSize.height).toDp())
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
when (pagerState.currentPage) {
|
when (pagerState.currentPage) {
|
||||||
0 -> TabNotes(baseUser, accountViewModel, navController)
|
0 -> TabNotesNewThreads(baseUser, accountViewModel, navController)
|
||||||
1 -> TabFollows(baseUser, accountViewModel, navController)
|
1 -> TabNotesConversations(baseUser, accountViewModel, navController)
|
||||||
2 -> TabFollowers(baseUser, accountViewModel, navController)
|
2 -> TabFollows(baseUser, accountViewModel, navController)
|
||||||
3 -> TabReceivedZaps(baseUser, accountViewModel, navController)
|
3 -> TabFollowers(baseUser, accountViewModel, navController)
|
||||||
4 -> TabReports(baseUser, accountViewModel, navController)
|
4 -> TabReceivedZaps(baseUser, accountViewModel, navController)
|
||||||
5 -> TabRelays(baseUser, accountViewModel, navController)
|
5 -> TabReports(baseUser, accountViewModel, navController)
|
||||||
|
6 -> TabRelays(baseUser, accountViewModel, navController)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -465,10 +451,30 @@ private fun DrawBanner(baseUser: User) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TabNotes(user: User, accountViewModel: AccountViewModel, navController: NavController) {
|
fun TabNotesNewThreads(user: User, accountViewModel: AccountViewModel, navController: NavController) {
|
||||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||||
if (accountState != null) {
|
if (accountState != null) {
|
||||||
val feedViewModel: NostrUserProfileFeedViewModel = viewModel()
|
val feedViewModel: NostrUserProfileNewThreadsFeedViewModel = viewModel()
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
feedViewModel.refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(Modifier.fillMaxHeight()) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.padding(vertical = 0.dp)
|
||||||
|
) {
|
||||||
|
FeedView(feedViewModel, accountViewModel, navController, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TabNotesConversations(user: User, accountViewModel: AccountViewModel, navController: NavController) {
|
||||||
|
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||||
|
if (accountState != null) {
|
||||||
|
val feedViewModel: NostrUserProfileConversationsFeedViewModel = viewModel()
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
feedViewModel.refresh()
|
feedViewModel.refresh()
|
||||||
|
|||||||
Reference in New Issue
Block a user