From f62078d02b1ac748a3bd51cc6d8e39bc59f6e636 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Fri, 15 Aug 2025 11:21:19 +0300 Subject: [PATCH] feat(react/settings): port sync options --- apps/client/src/services/utils.ts | 53 +++++----- apps/client/src/widgets/react/FormTextBox.tsx | 7 +- apps/client/src/widgets/react/hooks.tsx | 14 +++ .../widgets/type_widgets/content_widget.tsx | 6 +- .../src/widgets/type_widgets/options/sync.ts | 100 ------------------ .../src/widgets/type_widgets/options/sync.tsx | 62 +++++++++++ 6 files changed, 110 insertions(+), 132 deletions(-) delete mode 100644 apps/client/src/widgets/type_widgets/options/sync.ts create mode 100644 apps/client/src/widgets/type_widgets/options/sync.tsx diff --git a/apps/client/src/services/utils.ts b/apps/client/src/services/utils.ts index fb2d1941d..4b714bf9c 100644 --- a/apps/client/src/services/utils.ts +++ b/apps/client/src/services/utils.ts @@ -374,33 +374,36 @@ async function openInAppHelp($button: JQuery) { const inAppHelpPage = $button.attr("data-in-app-help"); if (inAppHelpPage) { - // Dynamic import to avoid import issues in tests. - const appContext = (await import("../components/app_context.js")).default; - const activeContext = appContext.tabManager.getActiveContext(); - if (!activeContext) { - return; - } - const subContexts = activeContext.getSubContexts(); - const targetNote = `_help_${inAppHelpPage}`; - const helpSubcontext = subContexts.find((s) => s.viewScope?.viewMode === "contextual-help"); - const viewScope: ViewScope = { - viewMode: "contextual-help", - }; - if (!helpSubcontext) { - // The help is not already open, open a new split with it. - const { ntxId } = subContexts[subContexts.length - 1]; - appContext.triggerCommand("openNewNoteSplit", { - ntxId, - notePath: targetNote, - hoistedNoteId: "_help", - viewScope - }) - } else { - // There is already a help window open, make sure it opens on the right note. - helpSubcontext.setNote(targetNote, { viewScope }); - } + openInAppHelpFromUrl(inAppHelpPage); + } +} + +export async function openInAppHelpFromUrl(inAppHelpPage: string) { + // Dynamic import to avoid import issues in tests. + const appContext = (await import("../components/app_context.js")).default; + const activeContext = appContext.tabManager.getActiveContext(); + if (!activeContext) { return; } + const subContexts = activeContext.getSubContexts(); + const targetNote = `_help_${inAppHelpPage}`; + const helpSubcontext = subContexts.find((s) => s.viewScope?.viewMode === "contextual-help"); + const viewScope: ViewScope = { + viewMode: "contextual-help", + }; + if (!helpSubcontext) { + // The help is not already open, open a new split with it. + const { ntxId } = subContexts[subContexts.length - 1]; + appContext.triggerCommand("openNewNoteSplit", { + ntxId, + notePath: targetNote, + hoistedNoteId: "_help", + viewScope + }) + } else { + // There is already a help window open, make sure it opens on the right note. + helpSubcontext.setNote(targetNote, { viewScope }); + } } function initHelpButtons($el: JQuery | JQuery) { diff --git a/apps/client/src/widgets/react/FormTextBox.tsx b/apps/client/src/widgets/react/FormTextBox.tsx index abf0e9c5a..01b7b56c2 100644 --- a/apps/client/src/widgets/react/FormTextBox.tsx +++ b/apps/client/src/widgets/react/FormTextBox.tsx @@ -1,5 +1,4 @@ import type { InputHTMLAttributes, RefObject } from "preact/compat"; -import FormText from "./FormText"; interface FormTextBoxProps extends Omit, "onChange" | "value"> { id?: string; @@ -11,9 +10,11 @@ interface FormTextBoxProps extends Omit, " export default function FormTextBox({ inputRef, className, type, currentValue, onChange, ...rest}: FormTextBoxProps) { if (type === "number" && currentValue) { const { min, max } = rest; - if (min && currentValue < min) { + console.log(currentValue , min, max); + const currentValueNum = parseInt(currentValue, 10); + if (min && currentValueNum < parseInt(String(min), 10)) { currentValue = String(min); - } else if (max && currentValue > max) { + } else if (max && currentValueNum > parseInt(String(max), 10)) { currentValue = String(max); } } diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx index 6ea511be9..846ea62fb 100644 --- a/apps/client/src/widgets/react/hooks.tsx +++ b/apps/client/src/widgets/react/hooks.tsx @@ -6,6 +6,7 @@ import { OptionNames } from "@triliumnext/commons"; import options, { type OptionValue } from "../../services/options"; import utils, { reloadFrontendApp } from "../../services/utils"; import Component from "../../components/component"; +import server from "../../services/server"; type TriliumEventHandler = (data: EventData) => void; const registeredHandlers: Map[]>> = new Map(); @@ -150,6 +151,19 @@ export function useTriliumOptionJson(name: OptionNames): [ T, (newValue: T) = ]; } +export function useTriliumOptions(...names: T[]) { + const values: Record = {}; + for (const name of names) { + values[name] = options.get(name); + } + + const setValue = (newValues: Record) => server.put("options", newValues); + return [ + values as Record, + setValue + ] as const; +} + /** * Generates a unique name via a random alphanumeric string of a fixed length. * diff --git a/apps/client/src/widgets/type_widgets/content_widget.tsx b/apps/client/src/widgets/type_widgets/content_widget.tsx index b847dd04d..9ec12e032 100644 --- a/apps/client/src/widgets/type_widgets/content_widget.tsx +++ b/apps/client/src/widgets/type_widgets/content_widget.tsx @@ -13,7 +13,6 @@ import PasswordOptions from "./options/password/password.js"; import ProtectedSessionTimeoutOptions from "./options/password/protected_session_timeout.js"; import EtapiOptions from "./options/etapi.js"; import BackupOptions from "./options/backup.js"; -import SyncOptions from "./options/sync.js"; import SearchEngineOptions from "./options/other/search_engine.js"; import TrayOptions from "./options/other/tray.js"; import NoteErasureTimeoutOptions from "./options/other/note_erasure_timeout.js"; @@ -40,6 +39,7 @@ import { renderReactWidget } from "../react/ReactBasicWidget.jsx"; import ImageSettings from "./options/images.jsx"; import AdvancedSettings from "./options/advanced.jsx"; import InternationalizationOptions from "./options/i18n.jsx"; +import SyncOptions from "./options/sync.jsx"; const TPL = /*html*/`