From 5c3daed968f5633b76e6f2eb44c1b5e3398d3e45 Mon Sep 17 00:00:00 2001 From: austinried <4966622+austinried@users.noreply.github.com> Date: Sun, 27 Sep 2026 10:41:58 +0000 Subject: [PATCH] keep the artist title's top line clear of the shuffle button Render the wrapped artist name as two rows: the first line spans the full width on its own row above, and the last line shares a row with the shuffle button, so the text can never run under it. --- .../ui/library/ArtistDetailScreen.kt | 56 +++++++++++-------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/app/src/main/kotlin/com/subtracks/ui/library/ArtistDetailScreen.kt b/app/src/main/kotlin/com/subtracks/ui/library/ArtistDetailScreen.kt index 7bdf9a5c..7423aa8a 100644 --- a/app/src/main/kotlin/com/subtracks/ui/library/ArtistDetailScreen.kt +++ b/app/src/main/kotlin/com/subtracks/ui/library/ArtistDetailScreen.kt @@ -99,6 +99,7 @@ private val ROW_GAP = 16.dp private val SHUFFLE_WIDTH = 68.dp private val SHUFFLE_HEIGHT = 48.dp private val SHUFFLE_ICON = 30.dp +private val SHUFFLE_GAP = 12.dp private val SHUFFLE_RESERVE = 80.dp internal fun estimateScrollPx( @@ -280,28 +281,24 @@ fun ArtistDetailScreen( ) } Box(Modifier.align(Alignment.BottomStart).fillMaxWidth()) { - HangingTitle( + ArtistTitle( text = artist?.name.orEmpty(), style = imageNameStyle, color = Color.White, endReserve = SHUFFLE_RESERVE, modifier = Modifier.align(Alignment.BottomStart).fillMaxWidth().padding(TITLE_INSET), - ) - FilledIconButton( - onClick = onShuffle, - shape = RoundedCornerShape(24.dp), - modifier = - Modifier - .align(Alignment.BottomEnd) - .padding(end = TITLE_INSET, bottom = TITLE_INSET) - .width(SHUFFLE_WIDTH) - .height(SHUFFLE_HEIGHT), ) { - Icon( - imageVector = Icons.Rounded.Shuffle, - contentDescription = "Shuffle artist", - modifier = Modifier.size(SHUFFLE_ICON), - ) + FilledIconButton( + onClick = onShuffle, + shape = RoundedCornerShape(24.dp), + modifier = Modifier.width(SHUFFLE_WIDTH).height(SHUFFLE_HEIGHT), + ) { + Icon( + imageVector = Icons.Rounded.Shuffle, + contentDescription = "Shuffle artist", + modifier = Modifier.size(SHUFFLE_ICON), + ) + } } } } @@ -425,12 +422,13 @@ fun ArtistDetailScreen( } @Composable -private fun HangingTitle( +private fun ArtistTitle( text: String, style: TextStyle, color: Color, endReserve: Dp, modifier: Modifier = Modifier, + trailing: @Composable () -> Unit, ) { val measurer = rememberTextMeasurer() val density = LocalDensity.current @@ -439,19 +437,31 @@ private fun HangingTitle( val reserve = with(density) { endReserve.roundToPx() } val lines = remember(text, style, fullWidth, reserve) { splitTitle(measurer, text, style, fullWidth, reserve) } Column { - lines.forEachIndexed { index, line -> + if (lines.size > 1) { Text( - text = line, + text = lines.first(), style = style, color = color, maxLines = 1, overflow = TextOverflow.Ellipsis, - modifier = - Modifier - .fillMaxWidth() - .then(if (index == lines.lastIndex) Modifier.padding(end = endReserve) else Modifier), + modifier = Modifier.fillMaxWidth(), ) } + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth(), + ) { + Text( + text = lines.last(), + style = style, + color = color, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.weight(1f), + ) + Spacer(Modifier.width(SHUFFLE_GAP)) + trailing() + } } } }