docs(04-02): complete notification settings UI plan
This commit is contained in:
146
.planning/phases/04-notifications/04-02-SUMMARY.md
Normal file
146
.planning/phases/04-notifications/04-02-SUMMARY.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
phase: 04-notifications
|
||||
plan: 02
|
||||
subsystem: ui
|
||||
tags: [flutter, riverpod, flutter_local_notifications, settings, permissions, widget-tests]
|
||||
|
||||
# Dependency graph
|
||||
requires:
|
||||
- phase: 04-notifications/04-01
|
||||
provides: NotificationService singleton, NotificationSettingsNotifier, DailyPlanDao task count queries, ARB strings
|
||||
- phase: 01-foundation
|
||||
provides: themeProvider pattern, ProviderScope test pattern
|
||||
|
||||
provides:
|
||||
- SettingsScreen with Benachrichtigungen section (SwitchListTile + AnimatedSize time picker)
|
||||
- Permission flow: request on toggle ON, revert on denial with SnackBar hint
|
||||
- Notification scheduling with task/overdue counts from DailyPlanDao
|
||||
- Notification tap navigation via router.go('/') in NotificationService._onTap
|
||||
- Widget tests for notification settings UI states
|
||||
|
||||
affects: [end-to-end notification flow complete]
|
||||
|
||||
# Tech tracking
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns:
|
||||
- ConsumerStatefulWidget for screens requiring async callbacks with BuildContext
|
||||
- AnimatedSize for progressive disclosure of conditional UI sections
|
||||
- overrideWithValue for Riverpod provider isolation in widget tests
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- test/features/settings/settings_screen_test.dart
|
||||
modified:
|
||||
- lib/features/settings/presentation/settings_screen.dart
|
||||
- lib/core/notifications/notification_service.dart
|
||||
- lib/l10n/app_localizations.dart
|
||||
- lib/l10n/app_localizations_de.dart
|
||||
|
||||
key-decisions:
|
||||
- "openNotificationSettings() not available in flutter_local_notifications v21 — simplified SnackBar to informational only (no action button)"
|
||||
- "ConsumerStatefulWidget chosen over ConsumerWidget for async callback isolation and mounted checks"
|
||||
- "notificationSettingsProvider (Riverpod 3 name, not notificationSettingsNotifierProvider) used throughout"
|
||||
|
||||
patterns-established:
|
||||
- "ConsumerStatefulWidget pattern: async permission/scheduling callbacks use mounted guards after every await"
|
||||
- "TDD with pre-existing implementation: write tests to document expected behavior, verify pass, commit as feat (not separate test/feat commits)"
|
||||
|
||||
requirements-completed: [NOTF-01, NOTF-02]
|
||||
|
||||
# Metrics
|
||||
duration: 5min
|
||||
completed: 2026-03-16
|
||||
---
|
||||
|
||||
# Phase 4 Plan 2: Notification Settings UI Summary
|
||||
|
||||
**ConsumerStatefulWidget SettingsScreen with Benachrichtigungen section, Android permission flow, DailyPlanDao-driven scheduling, notification tap navigation, and 5 widget tests**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** 5 min
|
||||
- **Started:** 2026-03-16T14:02:25Z
|
||||
- **Completed:** 2026-03-16T14:07:58Z
|
||||
- **Tasks:** 2
|
||||
- **Files modified:** 5
|
||||
|
||||
## Accomplishments
|
||||
- SettingsScreen rewritten as ConsumerStatefulWidget with Benachrichtigungen section inserted between Darstellung and Uber
|
||||
- SwitchListTile with permission request on toggle ON: `requestNotificationsPermission()` called before state update; toggle stays OFF on denial with SnackBar
|
||||
- AnimatedSize progressive disclosure: time picker row only appears when `notificationSettings.enabled` is true
|
||||
- `_scheduleNotification()` queries DailyPlanDao for total/overdue counts; skips scheduling when total==0; builds conditional body with overdue split when overdue > 0
|
||||
- `_onPickTime()` opens Material 3 showTimePicker dialog and reschedules on selection
|
||||
- `NotificationService._onTap` wired to `router.go('/')` for notification tap navigation to Home tab
|
||||
- AppLocalizations regenerated with 7 notification strings from Plan 01 ARB file
|
||||
- 5 new widget tests: section header, toggle default OFF, time picker visible/hidden, formatted time display — all 89 tests pass
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each task was committed atomically:
|
||||
|
||||
1. **Task 1: Settings UI with Benachrichtigungen section, permission flow, and notification scheduling** - `0103dde` (feat)
|
||||
2. **Task 2: Widget tests for notification settings UI** - `77de7cd` (feat)
|
||||
|
||||
**Plan metadata:** (docs commit — see final commit hash below)
|
||||
|
||||
## Files Created/Modified
|
||||
- `lib/features/settings/presentation/settings_screen.dart` - ConsumerStatefulWidget with Benachrichtigungen section, permission flow, scheduling, and time picker
|
||||
- `lib/core/notifications/notification_service.dart` - Added router import and `router.go('/')` in `_onTap`
|
||||
- `lib/l10n/app_localizations.dart` - Regenerated abstract class with 7 new notification string declarations
|
||||
- `lib/l10n/app_localizations_de.dart` - Regenerated German implementations for 7 new notification strings
|
||||
- `test/features/settings/settings_screen_test.dart` - 5 widget tests covering notification UI states
|
||||
|
||||
## Decisions Made
|
||||
- **openNotificationSettings() unavailable**: `AndroidFlutterLocalNotificationsPlugin` in v21.0.0 does not expose `openNotificationSettings()`. Simplified to informational SnackBar without action button. The ARB hint text already guides users to system settings manually.
|
||||
- **ConsumerStatefulWidget**: Chosen over ConsumerWidget because `_onNotificationToggle` and `_scheduleNotification` are async and require `mounted` checks after each `await` — this is only safe in `State`.
|
||||
- **notificationSettingsProvider naming**: Used `notificationSettingsProvider` (Riverpod 3 convention established in Plan 01), not `notificationSettingsNotifierProvider` as referenced in the plan interfaces section.
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. [Rule 1 - Bug] openNotificationSettings() does not exist on AndroidFlutterLocalNotificationsPlugin v21**
|
||||
- **Found during:** Task 1 (dart analyze after implementation)
|
||||
- **Issue:** Plan specified using `androidPlugin?.openNotificationSettings()` in the SnackBar action, but this method does not exist in flutter_local_notifications v21.0.0
|
||||
- **Fix:** Removed the action button from the SnackBar — simplified to an informational SnackBar showing `notificationsPermissionDeniedHint` text only. The plan explicitly offered "Pick the simpler approach: SnackBar with hint text" as an option.
|
||||
- **Files modified:** lib/features/settings/presentation/settings_screen.dart
|
||||
- **Verification:** dart analyze clean, no errors
|
||||
- **Committed in:** 0103dde
|
||||
|
||||
**2. [Rule 1 - Bug] AppLocalizations missing notification string getters (stale generated files)**
|
||||
- **Found during:** Task 1 (dart analyze)
|
||||
- **Issue:** `app_localizations.dart` and `app_localizations_de.dart` were not updated after Plan 01 added 7 strings to `app_de.arb`. The generated files were stale.
|
||||
- **Fix:** Ran `flutter gen-l10n` to regenerate localization files from ARB
|
||||
- **Files modified:** lib/l10n/app_localizations.dart, lib/l10n/app_localizations_de.dart
|
||||
- **Verification:** dart analyze clean after regeneration
|
||||
- **Committed in:** 0103dde
|
||||
|
||||
---
|
||||
|
||||
**Total deviations:** 2 auto-fixed (2 bugs — API mismatch and stale generated files)
|
||||
**Impact on plan:** Both auto-fixes were necessary. The SnackBar simplification is explicitly offered as the preferred option in the plan. The localization regeneration is a missing step from Plan 01 that Plan 02 needed.
|
||||
|
||||
## Issues Encountered
|
||||
- flutter_local_notifications v21 API surface for `AndroidFlutterLocalNotificationsPlugin` does not include `openNotificationSettings()` — the plan referenced a method that was either added later or never existed in this version. Simplified to informational SnackBar per plan's own "simpler approach" option.
|
||||
|
||||
## User Setup Required
|
||||
None — no external service configuration required.
|
||||
|
||||
## Next Phase Readiness
|
||||
- Phase 4 (Notifications) is fully complete: infrastructure (Plan 01) + Settings UI (Plan 02)
|
||||
- All 89 tests passing, dart analyze clean
|
||||
- Notification feature end-to-end: toggle ON/OFF, permission request, time picker, daily scheduling, tap navigation to Home
|
||||
|
||||
---
|
||||
*Phase: 04-notifications*
|
||||
*Completed: 2026-03-16*
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
- lib/features/settings/presentation/settings_screen.dart: FOUND
|
||||
- lib/core/notifications/notification_service.dart: FOUND
|
||||
- test/features/settings/settings_screen_test.dart: FOUND
|
||||
- .planning/phases/04-notifications/04-02-SUMMARY.md: FOUND
|
||||
- commit 0103dde: FOUND
|
||||
- commit 77de7cd: FOUND
|
||||
Reference in New Issue
Block a user