feat(react/settings): port electron integration

This commit is contained in:
Elian Doran
2025-08-14 21:42:48 +03:00
parent 0db556fac2
commit 81ac390eab
4 changed files with 43 additions and 83 deletions

View File

@@ -13,7 +13,7 @@ export function reloadFrontendApp(reason?: string) {
window.location.reload();
}
function restartDesktopApp() {
export function restartDesktopApp() {
if (!isElectron()) {
reloadFrontendApp();
return;
@@ -144,7 +144,7 @@ function now() {
/**
* Returns `true` if the client is currently running under Electron, or `false` if running in a web browser.
*/
function isElectron() {
export function isElectron() {
return !!(window && window.process && window.process.type);
}

View File

@@ -14,7 +14,7 @@ interface ButtonProps {
onClick?: () => void;
primary?: boolean;
disabled?: boolean;
size: "normal" | "small" | "micro";
size?: "normal" | "small" | "micro";
style?: CSSProperties;
}

View File

@@ -1,6 +1,6 @@
import { useEffect, useState } from "preact/hooks";
import { t } from "../../../services/i18n";
import { isMobile, reloadFrontendApp } from "../../../services/utils";
import { isElectron, isMobile, reloadFrontendApp, restartDesktopApp } from "../../../services/utils";
import Column from "../../react/Column";
import FormRadioGroup from "../../react/FormRadioGroup";
import FormSelect, { FormSelectWithGroups } from "../../react/FormSelect";
@@ -81,9 +81,10 @@ export default function AppearanceSettings() {
return (
<div>
<LayoutOrientation />
{!isMobile() && <LayoutOrientation />}
<ApplicationTheme />
{overrideThemeFonts === "true" && <Fonts />}
{isElectron() && <ElectronIntegration /> }
</div>
)
}
@@ -93,7 +94,7 @@ function LayoutOrientation() {
return (
<OptionsSection title={t("theme.layout")}>
{!isMobile() && <FormRadioGroup
<FormRadioGroup
name="layout-orientation"
values={[
{
@@ -106,7 +107,7 @@ function LayoutOrientation() {
}
]}
currentValue={layoutOrientation} onChange={setLayoutOrientation}
/>}
/>
</OptionsSection>
);
}
@@ -193,4 +194,39 @@ function Font({ title, fontFamilyOption, fontSizeOption }: { title: string, font
</div>
</>
);
}
function ElectronIntegration() {
const [ zoomFactor, setZoomFactor ] = useTriliumOption("zoomFactor");
const [ nativeTitleBarVisible, setNativeTitleBarVisible ] = useTriliumOptionBool("nativeTitleBarVisible");
const [ backgroundEffects, setBackgroundEffects ] = useTriliumOptionBool("backgroundEffects");
return (
<OptionsSection title={t("electron_integration.desktop-application")}>
<FormGroup label={t("electron_integration.zoom-factor")} description={t("zoom_factor.description")}>
<FormTextBox
type="number"
min="0.3" max="2.0" step="0.1"
currentValue={zoomFactor} onChange={setZoomFactor}
/>
</FormGroup>
<hr/>
<FormGroup description={t("electron_integration.native-title-bar-description")}>
<FormCheckbox
name="native-title-bar" label={t("electron_integration.native-title-bar")}
currentValue={nativeTitleBarVisible} onChange={setNativeTitleBarVisible}
/>
</FormGroup>
<FormGroup description={t("electron_integration.background-effects-description")}>
<FormCheckbox
name="background-effects" label={t("electron_integration.background-effects")}
currentValue={backgroundEffects} onChange={setBackgroundEffects}
/>
</FormGroup>
<Button text={t("electron_integration.restart-app-button")} onClick={restartDesktopApp} />
</OptionsSection>
)
}

View File

@@ -1,76 +0,0 @@
import OptionsWidget from "../options_widget.js";
import { t } from "../../../../services/i18n.js";
import utils from "../../../../services/utils.js";
import type { OptionMap } from "@triliumnext/commons";
const TPL = /*html*/`
<div class="options-section">
<h4>${t("electron_integration.desktop-application")}</h4>
<div class="form-group row">
<div class="col-12">
<label for="zoom-factor-select">${t("electron_integration.zoom-factor")}</label>
<input id="zoom-factor-select" type="number" class="zoom-factor-select form-control options-number-input" min="0.3" max="2.0" step="0.1"/>
<p class="form-text">${t("zoom_factor.description")}</p>
</div>
</div>
<hr />
<div>
<label class="form-check tn-checkbox">
<input type="checkbox" class="native-title-bar form-check-input" />
${t("electron_integration.native-title-bar")}
</label>
<p class="form-text">
${t("electron_integration.native-title-bar-description")}
</p>
</div>
<div>
<label class="form-check tn-checkbox">
<input type="checkbox" class="background-effects form-check-input" />
${t("electron_integration.background-effects")}
</label>
<p class="form-text">
${t("electron_integration.background-effects-description")}
</p>
</div>
<button class="btn btn-secondary btn-micro restart-app-button">${t("electron_integration.restart-app-button")}</button>
</div>
`;
export default class ElectronIntegrationOptions extends OptionsWidget {
private $zoomFactorSelect!: JQuery<HTMLElement>;
private $nativeTitleBar!: JQuery<HTMLElement>;
private $backgroundEffects!: JQuery<HTMLElement>;
doRender() {
this.$widget = $(TPL);
this.$zoomFactorSelect = this.$widget.find(".zoom-factor-select");
this.$zoomFactorSelect.on("change", () => {
this.triggerCommand("setZoomFactorAndSave", { zoomFactor: String(this.$zoomFactorSelect.val()) });
});
this.$nativeTitleBar = this.$widget.find("input.native-title-bar");
this.$nativeTitleBar.on("change", () => this.updateCheckboxOption("nativeTitleBarVisible", this.$nativeTitleBar));
this.$backgroundEffects = this.$widget.find("input.background-effects");
this.$backgroundEffects.on("change", () => this.updateCheckboxOption("backgroundEffects", this.$backgroundEffects));
const restartAppButton = this.$widget.find(".restart-app-button");
restartAppButton.on("click", utils.restartDesktopApp);
}
isEnabled() {
return utils.isElectron();
}
async optionsLoaded(options: OptionMap) {
this.$zoomFactorSelect.val(options.zoomFactor);
this.setCheckboxState(this.$nativeTitleBar, options.nativeTitleBarVisible);
this.setCheckboxState(this.$backgroundEffects, options.backgroundEffects);
}
}