Move fields_check()

This commit is contained in:
Abdo 2025-06-02 03:59:29 +03:00
parent 8391761bc2
commit 795aef09ee
3 changed files with 27 additions and 46 deletions

View file

@ -35,10 +35,9 @@ from anki.consts import MODEL_CLOZE
from anki.hooks import runFilter from anki.hooks import runFilter
from anki.httpclient import HttpClient from anki.httpclient import HttpClient
from anki.models import NotetypeDict, NotetypeId, StockNotetype from anki.models import NotetypeDict, NotetypeId, StockNotetype
from anki.notes import Note, NoteFieldsCheckResult, NoteId from anki.notes import Note, NoteId
from anki.utils import checksum, is_lin, is_mac, is_win, namedtmp from anki.utils import checksum, is_lin, is_mac, is_win, namedtmp
from aqt import AnkiQt, gui_hooks from aqt import AnkiQt, gui_hooks
from aqt.operations import QueryOp
from aqt.operations.note import update_note from aqt.operations.note import update_note
from aqt.operations.notetype import update_notetype_legacy from aqt.operations.notetype import update_notetype_legacy
from aqt.qt import * from aqt.qt import *
@ -407,11 +406,8 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
self.mw.progress.timer( self.mw.progress.timer(
100, self.loadNoteKeepingFocus, False, parent=self.widget 100, self.loadNoteKeepingFocus, False, parent=self.widget
) )
else:
self._check_and_update_duplicate_display_async()
else: else:
gui_hooks.editor_did_fire_typing_timer(self.note) gui_hooks.editor_did_fire_typing_timer(self.note)
self._check_and_update_duplicate_display_async()
# focused into field? # focused into field?
elif cmd.startswith("focus"): elif cmd.startswith("focus"):
@ -511,7 +507,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
return return
self.widget.show() self.widget.show()
note_fields_status = self.note.fields_check() # note_fields_status = self.note.fields_check()
def oncallback(arg: Any) -> None: def oncallback(arg: Any) -> None:
if not self.note: if not self.note:
@ -519,7 +515,6 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
self.setupForegroundButton() self.setupForegroundButton()
# we currently do this synchronously to ensure we load before the # we currently do this synchronously to ensure we load before the
# sidebar on browser startup # sidebar on browser startup
self._update_duplicate_display(note_fields_status)
if focusTo is not None: if focusTo is not None:
self.web.setFocus() self.web.setFocus()
gui_hooks.editor_did_load_note(self) gui_hooks.editor_did_load_note(self)
@ -552,42 +547,6 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
saveNow = call_after_note_saved saveNow = call_after_note_saved
def _check_and_update_duplicate_display_async(self) -> None:
note = self.note
if not note:
return
def on_done(result: NoteFieldsCheckResult.V) -> None:
if self.note != note:
return
self._update_duplicate_display(result)
QueryOp(
parent=self.parentWindow,
op=lambda _: note.fields_check(),
success=on_done,
).run_in_background()
checkValid = _check_and_update_duplicate_display_async
def _update_duplicate_display(self, result: NoteFieldsCheckResult.V) -> None:
assert self.note is not None
cols = [""] * len(self.note.fields)
cloze_hint = ""
if result == NoteFieldsCheckResult.DUPLICATE:
cols[0] = "dupe"
elif result == NoteFieldsCheckResult.NOTETYPE_NOT_CLOZE:
cloze_hint = tr.adding_cloze_outside_cloze_notetype()
elif result == NoteFieldsCheckResult.FIELD_NOT_CLOZE:
cloze_hint = tr.adding_cloze_outside_cloze_field()
self.web.eval(
'require("anki/ui").loaded.then(() => {'
f"setBackgrounds({json.dumps(cols)});\n"
f"setClozeHint({json.dumps(cloze_hint)});\n"
"}); "
)
def fieldsAreBlank(self, previousNote: Note | None = None) -> bool: def fieldsAreBlank(self, previousNote: Note | None = None) -> bool:
if not self.note: if not self.note:
return True return True

View file

@ -703,6 +703,7 @@ exposed_backend_list = [
"get_field_names", "get_field_names",
"get_note", "get_note",
"new_note", "new_note",
"note_fields_check",
# NotetypesService # NotetypesService
"get_notetype", "get_notetype",
"get_notetype_names", "get_notetype_names",

View file

@ -325,7 +325,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
fieldSave.schedule(async () => { fieldSave.schedule(async () => {
bridgeCommand(`key:${index}`); bridgeCommand(`key:${index}`);
note!.fields[index] = await transformContentBeforeSave(content); note!.fields[index] = await transformContentBeforeSave(content);
updateCurrentNote(); await updateCurrentNote();
await updateDuplicateDisplay();
}, 600); }, 600);
} }
@ -347,6 +348,23 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
} }
} }
async function updateDuplicateDisplay(): Promise<void> {
if (!note) {
return;
}
const result = await noteFieldsCheck(note);
const cols = new Array(note.fields.length).fill("");
if (result.state === NoteFieldsCheckResponse_State.DUPLICATE) {
cols[0] = "dupe";
} else if (result.state === NoteFieldsCheckResponse_State.NOTETYPE_NOT_CLOZE) {
hint = tr.addingClozeOutsideClozeNotetype();
} else if (result.state === NoteFieldsCheckResponse_State.FIELD_NOT_CLOZE) {
hint = tr.addingClozeOutsideClozeField();
}
setBackgrounds(cols);
setClozeHint(hint);
}
export function focusIfField(x: number, y: number): boolean { export function focusIfField(x: number, y: number): boolean {
const elements = document.elementsFromPoint(x, y); const elements = document.elementsFromPoint(x, y);
const first = elements[0].closest(".field-container"); const first = elements[0].closest(".field-container");
@ -446,6 +464,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
newNote, newNote,
editorUpdateNote, editorUpdateNote,
decodeIriPaths, decodeIriPaths,
noteFieldsCheck,
} from "@generated/backend"; } from "@generated/backend";
import { wrapInternal } from "@tslib/wrap"; import { wrapInternal } from "@tslib/wrap";
import { getProfileConfig, getMeta, setMeta, getColConfig } from "@tslib/profile"; import { getProfileConfig, getMeta, setMeta, getColConfig } from "@tslib/profile";
@ -466,7 +485,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import StickyBadge from "./StickyBadge.svelte"; import StickyBadge from "./StickyBadge.svelte";
import ButtonGroupItem from "$lib/components/ButtonGroupItem.svelte"; import ButtonGroupItem from "$lib/components/ButtonGroupItem.svelte";
import PreviewButton from "./PreviewButton.svelte"; import PreviewButton from "./PreviewButton.svelte";
import type { Note } from "@generated/anki/notes_pb"; import { NoteFieldsCheckResponse_State, type Note } from "@generated/anki/notes_pb";
$: isIOImageLoaded = false; $: isIOImageLoaded = false;
$: ioImageLoadedStore.set(isIOImageLoaded); $: ioImageLoadedStore.set(isIOImageLoaded);
@ -673,6 +692,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}); });
} }
} }
await updateDuplicateDisplay();
triggerChanges(); triggerChanges();
} }
@ -841,7 +861,8 @@ components and functionality for general note editing.
note!.fields[index] = await transformContentBeforeSave( note!.fields[index] = await transformContentBeforeSave(
get(content), get(content),
); );
updateCurrentNote(); await updateCurrentNote();
await updateDuplicateDisplay();
}} }}
on:mouseenter={() => { on:mouseenter={() => {
$hoveredField = fields[index]; $hoveredField = fields[index];