mirror of
https://github.com/ankitects/anki.git
synced 2025-09-23 00:12:25 -04:00
Revert bury restriction (#2432)
* Remove outdated comment. * Revert removal of independent bury rules * Revert 'hierarchical bury modes' It's now again allowed to bury new, but not review cards e.g., but siblings of previously gathered card queues will not be buried. * Tweak docs (dae) * Add missing Learn and PreviewRepeat queues
This commit is contained in:
parent
9b5148185a
commit
c4d5eeb7a3
7 changed files with 130 additions and 96 deletions
|
@ -104,22 +104,28 @@ deck-config-leech-action-tooltip =
|
||||||
## Burying section
|
## Burying section
|
||||||
|
|
||||||
deck-config-bury-title = Burying
|
deck-config-bury-title = Burying
|
||||||
deck-config-bury-siblings = Bury siblings
|
deck-config-bury-new-siblings = Bury new siblings
|
||||||
deck-config-do-not-bury = Do not bury siblings
|
deck-config-bury-review-siblings = Bury review siblings
|
||||||
deck-config-bury-if-new = Bury if new
|
deck-config-bury-interday-learning-siblings = Bury interday learning siblings
|
||||||
deck-config-bury-if-new-or-review = Bury if new or review
|
deck-config-bury-new-tooltip =
|
||||||
deck-config-bury-if-new-review-or-interday = Bury if new, review, or interday learning
|
Whether other `new` cards of the same note (eg reverse cards, adjacent cloze deletions)
|
||||||
deck-config-bury-tooltip =
|
will be delayed until the next day.
|
||||||
Siblings are other cards from the same note (eg forward/reverse cards, or
|
deck-config-bury-review-tooltip = Whether other `review` cards of the same note will be delayed until the next day.
|
||||||
other cloze deletions from the same text).
|
deck-config-bury-interday-learning-tooltip =
|
||||||
|
Whether other `learning` cards of the same note with intervals > 1 day
|
||||||
When this option is off, multiple cards from the same note may be seen on the same
|
will be delayed until the next day.
|
||||||
day. When enabled, Anki will automatically *bury* siblings, hiding them until the next
|
deck-config-bury-priority-tooltip =
|
||||||
day. This option allows you to choose which kinds of cards may be buried when you answer
|
When Anki gathers cards, it first gathers intraday learning cards, then
|
||||||
one of their siblings.
|
interday learning cards, then reviews, and finally new cards. This affects
|
||||||
|
how burying works:
|
||||||
When using the V3 scheduler, interday learning cards can also be buried. Interday
|
|
||||||
learning cards are cards with a current learning step of one or more days.
|
- If you have all burying options enabled, the sibling that comes earliest in
|
||||||
|
that list will be shown. For example, a review card will be shown in preference
|
||||||
|
to a new card.
|
||||||
|
- Siblings later in the list can not bury earlier card types. For example, if you
|
||||||
|
disable burying of new cards, and study a new card, it will not bury any interday
|
||||||
|
learning or review cards, and you may see both a review sibling and new sibling in the
|
||||||
|
same session.
|
||||||
|
|
||||||
## Ordering section
|
## Ordering section
|
||||||
|
|
||||||
|
@ -304,13 +310,19 @@ deck-config-which-deck = Which deck would you like?
|
||||||
|
|
||||||
## NO NEED TO TRANSLATE. This text is no longer used by Anki, and will be removed in the future.
|
## NO NEED TO TRANSLATE. This text is no longer used by Anki, and will be removed in the future.
|
||||||
|
|
||||||
deck-config-bury-new-siblings = Bury new siblings
|
deck-config-bury-siblings = Bury siblings
|
||||||
deck-config-bury-review-siblings = Bury review siblings
|
deck-config-do-not-bury = Do not bury siblings
|
||||||
deck-config-bury-interday-learning-siblings = Bury interday learning siblings
|
deck-config-bury-if-new = Bury if new
|
||||||
deck-config-bury-new-tooltip =
|
deck-config-bury-if-new-or-review = Bury if new or review
|
||||||
Whether other `new` cards of the same note (eg reverse cards, adjacent cloze deletions)
|
deck-config-bury-if-new-review-or-interday = Bury if new, review, or interday learning
|
||||||
will be delayed until the next day.
|
deck-config-bury-tooltip =
|
||||||
deck-config-bury-review-tooltip = Whether other `review` cards of the same note will be delayed until the next day.
|
Siblings are other cards from the same note (eg forward/reverse cards, or
|
||||||
deck-config-bury-interday-learning-tooltip =
|
other cloze deletions from the same text).
|
||||||
Whether other `learning` cards of the same note with intervals > 1 day
|
|
||||||
will be delayed until the next day.
|
When this option is off, multiple cards from the same note may be seen on the same
|
||||||
|
day. When enabled, Anki will automatically *bury* siblings, hiding them until the next
|
||||||
|
day. This option allows you to choose which kinds of cards may be buried when you answer
|
||||||
|
one of their siblings.
|
||||||
|
|
||||||
|
When using the V3 scheduler, interday learning cards can also be buried. Interday
|
||||||
|
learning cards are cards with a current learning step of one or more days.
|
||||||
|
|
|
@ -124,13 +124,8 @@ message DeckConfig {
|
||||||
bool show_timer = 25;
|
bool show_timer = 25;
|
||||||
bool skip_question_when_replaying_answer = 26;
|
bool skip_question_when_replaying_answer = 26;
|
||||||
|
|
||||||
// the new scheduler doesn't allow toggling these booleans freely anymore,
|
|
||||||
// but they are continued to be used for reasons of backwards compatibility
|
|
||||||
|
|
||||||
bool bury_new = 27;
|
bool bury_new = 27;
|
||||||
// only respected if bury_new
|
|
||||||
bool bury_reviews = 28;
|
bool bury_reviews = 28;
|
||||||
// only respected if bury_new and bury_reviews
|
|
||||||
bool bury_interday_learning = 29;
|
bool bury_interday_learning = 29;
|
||||||
|
|
||||||
bytes other = 255;
|
bytes other = 255;
|
||||||
|
|
|
@ -288,7 +288,7 @@ impl Collection {
|
||||||
fn maybe_bury_siblings(&mut self, card: &Card, config: &DeckConfig) -> Result<()> {
|
fn maybe_bury_siblings(&mut self, card: &Card, config: &DeckConfig) -> Result<()> {
|
||||||
let bury_mode = BuryMode::from_deck_config(config);
|
let bury_mode = BuryMode::from_deck_config(config);
|
||||||
if bury_mode.any_burying() {
|
if bury_mode.any_burying() {
|
||||||
self.bury_siblings(card.id, card.note_id, bury_mode)?;
|
self.bury_siblings(card, card.note_id, bury_mode)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,6 @@ impl Collection {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bury/suspend cards in search table, and clear it.
|
|
||||||
/// Marks the cards as modified.
|
/// Marks the cards as modified.
|
||||||
fn bury_or_suspend_cards_inner(
|
fn bury_or_suspend_cards_inner(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -139,15 +138,39 @@ impl Collection {
|
||||||
|
|
||||||
pub(crate) fn bury_siblings(
|
pub(crate) fn bury_siblings(
|
||||||
&mut self,
|
&mut self,
|
||||||
cid: CardId,
|
card: &Card,
|
||||||
nid: NoteId,
|
nid: NoteId,
|
||||||
bury_mode: BuryMode,
|
mut bury_mode: BuryMode,
|
||||||
) -> Result<usize> {
|
) -> Result<usize> {
|
||||||
let cards = self.storage.all_siblings_for_bury(cid, nid, bury_mode)?;
|
bury_mode.exclude_earlier_gathered_queues(card.queue);
|
||||||
|
let cards = self
|
||||||
|
.storage
|
||||||
|
.all_siblings_for_bury(card.id, nid, bury_mode)?;
|
||||||
self.bury_or_suspend_cards_inner(cards, BuryOrSuspendMode::BurySched)
|
self.bury_or_suspend_cards_inner(cards, BuryOrSuspendMode::BurySched)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BuryMode {
|
||||||
|
/// Disables burying for queues gathered before `queue`.
|
||||||
|
fn exclude_earlier_gathered_queues(&mut self, queue: CardQueue) {
|
||||||
|
self.bury_interday_learning &= queue.gather_ord() <= CardQueue::DayLearn.gather_ord();
|
||||||
|
self.bury_reviews &= queue.gather_ord() <= CardQueue::Review.gather_ord();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CardQueue {
|
||||||
|
fn gather_ord(self) -> u8 {
|
||||||
|
match self {
|
||||||
|
CardQueue::Learn | CardQueue::PreviewRepeat => 0,
|
||||||
|
CardQueue::DayLearn => 1,
|
||||||
|
CardQueue::Review => 2,
|
||||||
|
CardQueue::New => 3,
|
||||||
|
// not gathered
|
||||||
|
CardQueue::Suspended | CardQueue::SchedBuried | CardQueue::UserBuried => u8::MAX,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::card::Card;
|
use crate::card::Card;
|
||||||
|
|
|
@ -56,15 +56,10 @@ impl Context {
|
||||||
impl BuryMode {
|
impl BuryMode {
|
||||||
pub(crate) fn from_deck_config(config: &DeckConfig) -> BuryMode {
|
pub(crate) fn from_deck_config(config: &DeckConfig) -> BuryMode {
|
||||||
let cfg = &config.inner;
|
let cfg = &config.inner;
|
||||||
// Since cards are gathered in a certain order (learning > review > new) and
|
|
||||||
// a card can only bury siblings that are gathered later, only the four bury
|
|
||||||
// modes following this order are allowed.
|
|
||||||
// Booleans are continued to be used for reasons of backwards compatibility.
|
|
||||||
// https://github.com/ankitects/anki/issues/2352
|
|
||||||
BuryMode {
|
BuryMode {
|
||||||
bury_new: cfg.bury_new,
|
bury_new: cfg.bury_new,
|
||||||
bury_reviews: cfg.bury_new && cfg.bury_reviews,
|
bury_reviews: cfg.bury_reviews,
|
||||||
bury_interday_learning: cfg.bury_new && cfg.bury_reviews && cfg.bury_interday_learning,
|
bury_interday_learning: cfg.bury_interday_learning,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -456,7 +456,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn new_card_potentially_burying_review_card() {
|
fn new_card_potentially_burying_review_card() {
|
||||||
let mut col = open_test_collection();
|
let mut col = Collection::new_v3();
|
||||||
// add one new and one review card
|
// add one new and one review card
|
||||||
CardAdder::new().siblings(2).due_dates(["0"]).add(&mut col);
|
CardAdder::new().siblings(2).due_dates(["0"]).add(&mut col);
|
||||||
// Potentially problematic config: New cards are shown first and would bury
|
// Potentially problematic config: New cards are shown first and would bury
|
||||||
|
|
|
@ -3,7 +3,6 @@ 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
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { anki } from "@tslib/backend_proto";
|
|
||||||
import * as tr from "@tslib/ftl";
|
import * as tr from "@tslib/ftl";
|
||||||
import type Carousel from "bootstrap/js/dist/carousel";
|
import type Carousel from "bootstrap/js/dist/carousel";
|
||||||
import type Modal from "bootstrap/js/dist/modal";
|
import type Modal from "bootstrap/js/dist/modal";
|
||||||
|
@ -11,10 +10,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
import DynamicallySlottable from "../components/DynamicallySlottable.svelte";
|
import DynamicallySlottable from "../components/DynamicallySlottable.svelte";
|
||||||
import Item from "../components/Item.svelte";
|
import Item from "../components/Item.svelte";
|
||||||
import TitledContainer from "../components/TitledContainer.svelte";
|
import TitledContainer from "../components/TitledContainer.svelte";
|
||||||
import EnumSelectorRow from "./EnumSelectorRow.svelte";
|
|
||||||
import HelpModal from "./HelpModal.svelte";
|
import HelpModal from "./HelpModal.svelte";
|
||||||
import type { DeckOptionsState } from "./lib";
|
import type { DeckOptionsState } from "./lib";
|
||||||
import SettingTitle from "./SettingTitle.svelte";
|
import SettingTitle from "./SettingTitle.svelte";
|
||||||
|
import SwitchRow from "./SwitchRow.svelte";
|
||||||
import type { DeckOption } from "./types";
|
import type { DeckOption } from "./types";
|
||||||
|
|
||||||
export let state: DeckOptionsState;
|
export let state: DeckOptionsState;
|
||||||
|
@ -23,54 +22,33 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
const config = state.currentConfig;
|
const config = state.currentConfig;
|
||||||
const defaults = state.defaults;
|
const defaults = state.defaults;
|
||||||
|
|
||||||
const burySiblings: DeckOption = {
|
const priorityTooltip = state.v3Scheduler
|
||||||
title: tr.deckConfigBurySiblings(),
|
? "\n\n" + tr.deckConfigBuryPriorityTooltip()
|
||||||
help: tr.deckConfigBuryTooltip(),
|
: "";
|
||||||
|
|
||||||
|
const settings = {
|
||||||
|
buryNewSiblings: {
|
||||||
|
title: tr.deckConfigBuryNewSiblings(),
|
||||||
|
help: tr.deckConfigBuryNewTooltip() + priorityTooltip,
|
||||||
|
},
|
||||||
|
buryReviewSiblings: {
|
||||||
|
title: tr.deckConfigBuryReviewSiblings(),
|
||||||
|
help: tr.deckConfigBuryReviewTooltip() + priorityTooltip,
|
||||||
|
},
|
||||||
|
buryInterdayLearningSiblings: {
|
||||||
|
title: tr.deckConfigBuryInterdayLearningSiblings(),
|
||||||
|
help: tr.deckConfigBuryInterdayLearningTooltip() + priorityTooltip,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
const helpSections = Object.values(settings) as DeckOption[];
|
||||||
|
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let carousel: Carousel;
|
let carousel: Carousel;
|
||||||
|
|
||||||
function openHelpModal(): void {
|
function openHelpModal(index: number): void {
|
||||||
modal.show();
|
modal.show();
|
||||||
carousel.to(0);
|
carousel.to(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
const enum BuryMode {
|
|
||||||
NONE,
|
|
||||||
NEW,
|
|
||||||
NEW_REVIEW,
|
|
||||||
NEW_REVIEW_LEARNING,
|
|
||||||
}
|
|
||||||
|
|
||||||
const buryModeChoices = [
|
|
||||||
tr.deckConfigDoNotBury(),
|
|
||||||
tr.deckConfigBuryIfNew(),
|
|
||||||
tr.deckConfigBuryIfNewOrReview(),
|
|
||||||
];
|
|
||||||
if (state.v3Scheduler) {
|
|
||||||
buryModeChoices.push(tr.deckConfigBuryIfNewReviewOrInterday());
|
|
||||||
}
|
|
||||||
|
|
||||||
function buryModeFromConfig(config: anki.deckconfig.DeckConfig.Config): BuryMode {
|
|
||||||
// burying review cards is only allowed if also burying new cards
|
|
||||||
const buryReviews = config.buryNew && config.buryReviews;
|
|
||||||
// burying learning cards is only allowed if also burying review and new cards
|
|
||||||
const buryInterdayLearning =
|
|
||||||
buryReviews && config.buryInterdayLearning && state.v3Scheduler;
|
|
||||||
return (
|
|
||||||
Number(config.buryNew) + Number(buryReviews) + Number(buryInterdayLearning)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function buryModeToConfig(mode: BuryMode) {
|
|
||||||
$config.buryNew = mode >= 1;
|
|
||||||
$config.buryReviews = mode >= 2;
|
|
||||||
$config.buryInterdayLearning = mode >= 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mode = buryModeFromConfig($config);
|
|
||||||
$: buryModeToConfig(mode);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<TitledContainer title={tr.deckConfigBuryTitle()}>
|
<TitledContainer title={tr.deckConfigBuryTitle()}>
|
||||||
|
@ -78,7 +56,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
title={tr.deckConfigBuryTitle()}
|
title={tr.deckConfigBuryTitle()}
|
||||||
url="https://docs.ankiweb.net/studying.html#siblings-and-burying"
|
url="https://docs.ankiweb.net/studying.html#siblings-and-burying"
|
||||||
slot="tooltip"
|
slot="tooltip"
|
||||||
helpSections={[burySiblings]}
|
{helpSections}
|
||||||
on:mount={(e) => {
|
on:mount={(e) => {
|
||||||
modal = e.detail.modal;
|
modal = e.detail.modal;
|
||||||
carousel = e.detail.carousel;
|
carousel = e.detail.carousel;
|
||||||
|
@ -86,15 +64,46 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
/>
|
/>
|
||||||
<DynamicallySlottable slotHost={Item} {api}>
|
<DynamicallySlottable slotHost={Item} {api}>
|
||||||
<Item>
|
<Item>
|
||||||
<EnumSelectorRow
|
<SwitchRow bind:value={$config.buryNew} defaultValue={defaults.buryNew}>
|
||||||
bind:value={mode}
|
<SettingTitle
|
||||||
defaultValue={buryModeFromConfig(defaults)}
|
on:click={() =>
|
||||||
choices={buryModeChoices}
|
openHelpModal(Object.keys(settings).indexOf("buryNewSiblings"))}
|
||||||
>
|
>{settings.buryNewSiblings.title}</SettingTitle
|
||||||
<SettingTitle on:click={() => openHelpModal()}
|
|
||||||
>{tr.deckConfigBurySiblings()}</SettingTitle
|
|
||||||
>
|
>
|
||||||
</EnumSelectorRow>
|
</SwitchRow>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
<Item>
|
||||||
|
<SwitchRow
|
||||||
|
bind:value={$config.buryReviews}
|
||||||
|
defaultValue={defaults.buryReviews}
|
||||||
|
>
|
||||||
|
<SettingTitle
|
||||||
|
on:click={() =>
|
||||||
|
openHelpModal(
|
||||||
|
Object.keys(settings).indexOf("buryReviewSiblings"),
|
||||||
|
)}>{settings.buryReviewSiblings.title}</SettingTitle
|
||||||
|
>
|
||||||
|
</SwitchRow>
|
||||||
|
</Item>
|
||||||
|
|
||||||
|
{#if state.v3Scheduler}
|
||||||
|
<Item>
|
||||||
|
<SwitchRow
|
||||||
|
bind:value={$config.buryInterdayLearning}
|
||||||
|
defaultValue={defaults.buryInterdayLearning}
|
||||||
|
>
|
||||||
|
<SettingTitle
|
||||||
|
on:click={() =>
|
||||||
|
openHelpModal(
|
||||||
|
Object.keys(settings).indexOf(
|
||||||
|
"buryInterdayLearningSiblings",
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
>{settings.buryInterdayLearningSiblings.title}</SettingTitle
|
||||||
|
>
|
||||||
|
</SwitchRow>
|
||||||
|
</Item>
|
||||||
|
{/if}
|
||||||
</DynamicallySlottable>
|
</DynamicallySlottable>
|
||||||
</TitledContainer>
|
</TitledContainer>
|
||||||
|
|
Loading…
Reference in a new issue