diff --git a/proto/anki/deck_config.proto b/proto/anki/deck_config.proto index 137d03dc6..6519d1fea 100644 --- a/proto/anki/deck_config.proto +++ b/proto/anki/deck_config.proto @@ -202,6 +202,7 @@ message DeckConfigsForUpdate { bool new_cards_ignore_review_limit = 7; bool fsrs = 8; bool apply_all_parent_limits = 9; + uint32 days_since_last_fsrs_optimize = 10; } enum UpdateDeckConfigsMode { diff --git a/rslib/src/config/number.rs b/rslib/src/config/number.rs index 9a13c39b7..f7a0f7491 100644 --- a/rslib/src/config/number.rs +++ b/rslib/src/config/number.rs @@ -10,6 +10,7 @@ use crate::prelude::*; pub enum I32ConfigKey { CsvDuplicateResolution, MatchScope, + LastFsrsOptimize, } impl Collection { diff --git a/rslib/src/deckconfig/update.rs b/rslib/src/deckconfig/update.rs index 51776bb80..3925d56fc 100644 --- a/rslib/src/deckconfig/update.rs +++ b/rslib/src/deckconfig/update.rs @@ -14,6 +14,7 @@ use anki_proto::deck_config::UpdateDeckConfigsMode; use anki_proto::decks::deck::normal::DayLimit; use fsrs::DEFAULT_PARAMETERS; +use crate::config::I32ConfigKey; use crate::config::StringKey; use crate::decks::NormalDeck; use crate::prelude::*; @@ -47,6 +48,14 @@ impl Collection { ) -> Result { let mut defaults = DeckConfig::default(); defaults.inner.fsrs_weights = DEFAULT_PARAMETERS.into(); + let last_optimize = self.get_config_i32(I32ConfigKey::LastFsrsOptimize) as u32; + let days_since_last_fsrs_optimize = if last_optimize > 0 { + self.timing_today()? + .days_elapsed + .saturating_sub(last_optimize) + } else { + 0 + }; Ok(anki_proto::deck_config::DeckConfigsForUpdate { all_config: self.get_deck_config_with_extra_for_update()?, current_deck: Some(self.get_current_deck_for_update(deck)?), @@ -59,6 +68,7 @@ impl Collection { new_cards_ignore_review_limit: self.get_config_bool(BoolKey::NewCardsIgnoreReviewLimit), apply_all_parent_limits: self.get_config_bool(BoolKey::ApplyAllParentLimits), fsrs: self.get_config_bool(BoolKey::Fsrs), + days_since_last_fsrs_optimize, }) } @@ -354,6 +364,8 @@ impl Collection { println!("{}: {}", config.name, err) } } + let today = self.timing_today()?.days_elapsed as i32; + self.set_config_i32_inner(I32ConfigKey::LastFsrsOptimize, today)?; } Ok(()) } diff --git a/ts/deck-options/FsrsOptions.svelte b/ts/deck-options/FsrsOptions.svelte index f5030dcf1..f54ec8ce7 100644 --- a/ts/deck-options/FsrsOptions.svelte +++ b/ts/deck-options/FsrsOptions.svelte @@ -35,6 +35,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html const config = state.currentConfig; const defaults = state.defaults; const fsrsReschedule = state.fsrsReschedule; + const daysSinceLastOptimization = state.daysSinceLastOptimization; + + $: lastOptimizationWarning = + $daysSinceLastOptimization > 30 ? tr.deckConfigOptimizeAllTip() : ""; let computeWeightsProgress: ComputeWeightsProgress | undefined; let computingWeights = false; @@ -300,46 +304,44 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-
- {tr.deckConfigComputeOptimalWeights()} - - - - - openHelpModal("ignoreBefore")}> - {tr.deckConfigIgnoreBefore()} - - - {#if computingWeights || checkingWeights}
- {computeWeightsProgressString} -
{/if} + {tr.deckConfigComputeOptimalWeights()} + + + + + openHelpModal("ignoreBefore")}> + {tr.deckConfigIgnoreBefore()} + + + {#if computingWeights || checkingWeights}
+ {computeWeightsProgressString} +
{/if} -
{tr.deckConfigOptimizeAllTip()}
-
+
diff --git a/ts/deck-options/lib.ts b/ts/deck-options/lib.ts index 856ebc903..e1dd21ed5 100644 --- a/ts/deck-options/lib.ts +++ b/ts/deck-options/lib.ts @@ -45,6 +45,7 @@ export class DeckOptionsState { readonly applyAllParentLimits: Writable; readonly fsrs: Writable; readonly fsrsReschedule: Writable = writable(false); + readonly daysSinceLastOptimization: Writable; readonly currentPresetName: Writable; private targetDeckId: DeckOptionsId; @@ -78,6 +79,7 @@ export class DeckOptionsState { this.newCardsIgnoreReviewLimit = writable(data.newCardsIgnoreReviewLimit); this.applyAllParentLimits = writable(data.applyAllParentLimits); this.fsrs = writable(data.fsrs); + this.daysSinceLastOptimization = writable(data.daysSinceLastFsrsOptimize); // decrement the use count of the starting item, as we'll apply +1 to currently // selected one at display time