refactor: extract common part from the HomeTopBar and make component logic reusable

This commit is contained in:
2026-04-27 21:11:25 +02:00
parent afdd9b860f
commit 4c986432f6
7 changed files with 111 additions and 164 deletions

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

@@ -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),
)
}
}
}