mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-07-12 18:52:21 +02:00
Moving static sizes to the Shape class
This commit is contained in:
@ -73,7 +73,6 @@ class TextToSpeechEngine private constructor() {
|
|||||||
)
|
)
|
||||||
speak(message)
|
speak(message)
|
||||||
} else {
|
} else {
|
||||||
Log.d("AAA", "initTTS: $it")
|
|
||||||
onErrorListener?.invoke(getErrorText(it))
|
onErrorListener?.invoke(getErrorText(it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@ import com.vitorpamplona.amethyst.model.RelaySetupInfo
|
|||||||
import com.vitorpamplona.amethyst.service.relays.FeedType
|
import com.vitorpamplona.amethyst.service.relays.FeedType
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
import java.lang.Math.round
|
import java.lang.Math.round
|
||||||
|
|
||||||
@ -477,7 +478,7 @@ fun EditableServerConfig(relayToAdd: String, onNewRelay: (RelaySetupInfo) -> Uni
|
|||||||
imageVector = Icons.Default.Download,
|
imageVector = Icons.Default.Download,
|
||||||
null,
|
null,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(35.dp)
|
.size(Size35dp)
|
||||||
.padding(horizontal = 5.dp),
|
.padding(horizontal = 5.dp),
|
||||||
tint = if (read) Color.Green else MaterialTheme.colors.placeholderText
|
tint = if (read) Color.Green else MaterialTheme.colors.placeholderText
|
||||||
)
|
)
|
||||||
@ -488,7 +489,7 @@ fun EditableServerConfig(relayToAdd: String, onNewRelay: (RelaySetupInfo) -> Uni
|
|||||||
imageVector = Icons.Default.Upload,
|
imageVector = Icons.Default.Upload,
|
||||||
null,
|
null,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(35.dp)
|
.size(Size35dp)
|
||||||
.padding(horizontal = 5.dp),
|
.padding(horizontal = 5.dp),
|
||||||
tint = if (write) Color.Green else MaterialTheme.colors.placeholderText
|
tint = if (write) Color.Green else MaterialTheme.colors.placeholderText
|
||||||
)
|
)
|
||||||
|
@ -12,7 +12,7 @@ class UserProfileAppRecommendationsFeedFilter(val user: User) : FeedFilter<Note>
|
|||||||
}.mapNotNull {
|
}.mapNotNull {
|
||||||
(it.event as? AppRecommendationEvent)?.recommendations()
|
(it.event as? AppRecommendationEvent)?.recommendations()
|
||||||
}.flatten()
|
}.flatten()
|
||||||
.mapNotNull {
|
.map {
|
||||||
LocalCache.getOrCreateAddressableNote(it)
|
LocalCache.getOrCreateAddressableNote(it)
|
||||||
}.toSet().toList()
|
}.toSet().toList()
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import com.vitorpamplona.amethyst.R
|
|||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||||
import kotlinx.collections.immutable.ImmutableSet
|
import kotlinx.collections.immutable.ImmutableSet
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -88,7 +89,7 @@ fun HiddenNote(
|
|||||||
baseNote = it,
|
baseNote = it,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
size = 35.dp
|
size = Size35dp
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ import com.vitorpamplona.amethyst.ui.screen.MultiSetCard
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.showAmountAxis
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.showAmountAxis
|
||||||
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor
|
import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor
|
||||||
import com.vitorpamplona.amethyst.ui.theme.overPictureBackground
|
import com.vitorpamplona.amethyst.ui.theme.overPictureBackground
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
@ -367,9 +368,7 @@ val textBoxModifier = Modifier.padding(start = 5.dp).fillMaxWidth()
|
|||||||
|
|
||||||
val simpleModifier = Modifier
|
val simpleModifier = Modifier
|
||||||
|
|
||||||
val size = 35.dp
|
val sizedModifier = Modifier.size(Size35dp)
|
||||||
|
|
||||||
val sizedModifier = Modifier.size(size)
|
|
||||||
|
|
||||||
val bottomPadding1dp = Modifier.padding(bottom = 1.dp)
|
val bottomPadding1dp = Modifier.padding(bottom = 1.dp)
|
||||||
|
|
||||||
@ -398,7 +397,7 @@ private fun AuthorPictureAndComment(
|
|||||||
Box(modifier = sizedModifier, contentAlignment = Alignment.BottomCenter) {
|
Box(modifier = sizedModifier, contentAlignment = Alignment.BottomCenter) {
|
||||||
FastNoteAuthorPicture(
|
FastNoteAuthorPicture(
|
||||||
author = author,
|
author = author,
|
||||||
size = size,
|
size = Size35dp,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
pictureModifier = simpleModifier
|
pictureModifier = simpleModifier
|
||||||
)
|
)
|
||||||
|
@ -142,6 +142,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.ReportNoteDialog
|
|||||||
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
||||||
import com.vitorpamplona.amethyst.ui.theme.Following
|
import com.vitorpamplona.amethyst.ui.theme.Following
|
||||||
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
|
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.mediumImportanceLink
|
import com.vitorpamplona.amethyst.ui.theme.mediumImportanceLink
|
||||||
import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor
|
import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
@ -947,7 +948,7 @@ fun RenderAppDefinition(
|
|||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.height(35.dp)
|
.height(Size35dp)
|
||||||
.padding(bottom = 3.dp)
|
.padding(bottom = 3.dp)
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
@ -1354,7 +1355,7 @@ private fun RenderBadgeAward(
|
|||||||
awardees.take(100).forEach { user ->
|
awardees.take(100).forEach { user ->
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(size = 35.dp)
|
.size(size = Size35dp)
|
||||||
.clickable {
|
.clickable {
|
||||||
nav("User/${user.pubkeyHex}")
|
nav("User/${user.pubkeyHex}")
|
||||||
},
|
},
|
||||||
@ -1363,7 +1364,7 @@ private fun RenderBadgeAward(
|
|||||||
UserPicture(
|
UserPicture(
|
||||||
baseUser = user,
|
baseUser = user,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
size = 35.dp
|
size = Size35dp
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
|
|||||||
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
||||||
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
|
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
|
||||||
import com.vitorpamplona.amethyst.ui.qrcode.NIP19QrCodeScanner
|
import com.vitorpamplona.amethyst.ui.qrcode.NIP19QrCodeScanner
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ShowQRDialog(user: User, onScan: (String) -> Unit, onClose: () -> Unit) {
|
fun ShowQRDialog(user: User, onScan: (String) -> Unit, onClose: () -> Unit) {
|
||||||
@ -99,7 +100,7 @@ fun ShowQRDialog(user: User, onScan: (String) -> Unit, onClose: () -> Unit) {
|
|||||||
horizontalArrangement = Arrangement.Center,
|
horizontalArrangement = Arrangement.Center,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 35.dp)
|
.padding(horizontal = Size35dp)
|
||||||
) {
|
) {
|
||||||
QrCodeDrawer("nostr:${user.pubkeyNpub()}")
|
QrCodeDrawer("nostr:${user.pubkeyNpub()}")
|
||||||
}
|
}
|
||||||
@ -112,7 +113,7 @@ fun ShowQRDialog(user: User, onScan: (String) -> Unit, onClose: () -> Unit) {
|
|||||||
) {
|
) {
|
||||||
Button(
|
Button(
|
||||||
onClick = { presenting = false },
|
onClick = { presenting = false },
|
||||||
shape = RoundedCornerShape(35.dp),
|
shape = RoundedCornerShape(Size35dp),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.height(50.dp),
|
.height(50.dp),
|
||||||
|
@ -80,6 +80,7 @@ import com.vitorpamplona.amethyst.ui.note.ChatroomMessageCompose
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.NostrChannelFeedViewModel
|
import com.vitorpamplona.amethyst.ui.screen.NostrChannelFeedViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.RefreshingChatroomFeedView
|
import com.vitorpamplona.amethyst.ui.screen.RefreshingChatroomFeedView
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -396,11 +397,11 @@ fun ChannelHeader(baseChannel: Channel, accountViewModel: AccountViewModel, nav:
|
|||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
RobohashAsyncImageProxy(
|
RobohashAsyncImageProxy(
|
||||||
robot = channel.idHex,
|
robot = channel.idHex,
|
||||||
model = ResizeImage(channel.profilePicture(), 35.dp),
|
model = ResizeImage(channel.profilePicture(), Size35dp),
|
||||||
contentDescription = context.getString(R.string.profile_image),
|
contentDescription = context.getString(R.string.profile_image),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(35.dp)
|
.width(Size35dp)
|
||||||
.height(35.dp)
|
.height(Size35dp)
|
||||||
.clip(shape = CircleShape)
|
.clip(shape = CircleShape)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -429,7 +430,7 @@ fun ChannelHeader(baseChannel: Channel, accountViewModel: AccountViewModel, nav:
|
|||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.height(35.dp)
|
.height(Size35dp)
|
||||||
.padding(bottom = 3.dp)
|
.padding(bottom = 3.dp)
|
||||||
) {
|
) {
|
||||||
ChannelActionOptions(channel, accountViewModel, nav)
|
ChannelActionOptions(channel, accountViewModel, nav)
|
||||||
|
@ -36,6 +36,7 @@ import com.vitorpamplona.amethyst.ui.note.UserPicture
|
|||||||
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||||
import com.vitorpamplona.amethyst.ui.screen.NostrChatroomFeedViewModel
|
import com.vitorpamplona.amethyst.ui.screen.NostrChatroomFeedViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.RefreshingChatroomFeedView
|
import com.vitorpamplona.amethyst.ui.screen.RefreshingChatroomFeedView
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@ -198,7 +199,7 @@ fun ChatroomHeader(baseUser: User, accountViewModel: AccountViewModel, nav: (Str
|
|||||||
UserPicture(
|
UserPicture(
|
||||||
baseUser = baseUser,
|
baseUser = baseUser,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
size = 35.dp
|
size = Size35dp
|
||||||
)
|
)
|
||||||
|
|
||||||
Column(modifier = Modifier.padding(start = 10.dp)) {
|
Column(modifier = Modifier.padding(start = 10.dp)) {
|
||||||
|
@ -9,6 +9,7 @@ import androidx.compose.foundation.*
|
|||||||
import androidx.compose.foundation.gestures.scrollBy
|
import androidx.compose.foundation.gestures.scrollBy
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.pager.HorizontalPager
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
|
import androidx.compose.foundation.pager.PagerState
|
||||||
import androidx.compose.foundation.pager.rememberPagerState
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.text.ClickableText
|
import androidx.compose.foundation.text.ClickableText
|
||||||
@ -95,10 +96,12 @@ import com.vitorpamplona.amethyst.ui.screen.RefreshingFeedUserFeedView
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.RelayFeedView
|
import com.vitorpamplona.amethyst.ui.screen.RelayFeedView
|
||||||
import com.vitorpamplona.amethyst.ui.screen.RelayFeedViewModel
|
import com.vitorpamplona.amethyst.ui.screen.RelayFeedViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.UserFeedViewModel
|
import com.vitorpamplona.amethyst.ui.screen.UserFeedViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@ -108,13 +111,16 @@ import java.math.BigDecimal
|
|||||||
fun ProfileScreen(userId: String?, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
fun ProfileScreen(userId: String?, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||||
if (userId == null) return
|
if (userId == null) return
|
||||||
|
|
||||||
var userBase by remember { mutableStateOf<User?>(null) }
|
var userBase by remember { mutableStateOf<User?>(LocalCache.getUserIfExists(userId)) }
|
||||||
|
|
||||||
LaunchedEffect(userId) {
|
LaunchedEffect(userId) {
|
||||||
withContext(Dispatchers.IO) {
|
if (userBase == null) {
|
||||||
val newUserBase = LocalCache.checkGetOrCreateUser(userId)
|
// waits to resolve.
|
||||||
if (newUserBase != userBase) {
|
withContext(Dispatchers.IO) {
|
||||||
userBase = newUserBase
|
val newUserBase = LocalCache.checkGetOrCreateUser(userId)
|
||||||
|
if (newUserBase != userBase) {
|
||||||
|
userBase = newUserBase
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -257,7 +263,7 @@ fun ProfileScreen(
|
|||||||
})
|
})
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
) {
|
) {
|
||||||
Column(modifier = Modifier.padding()) {
|
Column() {
|
||||||
ProfileHeader(baseUser, appRecommendations, nav, accountViewModel)
|
ProfileHeader(baseUser, appRecommendations, nav, accountViewModel)
|
||||||
ScrollableTabRow(
|
ScrollableTabRow(
|
||||||
backgroundColor = MaterialTheme.colors.background,
|
backgroundColor = MaterialTheme.colors.background,
|
||||||
@ -267,26 +273,7 @@ fun ProfileScreen(
|
|||||||
tabsSize = it
|
tabsSize = it
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
val tabs = listOf<@Composable() (() -> Unit)?>(
|
CreateAndRenderTabs(baseUser, pagerState)
|
||||||
{ Text(text = stringResource(R.string.notes)) },
|
|
||||||
{ Text(text = stringResource(R.string.replies)) },
|
|
||||||
{ FollowTabHeader(baseUser) },
|
|
||||||
{ FollowersTabHeader(baseUser) },
|
|
||||||
{ ZapTabHeader(baseUser) },
|
|
||||||
{ BookmarkTabHeader(baseUser) },
|
|
||||||
{ ReportsTabHeader(baseUser) },
|
|
||||||
{ RelaysTabHeader(baseUser) }
|
|
||||||
)
|
|
||||||
|
|
||||||
tabs.forEachIndexed { index, function ->
|
|
||||||
Tab(
|
|
||||||
selected = pagerState.currentPage == index,
|
|
||||||
onClick = {
|
|
||||||
coroutineScope.launch { pagerState.animateScrollToPage(index) }
|
|
||||||
},
|
|
||||||
text = function
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
pageCount = 8,
|
pageCount = 8,
|
||||||
@ -295,16 +282,15 @@ fun ProfileScreen(
|
|||||||
Modifier.height((columnSize.height - tabsSize.height).toDp())
|
Modifier.height((columnSize.height - tabsSize.height).toDp())
|
||||||
}
|
}
|
||||||
) { page ->
|
) { page ->
|
||||||
when (page) {
|
CreateAndRenderPages(
|
||||||
0 -> TabNotesNewThreads(accountViewModel, nav)
|
page,
|
||||||
1 -> TabNotesConversations(accountViewModel, nav)
|
baseUser,
|
||||||
2 -> TabFollows(baseUser, followsFeedViewModel, accountViewModel, nav)
|
followsFeedViewModel,
|
||||||
3 -> TabFollowers(baseUser, followersFeedViewModel, accountViewModel, nav)
|
followersFeedViewModel,
|
||||||
4 -> TabReceivedZaps(baseUser, zapFeedViewModel, accountViewModel, nav)
|
zapFeedViewModel,
|
||||||
5 -> TabBookmarks(baseUser, accountViewModel, nav)
|
accountViewModel,
|
||||||
6 -> TabReports(baseUser, accountViewModel, nav)
|
nav,
|
||||||
7 -> TabRelays(baseUser, accountViewModel)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,6 +298,58 @@ fun ProfileScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun CreateAndRenderPages(
|
||||||
|
page: Int,
|
||||||
|
baseUser: User,
|
||||||
|
followsFeedViewModel: NostrUserProfileFollowsUserFeedViewModel,
|
||||||
|
followersFeedViewModel: NostrUserProfileFollowersUserFeedViewModel,
|
||||||
|
zapFeedViewModel: NostrUserProfileZapsFeedViewModel,
|
||||||
|
accountViewModel: AccountViewModel,
|
||||||
|
nav: (String) -> Unit
|
||||||
|
) {
|
||||||
|
when (page) {
|
||||||
|
0 -> TabNotesNewThreads(accountViewModel, nav)
|
||||||
|
1 -> TabNotesConversations(accountViewModel, nav)
|
||||||
|
2 -> TabFollows(baseUser, followsFeedViewModel, accountViewModel, nav)
|
||||||
|
3 -> TabFollowers(baseUser, followersFeedViewModel, accountViewModel, nav)
|
||||||
|
4 -> TabReceivedZaps(baseUser, zapFeedViewModel, accountViewModel, nav)
|
||||||
|
5 -> TabBookmarks(baseUser, accountViewModel, nav)
|
||||||
|
6 -> TabReports(baseUser, accountViewModel, nav)
|
||||||
|
7 -> TabRelays(baseUser, accountViewModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
|
@Composable
|
||||||
|
private fun CreateAndRenderTabs(
|
||||||
|
baseUser: User,
|
||||||
|
pagerState: PagerState,
|
||||||
|
) {
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
val tabs = listOf<@Composable() (() -> Unit)?>(
|
||||||
|
{ Text(text = stringResource(R.string.notes)) },
|
||||||
|
{ Text(text = stringResource(R.string.replies)) },
|
||||||
|
{ FollowTabHeader(baseUser) },
|
||||||
|
{ FollowersTabHeader(baseUser) },
|
||||||
|
{ ZapTabHeader(baseUser) },
|
||||||
|
{ BookmarkTabHeader(baseUser) },
|
||||||
|
{ ReportsTabHeader(baseUser) },
|
||||||
|
{ RelaysTabHeader(baseUser) }
|
||||||
|
)
|
||||||
|
|
||||||
|
tabs.forEachIndexed { index, function ->
|
||||||
|
Tab(
|
||||||
|
selected = pagerState.currentPage == index,
|
||||||
|
onClick = {
|
||||||
|
coroutineScope.launch { pagerState.animateScrollToPage(index) }
|
||||||
|
},
|
||||||
|
text = function
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun RelaysTabHeader(baseUser: User) {
|
private fun RelaysTabHeader(baseUser: User) {
|
||||||
val userState by baseUser.live().relays.observeAsState()
|
val userState by baseUser.live().relays.observeAsState()
|
||||||
@ -500,7 +538,7 @@ private fun ProfileHeader(
|
|||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.height(35.dp)
|
.height(Size35dp)
|
||||||
.padding(bottom = 3.dp)
|
.padding(bottom = 3.dp)
|
||||||
) {
|
) {
|
||||||
MessageButton(baseUser, nav)
|
MessageButton(baseUser, nav)
|
||||||
@ -879,7 +917,7 @@ private fun WatchApp(baseApp: Note, nav: (String) -> Unit) {
|
|||||||
Box(
|
Box(
|
||||||
remember {
|
remember {
|
||||||
Modifier
|
Modifier
|
||||||
.size(35.dp)
|
.size(Size35dp)
|
||||||
.clickable {
|
.clickable {
|
||||||
nav("Note/${baseApp.idHex}")
|
nav("Note/${baseApp.idHex}")
|
||||||
}
|
}
|
||||||
@ -890,7 +928,7 @@ private fun WatchApp(baseApp: Note, nav: (String) -> Unit) {
|
|||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = remember {
|
modifier = remember {
|
||||||
Modifier
|
Modifier
|
||||||
.size(35.dp)
|
.size(Size35dp)
|
||||||
.clip(shape = CircleShape)
|
.clip(shape = CircleShape)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -931,27 +969,37 @@ private fun DisplayBadges(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun LoadAndRenderBadge(badgeAwardEventHex: String, nav: (String) -> Unit) {
|
private fun LoadAndRenderBadge(badgeAwardEventHex: String, nav: (String) -> Unit) {
|
||||||
var baseNote by remember {
|
var baseNote by remember {
|
||||||
mutableStateOf<Note?>(null)
|
mutableStateOf<Note?>(LocalCache.getNoteIfExists(badgeAwardEventHex))
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(key1 = badgeAwardEventHex) {
|
LaunchedEffect(key1 = badgeAwardEventHex) {
|
||||||
launch(Dispatchers.IO) {
|
if (baseNote == null) {
|
||||||
baseNote = LocalCache.getOrCreateNote(badgeAwardEventHex)
|
launch(Dispatchers.IO) {
|
||||||
|
baseNote = LocalCache.getOrCreateNote(badgeAwardEventHex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
baseNote?.let {
|
baseNote?.let {
|
||||||
val badgeAwardState by it.live().metadata.observeAsState()
|
ObserveAndRenderBadge(it, nav)
|
||||||
val baseBadgeDefinition by remember(badgeAwardState) {
|
}
|
||||||
derivedStateOf {
|
}
|
||||||
badgeAwardState?.note?.replyTo?.firstOrNull()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
baseBadgeDefinition?.let {
|
@Composable
|
||||||
BadgeThumb(it, nav, 35.dp)
|
private fun ObserveAndRenderBadge(
|
||||||
|
it: Note,
|
||||||
|
nav: (String) -> Unit
|
||||||
|
) {
|
||||||
|
val badgeAwardState by it.live().metadata.observeAsState()
|
||||||
|
val baseBadgeDefinition by remember(badgeAwardState) {
|
||||||
|
derivedStateOf {
|
||||||
|
badgeAwardState?.note?.replyTo?.firstOrNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
baseBadgeDefinition?.let {
|
||||||
|
BadgeThumb(it, nav, Size35dp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -980,41 +1028,54 @@ fun BadgeThumb(
|
|||||||
.height(size)
|
.height(size)
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
val noteState by baseNote.live().metadata.observeAsState()
|
WatchAndRenderBadgeImage(baseNote, size, pictureModifier, onClick)
|
||||||
val event = remember(noteState) { noteState?.note?.event as? BadgeDefinitionEvent } ?: return
|
}
|
||||||
val image = remember(noteState) { event.thumb()?.ifBlank { null } ?: event.image()?.ifBlank { null } }
|
}
|
||||||
|
|
||||||
if (image == null) {
|
@Composable
|
||||||
RobohashAsyncImage(
|
private fun WatchAndRenderBadgeImage(
|
||||||
robot = "authornotfound",
|
baseNote: Note,
|
||||||
robotSize = size,
|
size: Dp,
|
||||||
contentDescription = stringResource(R.string.unknown_author),
|
pictureModifier: Modifier,
|
||||||
modifier = pictureModifier
|
onClick: ((String) -> Unit)?
|
||||||
.width(size)
|
) {
|
||||||
.height(size)
|
val noteState by baseNote.live().metadata.observeAsState()
|
||||||
.background(MaterialTheme.colors.background)
|
val eventId = remember(noteState) { noteState?.note?.idHex } ?: return
|
||||||
)
|
val image = remember(noteState) {
|
||||||
} else {
|
val event = noteState?.note?.event as? BadgeDefinitionEvent
|
||||||
RobohashFallbackAsyncImage(
|
event?.thumb()?.ifBlank { null } ?: event?.image()?.ifBlank { null }
|
||||||
robot = event.id,
|
}
|
||||||
robotSize = size,
|
|
||||||
model = image,
|
if (image == null) {
|
||||||
contentDescription = stringResource(id = R.string.profile_image),
|
RobohashAsyncImage(
|
||||||
modifier = pictureModifier
|
robot = "authornotfound",
|
||||||
.width(size)
|
robotSize = size,
|
||||||
.height(size)
|
contentDescription = stringResource(R.string.unknown_author),
|
||||||
.clip(shape = CircleShape)
|
modifier = pictureModifier
|
||||||
.background(MaterialTheme.colors.background)
|
.width(size)
|
||||||
.run {
|
.height(size)
|
||||||
if (onClick != null) {
|
.background(MaterialTheme.colors.background)
|
||||||
this.clickable(onClick = { onClick(event.id) })
|
)
|
||||||
} else {
|
} else {
|
||||||
this
|
RobohashFallbackAsyncImage(
|
||||||
}
|
robot = eventId,
|
||||||
|
robotSize = size,
|
||||||
|
model = image,
|
||||||
|
contentDescription = stringResource(id = R.string.profile_image),
|
||||||
|
modifier = pictureModifier
|
||||||
|
.width(size)
|
||||||
|
.height(size)
|
||||||
|
.clip(shape = CircleShape)
|
||||||
|
.background(MaterialTheme.colors.background)
|
||||||
|
.run {
|
||||||
|
if (onClick != null) {
|
||||||
|
this.clickable(onClick = { onClick(eventId) })
|
||||||
|
} else {
|
||||||
|
this
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1114,9 +1175,7 @@ fun TabFollows(baseUser: User, feedViewModel: UserFeedViewModel, accountViewMode
|
|||||||
WatchFollowChanges(baseUser, feedViewModel)
|
WatchFollowChanges(baseUser, feedViewModel)
|
||||||
|
|
||||||
Column(Modifier.fillMaxHeight()) {
|
Column(Modifier.fillMaxHeight()) {
|
||||||
Column(
|
Column() {
|
||||||
modifier = Modifier.padding(vertical = 0.dp)
|
|
||||||
) {
|
|
||||||
RefreshingFeedUserFeedView(feedViewModel, accountViewModel, nav, enablePullRefresh = false)
|
RefreshingFeedUserFeedView(feedViewModel, accountViewModel, nav, enablePullRefresh = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1127,9 +1186,7 @@ fun TabFollowers(baseUser: User, feedViewModel: UserFeedViewModel, accountViewMo
|
|||||||
WatchFollowerChanges(baseUser, feedViewModel)
|
WatchFollowerChanges(baseUser, feedViewModel)
|
||||||
|
|
||||||
Column(Modifier.fillMaxHeight()) {
|
Column(Modifier.fillMaxHeight()) {
|
||||||
Column(
|
Column() {
|
||||||
modifier = Modifier.padding(vertical = 0.dp)
|
|
||||||
) {
|
|
||||||
RefreshingFeedUserFeedView(feedViewModel, accountViewModel, nav, enablePullRefresh = false)
|
RefreshingFeedUserFeedView(feedViewModel, accountViewModel, nav, enablePullRefresh = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1164,9 +1221,7 @@ fun TabReceivedZaps(baseUser: User, zapFeedViewModel: NostrUserProfileZapsFeedVi
|
|||||||
WatchZapsAndUpdateFeed(baseUser, zapFeedViewModel)
|
WatchZapsAndUpdateFeed(baseUser, zapFeedViewModel)
|
||||||
|
|
||||||
Column(Modifier.fillMaxHeight()) {
|
Column(Modifier.fillMaxHeight()) {
|
||||||
Column(
|
Column() {
|
||||||
modifier = Modifier.padding(vertical = 0.dp)
|
|
||||||
) {
|
|
||||||
LnZapFeedView(zapFeedViewModel, accountViewModel, nav)
|
LnZapFeedView(zapFeedViewModel, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1191,9 +1246,7 @@ fun TabReports(baseUser: User, accountViewModel: AccountViewModel, nav: (String)
|
|||||||
WatchReportsAndUpdateFeed(baseUser, feedViewModel)
|
WatchReportsAndUpdateFeed(baseUser, feedViewModel)
|
||||||
|
|
||||||
Column(Modifier.fillMaxHeight()) {
|
Column(Modifier.fillMaxHeight()) {
|
||||||
Column(
|
Column() {
|
||||||
modifier = Modifier.padding(vertical = 0.dp)
|
|
||||||
) {
|
|
||||||
RefresheableFeedView(feedViewModel, null, accountViewModel, nav, enablePullRefresh = false)
|
RefresheableFeedView(feedViewModel, null, accountViewModel, nav, enablePullRefresh = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1346,16 +1399,16 @@ fun ShowUserButton(onClick: () -> Unit) {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UserProfileDropDownMenu(user: User, popupExpanded: Boolean, onDismiss: () -> Unit, accountViewModel: AccountViewModel) {
|
fun UserProfileDropDownMenu(user: User, popupExpanded: Boolean, onDismiss: () -> Unit, accountViewModel: AccountViewModel) {
|
||||||
val clipboardManager = LocalClipboardManager.current
|
|
||||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
|
||||||
val account = accountState?.account ?: return
|
|
||||||
|
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
|
|
||||||
DropdownMenu(
|
DropdownMenu(
|
||||||
expanded = popupExpanded,
|
expanded = popupExpanded,
|
||||||
onDismissRequest = onDismiss
|
onDismissRequest = onDismiss
|
||||||
) {
|
) {
|
||||||
|
val clipboardManager = LocalClipboardManager.current
|
||||||
|
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||||
|
val account = accountState?.account!!
|
||||||
|
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
DropdownMenuItem(onClick = { clipboardManager.setText(AnnotatedString(user.pubkeyNpub())); onDismiss() }) {
|
DropdownMenuItem(onClick = { clipboardManager.setText(AnnotatedString(user.pubkeyNpub())); onDismiss() }) {
|
||||||
Text(stringResource(R.string.copy_user_id))
|
Text(stringResource(R.string.copy_user_id))
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,7 @@ import com.vitorpamplona.amethyst.ui.screen.LoadingFeed
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.NostrVideoFeedViewModel
|
import com.vitorpamplona.amethyst.ui.screen.NostrVideoFeedViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.ScrollStateKeys
|
import com.vitorpamplona.amethyst.ui.screen.ScrollStateKeys
|
||||||
import com.vitorpamplona.amethyst.ui.screen.rememberForeverPagerState
|
import com.vitorpamplona.amethyst.ui.screen.rememberForeverPagerState
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -397,8 +398,8 @@ fun ReactionsColumn(baseNote: Note, accountViewModel: AccountViewModel, nav: (St
|
|||||||
BoostReaction(baseNote, accountViewModel, iconSize = 40.dp) {
|
BoostReaction(baseNote, accountViewModel, iconSize = 40.dp) {
|
||||||
wantsToQuote = baseNote
|
wantsToQuote = baseNote
|
||||||
}*/
|
}*/
|
||||||
LikeReaction(baseNote, grayTint = MaterialTheme.colors.onBackground, accountViewModel, iconSize = 40.dp, heartSize = 35.dp, 28.sp)
|
LikeReaction(baseNote, grayTint = MaterialTheme.colors.onBackground, accountViewModel, iconSize = 40.dp, heartSize = Size35dp, 28.sp)
|
||||||
ZapReaction(baseNote, grayTint = MaterialTheme.colors.onBackground, accountViewModel, iconSize = 40.dp, animationSize = 35.dp)
|
ZapReaction(baseNote, grayTint = MaterialTheme.colors.onBackground, accountViewModel, iconSize = 40.dp, animationSize = Size35dp)
|
||||||
ViewCountReaction(baseNote.idHex, grayTint = MaterialTheme.colors.onBackground, iconSize = 40.dp, barChartSize = 39.dp)
|
ViewCountReaction(baseNote.idHex, grayTint = MaterialTheme.colors.onBackground, iconSize = 40.dp, barChartSize = 39.dp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ import com.vitorpamplona.amethyst.R
|
|||||||
import com.vitorpamplona.amethyst.ui.qrcode.SimpleQrCodeScanner
|
import com.vitorpamplona.amethyst.ui.qrcode.SimpleQrCodeScanner
|
||||||
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
|
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ConnectOrbotDialog
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ConnectOrbotDialog
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -275,7 +276,7 @@ fun LoginPage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
shape = RoundedCornerShape(35.dp),
|
shape = RoundedCornerShape(Size35dp),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.height(50.dp),
|
.height(50.dp),
|
||||||
|
@ -22,3 +22,5 @@ val ChatBubbleShapeThem = RoundedCornerShape(3.dp, 15.dp, 15.dp, 15.dp)
|
|||||||
val StdButtonSizeModifier = Modifier.size(20.dp)
|
val StdButtonSizeModifier = Modifier.size(20.dp)
|
||||||
val StdHorzSpacer = Modifier.width(5.dp)
|
val StdHorzSpacer = Modifier.width(5.dp)
|
||||||
val DoubleHorzSpacer = Modifier.width(10.dp)
|
val DoubleHorzSpacer = Modifier.width(10.dp)
|
||||||
|
|
||||||
|
val Size35dp = 35.dp
|
Reference in New Issue
Block a user