mirror of
https://github.com/ankitects/anki.git
synced 2025-11-06 12:47:11 -05:00
This PR adds the "hide all but one" occlusion mode. An example use case is a note containing a collection of pairs of selection, where each selection is the prompt for the other in its pair. For example, given a table like | small | big | |-------+-----| | a | A | | b | B | | c | C | in each card, five letters are occluded, and one is shown. The user is prompted to state the occluded symbol that is adjacent to the shown symbol.
77 lines
2.6 KiB
TypeScript
77 lines
2.6 KiB
TypeScript
// Copyright: Ankitects Pty Ltd and contributors
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
import type { OpChanges } from "@generated/anki/collection_pb";
|
|
import { addImageOcclusionNote, updateImageOcclusionNote } from "@generated/backend";
|
|
import * as tr from "@generated/ftl";
|
|
import { get } from "svelte/store";
|
|
|
|
import { mount } from "svelte";
|
|
import type { IOAddingMode, IOMode } from "./lib";
|
|
import { exportShapesToClozeDeletions } from "./shapes/to-cloze";
|
|
import { notesDataStore, OcclusionMode, tagsWritable } from "./store";
|
|
import Toast from "./Toast.svelte";
|
|
|
|
export const addOrUpdateNote = async function(
|
|
mode: IOMode,
|
|
occlusionMode: OcclusionMode,
|
|
): Promise<void> {
|
|
const { clozes: occlusionCloze, noteCount } = exportShapesToClozeDeletions(occlusionMode);
|
|
if (noteCount === 0) {
|
|
return;
|
|
}
|
|
|
|
const fieldsData: { id: string; title: string; divValue: string; textareaValue: string }[] = get(notesDataStore);
|
|
const tags = get(tagsWritable);
|
|
let header = fieldsData[0].textareaValue;
|
|
let backExtra = fieldsData[1].textareaValue;
|
|
|
|
header = header ? `<div>${header}</div>` : "";
|
|
backExtra = backExtra ? `<div>${backExtra}</div>` : "";
|
|
|
|
if (mode.kind == "edit") {
|
|
const result = await updateImageOcclusionNote({
|
|
noteId: BigInt(mode.noteId),
|
|
occlusions: occlusionCloze,
|
|
header,
|
|
backExtra,
|
|
tags,
|
|
});
|
|
showResult(mode.noteId, result, noteCount);
|
|
} else {
|
|
const result = await addImageOcclusionNote({
|
|
// IOCloningMode is not used on mobile
|
|
notetypeId: BigInt((<IOAddingMode> mode).notetypeId),
|
|
imagePath: (<IOAddingMode> mode).imagePath,
|
|
occlusions: occlusionCloze,
|
|
header,
|
|
backExtra,
|
|
tags,
|
|
});
|
|
showResult(null, result, noteCount);
|
|
}
|
|
};
|
|
|
|
// show toast message
|
|
const showResult = (noteId: number | null, result: OpChanges, count: number) => {
|
|
const props = $state({
|
|
message: "",
|
|
type: "error" as "error" | "success",
|
|
showToast: true,
|
|
});
|
|
mount(Toast, {
|
|
target: document.body,
|
|
props,
|
|
});
|
|
|
|
if (result.note) {
|
|
const msg = noteId ? tr.browsingCardsUpdated({ count: count }) : tr.importingCardsAdded({ count: count });
|
|
props.message = msg;
|
|
props.type = "success";
|
|
props.showToast = true;
|
|
} else {
|
|
const msg = tr.notetypesErrorGeneratingCloze();
|
|
props.message = msg;
|
|
props.showToast = true;
|
|
}
|
|
};
|