mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 06:22:22 -04:00
Allow user to configure hard/good buttons when rescheduling off
Closes #2858
This commit is contained in:
parent
fdcdc14f6b
commit
e778cba089
13 changed files with 163 additions and 155 deletions
|
@ -25,7 +25,9 @@ decks-order-due = Order due
|
||||||
decks-please-select-something = Please select something.
|
decks-please-select-something = Please select something.
|
||||||
decks-random = Random
|
decks-random = Random
|
||||||
decks-relative-overdueness = Relative overdueness
|
decks-relative-overdueness = Relative overdueness
|
||||||
decks-repeat-failed-cards-after = Repeat failed cards after
|
decks-repeat-failed-cards-after = Delay Repeat failed cards after
|
||||||
|
# e.g. "Delay for Again", "Delay for Hard", "Delay for Good"
|
||||||
|
decks-delay-for-button = Delay for { $button }
|
||||||
decks-reschedule-cards-based-on-my-answers = Reschedule cards based on my answers in this deck
|
decks-reschedule-cards-based-on-my-answers = Reschedule cards based on my answers in this deck
|
||||||
decks-study = Study
|
decks-study = Study
|
||||||
decks-study-deck = Study Deck
|
decks-study-deck = Study Deck
|
||||||
|
|
|
@ -110,7 +110,11 @@ message Deck {
|
||||||
// v1 scheduler only
|
// v1 scheduler only
|
||||||
repeated float delays = 3;
|
repeated float delays = 3;
|
||||||
// v2 scheduler only
|
// v2 scheduler only
|
||||||
uint32 preview_delay = 4;
|
uint32 preview_again_mins = 4;
|
||||||
|
// recent v3 scheduler only; 0 means card will be returned
|
||||||
|
uint32 preview_hard_mins = 5;
|
||||||
|
// recent v3 scheduler only; 0 means card will be returned
|
||||||
|
uint32 preview_good_mins = 6;
|
||||||
}
|
}
|
||||||
// a container to store the deck specifics in the DB
|
// a container to store the deck specifics in the DB
|
||||||
// as a tagged enum
|
// as a tagged enum
|
||||||
|
|
|
@ -740,7 +740,7 @@ def test_preview():
|
||||||
|
|
||||||
passing_grade = 4
|
passing_grade = 4
|
||||||
assert col.sched.answerButtons(c) == passing_grade
|
assert col.sched.answerButtons(c) == passing_grade
|
||||||
assert col.sched.nextIvl(c, 1) == 600
|
assert col.sched.nextIvl(c, 1) == 60
|
||||||
assert col.sched.nextIvl(c, passing_grade) == 0
|
assert col.sched.nextIvl(c, passing_grade) == 0
|
||||||
|
|
||||||
# failing it will push its due time back
|
# failing it will push its due time back
|
||||||
|
|
|
@ -100,6 +100,16 @@ class FilteredDeckConfigDialog(QDialog):
|
||||||
self.form.buttonBox.helpRequested, lambda: openHelp(HelpPage.FILTERED_DECK)
|
self.form.buttonBox.helpRequested, lambda: openHelp(HelpPage.FILTERED_DECK)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.form.again_delay_label.setText(
|
||||||
|
tr.decks_delay_for_button(button=tr.studying_again())
|
||||||
|
)
|
||||||
|
self.form.hard_delay_label.setText(
|
||||||
|
tr.decks_delay_for_button(button=tr.studying_hard())
|
||||||
|
)
|
||||||
|
self.form.good_delay_label.setText(
|
||||||
|
tr.decks_delay_for_button(button=tr.studying_good())
|
||||||
|
)
|
||||||
|
|
||||||
restoreGeom(self, self.GEOMETRY_KEY)
|
restoreGeom(self, self.GEOMETRY_KEY)
|
||||||
|
|
||||||
def load_deck_and_show(self, deck: FilteredDeckForUpdate) -> None:
|
def load_deck_and_show(self, deck: FilteredDeckForUpdate) -> None:
|
||||||
|
@ -132,10 +142,9 @@ class FilteredDeckConfigDialog(QDialog):
|
||||||
form.order.setCurrentIndex(term1.order)
|
form.order.setCurrentIndex(term1.order)
|
||||||
form.limit.setValue(term1.limit)
|
form.limit.setValue(term1.limit)
|
||||||
|
|
||||||
form.steps.setVisible(False)
|
form.preview_again.setValue(config.preview_again_mins)
|
||||||
form.stepsOn.setVisible(False)
|
form.preview_hard.setValue(config.preview_hard_mins)
|
||||||
|
form.preview_good.setValue(config.preview_good_mins)
|
||||||
form.previewDelay.setValue(config.preview_delay)
|
|
||||||
|
|
||||||
if len(config.search_terms) > 1:
|
if len(config.search_terms) > 1:
|
||||||
term2: FilteredDeckConfig.SearchTerm = config.search_terms[1]
|
term2: FilteredDeckConfig.SearchTerm = config.search_terms[1]
|
||||||
|
@ -268,7 +277,9 @@ class FilteredDeckConfigDialog(QDialog):
|
||||||
|
|
||||||
del config.search_terms[:]
|
del config.search_terms[:]
|
||||||
config.search_terms.extend(terms)
|
config.search_terms.extend(terms)
|
||||||
config.preview_delay = form.previewDelay.value()
|
config.preview_again_mins = form.preview_again.value()
|
||||||
|
config.preview_hard_mins = form.preview_hard.value()
|
||||||
|
config.preview_good_mins = form.preview_good.value()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -293,32 +304,3 @@ class FilteredDeckConfigDialog(QDialog):
|
||||||
add_or_update_filtered_deck(parent=self, deck=self.deck).success(
|
add_or_update_filtered_deck(parent=self, deck=self.deck).success(
|
||||||
success
|
success
|
||||||
).run_in_background()
|
).run_in_background()
|
||||||
|
|
||||||
# Step load/save
|
|
||||||
########################################################
|
|
||||||
# fixme: remove once we drop support for v1
|
|
||||||
|
|
||||||
def listToUser(self, values: list[Union[float, int]]) -> str:
|
|
||||||
return " ".join(
|
|
||||||
[str(int(val)) if int(val) == val else str(val) for val in values]
|
|
||||||
)
|
|
||||||
|
|
||||||
def userToList(self, line: QLineEdit, minSize: int = 1) -> list[float] | None:
|
|
||||||
items = str(line.text()).split(" ")
|
|
||||||
ret = []
|
|
||||||
for item in items:
|
|
||||||
if not item:
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
i = float(item)
|
|
||||||
if i <= 0:
|
|
||||||
raise Exception("0 invalid")
|
|
||||||
ret.append(i)
|
|
||||||
except:
|
|
||||||
# invalid, don't update
|
|
||||||
showWarning(tr.scheduling_steps_must_be_numbers())
|
|
||||||
return None
|
|
||||||
if len(ret) < minSize:
|
|
||||||
showWarning(tr.scheduling_at_least_one_step_is_required())
|
|
||||||
return None
|
|
||||||
return ret
|
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>757</width>
|
<width>526</width>
|
||||||
<height>589</height>
|
<height>567</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -198,13 +198,67 @@
|
||||||
<string>actions_options</string>
|
<string>actions_options</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="0" column="0" colspan="2" alignment="Qt::AlignLeft">
|
<item row="1" column="0">
|
||||||
<widget class="QCheckBox" name="resched">
|
<widget class="QWidget" name="previewDelayWidget" native="true">
|
||||||
|
<layout class="QGridLayout" name="gridLayout_5">
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="good_delay_label">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">good delay</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QSpinBox" name="preview_again"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QSpinBox" name="preview_hard"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QLabel" name="again_delay_label">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">again delay</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2">
|
||||||
|
<widget class="QSpinBox" name="preview_good"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="3">
|
||||||
|
<widget class="QLabel" name="label_13">
|
||||||
|
<property name="text">
|
||||||
|
<string>decks_minutes</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="3" colspan="2">
|
||||||
|
<widget class="QLabel" name="label_9">
|
||||||
|
<property name="text">
|
||||||
|
<string>decks_minutes</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="hard_delay_label">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">hard delay</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="3">
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>decks_minutes</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0" alignment="Qt::AlignLeft">
|
||||||
|
<widget class="QCheckBox" name="allow_empty">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>decks_reschedule_cards_based_on_my_answers</string>
|
<string>decks_create_even_if_empty</string>
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -215,50 +269,13 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="0" column="0" colspan="2" alignment="Qt::AlignLeft">
|
||||||
<widget class="QWidget" name="previewDelayWidget" native="true">
|
<widget class="QCheckBox" name="resched">
|
||||||
<layout class="QHBoxLayout" name="previewDelayBox">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_7">
|
|
||||||
<property name="text">
|
|
||||||
<string>decks_repeat_failed_cards_after</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSpinBox" name="previewDelay"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_8">
|
|
||||||
<property name="text">
|
|
||||||
<string>decks_minutes</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLineEdit" name="steps">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string notr="true">1 10</string>
|
<string>decks_reschedule_cards_based_on_my_answers</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="checked">
|
||||||
</item>
|
<bool>true</bool>
|
||||||
<item row="3" column="0" alignment="Qt::AlignLeft">
|
|
||||||
<widget class="QCheckBox" name="stepsOn">
|
|
||||||
<property name="text">
|
|
||||||
<string>decks_custom_steps_in_minutes</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0" alignment="Qt::AlignLeft">
|
|
||||||
<widget class="QCheckBox" name="allow_empty">
|
|
||||||
<property name="text">
|
|
||||||
<string>decks_create_even_if_empty</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -331,19 +348,18 @@
|
||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>name</tabstop>
|
<tabstop>name</tabstop>
|
||||||
<tabstop>search_button</tabstop>
|
|
||||||
<tabstop>search</tabstop>
|
<tabstop>search</tabstop>
|
||||||
<tabstop>limit</tabstop>
|
<tabstop>limit</tabstop>
|
||||||
<tabstop>order</tabstop>
|
<tabstop>order</tabstop>
|
||||||
<tabstop>search_button_2</tabstop>
|
|
||||||
<tabstop>search_2</tabstop>
|
<tabstop>search_2</tabstop>
|
||||||
<tabstop>limit_2</tabstop>
|
<tabstop>limit_2</tabstop>
|
||||||
<tabstop>order_2</tabstop>
|
<tabstop>order_2</tabstop>
|
||||||
<tabstop>resched</tabstop>
|
<tabstop>resched</tabstop>
|
||||||
<tabstop>previewDelay</tabstop>
|
<tabstop>preview_again</tabstop>
|
||||||
|
<tabstop>preview_hard</tabstop>
|
||||||
|
<tabstop>preview_good</tabstop>
|
||||||
<tabstop>secondFilter</tabstop>
|
<tabstop>secondFilter</tabstop>
|
||||||
<tabstop>stepsOn</tabstop>
|
<tabstop>allow_empty</tabstop>
|
||||||
<tabstop>steps</tabstop>
|
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<connections>
|
||||||
|
@ -395,21 +411,5 @@
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
<connection>
|
|
||||||
<sender>stepsOn</sender>
|
|
||||||
<signal>toggled(bool)</signal>
|
|
||||||
<receiver>steps</receiver>
|
|
||||||
<slot>setEnabled(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>194</x>
|
|
||||||
<y>351</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>190</x>
|
|
||||||
<y>378</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
</connections>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
@ -22,7 +22,8 @@ impl Deck {
|
||||||
limit: 20,
|
limit: 20,
|
||||||
order: FilteredSearchOrder::Due as i32,
|
order: FilteredSearchOrder::Due as i32,
|
||||||
});
|
});
|
||||||
filt.preview_delay = 10;
|
filt.preview_again_mins = 1;
|
||||||
|
filt.preview_hard_mins = 10;
|
||||||
filt.reschedule = true;
|
filt.reschedule = true;
|
||||||
Deck {
|
Deck {
|
||||||
id: DeckId(0),
|
id: DeckId(0),
|
||||||
|
|
|
@ -156,8 +156,12 @@ pub struct FilteredDeckSchema11 {
|
||||||
delays: Option<Vec<f32>>,
|
delays: Option<Vec<f32>>,
|
||||||
|
|
||||||
// new scheduler
|
// new scheduler
|
||||||
|
#[serde(default, rename = "previewDelay")]
|
||||||
|
preview_again_mins: u32,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
preview_delay: u32,
|
preview_hard_mins: u32,
|
||||||
|
#[serde(default)]
|
||||||
|
preview_good_mins: u32,
|
||||||
}
|
}
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Default, Clone)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Default, Clone)]
|
||||||
pub struct DeckTodaySchema11 {
|
pub struct DeckTodaySchema11 {
|
||||||
|
@ -328,7 +332,9 @@ impl From<FilteredDeckSchema11> for FilteredDeck {
|
||||||
reschedule: deck.resched,
|
reschedule: deck.resched,
|
||||||
search_terms: deck.terms.into_iter().map(Into::into).collect(),
|
search_terms: deck.terms.into_iter().map(Into::into).collect(),
|
||||||
delays: deck.delays.unwrap_or_default(),
|
delays: deck.delays.unwrap_or_default(),
|
||||||
preview_delay: deck.preview_delay,
|
preview_again_mins: deck.preview_again_mins,
|
||||||
|
preview_hard_mins: deck.preview_hard_mins,
|
||||||
|
preview_good_mins: deck.preview_good_mins,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -367,7 +373,9 @@ impl From<Deck> for DeckSchema11 {
|
||||||
} else {
|
} else {
|
||||||
Some(filt.delays.clone())
|
Some(filt.delays.clone())
|
||||||
},
|
},
|
||||||
preview_delay: filt.preview_delay,
|
preview_again_mins: filt.preview_again_mins,
|
||||||
|
preview_hard_mins: filt.preview_hard_mins,
|
||||||
|
preview_good_mins: filt.preview_good_mins,
|
||||||
common: deck.into(),
|
common: deck.into(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl CardStateUpdater {
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
PreviewState {
|
PreviewState {
|
||||||
scheduled_secs: filtered.preview_delay * 60,
|
scheduled_secs: filtered.preview_again_mins * 60,
|
||||||
finished: false,
|
finished: false,
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
|
|
|
@ -91,10 +91,14 @@ impl CardStateUpdater {
|
||||||
lapse_multiplier: self.config.inner.lapse_multiplier,
|
lapse_multiplier: self.config.inner.lapse_multiplier,
|
||||||
minimum_lapse_interval: self.config.inner.minimum_lapse_interval,
|
minimum_lapse_interval: self.config.inner.minimum_lapse_interval,
|
||||||
in_filtered_deck: self.deck.is_filtered(),
|
in_filtered_deck: self.deck.is_filtered(),
|
||||||
preview_step: if let DeckKind::Filtered(deck) = &self.deck.kind {
|
preview_delays: if let DeckKind::Filtered(deck) = &self.deck.kind {
|
||||||
deck.preview_delay
|
PreviewDelays {
|
||||||
|
again: deck.preview_again_mins,
|
||||||
|
hard: deck.preview_hard_mins,
|
||||||
|
good: deck.preview_good_mins,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
0
|
Default::default()
|
||||||
},
|
},
|
||||||
fsrs_next_states: self.fsrs_next_states.clone(),
|
fsrs_next_states: self.fsrs_next_states.clone(),
|
||||||
}
|
}
|
||||||
|
@ -185,6 +189,13 @@ impl CardStateUpdater {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub(crate) struct PreviewDelays {
|
||||||
|
pub again: u32,
|
||||||
|
pub hard: u32,
|
||||||
|
pub good: u32,
|
||||||
|
}
|
||||||
|
|
||||||
impl Rating {
|
impl Rating {
|
||||||
fn as_number(self) -> u8 {
|
fn as_number(self) -> u8 {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
@ -79,6 +79,13 @@ mod test {
|
||||||
finished: true
|
finished: true
|
||||||
}))
|
}))
|
||||||
));
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
next.good,
|
||||||
|
CardState::Filtered(FilteredState::Preview(PreviewState {
|
||||||
|
scheduled_secs: 0,
|
||||||
|
finished: true
|
||||||
|
}))
|
||||||
|
));
|
||||||
|
|
||||||
// use Again on the preview
|
// use Again on the preview
|
||||||
col.answer_card(&mut CardAnswer {
|
col.answer_card(&mut CardAnswer {
|
||||||
|
@ -108,7 +115,8 @@ mod test {
|
||||||
c = col.storage.get_card(c.id)?.unwrap();
|
c = col.storage.get_card(c.id)?.unwrap();
|
||||||
assert_eq!(c.queue, CardQueue::PreviewRepeat);
|
assert_eq!(c.queue, CardQueue::PreviewRepeat);
|
||||||
|
|
||||||
// good
|
// and then it should return to its old state once good or easy selected,
|
||||||
|
// with the default filtered config
|
||||||
let next = col.get_scheduling_states(c.id)?;
|
let next = col.get_scheduling_states(c.id)?;
|
||||||
col.answer_card(&mut CardAnswer {
|
col.answer_card(&mut CardAnswer {
|
||||||
card_id: c.id,
|
card_id: c.id,
|
||||||
|
@ -120,20 +128,6 @@ mod test {
|
||||||
custom_data: None,
|
custom_data: None,
|
||||||
})?;
|
})?;
|
||||||
c = col.storage.get_card(c.id)?.unwrap();
|
c = col.storage.get_card(c.id)?.unwrap();
|
||||||
assert_eq!(c.queue, CardQueue::PreviewRepeat);
|
|
||||||
|
|
||||||
// and then it should return to its old state once easy selected
|
|
||||||
let next = col.get_scheduling_states(c.id)?;
|
|
||||||
col.answer_card(&mut CardAnswer {
|
|
||||||
card_id: c.id,
|
|
||||||
current_state: next.current,
|
|
||||||
new_state: next.easy,
|
|
||||||
rating: Rating::Easy,
|
|
||||||
answered_at: TimestampMillis::now(),
|
|
||||||
milliseconds_taken: 0,
|
|
||||||
custom_data: None,
|
|
||||||
})?;
|
|
||||||
c = col.storage.get_card(c.id)?.unwrap();
|
|
||||||
assert_eq!(c.queue, CardQueue::DayLearn);
|
assert_eq!(c.queue, CardQueue::DayLearn);
|
||||||
assert_eq!(c.due, 123);
|
assert_eq!(c.due, 123);
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,9 @@ fn custom_study_config(
|
||||||
order: order as i32,
|
order: order as i32,
|
||||||
}],
|
}],
|
||||||
delays: vec![],
|
delays: vec![],
|
||||||
preview_delay: 10,
|
preview_again_mins: 1,
|
||||||
|
preview_hard_mins: 10,
|
||||||
|
preview_good_mins: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ pub use review::ReviewState;
|
||||||
|
|
||||||
use self::steps::LearningSteps;
|
use self::steps::LearningSteps;
|
||||||
use crate::revlog::RevlogReviewKind;
|
use crate::revlog::RevlogReviewKind;
|
||||||
|
use crate::scheduler::answering::PreviewDelays;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum CardState {
|
pub enum CardState {
|
||||||
|
@ -106,7 +107,7 @@ pub(crate) struct StateContext<'a> {
|
||||||
|
|
||||||
// filtered
|
// filtered
|
||||||
pub in_filtered_deck: bool,
|
pub in_filtered_deck: bool,
|
||||||
pub preview_step: u32,
|
pub preview_delays: PreviewDelays,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> StateContext<'a> {
|
impl<'a> StateContext<'a> {
|
||||||
|
@ -136,7 +137,11 @@ impl<'a> StateContext<'a> {
|
||||||
lapse_multiplier: 0.0,
|
lapse_multiplier: 0.0,
|
||||||
minimum_lapse_interval: 1,
|
minimum_lapse_interval: 1,
|
||||||
in_filtered_deck: false,
|
in_filtered_deck: false,
|
||||||
preview_step: 10,
|
preview_delays: PreviewDelays {
|
||||||
|
again: 1,
|
||||||
|
hard: 10,
|
||||||
|
good: 0,
|
||||||
|
},
|
||||||
fsrs_next_states: None,
|
fsrs_next_states: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// 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 super::CardState;
|
||||||
use super::IntervalKind;
|
use super::IntervalKind;
|
||||||
use super::SchedulingStates;
|
use super::SchedulingStates;
|
||||||
use super::StateContext;
|
use super::StateContext;
|
||||||
|
@ -24,27 +25,25 @@ impl PreviewState {
|
||||||
pub(crate) fn next_states(self, ctx: &StateContext) -> SchedulingStates {
|
pub(crate) fn next_states(self, ctx: &StateContext) -> SchedulingStates {
|
||||||
SchedulingStates {
|
SchedulingStates {
|
||||||
current: self.into(),
|
current: self.into(),
|
||||||
again: PreviewState {
|
again: delay_or_return(ctx.preview_delays.again),
|
||||||
scheduled_secs: ctx.preview_step * 60,
|
hard: delay_or_return(ctx.preview_delays.hard),
|
||||||
..self
|
good: delay_or_return(ctx.preview_delays.good),
|
||||||
}
|
easy: delay_or_return(0),
|
||||||
.into(),
|
|
||||||
hard: PreviewState {
|
|
||||||
// ~15 minutes with the default setting
|
|
||||||
scheduled_secs: ctx.preview_step * 90,
|
|
||||||
..self
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
good: PreviewState {
|
|
||||||
scheduled_secs: ctx.preview_step * 120,
|
|
||||||
..self
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
easy: PreviewState {
|
|
||||||
scheduled_secs: 0,
|
|
||||||
finished: true,
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn delay_or_return(minutes: u32) -> CardState {
|
||||||
|
if minutes == 0 {
|
||||||
|
PreviewState {
|
||||||
|
scheduled_secs: 0,
|
||||||
|
finished: true,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PreviewState {
|
||||||
|
scheduled_secs: minutes * 60,
|
||||||
|
finished: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue