mirror of
https://github.com/ankitects/anki.git
synced 2025-12-10 21:36:55 -05:00
The old rescheduling dialog's two options have been split into two separate menu items, "Forget", and "Set Due Date" For cards that are not review cards, "Set Due Date" behaves like the old reschedule option, changing the cards into a review card, and and setting both the interval and due date to the provided number of days. When "Set Due Date" is applied to a review card, it no longer resets the card's interval. Instead, it looks at how much the provided number of days will change the original interval, and adjusts the interval by that amount, so that cards that are answered earlier receive a smaller next interval, and cards that are answered after a longer delay receive a bonus. For example, imagine a card was answered on day 5, and given an interval of 10 days, so it has a due date of day 15. - if on day 10 the due date is changed to day 12 (today+2), the card is being scheduled 3 days earlier than it was supposed to be, so the interval will be adjusted to 7 days. - and if on day 10 the due date is changed to day 20, the interval will be changed from 10 days to 15 days. There is no separate option to reset the interval of a review card, but it can be accomplished by forgetting the card(s), and then setting the desired due date. Other notes: - Added the action to the review screen as well. - Set the shortcut to Ctrl+Shift+D, and changed the existing Delete Tags shortcut to Ctrl+Alt+Shift+A.
110 lines
3.7 KiB
Rust
110 lines
3.7 KiB
Rust
// Copyright: Ankitects Pty Ltd and contributors
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
use crate::{collection::Collection, config::SchedulerVersion, err::Result, prelude::*};
|
|
|
|
pub mod bury_and_suspend;
|
|
pub(crate) mod congrats;
|
|
pub mod cutoff;
|
|
mod learning;
|
|
pub mod new;
|
|
mod reviews;
|
|
pub mod timespan;
|
|
|
|
use chrono::FixedOffset;
|
|
use cutoff::{
|
|
sched_timing_today, v1_creation_date_adjusted_to_hour, v1_rollover_from_creation_stamp,
|
|
SchedTimingToday,
|
|
};
|
|
pub use reviews::parse_due_date_str;
|
|
|
|
impl Collection {
|
|
pub fn timing_today(&self) -> Result<SchedTimingToday> {
|
|
self.timing_for_timestamp(TimestampSecs::now())
|
|
}
|
|
|
|
pub fn current_due_day(&mut self, delta: i32) -> Result<u32> {
|
|
Ok(((self.timing_today()?.days_elapsed as i32) + delta).max(0) as u32)
|
|
}
|
|
|
|
pub(crate) fn timing_for_timestamp(&self, now: TimestampSecs) -> Result<SchedTimingToday> {
|
|
let current_utc_offset = self.local_utc_offset_for_user()?;
|
|
|
|
let rollover_hour = match self.sched_ver() {
|
|
SchedulerVersion::V1 => None,
|
|
SchedulerVersion::V2 => {
|
|
let configured_rollover = self.get_v2_rollover();
|
|
match configured_rollover {
|
|
None => {
|
|
// an older Anki version failed to set this; correct
|
|
// the issue
|
|
self.set_v2_rollover(4)?;
|
|
Some(4)
|
|
}
|
|
val => val,
|
|
}
|
|
}
|
|
};
|
|
|
|
Ok(sched_timing_today(
|
|
self.storage.creation_stamp()?,
|
|
now,
|
|
self.creation_utc_offset(),
|
|
current_utc_offset,
|
|
rollover_hour,
|
|
))
|
|
}
|
|
|
|
/// In the client case, return the current local timezone offset,
|
|
/// ensuring the config reflects the current value.
|
|
/// In the server case, return the value set in the config, and
|
|
/// fall back on UTC if it's missing/invalid.
|
|
pub(crate) fn local_utc_offset_for_user(&self) -> Result<FixedOffset> {
|
|
let config_tz = self
|
|
.get_configured_utc_offset()
|
|
.and_then(|v| FixedOffset::west_opt(v * 60))
|
|
.unwrap_or_else(|| FixedOffset::west(0));
|
|
|
|
let local_tz = TimestampSecs::now().local_utc_offset();
|
|
|
|
Ok(if self.server {
|
|
config_tz
|
|
} else {
|
|
// if the timezone has changed, update the config
|
|
if config_tz != local_tz {
|
|
self.set_configured_utc_offset(local_tz.utc_minus_local() / 60)?;
|
|
}
|
|
local_tz
|
|
})
|
|
}
|
|
|
|
/// Return the timezone offset at collection creation time. This should
|
|
/// only be set when the V2 scheduler is active and the new timezone
|
|
/// code is enabled.
|
|
fn creation_utc_offset(&self) -> Option<FixedOffset> {
|
|
self.get_creation_utc_offset()
|
|
.and_then(|v| FixedOffset::west_opt(v * 60))
|
|
}
|
|
|
|
pub fn rollover_for_current_scheduler(&self) -> Result<u8> {
|
|
match self.sched_ver() {
|
|
SchedulerVersion::V1 => Ok(v1_rollover_from_creation_stamp(
|
|
self.storage.creation_stamp()?.0,
|
|
)),
|
|
SchedulerVersion::V2 => Ok(self.get_v2_rollover().unwrap_or(4)),
|
|
}
|
|
}
|
|
|
|
pub(crate) fn set_rollover_for_current_scheduler(&self, hour: u8) -> Result<()> {
|
|
match self.sched_ver() {
|
|
SchedulerVersion::V1 => {
|
|
self.storage
|
|
.set_creation_stamp(TimestampSecs(v1_creation_date_adjusted_to_hour(
|
|
self.storage.creation_stamp()?.0,
|
|
hour,
|
|
)))
|
|
}
|
|
SchedulerVersion::V2 => self.set_v2_rollover(hour as u32),
|
|
}
|
|
}
|
|
}
|