Clear memory states during bulk action if item is None (#3717)

* Clear memory states during bulk action if item is None

Prevents issues like https://forums.ankiweb.net/t/suggestion-copy-card-debug-info-button/54206/10 and https://github.com/ankitects/anki/issues/3634

* Fix entries not being removed if ignore_before_date after the last grade

* Fix test failure

* Also clear memory states when rescheduling using FSRS helper add-on if item is None
This commit is contained in:
user1823 2025-01-15 15:19:15 +05:30 committed by GitHub
parent 146a0b2dcf
commit 5ef2328ea4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 8 deletions

View file

@ -85,8 +85,8 @@ impl Collection {
progress.update(true, |state| state.current_cards = idx as u32 + 1)?;
let mut card = self.storage.get_card(card_id)?.or_not_found(card_id)?;
let original = card.clone();
if let Some(req) = &req {
card.set_memory_state(&fsrs, item, historical_retention.unwrap())?;
if let (Some(req), Some(item)) = (&req, item) {
card.set_memory_state(&fsrs, Some(item), historical_retention.unwrap())?;
card.desired_retention = desired_retention;
// if rescheduling
if let Some(reviews) = &last_revlog_info {
@ -163,11 +163,20 @@ impl Collection {
historical_retention,
ignore_revlogs_before_ms_from_config(&config)?,
)?;
card.set_memory_state(&fsrs, item, historical_retention)?;
Ok(ComputeMemoryStateResponse {
state: card.memory_state.map(Into::into),
desired_retention,
})
if item.is_some() {
card.set_memory_state(&fsrs, item, historical_retention)?;
Ok(ComputeMemoryStateResponse {
state: card.memory_state.map(Into::into),
desired_retention,
})
} else {
card.memory_state = None;
card.desired_retention = None;
Ok(ComputeMemoryStateResponse {
state: None,
desired_retention,
})
}
}
}

View file

@ -340,6 +340,9 @@ pub(crate) fn reviews_for_fsrs(
if idx > 0 {
entries.drain(..idx);
}
} else {
// if no valid user grades were found, ignore the card.
return None;
}
// Filter out unwanted entries
@ -424,7 +427,7 @@ fn revlog_entry_to_proto(e: RevlogEntry) -> anki_proto::stats::RevlogEntry {
pub(crate) mod tests {
use super::*;
const NEXT_DAY_AT: TimestampSecs = TimestampSecs(86400 * 100);
const NEXT_DAY_AT: TimestampSecs = TimestampSecs(86400 * 1000);
fn days_ago_ms(days_ago: i64) -> TimestampMillis {
((NEXT_DAY_AT.0 - days_ago * 86400) * 1000).into()
@ -709,4 +712,14 @@ pub(crate) mod tests {
2
);
}
#[test]
fn ignore_before_after_last_revlog_entry() {
let revlogs = &[
revlog(RevlogReviewKind::Learning, 10),
revlog(RevlogReviewKind::Review, 6),
];
// L R |
assert_eq!(convert_ignore_before(revlogs, false, days_ago_ms(4)), None);
}
}