mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
fix deck tree with a day delta, and support arbitrary timestamps
This commit is contained in:
parent
08b5718fe0
commit
19541c4a9d
7 changed files with 26 additions and 31 deletions
|
@ -545,9 +545,9 @@ message SchedTimingTodayOut {
|
||||||
}
|
}
|
||||||
|
|
||||||
message DeckTreeIn {
|
message DeckTreeIn {
|
||||||
bool include_counts = 1;
|
// if non-zero, counts for the provided timestamp will be included
|
||||||
|
int64 now = 1;
|
||||||
int64 top_deck_id = 2;
|
int64 top_deck_id = 2;
|
||||||
int32 today_delta = 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message DeckTreeNode {
|
message DeckTreeNode {
|
||||||
|
|
|
@ -140,9 +140,7 @@ class DeckManager:
|
||||||
return from_json_bytes(self.col.backend.new_deck_legacy(filtered))
|
return from_json_bytes(self.col.backend.new_deck_legacy(filtered))
|
||||||
|
|
||||||
def deck_tree(self) -> pb.DeckTreeNode:
|
def deck_tree(self) -> pb.DeckTreeNode:
|
||||||
return self.col.backend.deck_tree(
|
return self.col.backend.deck_tree(top_deck_id=0, now=0)
|
||||||
include_counts=False, top_deck_id=0, today_delta=0
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def find_deck_in_tree(
|
def find_deck_in_tree(
|
||||||
|
|
|
@ -241,9 +241,7 @@ order by due"""
|
||||||
def deck_due_tree(self, top_deck_id: int = 0) -> DeckTreeNode:
|
def deck_due_tree(self, top_deck_id: int = 0) -> DeckTreeNode:
|
||||||
"""Returns a tree of decks with counts.
|
"""Returns a tree of decks with counts.
|
||||||
If top_deck_id provided, counts are limited to that node."""
|
If top_deck_id provided, counts are limited to that node."""
|
||||||
return self.col.backend.deck_tree(
|
return self.col.backend.deck_tree(top_deck_id=top_deck_id, now=intTime())
|
||||||
include_counts=True, top_deck_id=top_deck_id, today_delta=0
|
|
||||||
)
|
|
||||||
|
|
||||||
# Getting the next card
|
# Getting the next card
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
|
@ -526,12 +526,12 @@ impl BackendService for Backend {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
self.with_col(|col| {
|
self.with_col(|col| {
|
||||||
let today = if input.include_counts {
|
let now = if input.now == 0 {
|
||||||
Some(col.current_due_day(input.today_delta)?)
|
|
||||||
} else {
|
|
||||||
None
|
None
|
||||||
|
} else {
|
||||||
|
Some(TimestampSecs(input.now))
|
||||||
};
|
};
|
||||||
col.deck_tree(today, lim)
|
col.deck_tree(now, lim)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,13 @@ pub(crate) struct DueCounts {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Collection {
|
impl Collection {
|
||||||
|
/// Get due counts for decks at the given timestamp.
|
||||||
pub(crate) fn due_counts(
|
pub(crate) fn due_counts(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
days_elapsed: u32,
|
||||||
|
learn_cutoff: u32,
|
||||||
limit_to: Option<&str>,
|
limit_to: Option<&str>,
|
||||||
) -> Result<HashMap<DeckID, DueCounts>> {
|
) -> Result<HashMap<DeckID, DueCounts>> {
|
||||||
let days_elapsed = self.timing_today()?.days_elapsed;
|
|
||||||
let learn_cutoff = self.learn_cutoff();
|
|
||||||
if let Some(limit) = limit_to {
|
if let Some(limit) = limit_to {
|
||||||
self.storage
|
self.storage
|
||||||
.due_counts_limited(self.sched_ver(), days_elapsed, learn_cutoff, limit)
|
.due_counts_limited(self.sched_ver(), days_elapsed, learn_cutoff, limit)
|
||||||
|
|
|
@ -8,6 +8,7 @@ use crate::{
|
||||||
deckconf::{DeckConf, DeckConfID},
|
deckconf::{DeckConf, DeckConfID},
|
||||||
decks::DeckID,
|
decks::DeckID,
|
||||||
err::Result,
|
err::Result,
|
||||||
|
timestamp::TimestampSecs,
|
||||||
};
|
};
|
||||||
use serde_tuple::Serialize_tuple;
|
use serde_tuple::Serialize_tuple;
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -208,13 +209,13 @@ impl From<DeckTreeNode> for LegacyDueCounts {
|
||||||
|
|
||||||
impl Collection {
|
impl Collection {
|
||||||
/// Get the deck tree.
|
/// Get the deck tree.
|
||||||
/// If today is provided, due counts for the provided day will be populated.
|
/// If now is provided, due counts for the provided timestamp will be populated.
|
||||||
/// If top_deck_id is provided, only the node starting at the provided deck ID will
|
/// If top_deck_id is provided, only the node starting at the provided deck ID will
|
||||||
/// have the counts populated. Currently the entire tree is returned in this case, but
|
/// have the counts populated. Currently the entire tree is returned in this case, but
|
||||||
/// this may change in the future.
|
/// this may change in the future.
|
||||||
pub fn deck_tree(
|
pub fn deck_tree(
|
||||||
&mut self,
|
&mut self,
|
||||||
today: Option<u32>,
|
now: Option<TimestampSecs>,
|
||||||
top_deck_id: Option<DeckID>,
|
top_deck_id: Option<DeckID>,
|
||||||
) -> Result<DeckTreeNode> {
|
) -> Result<DeckTreeNode> {
|
||||||
let names = self.storage.get_all_deck_names()?;
|
let names = self.storage.get_all_deck_names()?;
|
||||||
|
@ -227,12 +228,12 @@ impl Collection {
|
||||||
.map(|d| (d.id, d))
|
.map(|d| (d.id, d))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
add_collapsed_and_filtered(&mut tree, &decks_map, today.is_none());
|
add_collapsed_and_filtered(&mut tree, &decks_map, now.is_none());
|
||||||
if self.default_deck_is_empty()? {
|
if self.default_deck_is_empty()? {
|
||||||
hide_default_deck(&mut tree);
|
hide_default_deck(&mut tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(today) = today {
|
if let Some(now) = now {
|
||||||
let limit = top_deck_id.and_then(|did| {
|
let limit = top_deck_id.and_then(|did| {
|
||||||
if let Some(deck) = decks_map.get(&did) {
|
if let Some(deck) = decks_map.get(&did) {
|
||||||
Some(deck.name.as_str())
|
Some(deck.name.as_str())
|
||||||
|
@ -240,7 +241,9 @@ impl Collection {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let counts = self.due_counts(limit)?;
|
let days_elapsed = self.timing_for_timestamp(now)?.days_elapsed;
|
||||||
|
let learn_cutoff = (now.0 as u32) + self.learn_ahead_secs();
|
||||||
|
let counts = self.due_counts(days_elapsed, learn_cutoff, limit)?;
|
||||||
let dconf: HashMap<_, _> = self
|
let dconf: HashMap<_, _> = self
|
||||||
.storage
|
.storage
|
||||||
.all_deck_config()?
|
.all_deck_config()?
|
||||||
|
@ -250,7 +253,7 @@ impl Collection {
|
||||||
add_counts(&mut tree, &counts);
|
add_counts(&mut tree, &counts);
|
||||||
apply_limits(
|
apply_limits(
|
||||||
&mut tree,
|
&mut tree,
|
||||||
today,
|
days_elapsed,
|
||||||
&decks_map,
|
&decks_map,
|
||||||
&dconf,
|
&dconf,
|
||||||
(std::u32::MAX, std::u32::MAX),
|
(std::u32::MAX, std::u32::MAX),
|
||||||
|
@ -262,14 +265,12 @@ impl Collection {
|
||||||
|
|
||||||
pub fn current_deck_tree(&mut self) -> Result<Option<DeckTreeNode>> {
|
pub fn current_deck_tree(&mut self) -> Result<Option<DeckTreeNode>> {
|
||||||
let target = self.get_current_deck_id();
|
let target = self.get_current_deck_id();
|
||||||
let today = self.current_due_day(0)?;
|
let tree = self.deck_tree(Some(TimestampSecs::now()), Some(target))?;
|
||||||
let tree = self.deck_tree(Some(today), Some(target))?;
|
|
||||||
Ok(get_subnode(tree, target))
|
Ok(get_subnode(tree, target))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn legacy_deck_tree(&mut self) -> Result<LegacyDueCounts> {
|
pub(crate) fn legacy_deck_tree(&mut self) -> Result<LegacyDueCounts> {
|
||||||
let today = self.current_due_day(0)?;
|
let tree = self.deck_tree(Some(TimestampSecs::now()), None)?;
|
||||||
let tree = self.deck_tree(Some(today), None)?;
|
|
||||||
Ok(LegacyDueCounts::from(tree))
|
Ok(LegacyDueCounts::from(tree))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,6 +294,7 @@ impl Collection {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
use super::*;
|
||||||
use crate::{collection::open_test_collection, deckconf::DeckConfID, err::Result};
|
use crate::{collection::open_test_collection, deckconf::DeckConfID, err::Result};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -349,7 +351,7 @@ mod test {
|
||||||
note.fields[0] = "{{c1::}} {{c2::}} {{c3::}} {{c4::}}".into();
|
note.fields[0] = "{{c1::}} {{c2::}} {{c3::}} {{c4::}}".into();
|
||||||
col.add_note(&mut note, child_deck.id)?;
|
col.add_note(&mut note, child_deck.id)?;
|
||||||
|
|
||||||
let tree = col.deck_tree(Some(0), None)?;
|
let tree = col.deck_tree(Some(TimestampSecs::now()), None)?;
|
||||||
assert_eq!(tree.children[0].new_count, 4);
|
assert_eq!(tree.children[0].new_count, 4);
|
||||||
assert_eq!(tree.children[0].children[0].new_count, 4);
|
assert_eq!(tree.children[0].children[0].new_count, 4);
|
||||||
|
|
||||||
|
@ -360,7 +362,7 @@ mod test {
|
||||||
col.add_or_update_deck(&mut parent_deck)?;
|
col.add_or_update_deck(&mut parent_deck)?;
|
||||||
|
|
||||||
// with the default limit of 20, there should still be 4 due
|
// with the default limit of 20, there should still be 4 due
|
||||||
let tree = col.deck_tree(Some(0), None)?;
|
let tree = col.deck_tree(Some(TimestampSecs::now()), None)?;
|
||||||
assert_eq!(tree.children[0].new_count, 4);
|
assert_eq!(tree.children[0].new_count, 4);
|
||||||
assert_eq!(tree.children[0].children[0].new_count, 4);
|
assert_eq!(tree.children[0].children[0].new_count, 4);
|
||||||
|
|
||||||
|
@ -369,7 +371,7 @@ mod test {
|
||||||
conf.inner.new_per_day = 4;
|
conf.inner.new_per_day = 4;
|
||||||
col.add_or_update_deck_config(&mut conf, false)?;
|
col.add_or_update_deck_config(&mut conf, false)?;
|
||||||
|
|
||||||
let tree = col.deck_tree(Some(0), None)?;
|
let tree = col.deck_tree(Some(TimestampSecs::now()), None)?;
|
||||||
assert_eq!(tree.children[0].new_count, 3);
|
assert_eq!(tree.children[0].new_count, 3);
|
||||||
assert_eq!(tree.children[0].children[0].new_count, 3);
|
assert_eq!(tree.children[0].children[0].new_count, 3);
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,4 @@ impl Collection {
|
||||||
SchedulerVersion::V2 => self.set_v2_rollover(hour as u32),
|
SchedulerVersion::V2 => self.set_v2_rollover(hour as u32),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn learn_cutoff(&self) -> u32 {
|
|
||||||
TimestampSecs::now().0 as u32 + self.learn_ahead_secs()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue