Adjustments to padding of the last element and the size of the relay box in kind 1

This commit is contained in:
Vitor Pamplona
2024-02-29 17:05:41 -05:00
parent fd37826663
commit d506cf13a9
8 changed files with 159 additions and 59 deletions
@@ -24,9 +24,8 @@ import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import com.vitorpamplona.amethyst.commons.MediaUrlImage import com.vitorpamplona.amethyst.commons.MediaUrlImage
@@ -46,19 +45,16 @@ fun LoadUrlPreview(
if (!automaticallyShowUrlPreview) { if (!automaticallyShowUrlPreview) {
ClickableUrl(urlText, url) ClickableUrl(urlText, url)
} else { } else {
var urlPreviewState by val urlPreviewState by
remember(url) { produceState(
mutableStateOf( initialValue = UrlCachedPreviewer.cache.get(url) ?: UrlPreviewState.Loading,
UrlCachedPreviewer.cache.get(url) ?: UrlPreviewState.Loading, key1 = url,
) ) {
if (value == UrlPreviewState.Loading) {
accountViewModel.urlPreview(url) { value = it }
}
} }
// Doesn't use a viewModel because of viewModel reusing issues (too many UrlPreview are
// created).
if (urlPreviewState == UrlPreviewState.Loading) {
LaunchedEffect(url) { accountViewModel.urlPreview(url) { urlPreviewState = it } }
}
Crossfade( Crossfade(
targetState = urlPreviewState, targetState = urlPreviewState,
animationSpec = tween(durationMillis = 100), animationSpec = tween(durationMillis = 100),
@@ -28,6 +28,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.InlineTextContent import androidx.compose.foundation.text.InlineTextContent
import androidx.compose.foundation.text.appendInlineContent import androidx.compose.foundation.text.appendInlineContent
@@ -102,6 +103,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.LoadedBechLink
import com.vitorpamplona.amethyst.ui.theme.Font17SP import com.vitorpamplona.amethyst.ui.theme.Font17SP
import com.vitorpamplona.amethyst.ui.theme.HalfVertPadding import com.vitorpamplona.amethyst.ui.theme.HalfVertPadding
import com.vitorpamplona.amethyst.ui.theme.MarkdownTextStyle import com.vitorpamplona.amethyst.ui.theme.MarkdownTextStyle
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
import com.vitorpamplona.amethyst.ui.theme.innerPostModifier import com.vitorpamplona.amethyst.ui.theme.innerPostModifier
import com.vitorpamplona.amethyst.ui.theme.markdownStyle import com.vitorpamplona.amethyst.ui.theme.markdownStyle
import com.vitorpamplona.amethyst.ui.uriToRoute import com.vitorpamplona.amethyst.ui.uriToRoute
@@ -344,6 +346,16 @@ private fun RenderRegular(
} }
} }
} }
// UrlPreviews and Images have a 5dp spacing down. This also adds the space to Text.
val lastElement = state.paragraphs.lastOrNull()?.words?.lastOrNull()
if (lastElement !is ImageSegment &&
lastElement !is LinkSegment &&
lastElement !is InvoiceSegment &&
lastElement !is CashuSegment
) {
Spacer(modifier = StdVertSpacer)
}
} }
} }
@@ -150,7 +150,7 @@ fun ReactionsRow(
) { ) {
val wantsToSeeReactions = remember(baseNote) { mutableStateOf(false) } val wantsToSeeReactions = remember(baseNote) { mutableStateOf(false) }
Spacer(modifier = HalfDoubleVertSpacer) // Spacer(modifier = HalfDoubleVertSpacer)
InnerReactionRow(baseNote, showReactionDetail, wantsToSeeReactions, accountViewModel, nav) InnerReactionRow(baseNote, showReactionDetail, wantsToSeeReactions, accountViewModel, nav)
@@ -20,11 +20,19 @@
*/ */
package com.vitorpamplona.amethyst.ui.note package com.vitorpamplona.amethyst.ui.note
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material.icons.filled.ExpandMore
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@@ -37,14 +45,17 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R 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.DoubleVertSpacer
import com.vitorpamplona.amethyst.ui.theme.ShowMoreRelaysButtonBoxModifer import com.vitorpamplona.amethyst.ui.theme.ShowMoreRelaysButtonBoxModifer
import com.vitorpamplona.amethyst.ui.theme.ShowMoreRelaysButtonIconButtonModifier import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
import com.vitorpamplona.amethyst.ui.theme.ShowMoreRelaysButtonIconModifier
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
@OptIn(ExperimentalLayoutApi::class) @OptIn(ExperimentalLayoutApi::class)
@@ -58,16 +69,18 @@ fun RelayBadges(
val relayList by baseNote.live().relayInfo.observeAsState(baseNote.relays) val relayList by baseNote.live().relayInfo.observeAsState(baseNote.relays)
Spacer(DoubleVertSpacer) Spacer(StdVertSpacer)
// FlowRow Seems to be a lot faster than LazyVerticalGrid // FlowRow Seems to be a lot faster than LazyVerticalGrid
FlowRow { Box(modifier = Modifier.fillMaxWidth().padding(start = 2.dp, end = 1.dp)) {
if (expanded) { FlowRow(modifier = Modifier.fillMaxWidth()) {
relayList?.forEach { RenderRelay(it, accountViewModel, nav) } if (expanded) {
} else { relayList?.forEach { RenderRelay(it, accountViewModel, nav) }
relayList?.getOrNull(0)?.let { RenderRelay(it, accountViewModel, nav) } } else {
relayList?.getOrNull(1)?.let { RenderRelay(it, accountViewModel, nav) } relayList?.getOrNull(0)?.let { RenderRelay(it, accountViewModel, nav) }
relayList?.getOrNull(2)?.let { RenderRelay(it, accountViewModel, nav) } relayList?.getOrNull(1)?.let { RenderRelay(it, accountViewModel, nav) }
relayList?.getOrNull(2)?.let { RenderRelay(it, accountViewModel, nav) }
}
} }
} }
@@ -76,6 +89,62 @@ fun RelayBadges(
} }
} }
@OptIn(ExperimentalLayoutApi::class)
@Preview
@Composable
fun RelayIconLayoutPreview() {
Column(modifier = Modifier.width(55.dp)) {
Spacer(StdVertSpacer)
// FlowRow Seems to be a lot faster than LazyVerticalGrid
Box(modifier = Modifier.fillMaxWidth().padding(start = 2.dp, end = 1.dp)) {
FlowRow {
Box(
modifier = Modifier.size(17.dp),
contentAlignment = Alignment.Center,
) {
Box(
Modifier.size(13.dp).clip(shape = CircleShape).background(Color.Black),
)
}
Box(
modifier = Modifier.size(17.dp),
contentAlignment = Alignment.Center,
) {
Box(Modifier.size(13.dp).clip(shape = CircleShape).background(Color.Black))
}
Box(
modifier = Modifier.size(17.dp),
contentAlignment = Alignment.Center,
) {
Box(Modifier.size(13.dp).clip(shape = CircleShape).background(Color.Black))
}
Box(
modifier = Modifier.size(17.dp),
contentAlignment = Alignment.Center,
) {
Box(Modifier.size(13.dp).clip(shape = CircleShape).background(Color.Black))
}
Box(
modifier = Modifier.size(17.dp),
contentAlignment = Alignment.Center,
) {
Box(Modifier.size(13.dp).clip(shape = CircleShape).background(Color.Black))
}
Box(
modifier = Modifier.size(17.dp),
contentAlignment = Alignment.Center,
) {
Box(Modifier.size(13.dp).clip(shape = CircleShape).background(Color.Black))
}
}
}
ShowMoreRelaysButton { }
}
}
@Composable @Composable
private fun ShowMoreRelaysButton(onClick: () -> Unit) { private fun ShowMoreRelaysButton(onClick: () -> Unit) {
Row( Row(
@@ -84,13 +153,11 @@ private fun ShowMoreRelaysButton(onClick: () -> Unit) {
verticalAlignment = Alignment.Top, verticalAlignment = Alignment.Top,
) { ) {
IconButton( IconButton(
modifier = ShowMoreRelaysButtonIconButtonModifier,
onClick = onClick, onClick = onClick,
) { ) {
Icon( Icon(
imageVector = Icons.Default.ExpandMore, imageVector = Icons.Default.ExpandMore,
contentDescription = stringResource(id = R.string.expand_relay_list), contentDescription = stringResource(id = R.string.expand_relay_list),
modifier = ShowMoreRelaysButtonIconModifier,
tint = MaterialTheme.colorScheme.placeholderText, tint = MaterialTheme.colorScheme.placeholderText,
) )
} }
@@ -26,7 +26,6 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ChevronRight import androidx.compose.material.icons.filled.ChevronRight
@@ -47,7 +46,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import androidx.lifecycle.map import androidx.lifecycle.map
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
@@ -59,7 +57,7 @@ import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.theme.RelayIconFilter import com.vitorpamplona.amethyst.ui.theme.RelayIconFilter
import com.vitorpamplona.amethyst.ui.theme.Size15Modifier import com.vitorpamplona.amethyst.ui.theme.Size15Modifier
import com.vitorpamplona.amethyst.ui.theme.Size15dp import com.vitorpamplona.amethyst.ui.theme.Size17dp
import com.vitorpamplona.amethyst.ui.theme.StdStartPadding import com.vitorpamplona.amethyst.ui.theme.StdStartPadding
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
import com.vitorpamplona.amethyst.ui.theme.relayIconModifier import com.vitorpamplona.amethyst.ui.theme.relayIconModifier
@@ -164,13 +162,12 @@ fun RenderRelay(
val context = LocalContext.current val context = LocalContext.current
val interactionSource = remember { MutableInteractionSource() } val interactionSource = remember { MutableInteractionSource() }
val ripple = rememberRipple(bounded = false, radius = Size15dp) val ripple = rememberRipple(bounded = false, radius = Size17dp)
val clickableModifier = val clickableModifier =
remember(relay) { remember(relay) {
Modifier Modifier
.padding(1.dp) .size(Size17dp)
.size(Size15dp)
.clickable( .clickable(
role = Role.Button, role = Role.Button,
interactionSource = interactionSource, interactionSource = interactionSource,
@@ -23,7 +23,6 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn
import androidx.compose.animation.Crossfade import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.ScrollableState
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
@@ -232,7 +231,7 @@ private fun RenderDiscoverFeed(
viewModel: FeedViewModel, viewModel: FeedViewModel,
routeForLastRead: String?, routeForLastRead: String?,
forceEventKind: Int?, forceEventKind: Int?,
listState: ScrollableState, listState: LazyGridState,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: (String) -> Unit, nav: (String) -> Unit,
) { ) {
@@ -251,25 +250,54 @@ private fun RenderDiscoverFeed(
FeedError(state.errorMessage) { viewModel.invalidateData() } FeedError(state.errorMessage) { viewModel.invalidateData() }
} }
is FeedState.Loaded -> { is FeedState.Loaded -> {
if (listState is LazyGridState) { DiscoverFeedColumnsLoaded(
DiscoverFeedColumnsLoaded( state,
state, routeForLastRead,
routeForLastRead, listState,
listState, forceEventKind,
forceEventKind, accountViewModel,
accountViewModel, nav,
nav, )
) }
} else if (listState is LazyListState) { is FeedState.Loading -> {
DiscoverFeedLoaded( LoadingFeed()
state, }
routeForLastRead, }
listState, }
forceEventKind, }
accountViewModel,
nav, @Composable
) private fun RenderDiscoverFeed(
} viewModel: FeedViewModel,
routeForLastRead: String?,
forceEventKind: Int?,
listState: LazyListState,
accountViewModel: AccountViewModel,
nav: (String) -> Unit,
) {
val feedState by viewModel.feedContent.collectAsStateWithLifecycle()
Crossfade(
targetState = feedState,
animationSpec = tween(durationMillis = 100),
label = "RenderDiscoverFeed",
) { state ->
when (state) {
is FeedState.Empty -> {
FeedEmpty { viewModel.invalidateData() }
}
is FeedState.FeedError -> {
FeedError(state.errorMessage) { viewModel.invalidateData() }
}
is FeedState.Loaded -> {
DiscoverFeedLoaded(
state,
routeForLastRead,
listState,
forceEventKind,
accountViewModel,
nav,
)
} }
is FeedState.Loading -> { is FeedState.Loading -> {
LoadingFeed() LoadingFeed()
@@ -146,9 +146,9 @@ val Height4dpModifier = Modifier.height(4.dp)
val AccountPictureModifier = Modifier.size(55.dp).clip(shape = CircleShape) val AccountPictureModifier = Modifier.size(55.dp).clip(shape = CircleShape)
val HeaderPictureModifier = Modifier.size(34.dp).clip(shape = CircleShape) val HeaderPictureModifier = Modifier.size(34.dp).clip(shape = CircleShape)
val ShowMoreRelaysButtonIconButtonModifier = Modifier.size(24.dp) val ShowMoreRelaysButtonIconButtonModifier = Modifier.size(15.dp)
val ShowMoreRelaysButtonIconModifier = Modifier.size(15.dp) val ShowMoreRelaysButtonIconModifier = Modifier.size(20.dp)
val ShowMoreRelaysButtonBoxModifer = Modifier.fillMaxWidth().height(25.dp) val ShowMoreRelaysButtonBoxModifer = Modifier.fillMaxWidth().height(17.dp)
val ChatBubbleMaxSizeModifier = Modifier.fillMaxWidth(0.85f) val ChatBubbleMaxSizeModifier = Modifier.fillMaxWidth(0.85f)
@@ -167,14 +167,14 @@ val LightReplyBorderModifier =
val DarkInnerPostBorderModifier = val DarkInnerPostBorderModifier =
Modifier Modifier
.padding(top = 5.dp) .padding(vertical = 5.dp)
.fillMaxWidth() .fillMaxWidth()
.clip(shape = QuoteBorder) .clip(shape = QuoteBorder)
.border(1.dp, DarkSubtleBorder, QuoteBorder) .border(1.dp, DarkSubtleBorder, QuoteBorder)
val LightInnerPostBorderModifier = val LightInnerPostBorderModifier =
Modifier Modifier
.padding(top = 5.dp) .padding(vertical = 5.dp)
.fillMaxWidth() .fillMaxWidth()
.clip(shape = QuoteBorder) .clip(shape = QuoteBorder)
.border(1.dp, LightSubtleBorder, QuoteBorder) .border(1.dp, LightSubtleBorder, QuoteBorder)