refactor More menu and replace AppDropDownMenu with ModalBottomSheet in `LibraryScreen

This commit is contained in:
jonasgaudian
2026-02-17 11:27:23 +01:00
parent 35080c208b
commit 4dd9fe86aa
5 changed files with 114 additions and 37 deletions

View File

@@ -25,6 +25,7 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenu
@@ -550,7 +551,55 @@ fun AppDropdownMenu(
// ========================================= // =========================================
// LEGACY COMPONENTS (UPDATED TO USE UNIFIED STYLES) // LEGACY COMPONENTS (UPDATED TO USE UNIFIED STYLES)
// ========================================= // =========================================
@Composable
fun BottomSheetMenuItem(
icon: ImageVector,
title: String,
subtitle: String,
onClick: () -> Unit
) {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable { onClick() }
.padding(horizontal = 24.dp, vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
// Circular Icon Background
Surface(
shape = CircleShape,
color = MaterialTheme.colorScheme.surfaceVariant,
modifier = Modifier.size(52.dp)
) {
Box(contentAlignment = Alignment.Center) {
Icon(
imageVector = icon,
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.size(28.dp)
)
}
}
Spacer(modifier = Modifier.width(16.dp))
// Title and Subtitle Column
Column(modifier = Modifier.weight(1f)) {
Text(
text = title,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onSurface
)
Spacer(modifier = Modifier.height(2.dp))
Text(
text = subtitle,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
}
}
@Composable @Composable
fun LargeDropdownMenuItem( fun LargeDropdownMenuItem(
text: String, text: String,

View File

@@ -28,13 +28,13 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.PlayArrow import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.NavigationBarItemDefaults import androidx.compose.material3.NavigationBarItemDefaults
import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -326,10 +326,11 @@ private fun MoreBottomSheetContent(
Text( Text(
text = stringResource(R.string.label_more), text = stringResource(R.string.label_more),
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Bold, // Added bold to match the new style
modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp) modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp)
) )
HorizontalDivider() // Removed HorizontalDivider() for a cleaner look
moreItems.forEach { screen -> moreItems.forEach { screen ->
MoreMenuItem( MoreMenuItem(
@@ -340,31 +341,49 @@ private fun MoreBottomSheetContent(
} }
} }
@Composable @Composable
private fun MoreMenuItem( fun MoreMenuItem(
screen: Screen, screen: Screen,
onClick: () -> Unit onClick: () -> Unit
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable(onClick = onClick) .clickable { onClick() }
.padding(horizontal = 24.dp, vertical = 16.dp), .padding(horizontal = 24.dp, vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
// Circular Icon Background
Surface(
shape = CircleShape,
color = MaterialTheme.colorScheme.surfaceVariant,
modifier = Modifier.size(52.dp)
) {
Box(contentAlignment = Alignment.Center) {
// Adjust this depending on whether your Screen uses ImageVector or Drawable Res
Icon( Icon(
imageVector = screen.selectedIcon, imageVector = screen.selectedIcon,
contentDescription = null, contentDescription = null,
tint = MaterialTheme.colorScheme.primary tint = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.size(28.dp)
) )
}
}
Spacer(modifier = Modifier.width(16.dp)) Spacer(modifier = Modifier.width(16.dp))
// Title
Text( Text(
text = stringResource(screen.title), text = stringResource(id = screen.title), // Adjust to your actual string property
style = MaterialTheme.typography.bodyLarge style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.weight(1f)
) )
} }
} }
@ThemePreviews @ThemePreviews
@Composable @Composable
fun BottomNavigationBarPreview() { fun BottomNavigationBarPreview() {

View File

@@ -26,6 +26,9 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Add
import androidx.compose.material.icons.rounded.Folder
import androidx.compose.material3.BottomSheetDefaults import androidx.compose.material3.BottomSheetDefaults
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.FilterChip import androidx.compose.material3.FilterChip
@@ -60,10 +63,9 @@ import androidx.navigation.NavHostController
import eu.gaudian.translator.R import eu.gaudian.translator.R
import eu.gaudian.translator.model.VocabularyStage import eu.gaudian.translator.model.VocabularyStage
import eu.gaudian.translator.utils.findActivity import eu.gaudian.translator.utils.findActivity
import eu.gaudian.translator.view.composable.AppDropDownMenu
import eu.gaudian.translator.view.composable.AppIcons import eu.gaudian.translator.view.composable.AppIcons
import eu.gaudian.translator.view.composable.AppSwitch import eu.gaudian.translator.view.composable.AppSwitch
import eu.gaudian.translator.view.composable.LargeDropdownMenuItem import eu.gaudian.translator.view.composable.BottomSheetMenuItem
import eu.gaudian.translator.view.composable.MultipleLanguageDropdown import eu.gaudian.translator.view.composable.MultipleLanguageDropdown
import eu.gaudian.translator.view.dialogs.AddCategoryDialog import eu.gaudian.translator.view.dialogs.AddCategoryDialog
import eu.gaudian.translator.view.dialogs.CategorySelectionDialog import eu.gaudian.translator.view.dialogs.CategorySelectionDialog
@@ -329,23 +331,30 @@ fun LibraryScreen(
} }
if (showAddMenu) { if (showAddMenu) {
AppDropDownMenu( ModalBottomSheet(
expanded = showAddMenu, onDismissRequest = { showAddMenu = false },
onDismissRequest = { showAddMenu = false } sheetState = sheetState,
containerColor = MaterialTheme.colorScheme.surface,
) { ) {
LargeDropdownMenuItem( Column(
text = stringResource(R.string.label_add_vocabulary), modifier = Modifier
selected = false, .fillMaxWidth()
enabled = true, .padding(bottom = 32.dp) // Extra padding for system navigation bar
) {
BottomSheetMenuItem(
icon = Icons.Rounded.Add, // Or any custom vector icon you prefer
title = stringResource(R.string.label_add_vocabulary),
subtitle = "Füge ein neues Wort zu deiner Liste hinzu", // Suggest adding this to strings.xml
onClick = { onClick = {
showAddMenu = false showAddMenu = false
navController.navigate("new_word") navController.navigate("new_word")
} }
) )
LargeDropdownMenuItem(
text = stringResource(R.string.label_add_category), BottomSheetMenuItem(
selected = false, icon = Icons.Rounded.Folder,
enabled = true, title = stringResource(R.string.label_add_category),
subtitle = "Organisiere deine Vokabeln in Gruppen", // Suggest adding this to strings.xml
onClick = { onClick = {
showAddMenu = false showAddMenu = false
showAddCategoryDialog = true showAddCategoryDialog = true
@@ -353,6 +362,7 @@ fun LibraryScreen(
) )
} }
} }
}
if (showAddCategoryDialog) { if (showAddCategoryDialog) {
AddCategoryDialog(onDismiss = { showAddCategoryDialog = false }) AddCategoryDialog(onDismiss = { showAddCategoryDialog = false })

View File

@@ -105,7 +105,7 @@ fun MainSettingsScreen(
} }
item { item {
AppCard( AppCard(
modifier = Modifier.padding(horizontal = 8.dp, vertical = 8.dp), modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
) { ) {
Column { Column {
settings.forEachIndexed { index, setting -> settings.forEachIndexed { index, setting ->

View File

@@ -631,7 +631,6 @@
<string name="label_language_none">Keine</string> <string name="label_language_none">Keine</string>
<string name="text_no_data_available">Keine Daten verfügbar</string> <string name="text_no_data_available">Keine Daten verfügbar</string>
<string name="label_grammar_inflections">Flexionen</string> <string name="label_grammar_inflections">Flexionen</string>
<string name="label_more">Weniger</string>
<string name="label_translations">Übersetzungen</string> <string name="label_translations">Übersetzungen</string>
<string name="label_show_examples">Beispiele anzeigen</string> <string name="label_show_examples">Beispiele anzeigen</string>
<string name="label_grammar_hyphenation">Silbentrennung</string> <string name="label_grammar_hyphenation">Silbentrennung</string>