mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-09-27 12:17:52 +02:00
Quick Refactoring of the Author UI components.
This commit is contained in:
@@ -78,7 +78,7 @@ import com.vitorpamplona.amethyst.ui.theme.RowColSpacing
|
||||
import com.vitorpamplona.amethyst.ui.theme.RowColSpacing5dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size15Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size20dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size5dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size5Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdTopPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.chatAuthorBox
|
||||
@@ -769,7 +769,11 @@ private fun WatchAndDisplayUser(
|
||||
accountViewModel = accountViewModel,
|
||||
)
|
||||
|
||||
ObserveAndDisplayFollowingMark(author.pubkeyHex, Size5dp, accountViewModel)
|
||||
WatchUserFollows(author.pubkeyHex, accountViewModel) { newFollowingState ->
|
||||
if (newFollowingState) {
|
||||
FollowingIcon(Size5Modifier)
|
||||
}
|
||||
}
|
||||
},
|
||||
name = {
|
||||
if (userState != null) {
|
||||
|
@@ -87,10 +87,15 @@ fun AmethystIcon(iconSize: Dp) {
|
||||
|
||||
@Composable
|
||||
fun FollowingIcon(iconSize: Dp) {
|
||||
FollowingIcon(Modifier.size(iconSize))
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun FollowingIcon(modifier: Modifier) {
|
||||
Icon(
|
||||
imageVector = Following,
|
||||
contentDescription = stringResource(id = R.string.following),
|
||||
modifier = Modifier.size(iconSize),
|
||||
modifier = modifier,
|
||||
tint = Color.Unspecified,
|
||||
)
|
||||
}
|
||||
@@ -549,18 +554,26 @@ fun ZapSplitIcon(
|
||||
fun ZapSplitPreview() {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Box(
|
||||
Modifier.height(20.dp).width(25.dp),
|
||||
Modifier
|
||||
.height(20.dp)
|
||||
.width(25.dp),
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Bolt,
|
||||
contentDescription = stringResource(id = R.string.zaps),
|
||||
modifier = Modifier.size(20.dp).align(Alignment.CenterStart),
|
||||
modifier =
|
||||
Modifier
|
||||
.size(20.dp)
|
||||
.align(Alignment.CenterStart),
|
||||
tint = BitcoinOrange,
|
||||
)
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.ArrowForwardIos,
|
||||
contentDescription = stringResource(id = R.string.zaps),
|
||||
modifier = Modifier.size(13.dp).align(Alignment.CenterEnd),
|
||||
modifier =
|
||||
Modifier
|
||||
.size(13.dp)
|
||||
.align(Alignment.CenterEnd),
|
||||
tint = BitcoinOrange,
|
||||
)
|
||||
}
|
||||
|
@@ -20,9 +20,6 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.note
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
@@ -30,7 +27,6 @@ import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -40,7 +36,6 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.lifecycle.distinctUntilChanged
|
||||
import androidx.lifecycle.map
|
||||
@@ -161,23 +156,19 @@ fun ClickableUserPicture(
|
||||
.combinedClickable(
|
||||
onClick = { onClick(baseUser) },
|
||||
onLongClick = { onLongClick(baseUser) },
|
||||
role = Role.Button,
|
||||
)
|
||||
} else if (onClick != null) {
|
||||
Modifier
|
||||
.size(size)
|
||||
.clickable(
|
||||
onClick = { onClick(baseUser) },
|
||||
role = Role.Button,
|
||||
)
|
||||
} else {
|
||||
Modifier.size(size)
|
||||
}
|
||||
}
|
||||
|
||||
Box(modifier = myModifier, contentAlignment = Alignment.TopEnd) {
|
||||
BaseUserPicture(baseUser, size, accountViewModel, modifier)
|
||||
}
|
||||
BaseUserPicture(baseUser, size, accountViewModel, modifier, myModifier)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -301,10 +292,8 @@ fun BaseUserPicture(
|
||||
size: Dp,
|
||||
accountViewModel: AccountViewModel,
|
||||
innerModifier: Modifier = Modifier,
|
||||
outerModifier: Modifier = remember { Modifier.size(size) },
|
||||
outerModifier: Modifier = Modifier.size(size),
|
||||
) {
|
||||
val myIconSize by remember(size) { derivedStateOf { size.div(3.5f) } }
|
||||
|
||||
Box(outerModifier, contentAlignment = Alignment.TopEnd) {
|
||||
LoadUserProfilePicture(baseUser) { userProfilePicture, userName ->
|
||||
InnerUserPicture(
|
||||
@@ -317,7 +306,11 @@ fun BaseUserPicture(
|
||||
)
|
||||
}
|
||||
|
||||
ObserveAndDisplayFollowingMark(baseUser.pubkeyHex, myIconSize, accountViewModel)
|
||||
WatchUserFollows(baseUser.pubkeyHex, accountViewModel) { newFollowingState ->
|
||||
if (newFollowingState) {
|
||||
FollowingIcon(Modifier.size(size.div(3.5f)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,11 +338,6 @@ fun InnerUserPicture(
|
||||
modifier.size(size).clip(shape = CircleShape)
|
||||
}
|
||||
|
||||
val automaticallyShowProfilePicture =
|
||||
remember {
|
||||
accountViewModel.settings.showProfilePictures.value
|
||||
}
|
||||
|
||||
RobohashFallbackAsyncImage(
|
||||
robot = userHex,
|
||||
model = userPicture,
|
||||
@@ -361,27 +349,10 @@ fun InnerUserPicture(
|
||||
},
|
||||
modifier = myImageModifier,
|
||||
contentScale = ContentScale.Crop,
|
||||
loadProfilePicture = automaticallyShowProfilePicture,
|
||||
loadProfilePicture = accountViewModel.settings.showProfilePictures.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ObserveAndDisplayFollowingMark(
|
||||
userHex: String,
|
||||
iconSize: Dp,
|
||||
accountViewModel: AccountViewModel,
|
||||
) {
|
||||
WatchUserFollows(userHex, accountViewModel) { newFollowingState ->
|
||||
AnimatedVisibility(
|
||||
visible = newFollowingState,
|
||||
enter = remember { fadeIn() },
|
||||
exit = remember { fadeOut() },
|
||||
) {
|
||||
FollowingIcon(iconSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun WatchUserFollows(
|
||||
userHex: String,
|
||||
|
@@ -77,21 +77,6 @@ fun RefresheableFeedView(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DVMStatusView(
|
||||
viewModel: FeedViewModel,
|
||||
routeForLastRead: String?,
|
||||
enablePullRefresh: Boolean = true,
|
||||
scrollStateKey: String? = null,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: (String) -> Unit,
|
||||
) {
|
||||
viewModel.invalidateData()
|
||||
SaveableFeedState(viewModel, scrollStateKey) { listState ->
|
||||
RenderFeedState(viewModel, accountViewModel, listState, nav, routeForLastRead)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RefresheableBox(
|
||||
viewModel: InvalidatableViewModel,
|
||||
|
@@ -25,7 +25,6 @@ import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.gestures.scrollBy
|
||||
@@ -159,6 +158,7 @@ import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||
import com.vitorpamplona.amethyst.ui.theme.ButtonPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size100dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size15Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size16Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size25Modifier
|
||||
@@ -166,6 +166,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.ZeroPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import com.vitorpamplona.amethyst.ui.theme.userProfileBorderModifier
|
||||
import com.vitorpamplona.quartz.events.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.events.BadgeDefinitionEvent
|
||||
import com.vitorpamplona.quartz.events.BadgeProfilesEvent
|
||||
@@ -429,8 +430,7 @@ private fun RenderSurface(
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
.fillMaxHeight()
|
||||
).fillMaxHeight()
|
||||
},
|
||||
) {
|
||||
RenderScreen(
|
||||
@@ -550,8 +550,7 @@ fun UpdateThreadsAndRepliesWhenBlockUnblock(
|
||||
accountViewModel.account.liveHiddenUsers
|
||||
.map {
|
||||
it.hiddenUsers.contains(baseUser.pubkeyHex) || it.spammers.contains(baseUser.pubkeyHex)
|
||||
}
|
||||
.observeAsState(accountViewModel.account.isHidden(baseUser))
|
||||
}.observeAsState(accountViewModel.account.isHidden(baseUser))
|
||||
|
||||
LaunchedEffect(key1 = isHidden) {
|
||||
threadsViewModel.invalidateData()
|
||||
@@ -597,7 +596,11 @@ private fun RelaysTabHeader(baseUser: User) {
|
||||
val userStateRelayInfo by baseUser.live().relayInfo.observeAsState()
|
||||
val userRelays =
|
||||
remember(userStateRelayInfo) {
|
||||
userStateRelayInfo?.user?.latestContactList?.relays()?.size ?: "--"
|
||||
userStateRelayInfo
|
||||
?.user
|
||||
?.latestContactList
|
||||
?.relays()
|
||||
?.size ?: "--"
|
||||
}
|
||||
|
||||
Text(text = "$userRelaysBeingUsed / $userRelays ${stringResource(R.string.relays)}")
|
||||
@@ -780,13 +783,8 @@ private fun ProfileHeader(
|
||||
ClickableUserPicture(
|
||||
baseUser = baseUser,
|
||||
accountViewModel = accountViewModel,
|
||||
size = 100.dp,
|
||||
modifier =
|
||||
Modifier.border(
|
||||
3.dp,
|
||||
MaterialTheme.colorScheme.background,
|
||||
CircleShape,
|
||||
),
|
||||
size = Size100dp,
|
||||
modifier = MaterialTheme.colorScheme.userProfileBorderModifier,
|
||||
onClick = {
|
||||
if (baseUser.profilePicture() != null) {
|
||||
zoomImageDialogOpen = true
|
||||
@@ -922,31 +920,28 @@ fun WatchIsHiddenUser(
|
||||
accountViewModel.account.liveHiddenUsers
|
||||
.map {
|
||||
it.hiddenUsers.contains(baseUser.pubkeyHex) || it.spammers.contains(baseUser.pubkeyHex)
|
||||
}
|
||||
.observeAsState(accountViewModel.account.isHidden(baseUser))
|
||||
}.observeAsState(accountViewModel.account.isHidden(baseUser))
|
||||
|
||||
content(isHidden)
|
||||
}
|
||||
|
||||
fun getIdentityClaimIcon(identity: IdentityClaim): Int {
|
||||
return when (identity) {
|
||||
fun getIdentityClaimIcon(identity: IdentityClaim): Int =
|
||||
when (identity) {
|
||||
is TwitterIdentity -> R.drawable.twitter
|
||||
is TelegramIdentity -> R.drawable.telegram
|
||||
is MastodonIdentity -> R.drawable.mastodon
|
||||
is GitHubIdentity -> R.drawable.github
|
||||
else -> R.drawable.github
|
||||
}
|
||||
}
|
||||
|
||||
fun getIdentityClaimDescription(identity: IdentityClaim): Int {
|
||||
return when (identity) {
|
||||
fun getIdentityClaimDescription(identity: IdentityClaim): Int =
|
||||
when (identity) {
|
||||
is TwitterIdentity -> R.string.twitter
|
||||
is TelegramIdentity -> R.string.telegram
|
||||
is MastodonIdentity -> R.string.mastodon
|
||||
is GitHubIdentity -> R.string.github
|
||||
else -> R.drawable.github
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DrawAdditionalInfo(
|
||||
|
@@ -97,6 +97,7 @@ val Size35dp = 35.dp
|
||||
val Size40dp = 40.dp
|
||||
val Size55dp = 55.dp
|
||||
val Size75dp = 75.dp
|
||||
val Size100dp = 100.dp
|
||||
val Size110dp = 110.dp
|
||||
val Size165dp = 165.dp
|
||||
|
||||
@@ -122,7 +123,7 @@ val VertPadding = Modifier.padding(vertical = 10.dp)
|
||||
|
||||
val MaxWidthWithHorzPadding = Modifier.fillMaxWidth().padding(horizontal = 10.dp)
|
||||
|
||||
val Size6Modifier = Modifier.size(6.dp)
|
||||
val Size5Modifier = Modifier.size(5.dp)
|
||||
val Size10Modifier = Modifier.size(10.dp)
|
||||
val Size15Modifier = Modifier.size(15.dp)
|
||||
val Size16Modifier = Modifier.size(16.dp)
|
||||
|
@@ -191,6 +191,20 @@ val LightChannelNotePictureModifier =
|
||||
.clip(shape = CircleShape)
|
||||
.border(2.dp, LightColorPalette.background, CircleShape)
|
||||
|
||||
val LightProfilePictureBorder =
|
||||
Modifier.border(
|
||||
3.dp,
|
||||
DarkColorPalette.background,
|
||||
CircleShape,
|
||||
)
|
||||
|
||||
val DarkProfilePictureBorder =
|
||||
Modifier.border(
|
||||
3.dp,
|
||||
LightColorPalette.background,
|
||||
CircleShape,
|
||||
)
|
||||
|
||||
val LightRelayIconModifier =
|
||||
Modifier
|
||||
.size(Size13dp)
|
||||
@@ -379,6 +393,9 @@ val ColorScheme.innerPostModifier: Modifier
|
||||
val ColorScheme.channelNotePictureModifier: Modifier
|
||||
get() = if (isLight) LightChannelNotePictureModifier else DarkChannelNotePictureModifier
|
||||
|
||||
val ColorScheme.userProfileBorderModifier: Modifier
|
||||
get() = if (isLight) LightProfilePictureBorder else DarkProfilePictureBorder
|
||||
|
||||
val ColorScheme.relayIconModifier: Modifier
|
||||
get() = if (isLight) LightRelayIconModifier else DarkRelayIconModifier
|
||||
|
||||
@@ -400,8 +417,7 @@ val ColorScheme.chartStyle: ChartStyle
|
||||
defaultColors.entity1Color,
|
||||
defaultColors.entity2Color,
|
||||
defaultColors.entity3Color,
|
||||
)
|
||||
.map(::Color),
|
||||
).map(::Color),
|
||||
elevationOverlayColor = Color(defaultColors.elevationOverlayColor),
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user