mirror of
https://github.com/zadam/trilium.git
synced 2025-12-18 21:39:32 +08:00
feat(options/appearance): add basic illustration for old layout
This commit is contained in:
parent
af02685f2f
commit
948a6f84d6
7 changed files with 237 additions and 33 deletions
91
apps/client/src/widgets/type_widgets/options/appearance.css
Normal file
91
apps/client/src/widgets/type_widgets/options/appearance.css
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
.old-layout-illustration {
|
||||
width: 170px;
|
||||
height: 130px;
|
||||
border: 1px solid var(--main-border-color);
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
background: var(--root-background);
|
||||
overflow: hidden;
|
||||
|
||||
.launcher-pane {
|
||||
width: 10%;
|
||||
background: var(--launcher-pane-vert-background-color);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 1px 0;
|
||||
|
||||
svg {
|
||||
margin-top: 1px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.bx {
|
||||
margin: 4px 0;
|
||||
font-size: 12px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.tree {
|
||||
width: 20%;
|
||||
font-size: 4px;
|
||||
padding: 12px 5px;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
|
||||
.tab-bar {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.content {
|
||||
background-color: var(--main-background-color);
|
||||
flex-grow: 1;
|
||||
border-top-left-radius: 6px;
|
||||
padding: 5px;
|
||||
|
||||
.title-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
|
||||
.title {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.ribbon {
|
||||
.bx {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.ribbon-header {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.ribbon-body {
|
||||
height: 20px;
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
border-radius: 6px;
|
||||
margin: 1px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.content-inner {
|
||||
font-size: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,23 @@
|
|||
import "./appearance.css";
|
||||
|
||||
import { FontFamily, OptionNames } from "@triliumnext/commons";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
import { t } from "../../../services/i18n";
|
||||
import { isElectron, isMobile, reloadFrontendApp, restartDesktopApp } from "../../../services/utils";
|
||||
import Column from "../../react/Column";
|
||||
import FormRadioGroup from "../../react/FormRadioGroup";
|
||||
import FormSelect, { FormSelectWithGroups } from "../../react/FormSelect";
|
||||
import { useTriliumOption, useTriliumOptionBool } from "../../react/hooks";
|
||||
import OptionsSection from "./components/OptionsSection";
|
||||
import server from "../../../services/server";
|
||||
import { isElectron, isMobile, reloadFrontendApp, restartDesktopApp } from "../../../services/utils";
|
||||
import Button from "../../react/Button";
|
||||
import Column from "../../react/Column";
|
||||
import FormCheckbox from "../../react/FormCheckbox";
|
||||
import FormGroup from "../../react/FormGroup";
|
||||
import { FontFamily, OptionNames } from "@triliumnext/commons";
|
||||
import FormTextBox, { FormTextBoxWithUnit } from "../../react/FormTextBox";
|
||||
import FormRadioGroup from "../../react/FormRadioGroup";
|
||||
import FormSelect, { FormSelectWithGroups } from "../../react/FormSelect";
|
||||
import FormText from "../../react/FormText";
|
||||
import Button from "../../react/Button";
|
||||
import FormTextBox, { FormTextBoxWithUnit } from "../../react/FormTextBox";
|
||||
import { useTriliumOption, useTriliumOptionBool } from "../../react/hooks";
|
||||
import Icon from "../../react/Icon";
|
||||
import OptionsSection from "./components/OptionsSection";
|
||||
import RadioWithIllustration from "./components/RadioWithIllustration";
|
||||
import RelatedSettings from "./components/RelatedSettings";
|
||||
|
||||
const MIN_CONTENT_WIDTH = 640;
|
||||
|
|
@ -30,7 +35,7 @@ const BUILTIN_THEMES: Theme[] = [
|
|||
{ val: "auto", title: t("theme.auto_theme") },
|
||||
{ val: "light", title: t("theme.light_theme") },
|
||||
{ val: "dark", title: t("theme.dark_theme") }
|
||||
]
|
||||
];
|
||||
|
||||
interface FontFamilyEntry {
|
||||
value: FontFamily;
|
||||
|
|
@ -84,6 +89,7 @@ export default function AppearanceSettings() {
|
|||
|
||||
return (
|
||||
<div>
|
||||
{!isMobile() && <LayoutSwitcher />}
|
||||
{!isMobile() && <LayoutOrientation />}
|
||||
<ApplicationTheme />
|
||||
{overrideThemeFonts === "true" && <Fonts />}
|
||||
|
|
@ -102,7 +108,73 @@ export default function AppearanceSettings() {
|
|||
}
|
||||
]} />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function LayoutSwitcher() {
|
||||
return (
|
||||
<OptionsSection title="Layout">
|
||||
<RadioWithIllustration
|
||||
values={[
|
||||
{ key: "old-layout", text: "Old layout", illustration: <LayoutIllustration /> },
|
||||
{ key: "new-layout", text: "New layout", illustration: <LayoutIllustration isNewLayout /> }
|
||||
]}
|
||||
/>
|
||||
</OptionsSection>
|
||||
);
|
||||
}
|
||||
|
||||
function LayoutIllustration({ isNewLayout }: { isNewLayout: boolean }) {
|
||||
return (
|
||||
<div className="old-layout-illustration">
|
||||
<div className="launcher-pane">
|
||||
<svg viewBox="0 0 256 256" aria-label="Menu" data-bs-original-title="Menu"><g><path d="m202.9 112.7c-22.5 16.1-54.5 12.8-74.9 6.3l14.8-11.8 14.1-11.3 49.1-39.3-51.2 35.9-14.3 10-14.9 10.5c0.7-21.2 7-49.9 28.6-65.4 1.8-1.3 3.9-2.6 6.1-3.8 2.7-1.5 5.7-2.9 8.8-4.1 27.1-11.1 68.5-15.3 85.2-9.5 0.1 16.2-15.9 45.4-33.9 65.9-2.4 2.8-4.9 5.4-7.4 7.8-3.4 3.5-6.8 6.4-10.1 8.8z" class="st0" /><path d="m213.1 104c-22.2 12.6-51.4 9.3-70.3 3.2l14.1-11.3 49.1-39.3-51.2 35.9-14.3 10c0.5-18.1 4.9-42.1 19.7-58.6 2.7-1.5 5.7-2.9 8.8-4.1 27.1-11.1 68.5-15.3 85.2-9.5 0.1 16.2-15.9 45.4-33.9 65.9-2.3 2.8-4.8 5.4-7.2 7.8z" class="st1" /><path d="m220.5 96.2c-21.1 8.6-46.6 5.3-63.7-0.2l49.2-39.4-51.2 35.9c0.3-15.8 3.5-36.6 14.3-52.8 27.1-11.1 68.5-15.3 85.2-9.5 0.1 16.2-15.9 45.4-33.8 66z" class="st2" /><path d="m106.7 179c-5.8-21 5.2-43.8 15.5-57.2l4.8 14.2 4.5 13.4 15.9 47-12.8-47.6-3.6-13.2-3.7-13.9c15.5 6.2 35.1 18.6 40.7 38.8 0.5 1.7 0.9 3.6 1.2 5.5 0.4 2.4 0.6 5 0.7 7.7 0.9 23.1-7.1 54.9-15.9 65.7-12-4.3-29.3-24-39.7-42.8-1.4-2.6-2.7-5.1-3.8-7.6-1.6-3.5-2.9-6.8-3.8-10z" class="st3" /><path d="m110.4 188.9c-3.4-19.8 6.9-40.5 16.6-52.9l4.5 13.4 15.9 47-12.8-47.6-3.6-13.2c13.3 5.2 29.9 15 38.1 30.4 0.4 2.4 0.6 5 0.7 7.7 0.9 23.1-7.1 54.9-15.9 65.7-12-4.3-29.3-24-39.7-42.8-1.4-2.6-2.7-5.2-3.8-7.7z" class="st4" /><path d="m114.2 196.5c-0.7-18 8.6-35.9 17.3-47.1l15.9 47-12.8-47.6c11.6 4.4 26.1 12.4 35.2 24.8 0.9 23.1-7.1 54.9-15.9 65.7-12-4.3-29.3-24-39.7-42.8z" class="st5" /><path d="m86.3 59.1c21.7 10.9 32.4 36.6 35.8 54.9l-15.2-6.6-14.5-6.3-50.6-22 48.8 24.9 13.6 6.9 14.3 7.3c-16.6 7.9-41.3 14.5-62.1 4.1-1.8-0.9-3.6-1.9-5.4-3.2-2.3-1.5-4.5-3.2-6.8-5.1-19.9-16.4-40.3-46.4-42.7-61.5 12.4-6.5 41.5-5.8 64.8-0.3 3.2 0.8 6.2 1.6 9.1 2.5 4 1.3 7.6 2.8 10.9 4.4z" class="st6" /><path d="m75.4 54.8c18.9 12 28.4 35.6 31.6 52.6l-14.5-6.3-50.6-22 48.7 24.9 13.6 6.9c-14.1 6.8-34.5 13-53.3 8.2-2.3-1.5-4.5-3.2-6.8-5.1-19.8-16.4-40.2-46.4-42.6-61.5 12.4-6.5 41.5-5.8 64.8-0.3 3.1 0.8 6.2 1.6 9.1 2.6z" class="st7" /><path d="m66.3 52.2c15.3 12.8 23.3 33.6 26.1 48.9l-50.6-22 48.8 24.9c-12.2 6-29.6 11.8-46.5 10-19.8-16.4-40.2-46.4-42.6-61.5 12.4-6.5 41.5-5.8 64.8-0.3z" class="st8" /></g></svg>
|
||||
<Icon icon="bx bx-send" />
|
||||
<Icon icon="bx bx-file-blank" />
|
||||
<Icon icon="bx bx-search" />
|
||||
</div>
|
||||
|
||||
<div className="tree">
|
||||
<ul>
|
||||
<li>Options</li>
|
||||
<ul>
|
||||
<li>Appearance</li>
|
||||
<li>Shortcuts</li>
|
||||
<li>Text Notes</li>
|
||||
<li>Code Notes</li>
|
||||
<li>Images</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="main">
|
||||
<div className="tab-bar" />
|
||||
|
||||
<div className="content">
|
||||
<div className="title-bar">
|
||||
<Icon icon="bx bx-note" />
|
||||
<span className="title">Title</span>
|
||||
<Icon icon="bx bx-dock-right" />
|
||||
</div>
|
||||
|
||||
{!isNewLayout && <div className="ribbon">
|
||||
<div className="ribbon-header">
|
||||
<Icon icon="bx bx-slider" />
|
||||
<Icon icon="bx bx-list-check" />
|
||||
<Icon icon="bx bx-list-plus" />
|
||||
<Icon icon="bx bx-collection" />
|
||||
</div>
|
||||
|
||||
<div className="ribbon-body" />
|
||||
</div>}
|
||||
|
||||
<div className="content-inner">
|
||||
This is a "demo" document packaged with Trilium to showcase some of its features and also give you some ideas on how you might structure your notes. You can play with it, and modify the note content and tree structure as you wish.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function LayoutOrientation() {
|
||||
|
|
@ -141,7 +213,7 @@ function ApplicationTheme() {
|
|||
setThemes([
|
||||
...BUILTIN_THEMES,
|
||||
...userThemes
|
||||
])
|
||||
]);
|
||||
});
|
||||
}, []);
|
||||
|
||||
|
|
@ -162,7 +234,7 @@ function ApplicationTheme() {
|
|||
</FormGroup>
|
||||
</div>
|
||||
</OptionsSection>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function Fonts() {
|
||||
|
|
@ -245,7 +317,7 @@ function ElectronIntegration() {
|
|||
|
||||
<Button text={t("electron_integration.restart-app-button")} onClick={restartDesktopApp} />
|
||||
</OptionsSection>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function Performance() {
|
||||
|
|
@ -271,7 +343,7 @@ function Performance() {
|
|||
|
||||
{isElectron() && <SmoothScrollEnabledOption />}
|
||||
|
||||
</OptionsSection>
|
||||
</OptionsSection>;
|
||||
}
|
||||
|
||||
function SmoothScrollEnabledOption() {
|
||||
|
|
@ -280,7 +352,7 @@ function SmoothScrollEnabledOption() {
|
|||
return <FormCheckbox
|
||||
label={`${t("ui-performance.enable-smooth-scroll")} ${t("ui-performance.app-restart-required")}`}
|
||||
currentValue={smoothScrollEnabled} onChange={setSmoothScrollEnabled}
|
||||
/>
|
||||
/>;
|
||||
}
|
||||
|
||||
function MaxContentWidth() {
|
||||
|
|
@ -302,10 +374,10 @@ function MaxContentWidth() {
|
|||
</Column>
|
||||
|
||||
<FormCheckbox label={t("max_content_width.centerContent")}
|
||||
currentValue={centerContent}
|
||||
onChange={setCenterContent} />
|
||||
currentValue={centerContent}
|
||||
onChange={setCenterContent} />
|
||||
</OptionsSection>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function RibbonOptions() {
|
||||
|
|
@ -318,5 +390,5 @@ function RibbonOptions() {
|
|||
currentValue={editedNotesOpenInRibbon} onChange={setEditedNotesOpenInRibbon}
|
||||
/>
|
||||
</OptionsSection>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
.radio-with-illustration {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
gap: 1em;
|
||||
justify-content: center;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import "./RadioWithIllustration.css";
|
||||
|
||||
import { ComponentChild } from "preact";
|
||||
|
||||
interface RadioWithIllustrationProps {
|
||||
values: {
|
||||
key: string;
|
||||
text: string;
|
||||
illustration: ComponentChild;
|
||||
}[];
|
||||
currentValue: string;
|
||||
onChange(newValue: string);
|
||||
}
|
||||
|
||||
export default function RadioWithIllustration({ values }: RadioWithIllustrationProps) {
|
||||
return (
|
||||
<ul className="radio-with-illustration">
|
||||
{values.map(value => (
|
||||
<li key={value.key}>
|
||||
<figure>
|
||||
{value.illustration}
|
||||
<figcaption>{value.text}</figcaption>
|
||||
</figure>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,13 +1,14 @@
|
|||
"use strict";
|
||||
|
||||
import optionService from "../../services/options.js";
|
||||
import log from "../../services/log.js";
|
||||
import searchService from "../../services/search/services/search.js";
|
||||
import ValidationError from "../../errors/validation_error.js";
|
||||
import type { Request } from "express";
|
||||
import { changeLanguage, getLocales } from "../../services/i18n.js";
|
||||
|
||||
import type { OptionNames } from "@triliumnext/commons";
|
||||
import type { Request } from "express";
|
||||
|
||||
import ValidationError from "../../errors/validation_error.js";
|
||||
import config from "../../services/config.js";
|
||||
import { changeLanguage, getLocales } from "../../services/i18n.js";
|
||||
import log from "../../services/log.js";
|
||||
import optionService from "../../services/options.js";
|
||||
import searchService from "../../services/search/services/search.js";
|
||||
|
||||
interface UserTheme {
|
||||
val: string; // value of the theme, used in the URL
|
||||
|
|
@ -100,6 +101,7 @@ const ALLOWED_OPTIONS = new Set<OptionNames>([
|
|||
"splitEditorOrientation",
|
||||
"seenCallToActions",
|
||||
"experimentalFeatures",
|
||||
"newLayout",
|
||||
|
||||
// AI/LLM integration options
|
||||
"aiEnabled",
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import optionService from "./options.js";
|
||||
import { type KeyboardShortcutWithRequiredActionName, type OptionMap, type OptionNames, SANITIZER_DEFAULT_ALLOWED_TAGS } from "@triliumnext/commons";
|
||||
|
||||
import appInfo from "./app_info.js";
|
||||
import { randomSecureToken, isWindows } from "./utils.js";
|
||||
import log from "./log.js";
|
||||
import dateUtils from "./date_utils.js";
|
||||
import keyboardActions from "./keyboard_actions.js";
|
||||
import { SANITIZER_DEFAULT_ALLOWED_TAGS, type KeyboardShortcutWithRequiredActionName, type OptionMap, type OptionNames } from "@triliumnext/commons";
|
||||
import log from "./log.js";
|
||||
import optionService from "./options.js";
|
||||
import { isWindows,randomSecureToken } from "./utils.js";
|
||||
|
||||
function initDocumentOptions() {
|
||||
optionService.createOption("documentId", randomSecureToken(16), false);
|
||||
|
|
@ -156,6 +157,7 @@ const defaultOptions: DefaultOption[] = [
|
|||
{ name: "shadowsEnabled", value: "true", isSynced: false },
|
||||
{ name: "backdropEffectsEnabled", value: "true", isSynced: false },
|
||||
{ name: "smoothScrollEnabled", value: "true", isSynced: false },
|
||||
{ name: "newLayout", value: "true", isSynced: true },
|
||||
|
||||
// Internationalization
|
||||
{ name: "locale", value: "en", isSynced: true },
|
||||
|
|
@ -171,9 +173,9 @@ const defaultOptions: DefaultOption[] = [
|
|||
value: (optionsMap) => {
|
||||
if (optionsMap.theme === "light") {
|
||||
return "default:stackoverflow-light";
|
||||
} else {
|
||||
return "default:stackoverflow-dark";
|
||||
}
|
||||
return "default:stackoverflow-dark";
|
||||
|
||||
},
|
||||
isSynced: false
|
||||
},
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ export interface OptionDefinitions extends KeyboardShortcutsOptions<KeyboardActi
|
|||
/** Whether keyboard auto-completion for editing commands is triggered when typing `/`. */
|
||||
textNoteSlashCommandsEnabled: boolean;
|
||||
backgroundEffects: boolean;
|
||||
newLayout: boolean;
|
||||
|
||||
// Share settings
|
||||
redirectBareDomain: boolean;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue