From e6fdfc20a9a48be99a38ebc9968c148cf161cb4a Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sat, 23 Sep 2023 16:12:05 +1000 Subject: [PATCH] Use FSRS difficulty when sorting by ease --- ftl/core/deck-config.ftl | 2 ++ .../src/scheduler/queue/builder/gathering.rs | 1 + rslib/src/scheduler/queue/builder/mod.rs | 2 ++ rslib/src/storage/card/mod.rs | 29 +++++++++++++++---- ts/deck-options/DisplayOrder.svelte | 3 +- ts/deck-options/choices.ts | 6 ++-- 6 files changed, 34 insertions(+), 9 deletions(-) diff --git a/ftl/core/deck-config.ftl b/ftl/core/deck-config.ftl index 56fe974e1..be3bae52a 100644 --- a/ftl/core/deck-config.ftl +++ b/ftl/core/deck-config.ftl @@ -203,6 +203,8 @@ deck-config-sort-order-ascending-intervals = Ascending intervals deck-config-sort-order-descending-intervals = Descending intervals deck-config-sort-order-ascending-ease = Ascending ease deck-config-sort-order-descending-ease = Descending ease +deck-config-sort-order-ascending-difficulty = Ascending difficulty +deck-config-sort-order-descending-difficulty = Descending difficulty deck-config-sort-order-relative-overdueness = Relative overdueness deck-config-display-order-will-use-current-deck = Anki will use the display order from the deck you diff --git a/rslib/src/scheduler/queue/builder/gathering.rs b/rslib/src/scheduler/queue/builder/gathering.rs index 5f513a602..6aad83f7c 100644 --- a/rslib/src/scheduler/queue/builder/gathering.rs +++ b/rslib/src/scheduler/queue/builder/gathering.rs @@ -40,6 +40,7 @@ impl QueueBuilder { self.context.timing.days_elapsed, self.context.sort_options.review_order, kind, + self.context.fsrs, |card| { if self.limits.root_limit_reached(LimitKind::Review) { return Ok(false); diff --git a/rslib/src/scheduler/queue/builder/mod.rs b/rslib/src/scheduler/queue/builder/mod.rs index 88747c49d..cdba84d9e 100644 --- a/rslib/src/scheduler/queue/builder/mod.rs +++ b/rslib/src/scheduler/queue/builder/mod.rs @@ -118,6 +118,7 @@ struct Context { sort_options: QueueSortOptions, seen_note_ids: HashMap, deck_map: HashMap, + fsrs: bool, } impl QueueBuilder { @@ -150,6 +151,7 @@ impl QueueBuilder { sort_options, seen_note_ids: HashMap::new(), deck_map, + fsrs: col.get_config_bool(BoolKey::Fsrs), }, }) } diff --git a/rslib/src/storage/card/mod.rs b/rslib/src/storage/card/mod.rs index 22046f88e..c8d77b5dd 100644 --- a/rslib/src/storage/card/mod.rs +++ b/rslib/src/storage/card/mod.rs @@ -253,12 +253,13 @@ impl super::SqliteStorage { day_cutoff: u32, order: ReviewCardOrder, kind: DueCardKind, + fsrs: bool, mut func: F, ) -> Result<()> where F: FnMut(DueCard) -> Result, { - let order_clause = review_order_sql(order, day_cutoff); + let order_clause = review_order_sql(order, day_cutoff, fsrs); let mut stmt = self.db.prepare_cached(&format!( "{} order by {}", include_str!("due_cards.sql"), @@ -693,7 +694,13 @@ enum ReviewOrderSubclause { IntervalsDescending, EaseAscending, EaseDescending, - RelativeOverdueness { today: u32 }, + /// FSRS + DifficultyAscending, + /// FSRS + DifficultyDescending, + RelativeOverdueness { + today: u32, + }, } impl fmt::Display for ReviewOrderSubclause { @@ -707,6 +714,8 @@ impl fmt::Display for ReviewOrderSubclause { ReviewOrderSubclause::IntervalsDescending => "ivl desc", ReviewOrderSubclause::EaseAscending => "factor asc", ReviewOrderSubclause::EaseDescending => "factor desc", + ReviewOrderSubclause::DifficultyAscending => "extract_fsrs_variable(data, 'd') asc", + ReviewOrderSubclause::DifficultyDescending => "extract_fsrs_variable(data, 'd') desc", ReviewOrderSubclause::RelativeOverdueness { today } => { temp_string = format!("ivl / cast({today}-due+0.001 as real)", today = today); &temp_string @@ -716,15 +725,25 @@ impl fmt::Display for ReviewOrderSubclause { } } -fn review_order_sql(order: ReviewCardOrder, today: u32) -> String { +fn review_order_sql(order: ReviewCardOrder, today: u32, fsrs: bool) -> String { let mut subclauses = match order { ReviewCardOrder::Day => vec![ReviewOrderSubclause::Day], ReviewCardOrder::DayThenDeck => vec![ReviewOrderSubclause::Day, ReviewOrderSubclause::Deck], ReviewCardOrder::DeckThenDay => vec![ReviewOrderSubclause::Deck, ReviewOrderSubclause::Day], ReviewCardOrder::IntervalsAscending => vec![ReviewOrderSubclause::IntervalsAscending], ReviewCardOrder::IntervalsDescending => vec![ReviewOrderSubclause::IntervalsDescending], - ReviewCardOrder::EaseAscending => vec![ReviewOrderSubclause::EaseAscending], - ReviewCardOrder::EaseDescending => vec![ReviewOrderSubclause::EaseDescending], + ReviewCardOrder::EaseAscending => { + vec![if fsrs { + ReviewOrderSubclause::DifficultyDescending + } else { + ReviewOrderSubclause::EaseAscending + }] + } + ReviewCardOrder::EaseDescending => vec![if fsrs { + ReviewOrderSubclause::DifficultyAscending + } else { + ReviewOrderSubclause::EaseDescending + }], ReviewCardOrder::RelativeOverdueness => { vec![ReviewOrderSubclause::RelativeOverdueness { today }] } diff --git a/ts/deck-options/DisplayOrder.svelte b/ts/deck-options/DisplayOrder.svelte index 5a313c970..d5282f5b4 100644 --- a/ts/deck-options/DisplayOrder.svelte +++ b/ts/deck-options/DisplayOrder.svelte @@ -32,6 +32,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html const config = state.currentConfig; const defaults = state.defaults; + const fsrs = state.fsrs; const currentDeck = "\n\n" + tr.deckConfigDisplayOrderWillUseCurrentDeck(); @@ -191,7 +192,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html diff --git a/ts/deck-options/choices.ts b/ts/deck-options/choices.ts index 48b18af12..f89b07050 100644 --- a/ts/deck-options/choices.ts +++ b/ts/deck-options/choices.ts @@ -62,7 +62,7 @@ export function newSortOrderChoices(): Choice[] { +export function reviewOrderChoices(fsrs: boolean): Choice[] { return [ { label: tr.deckConfigSortOrderDueDateThenRandom(), @@ -85,11 +85,11 @@ export function reviewOrderChoices(): Choice[ value: DeckConfig_Config_ReviewCardOrder.INTERVALS_DESCENDING, }, { - label: tr.deckConfigSortOrderAscendingEase(), + label: fsrs ? tr.deckConfigSortOrderDescendingDifficulty() : tr.deckConfigSortOrderAscendingEase(), value: DeckConfig_Config_ReviewCardOrder.EASE_ASCENDING, }, { - label: tr.deckConfigSortOrderDescendingEase(), + label: fsrs ? tr.deckConfigSortOrderAscendingDifficulty() : tr.deckConfigSortOrderDescendingEase(), value: DeckConfig_Config_ReviewCardOrder.EASE_DESCENDING, }, {