Skip to content

Commit c94644b

Browse files
committed
feat(reminders): AddEditReminderDialog view model
GSoC 2025: Review Reminders - 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.
1 parent ea3e0a7 commit c94644b

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright (c) 2025 Eric Li <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify it under
5+
* the terms of the GNU General Public License as published by the Free Software
6+
* Foundation; either version 3 of the License, or (at your option) any later
7+
* version.
8+
*
9+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
10+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
11+
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
12+
*
13+
* You should have received a copy of the GNU General Public License along with
14+
* this program. If not, see <http://www.gnu.org/licenses/>.
15+
*/
16+
17+
package com.ichi2.anki.reviewreminders
18+
19+
import androidx.lifecycle.LiveData
20+
import androidx.lifecycle.MutableLiveData
21+
import androidx.lifecycle.ViewModel
22+
import com.ichi2.anki.libanki.DeckId
23+
import timber.log.Timber
24+
25+
/**
26+
* Represents the state of an [AddEditReminderDialog]'s UI. Does not represent the [ReviewReminder] object itself.
27+
* For example, instead of storing the card trigger threshold as a [ReviewReminderCardTriggerThreshold], we store an Int, since that's
28+
* the input type the user is using to enter the threshold into the app. In other words, this class reflects the concrete
29+
* EditText fields in the dialog, not abstract backend data representations.
30+
*/
31+
class AddEditReminderDialogViewModel(
32+
initialTime: ReviewReminderTime,
33+
initialDeckSelected: DeckId,
34+
initialCardTriggerThreshold: Int,
35+
initialAdvancedSettingsOpen: Boolean,
36+
) : ViewModel() {
37+
private val _time = MutableLiveData(initialTime)
38+
val time: LiveData<ReviewReminderTime> = _time
39+
40+
private val _deckSelected = MutableLiveData(initialDeckSelected)
41+
42+
/**
43+
* [com.ichi2.anki.DeckSpinnerSelection.ALL_DECKS_ID] is used to represent All Decks
44+
* (i.e. [ReviewReminderScope.Global]) being selected.
45+
*/
46+
val deckSelected: LiveData<DeckId> = _deckSelected
47+
48+
private val _cardTriggerThreshold = MutableLiveData(initialCardTriggerThreshold)
49+
val cardTriggerThreshold: LiveData<Int> = _cardTriggerThreshold
50+
51+
private val _advancedSettingsOpen = MutableLiveData(initialAdvancedSettingsOpen)
52+
val advancedSettingsOpen: LiveData<Boolean> = _advancedSettingsOpen
53+
54+
fun setTime(time: ReviewReminderTime) {
55+
Timber.d("Updated time to %s", time)
56+
_time.value = time
57+
}
58+
59+
fun setDeckSelected(deckId: DeckId) {
60+
Timber.d("Updated deck selected to %s", deckId)
61+
_deckSelected.value = deckId
62+
}
63+
64+
fun setCardTriggerThreshold(threshold: Int) {
65+
Timber.d("Updated card trigger threshold to %s", threshold)
66+
_cardTriggerThreshold.value = threshold
67+
}
68+
69+
fun toggleAdvancedSettingsOpen() {
70+
Timber.d("Toggled advanced settings open from %s", _advancedSettingsOpen.value)
71+
_advancedSettingsOpen.value = !(_advancedSettingsOpen.value ?: false)
72+
}
73+
}

0 commit comments

Comments
 (0)