Reuse baseline-aligned headers with source subtitle typography
This commit is contained in:
parent
b1b15b384b
commit
4e62aad638
6 changed files with 18 additions and 20 deletions
|
|
@ -94,7 +94,7 @@ fun DiscoverScreen(state: DiscoverState, modifier: Modifier = Modifier) {
|
|||
if (state.hasHero && state.service == null && list.firstVisibleItemIndex == 0) state.hero?.let { DiscoverBackdrop(it, modifier = Modifier.graphicsLayer { translationY = -list.firstVisibleItemScrollOffset.toFloat() }) }
|
||||
LazyColumn(state = list, contentPadding = PaddingValues(bottom = (WolfskinTokens.Shell.stageHeight - L.pinnedLine - heights.last()).coerceAtLeast(D.frameBottomMin)), modifier = Modifier.fillMaxSize()) {
|
||||
item(key = "discover-header", contentType = if (state.hasHero && state.service == null) "hero" else "header") {
|
||||
if (state.hasHero && state.service == null) DiscoverHero(state) else DiscoverHeader(state.shell.person, state.service?.name ?: "Discover", if (state.service != null) "General interest" else "")
|
||||
if (state.hasHero && state.service == null) DiscoverHero(state) else LibraryHeader(state.shell.person, state.service?.name ?: "Discover", if (state.service != null) "General interest" else "")
|
||||
}
|
||||
item(key = "discover-chips", contentType = "chips") {
|
||||
if (state.snapshot.status !in setOf(DiscoverStatus.NeedsSignIn, DiscoverStatus.Unavailable, DiscoverStatus.Loading)) DiscoverChips(state)
|
||||
|
|
@ -116,16 +116,6 @@ fun DiscoverScreen(state: DiscoverState, modifier: Modifier = Modifier) {
|
|||
}
|
||||
}
|
||||
|
||||
/** Header and type chips use the same safe area as the shell. */
|
||||
@Composable
|
||||
private fun DiscoverHeader(person: ShellPerson, title: String, subtitle: String) {
|
||||
Row(Modifier.fillMaxWidth().height(L.row_lhead).padding(start = L.safeSide, top = D.headerTop), horizontalArrangement = Arrangement.spacedBy(D.headerGap), verticalAlignment = Alignment.CenterVertically) {
|
||||
Avatar(person, WolfskinTokens.Shell.settingsHeaderAvatar, WolfskinTokens.Type.avatarLetterLibHeader, letterColor = C.muted)
|
||||
Text(title, color = C.fg, style = WolfskinTokens.Type.screenTitle)
|
||||
if (subtitle.isNotEmpty()) Text(subtitle, color = C.muted, style = WolfskinTokens.Type.nav)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DiscoverHero(state: DiscoverState) {
|
||||
val title = state.hero ?: return
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ fun LibraryScreen(
|
|||
val active = !shell.navFocused && !shell.pickerVisible
|
||||
val items = grid.items
|
||||
val focused = grid.focusedTitle
|
||||
val count = if (grid.catalogue) items.size else grid.source.size
|
||||
var plateKey by remember { mutableStateOf<String?>(null) }
|
||||
DisposableEffect(shell, grid, registerFocus) {
|
||||
if (registerFocus) shell.contentFocus = grid
|
||||
|
|
@ -104,7 +105,11 @@ fun LibraryScreen(
|
|||
}
|
||||
}
|
||||
}, contentPadding = PaddingValues(bottom = WolfskinTokens.Shell.stageHeight - L.pinnedLine - rowHeight)) {
|
||||
item(key = "header", contentType = "header") { LibraryHeader(grid, shell.person) }
|
||||
item(key = "header", contentType = "header") {
|
||||
LibraryHeader(shell.person, grid.title,
|
||||
if (grid.status != LibraryStatus.Ready) "" else "$count ${if (grid.catalogue) "titles" else if (grid.title == "Movies") if (count == 1) "film" else "films" else "series"}",
|
||||
grid.savedAt)
|
||||
}
|
||||
if (headerCount == 2) item(key = "toolbar", contentType = "chips") { LibraryToolbar(grid, active) }
|
||||
when (grid.status) {
|
||||
LibraryStatus.Loading -> items(3, key = { "skeleton-$it" }, contentType = { "grid" }) {
|
||||
|
|
@ -157,15 +162,15 @@ fun LibraryScreen(
|
|||
}
|
||||
}
|
||||
|
||||
/** Library, catalogue and service headers share one baseline and person treatment. */
|
||||
@Composable
|
||||
private fun LibraryHeader(grid: LibraryGridState, person: ShellPerson) {
|
||||
val count = if (grid.catalogue) grid.items.size else grid.source.size
|
||||
fun LibraryHeader(person: ShellPerson, title: String, subtitle: String = "", savedAt: String? = null) {
|
||||
Box(Modifier.fillMaxWidth().height(L.row_lhead)) {
|
||||
Row(Modifier.offset(L.safeSide, L.navBand), horizontalArrangement = Arrangement.spacedBy(WolfskinTokens.Shell.settingsHeaderGap), verticalAlignment = Alignment.CenterVertically) {
|
||||
Avatar(person, WolfskinTokens.Shell.settingsHeaderAvatar, WolfskinTokens.Type.avatarLetterLibHeader, letterColor = C.muted)
|
||||
Text(grid.title, modifier = Modifier.alignByBaseline(), color = C.fg, style = WolfskinTokens.Type.screenTitle)
|
||||
Text(if (grid.status != LibraryStatus.Ready) "" else "$count ${if (grid.catalogue) "titles" else if (grid.title == "Movies") if (count == 1) "film" else "films" else "series"}", modifier = Modifier.alignByBaseline(), color = C.muted, style = WolfskinTokens.Type.nav.copy(fontWeight = FontWeight.Normal))
|
||||
grid.savedAt?.let { Text("Saved $it", color = C.warn, style = WolfskinTokens.Type.caption) }
|
||||
Text(title, modifier = Modifier.alignByBaseline(), color = C.fg, style = WolfskinTokens.Type.screenTitle)
|
||||
if (subtitle.isNotEmpty()) Text(subtitle, modifier = Modifier.alignByBaseline(), color = C.muted, style = G.headerSubtitle)
|
||||
savedAt?.let { Text("Saved $it", color = C.warn, style = WolfskinTokens.Type.caption) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -325,6 +325,7 @@ object WolfskinTokens {
|
|||
val badgeIcon = 14.0.dp
|
||||
val seeAllGap = 4.0.dp
|
||||
val tailDescription = TextStyle(fontSize = 12.0.sp, fontWeight = FontWeight(500), lineHeight = 15.600000000000001.sp, letterSpacing = 0.0.em)
|
||||
val headerSubtitle = TextStyle(fontSize = 15.0.sp, fontWeight = FontWeight(400), lineHeight = 19.5.sp, letterSpacing = 0.0.em)
|
||||
const val imageReads = 4.0f
|
||||
const val unknownCriticOpacity = 0.55f
|
||||
val fallbackPadding = 11.0.dp
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue