fix: Android Gruppen-Umschalter sichtbar + Menü überlappt Navigationsleiste nicht
Top-Bar-Gruppenumschalter ist jetzt eine tonale Pille (Akzentfarbe im Gruppenmodus) statt eines flachen Icons – klar als Button erkennbar; das Dropdown markiert die aktive Auswahl. Gruppen-Verwaltung: Tipp auf eine Gruppe öffnet direkt deren Ansicht, Verwalten liegt aufs Zahnrad. Menü-Bottom-Sheet respektiert jetzt das Navigationsleisten-Inset (+ Scroll-Fallback), sodass Abmelden/Server wechseln nicht mehr hinter den Android-Buttons liegen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,8 @@ import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
@@ -16,6 +18,7 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.ChevronLeft
|
||||
import androidx.compose.material.icons.filled.ChevronRight
|
||||
import androidx.compose.material.icons.filled.FilterList
|
||||
@@ -36,6 +39,7 @@ import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -45,6 +49,7 @@ 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.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
@@ -243,6 +248,7 @@ fun CalendarScreen(
|
||||
Overlay.GROUPS -> GroupsScreen(
|
||||
onClose = { overlay = Overlay.NONE },
|
||||
onChanged = { vm.loadGroups(); vm.loadWritableCalendars() },
|
||||
onOpenGroupView = { g -> overlay = Overlay.NONE; vm.switchGroup(g) },
|
||||
)
|
||||
Overlay.NONE -> Unit
|
||||
}
|
||||
@@ -380,27 +386,42 @@ private fun CompactIcon(
|
||||
}
|
||||
}
|
||||
|
||||
/** Top-bar switcher: "My calendar" + each group; flips the calendar into the group overlay. */
|
||||
/**
|
||||
* Top-bar switcher: "My calendar" + each group; flips the calendar into the
|
||||
* group overlay. Rendered as a tonal pill so it stands out from the flat icons
|
||||
* (filled in the accent colour while a group overlay is active).
|
||||
*/
|
||||
@Composable
|
||||
private fun GroupSwitcher(groups: List<Group>, activeGroup: Group?, onSwitchGroup: (Group?) -> Unit) {
|
||||
var open by remember { mutableStateOf(false) }
|
||||
val active = activeGroup != null
|
||||
Box {
|
||||
IconButton(onClick = { open = true }, modifier = Modifier.size(40.dp)) {
|
||||
Box(
|
||||
Modifier
|
||||
.padding(horizontal = 2.dp)
|
||||
.size(38.dp)
|
||||
.clip(CircleShape)
|
||||
.background(if (active) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surfaceVariant)
|
||||
.clickable { open = true },
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Icon(
|
||||
Icons.Filled.People,
|
||||
contentDescription = tr("groups.title"),
|
||||
modifier = Modifier.size(22.dp),
|
||||
tint = if (activeGroup != null) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface,
|
||||
modifier = Modifier.size(21.dp),
|
||||
tint = if (active) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
DropdownMenu(expanded = open, onDismissRequest = { open = false }) {
|
||||
DropdownMenuItem(
|
||||
text = { Text(tr("group.switch.personal")) },
|
||||
trailingIcon = { if (!active) Icon(Icons.Filled.Check, contentDescription = null) },
|
||||
onClick = { open = false; onSwitchGroup(null) },
|
||||
)
|
||||
groups.forEach { g ->
|
||||
DropdownMenuItem(
|
||||
text = { Text("${g.icon ?: "👥"} ${g.name}") },
|
||||
trailingIcon = { if (activeGroup?.id == g.id) Icon(Icons.Filled.Check, contentDescription = null) },
|
||||
onClick = { open = false; onSwitchGroup(g) },
|
||||
)
|
||||
}
|
||||
|
||||
@@ -21,8 +21,10 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.ChevronRight
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Tune
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Checkbox
|
||||
@@ -66,6 +68,7 @@ private val GROUP_ICONS = listOf(
|
||||
fun GroupsScreen(
|
||||
onClose: () -> Unit,
|
||||
onChanged: () -> Unit,
|
||||
onOpenGroupView: (Group) -> Unit = {},
|
||||
vm: GroupsViewModel = hiltViewModel(),
|
||||
) {
|
||||
var createOpen by remember { mutableStateOf(false) }
|
||||
@@ -97,16 +100,22 @@ fun GroupsScreen(
|
||||
}
|
||||
items(vm.groups, key = { it.id }) { g ->
|
||||
Row(
|
||||
Modifier.fillMaxWidth().clickable { manageId = g.id }.padding(vertical = 12.dp),
|
||||
Modifier.fillMaxWidth().clickable { onOpenGroupView(g) }.padding(vertical = 10.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(g.icon ?: "👥", style = MaterialTheme.typography.titleMedium)
|
||||
Text(g.name, modifier = Modifier.weight(1f).padding(start = 12.dp), style = MaterialTheme.typography.bodyLarge)
|
||||
Text(
|
||||
tr("groups.member_count", g.memberCount),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
Column(Modifier.weight(1f).padding(start = 12.dp)) {
|
||||
Text(g.name, style = MaterialTheme.typography.bodyLarge)
|
||||
Text(
|
||||
tr("groups.member_count", g.memberCount),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
IconButton(onClick = { manageId = g.id }) {
|
||||
Icon(Icons.Filled.Tune, contentDescription = tr("groups.manage"), tint = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||
}
|
||||
Icon(Icons.Filled.ChevronRight, contentDescription = tr("groups.view"), tint = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||
}
|
||||
Divider()
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.AccountCircle
|
||||
import androidx.compose.material.icons.filled.Dns
|
||||
@@ -44,7 +47,14 @@ fun MenuSheet(
|
||||
onSwitchServer: () -> Unit,
|
||||
) {
|
||||
ModalBottomSheet(onDismissRequest = onDismiss) {
|
||||
Column(Modifier.fillMaxWidth().padding(bottom = 24.dp)) {
|
||||
// Inset for the system navigation bar so the last rows aren't hidden
|
||||
// behind the Android nav buttons; scroll as a fallback on short screens.
|
||||
Column(
|
||||
Modifier.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.navigationBarsPadding()
|
||||
.padding(bottom = 12.dp),
|
||||
) {
|
||||
Text(
|
||||
"Calendarr",
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
|
||||
Reference in New Issue
Block a user