update AppFabMenu to support optional titles and expand FABs in MainVocabularyScreen and VocabularyMenu

This commit is contained in:
jonasgaudian
2026-02-14 00:25:23 +01:00
parent 73cb3e1855
commit 37d8518e50
7 changed files with 41 additions and 16 deletions

View File

@@ -12,7 +12,7 @@ sealed class WidgetType(val id: String, @param:StringRes val titleRes: Int) {
data object StartButtons : WidgetType("start_buttons", R.string.label_start_exercise) data object StartButtons : WidgetType("start_buttons", R.string.label_start_exercise)
data object AllVocabulary : WidgetType("all_vocabulary", R.string.label_all_vocabulary) data object AllVocabulary : WidgetType("all_vocabulary", R.string.label_all_vocabulary)
data object DueToday : WidgetType("due_today", R.string.title_widget_due_today) data object DueToday : WidgetType("due_today", R.string.title_widget_due_today)
data object CategoryProgress : WidgetType("category_progress", R.string.title_widget_category_progress) data object CategoryProgress : WidgetType("category_progress", R.string.label_categories)
data object WeeklyActivityChart : WidgetType("weekly_activity_chart", R.string.text_widget_title_weekly_activity) data object WeeklyActivityChart : WidgetType("weekly_activity_chart", R.string.text_widget_title_weekly_activity)
data object Levels : WidgetType("category_stats", R.string.levels) data object Levels : WidgetType("category_stats", R.string.levels)

View File

@@ -54,7 +54,8 @@ data class FabMenuItem(
@Composable @Composable
fun AppFabMenu( fun AppFabMenu(
items: List<FabMenuItem>, items: List<FabMenuItem>,
modifier: Modifier = Modifier modifier: Modifier = Modifier,
title: String? = null
) { ) {
var isMenuExpanded by remember { mutableStateOf(false) } var isMenuExpanded by remember { mutableStateOf(false) }
@@ -67,6 +68,10 @@ fun AppFabMenu(
label = "fabRotation" label = "fabRotation"
) )
// Only rotate the FAB itself if there's no title, otherwise rotate just the icon
val fabRotationAngle = if (title == null) rotationAngle else 0f
val iconRotationAngle = if (title != null) rotationAngle else 0f
Column( Column(
modifier = modifier, modifier = modifier,
horizontalAlignment = Alignment.End, horizontalAlignment = Alignment.End,
@@ -97,16 +102,29 @@ fun AppFabMenu(
FloatingActionButton( FloatingActionButton(
onClick = { isMenuExpanded = !isMenuExpanded }, onClick = { isMenuExpanded = !isMenuExpanded },
modifier = Modifier.rotate(rotationAngle), modifier = Modifier.rotate(fabRotationAngle),
shape = RoundedCornerShape(16.dp), shape = RoundedCornerShape(16.dp),
containerColor = MaterialTheme.colorScheme.primary, containerColor = MaterialTheme.colorScheme.primary,
contentColor = MaterialTheme.colorScheme.onPrimary, contentColor = MaterialTheme.colorScheme.onPrimary,
elevation = FloatingActionButtonDefaults.elevation(defaultElevation = ComponentDefaults.DefaultElevation) elevation = FloatingActionButtonDefaults.elevation(defaultElevation = ComponentDefaults.DefaultElevation)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.padding(horizontal = 16.dp)
) { ) {
Icon( Icon(
imageVector = AppIcons.Add, imageVector = AppIcons.Add,
contentDescription = stringResource(R.string.cd_toggle_menu) contentDescription = stringResource(R.string.cd_toggle_menu),
modifier = Modifier.rotate(iconRotationAngle)
) )
if (title != null) {
Text(
text = title,
style = MaterialTheme.typography.labelLarge
)
}
}
} }
} }
} }

View File

@@ -48,7 +48,7 @@ fun VocabularyMenu(
) )
) )
AppFabMenu(items = menuItems, modifier = modifier) AppFabMenu(items = menuItems, modifier = modifier, title = stringResource(R.string.label_add_vocabulary))
if (showAddVocabularyDialog) { if (showAddVocabularyDialog) {
AddVocabularyDialog( AddVocabularyDialog(

View File

@@ -382,7 +382,7 @@ fun MainVocabularyScreen(
var menuHeightPx by remember { mutableIntStateOf(0) } var menuHeightPx by remember { mutableIntStateOf(0) }
val density = LocalDensity.current val density = LocalDensity.current
val menuHeightDp = (menuHeightPx / density.density).dp val menuHeightDp = (menuHeightPx / density.density).dp
val animatedBottomPadding by animateDpAsState(targetValue = 16.dp + 8.dp + menuHeightDp, label = "fabBottomPadding") val animatedBottomPadding by animateDpAsState(targetValue = 16.dp + 8.dp + menuHeightDp, label = "FBottomPadding")
Column( Column(
modifier = Modifier modifier = Modifier
@@ -401,11 +401,21 @@ fun MainVocabularyScreen(
modifier = Modifier modifier = Modifier
.align(Alignment.BottomEnd) .align(Alignment.BottomEnd)
.padding(end = 16.dp, bottom = animatedBottomPadding) .padding(end = 16.dp, bottom = animatedBottomPadding)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.padding(horizontal = 16.dp)
) { ) {
Icon( Icon(
imageVector = AppIcons.Quiz, imageVector = AppIcons.Quiz,
contentDescription = stringResource(R.string.cd_start_exercise) contentDescription = null
) )
Text(
text = stringResource(R.string.label_start_exercise),
style = MaterialTheme.typography.labelLarge
)
}
} }
} }
} }

View File

@@ -33,7 +33,6 @@
<string name="title_single">Einzeln</string> <string name="title_single">Einzeln</string>
<string name="title_widget_streak">Streak</string> <string name="title_widget_streak">Streak</string>
<string name="label_all_vocabulary">Alle Vokabeln</string> <string name="label_all_vocabulary">Alle Vokabeln</string>
<string name="title_widget_category_progress">Kategoriefortschritt</string>
<string name="title_widget_due_today">Heute fällig</string> <string name="title_widget_due_today">Heute fällig</string>
<string name="title_show_success_message">Erfolgsmeldung anzeigen</string> <string name="title_show_success_message">Erfolgsmeldung anzeigen</string>
<string name="label_add_category">Kategorie hinzufügen</string> <string name="label_add_category">Kategorie hinzufügen</string>

View File

@@ -33,7 +33,6 @@
<string name="title_single">Único</string> <string name="title_single">Único</string>
<string name="title_widget_streak">Sequência</string> <string name="title_widget_streak">Sequência</string>
<string name="label_all_vocabulary">Todo o Vocabulário</string> <string name="label_all_vocabulary">Todo o Vocabulário</string>
<string name="title_widget_category_progress">Progresso da Categoria</string>
<string name="title_widget_due_today">Para Hoje</string> <string name="title_widget_due_today">Para Hoje</string>
<string name="title_show_success_message">Mostrar Mensagem de Sucesso</string> <string name="title_show_success_message">Mostrar Mensagem de Sucesso</string>
<string name="label_add_category">Adicionar Categoria</string> <string name="label_add_category">Adicionar Categoria</string>

View File

@@ -986,7 +986,6 @@
<string name="title_show_success_message">Show Success Message</string> <string name="title_show_success_message">Show Success Message</string>
<string name="title_single">Single</string> <string name="title_single">Single</string>
<string name="title_title_preview_title">Preview Title</string> <string name="title_title_preview_title">Preview Title</string>
<string name="title_widget_category_progress">Category Progress</string>
<string name="title_widget_due_today">Due Today</string> <string name="title_widget_due_today">Due Today</string>
<string name="title_widget_streak">Streak</string> <string name="title_widget_streak">Streak</string>