mirror of
https://github.com/zadam/trilium.git
synced 2026-05-07 09:15:49 +02:00
feat(options/appearance): display icon for custom themes
This commit is contained in:
@@ -16,7 +16,7 @@ import FormCheckbox from "../../react/FormCheckbox";
|
||||
import FormGroup from "../../react/FormGroup";
|
||||
import FormList, { FormListHeader, FormListItem } from "../../react/FormList";
|
||||
import { FormTextBoxWithUnit } from "../../react/FormTextBox";
|
||||
import { useTriliumOption, useTriliumOptionBool } from "../../react/hooks";
|
||||
import { useNote, useNoteIcon, useTriliumOption, useTriliumOptionBool } from "../../react/hooks";
|
||||
import Icon from "../../react/Icon";
|
||||
import Modal from "../../react/Modal";
|
||||
import Slider from "../../react/Slider";
|
||||
@@ -47,6 +47,51 @@ const LEGACY_THEMES: Theme[] = [
|
||||
{ val: "dark", title: t("theme.dark_theme"), icon: "bx bx-moon" }
|
||||
];
|
||||
|
||||
interface CustomThemeItemProps {
|
||||
theme: Theme;
|
||||
selected: boolean;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
function CustomThemeItem({ theme, selected, onClick }: CustomThemeItemProps) {
|
||||
const note = useNote(theme.noteId);
|
||||
const noteIcon = useNoteIcon(note);
|
||||
const icon = noteIcon ?? "bx bx-palette";
|
||||
|
||||
return (
|
||||
<FormListItem
|
||||
key={theme.val}
|
||||
icon={icon}
|
||||
selected={selected}
|
||||
onClick={onClick}
|
||||
>
|
||||
{theme.title}
|
||||
</FormListItem>
|
||||
);
|
||||
}
|
||||
|
||||
interface CurrentThemeDisplayProps {
|
||||
theme: Theme | undefined;
|
||||
fallbackLabel: string;
|
||||
}
|
||||
|
||||
function CurrentThemeDisplay({ theme, fallbackLabel }: CurrentThemeDisplayProps) {
|
||||
const note = useNote(theme?.noteId);
|
||||
const noteIcon = useNoteIcon(note);
|
||||
|
||||
// For built-in themes, use the icon from the theme object
|
||||
// For custom themes, use the note icon or fallback to palette
|
||||
const icon = theme?.icon ?? noteIcon ?? "bx bx-palette";
|
||||
const label = theme?.title ?? fallbackLabel;
|
||||
|
||||
return (
|
||||
<>
|
||||
<span className={icon} style={{ marginRight: "8px" }} />
|
||||
{label}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
interface FontFamilyEntry {
|
||||
value: FontFamily;
|
||||
label?: string;
|
||||
@@ -125,25 +170,19 @@ function UserInterface() {
|
||||
|
||||
useEffect(() => {
|
||||
server.get<Theme[]>("options/user-themes").then((userThemes) => {
|
||||
// Add placeholder icon for custom themes
|
||||
setCustomThemes(userThemes.map(t => ({ ...t, icon: "bx bx-palette" })));
|
||||
setCustomThemes(userThemes);
|
||||
});
|
||||
}, []);
|
||||
|
||||
// Find current theme for display
|
||||
const allThemes = [...MODERN_THEMES, ...LEGACY_THEMES, ...customThemes];
|
||||
const currentTheme = allThemes.find(t => t.val === theme);
|
||||
const currentThemeLabel = currentTheme?.title ?? theme ?? "";
|
||||
const currentThemeIcon = currentTheme?.icon ?? "bx bx-palette";
|
||||
|
||||
return (
|
||||
<OptionsSection title={t("theme.title")}>
|
||||
<OptionsRow name="theme" label={t("theme.theme_label")}>
|
||||
<Dropdown
|
||||
text={<>
|
||||
<span className={currentThemeIcon} style={{ marginRight: "8px" }} />
|
||||
{currentThemeLabel}
|
||||
</>}
|
||||
text={<CurrentThemeDisplay theme={currentTheme} fallbackLabel={theme ?? ""} />}
|
||||
>
|
||||
<FormListHeader text={t("theme.modern_themes")} />
|
||||
{MODERN_THEMES.map(t => (
|
||||
@@ -170,15 +209,13 @@ function UserInterface() {
|
||||
{customThemes.length > 0 && (
|
||||
<>
|
||||
<FormListHeader text={t("theme.custom_themes")} />
|
||||
{customThemes.map(t => (
|
||||
<FormListItem
|
||||
key={t.val}
|
||||
icon={t.icon}
|
||||
selected={theme === t.val}
|
||||
onClick={() => setTheme(t.val)}
|
||||
>
|
||||
{t.title}
|
||||
</FormListItem>
|
||||
{customThemes.map(ct => (
|
||||
<CustomThemeItem
|
||||
key={ct.val}
|
||||
theme={ct}
|
||||
selected={theme === ct.val}
|
||||
onClick={() => setTheme(ct.val)}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user