mirror of
https://github.com/zadam/trilium.git
synced 2025-10-20 15:19:01 +02:00
refactor(options/i18n): share locale selector with content language selector
This commit is contained in:
parent
5693b59318
commit
dd9d13b175
@ -5,7 +5,7 @@ import { FormDropdownDivider, FormListBadge, FormListItem } from "../react/FormL
|
|||||||
import { getAvailableLocales, t } from "../../services/i18n";
|
import { getAvailableLocales, t } from "../../services/i18n";
|
||||||
import { useNoteLabel, useNoteLabelBoolean, useNoteProperty, useTriliumEvent, useTriliumOption } from "../react/hooks";
|
import { useNoteLabel, useNoteLabelBoolean, useNoteProperty, useTriliumEvent, useTriliumOption } from "../react/hooks";
|
||||||
import mime_types from "../../services/mime_types";
|
import mime_types from "../../services/mime_types";
|
||||||
import { Locale, NoteType, ToggleInParentResponse } from "@triliumnext/commons";
|
import { Locale, LOCALES, NoteType, ToggleInParentResponse } from "@triliumnext/commons";
|
||||||
import server from "../../services/server";
|
import server from "../../services/server";
|
||||||
import dialog from "../../services/dialog";
|
import dialog from "../../services/dialog";
|
||||||
import FormToggle from "../react/FormToggle";
|
import FormToggle from "../react/FormToggle";
|
||||||
@ -20,6 +20,7 @@ import { TabContext } from "./ribbon-interface";
|
|||||||
import Modal from "../react/Modal";
|
import Modal from "../react/Modal";
|
||||||
import { CodeMimeTypesList } from "../type_widgets/options/code_notes";
|
import { CodeMimeTypesList } from "../type_widgets/options/code_notes";
|
||||||
import { ContentLanguagesList } from "../type_widgets/options/i18n";
|
import { ContentLanguagesList } from "../type_widgets/options/i18n";
|
||||||
|
import { LocaleSelector } from "../type_widgets/options/components/LocaleSelector";
|
||||||
|
|
||||||
export default function BasicPropertiesTab({ note }: TabContext) {
|
export default function BasicPropertiesTab({ note }: TabContext) {
|
||||||
return (
|
return (
|
||||||
@ -290,68 +291,30 @@ function NoteLanguageSwitch({ note }: { note?: FNote | null }) {
|
|||||||
id: "",
|
id: "",
|
||||||
name: t("note_language.not_set")
|
name: t("note_language.not_set")
|
||||||
};
|
};
|
||||||
|
|
||||||
const [ currentNoteLanguage, setCurrentNoteLanguage ] = useNoteLabel(note, "language");
|
const [ currentNoteLanguage, setCurrentNoteLanguage ] = useNoteLabel(note, "language");
|
||||||
const [ modalShown, setModalShown ] = useState(false);
|
const [ modalShown, setModalShown ] = useState(false);
|
||||||
|
|
||||||
const locales = useMemo(() => {
|
const locales = useMemo(() => {
|
||||||
const enabledLanguages = JSON.parse(languages ?? "[]") as string[];
|
const enabledLanguages = JSON.parse(languages ?? "[]") as string[];
|
||||||
const filteredLanguages = getAvailableLocales().filter((l) => typeof l !== "object" || enabledLanguages.includes(l.id));
|
const filteredLanguages = getAvailableLocales().filter((l) => typeof l !== "object" || enabledLanguages.includes(l.id));
|
||||||
const leftToRightLanguages = filteredLanguages.filter((l) => !l.rtl);
|
return filteredLanguages;
|
||||||
const rightToLeftLanguages = filteredLanguages.filter((l) => l.rtl);
|
|
||||||
|
|
||||||
let locales: ("---" | Locale)[] = [
|
|
||||||
DEFAULT_LOCALE
|
|
||||||
];
|
|
||||||
|
|
||||||
if (leftToRightLanguages.length > 0) {
|
|
||||||
locales = [
|
|
||||||
...locales,
|
|
||||||
"---",
|
|
||||||
...leftToRightLanguages
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rightToLeftLanguages.length > 0) {
|
|
||||||
locales = [
|
|
||||||
...locales,
|
|
||||||
"---",
|
|
||||||
...rightToLeftLanguages
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// This will separate the list of languages from the "Configure languages" button.
|
|
||||||
// If there is at least one language.
|
|
||||||
locales.push("---");
|
|
||||||
return locales;
|
|
||||||
}, [ languages ]);
|
}, [ languages ]);
|
||||||
|
|
||||||
const currentLocale = useMemo(() => {
|
|
||||||
return locales.find(locale => typeof locale === "object" && locale.id === currentNoteLanguage) as Locale | undefined;
|
|
||||||
}, [ currentNoteLanguage ]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="note-language-container">
|
<div className="note-language-container">
|
||||||
<span>{t("basic_properties.language")}:</span>
|
<span>{t("basic_properties.language")}:</span>
|
||||||
|
|
||||||
<Dropdown text={currentLocale?.name ?? DEFAULT_LOCALE.name}>
|
<LocaleSelector
|
||||||
{locales.map(locale => {
|
locales={locales}
|
||||||
if (typeof locale === "object") {
|
defaultLocale={DEFAULT_LOCALE}
|
||||||
const checked = locale.id === (currentNoteLanguage ?? "");
|
currentValue={currentNoteLanguage ?? ""} onChange={setCurrentNoteLanguage}
|
||||||
return <FormListItem
|
extraChildren={(
|
||||||
rtl={locale.rtl}
|
<FormListItem
|
||||||
checked={checked}
|
onClick={() => setModalShown(true)}
|
||||||
onClick={() => setCurrentNoteLanguage(locale.id || null)}
|
>{t("note_language.configure-languages")}</FormListItem>
|
||||||
>{locale.name}</FormListItem>
|
)}
|
||||||
} else {
|
>
|
||||||
return <FormDropdownDivider />
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
|
|
||||||
<FormListItem
|
</LocaleSelector>
|
||||||
onClick={() => setModalShown(true)}
|
|
||||||
>{t("note_language.configure-languages")}</FormListItem>
|
|
||||||
</Dropdown>
|
|
||||||
|
|
||||||
<HelpButton helpPage="B0lcI9xz1r8K" style={{ marginInlineStart: "4px" }} />
|
<HelpButton helpPage="B0lcI9xz1r8K" style={{ marginInlineStart: "4px" }} />
|
||||||
|
|
||||||
@ -364,7 +327,7 @@ function NoteLanguageSwitch({ note }: { note?: FNote | null }) {
|
|||||||
<ContentLanguagesList />
|
<ContentLanguagesList />
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function findTypeTitle(type?: NoteType, mime?: string | null) {
|
function findTypeTitle(type?: NoteType, mime?: string | null) {
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
import { Locale } from "@triliumnext/commons";
|
||||||
|
import Dropdown from "../../../react/Dropdown";
|
||||||
|
import { FormDropdownDivider, FormListItem } from "../../../react/FormList";
|
||||||
|
import { ComponentChildren } from "preact";
|
||||||
|
import { useMemo, useState } from "preact/hooks";
|
||||||
|
|
||||||
|
export function LocaleSelector({ id, locales, currentValue, onChange, defaultLocale, extraChildren }: {
|
||||||
|
id?: string;
|
||||||
|
locales: Locale[],
|
||||||
|
currentValue: string,
|
||||||
|
onChange: (newLocale: string) => void,
|
||||||
|
defaultLocale?: Locale,
|
||||||
|
extraChildren?: ComponentChildren
|
||||||
|
}) {
|
||||||
|
const [ activeLocale, setActiveLocale ] = useState(defaultLocale?.id === currentValue ? defaultLocale : locales.find(l => l.id === currentValue));
|
||||||
|
console.log("defaultLocale ", defaultLocale, currentValue, activeLocale)
|
||||||
|
|
||||||
|
const processedLocales = useMemo(() => {
|
||||||
|
const leftToRightLanguages = locales.filter((l) => !l.rtl);
|
||||||
|
const rightToLeftLanguages = locales.filter((l) => l.rtl);
|
||||||
|
|
||||||
|
let items: ("---" | Locale)[] = [];
|
||||||
|
if (defaultLocale) items.push(defaultLocale);
|
||||||
|
|
||||||
|
if (leftToRightLanguages.length > 0) {
|
||||||
|
if (items.length > 0) items.push("---");
|
||||||
|
items = [ ...items, ...leftToRightLanguages ];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rightToLeftLanguages.length > 0) {
|
||||||
|
items = [
|
||||||
|
...items,
|
||||||
|
"---",
|
||||||
|
...rightToLeftLanguages
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extraChildren) {
|
||||||
|
items.push("---");
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}, [ locales ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dropdown id={id} text={activeLocale?.name}>
|
||||||
|
{processedLocales.map(locale => {
|
||||||
|
if (typeof locale === "object") {
|
||||||
|
return <FormListItem
|
||||||
|
rtl={locale.rtl}
|
||||||
|
checked={locale.id === currentValue}
|
||||||
|
onClick={() => {
|
||||||
|
setActiveLocale(locale);
|
||||||
|
onChange(locale.id);
|
||||||
|
}}
|
||||||
|
>{locale.name}</FormListItem>
|
||||||
|
} else {
|
||||||
|
return <FormDropdownDivider />
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
{extraChildren}
|
||||||
|
</Dropdown>
|
||||||
|
)
|
||||||
|
}
|
@ -1,20 +1,18 @@
|
|||||||
import { useMemo, useState } from "preact/hooks";
|
import { useMemo } from "preact/hooks";
|
||||||
import { getAvailableLocales, t } from "../../../services/i18n";
|
import { getAvailableLocales, t } from "../../../services/i18n";
|
||||||
import FormSelect from "../../react/FormSelect";
|
import FormSelect from "../../react/FormSelect";
|
||||||
import OptionsRow from "./components/OptionsRow";
|
import OptionsRow from "./components/OptionsRow";
|
||||||
import OptionsSection from "./components/OptionsSection";
|
import OptionsSection from "./components/OptionsSection";
|
||||||
import { useTriliumOption, useTriliumOptionJson } from "../../react/hooks";
|
import { useTriliumOption, useTriliumOptionJson } from "../../react/hooks";
|
||||||
import type { Locale } from "@triliumnext/commons";
|
import type { Locale } from "@triliumnext/commons";
|
||||||
import { isElectron, restartDesktopApp } from "../../../services/utils";
|
import { restartDesktopApp } from "../../../services/utils";
|
||||||
import FormRadioGroup, { FormInlineRadioGroup } from "../../react/FormRadioGroup";
|
import FormRadioGroup from "../../react/FormRadioGroup";
|
||||||
import FormText from "../../react/FormText";
|
import FormText from "../../react/FormText";
|
||||||
import RawHtml from "../../react/RawHtml";
|
import RawHtml from "../../react/RawHtml";
|
||||||
import Admonition from "../../react/Admonition";
|
import Admonition from "../../react/Admonition";
|
||||||
import Button from "../../react/Button";
|
import Button from "../../react/Button";
|
||||||
import CheckboxList from "./components/CheckboxList";
|
import CheckboxList from "./components/CheckboxList";
|
||||||
import FormDropdownList from "../../react/FormDropdownList";
|
import { LocaleSelector } from "./components/LocaleSelector";
|
||||||
import Dropdown from "../../react/Dropdown";
|
|
||||||
import { FormListItem } from "../../react/FormList";
|
|
||||||
|
|
||||||
export default function InternationalizationOptions() {
|
export default function InternationalizationOptions() {
|
||||||
return (
|
return (
|
||||||
@ -35,7 +33,6 @@ function LocalizationOptions() {
|
|||||||
return true;
|
return true;
|
||||||
}),
|
}),
|
||||||
formattingLocales: [
|
formattingLocales: [
|
||||||
{ id: "", name: t("i18n.formatting-locale-auto") },
|
|
||||||
...allLocales.filter(locale => locale.electronLocale)
|
...allLocales.filter(locale => locale.electronLocale)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -51,7 +48,7 @@ function LocalizationOptions() {
|
|||||||
</OptionsRow>
|
</OptionsRow>
|
||||||
|
|
||||||
{<OptionsRow name="formatting-locale" label={t("i18n.formatting-locale")}>
|
{<OptionsRow name="formatting-locale" label={t("i18n.formatting-locale")}>
|
||||||
<LocaleSelector locales={contentLocales} currentValue={formattingLocale} onChange={setFormattingLocale} />
|
<LocaleSelector locales={contentLocales} currentValue={formattingLocale} onChange={setFormattingLocale} defaultLocale={{ id: "", name: t("i18n.formatting-locale-auto") }} />
|
||||||
</OptionsRow>}
|
</OptionsRow>}
|
||||||
|
|
||||||
<DateSettings />
|
<DateSettings />
|
||||||
@ -59,23 +56,6 @@ function LocalizationOptions() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function LocaleSelector({ id, locales, currentValue, onChange }: { id?: string; locales: Locale[], currentValue: string, onChange: (newLocale: string) => void }) {
|
|
||||||
const [ activeLocale, setActiveLocale ] = useState(locales.find(l => l.id === currentValue));
|
|
||||||
return (
|
|
||||||
<Dropdown id={id} text={activeLocale?.name}>
|
|
||||||
{locales.map(locale => (
|
|
||||||
<FormListItem
|
|
||||||
checked={locale === activeLocale }
|
|
||||||
onClick={() => {
|
|
||||||
setActiveLocale(locale);
|
|
||||||
onChange(locale.id);
|
|
||||||
}}
|
|
||||||
>{locale.name}</FormListItem>
|
|
||||||
))}
|
|
||||||
</Dropdown>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function DateSettings() {
|
function DateSettings() {
|
||||||
const [ firstDayOfWeek, setFirstDayOfWeek ] = useTriliumOption("firstDayOfWeek");
|
const [ firstDayOfWeek, setFirstDayOfWeek ] = useTriliumOption("firstDayOfWeek");
|
||||||
const [ firstWeekOfYear, setFirstWeekOfYear ] = useTriliumOption("firstWeekOfYear");
|
const [ firstWeekOfYear, setFirstWeekOfYear ] = useTriliumOption("firstWeekOfYear");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user