diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py index 5065abb297b..f1be916dd48 100644 --- a/qt/aqt/editor.py +++ b/qt/aqt/editor.py @@ -76,11 +76,6 @@ ) _html = """ -
@@ -135,10 +130,9 @@ def setupWeb(self) -> None: self.web.set_bridge_command(self.onBridgeCmd, self) self.outerLayout.addWidget(self.web, 1) - bgcol = self.mw.app.palette().window().color().name() # type: ignore # then load page self.web.stdHtml( - _html % (bgcol, tr.editing_show_duplicates()), + _html % tr.editing_show_duplicates(), css=[ "css/editor.css", ], diff --git a/ts/deckoptions/BUILD.bazel b/ts/deckoptions/BUILD.bazel index 060214fc5ef..94c2683d430 100644 --- a/ts/deckoptions/BUILD.bazel +++ b/ts/deckoptions/BUILD.bazel @@ -58,6 +58,7 @@ ts_library( "lib.ts", "steps.ts", "textInputModal.ts", + "optionsDropdown.ts", ], module_name = "deckoptions", deps = [ @@ -97,6 +98,7 @@ esbuild( "@npm//bootstrap", ":base_css", "//ts/sveltelib", + "//ts/sveltelib:svelte_components", ] + svelte_names, ) diff --git a/ts/deckoptions/ConfigSelector.svelte b/ts/deckoptions/ConfigSelector.svelte index c6fea0a0dba..72e78586df7 100644 --- a/ts/deckoptions/ConfigSelector.svelte +++ b/ts/deckoptions/ConfigSelector.svelte @@ -4,54 +4,20 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html --> - + + diff --git a/ts/deckoptions/DeckOptionsPage.svelte b/ts/deckoptions/DeckOptionsPage.svelte index bacffa18647..072f208a797 100644 --- a/ts/deckoptions/DeckOptionsPage.svelte +++ b/ts/deckoptions/DeckOptionsPage.svelte @@ -6,15 +6,19 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import ConfigSelector from "./ConfigSelector.svelte"; import ConfigEditor from "./ConfigEditor.svelte"; import type { DeckOptionsState } from "./lib"; - import { onMount, onDestroy } from "svelte"; + import { onMount, onDestroy, setContext } from "svelte"; import { registerShortcut } from "lib/shortcuts"; import type { Writable } from "svelte/store"; import HtmlAddon from "./HtmlAddon.svelte"; - import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent"; + import type { DynamicSvelteComponent } from "sveltelib/dynamicComponents"; + import { nightModeKey } from "sveltelib/contextKeys"; export let state: DeckOptionsState; let addons = state.addonComponents; + export let nightMode: boolean; + setContext(nightModeKey, nightMode); + export function auxData(): Writable> { return state.currentAuxData; } diff --git a/ts/deckoptions/OptionsDropdown.svelte b/ts/deckoptions/OptionsDropdown.svelte deleted file mode 100644 index 23916d34a04..00000000000 --- a/ts/deckoptions/OptionsDropdown.svelte +++ /dev/null @@ -1,97 +0,0 @@ - - - - - -
- - - -
diff --git a/ts/deckoptions/deckoptions-base.scss b/ts/deckoptions/deckoptions-base.scss index 9c050d5b983..d0af397ad0b 100644 --- a/ts/deckoptions/deckoptions-base.scss +++ b/ts/deckoptions/deckoptions-base.scss @@ -1,3 +1,4 @@ +@use "ts/sass/vars"; @use "ts/sass/scrollbar"; @use "ts/sass/bootstrap-dark"; diff --git a/ts/deckoptions/index.ts b/ts/deckoptions/index.ts index 7af7871f00e..75a754fee52 100644 --- a/ts/deckoptions/index.ts +++ b/ts/deckoptions/index.ts @@ -14,7 +14,7 @@ export async function deckOptions( target: HTMLDivElement, deckId: number ): Promise { - checkNightMode(); + const nightMode = checkNightMode(); await setupI18n({ modules: [ModuleName.SCHEDULING, ModuleName.ACTIONS, ModuleName.DECK_CONFIG], }); @@ -22,7 +22,7 @@ export async function deckOptions( const state = new DeckOptionsState(deckId, info); return new DeckOptionsPage({ target, - props: { state }, + props: { state, nightMode }, }); } diff --git a/ts/deckoptions/lib.ts b/ts/deckoptions/lib.ts index c34cc38e71f..b9cc2b4191b 100644 --- a/ts/deckoptions/lib.ts +++ b/ts/deckoptions/lib.ts @@ -10,7 +10,7 @@ import { postRequest } from "lib/postrequest"; import { Writable, writable, get, Readable, readable } from "svelte/store"; import { isEqual, cloneDeep } from "lodash-es"; import * as tr from "lib/i18n"; -import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent"; +import type { DynamicSvelteComponent } from "sveltelib/dynamicComponents"; export async function getDeckOptionsInfo( deckId: number diff --git a/ts/deckoptions/optionsDropdown.ts b/ts/deckoptions/optionsDropdown.ts new file mode 100644 index 00000000000..99c22b7140d --- /dev/null +++ b/ts/deckoptions/optionsDropdown.ts @@ -0,0 +1,136 @@ +// Copyright: Ankitects Pty Ltd and contributors +// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +import * as tr from "lib/i18n"; +import { textInputModal } from "./textInputModal"; +import type { DeckOptionsState, ConfigListEntry } from "./lib"; +import { + DynamicSvelteComponent, + labelButton, + buttonGroup, + dropdownMenu, + dropdownItem, + dropdownDivider, + selectButton, +} from "sveltelib/dynamicComponents"; + +function configLabel(entry: ConfigListEntry): string { + const count = tr.deckConfigUsedByDecks({ decks: entry.useCount }); + return `${entry.name} (${count})`; +} + +export function getOptionsDropdown( + state: DeckOptionsState, + configList: ConfigListEntry[] +): DynamicSvelteComponent { + function addConfig(): void { + textInputModal({ + title: "Add Config", + prompt: "Name:", + onOk: (text: string) => { + const trimmed = text.trim(); + if (trimmed.length) { + state.addConfig(trimmed); + } + }, + }); + } + + function renameConfig(): void { + textInputModal({ + title: "Rename Config", + prompt: "Name:", + startingValue: state.getCurrentName(), + onOk: (text: string) => { + state.setCurrentName(text); + }, + }); + } + + function removeConfig(): void { + // show pop-up after dropdown has gone away + setTimeout(() => { + if (state.defaultConfigSelected()) { + alert(tr.schedulingTheDefaultConfigurationCantBeRemoved()); + return; + } + // fixme: move tr.qt_misc schema mod msg into core + // fixme: include name of deck in msg + const msg = state.removalWilLForceFullSync() + ? "This will require a one-way sync. Are you sure?" + : "Are you sure?"; + if (confirm(msg)) { + try { + state.removeCurrentConfig(); + } catch (err) { + alert(err); + } + } + }, 100); + } + + function save(applyToChildDecks: boolean): void { + state.save(applyToChildDecks); + } + + function blur(this: HTMLSelectElement) { + state.setCurrentIndex(parseInt(this.value)); + } + + const options = configList.map((entry) => ({ + value: entry.idx, + selected: entry.current, + label: configLabel(entry), + })); + + return buttonGroup({ + id: "configSelector", + className: "justify-content-between", + size: 35, + items: [ + buttonGroup({ + className: "flex-basis-75", + items: [ + selectButton({ + options, + className: "flex-basis-100", + onChange: blur, + }), + ], + }), + buttonGroup({ + id: "optionsDropdown", + items: [ + labelButton({ + label: "Save", + theme: "primary", + onClick: () => save(false), + }), + labelButton({ + dropdownToggle: true, + }), + dropdownMenu({ + items: [ + dropdownItem({ + label: "Add Config", + onClick: addConfig, + }), + dropdownItem({ + label: "Rename Config", + onClick: renameConfig, + }), + dropdownItem({ + label: "Remove Config", + onClick: removeConfig, + }), + dropdownDivider({}), + dropdownItem({ + label: "Save to All Children", + onClick: () => save(true), + }), + ], + }), + ], + }), + ], + }); +} diff --git a/ts/editor-toolbar/ButtonDropdown.d.ts b/ts/editor-toolbar/ButtonDropdown.d.ts index 2b3cdb70f1f..b35d2e6e077 100644 --- a/ts/editor-toolbar/ButtonDropdown.d.ts +++ b/ts/editor-toolbar/ButtonDropdown.d.ts @@ -1,6 +1,6 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import type { ToolbarItem } from "./types"; +import type { ToolbarItem } from "sveltelib/types"; export interface ButtonDropdownProps { id: string; diff --git a/ts/editor-toolbar/ButtonDropdown.svelte b/ts/editor-toolbar/ButtonDropdown.svelte index a1585c12f8c..684c17776f7 100644 --- a/ts/editor-toolbar/ButtonDropdown.svelte +++ b/ts/editor-toolbar/ButtonDropdown.svelte @@ -3,8 +3,8 @@ Copyright: Ankitects Pty Ltd and contributors License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html --> diff --git a/ts/editor-toolbar/ColorPicker.svelte b/ts/editor-toolbar/ColorPicker.svelte index 277b74eaec6..a669977a7fc 100644 --- a/ts/editor-toolbar/ColorPicker.svelte +++ b/ts/editor-toolbar/ColorPicker.svelte @@ -4,8 +4,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html --> - -
{#each menus as menu} {/each} -
- + + + +
diff --git a/ts/editor-toolbar/SquareButton.svelte b/ts/editor-toolbar/SquareButton.svelte index ae0ac2bdbe6..bcf51653aac 100644 --- a/ts/editor-toolbar/SquareButton.svelte +++ b/ts/editor-toolbar/SquareButton.svelte @@ -5,8 +5,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html - +
diff --git a/ts/sveltelib/DropdownDivider.svelte b/ts/sveltelib/DropdownDivider.svelte new file mode 100644 index 00000000000..7f3db50bfc9 --- /dev/null +++ b/ts/sveltelib/DropdownDivider.svelte @@ -0,0 +1,5 @@ + + diff --git a/ts/editor-toolbar/DropdownItem.d.ts b/ts/sveltelib/DropdownItem.d.ts similarity index 100% rename from ts/editor-toolbar/DropdownItem.d.ts rename to ts/sveltelib/DropdownItem.d.ts diff --git a/ts/editor-toolbar/DropdownItem.svelte b/ts/sveltelib/DropdownItem.svelte similarity index 100% rename from ts/editor-toolbar/DropdownItem.svelte rename to ts/sveltelib/DropdownItem.svelte diff --git a/ts/editor-toolbar/DropdownMenu.d.ts b/ts/sveltelib/DropdownMenu.d.ts similarity index 100% rename from ts/editor-toolbar/DropdownMenu.d.ts rename to ts/sveltelib/DropdownMenu.d.ts diff --git a/ts/editor-toolbar/DropdownMenu.svelte b/ts/sveltelib/DropdownMenu.svelte similarity index 69% rename from ts/editor-toolbar/DropdownMenu.svelte rename to ts/sveltelib/DropdownMenu.svelte index f616dd0a55e..d3327b0cbb1 100644 --- a/ts/editor-toolbar/DropdownMenu.svelte +++ b/ts/sveltelib/DropdownMenu.svelte @@ -9,24 +9,16 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html export let id: string; export let items: ToolbarItem[]; - - const nightMode = getContext(nightModeKey); -