mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-08-01 17:16:11 +00:00
feat: add SettingsScreen and integrate into navigation; update NuvioScreenHeader for back navigation
This commit is contained in:
parent
9366f09292
commit
3c4cc6b59f
4 changed files with 476 additions and 18 deletions
|
|
@ -6,9 +6,9 @@ import androidx.compose.foundation.layout.WindowInsets
|
|||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.Extension
|
||||
import androidx.compose.material.icons.rounded.Home
|
||||
import androidx.compose.material.icons.rounded.Search
|
||||
import androidx.compose.material.icons.rounded.Settings
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
|
|
@ -40,6 +40,7 @@ import com.nuvio.app.features.home.HomeCatalogSection
|
|||
import com.nuvio.app.features.home.HomeScreen
|
||||
import com.nuvio.app.features.home.MetaPreview
|
||||
import com.nuvio.app.features.search.SearchScreen
|
||||
import com.nuvio.app.features.settings.SettingsScreen
|
||||
import com.nuvio.app.features.streams.StreamsRepository
|
||||
import com.nuvio.app.features.streams.StreamsScreen
|
||||
import kotlinx.serialization.Serializable
|
||||
|
|
@ -75,10 +76,13 @@ data class CatalogRoute(
|
|||
val genre: String? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
object AddonsRoute
|
||||
|
||||
enum class AppScreenTab {
|
||||
Home,
|
||||
Search,
|
||||
Addons,
|
||||
Settings,
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -87,6 +91,7 @@ fun AppScreen(
|
|||
modifier: Modifier = Modifier,
|
||||
onCatalogClick: ((HomeCatalogSection) -> Unit)? = null,
|
||||
onPosterClick: ((MetaPreview) -> Unit)? = null,
|
||||
onAddonsClick: (() -> Unit)? = null,
|
||||
) {
|
||||
when (tab) {
|
||||
AppScreenTab.Home -> HomeScreen(
|
||||
|
|
@ -98,7 +103,10 @@ fun AppScreen(
|
|||
modifier = modifier,
|
||||
onPosterClick = onPosterClick,
|
||||
)
|
||||
AppScreenTab.Addons -> AddonsScreen(modifier = modifier)
|
||||
AppScreenTab.Settings -> SettingsScreen(
|
||||
modifier = modifier,
|
||||
onAddonsClick = { onAddonsClick?.invoke() },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -173,10 +181,10 @@ fun App() {
|
|||
label = { Text("Search") },
|
||||
)
|
||||
NavigationBarItem(
|
||||
selected = selectedTab == AppScreenTab.Addons,
|
||||
onClick = { selectedTab = AppScreenTab.Addons },
|
||||
icon = { Icon(Icons.Rounded.Extension, contentDescription = null) },
|
||||
label = { Text("Addons") },
|
||||
selected = selectedTab == AppScreenTab.Settings,
|
||||
onClick = { selectedTab = AppScreenTab.Settings },
|
||||
icon = { Icon(Icons.Rounded.Settings, contentDescription = null) },
|
||||
label = { Text("Settings") },
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
@ -188,6 +196,9 @@ fun App() {
|
|||
onPosterClick = { meta ->
|
||||
navController.navigate(DetailRoute(type = meta.type, id = meta.id))
|
||||
},
|
||||
onAddonsClick = {
|
||||
navController.navigate(AddonsRoute)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -252,6 +263,13 @@ fun App() {
|
|||
modifier = Modifier.fillMaxSize(),
|
||||
)
|
||||
}
|
||||
composable<AddonsRoute> {
|
||||
AddonsScreen(
|
||||
title = "Addons",
|
||||
onBack = { navController.popBackStack() },
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ import androidx.compose.ui.text.font.FontWeight
|
|||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
|
||||
|
||||
@Composable
|
||||
fun NuvioScreen(
|
||||
|
|
@ -94,6 +96,7 @@ fun NuvioSurfaceCard(
|
|||
fun NuvioScreenHeader(
|
||||
title: String,
|
||||
modifier: Modifier = Modifier,
|
||||
onBack: (() -> Unit)? = null,
|
||||
actions: @Composable RowScope.() -> Unit = {},
|
||||
) {
|
||||
val statusBarTop = WindowInsets.statusBars.asPaddingValues().calculateTopPadding()
|
||||
|
|
@ -105,16 +108,30 @@ fun NuvioScreenHeader(
|
|||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.Bottom,
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = title,
|
||||
transitionSpec = { fadeIn() togetherWith fadeOut() },
|
||||
label = "screen_header_title",
|
||||
) { currentTitle ->
|
||||
Text(
|
||||
text = currentTitle,
|
||||
style = MaterialTheme.typography.displayLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
if (onBack != null) {
|
||||
IconButton(onClick = onBack) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Rounded.ArrowBack,
|
||||
contentDescription = "Back",
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
}
|
||||
}
|
||||
AnimatedContent(
|
||||
targetState = title,
|
||||
transitionSpec = { fadeIn() togetherWith fadeOut() },
|
||||
label = "screen_header_title",
|
||||
) { currentTitle ->
|
||||
Text(
|
||||
text = currentTitle,
|
||||
style = MaterialTheme.typography.displayLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
}
|
||||
}
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(2.dp),
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ import kotlinx.coroutines.launch
|
|||
@Composable
|
||||
fun AddonsScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
title: String = "Content & Discovery",
|
||||
onBack: (() -> Unit)? = null,
|
||||
) {
|
||||
LaunchedEffect(Unit) {
|
||||
AddonRepository.initialize()
|
||||
|
|
@ -76,7 +78,8 @@ fun AddonsScreen(
|
|||
NuvioScreen(modifier = modifier) {
|
||||
stickyHeader {
|
||||
NuvioScreenHeader(
|
||||
title = "Addons",
|
||||
title = title,
|
||||
onBack = onBack,
|
||||
) {
|
||||
NuvioIconActionButton(
|
||||
icon = Icons.Rounded.SwapVert,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,420 @@
|
|||
package com.nuvio.app.features.settings
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.asPaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.statusBars
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
|
||||
import androidx.compose.material.icons.automirrored.rounded.ArrowForward
|
||||
import androidx.compose.material.icons.rounded.Extension
|
||||
import androidx.compose.material.icons.rounded.Settings
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.max
|
||||
import com.nuvio.app.core.ui.NuvioScreen
|
||||
import com.nuvio.app.core.ui.NuvioScreenHeader
|
||||
import com.nuvio.app.core.ui.NuvioSectionLabel
|
||||
|
||||
private enum class SettingsCategory(
|
||||
val label: String,
|
||||
val icon: ImageVector,
|
||||
) {
|
||||
General("General", Icons.Rounded.Settings),
|
||||
}
|
||||
|
||||
private enum class SettingsPage(
|
||||
val title: String,
|
||||
) {
|
||||
Root("Settings"),
|
||||
ContentDiscovery("Content & Discovery"),
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SettingsScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
onAddonsClick: () -> Unit = {},
|
||||
) {
|
||||
BoxWithConstraints(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.background(MaterialTheme.colorScheme.background),
|
||||
) {
|
||||
var currentPage by rememberSaveable { mutableStateOf(SettingsPage.Root.name) }
|
||||
val page = remember(currentPage) { SettingsPage.valueOf(currentPage) }
|
||||
|
||||
if (maxWidth >= 768.dp) {
|
||||
TabletSettingsScreen(
|
||||
page = page,
|
||||
onPageChange = { currentPage = it.name },
|
||||
onAddonsClick = onAddonsClick,
|
||||
)
|
||||
} else {
|
||||
MobileSettingsScreen(
|
||||
page = page,
|
||||
onPageChange = { currentPage = it.name },
|
||||
onAddonsClick = onAddonsClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MobileSettingsScreen(
|
||||
page: SettingsPage,
|
||||
onPageChange: (SettingsPage) -> Unit,
|
||||
onAddonsClick: () -> Unit,
|
||||
) {
|
||||
NuvioScreen {
|
||||
stickyHeader {
|
||||
NuvioScreenHeader(
|
||||
title = page.title,
|
||||
onBack = if (page != SettingsPage.Root) {
|
||||
{ onPageChange(SettingsPage.Root) }
|
||||
} else {
|
||||
null
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
when (page) {
|
||||
SettingsPage.Root -> settingsRootContent(
|
||||
isTablet = false,
|
||||
onContentDiscoveryClick = { onPageChange(SettingsPage.ContentDiscovery) },
|
||||
)
|
||||
SettingsPage.ContentDiscovery -> contentDiscoveryContent(
|
||||
isTablet = false,
|
||||
onAddonsClick = onAddonsClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TabletSettingsScreen(
|
||||
page: SettingsPage,
|
||||
onPageChange: (SettingsPage) -> Unit,
|
||||
onAddonsClick: () -> Unit,
|
||||
) {
|
||||
var selectedCategory by rememberSaveable { mutableStateOf(SettingsCategory.General.name) }
|
||||
val activeCategory = SettingsCategory.valueOf(selectedCategory)
|
||||
val statusBarPadding = WindowInsets.statusBars.asPaddingValues().calculateTopPadding()
|
||||
val topOffset = max(statusBarPadding + 24.dp, 48.dp) + 64.dp
|
||||
|
||||
Row(modifier = Modifier.fillMaxSize()) {
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.width(280.dp)
|
||||
.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.surface,
|
||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(top = topOffset),
|
||||
) {
|
||||
Text(
|
||||
text = "Settings",
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp)
|
||||
.padding(bottom = 20.dp),
|
||||
style = MaterialTheme.typography.displayLarge,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
HorizontalDivider(color = MaterialTheme.colorScheme.outlineVariant)
|
||||
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
SettingsSidebarItem(
|
||||
label = activeCategory.label,
|
||||
icon = activeCategory.icon,
|
||||
selected = true,
|
||||
onClick = { selectedCategory = activeCategory.name },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = PaddingValues(
|
||||
start = 40.dp,
|
||||
top = topOffset,
|
||||
end = 40.dp,
|
||||
bottom = 40.dp,
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(18.dp),
|
||||
) {
|
||||
item {
|
||||
TabletPageHeader(
|
||||
title = if (page == SettingsPage.Root) activeCategory.label else page.title,
|
||||
showBack = page != SettingsPage.Root,
|
||||
onBack = { onPageChange(SettingsPage.Root) },
|
||||
)
|
||||
}
|
||||
when (page) {
|
||||
SettingsPage.Root -> settingsRootContent(
|
||||
isTablet = true,
|
||||
onContentDiscoveryClick = { onPageChange(SettingsPage.ContentDiscovery) },
|
||||
)
|
||||
SettingsPage.ContentDiscovery -> contentDiscoveryContent(
|
||||
isTablet = true,
|
||||
onAddonsClick = onAddonsClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun androidx.compose.foundation.lazy.LazyListScope.settingsRootContent(
|
||||
isTablet: Boolean,
|
||||
onContentDiscoveryClick: () -> Unit,
|
||||
) {
|
||||
item {
|
||||
SettingsSection(
|
||||
title = "GENERAL",
|
||||
isTablet = isTablet,
|
||||
) {
|
||||
SettingsNavigationRow(
|
||||
title = "Content & Discovery",
|
||||
description = "Manage addons and discovery sources.",
|
||||
icon = Icons.Rounded.Extension,
|
||||
isTablet = isTablet,
|
||||
onClick = onContentDiscoveryClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun androidx.compose.foundation.lazy.LazyListScope.contentDiscoveryContent(
|
||||
isTablet: Boolean,
|
||||
onAddonsClick: () -> Unit,
|
||||
) {
|
||||
item {
|
||||
SettingsSection(
|
||||
title = "GENERAL",
|
||||
isTablet = isTablet,
|
||||
) {
|
||||
SettingsNavigationRow(
|
||||
title = "Addons",
|
||||
description = "Install, remove, refresh, and sort your content sources.",
|
||||
icon = Icons.Rounded.Extension,
|
||||
isTablet = isTablet,
|
||||
onClick = onAddonsClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TabletPageHeader(
|
||||
title: String,
|
||||
showBack: Boolean,
|
||||
onBack: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
if (showBack) {
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.size(36.dp)
|
||||
.clickable(onClick = onBack),
|
||||
color = MaterialTheme.colorScheme.surface,
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Rounded.ArrowBack,
|
||||
contentDescription = "Back",
|
||||
tint = MaterialTheme.colorScheme.onSurface,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.headlineLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SettingsSidebarItem(
|
||||
label: String,
|
||||
icon: ImageVector,
|
||||
selected: Boolean,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
val primary = MaterialTheme.colorScheme.primary
|
||||
val background = if (selected) primary.copy(alpha = 0.10f) else Color.Transparent
|
||||
val iconChip = if (selected) primary.copy(alpha = 0.15f) else Color.Transparent
|
||||
val contentColor = if (selected) MaterialTheme.colorScheme.onSurface else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 12.dp, vertical = 2.dp)
|
||||
.background(background, RoundedCornerShape(10.dp))
|
||||
.clickable(onClick = onClick)
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier.size(32.dp),
|
||||
color = iconChip,
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = if (selected) primary else contentColor,
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
Text(
|
||||
text = label,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = contentColor,
|
||||
fontWeight = if (selected) FontWeight.SemiBold else FontWeight.Medium,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SettingsSection(
|
||||
title: String,
|
||||
isTablet: Boolean,
|
||||
content: @Composable ColumnScope.() -> Unit,
|
||||
) {
|
||||
Column {
|
||||
NuvioSectionLabel(text = title)
|
||||
Spacer(modifier = Modifier.height(if (isTablet) 12.dp else 10.dp))
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
color = MaterialTheme.colorScheme.surface,
|
||||
shape = RoundedCornerShape(if (isTablet) 20.dp else 16.dp),
|
||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant),
|
||||
) {
|
||||
Column(content = content)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SettingsNavigationRow(
|
||||
title: String,
|
||||
description: String,
|
||||
icon: ImageVector,
|
||||
isTablet: Boolean,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
val iconSize = if (isTablet) 42.dp else 36.dp
|
||||
val iconRadius = if (isTablet) 12.dp else 10.dp
|
||||
val verticalPadding = if (isTablet) 16.dp else 14.dp
|
||||
val horizontalPadding = if (isTablet) 20.dp else 16.dp
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onClick)
|
||||
.padding(horizontal = horizontalPadding, vertical = verticalPadding),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(end = 12.dp)
|
||||
.widthIn(max = if (isTablet) 560.dp else 320.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier.size(iconSize),
|
||||
color = MaterialTheme.colorScheme.primary.copy(alpha = 0.12f),
|
||||
shape = RoundedCornerShape(iconRadius),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.width(if (isTablet) 16.dp else 14.dp))
|
||||
Column {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontWeight = FontWeight.Medium,
|
||||
)
|
||||
Spacer(modifier = Modifier.height(2.dp))
|
||||
Text(
|
||||
text = description,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.alpha(0.92f),
|
||||
)
|
||||
}
|
||||
}
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Rounded.ArrowForward,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue