mirror of
https://github.com/ankitects/anki.git
synced 2025-09-25 01:06:35 -04:00
Move setColorButtons()
This commit is contained in:
parent
3ae7484610
commit
9395b89b92
9 changed files with 73 additions and 25 deletions
|
@ -31,6 +31,10 @@ service FrontendService {
|
||||||
|
|
||||||
// Editor
|
// Editor
|
||||||
rpc editorUpdateNote(notes.UpdateNotesRequest) returns (generic.Empty);
|
rpc editorUpdateNote(notes.UpdateNotesRequest) returns (generic.Empty);
|
||||||
|
|
||||||
|
// Profile config
|
||||||
|
rpc GetProfileConfigJson(generic.String) returns (generic.Json);
|
||||||
|
rpc SetProfileConfigJson(SetProfileConfigJsonRequest) returns (generic.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
service BackendFrontendService {}
|
service BackendFrontendService {}
|
||||||
|
@ -44,3 +48,8 @@ message SetSchedulingStatesRequest {
|
||||||
string key = 1;
|
string key = 1;
|
||||||
scheduler.SchedulingStates states = 2;
|
scheduler.SchedulingStates states = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message SetProfileConfigJsonRequest {
|
||||||
|
string key = 1;
|
||||||
|
bytes value_json = 2;
|
||||||
|
}
|
||||||
|
|
|
@ -457,16 +457,6 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
|
||||||
|
|
||||||
return new_state
|
return new_state
|
||||||
|
|
||||||
elif cmd.startswith("lastTextColor"):
|
|
||||||
(_, textColor) = cmd.split(":", 1)
|
|
||||||
assert self.mw.pm.profile is not None
|
|
||||||
self.mw.pm.profile["lastTextColor"] = textColor
|
|
||||||
|
|
||||||
elif cmd.startswith("lastHighlightColor"):
|
|
||||||
(_, highlightColor) = cmd.split(":", 1)
|
|
||||||
assert self.mw.pm.profile is not None
|
|
||||||
self.mw.pm.profile["lastHighlightColor"] = highlightColor
|
|
||||||
|
|
||||||
elif cmd.startswith("saveTags"):
|
elif cmd.startswith("saveTags"):
|
||||||
gui_hooks.editor_did_update_tags(self.note)
|
gui_hooks.editor_did_update_tags(self.note)
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import enum
|
import enum
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import os
|
import os
|
||||||
|
@ -28,7 +29,7 @@ from waitress.server import create_server
|
||||||
import aqt
|
import aqt
|
||||||
import aqt.main
|
import aqt.main
|
||||||
import aqt.operations
|
import aqt.operations
|
||||||
from anki import hooks
|
from anki import frontend_pb2, generic_pb2, hooks
|
||||||
from anki.collection import OpChanges, OpChangesOnly, Progress, SearchNode
|
from anki.collection import OpChanges, OpChangesOnly, Progress, SearchNode
|
||||||
from anki.decks import UpdateDeckConfigs
|
from anki.decks import UpdateDeckConfigs
|
||||||
from anki.scheduler.v3 import SchedulingStatesWithContext, SetSchedulingStatesRequest
|
from anki.scheduler.v3 import SchedulingStatesWithContext, SetSchedulingStatesRequest
|
||||||
|
@ -621,6 +622,23 @@ def editor_update_note() -> bytes:
|
||||||
return output
|
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)
|
||||||
|
output = generic_pb2.Json(json=json.dumps(value).encode()).SerializeToString()
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
def set_profile_config_json() -> bytes:
|
||||||
|
req = frontend_pb2.SetProfileConfigJsonRequest()
|
||||||
|
req.ParseFromString(request.data)
|
||||||
|
aqt.mw.pm.profile[req.key] = json.loads(req.value_json)
|
||||||
|
|
||||||
|
return b""
|
||||||
|
|
||||||
|
|
||||||
post_handler_list = [
|
post_handler_list = [
|
||||||
congrats_info,
|
congrats_info,
|
||||||
get_deck_configs_for_update,
|
get_deck_configs_for_update,
|
||||||
|
@ -637,6 +655,8 @@ post_handler_list = [
|
||||||
deck_options_require_close,
|
deck_options_require_close,
|
||||||
deck_options_ready,
|
deck_options_ready,
|
||||||
editor_update_note,
|
editor_update_note,
|
||||||
|
get_profile_config_json,
|
||||||
|
set_profile_config_json,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
16
ts/lib/tslib/profile.ts
Normal file
16
ts/lib/tslib/profile.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// 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";
|
||||||
|
|
||||||
|
export async function getProfileConfig(key: string): Promise<any> {
|
||||||
|
const decoder = new TextDecoder();
|
||||||
|
const json = decoder.decode((await getProfileConfigJson({ val: key })).json);
|
||||||
|
return JSON.parse(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setProfileConfig(key: string, value: any): Promise<void> {
|
||||||
|
const encoder = new TextEncoder();
|
||||||
|
const json = JSON.stringify(value);
|
||||||
|
await setProfileConfigJson({ key: key, valueJson: encoder.encode(json) });
|
||||||
|
}
|
|
@ -446,7 +446,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
decodeIriPaths,
|
decodeIriPaths,
|
||||||
} from "@generated/backend";
|
} from "@generated/backend";
|
||||||
import { wrapInternal } from "@tslib/wrap";
|
import { wrapInternal } from "@tslib/wrap";
|
||||||
|
import { getProfileConfig } from "@tslib/profile";
|
||||||
import Shortcut from "$lib/components/Shortcut.svelte";
|
import Shortcut from "$lib/components/Shortcut.svelte";
|
||||||
|
|
||||||
import { mathjaxConfig } from "$lib/editable/mathjax-element.svelte";
|
import { mathjaxConfig } from "$lib/editable/mathjax-element.svelte";
|
||||||
|
@ -465,6 +465,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
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 type { Note } from "@generated/anki/notes_pb";
|
||||||
|
import InlineButtons from "./editor-toolbar/InlineButtons.svelte";
|
||||||
|
|
||||||
$: isIOImageLoaded = false;
|
$: isIOImageLoaded = false;
|
||||||
$: ioImageLoadedStore.set(isIOImageLoaded);
|
$: ioImageLoadedStore.set(isIOImageLoaded);
|
||||||
|
@ -613,6 +614,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
)
|
)
|
||||||
).map((field) => field.val);
|
).map((field) => field.val);
|
||||||
const tags = note!.tags;
|
const tags = note!.tags;
|
||||||
|
const lastTextColor = (await getProfileConfig("lastTextColor")) ?? "#0000ff";
|
||||||
|
const lastHighlightColor =
|
||||||
|
(await getProfileConfig("lastHighlightColor")) ?? "#0000ff";
|
||||||
|
|
||||||
saveSession();
|
saveSession();
|
||||||
setFields(fieldNames, fieldValues);
|
setFields(fieldNames, fieldValues);
|
||||||
|
@ -635,8 +639,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
focusField(focusTo);
|
focusField(focusTo);
|
||||||
// TODO: lastTextColor/lastHighlightColor profile config
|
toolbar.inlineButtons?.setColorButtons([lastTextColor, lastHighlightColor]);
|
||||||
// setColorButtons(["#0000ff", "#0000ff"]);
|
|
||||||
setTags(tags);
|
setTags(tags);
|
||||||
// TODO: mw.pm.tags_collapsed()
|
// TODO: mw.pm.tags_collapsed()
|
||||||
setTagsCollapsed(false);
|
setTagsCollapsed(false);
|
||||||
|
|
|
@ -26,7 +26,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
export interface EditorToolbarAPI {
|
export interface EditorToolbarAPI {
|
||||||
toolbar: DefaultSlotInterface;
|
toolbar: DefaultSlotInterface;
|
||||||
notetypeButtons: DefaultSlotInterface;
|
notetypeButtons: DefaultSlotInterface;
|
||||||
inlineButtons: DefaultSlotInterface;
|
inlineButtons: InlineButtonsAPI;
|
||||||
blockButtons: DefaultSlotInterface;
|
blockButtons: DefaultSlotInterface;
|
||||||
templateButtons: DefaultSlotInterface;
|
templateButtons: DefaultSlotInterface;
|
||||||
removeFormats: Writable<RemoveFormat[]>;
|
removeFormats: Writable<RemoveFormat[]>;
|
||||||
|
@ -62,14 +62,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
import OptionsButtons from "./OptionsButtons.svelte";
|
import OptionsButtons from "./OptionsButtons.svelte";
|
||||||
import RichTextClozeButtons from "./RichTextClozeButtons.svelte";
|
import RichTextClozeButtons from "./RichTextClozeButtons.svelte";
|
||||||
import TemplateButtons from "./TemplateButtons.svelte";
|
import TemplateButtons from "./TemplateButtons.svelte";
|
||||||
|
import type { InlineButtonsAPI } from "./InlineButtons.svelte";
|
||||||
export let size: number;
|
export let size: number;
|
||||||
export let wrap: boolean;
|
export let wrap: boolean;
|
||||||
|
|
||||||
const toolbar = {} as DefaultSlotInterface;
|
const toolbar = {} as DefaultSlotInterface;
|
||||||
const notetypeButtons = {} as DefaultSlotInterface;
|
const notetypeButtons = {} as DefaultSlotInterface;
|
||||||
const optionsButtons = {} as DefaultSlotInterface;
|
const optionsButtons = {} as DefaultSlotInterface;
|
||||||
const inlineButtons = {} as DefaultSlotInterface;
|
const inlineButtons = {} as InlineButtonsAPI;
|
||||||
const blockButtons = {} as DefaultSlotInterface;
|
const blockButtons = {} as DefaultSlotInterface;
|
||||||
const templateButtons = {} as DefaultSlotInterface;
|
const templateButtons = {} as DefaultSlotInterface;
|
||||||
const removeFormats = writable<RemoveFormat[]>([]);
|
const removeFormats = writable<RemoveFormat[]>([]);
|
||||||
|
|
|
@ -4,7 +4,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as tr from "@generated/ftl";
|
import * as tr from "@generated/ftl";
|
||||||
import { bridgeCommand } from "@tslib/bridgecommand";
|
|
||||||
import { removeStyleProperties } from "@tslib/styling";
|
import { removeStyleProperties } from "@tslib/styling";
|
||||||
import { singleCallback } from "@tslib/typing";
|
import { singleCallback } from "@tslib/typing";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
@ -19,6 +18,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
import ColorPicker from "./ColorPicker.svelte";
|
import ColorPicker from "./ColorPicker.svelte";
|
||||||
import { context as editorToolbarContext } from "./EditorToolbar.svelte";
|
import { context as editorToolbarContext } from "./EditorToolbar.svelte";
|
||||||
import WithColorHelper from "./WithColorHelper.svelte";
|
import WithColorHelper from "./WithColorHelper.svelte";
|
||||||
|
import { setProfileConfig } from "@tslib/profile";
|
||||||
|
|
||||||
export let color: string;
|
export let color: string;
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
value={color}
|
value={color}
|
||||||
on:input={(event) => {
|
on:input={(event) => {
|
||||||
color = setColor(event);
|
color = setColor(event);
|
||||||
bridgeCommand(`lastHighlightColor:${color}`);
|
setProfileConfig("lastHighlightColor", color);
|
||||||
}}
|
}}
|
||||||
on:change={() => setTextColor()}
|
on:change={() => setTextColor()}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -2,6 +2,14 @@
|
||||||
Copyright: Ankitects Pty Ltd and contributors
|
Copyright: Ankitects Pty Ltd and contributors
|
||||||
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<script context="module" lang="ts">
|
||||||
|
import type { DefaultSlotInterface } from "$lib/sveltelib/dynamic-slotting";
|
||||||
|
export interface InlineButtonsAPI extends DefaultSlotInterface {
|
||||||
|
setColorButtons: (colors: [string, string]) => void;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import ButtonGroup from "$lib/components/ButtonGroup.svelte";
|
import ButtonGroup from "$lib/components/ButtonGroup.svelte";
|
||||||
import DynamicallySlottable from "$lib/components/DynamicallySlottable.svelte";
|
import DynamicallySlottable from "$lib/components/DynamicallySlottable.svelte";
|
||||||
|
@ -16,16 +24,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
import TextColorButton from "./TextColorButton.svelte";
|
import TextColorButton from "./TextColorButton.svelte";
|
||||||
import UnderlineButton from "./UnderlineButton.svelte";
|
import UnderlineButton from "./UnderlineButton.svelte";
|
||||||
|
|
||||||
export let api = {};
|
|
||||||
|
|
||||||
let textColor: string = "black";
|
let textColor: string = "black";
|
||||||
let highlightColor: string = "black";
|
let highlightColor: string = "black";
|
||||||
export function setColorButtons([textClr, highlightClr]: [string, string]): void {
|
|
||||||
|
function setColorButtons([textClr, highlightClr]: [string, string]): void {
|
||||||
textColor = textClr;
|
textColor = textClr;
|
||||||
highlightColor = highlightClr;
|
highlightColor = highlightClr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.assign(globalThis, { setColorButtons });
|
export let api = {} as InlineButtonsAPI;
|
||||||
|
Object.assign(api, {
|
||||||
|
setColorButtons,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DynamicallySlottable slotHost={Item} {api}>
|
<DynamicallySlottable slotHost={Item} {api}>
|
||||||
|
|
|
@ -4,7 +4,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as tr from "@generated/ftl";
|
import * as tr from "@generated/ftl";
|
||||||
import { bridgeCommand } from "@tslib/bridgecommand";
|
|
||||||
import { getPlatformString } from "@tslib/shortcuts";
|
import { getPlatformString } from "@tslib/shortcuts";
|
||||||
import { removeStyleProperties } from "@tslib/styling";
|
import { removeStyleProperties } from "@tslib/styling";
|
||||||
import { singleCallback } from "@tslib/typing";
|
import { singleCallback } from "@tslib/typing";
|
||||||
|
@ -22,6 +21,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
import ColorPicker from "./ColorPicker.svelte";
|
import ColorPicker from "./ColorPicker.svelte";
|
||||||
import { context as editorToolbarContext } from "./EditorToolbar.svelte";
|
import { context as editorToolbarContext } from "./EditorToolbar.svelte";
|
||||||
import WithColorHelper from "./WithColorHelper.svelte";
|
import WithColorHelper from "./WithColorHelper.svelte";
|
||||||
|
import { setProfileConfig } from "@tslib/profile";
|
||||||
|
|
||||||
export let color: string;
|
export let color: string;
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
value={color}
|
value={color}
|
||||||
on:input={(event) => {
|
on:input={(event) => {
|
||||||
color = setColor(event);
|
color = setColor(event);
|
||||||
bridgeCommand(`lastTextColor:${color}`);
|
setProfileConfig("lastTextColor", color);
|
||||||
}}
|
}}
|
||||||
on:change={() => {
|
on:change={() => {
|
||||||
// Delay added to work around intermittent failures on macOS/Qt6.5
|
// Delay added to work around intermittent failures on macOS/Qt6.5
|
||||||
|
|
Loading…
Reference in a new issue