From 42100d6dd7674cea180cbb0644e348062a8ff1c7 Mon Sep 17 00:00:00 2001 From: Moreno <154519856+morenotropical@users.noreply.github.com> Date: Fri, 7 Jun 2024 11:11:35 -0300 Subject: [PATCH] add next card due message --- .../java/com/ichi2/anki/pages/CongratsPage.kt | 42 ++++++++++++++++--- .../main/java/com/ichi2/anki/utils/Time.kt | 6 +-- AnkiDroid/src/main/res/values/01-core.xml | 1 + 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/pages/CongratsPage.kt b/AnkiDroid/src/main/java/com/ichi2/anki/pages/CongratsPage.kt index 5349e471a72e..0e1bf95b3945 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/pages/CongratsPage.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/pages/CongratsPage.kt @@ -15,7 +15,6 @@ */ package com.ichi2.anki.pages -import android.app.Activity import android.content.Context import android.content.Intent import android.os.Bundle @@ -23,6 +22,7 @@ import android.view.View import android.webkit.JavascriptInterface import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment +import androidx.fragment.app.FragmentActivity import androidx.fragment.app.viewModels import androidx.lifecycle.ViewModel import androidx.lifecycle.flowWithLifecycle @@ -30,6 +30,7 @@ import androidx.lifecycle.lifecycleScope import anki.collection.OpChanges import com.google.android.material.appbar.MaterialToolbar import com.ichi2.anki.CollectionManager +import com.ichi2.anki.CollectionManager.TR import com.ichi2.anki.CollectionManager.withCol import com.ichi2.anki.DeckPicker import com.ichi2.anki.FilteredDeckOptions @@ -40,9 +41,13 @@ import com.ichi2.anki.SingleFragmentActivity import com.ichi2.anki.StudyOptionsActivity import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog import com.ichi2.anki.launchCatchingIO +import com.ichi2.anki.launchCatchingTask import com.ichi2.anki.preferences.sharedPrefs import com.ichi2.anki.showThemedToast import com.ichi2.anki.snackbar.showSnackbar +import com.ichi2.anki.utils.SECONDS_PER_DAY +import com.ichi2.anki.utils.TIME_HOUR +import com.ichi2.anki.utils.TIME_MINUTE import com.ichi2.libanki.ChangeManager import com.ichi2.libanki.DeckId import com.ichi2.libanki.undoableOp @@ -50,6 +55,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import timber.log.Timber +import kotlin.math.round class CongratsPage : PageFragment(), @@ -183,15 +189,18 @@ class CongratsPage : private fun displayNewCongratsScreen(context: Context): Boolean = context.sharedPrefs().getBoolean("new_congrats_screen", false) - fun display(activity: Activity) { + fun display(activity: FragmentActivity) { if (displayNewCongratsScreen(activity)) { activity.startActivity(getIntent(activity)) } else { - showThemedToast(activity, R.string.studyoptions_congrats_finished, false) + activity.launchCatchingTask { + val message = getDeckFinishedMessage(activity) + showThemedToast(activity, message, false) + } } } - fun onReviewsCompleted(activity: Activity, cardsInDeck: Boolean) { + fun onReviewsCompleted(activity: FragmentActivity, cardsInDeck: Boolean) { if (displayNewCongratsScreen(activity)) { activity.startActivity(getIntent(activity)) return @@ -199,12 +208,35 @@ class CongratsPage : // Show a message when reviewing has finished if (cardsInDeck) { - activity.showSnackbar(R.string.studyoptions_congrats_finished) + activity.launchCatchingTask { + val message = getDeckFinishedMessage(activity) + activity.showSnackbar(message) + } } else { activity.showSnackbar(R.string.studyoptions_no_cards_due) } } + // based in https://github.com/ankitects/anki/blob/9b4dd54312de8798a3f2bee07892bb3a488d1f9b/ts/routes/congrats/lib.ts#L8C17-L8C34 + private suspend fun getDeckFinishedMessage(activity: FragmentActivity): String { + val info = withCol { sched.congratulationsInfo() } + val secsUntilNextLearn = info.secsUntilNextLearn + if (secsUntilNextLearn >= SECONDS_PER_DAY) { + return activity.getString(R.string.studyoptions_congrats_finished) + } + // https://github.com/ankitects/anki/blob/9b4dd54312de8798a3f2bee07892bb3a488d1f9b/ts/lib/tslib/time.ts#L22 + val (unit, amount) = if (secsUntilNextLearn < TIME_MINUTE) { + "seconds" to secsUntilNextLearn.toDouble() + } else if (secsUntilNextLearn < TIME_HOUR) { + "minutes" to secsUntilNextLearn / TIME_MINUTE + } else { + "hours" to secsUntilNextLearn / TIME_HOUR + } + + val nextLearnDue = TR.schedulingNextLearnDue(unit, round(amount).toInt()) + return activity.getString(R.string.studyoptions_congrats_next_due_in, nextLearnDue) + } + fun DeckPicker.onDeckCompleted() { startActivity(getIntent(this)) } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/utils/Time.kt b/AnkiDroid/src/main/java/com/ichi2/anki/utils/Time.kt index 819b751fdc0a..0483df1e3d78 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/utils/Time.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/utils/Time.kt @@ -37,9 +37,9 @@ private const val TIME_DAY_LONG = 24 * TIME_HOUR_LONG // These are doubles on purpose because we want a rounded, not integer result later. // Use values from Anki Desktop: // https://github.com/ankitects/anki/blob/05cc47a5d3d48851267cda47f62af79f468eb028/rslib/src/sched/timespan.rs#L83 -private const val TIME_MINUTE = 60.0 // seconds -private const val TIME_HOUR = 60.0 * TIME_MINUTE -private const val TIME_DAY = 24.0 * TIME_HOUR +const val TIME_MINUTE = 60.0 // seconds +const val TIME_HOUR = 60.0 * TIME_MINUTE +const val TIME_DAY = 24.0 * TIME_HOUR private const val TIME_MONTH = 30.0 * TIME_DAY private const val TIME_YEAR = 12.0 * TIME_MONTH diff --git a/AnkiDroid/src/main/res/values/01-core.xml b/AnkiDroid/src/main/res/values/01-core.xml index 414a22872a0a..5b7347225a5c 100644 --- a/AnkiDroid/src/main/res/values/01-core.xml +++ b/AnkiDroid/src/main/res/values/01-core.xml @@ -111,6 +111,7 @@ Deck Search Invalid deck name Congratulations! You have finished for now. + Congratulations! %s No cards are due yet Device storage not mounted