diff --git a/proto/anki/deck_config.proto b/proto/anki/deck_config.proto index 22ecc8c60..7686a2d85 100644 --- a/proto/anki/deck_config.proto +++ b/proto/anki/deck_config.proto @@ -43,6 +43,9 @@ message DeckConfig { // Decks in alphabetical order (preorder), then ascending position. // Siblings are consecutive, provided they have the same position. NEW_CARD_GATHER_PRIORITY_DECK = 0; + // Notes are randomly picked from each deck in alphabetical order. + // Siblings are consecutive, provided they have the same position. + NEW_CARD_GATHER_PRIORITY_DECK_THEN_RANDOM_NOTES = 5; // Ascending position. // Siblings are consecutive, provided they have the same position. NEW_CARD_GATHER_PRIORITY_LOWEST_POSITION = 1; diff --git a/rslib/src/scheduler/queue/builder/gathering.rs b/rslib/src/scheduler/queue/builder/gathering.rs index 6aad83f7c..349951098 100644 --- a/rslib/src/scheduler/queue/builder/gathering.rs +++ b/rslib/src/scheduler/queue/builder/gathering.rs @@ -62,7 +62,13 @@ impl QueueBuilder { fn gather_new_cards(&mut self, col: &mut Collection) -> Result<()> { match self.context.sort_options.new_gather_priority { - NewCardGatherPriority::Deck => self.gather_new_cards_by_deck(col), + NewCardGatherPriority::Deck => { + self.gather_new_cards_by_deck(col, NewCardSorting::LowestPosition) + } + NewCardGatherPriority::DeckThenRandomNotes => self.gather_new_cards_by_deck( + col, + NewCardSorting::RandomNotes(self.context.timing.days_elapsed), + ), NewCardGatherPriority::LowestPosition => { self.gather_new_cards_sorted(col, NewCardSorting::LowestPosition) } @@ -80,7 +86,11 @@ impl QueueBuilder { } } - fn gather_new_cards_by_deck(&mut self, col: &mut Collection) -> Result<()> { + fn gather_new_cards_by_deck( + &mut self, + col: &mut Collection, + sort: NewCardSorting, + ) -> Result<()> { for deck_id in self.limits.active_decks() { if self.limits.root_limit_reached(LimitKind::New) { break; @@ -88,14 +98,15 @@ impl QueueBuilder { if self.limits.limit_reached(deck_id, LimitKind::New)? { continue; } - col.storage.for_each_new_card_in_deck(deck_id, |card| { - let limit_reached = self.limits.limit_reached(deck_id, LimitKind::New)?; - if !limit_reached && self.add_new_card(card) { - self.limits - .decrement_deck_and_parent_limits(deck_id, LimitKind::New)?; - } - Ok(!limit_reached) - })?; + col.storage + .for_each_new_card_in_deck(deck_id, sort, |card| { + let limit_reached = self.limits.limit_reached(deck_id, LimitKind::New)?; + if !limit_reached && self.add_new_card(card) { + self.limits + .decrement_deck_and_parent_limits(deck_id, LimitKind::New)?; + } + Ok(!limit_reached) + })?; } Ok(()) diff --git a/rslib/src/storage/card/mod.rs b/rslib/src/storage/card/mod.rs index c8d77b5dd..c17479128 100644 --- a/rslib/src/storage/card/mod.rs +++ b/rslib/src/storage/card/mod.rs @@ -289,13 +289,19 @@ impl super::SqliteStorage { /// Call func() for each new card in the provided deck, stopping when it /// returns or no more cards found. - pub(crate) fn for_each_new_card_in_deck(&self, deck: DeckId, mut func: F) -> Result<()> + pub(crate) fn for_each_new_card_in_deck( + &self, + deck: DeckId, + sort: NewCardSorting, + mut func: F, + ) -> Result<()> where F: FnMut(NewCard) -> Result, { let mut stmt = self.db.prepare_cached(&format!( - "{} ORDER BY due, ord ASC", - include_str!("new_cards.sql") + "{} ORDER BY {}", + include_str!("new_cards.sql"), + sort.write() ))?; let mut rows = stmt.query(params![deck])?; while let Some(row) = rows.next()? {