Skip to content

Conversation

@ericli3690
Copy link
Member

@ericli3690 ericli3690 commented Aug 21, 2025

If you're not receiving notifications, ensure you've granted notification permissions and that power saver mode is not on.

Blocked by dependency Currently blocked by some other dependent / related change :

Purpose / Description

  • Modifies ScheduleReminders so that it sets alarms for review reminders via AlarmManagerService.

Fixes

  • GSoC 2025: Review Reminders

How Has This Been Tested?

  • Works on a physical Samsung S23, API 34.
  • I can set and receive review reminders! They recur after a day, can be snoozed, etc. More alpha testing is likely necessary.

Checklist

  • You have a descriptive commit message with a short title (first line, max 50 chars).
  • You have commented your code, particularly in hard-to-understand areas
  • You have performed a self-review of your own code

@github-actions
Copy link
Contributor

Important

Maintainers: This PR contains Strings changes

  1. Sync Translations before merging this PR and wait for the action to complete
  2. Review and merge the auto-generated PR in order to sync all user-submitted translations
  3. Sync Translations again and merge the PR so the huge automated string changes caused by merging this PR are by themselves and easy to review

@ericli3690 ericli3690 added Needs Review Blocked by dependency Currently blocked by some other dependent / related change GSoC Pull requests authored by a Google Summer of Code participant [Candidate/Selected], for GSoC mentors and removed Strings labels Aug 21, 2025
@ericli3690 ericli3690 force-pushed the ericli3690-review-reminders-integrated-firing branch from 86d5775 to b42953f Compare August 27, 2025 02:05
@ericli3690 ericli3690 force-pushed the ericli3690-review-reminders-integrated-firing branch from b42953f to 67f2773 Compare August 28, 2025 07:15
@ericli3690
Copy link
Member Author

Rebased on top of #19109.

@ericli3690 ericli3690 force-pushed the ericli3690-review-reminders-integrated-firing branch from 67f2773 to 2ff606f Compare August 28, 2025 18:17
@ericli3690
Copy link
Member Author

Resolved merge conflict.

@ericli3690 ericli3690 force-pushed the ericli3690-review-reminders-integrated-firing branch from 2ff606f to 7f9325a Compare August 29, 2025 00:29
@ericli3690
Copy link
Member Author

Rebased on top of #19118.

@ericli3690 ericli3690 force-pushed the ericli3690-review-reminders-integrated-firing branch from 7f9325a to 2ddcb22 Compare September 5, 2025 21:42
@ericli3690 ericli3690 marked this pull request as draft September 5, 2025 21:50
@ericli3690 ericli3690 force-pushed the ericli3690-review-reminders-integrated-firing branch 2 times, most recently from f2c9dde to 13fa0af Compare September 6, 2025 05:22
@ericli3690 ericli3690 marked this pull request as ready for review September 6, 2025 05:37
@ericli3690
Copy link
Member Author

  • Rebased.

@ericli3690 ericli3690 force-pushed the ericli3690-review-reminders-integrated-firing branch 3 times, most recently from c4a7852 to 2d3626e Compare September 7, 2025 17:16
@ericli3690
Copy link
Member Author

  • Rebased.

GSoC 2025: Review Reminders

- `initializeScheduleRemindersDeckSpinner` doesn't properly handle what happens if showAllDecks is true. This makes pressing on a deck select the wrong deck. This commit fixes this.
GSoC 2025: Review Reminders

- Added TimePicker styling, used when users edit the time of a review reminder.
GSoC 2025: Review Reminders

- The AddEditReminderDialog displays the current time in the TimePicker when a review reminder is being created. This change adds a utility function to ReviewReminderTime's companion object to calculate this time. I decided to put this function within ReviewReminderTime so it can be accessed by both AddEditReminderDialog and AddEditReminderDialogViewModel.
GSoC 2025: Review Reminders

- XML file for AddEditReminderDialog. Allows time and deck modification. Also has a dropdown for advanced settings, including minimum card trigger threshold (with more advanced settings hopefully coming soon). The advanced settings will be grouped under a dropdown to prevent them from overwhelming users when the dialog initially opens.
GSoC 2025: Review Reminders

- Creates AddEditReminderDialog.
- Adds DialogMode, which represents whether the dialog is in adding or editing mode.
- Created a ViewModel for the AddEditReminderDialog. A specific view model is created because this allows the dialog's state to persist across redraws, ex. if the theme changes, if the device rotates, etc. It also centralizes the data of the review reminder being edited in a single source of truth.
- Sets submit, cancel, and delete actions for the dialog; this is the main way users can delete review reminders. Deletion is locked behind a confirmation box just in case the user accidentally clicks the button.
- Results for the deck picker dropdown in the dialog are received in ScheduleReminders and sent to the AddEditReminderDialog via a FragmentResult. See the docstring of `onDeckSelected` in ScheduleReminders to see why this is done.
- Filling in the values in the dialog fields and setting listeners for when the values change is pulled out into a separate methods for readability.
- Adds `showTimePickerDialog`. Shows a TimePicker dialog for picking review reminder time via modern Material3 guidelines. Overrides `onConfigurationChanged` to properly handle device rotation, which for some reason is not handled by default by MaterialTimePicker.
- An edited review reminder is passed back to ReviewRemindersDatabase as a FragmentResult, which is a simple way of passing information between fragments.
GSoC 2025: Review Reminders

- Adds a fragment result listener to ScheduleReminders to detect when an AddEditReminderDialog has completed, and if so, edits the database and UI accordingly.
- Filled out the `addReminder` and `editReminder` methods to show the AddEditReminderDialog.
GSoC 2025: Review Reminders

- Added logic for checking if a deck exists before returning deck-specific reminders to ReviewRemindersDatabase. This code uses the `decks.have` method, since it seemed like the most straightforward way to accomplish deck-existence-checking.
- `decks.have` was previously marked as "unused". I've removed this annotation.
- Added a deleteAllRemindersForDeck helper method. It's public because it will also be used in NotificationService.
- Had to mark a few database methods as suspending since they use the collection to check if a deck exists. This in turn meant wrapping some of the tests in the test file with `runTest` and marking the database access wrapper in ScheduleReminders with `suspend`. Also had to explicitly create decks using `addDeck` in the test file. Moved the dummy review reminder declarations to setUp to accommodate this.
- Added new tests for deck deletion functionality.
GSoC 2025: Review Reminders

- Added logic for review reminder notifications being sent to the user. Alarms for sending notifications are created by AlarmManagerService, and the actual notifications themselves are fired by NotificationService.
- Moved catchAlarmManagerExceptions method that was previously in BootService to AlarmManagerService to ensure no regressions occur and old bugs are still solved.
- `scheduleReviewReminderNotification` is the primary part of AlarmManagerService, setting the recurring notifications for a review reminder. `unschedule` and `scheduleAll` methods are also provided.
- Snoozing is handled by AlarmManagerService via `scheduleSnoozedNotification`. AlarmManagerService must be a BroadcastReceiver so that it can receive snoozing requests via onReceive from PendingIntents created by NotificationService.
- `sendReviewReminderNotification` in NotificationService does the bulk of the work for sending notifications, filling out content, etc.
- `fireReviewReminderNotification` is a separate method that handles the actual OS call to fire the notification itself.
- Marked old functionality in NotificationService as legacy notification code.
- Had to create a NotificationServiceAction sealed class to mark the kinds of notification requests the NotificationService gets. These different requests must have different actions set, otherwise they collide with each other and interfere. This can cause snoozes to cancel normal notifications, normal notifications to cancel snoozes, etc., hence why we add this sealed class.
- NotificationService must be a BroadcastReceiver because it needs to listen to PendingIntents triggered by AlarmManager alarms, which trigger the onReceive method.
- Added unit tests for AlarmManagerService and NotificationService.
- Added AlarmManagerService as a BroadcastReceiver to the AndroidManifest.xml file.
- Added calls to set review reminder notifications on device boot-up and app start-up to AnkiDroidApp and BootService.
- Renamed the inner field of ReviewReminderId to avoid confusing calls to `reviewReminder.id.id`.
…rs-dialog-august' into ericli3690-review-reminders-integrated-firing
GSoC 2025: Review Reminders

- Modifies ScheduleReminders so that it sets alarms for review reminders via AlarmManagerService.
@ericli3690 ericli3690 force-pushed the ericli3690-review-reminders-integrated-firing branch from 2d3626e to 845d78f Compare September 9, 2025 02:47
@ericli3690
Copy link
Member Author

  • Rebased.

@ericli3690 ericli3690 marked this pull request as draft September 26, 2025 04:11
@ericli3690
Copy link
Member Author

I've now combined this small PR with the one it was previously blocked by, #19118. Previously, I had this separate so that #19118 would not be blocked by AddEditReminderDialog, but now that AddEditReminderDialog has been merged, that's no longer necessary. Closing!

@ericli3690 ericli3690 closed this Nov 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Blocked by dependency Currently blocked by some other dependent / related change GSoC Pull requests authored by a Google Summer of Code participant [Candidate/Selected], for GSoC mentors Has Conflicts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant