feat(react/settings): basic hook to read Trilium option

This commit is contained in:
Elian Doran 2025-08-14 17:36:11 +03:00
parent 8ff108db9e
commit fbc1af56ed
No known key found for this signature in database
6 changed files with 67 additions and 29 deletions

View File

@ -1,9 +1,11 @@
import type { ComponentChildren } from "preact";
interface FormRadioProps { interface FormRadioProps {
name: string; name: string;
currentValue?: string; currentValue?: string;
values: { values: {
value: string; value: string;
label: string; label: string | ComponentChildren;
}[]; }[];
onChange(newValue: string): void; onChange(newValue: string): void;
} }

View File

@ -1,7 +1,9 @@
import { useContext, useEffect, useRef } from "preact/hooks"; import { type Dispatch, type StateUpdater, useContext, useEffect, useRef, useState } from "preact/hooks";
import { EventData, EventNames } from "../../components/app_context"; import { EventData, EventNames } from "../../components/app_context";
import { ParentComponent } from "./ReactBasicWidget"; import { ParentComponent } from "./ReactBasicWidget";
import SpacedUpdate from "../../services/spaced_update"; import SpacedUpdate from "../../services/spaced_update";
import { OptionNames } from "@triliumnext/commons";
import options from "../../services/options";
/** /**
* Allows a React component to react to Trilium events (e.g. `entitiesReloaded`). When the desired event is triggered, the handler is invoked with the event parameters. * Allows a React component to react to Trilium events (e.g. `entitiesReloaded`). When the desired event is triggered, the handler is invoked with the event parameters.
@ -63,4 +65,14 @@ export function useSpacedUpdate(callback: () => Promise<void>, interval = 1000)
}, [interval]); }, [interval]);
return spacedUpdateRef.current; return spacedUpdateRef.current;
}
export function useTriliumOption(name: OptionNames): [string, Dispatch<StateUpdater<string>>] {
const initialValue = options.get(name);
const [ value, setValue ] = useState(initialValue);
return [
value,
setValue
]
} }

View File

@ -76,8 +76,8 @@ const TPL = /*html*/`<div class="note-detail-content-widget note-detail-printabl
export type OptionPages = "_optionsAppearance" | "_optionsShortcuts" | "_optionsTextNotes" | "_optionsCodeNotes" | "_optionsImages" | "_optionsSpellcheck" | "_optionsPassword" | "_optionsMFA" | "_optionsEtapi" | "_optionsBackup" | "_optionsSync" | "_optionsAi" | "_optionsOther" | "_optionsLocalization" | "_optionsAdvanced"; export type OptionPages = "_optionsAppearance" | "_optionsShortcuts" | "_optionsTextNotes" | "_optionsCodeNotes" | "_optionsImages" | "_optionsSpellcheck" | "_optionsPassword" | "_optionsMFA" | "_optionsEtapi" | "_optionsBackup" | "_optionsSync" | "_optionsAi" | "_optionsOther" | "_optionsLocalization" | "_optionsAdvanced";
const CONTENT_WIDGETS: Record<OptionPages | "_backendLog", ((typeof NoteContextAwareWidget)[] | (() => JSX.Element))> = { const CONTENT_WIDGETS: Record<OptionPages | "_backendLog", ((typeof NoteContextAwareWidget)[] | JSX.Element)> = {
_optionsAppearance: AppearanceSettings, _optionsAppearance: <AppearanceSettings />,
_optionsShortcuts: [ _optionsShortcuts: [
KeyboardShortcutsOptions KeyboardShortcutsOptions
], ],
@ -169,7 +169,7 @@ export default class ContentWidgetTypeWidget extends TypeWidget {
this.$content.empty(); this.$content.empty();
this.children = []; this.children = [];
const contentWidgets = (CONTENT_WIDGETS as Record<string, (typeof NoteContextAwareWidget[] | (() => JSX.Element))>)[note.noteId]; const contentWidgets = (CONTENT_WIDGETS as Record<string, (typeof NoteContextAwareWidget[] | JSX.Element)>)[note.noteId];
this.$content.toggleClass("options", note.noteId.startsWith("_options")); this.$content.toggleClass("options", note.noteId.startsWith("_options"));
// Unknown widget. // Unknown widget.
@ -196,7 +196,7 @@ export default class ContentWidgetTypeWidget extends TypeWidget {
} }
// React widget. // React widget.
this.$content.append(renderReactWidget(this, contentWidgets())); this.$content.append(renderReactWidget(this, contentWidgets));
} }
} }

View File

@ -1,3 +1,33 @@
import { t } from "../../../services/i18n";
import FormRadioGroup from "../../react/FormRadioGroup";
import { useTriliumOption } from "../../react/hooks";
import OptionsSection from "./components/OptionsSection";
export default function AppearanceSettings() { export default function AppearanceSettings() {
return <p>Hi</p> const [ layoutOrientation, setLayoutOrientation ] = useTriliumOption("layoutOrientation");
return (
<OptionsSection title={t("theme.layout")}>
<FormRadioGroup
name="layout-orientation"
values={[
{
label: <>
<strong>{t("theme.layout-vertical-title")}</strong>
- {t("theme.layout-vertical-description")}
</>,
value: "vertical"
},
{
label: <>
<strong>{t("theme.layout-horizontal-title")}</strong>
- {t("theme.layout-horizontal-description")}
</>,
value: "horizontal"
}
]}
currentValue={layoutOrientation} onChange={setLayoutOrientation}
/>
</OptionsSection>
)
} }

View File

@ -5,28 +5,6 @@ import { t } from "../../../../services/i18n.js";
import type { OptionMap } from "@triliumnext/commons"; import type { OptionMap } from "@triliumnext/commons";
const TPL = /*html*/` const TPL = /*html*/`
<div class="options-section">
<h4>${t("theme.layout")}</h4>
<div class="form-group row">
<div>
<label class="tn-radio">
<input type="radio" name="layout-orientation" value="vertical" />
<strong>${t("theme.layout-vertical-title")}</strong>
- ${t("theme.layout-vertical-description")}
</label>
</div>
<div>
<label class="tn-radio">
<input type="radio" name="layout-orientation" value="horizontal" />
<strong>${t("theme.layout-horizontal-title")}</strong>
- ${t("theme.layout-horizontal-description")}
</label>
</div>
</div>
</div>
<div class="options-section"> <div class="options-section">
<h4>${t("theme.title")}</h4> <h4>${t("theme.title")}</h4>

View File

@ -0,0 +1,16 @@
import type { ComponentChildren } from "preact";
interface OptionsSectionProps {
title: string;
children: ComponentChildren;
}
export default function OptionsSection({ title, children }: OptionsSectionProps) {
return (
<div className="options-section">
<h4>{title}</h4>
{children}
</div>
);
}