forked from ankidroid/Anki-Android
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This differs from the legacy reviewer in four things: 1. It implements `Show reminder` as an action (it is a tooltip in Anki, so I made it a snackbar here) 2. It doesn't follow the global switch in settings, as Anki desktop doesn't have one and users complained about finding the global setting unexpected 3. There is now a `Question action` setting 4. The legacy reviewer has an issue where the same configuration is carried through all cards in the review session. So if a card with a different deck config shows up, the config won't be respected. This is fixed in the new reviewer
- Loading branch information
Showing
6 changed files
with
241 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/autoadvance/AnswerAction.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Copyright (c) 2024 Brayan Oliveira <[email protected]> | ||
* | ||
* This program is free software; you can redistribute it and/or modify it under | ||
* the terms of the GNU General Public License as published by the Free Software | ||
* Foundation; either version 3 of the License, or (at your option) any later | ||
* version. | ||
* | ||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY | ||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||
* PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License along with | ||
* this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package com.ichi2.anki.ui.windows.reviewer.autoadvance | ||
|
||
import com.ichi2.libanki.DeckConfig | ||
|
||
enum class AnswerAction(val configValue: Int) { | ||
BURY_CARD(0), | ||
ANSWER_AGAIN(1), | ||
ANSWER_GOOD(2), | ||
ANSWER_HARD(3), | ||
SHOW_REMINDER(4); | ||
|
||
companion object { | ||
fun from(config: DeckConfig): AnswerAction { | ||
val value = config.optInt("answerAction") | ||
return entries.firstOrNull { it.configValue == value } ?: BURY_CARD | ||
} | ||
} | ||
} |
97 changes: 97 additions & 0 deletions
97
AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/autoadvance/AutoAdvance.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
* Copyright (c) 2024 Brayan Oliveira <[email protected]> | ||
* | ||
* This program is free software; you can redistribute it and/or modify it under | ||
* the terms of the GNU General Public License as published by the Free Software | ||
* Foundation; either version 3 of the License, or (at your option) any later | ||
* version. | ||
* | ||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY | ||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||
* PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License along with | ||
* this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package com.ichi2.anki.ui.windows.reviewer.autoadvance | ||
|
||
import com.ichi2.anki.CollectionManager.TR | ||
import com.ichi2.anki.asyncIO | ||
import com.ichi2.anki.launchCatchingIO | ||
import com.ichi2.anki.ui.windows.reviewer.ReviewerViewModel | ||
import com.ichi2.libanki.Card | ||
import kotlinx.coroutines.Job | ||
import kotlinx.coroutines.delay | ||
|
||
/** | ||
* Implementation of the `Auto Advance` deck options | ||
* | ||
* A timer (in seconds) can be set to automatically trigger an action after it runs out, | ||
* either in the question side ([QuestionAction]) or in the answer side ([AnswerAction]). | ||
* | ||
* If a timer is set to 0, the corresponding action is not triggered. | ||
* | ||
* @see AutoAdvanceSettings | ||
*/ | ||
class AutoAdvance(val viewModel: ReviewerViewModel) { | ||
private var questionActionJob: Job? = null | ||
private var answerActionJob: Job? = null | ||
|
||
private var settings = viewModel.asyncIO { | ||
val card = viewModel.currentCard.await() | ||
AutoAdvanceSettings.createInstance(card.currentDeckId().did) | ||
} | ||
|
||
private suspend fun durationToShowQuestionFor() = settings.await().durationToShowQuestionFor | ||
private suspend fun durationToShowAnswerFor() = settings.await().durationToShowAnswerFor | ||
private suspend fun questionAction() = settings.await().questionAction | ||
private suspend fun answerAction() = settings.await().answerAction | ||
suspend fun shouldWaitForAudio() = settings.await().waitForAudio | ||
|
||
fun cancelQuestionAndAnswerActionJobs() { | ||
questionActionJob?.cancel() | ||
answerActionJob?.cancel() | ||
} | ||
|
||
fun onCardChange(card: Card) { | ||
cancelQuestionAndAnswerActionJobs() | ||
settings = viewModel.asyncIO { | ||
AutoAdvanceSettings.createInstance(card.currentDeckId().did) | ||
} | ||
} | ||
|
||
suspend fun onShowQuestion() { | ||
answerActionJob?.cancel() | ||
if (!durationToShowQuestionFor().isPositive()) return | ||
|
||
questionActionJob = viewModel.launchCatchingIO { | ||
delay(durationToShowQuestionFor()) | ||
when (questionAction()) { | ||
QuestionAction.SHOW_ANSWER -> viewModel.showAnswer() | ||
QuestionAction.SHOW_REMINDER -> showReminder(TR.studyingQuestionTimeElapsed()) | ||
} | ||
} | ||
} | ||
|
||
suspend fun onShowAnswer() { | ||
questionActionJob?.cancel() | ||
if (!durationToShowAnswerFor().isPositive()) return | ||
|
||
answerActionJob = viewModel.launchCatchingIO { | ||
delay(durationToShowAnswerFor()) | ||
when (answerAction()) { | ||
AnswerAction.BURY_CARD -> viewModel.buryCard() | ||
AnswerAction.ANSWER_AGAIN -> viewModel.answerAgain() | ||
AnswerAction.ANSWER_HARD -> viewModel.answerHard() | ||
AnswerAction.ANSWER_GOOD -> viewModel.answerGood() | ||
AnswerAction.SHOW_REMINDER -> showReminder(TR.studyingAnswerTimeElapsed()) | ||
} | ||
} | ||
} | ||
|
||
private fun showReminder(message: String) { | ||
viewModel.launchCatchingIO { | ||
viewModel.actionFeedbackFlow.emit(message) | ||
} | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
...Droid/src/main/java/com/ichi2/anki/ui/windows/reviewer/autoadvance/AutoAdvanceSettings.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* Copyright (c) 2024 Brayan Oliveira <[email protected]> | ||
* | ||
* This program is free software; you can redistribute it and/or modify it under | ||
* the terms of the GNU General Public License as published by the Free Software | ||
* Foundation; either version 3 of the License, or (at your option) any later | ||
* version. | ||
* | ||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY | ||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||
* PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License along with | ||
* this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package com.ichi2.anki.ui.windows.reviewer.autoadvance | ||
|
||
import com.ichi2.anki.CollectionManager.withCol | ||
import com.ichi2.anki.utils.ext.secondsToShowAnswer | ||
import com.ichi2.anki.utils.ext.secondsToShowQuestion | ||
import com.ichi2.libanki.DeckId | ||
import kotlin.time.Duration | ||
import kotlin.time.DurationUnit | ||
import kotlin.time.toDuration | ||
|
||
data class AutoAdvanceSettings( | ||
val questionAction: QuestionAction, | ||
val answerAction: AnswerAction, | ||
val durationToShowQuestionFor: Duration, | ||
val durationToShowAnswerFor: Duration, | ||
val waitForAudio: Boolean | ||
) { | ||
companion object { | ||
suspend fun createInstance(deckId: DeckId): AutoAdvanceSettings { | ||
val config = withCol { decks.configDictForDeckId(deckId) } | ||
val questionAction = QuestionAction.from(config) | ||
val answerAction = AnswerAction.from(config) | ||
val waitForAudio = config.optBoolean("waitForAudio", true) | ||
|
||
return AutoAdvanceSettings( | ||
questionAction = questionAction, | ||
answerAction = answerAction, | ||
durationToShowQuestionFor = config.secondsToShowQuestion.toDuration(DurationUnit.SECONDS), | ||
durationToShowAnswerFor = config.secondsToShowAnswer.toDuration(DurationUnit.SECONDS), | ||
waitForAudio = waitForAudio | ||
) | ||
} | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/autoadvance/QuestionAction.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* Copyright (c) 2024 Brayan Oliveira <[email protected]> | ||
* | ||
* This program is free software; you can redistribute it and/or modify it under | ||
* the terms of the GNU General Public License as published by the Free Software | ||
* Foundation; either version 3 of the License, or (at your option) any later | ||
* version. | ||
* | ||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY | ||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||
* PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License along with | ||
* this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package com.ichi2.anki.ui.windows.reviewer.autoadvance | ||
|
||
import com.ichi2.libanki.DeckConfig | ||
|
||
enum class QuestionAction(val configValue: Int) { | ||
SHOW_ANSWER(0), | ||
SHOW_REMINDER(1); | ||
|
||
companion object { | ||
fun from(config: DeckConfig): QuestionAction { | ||
val value = config.optInt("questionAction") | ||
return entries.firstOrNull { it.configValue == value } ?: SHOW_ANSWER | ||
} | ||
} | ||
} |