diff --git a/proto/anki/frontend.proto b/proto/anki/frontend.proto index 1f3e7b6b3..461d10528 100644 --- a/proto/anki/frontend.proto +++ b/proto/anki/frontend.proto @@ -34,7 +34,12 @@ service FrontendService { // Profile config rpc GetProfileConfigJson(generic.String) returns (generic.Json); - rpc SetProfileConfigJson(SetProfileConfigJsonRequest) returns (generic.Empty); + rpc SetProfileConfigJson(SetSettingJsonRequest) returns (generic.Empty); + + // Metadata + rpc GetMetaJson(generic.String) returns (generic.Json); + rpc SetMetaJson(SetSettingJsonRequest) returns (generic.Empty); + } service BackendFrontendService {} @@ -49,7 +54,7 @@ message SetSchedulingStatesRequest { scheduler.SchedulingStates states = 2; } -message SetProfileConfigJsonRequest { +message SetSettingJsonRequest { string key = 1; bytes value_json = 2; } diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py index b35d11a90..344256059 100644 --- a/qt/aqt/editor.py +++ b/qt/aqt/editor.py @@ -181,13 +181,8 @@ class Editor: self.outerLayout.addWidget(self.web, 1) def setupWeb(self) -> None: - if self.editorMode == EditorMode.ADD_CARDS: - mode = "add" - elif self.editorMode == EditorMode.BROWSER: - mode = "browse" - else: - mode = "review" - self.web.load_sveltekit_page(f"editor/?mode={mode}") + editor_key = self.mw.pm.editor_key(self.editorMode) + self.web.load_sveltekit_page(f"editor/?mode={editor_key}") def _set_ready(self) -> None: lefttopbtns: list[str] = [] @@ -460,11 +455,6 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too elif cmd.startswith("saveTags"): gui_hooks.editor_did_update_tags(self.note) - elif cmd.startswith("setTagsCollapsed"): - (type, collapsed_string) = cmd.split(":", 1) - collapsed = collapsed_string == "true" - self.setTagsCollapsed(collapsed) - elif cmd.startswith("editorState"): (_, new_state_id, old_state_id) = cmd.split(":", 2) self.signal_state_change( diff --git a/qt/aqt/mediasrv.py b/qt/aqt/mediasrv.py index 636d88545..8c557bbc7 100644 --- a/qt/aqt/mediasrv.py +++ b/qt/aqt/mediasrv.py @@ -18,6 +18,7 @@ from collections.abc import Callable from dataclasses import dataclass from errno import EPROTOTYPE from http import HTTPStatus +from typing import Any import flask import flask_cors @@ -622,23 +623,37 @@ def editor_update_note() -> bytes: return output -def get_profile_config_json() -> bytes: - key = generic_pb2.String() - key.ParseFromString(request.data) - value = aqt.mw.pm.profile.get(key.val, None) +def get_setting_json(getter: Callable[[str], Any]) -> bytes: + req = generic_pb2.String() + req.ParseFromString(request.data) + value = getter(req.val) output = generic_pb2.Json(json=json.dumps(value).encode()).SerializeToString() - return output -def set_profile_config_json() -> bytes: - req = frontend_pb2.SetProfileConfigJsonRequest() +def set_setting_json(setter: Callable[[str, Any], Any]) -> bytes: + req = frontend_pb2.SetSettingJsonRequest() req.ParseFromString(request.data) - aqt.mw.pm.profile[req.key] = json.loads(req.value_json) - + setter(req.key, json.loads(req.value_json)) return b"" +def get_profile_config_json() -> bytes: + return get_setting_json(aqt.mw.pm.profile.get) + + +def set_profile_config_json() -> bytes: + return set_setting_json(aqt.mw.pm.profile.__setitem__) + + +def get_meta_json() -> bytes: + return get_setting_json(aqt.mw.pm.meta.get) + + +def set_meta_json() -> bytes: + return set_setting_json(aqt.mw.pm.meta.__setitem__) + + post_handler_list = [ congrats_info, get_deck_configs_for_update, @@ -657,6 +672,8 @@ post_handler_list = [ editor_update_note, get_profile_config_json, set_profile_config_json, + get_meta_json, + set_meta_json, ] diff --git a/ts/lib/tslib/profile.ts b/ts/lib/tslib/profile.ts index 3ec10eff7..b54d4eed8 100644 --- a/ts/lib/tslib/profile.ts +++ b/ts/lib/tslib/profile.ts @@ -1,16 +1,36 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import { getProfileConfigJson, setProfileConfigJson } from "@generated/backend"; +import { getMetaJson, getProfileConfigJson, setMetaJson, setProfileConfigJson } from "@generated/backend"; -export async function getProfileConfig(key: string): Promise { +async function getSettingJson(key: string, backendGetter: (key: string) => Promise): Promise { const decoder = new TextDecoder(); - const json = decoder.decode((await getProfileConfigJson({ val: key })).json); + const json = decoder.decode((await backendGetter(key)).json); return JSON.parse(json); } -export async function setProfileConfig(key: string, value: any): Promise { +async function setSettingJson( + key: string, + value: any, + backendSetter: (key: string, value: any) => Promise, +): Promise { const encoder = new TextEncoder(); const json = JSON.stringify(value); - await setProfileConfigJson({ key: key, valueJson: encoder.encode(json) }); + await backendSetter(key, encoder.encode(json)); +} + +export async function getProfileConfig(key: string): Promise { + return getSettingJson(key, async (k) => await getProfileConfigJson({ val: k })); +} + +export async function setProfileConfig(key: string, value: any): Promise { + return await setSettingJson(key, value, async (k, v) => await setProfileConfigJson({ key: k, valueJson: v })); +} + +export async function getMeta(key: string): Promise { + return getSettingJson(key, async (k) => await getMetaJson({ val: k })); +} + +export async function setMeta(key: string, value: any): Promise { + return await setSettingJson(key, value, async (k, v) => await setMetaJson({ key: k, valueJson: v })); } diff --git a/ts/routes/editor/NoteEditor.svelte b/ts/routes/editor/NoteEditor.svelte index 4e2159d5e..dfed151ce 100644 --- a/ts/routes/editor/NoteEditor.svelte +++ b/ts/routes/editor/NoteEditor.svelte @@ -222,13 +222,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html } const tagsCollapsed = writable(); + $: tagsCollapsedMetaKey = `${mode}TagsCollapsed`; + export function setTagsCollapsed(collapsed: boolean): void { $tagsCollapsed = collapsed; } - function updateTagsCollapsed(collapsed: boolean) { + async function updateTagsCollapsed(collapsed: boolean) { $tagsCollapsed = collapsed; - bridgeCommand(`setTagsCollapsed:${$tagsCollapsed}`); + await setMeta(tagsCollapsedMetaKey, collapsed); } let note: Note | null = null; @@ -446,7 +448,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html decodeIriPaths, } from "@generated/backend"; import { wrapInternal } from "@tslib/wrap"; - import { getProfileConfig } from "@tslib/profile"; + import { getProfileConfig, getMeta, setMeta } from "@tslib/profile"; import Shortcut from "$lib/components/Shortcut.svelte"; import { mathjaxConfig } from "$lib/editable/mathjax-element.svelte"; @@ -465,7 +467,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import ButtonGroupItem from "$lib/components/ButtonGroupItem.svelte"; import PreviewButton from "./PreviewButton.svelte"; import type { Note } from "@generated/anki/notes_pb"; - import InlineButtons from "./editor-toolbar/InlineButtons.svelte"; $: isIOImageLoaded = false; $: ioImageLoadedStore.set(isIOImageLoaded); @@ -641,8 +642,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html focusField(focusTo); toolbar.inlineButtons?.setColorButtons([lastTextColor, lastHighlightColor]); setTags(tags); - // TODO: mw.pm.tags_collapsed() - setTagsCollapsed(false); + setTagsCollapsed(await getMeta(tagsCollapsedMetaKey)); // TODO: renderMathjax col config setMathjaxEnabled(true); // TODO: shrinkEditorImages col config @@ -759,7 +759,7 @@ components and functionality for general note editing.
- {#if mode === "browse"} + {#if mode === "browser"} diff --git a/ts/routes/editor/base.ts b/ts/routes/editor/base.ts index 884b1c8a3..a1905c5a4 100644 --- a/ts/routes/editor/base.ts +++ b/ts/routes/editor/base.ts @@ -54,7 +54,7 @@ export const components = { export { editorToolbar } from "./editor-toolbar"; export async function setupEditor(mode: EditorMode) { - if (!["add", "browse", "review"].includes(mode)) { + if (!["add", "browser", "current"].includes(mode)) { alert("unexpected editor type"); return; } diff --git a/ts/routes/editor/types.ts b/ts/routes/editor/types.ts index dc1ead9ed..01aa42855 100644 --- a/ts/routes/editor/types.ts +++ b/ts/routes/editor/types.ts @@ -28,4 +28,4 @@ export enum EditorState { ImageOcclusionFields = 3, } -export type EditorMode = "add" | "browse" | "review"; +export type EditorMode = "add" | "browser" | "current";