Compare commits

...

3 Commits

Author SHA1 Message Date
4c986432f6 refactor: extract common part from the HomeTopBar and make component logic reusable 2026-04-27 21:11:25 +02:00
afdd9b860f feat: integrate dynamic library navigation in TV drawer
Refactors the TV navigation drawer to use specific library routes instead
of a static libraries overview. Added a `NavDisplay` with a backstack to
manage navigation between the Home screen and individual Library screens
directly from the drawer.

- Replace `TvDrawerDestination` enum with `Route` in the navigation drawer
- Dynamically populate drawer items based on available libraries
- Add `NavDisplay` to `TvAppScreen` for nested TV navigation
- Connect `TvLibraryScreen` to `AppViewModel` for media selection handling
- Remove back button from `TvLibraryScreen` in favor of drawer navigation
- Update `TvNavigationDrawerTest` to reflect routing changes
2026-04-26 18:08:40 +02:00
51ffd14804 refactor: reduce maxLines for primary text in HomeBrowseCard 2026-04-26 14:53:57 +02:00
14 changed files with 234 additions and 269 deletions

View File

@@ -24,9 +24,12 @@ import androidx.compose.ui.test.performKeyInput
import androidx.compose.ui.test.performSemanticsAction
import androidx.compose.ui.test.pressKey
import androidx.compose.ui.unit.dp
import hu.bbara.purefin.navigation.LibraryDto
import hu.bbara.purefin.navigation.Route
import hu.bbara.purefin.ui.theme.AppTheme
import org.junit.Rule
import org.junit.Test
import java.util.UUID
@OptIn(ExperimentalTestApi::class)
class TvNavigationDrawerTest {
@@ -56,20 +59,26 @@ class TvNavigationDrawerTest {
@Test
fun tvNavigationDrawer_updatesSelectedDestination() {
var selectedDestination by mutableStateOf(TvDrawerDestination.HOME)
val libraryRoute = Route.LibraryRoute(
library = LibraryDto(
id = UUID.fromString("22222222-2222-2222-2222-222222222222"),
name = "Movies"
)
)
var selectedDestination by mutableStateOf<Route>(Route.Home)
composeRule.setContent {
AppTheme {
TvNavigationDrawer(
destinations = listOf(
TvDrawerDestinationItem(
destination = TvDrawerDestination.HOME,
destination = Route.Home,
label = "Home",
icon = Icons.Outlined.Home
),
TvDrawerDestinationItem(
destination = TvDrawerDestination.LIBRARIES,
label = "Libraries",
destination = libraryRoute,
label = "Movies",
icon = Icons.Outlined.Collections
)
),

View File

@@ -1,6 +1,8 @@
package hu.bbara.purefin.navigation
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation3.runtime.EntryProviderScope
import hu.bbara.purefin.feature.browse.home.AppViewModel
import hu.bbara.purefin.ui.screen.episode.TvEpisodeScreen
import hu.bbara.purefin.ui.screen.movie.TvMovieScreen
import hu.bbara.purefin.ui.screen.series.TvSeriesScreen
@@ -51,6 +53,10 @@ fun EntryProviderScope<Route>.tvPlayerSection() {
fun EntryProviderScope<Route>.tvLibrarySection() {
entry<Route.LibraryRoute> { route ->
TvLibraryScreen(library = route.library)
val viewModel: AppViewModel = hiltViewModel()
TvLibraryScreen(
library = route.library,
onMediaSelected = viewModel::onMediaSelected
)
}
}

View File

@@ -2,7 +2,6 @@ package hu.bbara.purefin.ui.screen
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Collections
import androidx.compose.material.icons.outlined.Home
import androidx.compose.material.icons.outlined.Movie
import androidx.compose.material.icons.outlined.Tv
@@ -10,18 +9,24 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.LifecycleResumeEffect
import hu.bbara.purefin.model.LibraryKind
import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator
import androidx.navigation3.runtime.NavBackStack
import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.runtime.rememberNavBackStack
import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
import androidx.navigation3.ui.NavDisplay
import hu.bbara.purefin.feature.browse.home.AppViewModel
import hu.bbara.purefin.model.LibraryKind
import hu.bbara.purefin.navigation.LibraryDto
import hu.bbara.purefin.navigation.LocalNavigationManager
import hu.bbara.purefin.navigation.Route
import hu.bbara.purefin.ui.screen.home.TvHomeScreen
import hu.bbara.purefin.ui.screen.home.components.TvDrawerDestination
import hu.bbara.purefin.ui.screen.home.components.TvDrawerDestinationItem
import hu.bbara.purefin.ui.screen.home.components.TvNavigationDrawer
import hu.bbara.purefin.ui.screen.libraries.TvLibrariesOverviewScreen
import hu.bbara.purefin.ui.screen.library.TvLibraryScreen
@Composable
fun TvAppScreen(
@@ -32,45 +37,41 @@ fun TvAppScreen(
val continueWatching by viewModel.continueWatching.collectAsState()
val nextUp by viewModel.nextUp.collectAsState()
val latestLibraryContent by viewModel.latestLibraryContent.collectAsState()
val navigationManager = LocalNavigationManager.current
var selectedDestination by rememberSaveable { androidx.compose.runtime.mutableStateOf(TvDrawerDestination.HOME) }
@Suppress("UNCHECKED_CAST")
val backStack = rememberNavBackStack(Route.Home) as NavBackStack<Route>
val selectedDestination = backStack.lastOrNull() ?: Route.Home
val destinations = remember(libraries, selectedDestination) {
val destinations = remember(libraries) {
listOf(
TvDrawerDestinationItem(
destination = TvDrawerDestination.HOME,
destination = Route.Home,
label = "Home",
icon = Icons.Outlined.Home,
selected = selectedDestination == TvDrawerDestination.HOME
),
icon = Icons.Outlined.Home
)
) + libraries.map { library ->
val destination = Route.LibraryRoute(
library = LibraryDto(id = library.id, name = library.name)
)
TvDrawerDestinationItem(
destination = TvDrawerDestination.LIBRARIES,
label = "Libraries",
icon = when {
libraries.any { it.type == LibraryKind.MOVIES } -> Icons.Outlined.Movie
libraries.any { it.type == LibraryKind.SERIES } -> Icons.Outlined.Tv
else -> Icons.Outlined.Collections
},
selected = selectedDestination == TvDrawerDestination.LIBRARIES
)
destination = destination,
label = library.name,
icon = when (library.type) {
LibraryKind.MOVIES -> Icons.Outlined.Movie
LibraryKind.SERIES -> Icons.Outlined.Tv
}
)
}
}
LifecycleResumeEffect(Unit) {
viewModel.onResumed()
onPauseOrDispose { }
}
TvNavigationDrawer(
destinations = destinations,
selectedDestination = selectedDestination,
onDestinationSelected = { destination ->
selectedDestination = destination
},
modifier = modifier.fillMaxSize()
) {
when (selectedDestination) {
TvDrawerDestination.HOME -> {
val tvEntryProvider = entryProvider {
entry<Route.Home> {
TvHomeScreen(
libraries = libraries,
libraryContent = latestLibraryContent,
@@ -80,15 +81,44 @@ fun TvAppScreen(
modifier = Modifier.fillMaxSize()
)
}
TvDrawerDestination.LIBRARIES -> {
TvLibrariesOverviewScreen(
libraries = libraries,
onLibrarySelected = { library ->
viewModel.onLibrarySelected(library.id, library.name)
},
entry<Route.LibraryRoute> { route ->
TvLibraryScreen(
library = route.library,
onMediaSelected = viewModel::onMediaSelected,
modifier = Modifier.fillMaxSize()
)
}
}
TvNavigationDrawer(
destinations = destinations,
selectedDestination = selectedDestination,
onDestinationSelected = { destination ->
if (selectedDestination != destination) {
backStack.clear()
backStack.add(Route.Home)
if (destination is Route.LibraryRoute) {
backStack.add(destination)
}
}
},
modifier = modifier.fillMaxSize()
) {
NavDisplay(
backStack = backStack,
onBack = {
if (backStack.size > 1) {
backStack.removeLastOrNull()
} else {
navigationManager.pop()
}
},
entryDecorators = listOf(
rememberSaveableStateHolderNavEntryDecorator(),
rememberViewModelStoreNavEntryDecorator()
),
entryProvider = tvEntryProvider,
modifier = Modifier.fillMaxSize()
)
}
}

View File

@@ -1,15 +1,10 @@
package hu.bbara.purefin.ui.screen.home.components
import androidx.compose.ui.graphics.vector.ImageVector
enum class TvDrawerDestination {
HOME,
LIBRARIES
}
import hu.bbara.purefin.navigation.Route
data class TvDrawerDestinationItem(
val destination: TvDrawerDestination,
val destination: Route,
val label: String,
val icon: ImageVector,
val selected: Boolean = false
val icon: ImageVector
)

View File

@@ -30,9 +30,10 @@ import androidx.tv.material3.Icon
import androidx.tv.material3.NavigationDrawer
import androidx.tv.material3.NavigationDrawerItem
import androidx.tv.material3.Text
import androidx.tv.material3.MaterialTheme as TvMaterialTheme
import androidx.tv.material3.darkColorScheme
import hu.bbara.purefin.navigation.Route
import hu.bbara.purefin.tv.R
import androidx.tv.material3.MaterialTheme as TvMaterialTheme
internal const val TvDrawerItemTagPrefix = "tv-drawer-item-"
internal const val TvDrawerTitleTag = "tv-drawer-title"
@@ -43,8 +44,8 @@ private val TvDrawerExpandedWidth = 280.dp
@Composable
fun TvNavigationDrawer(
destinations: List<TvDrawerDestinationItem>,
selectedDestination: TvDrawerDestination,
onDestinationSelected: (TvDrawerDestination) -> Unit,
selectedDestination: Route,
onDestinationSelected: (Route) -> Unit,
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
@@ -132,15 +133,15 @@ fun TvDrawerHeader(
private fun androidx.tv.material3.NavigationDrawerScope.TvNavigationDrawerRail(
drawerValue: DrawerValue,
destinations: List<TvDrawerDestinationItem>,
selectedDestination: TvDrawerDestination,
onDestinationSelected: (TvDrawerDestination) -> Unit,
selectedDestination: Route,
onDestinationSelected: (Route) -> Unit,
) {
val expanded = drawerValue == DrawerValue.Open
val drawerWidth = animateDpAsState(
targetValue = if (expanded) TvDrawerExpandedWidth else TvDrawerCollapsedWidth,
label = "tv-drawer-width"
)
val scheme = androidx.tv.material3.MaterialTheme.colorScheme
val scheme = MaterialTheme.colorScheme
Box(
modifier = Modifier

View File

@@ -4,15 +4,12 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
@@ -22,16 +19,15 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import hu.bbara.purefin.navigation.LibraryDto
import hu.bbara.purefin.ui.model.MediaUiModel
import hu.bbara.purefin.feature.browse.library.LibraryViewModel
import hu.bbara.purefin.ui.common.button.PurefinIconButton
import hu.bbara.purefin.navigation.LibraryDto
import hu.bbara.purefin.ui.common.card.PosterCard
import java.util.UUID
import hu.bbara.purefin.ui.model.MediaUiModel
@Composable
fun TvLibraryScreen(
library: LibraryDto,
onMediaSelected: (MediaUiModel) -> Unit,
viewModel: LibraryViewModel = hiltViewModel(),
modifier: Modifier = Modifier
) {
@@ -45,15 +41,13 @@ fun TvLibraryScreen(
modifier = modifier,
topBar = {
TvLibraryTopBar(
title = library.name,
onBack = viewModel::onBack
title = library.name
)
}
) { innerPadding ->
TvLibraryContent(
libraryItems = libraryItems.value,
onMovieSelected = viewModel::onMovieSelected,
onSeriesSelected = viewModel::onSeriesSelected,
onMediaSelected = onMediaSelected,
modifier = Modifier.padding(innerPadding)
)
}
@@ -61,40 +55,23 @@ fun TvLibraryScreen(
@Composable
private fun TvLibraryTopBar(
title: String,
onBack: () -> Unit
title: String
) {
val scheme = MaterialTheme.colorScheme
Row(
modifier = Modifier
.fillMaxWidth()
.statusBarsPadding()
.padding(horizontal = 16.dp, vertical = 12.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
PurefinIconButton(
icon = Icons.AutoMirrored.Outlined.ArrowBack,
contentDescription = "Back",
onClick = onBack,
focusedScale = 1.1f,
focusedBorderWidth = 2.5.dp,
focusedBorderColor = scheme.onPrimary,
focusedBackgroundColor = scheme.primary
)
Text(
text = title,
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.padding(top = 12.dp)
modifier = Modifier
.fillMaxWidth()
.statusBarsPadding()
.padding(horizontal = 16.dp, vertical = 12.dp)
)
}
}
@Composable
fun TvLibraryContent(
libraryItems: List<MediaUiModel>,
onMovieSelected: (UUID) -> Unit,
onSeriesSelected: (UUID) -> Unit,
onMediaSelected: (MediaUiModel) -> Unit,
modifier: Modifier = Modifier
) {
Column(modifier = modifier) {
@@ -108,9 +85,9 @@ fun TvLibraryContent(
items(libraryItems, key = { item -> item.id }) { item ->
PosterCard(
item = item,
onMovieSelected = onMovieSelected,
onSeriesSelected = onSeriesSelected,
onEpisodeSelected = { _, _, _ -> }
onMovieSelected = { onMediaSelected(item) },
onSeriesSelected = { onMediaSelected(item) },
onEpisodeSelected = { _, _, _ -> onMediaSelected(item) }
)
}
}

View File

@@ -1,102 +0,0 @@
package hu.bbara.purefin.ui.common
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Person
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import androidx.hilt.navigation.compose.hiltViewModel
import hu.bbara.purefin.feature.search.SearchViewModel
@Composable
fun DefaultTopBar(
modifier: Modifier = Modifier,
searchViewModel: SearchViewModel = hiltViewModel(),
onProfileClick: () -> Unit = {},
onSettingsClick: () -> Unit = {},
onLogoutClick: () -> Unit = {},
) {
val scheme = MaterialTheme.colorScheme
val searchResult = searchViewModel.searchResult.collectAsState()
var isProfileMenuExpanded by remember { mutableStateOf(false) }
var isSearchExpanded by remember { mutableStateOf(false) }
Box(
modifier = modifier
.fillMaxWidth()
.background(scheme.background.copy(alpha = 0.95f))
.zIndex(1f)
) {
Box(
modifier = Modifier
.statusBarsPadding()
.padding(horizontal = 16.dp, vertical = 16.dp)
.fillMaxWidth(),
contentAlignment = Alignment.CenterEnd
) {
if (!isSearchExpanded) {
Box {
IconButton(
onClick = { isProfileMenuExpanded = true },
modifier = Modifier
.size(56.dp)
.clip(CircleShape),
) {
Icon(
imageVector = Icons.Outlined.Person,
contentDescription = "Profile",
modifier = Modifier.size(30.dp),
)
}
DropdownMenu(
expanded = isProfileMenuExpanded,
onDismissRequest = { isProfileMenuExpanded = false },
) {
DropdownMenuItem(
text = { Text("Profile") },
onClick = {
isProfileMenuExpanded = false
onProfileClick()
}
)
DropdownMenuItem(
text = { Text("Settings") },
onClick = {
isProfileMenuExpanded = false
onSettingsClick()
}
)
DropdownMenuItem(
text = { Text("Logout") },
onClick = {
isProfileMenuExpanded = false
onLogoutClick()
}
)
}
}
}
}
}
}

View File

@@ -3,6 +3,9 @@ package hu.bbara.purefin.ui.screen
import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.ContentTransform
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
@@ -26,9 +29,6 @@ import hu.bbara.purefin.ui.screen.home.HomeScreen
import hu.bbara.purefin.ui.screen.home.components.HomeNavItem
import hu.bbara.purefin.ui.screen.libraries.LibrariesScreen
import kotlinx.serialization.Serializable
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.animation.togetherWith
@Composable
fun AppScreen(
@@ -99,9 +99,6 @@ fun AppScreen(
LibrariesScreen(
items = libraryNavItems,
onLibrarySelected = { item -> viewModel.onLibrarySelected(item.id, item.label) },
onProfileClick = {},
onSettingsClick = {},
onLogoutClick = viewModel::logout,
selectedTab = selectedTab,
onTabSelected = onTabSelected,
modifier = Modifier.fillMaxSize()

View File

@@ -12,8 +12,8 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import hu.bbara.purefin.ui.model.MediaUiModel
import hu.bbara.purefin.feature.browse.home.LibraryItem
import hu.bbara.purefin.ui.model.MediaUiModel
import hu.bbara.purefin.ui.screen.AppBottomBar
import hu.bbara.purefin.ui.screen.home.components.HomeContent
import hu.bbara.purefin.ui.screen.home.components.HomeTopBar

View File

@@ -0,0 +1,60 @@
package hu.bbara.purefin.ui.screen.home.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import hu.bbara.purefin.ui.common.image.PurefinLogo
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DefaultTopBar(
actions: @Composable RowScope.() -> Unit
) {
val scheme = MaterialTheme.colorScheme
TopAppBar(
title = {
Row(
modifier = Modifier,
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalAlignment = Alignment.CenterVertically
) {
PurefinLogo(
contentDescription = "Purefin",
modifier = Modifier.size(48.dp),
contentScale = ContentScale.Fit,
)
Text(
text = "PureFin",
fontSize = 32.sp,
fontWeight = FontWeight.Bold,
fontStyle = FontStyle.Italic,
color = scheme.onSecondary
)
}
},
actions = actions,
colors = TopAppBarDefaults.largeTopAppBarColors(
containerColor = scheme.background,
navigationIconContentColor = scheme.onSurface,
actionIconContentColor = scheme.onSurface,
titleContentColor = scheme.onSurface
),
modifier = Modifier.padding(end = 12.dp)
)
}

View File

@@ -1,7 +1,5 @@
package hu.bbara.purefin.ui.screen.home.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
@@ -10,63 +8,33 @@ import androidx.compose.material.icons.outlined.Person
import androidx.compose.material.icons.outlined.Search
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonColors
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
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.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import hu.bbara.purefin.ui.common.image.PurefinLogo
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HomeTopBar(
onSearchClick: () -> Unit,
onProfileClick: () -> Unit,
onSettingsClick: () -> Unit,
onLogoutClick: () -> Unit,
modifier: Modifier = Modifier,
) {
val scheme = MaterialTheme.colorScheme
var isProfileMenuExpanded by remember { mutableStateOf(false) }
TopAppBar(
title = {
Row(
modifier = Modifier,
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalAlignment = Alignment.CenterVertically
) {
PurefinLogo(
contentDescription = "Purefin",
modifier = Modifier.size(48.dp),
contentScale = ContentScale.Fit,
)
Text(
text = "PureFin",
fontSize = 32.sp,
fontWeight = FontWeight.Bold,
fontStyle = FontStyle.Italic,
color = scheme.onSecondary
)
}
},
actions = {
DefaultTopBar()
{
IconButton(
onClick = onSearchClick,
colors = IconButtonColors(
@@ -126,14 +94,5 @@ fun HomeTopBar(
}
)
}
},
colors = TopAppBarDefaults.largeTopAppBarColors(
containerColor = scheme.background,
scrolledContainerColor = scheme.surface.copy(alpha = 0.96f),
navigationIconContentColor = scheme.onSurface,
actionIconContentColor = scheme.onSurface,
titleContentColor = scheme.onSurface
),
modifier = modifier
)
}
}

View File

@@ -23,11 +23,11 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import hu.bbara.purefin.ui.common.badge.WatchStateBadge
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
import hu.bbara.purefin.ui.model.EpisodeUiModel
import hu.bbara.purefin.ui.model.MediaUiModel
import hu.bbara.purefin.ui.model.MovieUiModel
import hu.bbara.purefin.ui.common.badge.WatchStateBadge
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
@Composable
internal fun HomeBrowseCard(
@@ -80,7 +80,7 @@ internal fun HomeBrowseCard(
text = uiModel.primaryText,
style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.SemiBold,
maxLines = 2,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
Spacer(modifier = Modifier.height(4.dp))

View File

@@ -6,18 +6,15 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import hu.bbara.purefin.ui.common.DefaultTopBar
import hu.bbara.purefin.ui.screen.home.components.HomeNavItem
import hu.bbara.purefin.ui.screen.AppBottomBar
import hu.bbara.purefin.ui.screen.home.components.HomeNavItem
import hu.bbara.purefin.ui.screen.libraries.components.LibrariesContent
import hu.bbara.purefin.ui.screen.library.components.LibraryTopBar
@Composable
fun LibrariesScreen(
items: List<HomeNavItem>,
onLibrarySelected: (HomeNavItem) -> Unit,
onProfileClick: () -> Unit,
onSettingsClick: () -> Unit,
onLogoutClick: () -> Unit,
selectedTab: Int,
onTabSelected: (Int) -> Unit,
modifier: Modifier = Modifier
@@ -27,10 +24,8 @@ fun LibrariesScreen(
containerColor = MaterialTheme.colorScheme.background,
contentColor = MaterialTheme.colorScheme.onBackground,
topBar = {
DefaultTopBar(
onProfileClick = onProfileClick,
onSettingsClick = onSettingsClick,
onLogoutClick = onLogoutClick
LibraryTopBar(
onSearchClick = {},
)
},
bottomBar = {

View File

@@ -0,0 +1,38 @@
package hu.bbara.purefin.ui.screen.library.components
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Search
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonColors
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import hu.bbara.purefin.ui.screen.home.components.DefaultTopBar
@Composable
fun LibraryTopBar(
onSearchClick: () -> Unit,
) {
val scheme = MaterialTheme.colorScheme
DefaultTopBar {
IconButton(
onClick = onSearchClick,
colors = IconButtonColors(
containerColor = scheme.secondary,
contentColor = scheme.onSecondary,
disabledContainerColor = scheme.secondary,
disabledContentColor = scheme.onSecondary),
modifier = Modifier.size(50.dp),
) {
Icon(
imageVector = Icons.Outlined.Search,
contentDescription = "Search",
modifier = Modifier.size(30.dp),
)
}
}
}