mirror of
https://github.com/ankitects/anki.git
synced 2026-01-07 02:53:54 -05:00
Merge 413ebb59b5 into 8f2144534b
This commit is contained in:
commit
0de109885a
10 changed files with 76 additions and 55 deletions
|
|
@ -47,9 +47,8 @@ decks-decreasing-intervals = Decreasing intervals
|
||||||
decks-oldest-seen-first = Oldest seen first
|
decks-oldest-seen-first = Oldest seen first
|
||||||
# Combobox entry: Sort the cards in random order
|
# Combobox entry: Sort the cards in random order
|
||||||
decks-random = Random
|
decks-random = Random
|
||||||
|
# Combobox entry: Sort the cards by relative overdueness, in descending order (most overdue to least overdue)
|
||||||
|
decks-relative-overdueness = Relative overdueness
|
||||||
|
|
||||||
## These strings are no longer used - you do not need to translate them if they
|
## These strings are no longer used - you do not need to translate them if they
|
||||||
## are not already translated.
|
## are not already translated.
|
||||||
|
|
||||||
# Combobox entry: Sort the cards by relative overdueness, in descending order (most overdue to least overdue)
|
|
||||||
decks-relative-overdueness = Relative overdueness
|
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ message DeckConfig {
|
||||||
REVIEW_CARD_ORDER_EASE_DESCENDING = 6;
|
REVIEW_CARD_ORDER_EASE_DESCENDING = 6;
|
||||||
REVIEW_CARD_ORDER_RETRIEVABILITY_ASCENDING = 7;
|
REVIEW_CARD_ORDER_RETRIEVABILITY_ASCENDING = 7;
|
||||||
REVIEW_CARD_ORDER_RETRIEVABILITY_DESCENDING = 11;
|
REVIEW_CARD_ORDER_RETRIEVABILITY_DESCENDING = 11;
|
||||||
|
REVIEW_CARD_ORDER_RELATIVE_OVERDUENESS = 12;
|
||||||
REVIEW_CARD_ORDER_RANDOM = 8;
|
REVIEW_CARD_ORDER_RANDOM = 8;
|
||||||
REVIEW_CARD_ORDER_ADDED = 9;
|
REVIEW_CARD_ORDER_ADDED = 9;
|
||||||
REVIEW_CARD_ORDER_REVERSE_ADDED = 10;
|
REVIEW_CARD_ORDER_REVERSE_ADDED = 10;
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@ message Deck {
|
||||||
REVERSE_ADDED = 7;
|
REVERSE_ADDED = 7;
|
||||||
RETRIEVABILITY_ASCENDING = 8;
|
RETRIEVABILITY_ASCENDING = 8;
|
||||||
RETRIEVABILITY_DESCENDING = 9;
|
RETRIEVABILITY_DESCENDING = 9;
|
||||||
|
RELATIVE_OVERDUENESS = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
string search = 1;
|
string search = 1;
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ fn search_order_label(order: FilteredSearchOrder, tr: &I18n) -> String {
|
||||||
FilteredSearchOrder::RetrievabilityDescending => {
|
FilteredSearchOrder::RetrievabilityDescending => {
|
||||||
tr.deck_config_sort_order_retrievability_descending()
|
tr.deck_config_sort_order_retrievability_descending()
|
||||||
}
|
}
|
||||||
|
FilteredSearchOrder::RelativeOverdueness => tr.decks_relative_overdueness(),
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ fn create_review_priority_fn(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not implemented yet
|
// Not implemented yet
|
||||||
Added | ReverseAdded => None,
|
Added | ReverseAdded | RelativeOverdueness => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -469,7 +469,7 @@ mod test {
|
||||||
cards.push(card);
|
cards.push(card);
|
||||||
}
|
}
|
||||||
col.update_cards_maybe_undoable(cards, false)?;
|
col.update_cards_maybe_undoable(cards, false)?;
|
||||||
col.set_deck_review_order(&mut deck, ReviewCardOrder::RetrievabilityAscending);
|
col.set_deck_review_order(&mut deck, ReviewCardOrder::RelativeOverdueness);
|
||||||
assert_eq!(col.queue_as_due_and_ivl(deck.id), expected_queue);
|
assert_eq!(col.queue_as_due_and_ivl(deck.id), expected_queue);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// Copyright: Ankitects Pty Ltd and contributors
|
// Copyright: Ankitects Pty Ltd and contributors
|
||||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
use crate::card::CardQueue;
|
|
||||||
use crate::decks::FilteredSearchOrder;
|
use crate::decks::FilteredSearchOrder;
|
||||||
use crate::decks::FilteredSearchTerm;
|
use crate::decks::FilteredSearchTerm;
|
||||||
use crate::scheduler::timing::SchedTimingToday;
|
use crate::scheduler::timing::SchedTimingToday;
|
||||||
|
|
@ -40,6 +39,11 @@ pub(crate) fn order_and_limit_for_search(
|
||||||
build_retrievability_query(fsrs, today, next_day_at, now, SqlSortOrder::Descending);
|
build_retrievability_query(fsrs, today, next_day_at, now, SqlSortOrder::Descending);
|
||||||
&temp_string
|
&temp_string
|
||||||
}
|
}
|
||||||
|
FilteredSearchOrder::RelativeOverdueness => {
|
||||||
|
temp_string =
|
||||||
|
format!("extract_fsrs_relative_retrievability(data, case when odue !=0 then odue else due end, ivl, {today}, {next_day_at}, {now}) asc");
|
||||||
|
&temp_string
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
format!("{}, fnvhash(c.id, c.mod) limit {}", order, term.limit)
|
format!("{}, fnvhash(c.id, c.mod) limit {}", order, term.limit)
|
||||||
|
|
@ -54,15 +58,9 @@ fn build_retrievability_query(
|
||||||
) -> String {
|
) -> String {
|
||||||
if fsrs {
|
if fsrs {
|
||||||
format!(
|
format!(
|
||||||
"extract_fsrs_relative_retrievability(c.data, case when c.odue !=0 then c.odue else c.due end, ivl, {today}, {next_day_at}, {now}) {order}"
|
"extract_fsrs_retrievability(c.data, case when c.odue !=0 then c.odue else c.due end, ivl, {today}, {next_day_at}, {now}) {order}"
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
format!(
|
String::new()
|
||||||
"
|
|
||||||
(case when queue={rev_queue} and due <= {today}
|
|
||||||
then (ivl / cast({today}-due+0.001 as real)) else 100000+due end) {order}",
|
|
||||||
rev_queue = CardQueue::Review as i8,
|
|
||||||
today = today
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -800,14 +800,14 @@ pub(crate) enum ReviewOrderSubclause {
|
||||||
DifficultyAscending,
|
DifficultyAscending,
|
||||||
/// FSRS
|
/// FSRS
|
||||||
DifficultyDescending,
|
DifficultyDescending,
|
||||||
RetrievabilitySm2 {
|
|
||||||
today: u32,
|
|
||||||
order: SqlSortOrder,
|
|
||||||
},
|
|
||||||
RetrievabilityFsrs {
|
RetrievabilityFsrs {
|
||||||
timing: SchedTimingToday,
|
timing: SchedTimingToday,
|
||||||
order: SqlSortOrder,
|
order: SqlSortOrder,
|
||||||
},
|
},
|
||||||
|
RelativeOverdueness {
|
||||||
|
fsrs: bool,
|
||||||
|
timing: SchedTimingToday,
|
||||||
|
},
|
||||||
Added,
|
Added,
|
||||||
ReverseAdded,
|
ReverseAdded,
|
||||||
}
|
}
|
||||||
|
|
@ -825,19 +825,26 @@ impl fmt::Display for ReviewOrderSubclause {
|
||||||
ReviewOrderSubclause::EaseDescending => "factor desc",
|
ReviewOrderSubclause::EaseDescending => "factor desc",
|
||||||
ReviewOrderSubclause::DifficultyAscending => "extract_fsrs_variable(data, 'd') asc",
|
ReviewOrderSubclause::DifficultyAscending => "extract_fsrs_variable(data, 'd') asc",
|
||||||
ReviewOrderSubclause::DifficultyDescending => "extract_fsrs_variable(data, 'd') desc",
|
ReviewOrderSubclause::DifficultyDescending => "extract_fsrs_variable(data, 'd') desc",
|
||||||
ReviewOrderSubclause::RetrievabilitySm2 { today, order } => {
|
|
||||||
temp_string = format!(
|
|
||||||
// - (elapsed days+0.001)/(scheduled interval)
|
|
||||||
"-(1 + cast({today}-due+0.001 as real)/ivl) {order}"
|
|
||||||
);
|
|
||||||
&temp_string
|
|
||||||
}
|
|
||||||
ReviewOrderSubclause::RetrievabilityFsrs { timing, order } => {
|
ReviewOrderSubclause::RetrievabilityFsrs { timing, order } => {
|
||||||
let today = timing.days_elapsed;
|
let today = timing.days_elapsed;
|
||||||
let next_day_at = timing.next_day_at.0;
|
let next_day_at = timing.next_day_at.0;
|
||||||
let now = timing.now.0;
|
let now = timing.now.0;
|
||||||
temp_string =
|
temp_string =
|
||||||
format!("extract_fsrs_relative_retrievability(data, case when odue !=0 then odue else due end, ivl, {today}, {next_day_at}, {now}) {order}");
|
format!("extract_fsrs_retrievability(data, case when odue !=0 then odue else due end, ivl, {today}, {next_day_at}, {now}) {order}");
|
||||||
|
&temp_string
|
||||||
|
}
|
||||||
|
ReviewOrderSubclause::RelativeOverdueness { fsrs, timing } => {
|
||||||
|
let today = timing.days_elapsed;
|
||||||
|
let next_day_at = timing.next_day_at.0;
|
||||||
|
let now = timing.now.0;
|
||||||
|
temp_string = if *fsrs {
|
||||||
|
format!("extract_fsrs_relative_retrievability(data, case when odue !=0 then odue else due end, ivl, {today}, {next_day_at}, {now}) asc")
|
||||||
|
} else {
|
||||||
|
format!(
|
||||||
|
// - (elapsed days+0.001)/(scheduled interval)
|
||||||
|
"-(1 + cast({today}-due+0.001 as real)/ivl) asc"
|
||||||
|
)
|
||||||
|
};
|
||||||
&temp_string
|
&temp_string
|
||||||
}
|
}
|
||||||
ReviewOrderSubclause::Added => "nid asc, ord asc",
|
ReviewOrderSubclause::Added => "nid asc, ord asc",
|
||||||
|
|
@ -867,10 +874,19 @@ fn review_order_sql(order: ReviewCardOrder, timing: SchedTimingToday, fsrs: bool
|
||||||
ReviewOrderSubclause::EaseDescending
|
ReviewOrderSubclause::EaseDescending
|
||||||
}],
|
}],
|
||||||
ReviewCardOrder::RetrievabilityAscending => {
|
ReviewCardOrder::RetrievabilityAscending => {
|
||||||
build_retrievability_clauses(fsrs, timing, SqlSortOrder::Ascending)
|
vec![ReviewOrderSubclause::RetrievabilityFsrs {
|
||||||
|
timing,
|
||||||
|
order: SqlSortOrder::Ascending,
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
ReviewCardOrder::RetrievabilityDescending => {
|
ReviewCardOrder::RetrievabilityDescending => {
|
||||||
build_retrievability_clauses(fsrs, timing, SqlSortOrder::Descending)
|
vec![ReviewOrderSubclause::RetrievabilityFsrs {
|
||||||
|
timing,
|
||||||
|
order: SqlSortOrder::Descending,
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
ReviewCardOrder::RelativeOverdueness => {
|
||||||
|
vec![ReviewOrderSubclause::RelativeOverdueness { fsrs, timing }]
|
||||||
}
|
}
|
||||||
ReviewCardOrder::Random => vec![],
|
ReviewCardOrder::Random => vec![],
|
||||||
ReviewCardOrder::Added => vec![ReviewOrderSubclause::Added],
|
ReviewCardOrder::Added => vec![ReviewOrderSubclause::Added],
|
||||||
|
|
@ -885,21 +901,6 @@ fn review_order_sql(order: ReviewCardOrder, timing: SchedTimingToday, fsrs: bool
|
||||||
v.join(", ")
|
v.join(", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_retrievability_clauses(
|
|
||||||
fsrs: bool,
|
|
||||||
timing: SchedTimingToday,
|
|
||||||
order: SqlSortOrder,
|
|
||||||
) -> Vec<ReviewOrderSubclause> {
|
|
||||||
vec![if fsrs {
|
|
||||||
ReviewOrderSubclause::RetrievabilityFsrs { timing, order }
|
|
||||||
} else {
|
|
||||||
ReviewOrderSubclause::RetrievabilitySm2 {
|
|
||||||
today: timing.days_elapsed,
|
|
||||||
order,
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub(crate) enum NewCardSorting {
|
pub(crate) enum NewCardSorting {
|
||||||
/// Ascending position, consecutive siblings,
|
/// Ascending position, consecutive siblings,
|
||||||
|
|
|
||||||
|
|
@ -654,7 +654,7 @@ impl SqliteStorage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum SqlSortOrder {
|
pub enum SqlSortOrder {
|
||||||
Ascending,
|
Ascending,
|
||||||
Descending,
|
Descending,
|
||||||
|
|
@ -686,8 +686,7 @@ mod test {
|
||||||
col.answer_easy();
|
col.answer_easy();
|
||||||
|
|
||||||
let timing = col.timing_today()?;
|
let timing = col.timing_today()?;
|
||||||
let order = SqlSortOrder::Ascending;
|
let sql_func = ReviewOrderSubclause::RelativeOverdueness { fsrs: true, timing }
|
||||||
let sql_func = ReviewOrderSubclause::RetrievabilityFsrs { timing, order }
|
|
||||||
.to_string()
|
.to_string()
|
||||||
.replace(" asc", "");
|
.replace(" asc", "");
|
||||||
let sql = format!("select {sql_func} from cards");
|
let sql = format!("select {sql_func} from cards");
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,9 @@ export function newSortOrderChoices(): Choice<DeckConfig_Config_NewCardSortOrder
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function reviewOrderChoices(fsrs: boolean): Choice<DeckConfig_Config_ReviewCardOrder>[] {
|
export function reviewOrderChoices(
|
||||||
|
fsrs: boolean,
|
||||||
|
): Choice<DeckConfig_Config_ReviewCardOrder>[] {
|
||||||
return [
|
return [
|
||||||
...[
|
...[
|
||||||
{
|
{
|
||||||
|
|
@ -94,14 +96,11 @@ export function reviewOrderChoices(fsrs: boolean): Choice<DeckConfig_Config_Revi
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
...difficultyOrders(fsrs),
|
...difficultyOrders(fsrs),
|
||||||
|
...retrievabilityOrders(fsrs),
|
||||||
...[
|
...[
|
||||||
{
|
{
|
||||||
label: tr.deckConfigSortOrderRetrievabilityAscending(),
|
label: tr.decksRelativeOverdueness(),
|
||||||
value: DeckConfig_Config_ReviewCardOrder.RETRIEVABILITY_ASCENDING,
|
value: DeckConfig_Config_ReviewCardOrder.RELATIVE_OVERDUENESS,
|
||||||
},
|
|
||||||
{
|
|
||||||
label: tr.deckConfigSortOrderRetrievabilityDescending(),
|
|
||||||
value: DeckConfig_Config_ReviewCardOrder.RETRIEVABILITY_DESCENDING,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: tr.deckConfigSortOrderRandom(),
|
label: tr.deckConfigSortOrderRandom(),
|
||||||
|
|
@ -202,11 +201,15 @@ export function questionActionChoices(): Choice<DeckConfig_Config_QuestionAction
|
||||||
function difficultyOrders(fsrs: boolean): Choice<DeckConfig_Config_ReviewCardOrder>[] {
|
function difficultyOrders(fsrs: boolean): Choice<DeckConfig_Config_ReviewCardOrder>[] {
|
||||||
const order = [
|
const order = [
|
||||||
{
|
{
|
||||||
label: fsrs ? tr.deckConfigSortOrderDescendingDifficulty() : tr.deckConfigSortOrderAscendingEase(),
|
label: fsrs
|
||||||
|
? tr.deckConfigSortOrderDescendingDifficulty()
|
||||||
|
: tr.deckConfigSortOrderAscendingEase(),
|
||||||
value: DeckConfig_Config_ReviewCardOrder.EASE_ASCENDING,
|
value: DeckConfig_Config_ReviewCardOrder.EASE_ASCENDING,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: fsrs ? tr.deckConfigSortOrderAscendingDifficulty() : tr.deckConfigSortOrderDescendingEase(),
|
label: fsrs
|
||||||
|
? tr.deckConfigSortOrderAscendingDifficulty()
|
||||||
|
: tr.deckConfigSortOrderDescendingEase(),
|
||||||
value: DeckConfig_Config_ReviewCardOrder.EASE_DESCENDING,
|
value: DeckConfig_Config_ReviewCardOrder.EASE_DESCENDING,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
@ -215,3 +218,21 @@ function difficultyOrders(fsrs: boolean): Choice<DeckConfig_Config_ReviewCardOrd
|
||||||
}
|
}
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function retrievabilityOrders(
|
||||||
|
fsrs: boolean,
|
||||||
|
): Choice<DeckConfig_Config_ReviewCardOrder>[] {
|
||||||
|
if (!fsrs) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: tr.deckConfigSortOrderRetrievabilityAscending(),
|
||||||
|
value: DeckConfig_Config_ReviewCardOrder.RETRIEVABILITY_ASCENDING,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: tr.deckConfigSortOrderRetrievabilityDescending(),
|
||||||
|
value: DeckConfig_Config_ReviewCardOrder.RETRIEVABILITY_DESCENDING,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue