Fixes matching image borders in the loading step of preview cards

This commit is contained in:
Vitor Pamplona
2025-07-10 09:43:36 -04:00
parent a2d16c173c
commit ec985d58e7
10 changed files with 36 additions and 31 deletions

View File

@@ -90,7 +90,18 @@ fun MyAsyncImage(
}
is AsyncImagePainter.State.Error -> {
if (onError != null) {
onError()
if (ratio != null) {
Box(loadedImageModifier.aspectRatio(ratio), contentAlignment = Alignment.Center) {
onError()
}
} else {
Box(loadedImageModifier, contentAlignment = Alignment.Center) {
if (onLoadingBackground != null) {
onLoadingBackground()
}
DisplayUrlWithLoadingSymbol(imageUrl)
}
}
}
}
is AsyncImagePainter.State.Success -> {

View File

@@ -20,26 +20,23 @@
*/
package com.vitorpamplona.amethyst.ui.note
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.ui.note.elements.BannerImage
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
import com.vitorpamplona.amethyst.ui.theme.SimpleImageBorder
@Composable
fun DisplayAuthorBanner(
note: Note,
accountViewModel: AccountViewModel,
modifier: Modifier = SimpleImageBorder,
) {
WatchAuthor(note, accountViewModel) {
BannerImage(
it,
Modifier
.fillMaxSize()
.clip(QuoteBorder),
modifier,
accountViewModel,
)
}

View File

@@ -22,15 +22,12 @@ package com.vitorpamplona.amethyst.ui.note.elements
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.blur
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
@@ -41,6 +38,7 @@ import com.vitorpamplona.amethyst.ui.note.WatchAuthor
import com.vitorpamplona.amethyst.ui.painterRes
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.SimpleHeaderImage
import com.vitorpamplona.amethyst.ui.theme.Size16dp
import com.vitorpamplona.amethyst.ui.theme.Size55dp
import com.vitorpamplona.amethyst.ui.theme.authorNotePictureForImageHeader
@@ -49,10 +47,11 @@ import com.vitorpamplona.amethyst.ui.theme.authorNotePictureForImageHeader
fun DefaultImageHeader(
note: Note,
accountViewModel: AccountViewModel,
modifier: Modifier = SimpleHeaderImage,
) {
WatchAuthor(baseNote = note, accountViewModel) {
Box {
BannerImage(it, Modifier.fillMaxWidth().heightIn(max = 200.dp), accountViewModel)
BannerImage(it, modifier, accountViewModel)
Box(authorNotePictureForImageHeader.align(Alignment.BottomStart)) {
BaseUserPicture(it, Size55dp, accountViewModel, Modifier)
@@ -65,10 +64,11 @@ fun DefaultImageHeader(
fun DefaultImageHeaderBackground(
note: Note,
accountViewModel: AccountViewModel,
modifier: Modifier = SimpleHeaderImage,
) {
WatchAuthor(baseNote = note, accountViewModel) {
Box {
BannerImage(it, Modifier.fillMaxWidth().heightIn(max = 200.dp).blur(Size16dp), accountViewModel)
BannerImage(it, modifier.blur(Size16dp), accountViewModel)
Box(authorNotePictureForImageHeader.align(Alignment.BottomStart)) {
BaseUserPicture(it, Size55dp, accountViewModel, Modifier)

View File

@@ -24,6 +24,7 @@ import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@@ -99,7 +100,7 @@ fun RenderClassifieds(
)
}
} ?: run {
DefaultImageHeader(note, accountViewModel)
DefaultImageHeader(note, accountViewModel, Modifier.fillMaxWidth())
}
}

View File

@@ -59,6 +59,7 @@ import com.vitorpamplona.amethyst.ui.note.getGradient
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.FollowSetImageModifier
import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUserIds
import com.vitorpamplona.quartz.nip51Lists.FollowListEvent
import kotlinx.collections.immutable.ImmutableList
@@ -97,13 +98,13 @@ fun DisplayFollowList(
),
contentScale = ContentScale.Crop,
mainImageModifier = Modifier.fillMaxWidth(),
loadedImageModifier = Modifier,
loadedImageModifier = FollowSetImageModifier,
accountViewModel = accountViewModel,
onLoadingBackground = { DefaultImageHeaderBackground(baseNote, accountViewModel) },
onError = { DefaultImageHeader(baseNote, accountViewModel) },
)
} ?: run {
DefaultImageHeader(baseNote, accountViewModel)
DefaultImageHeader(baseNote, accountViewModel, FollowSetImageModifier)
}
Text(

View File

@@ -262,7 +262,7 @@ fun DisplayEntryForNote(
RenderUserAsClickableText(author, null, accountViewModel, nav)
}
val noteEvent = noteState?.note?.event as? BaseThreadedEvent ?: return
val noteEvent = noteState.note.event as? BaseThreadedEvent ?: return
val description = remember(noteEvent) { noteEvent.tags.firstTagValueFor("title", "subject", "alt") }
@@ -274,7 +274,7 @@ fun DisplayEntryForNote(
onClick = { routeFor(note, accountViewModel.userProfile())?.let { nav.nav(it) } },
)
} else {
DisplayEvent(noteEvent.id, noteEvent.kind, note.toNostrUri(), null, accountViewModel, nav)
DisplayEvent(noteEvent.id, note.toNostrUri(), null, accountViewModel, nav)
}
}

View File

@@ -237,7 +237,7 @@ fun RenderLiveActivityEventInner(
onError = { DefaultImageHeader(baseNote, accountViewModel) },
)
}
} ?: run { DisplayAuthorBanner(baseNote, accountViewModel) }
} ?: run { DisplayAuthorBanner(baseNote, accountViewModel, MaterialTheme.colorScheme.imageModifier) }
Text(
text = stringRes(id = R.string.live_stream_has_ended),

View File

@@ -44,6 +44,7 @@ import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeaderBackground
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
import com.vitorpamplona.amethyst.ui.theme.SimpleImageBorder
import com.vitorpamplona.amethyst.ui.theme.Size5dp
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
import com.vitorpamplona.amethyst.ui.theme.subtleBorder
@@ -93,14 +94,14 @@ fun LongFormHeader(
it,
),
contentScale = ContentScale.FillWidth,
mainImageModifier = Modifier.fillMaxWidth(),
mainImageModifier = SimpleImageBorder,
loadedImageModifier = Modifier,
accountViewModel = accountViewModel,
onLoadingBackground = { DefaultImageHeaderBackground(note, accountViewModel) },
onError = { DefaultImageHeader(note, accountViewModel) },
)
} ?: run {
DefaultImageHeader(note, accountViewModel)
DefaultImageHeader(note, accountViewModel, SimpleImageBorder)
}
title?.let {
Text(

View File

@@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
@@ -35,7 +34,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
@@ -58,7 +56,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
import com.vitorpamplona.amethyst.ui.theme.FollowSetImageModifier
import com.vitorpamplona.amethyst.ui.theme.RowColSpacing5dp
import com.vitorpamplona.amethyst.ui.theme.Size10dp
import com.vitorpamplona.amethyst.ui.theme.Size25dp
@@ -158,17 +156,13 @@ fun RenderFollowSetThumb(
it,
),
contentScale = ContentScale.Crop,
mainImageModifier = Modifier.fillMaxWidth(),
loadedImageModifier =
Modifier
.fillMaxWidth()
.aspectRatio(ratio = 21f / 9f)
.clip(QuoteBorder),
mainImageModifier = Modifier,
loadedImageModifier = FollowSetImageModifier,
accountViewModel = accountViewModel,
onLoadingBackground = { DefaultImageHeaderBackground(baseNote, accountViewModel) },
onError = { DefaultImageHeader(baseNote, accountViewModel) },
)
} ?: run { DefaultImageHeader(baseNote, accountViewModel) }
} ?: run { DefaultImageHeader(baseNote, accountViewModel, FollowSetImageModifier) }
Gallery(card.users, Modifier.padding(Size10dp), accountViewModel, nav)
}

View File

@@ -118,7 +118,7 @@ fun InnerRenderClassifiedsThumb(
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize(),
)
} ?: run { DisplayAuthorBanner(note, accountViewModel) }
} ?: run { DisplayAuthorBanner(note, accountViewModel, Modifier.fillMaxSize()) }
Row(
Modifier