mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
Add editor hints for cloze errors
This commit is contained in:
parent
ab7c07e830
commit
d8c3e71105
3 changed files with 33 additions and 10 deletions
|
@ -27,7 +27,7 @@ from anki.collection import Config, SearchNode
|
||||||
from anki.consts import MODEL_CLOZE
|
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.notes import DuplicateOrEmptyResult, Note
|
from anki.notes import Note, NoteFieldsCheckResult
|
||||||
from anki.utils import checksum, isLin, isWin, namedtmp
|
from anki.utils import checksum, isLin, isWin, namedtmp
|
||||||
from aqt import AnkiQt, colors, gui_hooks
|
from aqt import AnkiQt, colors, gui_hooks
|
||||||
from aqt.operations import QueryOp
|
from aqt.operations import QueryOp
|
||||||
|
@ -79,8 +79,10 @@ audio = (
|
||||||
_html = """
|
_html = """
|
||||||
<div id="fields"></div>
|
<div id="fields"></div>
|
||||||
<div id="dupes" class="is-inactive">
|
<div id="dupes" class="is-inactive">
|
||||||
<a href="#" onclick="pycmd('dupes');return false;">%s</a>
|
<a href="#" onclick="pycmd('dupes');return false;">{}</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="not-a-cloze-notetype" class="is-inactive">{}</div>
|
||||||
|
<div id="not-a-cloze-field" class="is-inactive">{}</div>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,7 +131,11 @@ class Editor:
|
||||||
|
|
||||||
# then load page
|
# then load page
|
||||||
self.web.stdHtml(
|
self.web.stdHtml(
|
||||||
_html % tr.editing_show_duplicates(),
|
_html.format(
|
||||||
|
tr.editing_show_duplicates(),
|
||||||
|
tr.adding_cloze_outside_cloze_notetype(),
|
||||||
|
tr.adding_cloze_outside_cloze_field(),
|
||||||
|
),
|
||||||
css=[
|
css=[
|
||||||
"css/editor.css",
|
"css/editor.css",
|
||||||
],
|
],
|
||||||
|
@ -437,7 +443,7 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{
|
||||||
self.widget.show()
|
self.widget.show()
|
||||||
self.updateTags()
|
self.updateTags()
|
||||||
|
|
||||||
dupe_status = self.note.duplicate_or_empty()
|
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:
|
||||||
|
@ -445,7 +451,7 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{
|
||||||
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(dupe_status)
|
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)
|
||||||
|
@ -494,25 +500,31 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{
|
||||||
if not note:
|
if not note:
|
||||||
return
|
return
|
||||||
|
|
||||||
def on_done(result: DuplicateOrEmptyResult.V) -> None:
|
def on_done(result: NoteFieldsCheckResult.V) -> None:
|
||||||
if self.note != note:
|
if self.note != note:
|
||||||
return
|
return
|
||||||
self._update_duplicate_display(result)
|
self._update_duplicate_display(result)
|
||||||
|
|
||||||
QueryOp(
|
QueryOp(
|
||||||
parent=self.parentWindow,
|
parent=self.parentWindow,
|
||||||
op=lambda _: note.duplicate_or_empty(),
|
op=lambda _: note.fields_check(),
|
||||||
success=on_done,
|
success=on_done,
|
||||||
).run_in_background()
|
).run_in_background()
|
||||||
|
|
||||||
checkValid = _check_and_update_duplicate_display_async
|
checkValid = _check_and_update_duplicate_display_async
|
||||||
|
|
||||||
def _update_duplicate_display(self, result: DuplicateOrEmptyResult.V) -> None:
|
def _update_duplicate_display(self, result: NoteFieldsCheckResult.V) -> None:
|
||||||
cols = [""] * len(self.note.fields)
|
cols = [""] * len(self.note.fields)
|
||||||
if result == DuplicateOrEmptyResult.DUPLICATE:
|
wrong_notetype = wrong_field = "false"
|
||||||
|
if result == NoteFieldsCheckResult.DUPLICATE:
|
||||||
cols[0] = "dupe"
|
cols[0] = "dupe"
|
||||||
|
elif result == NoteFieldsCheckResult.NOTETYPE_NOT_CLOZE:
|
||||||
|
wrong_notetype = "true"
|
||||||
|
elif result == NoteFieldsCheckResult.FIELD_NOT_CLOZE:
|
||||||
|
wrong_field = "true"
|
||||||
|
|
||||||
self.web.eval(f"setBackgrounds({json.dumps(cols)});")
|
self.web.eval(f"setBackgrounds({json.dumps(cols)});")
|
||||||
|
self.web.eval(f"setClozeHints({wrong_notetype}, {wrong_field});")
|
||||||
|
|
||||||
def showDupes(self) -> None:
|
def showDupes(self) -> None:
|
||||||
aqt.dialogs.open(
|
aqt.dialogs.open(
|
||||||
|
|
|
@ -28,7 +28,9 @@
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#dupes {
|
#dupes,
|
||||||
|
#not-a-cloze-notetype,
|
||||||
|
#not-a-cloze-field {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,15 @@ export function setBackgrounds(cols: ("dupe" | "")[]): void {
|
||||||
.classList.toggle("is-inactive", !cols.includes("dupe"));
|
.classList.toggle("is-inactive", !cols.includes("dupe"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setClozeHints(wrong_notetype: boolean, wrong_field: boolean): void {
|
||||||
|
document
|
||||||
|
.getElementById("not-a-cloze-notetype")!
|
||||||
|
.classList.toggle("is-inactive", !wrong_notetype);
|
||||||
|
document
|
||||||
|
.getElementById("not-a-cloze-field")!
|
||||||
|
.classList.toggle("is-inactive", !wrong_field);
|
||||||
|
}
|
||||||
|
|
||||||
export function setFonts(fonts: [string, number, boolean][]): void {
|
export function setFonts(fonts: [string, number, boolean][]): void {
|
||||||
forEditorField(
|
forEditorField(
|
||||||
fonts,
|
fonts,
|
||||||
|
|
Loading…
Reference in a new issue