Skip to content

Commit 8cc859b

Browse files
ericli3690david-allison
authored andcommitted
feat(reminders): ensure valid deck selected during edits
GSoC 2025: Review Reminders Currently, if the user tries to edit a review reminder corresponding to a non-existent deck, the deck spinner will become bugged. This change ensures the AddEditReminderDialog always has a valid deck selected. For example, this change means that if the user deletes a deck and goes to check their reminders, quickly clicking and saving the review reminder which is now no longer associated with a deck will cause the review reminder to be reassigned to a valid deck.
1 parent 42d5c0c commit 8cc859b

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

AnkiDroid/src/main/java/com/ichi2/anki/reviewreminders/AddEditReminderDialog.kt

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ import com.google.android.material.button.MaterialButton
4040
import com.google.android.material.textfield.TextInputLayout
4141
import com.google.android.material.timepicker.MaterialTimePicker
4242
import com.google.android.material.timepicker.TimeFormat
43+
import com.ichi2.anki.CollectionManager.withCol
4344
import com.ichi2.anki.DeckSpinnerSelection
4445
import com.ichi2.anki.R
4546
import com.ichi2.anki.dialogs.ConfirmationDialog
47+
import com.ichi2.anki.isDefaultDeckEmpty
4648
import com.ichi2.anki.launchCatchingTask
4749
import com.ichi2.anki.libanki.Consts
4850
import com.ichi2.anki.libanki.DeckId
@@ -192,10 +194,35 @@ class AddEditReminderDialog : DialogFragment() {
192194
launchCatchingTask {
193195
Timber.d("Setting up deck spinner")
194196
deckSpinnerSelection.initializeScheduleRemindersDeckSpinner()
195-
deckSpinnerSelection.selectDeckById(viewModel.deckSelected.value ?: Consts.DEFAULT_DECK_ID, setAsCurrentDeck = false)
197+
val deckToSelect = ensureValidDeckSelected()
198+
deckSpinnerSelection.selectDeckById(deckToSelect, setAsCurrentDeck = false)
196199
}
197200
}
198201

202+
/**
203+
* Checks to see if the ViewModel's selected deck is valid and exists. If it does not, we set the selected deck to a
204+
* valid deck (either the default deck or "all decks", depending on whether the default deck is present or not).
205+
*
206+
* @return The valid deck ID that is now selected.
207+
*/
208+
private suspend fun ensureValidDeckSelected(): DeckId {
209+
val fallbackSelection = if (isDefaultDeckEmpty()) DeckSpinnerSelection.ALL_DECKS_ID else Consts.DEFAULT_DECK_ID
210+
val currentlySelectedDeckID = viewModel.deckSelected.value
211+
val deckToSelect =
212+
when (currentlySelectedDeckID) {
213+
DeckSpinnerSelection.ALL_DECKS_ID -> DeckSpinnerSelection.ALL_DECKS_ID
214+
Consts.DEFAULT_DECK_ID -> fallbackSelection
215+
null -> fallbackSelection
216+
else -> {
217+
val doesDeckExist = withCol { decks.have(currentlySelectedDeckID) }
218+
if (doesDeckExist) currentlySelectedDeckID else fallbackSelection
219+
}
220+
}
221+
viewModel.setDeckSelected(deckToSelect)
222+
Timber.d("Initial selected deck ID: %s, newly selected deck ID: %s", currentlySelectedDeckID, deckToSelect)
223+
return deckToSelect
224+
}
225+
199226
private fun setUpAdvancedDropdown() {
200227
val advancedDropdown = contentView.findViewById<LinearLayout>(R.id.add_edit_reminder_advanced_dropdown)
201228
val advancedDropdownIcon = contentView.findViewById<ImageView>(R.id.add_edit_reminder_advanced_dropdown_icon)

AnkiDroid/src/main/java/com/ichi2/anki/reviewreminders/AddEditReminderDialogViewModel.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ class AddEditReminderDialogViewModel(
5151
)
5252
val time: LiveData<ReviewReminderTime> = _time
5353

54+
/**
55+
* Here, we set an immediate default value for the deck selected based on the dialog mode.
56+
* However, it is possible that the deck with this deck ID does not currently exist in the collection
57+
* (ex. due to a deleted deck, changed collection folder, etc.). Since checking for this case requires
58+
* accessing the collection, we handle it in [AddEditReminderDialog.ensureValidDeckSelected].
59+
*/
5460
private val _deckSelected =
5561
MutableLiveData(
5662
when (dialogMode) {

0 commit comments

Comments
 (0)