From 4c986432f6c9e7050b27ff744d881d6a502c0f5b Mon Sep 17 00:00:00 2001 From: Barnabas Balogh Date: Mon, 27 Apr 2026 21:11:25 +0200 Subject: [PATCH] refactor: extract common part from the HomeTopBar and make component logic reusable --- .../bbara/purefin/ui/common/DefaultTopBar.kt | 102 ------------------ .../hu/bbara/purefin/ui/screen/AppScreen.kt | 9 +- .../purefin/ui/screen/home/HomeScreen.kt | 2 +- .../screen/home/components/DefaultTopBar.kt | 60 +++++++++++ .../ui/screen/home/components/HomeTopBar.kt | 51 +-------- .../ui/screen/libraries/LibrariesScreen.kt | 13 +-- .../library/components/LibraryTopBar.kt | 38 +++++++ 7 files changed, 111 insertions(+), 164 deletions(-) delete mode 100644 app/src/main/java/hu/bbara/purefin/ui/common/DefaultTopBar.kt create mode 100644 app/src/main/java/hu/bbara/purefin/ui/screen/home/components/DefaultTopBar.kt create mode 100644 app/src/main/java/hu/bbara/purefin/ui/screen/library/components/LibraryTopBar.kt diff --git a/app/src/main/java/hu/bbara/purefin/ui/common/DefaultTopBar.kt b/app/src/main/java/hu/bbara/purefin/ui/common/DefaultTopBar.kt deleted file mode 100644 index 8b27855d..00000000 --- a/app/src/main/java/hu/bbara/purefin/ui/common/DefaultTopBar.kt +++ /dev/null @@ -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() - } - ) - } - } - } - } - } -} diff --git a/app/src/main/java/hu/bbara/purefin/ui/screen/AppScreen.kt b/app/src/main/java/hu/bbara/purefin/ui/screen/AppScreen.kt index 568b22ed..88494da1 100644 --- a/app/src/main/java/hu/bbara/purefin/ui/screen/AppScreen.kt +++ b/app/src/main/java/hu/bbara/purefin/ui/screen/AppScreen.kt @@ -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() diff --git a/app/src/main/java/hu/bbara/purefin/ui/screen/home/HomeScreen.kt b/app/src/main/java/hu/bbara/purefin/ui/screen/home/HomeScreen.kt index f91d6f34..0ec2f6e0 100644 --- a/app/src/main/java/hu/bbara/purefin/ui/screen/home/HomeScreen.kt +++ b/app/src/main/java/hu/bbara/purefin/ui/screen/home/HomeScreen.kt @@ -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 diff --git a/app/src/main/java/hu/bbara/purefin/ui/screen/home/components/DefaultTopBar.kt b/app/src/main/java/hu/bbara/purefin/ui/screen/home/components/DefaultTopBar.kt new file mode 100644 index 00000000..a672bbea --- /dev/null +++ b/app/src/main/java/hu/bbara/purefin/ui/screen/home/components/DefaultTopBar.kt @@ -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) + ) +} diff --git a/app/src/main/java/hu/bbara/purefin/ui/screen/home/components/HomeTopBar.kt b/app/src/main/java/hu/bbara/purefin/ui/screen/home/components/HomeTopBar.kt index 97a86d5e..3d5c6ab4 100644 --- a/app/src/main/java/hu/bbara/purefin/ui/screen/home/components/HomeTopBar.kt +++ b/app/src/main/java/hu/bbara/purefin/ui/screen/home/components/HomeTopBar.kt @@ -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 - ) -} + } +} \ No newline at end of file diff --git a/app/src/main/java/hu/bbara/purefin/ui/screen/libraries/LibrariesScreen.kt b/app/src/main/java/hu/bbara/purefin/ui/screen/libraries/LibrariesScreen.kt index 246e3fc3..e1949dcd 100644 --- a/app/src/main/java/hu/bbara/purefin/ui/screen/libraries/LibrariesScreen.kt +++ b/app/src/main/java/hu/bbara/purefin/ui/screen/libraries/LibrariesScreen.kt @@ -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, 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 = { diff --git a/app/src/main/java/hu/bbara/purefin/ui/screen/library/components/LibraryTopBar.kt b/app/src/main/java/hu/bbara/purefin/ui/screen/library/components/LibraryTopBar.kt new file mode 100644 index 00000000..5c07c7a6 --- /dev/null +++ b/app/src/main/java/hu/bbara/purefin/ui/screen/library/components/LibraryTopBar.kt @@ -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), + ) + } + } +} \ No newline at end of file