diff --git a/app/src/main/java/com/scarriffle/calendarr/ui/calendar/CalendarScreen.kt b/app/src/main/java/com/scarriffle/calendarr/ui/calendar/CalendarScreen.kt index 797e527..4e930f1 100644 --- a/app/src/main/java/com/scarriffle/calendarr/ui/calendar/CalendarScreen.kt +++ b/app/src/main/java/com/scarriffle/calendarr/ui/calendar/CalendarScreen.kt @@ -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, 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) }, ) } diff --git a/app/src/main/java/com/scarriffle/calendarr/ui/groups/GroupsScreen.kt b/app/src/main/java/com/scarriffle/calendarr/ui/groups/GroupsScreen.kt index 69f2c99..75b9c33 100644 --- a/app/src/main/java/com/scarriffle/calendarr/ui/groups/GroupsScreen.kt +++ b/app/src/main/java/com/scarriffle/calendarr/ui/groups/GroupsScreen.kt @@ -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() } diff --git a/app/src/main/java/com/scarriffle/calendarr/ui/menu/MenuSheet.kt b/app/src/main/java/com/scarriffle/calendarr/ui/menu/MenuSheet.kt index 20f6f16..a95b242 100644 --- a/app/src/main/java/com/scarriffle/calendarr/ui/menu/MenuSheet.kt +++ b/app/src/main/java/com/scarriffle/calendarr/ui/menu/MenuSheet.kt @@ -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,