mirror of
https://github.com/ankitects/anki.git
synced 2025-09-21 15:32:23 -04:00
Move some JS calls in loadNote()
This commit is contained in:
parent
0ace032dc6
commit
053bd4380f
4 changed files with 104 additions and 72 deletions
|
@ -553,22 +553,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
|
|||
if not self.note:
|
||||
return
|
||||
|
||||
data = [
|
||||
(fld, self.mw.col.media.escape_media_filenames(val))
|
||||
for fld, val in self.note.items()
|
||||
]
|
||||
|
||||
note_type = self.note_type()
|
||||
flds = note_type["flds"]
|
||||
collapsed = [fld["collapsed"] for fld in flds]
|
||||
cloze_fields_ords = self.mw.col.models.cloze_fields(self.note.mid)
|
||||
cloze_fields = [ord in cloze_fields_ords for ord in range(len(flds))]
|
||||
plain_texts = [fld.get("plainText", False) for fld in flds]
|
||||
descriptions = [fld.get("description", "") for fld in flds]
|
||||
notetype_meta = {"id": self.note.mid, "modTime": note_type["mod"]}
|
||||
|
||||
self.widget.show()
|
||||
|
||||
note_fields_status = self.note.fields_check()
|
||||
|
||||
def oncallback(arg: Any) -> None:
|
||||
|
@ -583,29 +568,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
|
|||
gui_hooks.editor_did_load_note(self)
|
||||
|
||||
assert self.mw.pm.profile is not None
|
||||
text_color = self.mw.pm.profile.get("lastTextColor", "#0000ff")
|
||||
highlight_color = self.mw.pm.profile.get("lastHighlightColor", "#0000ff")
|
||||
|
||||
js = f"""
|
||||
saveSession();
|
||||
setFields({json.dumps(data)});
|
||||
setIsImageOcclusion({json.dumps(self.current_notetype_is_image_occlusion())});
|
||||
setNotetypeMeta({json.dumps(notetype_meta)});
|
||||
setCollapsed({json.dumps(collapsed)});
|
||||
setClozeFields({json.dumps(cloze_fields)});
|
||||
setPlainTexts({json.dumps(plain_texts)});
|
||||
setDescriptions({json.dumps(descriptions)});
|
||||
setFonts({json.dumps(self.fonts())});
|
||||
focusField({json.dumps(focusTo)});
|
||||
setNoteId({json.dumps(self.note.id)});
|
||||
setColorButtons({json.dumps([text_color, highlight_color])});
|
||||
setTags({json.dumps(self.note.tags)});
|
||||
setTagsCollapsed({json.dumps(self.mw.pm.tags_collapsed(self.editorMode))});
|
||||
setMathjaxEnabled({json.dumps(self.mw.col.get_config("renderMathjax", True))});
|
||||
setShrinkImages({json.dumps(self.mw.col.get_config("shrinkEditorImages", True))});
|
||||
setCloseHTMLTags({json.dumps(self.mw.col.get_config("closeHTMLTags", True))});
|
||||
triggerChanges();
|
||||
"""
|
||||
js = f"loadNote({self.note.id}, {self.note.mid});"
|
||||
|
||||
if self.addMode:
|
||||
sticky = [field["sticky"] for field in self.note_type()["flds"]]
|
||||
|
|
|
@ -648,8 +648,10 @@ exposed_backend_list = [
|
|||
"get_field_names",
|
||||
"get_note",
|
||||
# NotetypesService
|
||||
"get_notetype",
|
||||
"get_notetype_names",
|
||||
"get_change_notetype_info",
|
||||
"get_cloze_field_ords",
|
||||
# StatsService
|
||||
"card_stats",
|
||||
"get_review_logs",
|
||||
|
|
|
@ -92,7 +92,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
const sessionOptions: SessionOptions = {};
|
||||
export function saveSession(): void {
|
||||
if (notetypeMeta) {
|
||||
sessionOptions[notetypeMeta.id] = {
|
||||
sessionOptions[notetypeMeta.id.toString()] = {
|
||||
fieldsCollapsed,
|
||||
fieldStates: {
|
||||
richTextsHidden,
|
||||
|
@ -106,19 +106,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
|
||||
const fieldStores: Writable<string>[] = [];
|
||||
let fieldNames: string[] = [];
|
||||
export function setFields(fs: [string, string][]): void {
|
||||
// this is a bit of a mess -- when moving to Rust calls, we should make
|
||||
// sure to have two backend endpoints for:
|
||||
// * the note, which can be set through this view
|
||||
// * the fieldname, font, etc., which cannot be set
|
||||
export function setFields(newFieldNames: string[], fieldValues: string[]): void {
|
||||
fieldNames = newFieldNames;
|
||||
|
||||
const newFieldNames: string[] = [];
|
||||
|
||||
for (const [index, [fieldName]] of fs.entries()) {
|
||||
newFieldNames[index] = fieldName;
|
||||
}
|
||||
|
||||
for (let i = fieldStores.length; i < newFieldNames.length; i++) {
|
||||
for (let i = fieldStores.length; i < fieldValues.length; i++) {
|
||||
const newStore = writable("");
|
||||
fieldStores[i] = newStore;
|
||||
newStore.subscribe((value) => updateField(i, value));
|
||||
|
@ -126,23 +117,22 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
|
||||
for (
|
||||
let i = fieldStores.length;
|
||||
i > newFieldNames.length;
|
||||
i > fieldValues.length;
|
||||
i = fieldStores.length
|
||||
) {
|
||||
fieldStores.pop();
|
||||
}
|
||||
|
||||
for (const [index, [, fieldContent]] of fs.entries()) {
|
||||
fieldStores[index].set(fieldContent);
|
||||
for (const [index, value] of fieldValues.entries()) {
|
||||
fieldStores[index].set(value);
|
||||
}
|
||||
|
||||
fieldNames = newFieldNames;
|
||||
}
|
||||
|
||||
let fieldsCollapsed: boolean[] = [];
|
||||
export function setCollapsed(defaultCollapsed: boolean[]): void {
|
||||
fieldsCollapsed =
|
||||
sessionOptions[notetypeMeta?.id]?.fieldsCollapsed ?? defaultCollapsed;
|
||||
sessionOptions[notetypeMeta?.id?.toString()]?.fieldsCollapsed ??
|
||||
defaultCollapsed;
|
||||
}
|
||||
let clozeFields: boolean[] = [];
|
||||
export function setClozeFields(defaultClozeFields: boolean[]): void {
|
||||
|
@ -154,7 +144,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
let plainTextDefaults: boolean[] = [];
|
||||
|
||||
export function setPlainTexts(defaultPlainTexts: boolean[]): void {
|
||||
const states = sessionOptions[notetypeMeta?.id]?.fieldStates;
|
||||
const states = sessionOptions[notetypeMeta?.id?.toString()]?.fieldStates;
|
||||
if (states) {
|
||||
richTextsHidden = states.richTextsHidden;
|
||||
plainTextsHidden = states.plainTextsHidden;
|
||||
|
@ -227,8 +217,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
bridgeCommand(`setTagsCollapsed:${$tagsCollapsed}`);
|
||||
}
|
||||
|
||||
let noteId: number | null = null;
|
||||
export function setNoteId(ntid: number): void {
|
||||
let noteId: bigint | null = null;
|
||||
export function setNoteId(ntid: bigint | null): void {
|
||||
// TODO this is a hack, because it requires the NoteEditor to know implementation details of the PlainTextInput.
|
||||
// It should be refactored once we work on our own Undo stack
|
||||
for (const pi of plainTextInputs) {
|
||||
|
@ -238,21 +228,24 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
}
|
||||
|
||||
let notetypeMeta: NotetypeIdAndModTime;
|
||||
function setNotetypeMeta({ id, modTime }: NotetypeIdAndModTime): void {
|
||||
notetypeMeta = { id, modTime };
|
||||
function setNotetypeMeta(notetype: Notetype): void {
|
||||
notetypeMeta = { id: notetype.id, modTime: notetype.mtimeSecs };
|
||||
// Discard the saved state of the fields if the notetype has been modified.
|
||||
if (sessionOptions[id]?.modTimeOfNotetype !== modTime) {
|
||||
delete sessionOptions[id];
|
||||
if (
|
||||
sessionOptions[notetype.id.toString()]?.modTimeOfNotetype !==
|
||||
notetype.mtimeSecs
|
||||
) {
|
||||
delete sessionOptions[notetype.id.toString()];
|
||||
}
|
||||
if (isImageOcclusion) {
|
||||
getImageOcclusionFields({
|
||||
notetypeId: BigInt(notetypeMeta.id),
|
||||
notetypeId: BigInt(notetype.id),
|
||||
}).then((r) => (ioFields = r.fields!));
|
||||
}
|
||||
}
|
||||
|
||||
function getNoteId(): number | null {
|
||||
return noteId;
|
||||
function getNoteId(): string | null {
|
||||
return noteId?.toString() ?? null;
|
||||
}
|
||||
|
||||
let isImageOcclusion = false;
|
||||
|
@ -412,7 +405,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
}
|
||||
|
||||
import { ImageOcclusionFieldIndexes } from "@generated/anki/image_occlusion_pb";
|
||||
import { getImageOcclusionFields } from "@generated/backend";
|
||||
|
||||
import { StockNotetype_OriginalStockKind } from "@generated/anki/notetypes_pb";
|
||||
import type { Notetype } from "@generated/anki/notetypes_pb";
|
||||
import {
|
||||
getFieldNames,
|
||||
getClozeFieldOrds,
|
||||
getImageOcclusionFields,
|
||||
getNote,
|
||||
getNotetype,
|
||||
encodeIriPaths,
|
||||
} from "@generated/backend";
|
||||
import { wrapInternal } from "@tslib/wrap";
|
||||
|
||||
import Shortcut from "$lib/components/Shortcut.svelte";
|
||||
|
@ -549,6 +552,69 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
});
|
||||
}
|
||||
|
||||
async function loadNote(nid: bigint | null, notetypeId: bigint, focusTo: number) {
|
||||
const notetype = await getNotetype({
|
||||
ntid: notetypeId,
|
||||
});
|
||||
let fieldValues: string[] = notetype.fields.map(() => "");
|
||||
const fieldNames = (
|
||||
await getFieldNames({
|
||||
ntid: notetype.id,
|
||||
})
|
||||
).vals;
|
||||
const clozeFieldOrds = (await getClozeFieldOrds({ ntid: notetype.id })).ords;
|
||||
const clozeFields = fieldNames.map((name, index) =>
|
||||
clozeFieldOrds.includes(index),
|
||||
);
|
||||
let tags: string[] = [];
|
||||
if (nid) {
|
||||
const note = await getNote({
|
||||
nid,
|
||||
});
|
||||
fieldValues = (
|
||||
await Promise.all(
|
||||
note.fields.map((field) => encodeIriPaths({ val: field })),
|
||||
)
|
||||
).map((field) => field.val);
|
||||
tags = note.tags;
|
||||
}
|
||||
saveSession();
|
||||
setFields(fieldNames, fieldValues);
|
||||
setIsImageOcclusion(
|
||||
notetype.config?.originalStockKind ===
|
||||
StockNotetype_OriginalStockKind.IMAGE_OCCLUSION,
|
||||
);
|
||||
setNotetypeMeta(notetype);
|
||||
setCollapsed(notetype.fields.map((field) => field.config?.collapsed ?? false));
|
||||
setClozeFields(clozeFields);
|
||||
setPlainTexts(notetype.fields.map((field) => field.config?.plainText ?? false));
|
||||
setDescriptions(
|
||||
notetype.fields.map((field) => field.config?.description ?? ""),
|
||||
);
|
||||
// TODO: gui_hooks.editor_will_use_font_for_field
|
||||
setFonts(
|
||||
notetype.fields.map((field) => [
|
||||
field.config?.fontName ?? "",
|
||||
field.config?.fontSize ?? 16,
|
||||
field.config?.rtl ?? false,
|
||||
]),
|
||||
);
|
||||
focusField(focusTo);
|
||||
setNoteId(nid);
|
||||
// TODO: lastTextColor/lastHighlightColor profile config
|
||||
// setColorButtons(["#0000ff", "#0000ff"]);
|
||||
setTags(tags);
|
||||
// TODO: mw.pm.tags_collapsed()
|
||||
setTagsCollapsed(false);
|
||||
// TODO: renderMathjax col config
|
||||
setMathjaxEnabled(true);
|
||||
// TODO: shrinkEditorImages col config
|
||||
setShrinkImages(true);
|
||||
// TODO: closeHTMLTags col config
|
||||
setCloseHTMLTags(true);
|
||||
triggerChanges();
|
||||
}
|
||||
|
||||
$: signalEditorState(editorState);
|
||||
|
||||
$: editorState = getEditorState(
|
||||
|
@ -575,6 +641,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
}
|
||||
|
||||
Object.assign(globalThis, {
|
||||
loadNote,
|
||||
saveSession,
|
||||
setFields,
|
||||
setCollapsed,
|
||||
|
|
|
@ -8,16 +8,16 @@ export type EditorOptions = {
|
|||
plainTextsHidden: boolean[];
|
||||
plainTextDefaults: boolean[];
|
||||
};
|
||||
modTimeOfNotetype: number;
|
||||
modTimeOfNotetype: bigint;
|
||||
};
|
||||
|
||||
export type SessionOptions = {
|
||||
[key: number]: EditorOptions;
|
||||
[key: string]: EditorOptions;
|
||||
};
|
||||
|
||||
export type NotetypeIdAndModTime = {
|
||||
id: number;
|
||||
modTime: number;
|
||||
id: bigint;
|
||||
modTime: bigint;
|
||||
};
|
||||
|
||||
export enum EditorState {
|
||||
|
|
Loading…
Reference in a new issue