feat(drawer): add View section to switch Month/Week/Day
The slide-out panel gains a "View" section mirroring the top-bar switcher pill: three NavigationDrawerItems (Month/Week/Day) with the current view highlighted; tapping one selects that view and closes the drawer. The pill stays as-is for quick cycling. Centralise each view's label + icon as labelRes/icon extensions on CalendarView so the pill and the drawer share one mapping. The drawer's "Today" jump is dropped — the top-bar Today action and error-state retry still cover it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- The slide-out panel now has a "View" section to switch between Month,
|
||||||
|
Week, and Day, mirroring the top-bar switcher pill — tapping a view
|
||||||
|
selects it and closes the drawer. The current view is highlighted
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Typing in the event title, location, and description fields no longer
|
- Typing in the event title, location, and description fields no longer
|
||||||
makes the cursor jump around: the form state's round-trip to the UI was
|
makes the cursor jump around: the form state's round-trip to the UI was
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.height
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Settings
|
import androidx.compose.material.icons.filled.Settings
|
||||||
import androidx.compose.material.icons.filled.Today
|
|
||||||
import androidx.compose.material3.HorizontalDivider
|
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
|
||||||
@@ -27,16 +26,19 @@ import de.jeanlucmakiola.calendula.ui.filter.CalendarFilterList
|
|||||||
* Visual language (kept deliberately small so sizes don't drift):
|
* Visual language (kept deliberately small so sizes don't drift):
|
||||||
* - Drawer title — `titleLarge`
|
* - Drawer title — `titleLarge`
|
||||||
* - Section headers (e.g. "Calendars") — `titleSmall`, primary, text only
|
* - Section headers (e.g. "Calendars") — `titleSmall`, primary, text only
|
||||||
* - Nav items (Today / Settings) — Material `NavigationDrawerItem`
|
* - Nav items (the views, Today / Settings) — Material `NavigationDrawerItem`
|
||||||
* (`labelLarge` label + a single 24dp leading icon)
|
* (`labelLarge` label + a single 24dp leading icon)
|
||||||
*
|
*
|
||||||
* Hosts the per-calendar visibility filter (M3) inline — the calendar list with
|
* The "View" section mirrors the top-bar switcher pill: tapping a view here
|
||||||
* its checkboxes lives here rather than in a separate sheet — plus the "today"
|
* selects it (and closes the drawer) rather than cycling. Also hosts the
|
||||||
* jump and a Settings entry (M4). The host screen owns the drawer state.
|
* per-calendar visibility filter (M3) inline — the calendar list with its
|
||||||
|
* checkboxes lives here rather than in a separate sheet — plus a Settings
|
||||||
|
* entry (M4). The host screen owns the drawer state.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CalendarDrawer(
|
fun CalendarDrawer(
|
||||||
onToday: () -> Unit,
|
currentView: CalendarView,
|
||||||
|
onSelectView: (CalendarView) -> Unit,
|
||||||
onSettings: () -> Unit,
|
onSettings: () -> Unit,
|
||||||
) {
|
) {
|
||||||
ModalDrawerSheet {
|
ModalDrawerSheet {
|
||||||
@@ -47,14 +49,17 @@ fun CalendarDrawer(
|
|||||||
modifier = Modifier.padding(horizontal = 28.dp, vertical = 24.dp),
|
modifier = Modifier.padding(horizontal = 28.dp, vertical = 24.dp),
|
||||||
)
|
)
|
||||||
HorizontalDivider()
|
HorizontalDivider()
|
||||||
Spacer(Modifier.height(8.dp))
|
|
||||||
|
DrawerSectionHeader(stringResource(R.string.view_section))
|
||||||
|
IMPLEMENTED_VIEWS.forEach { view ->
|
||||||
NavigationDrawerItem(
|
NavigationDrawerItem(
|
||||||
icon = { Icon(Icons.Filled.Today, contentDescription = null) },
|
icon = { Icon(view.icon, contentDescription = null) },
|
||||||
label = { Text(stringResource(R.string.month_today_action)) },
|
label = { Text(stringResource(view.labelRes)) },
|
||||||
selected = false,
|
selected = view == currentView,
|
||||||
onClick = onToday,
|
onClick = { onSelectView(view) },
|
||||||
modifier = Modifier.padding(horizontal = 12.dp),
|
modifier = Modifier.padding(horizontal = 12.dp),
|
||||||
)
|
)
|
||||||
|
}
|
||||||
Spacer(Modifier.height(8.dp))
|
Spacer(Modifier.height(8.dp))
|
||||||
HorizontalDivider()
|
HorizontalDivider()
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
package de.jeanlucmakiola.calendula.ui.common
|
package de.jeanlucmakiola.calendula.ui.common
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.CalendarViewDay
|
||||||
|
import androidx.compose.material.icons.filled.CalendarViewMonth
|
||||||
|
import androidx.compose.material.icons.filled.CalendarViewWeek
|
||||||
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
import de.jeanlucmakiola.calendula.R
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The top-level calendar views the user can switch between (spec M1).
|
* The top-level calendar views the user can switch between (spec M1).
|
||||||
* Day is declared but not yet implemented (v0.5) — see [IMPLEMENTED_VIEWS].
|
* Day is declared but not yet implemented (v0.5) — see [IMPLEMENTED_VIEWS].
|
||||||
@@ -10,6 +18,23 @@ enum class CalendarView {
|
|||||||
Day,
|
Day,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Switcher label, shared by the top-bar pill and the drawer's View section. */
|
||||||
|
@get:StringRes
|
||||||
|
val CalendarView.labelRes: Int
|
||||||
|
get() = when (this) {
|
||||||
|
CalendarView.Month -> R.string.view_month
|
||||||
|
CalendarView.Week -> R.string.view_week
|
||||||
|
CalendarView.Day -> R.string.view_day
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Leading icon for the view in the drawer's View section. */
|
||||||
|
val CalendarView.icon: ImageVector
|
||||||
|
get() = when (this) {
|
||||||
|
CalendarView.Month -> Icons.Filled.CalendarViewMonth
|
||||||
|
CalendarView.Week -> Icons.Filled.CalendarViewWeek
|
||||||
|
CalendarView.Day -> Icons.Filled.CalendarViewDay
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Views that actually have a screen today. The view-switcher pill cycles
|
* Views that actually have a screen today. The view-switcher pill cycles
|
||||||
* through these in order.
|
* through these in order.
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import de.jeanlucmakiola.calendula.R
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Top-bar pill that shows the current view and cycles to the next one on tap
|
* Top-bar pill that shows the current view and cycles to the next one on tap
|
||||||
@@ -18,16 +17,11 @@ fun ViewSwitcherPill(
|
|||||||
onCycle: () -> Unit,
|
onCycle: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val labelRes = when (current) {
|
|
||||||
CalendarView.Month -> R.string.view_month
|
|
||||||
CalendarView.Week -> R.string.view_week
|
|
||||||
CalendarView.Day -> R.string.view_day
|
|
||||||
}
|
|
||||||
FilledTonalButton(
|
FilledTonalButton(
|
||||||
onClick = onCycle,
|
onClick = onCycle,
|
||||||
shape = MaterialTheme.shapes.large,
|
shape = MaterialTheme.shapes.large,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
) {
|
) {
|
||||||
Text(stringResource(labelRes))
|
Text(stringResource(current.labelRes))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,7 +157,11 @@ fun DayScreen(
|
|||||||
gesturesEnabled = drawerState.isOpen,
|
gesturesEnabled = drawerState.isOpen,
|
||||||
drawerContent = {
|
drawerContent = {
|
||||||
CalendarDrawer(
|
CalendarDrawer(
|
||||||
onToday = { jumpToToday(); scope.launch { drawerState.close() } },
|
currentView = selectedView,
|
||||||
|
onSelectView = { view ->
|
||||||
|
onSelectView(view)
|
||||||
|
scope.launch { drawerState.close() }
|
||||||
|
},
|
||||||
onSettings = {
|
onSettings = {
|
||||||
onOpenSettings()
|
onOpenSettings()
|
||||||
scope.launch { drawerState.close() }
|
scope.launch { drawerState.close() }
|
||||||
|
|||||||
@@ -130,8 +130,9 @@ fun MonthScreen(
|
|||||||
gesturesEnabled = drawerState.isOpen,
|
gesturesEnabled = drawerState.isOpen,
|
||||||
drawerContent = {
|
drawerContent = {
|
||||||
CalendarDrawer(
|
CalendarDrawer(
|
||||||
onToday = {
|
currentView = selectedView,
|
||||||
jumpToToday()
|
onSelectView = { view ->
|
||||||
|
onSelectView(view)
|
||||||
scope.launch { drawerState.close() }
|
scope.launch { drawerState.close() }
|
||||||
},
|
},
|
||||||
onSettings = {
|
onSettings = {
|
||||||
|
|||||||
@@ -162,7 +162,11 @@ fun WeekScreen(
|
|||||||
gesturesEnabled = drawerState.isOpen,
|
gesturesEnabled = drawerState.isOpen,
|
||||||
drawerContent = {
|
drawerContent = {
|
||||||
CalendarDrawer(
|
CalendarDrawer(
|
||||||
onToday = { jumpToToday(); scope.launch { drawerState.close() } },
|
currentView = selectedView,
|
||||||
|
onSelectView = { view ->
|
||||||
|
onSelectView(view)
|
||||||
|
scope.launch { drawerState.close() }
|
||||||
|
},
|
||||||
onSettings = {
|
onSettings = {
|
||||||
onOpenSettings()
|
onOpenSettings()
|
||||||
scope.launch { drawerState.close() }
|
scope.launch { drawerState.close() }
|
||||||
|
|||||||
@@ -187,6 +187,7 @@
|
|||||||
<string name="view_month">Monat</string>
|
<string name="view_month">Monat</string>
|
||||||
<string name="view_week">Woche</string>
|
<string name="view_week">Woche</string>
|
||||||
<string name="view_day">Tag</string>
|
<string name="view_day">Tag</string>
|
||||||
|
<string name="view_section">Ansicht</string>
|
||||||
|
|
||||||
<!-- Kalender-Filter (M3) -->
|
<!-- Kalender-Filter (M3) -->
|
||||||
<string name="filter_title">Kalender</string>
|
<string name="filter_title">Kalender</string>
|
||||||
|
|||||||
@@ -188,6 +188,7 @@
|
|||||||
<string name="view_month">Month</string>
|
<string name="view_month">Month</string>
|
||||||
<string name="view_week">Week</string>
|
<string name="view_week">Week</string>
|
||||||
<string name="view_day">Day</string>
|
<string name="view_day">Day</string>
|
||||||
|
<string name="view_section">View</string>
|
||||||
|
|
||||||
<!-- Calendar filter (M3) -->
|
<!-- Calendar filter (M3) -->
|
||||||
<string name="filter_title">Calendars</string>
|
<string name="filter_title">Calendars</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user