Use FSRS difficulty when sorting by ease

This commit is contained in:
Damien Elmes 2023-09-23 16:12:05 +10:00
parent 06d99b5871
commit e6fdfc20a9
6 changed files with 34 additions and 9 deletions

View file

@ -203,6 +203,8 @@ deck-config-sort-order-ascending-intervals = Ascending intervals
deck-config-sort-order-descending-intervals = Descending intervals deck-config-sort-order-descending-intervals = Descending intervals
deck-config-sort-order-ascending-ease = Ascending ease deck-config-sort-order-ascending-ease = Ascending ease
deck-config-sort-order-descending-ease = Descending 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-sort-order-relative-overdueness = Relative overdueness
deck-config-display-order-will-use-current-deck = deck-config-display-order-will-use-current-deck =
Anki will use the display order from the deck you Anki will use the display order from the deck you

View file

@ -40,6 +40,7 @@ impl QueueBuilder {
self.context.timing.days_elapsed, self.context.timing.days_elapsed,
self.context.sort_options.review_order, self.context.sort_options.review_order,
kind, kind,
self.context.fsrs,
|card| { |card| {
if self.limits.root_limit_reached(LimitKind::Review) { if self.limits.root_limit_reached(LimitKind::Review) {
return Ok(false); return Ok(false);

View file

@ -118,6 +118,7 @@ struct Context {
sort_options: QueueSortOptions, sort_options: QueueSortOptions,
seen_note_ids: HashMap<NoteId, BuryMode>, seen_note_ids: HashMap<NoteId, BuryMode>,
deck_map: HashMap<DeckId, Deck>, deck_map: HashMap<DeckId, Deck>,
fsrs: bool,
} }
impl QueueBuilder { impl QueueBuilder {
@ -150,6 +151,7 @@ impl QueueBuilder {
sort_options, sort_options,
seen_note_ids: HashMap::new(), seen_note_ids: HashMap::new(),
deck_map, deck_map,
fsrs: col.get_config_bool(BoolKey::Fsrs),
}, },
}) })
} }

View file

@ -253,12 +253,13 @@ impl super::SqliteStorage {
day_cutoff: u32, day_cutoff: u32,
order: ReviewCardOrder, order: ReviewCardOrder,
kind: DueCardKind, kind: DueCardKind,
fsrs: bool,
mut func: F, mut func: F,
) -> Result<()> ) -> Result<()>
where where
F: FnMut(DueCard) -> Result<bool>, F: FnMut(DueCard) -> Result<bool>,
{ {
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!( let mut stmt = self.db.prepare_cached(&format!(
"{} order by {}", "{} order by {}",
include_str!("due_cards.sql"), include_str!("due_cards.sql"),
@ -693,7 +694,13 @@ enum ReviewOrderSubclause {
IntervalsDescending, IntervalsDescending,
EaseAscending, EaseAscending,
EaseDescending, EaseDescending,
RelativeOverdueness { today: u32 }, /// FSRS
DifficultyAscending,
/// FSRS
DifficultyDescending,
RelativeOverdueness {
today: u32,
},
} }
impl fmt::Display for ReviewOrderSubclause { impl fmt::Display for ReviewOrderSubclause {
@ -707,6 +714,8 @@ impl fmt::Display for ReviewOrderSubclause {
ReviewOrderSubclause::IntervalsDescending => "ivl desc", ReviewOrderSubclause::IntervalsDescending => "ivl desc",
ReviewOrderSubclause::EaseAscending => "factor asc", ReviewOrderSubclause::EaseAscending => "factor asc",
ReviewOrderSubclause::EaseDescending => "factor desc", ReviewOrderSubclause::EaseDescending => "factor desc",
ReviewOrderSubclause::DifficultyAscending => "extract_fsrs_variable(data, 'd') asc",
ReviewOrderSubclause::DifficultyDescending => "extract_fsrs_variable(data, 'd') desc",
ReviewOrderSubclause::RelativeOverdueness { today } => { ReviewOrderSubclause::RelativeOverdueness { today } => {
temp_string = format!("ivl / cast({today}-due+0.001 as real)", today = today); temp_string = format!("ivl / cast({today}-due+0.001 as real)", today = today);
&temp_string &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 { let mut subclauses = match order {
ReviewCardOrder::Day => vec![ReviewOrderSubclause::Day], ReviewCardOrder::Day => vec![ReviewOrderSubclause::Day],
ReviewCardOrder::DayThenDeck => vec![ReviewOrderSubclause::Day, ReviewOrderSubclause::Deck], ReviewCardOrder::DayThenDeck => vec![ReviewOrderSubclause::Day, ReviewOrderSubclause::Deck],
ReviewCardOrder::DeckThenDay => vec![ReviewOrderSubclause::Deck, ReviewOrderSubclause::Day], ReviewCardOrder::DeckThenDay => vec![ReviewOrderSubclause::Deck, ReviewOrderSubclause::Day],
ReviewCardOrder::IntervalsAscending => vec![ReviewOrderSubclause::IntervalsAscending], ReviewCardOrder::IntervalsAscending => vec![ReviewOrderSubclause::IntervalsAscending],
ReviewCardOrder::IntervalsDescending => vec![ReviewOrderSubclause::IntervalsDescending], ReviewCardOrder::IntervalsDescending => vec![ReviewOrderSubclause::IntervalsDescending],
ReviewCardOrder::EaseAscending => vec![ReviewOrderSubclause::EaseAscending], ReviewCardOrder::EaseAscending => {
ReviewCardOrder::EaseDescending => vec![ReviewOrderSubclause::EaseDescending], vec![if fsrs {
ReviewOrderSubclause::DifficultyDescending
} else {
ReviewOrderSubclause::EaseAscending
}]
}
ReviewCardOrder::EaseDescending => vec![if fsrs {
ReviewOrderSubclause::DifficultyAscending
} else {
ReviewOrderSubclause::EaseDescending
}],
ReviewCardOrder::RelativeOverdueness => { ReviewCardOrder::RelativeOverdueness => {
vec![ReviewOrderSubclause::RelativeOverdueness { today }] vec![ReviewOrderSubclause::RelativeOverdueness { today }]
} }

View file

@ -32,6 +32,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const config = state.currentConfig; const config = state.currentConfig;
const defaults = state.defaults; const defaults = state.defaults;
const fsrs = state.fsrs;
const currentDeck = "\n\n" + tr.deckConfigDisplayOrderWillUseCurrentDeck(); const currentDeck = "\n\n" + tr.deckConfigDisplayOrderWillUseCurrentDeck();
@ -191,7 +192,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<EnumSelectorRow <EnumSelectorRow
bind:value={$config.reviewOrder} bind:value={$config.reviewOrder}
defaultValue={defaults.reviewOrder} defaultValue={defaults.reviewOrder}
choices={reviewOrderChoices()} choices={reviewOrderChoices($fsrs)}
> >
<SettingTitle <SettingTitle
on:click={() => on:click={() =>

View file

@ -62,7 +62,7 @@ export function newSortOrderChoices(): Choice<DeckConfig_Config_NewCardSortOrder
]; ];
} }
export function reviewOrderChoices(): Choice<DeckConfig_Config_ReviewCardOrder>[] { export function reviewOrderChoices(fsrs: boolean): Choice<DeckConfig_Config_ReviewCardOrder>[] {
return [ return [
{ {
label: tr.deckConfigSortOrderDueDateThenRandom(), label: tr.deckConfigSortOrderDueDateThenRandom(),
@ -85,11 +85,11 @@ export function reviewOrderChoices(): Choice<DeckConfig_Config_ReviewCardOrder>[
value: DeckConfig_Config_ReviewCardOrder.INTERVALS_DESCENDING, value: DeckConfig_Config_ReviewCardOrder.INTERVALS_DESCENDING,
}, },
{ {
label: tr.deckConfigSortOrderAscendingEase(), label: fsrs ? tr.deckConfigSortOrderDescendingDifficulty() : tr.deckConfigSortOrderAscendingEase(),
value: DeckConfig_Config_ReviewCardOrder.EASE_ASCENDING, value: DeckConfig_Config_ReviewCardOrder.EASE_ASCENDING,
}, },
{ {
label: tr.deckConfigSortOrderDescendingEase(), label: fsrs ? tr.deckConfigSortOrderAscendingDifficulty() : tr.deckConfigSortOrderDescendingEase(),
value: DeckConfig_Config_ReviewCardOrder.EASE_DESCENDING, value: DeckConfig_Config_ReviewCardOrder.EASE_DESCENDING,
}, },
{ {