Skip to content

feat: add dedicated Notifications settings page with frequency slider#4247

Merged
kodjima33 merged 1 commit intomainfrom
feat/notifications-settings-page
Jan 16, 2026
Merged

feat: add dedicated Notifications settings page with frequency slider#4247
kodjima33 merged 1 commit intomainfrom
feat/notifications-settings-page

Conversation

@kodjima33
Copy link
Copy Markdown
Collaborator

Changes

  • Add NotificationsSettingsPage combining Daily Summary, Daily Reflection, and Notification Frequency settings
  • Move Notifications to main Settings drawer (after Profile)
  • Remove Daily Summary from Profile page (now consolidated in Notifications page)
  • Add 0-5 Notification Frequency slider to control proactive notification frequency
  • Add notifications section to desktop settings modal with same functionality
  • Comment out 'Wrapped 2025' option from settings drawer

⚠️ WARNING

This PR is NOT fully tested and can be reverted if issues are found.

The notification frequency slider currently only saves the preference locally. Backend integration for using this frequency value in notification scheduling is pending.

- Add NotificationsSettingsPage combining Daily Summary, Daily Reflection, and Notification Frequency settings
- Move Notifications to main Settings drawer (after Profile)
- Remove Daily Summary from Profile page (now consolidated in Notifications page)
- Add 0-5 Notification Frequency slider to control proactive notification frequency
- Add notifications section to desktop settings modal with same functionality
- Comment out 'Wrapped 2025' option from settings drawer

⚠️ NOT FULLY TESTED - Can be reverted if issues are found
@kodjima33 kodjima33 merged commit 2a57b55 into main Jan 16, 2026
1 check passed
@kodjima33 kodjima33 deleted the feat/notifications-settings-page branch January 16, 2026 09:30
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new dedicated "Notifications" settings page, consolidating daily summary, daily reflection, and a new notification frequency control. The changes are well-structured, moving notification-related settings to a more logical place and enhancing user control over notifications. The implementation on both mobile and desktop looks consistent.

My review focuses on improving code robustness and maintainability, particularly around asynchronous operations in Flutter widgets. I've suggested a couple of refactorings to prevent potential issues with widget lifecycle and to improve code clarity.

Comment on lines 164 to 183
Future<void> _loadDailySummarySettings() async {
final settings = await getDailySummarySettings();
final reflectionEnabled = SharedPreferencesUtil().dailyReflectionEnabled;
final frequency = SharedPreferencesUtil().notificationFrequency;
if (settings != null && mounted) {
setState(() {
_dailySummaryEnabled = settings.enabled;
_dailySummaryHour = settings.hour;
_dailyReflectionEnabled = reflectionEnabled;
_notificationFrequency = frequency;
_dailySummaryLoading = false;
});
} else if (mounted) {
setState(() => _dailySummaryLoading = false);
setState(() {
_dailyReflectionEnabled = reflectionEnabled;
_notificationFrequency = frequency;
_dailySummaryLoading = false;
});
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The _loadDailySummarySettings method contains duplicated code in the if and else if blocks for setting state. This can lead to maintenance issues where one block is updated but the other is forgotten. Additionally, the mounted check should ideally be performed immediately after an await call to avoid further processing if the widget has been disposed. Refactoring this method will improve its readability and robustness.

  Future<void> _loadDailySummarySettings() async {
    final settings = await getDailySummarySettings();
    if (!mounted) return;

    final reflectionEnabled = SharedPreferencesUtil().dailyReflectionEnabled;
    final frequency = SharedPreferencesUtil().notificationFrequency;
    setState(() {
      if (settings != null) {
        _dailySummaryEnabled = settings.enabled;
        _dailySummaryHour = settings.hour;
      }
      _dailyReflectionEnabled = reflectionEnabled;
      _notificationFrequency = frequency;
      _dailySummaryLoading = false;
    });
  }

Comment on lines +38 to +57
Future<void> _loadSettings() async {
// Load Daily Summary settings from API
final settings = await getDailySummarySettings();

// Load settings from local prefs
final reflectionEnabled = SharedPreferencesUtil().dailyReflectionEnabled;
final frequency = SharedPreferencesUtil().notificationFrequency;

if (mounted) {
setState(() {
if (settings != null) {
_dailySummaryEnabled = settings.enabled;
_dailySummaryHour = settings.hour;
}
_dailyReflectionEnabled = reflectionEnabled;
_notificationFrequency = frequency;
_isLoading = false;
});
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

To prevent potential 'setState() called after dispose()' errors, it's a best practice to check if (mounted) immediately after an await call before executing any further logic that depends on the widget's state. In _loadSettings, the mounted check is performed after synchronous calls to SharedPreferencesUtil, which could be avoided if the widget is no longer in the tree.

Suggested change
Future<void> _loadSettings() async {
// Load Daily Summary settings from API
final settings = await getDailySummarySettings();
// Load settings from local prefs
final reflectionEnabled = SharedPreferencesUtil().dailyReflectionEnabled;
final frequency = SharedPreferencesUtil().notificationFrequency;
if (mounted) {
setState(() {
if (settings != null) {
_dailySummaryEnabled = settings.enabled;
_dailySummaryHour = settings.hour;
}
_dailyReflectionEnabled = reflectionEnabled;
_notificationFrequency = frequency;
_isLoading = false;
});
}
}
Future<void> _loadSettings() async {
// Load Daily Summary settings from API
final settings = await getDailySummarySettings();
if (!mounted) return;
// Load settings from local prefs
final reflectionEnabled = SharedPreferencesUtil().dailyReflectionEnabled;
final frequency = SharedPreferencesUtil().notificationFrequency;
setState(() {
if (settings != null) {
_dailySummaryEnabled = settings.enabled;
_dailySummaryHour = settings.hour;
}
_dailyReflectionEnabled = reflectionEnabled;
_notificationFrequency = frequency;
_isLoading = false;
});
}

Glucksberg pushed a commit to Glucksberg/omi-local that referenced this pull request Apr 28, 2026
…BasedHardware#4247)

## Changes
- Add `NotificationsSettingsPage` combining Daily Summary, Daily
Reflection, and Notification Frequency settings
- Move Notifications to main Settings drawer (after Profile)
- Remove Daily Summary from Profile page (now consolidated in
Notifications page)
- Add 0-5 Notification Frequency slider to control proactive
notification frequency
- Add notifications section to desktop settings modal with same
functionality
- Comment out 'Wrapped 2025' option from settings drawer

## ⚠️ WARNING
**This PR is NOT fully tested and can be reverted if issues are found.**

The notification frequency slider currently only saves the preference
locally. Backend integration for using this frequency value in
notification scheduling is pending.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant