mirror of
https://github.com/zadam/trilium.git
synced 2025-12-15 12:49:53 +01:00
refactor(status_bar/language): stop reusing UI for greater customisibility
This commit is contained in:
@@ -3,10 +3,15 @@ import "./StatusBar.css";
|
|||||||
import FNote from "../../entities/fnote";
|
import FNote from "../../entities/fnote";
|
||||||
import { t } from "../../services/i18n";
|
import { t } from "../../services/i18n";
|
||||||
import { openInAppHelpFromUrl } from "../../services/utils";
|
import { openInAppHelpFromUrl } from "../../services/utils";
|
||||||
import { FormListItem } from "../react/FormList";
|
import { FormDropdownDivider, FormListItem } from "../react/FormList";
|
||||||
import { useNoteContext } from "../react/hooks";
|
import { useNoteContext } from "../react/hooks";
|
||||||
import { NoteLanguageSelector } from "../ribbon/BasicPropertiesTab";
|
import { ContentLanguagesModal, NoteLanguageSelector, useLanguageSwitcher } from "../ribbon/BasicPropertiesTab";
|
||||||
import Breadcrumb from "./Breadcrumb";
|
import Breadcrumb from "./Breadcrumb";
|
||||||
|
import { useState } from "preact/hooks";
|
||||||
|
import { createPortal } from "preact/compat";
|
||||||
|
import { useProcessedLocales } from "../type_widgets/options/components/LocaleSelector";
|
||||||
|
import Dropdown from "../react/Dropdown";
|
||||||
|
import { Locale } from "@triliumnext/commons";
|
||||||
|
|
||||||
interface StatusBarContext {
|
interface StatusBarContext {
|
||||||
note: FNote;
|
note: FNote;
|
||||||
@@ -32,16 +37,44 @@ export default function StatusBar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function LanguageSwitcher({ note }: StatusBarContext) {
|
function LanguageSwitcher({ note }: StatusBarContext) {
|
||||||
|
const [ modalShown, setModalShown ] = useState(false);
|
||||||
|
const { locales, DEFAULT_LOCALE, currentNoteLanguage, setCurrentNoteLanguage } = useLanguageSwitcher(note);
|
||||||
|
const { activeLocale, processedLocales } = useProcessedLocales(locales, DEFAULT_LOCALE, currentNoteLanguage ?? DEFAULT_LOCALE.id);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NoteLanguageSelector
|
<>
|
||||||
note={note}
|
<Dropdown text={getLocaleName(activeLocale)}>
|
||||||
extraChildren={(
|
{processedLocales.map(locale => {
|
||||||
|
if (typeof locale === "object") {
|
||||||
|
return <FormListItem
|
||||||
|
rtl={locale.rtl}
|
||||||
|
checked={locale.id === currentNoteLanguage}
|
||||||
|
onClick={() => setCurrentNoteLanguage(locale.id)}
|
||||||
|
>{locale.name}</FormListItem>
|
||||||
|
} else {
|
||||||
|
return <FormDropdownDivider />
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
<FormDropdownDivider />
|
||||||
<FormListItem
|
<FormListItem
|
||||||
onClick={() => openInAppHelpFromUrl("veGu4faJErEM")}
|
onClick={() => openInAppHelpFromUrl("veGu4faJErEM")}
|
||||||
icon="bx bx-help-circle"
|
icon="bx bx-help-circle"
|
||||||
>{t("note_language.help-on-languages")}</FormListItem>
|
>{t("note_language.help-on-languages")}</FormListItem>
|
||||||
|
<FormListItem
|
||||||
|
onClick={() => setModalShown(true)}
|
||||||
|
icon="bx bx-cog"
|
||||||
|
>{t("note_language.configure-languages")}</FormListItem>
|
||||||
|
</Dropdown>
|
||||||
|
{createPortal(
|
||||||
|
<ContentLanguagesModal modalShown={modalShown} setModalShown={setModalShown} />,
|
||||||
|
document.body
|
||||||
)}
|
)}
|
||||||
compact
|
</>
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getLocaleName(locale: Locale | null | undefined) {
|
||||||
|
if (!locale) return "";
|
||||||
|
if (!locale.id) return "-";
|
||||||
|
return locale.id.toLocaleUpperCase();
|
||||||
|
}
|
||||||
|
|||||||
@@ -330,12 +330,32 @@ function NoteLanguageSwitch({ note }: { note?: FNote | null }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NoteLanguageSelector({ note, extraChildren, ...restProps }: {
|
export function NoteLanguageSelector({ note }: { note: FNote | null | undefined }) {
|
||||||
note: FNote | null | undefined,
|
|
||||||
extraChildren?: ComponentChildren,
|
|
||||||
compact?: boolean;
|
|
||||||
}) {
|
|
||||||
const [ modalShown, setModalShown ] = useState(false);
|
const [ modalShown, setModalShown ] = useState(false);
|
||||||
|
const { locales, DEFAULT_LOCALE, currentNoteLanguage, setCurrentNoteLanguage } = useLanguageSwitcher(note);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<LocaleSelector
|
||||||
|
locales={locales}
|
||||||
|
defaultLocale={DEFAULT_LOCALE}
|
||||||
|
currentValue={currentNoteLanguage} onChange={setCurrentNoteLanguage}
|
||||||
|
extraChildren={<>
|
||||||
|
<FormListItem
|
||||||
|
onClick={() => setModalShown(true)}
|
||||||
|
icon="bx bx-cog"
|
||||||
|
>{t("note_language.configure-languages")}</FormListItem>
|
||||||
|
</>}
|
||||||
|
/>
|
||||||
|
{createPortal(
|
||||||
|
<ContentLanguagesModal modalShown={modalShown} setModalShown={setModalShown} />,
|
||||||
|
document.body
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useLanguageSwitcher(note: FNote | null | undefined) {
|
||||||
const [ languages ] = useTriliumOption("languages");
|
const [ languages ] = useTriliumOption("languages");
|
||||||
const DEFAULT_LOCALE = {
|
const DEFAULT_LOCALE = {
|
||||||
id: "",
|
id: "",
|
||||||
@@ -347,31 +367,10 @@ export function NoteLanguageSelector({ note, extraChildren, ...restProps }: {
|
|||||||
const filteredLanguages = getAvailableLocales().filter((l) => typeof l !== "object" || enabledLanguages.includes(l.id));
|
const filteredLanguages = getAvailableLocales().filter((l) => typeof l !== "object" || enabledLanguages.includes(l.id));
|
||||||
return filteredLanguages;
|
return filteredLanguages;
|
||||||
}, [ languages ]);
|
}, [ languages ]);
|
||||||
|
return { locales, DEFAULT_LOCALE, currentNoteLanguage, setCurrentNoteLanguage };
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<LocaleSelector
|
|
||||||
locales={locales}
|
|
||||||
defaultLocale={DEFAULT_LOCALE}
|
|
||||||
currentValue={currentNoteLanguage ?? ""} onChange={setCurrentNoteLanguage}
|
|
||||||
extraChildren={<>
|
|
||||||
{extraChildren}
|
|
||||||
<FormListItem
|
|
||||||
onClick={() => setModalShown(true)}
|
|
||||||
icon="bx bx-cog"
|
|
||||||
>{t("note_language.configure-languages")}</FormListItem>
|
|
||||||
</>}
|
|
||||||
{...restProps}
|
|
||||||
/>
|
|
||||||
{createPortal(
|
|
||||||
<ContentLanguagesModal modalShown={modalShown} setModalShown={setModalShown} />,
|
|
||||||
document.body
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function ContentLanguagesModal({ modalShown, setModalShown }: { modalShown: boolean, setModalShown: (shown: boolean) => void }) {
|
export function ContentLanguagesModal({ modalShown, setModalShown }: { modalShown: boolean, setModalShown: (shown: boolean) => void }) {
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
className="content-languages-modal"
|
className="content-languages-modal"
|
||||||
|
|||||||
@@ -5,15 +5,42 @@ import { useMemo } from "preact/hooks";
|
|||||||
import Dropdown from "../../../react/Dropdown";
|
import Dropdown from "../../../react/Dropdown";
|
||||||
import { FormDropdownDivider, FormListItem } from "../../../react/FormList";
|
import { FormDropdownDivider, FormListItem } from "../../../react/FormList";
|
||||||
|
|
||||||
export function LocaleSelector({ id, locales, currentValue, onChange, defaultLocale, extraChildren, compact }: {
|
export function LocaleSelector({ id, locales, currentValue, onChange, defaultLocale, extraChildren }: {
|
||||||
id?: string;
|
id?: string;
|
||||||
locales: Locale[],
|
locales: Locale[],
|
||||||
currentValue: string,
|
currentValue: string | null | undefined,
|
||||||
onChange: (newLocale: string) => void,
|
onChange: (newLocale: string) => void,
|
||||||
defaultLocale?: Locale,
|
defaultLocale?: Locale,
|
||||||
extraChildren?: ComponentChildren,
|
extraChildren?: ComponentChildren,
|
||||||
compact?: boolean;
|
|
||||||
}) {
|
}) {
|
||||||
|
const currentValueWithDefault = currentValue ?? defaultLocale?.id ?? "";
|
||||||
|
const { activeLocale, processedLocales } = useProcessedLocales(locales, defaultLocale, currentValueWithDefault);
|
||||||
|
return (
|
||||||
|
<Dropdown id={id} text={activeLocale?.name}>
|
||||||
|
{processedLocales.map(locale => {
|
||||||
|
if (typeof locale === "object") {
|
||||||
|
return <FormListItem
|
||||||
|
rtl={locale.rtl}
|
||||||
|
checked={locale.id === currentValue}
|
||||||
|
onClick={() => {
|
||||||
|
onChange(locale.id);
|
||||||
|
}}
|
||||||
|
>{locale.name}</FormListItem>
|
||||||
|
} else {
|
||||||
|
return <FormDropdownDivider />
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
{extraChildren && (
|
||||||
|
<>
|
||||||
|
<FormDropdownDivider />
|
||||||
|
{extraChildren}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Dropdown>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useProcessedLocales(locales: Locale[], defaultLocale: Locale | undefined, currentValue: string) {
|
||||||
const activeLocale = defaultLocale?.id === currentValue ? defaultLocale : locales.find(l => l.id === currentValue);
|
const activeLocale = defaultLocale?.id === currentValue ? defaultLocale : locales.find(l => l.id === currentValue);
|
||||||
|
|
||||||
const processedLocales = useMemo(() => {
|
const processedLocales = useMemo(() => {
|
||||||
@@ -36,35 +63,8 @@ export function LocaleSelector({ id, locales, currentValue, onChange, defaultLoc
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extraChildren) {
|
|
||||||
items.push("---");
|
|
||||||
}
|
|
||||||
return items;
|
return items;
|
||||||
}, [ locales ]);
|
}, [ locales, defaultLocale ]);
|
||||||
|
|
||||||
return (
|
return { activeLocale, processedLocales };
|
||||||
<Dropdown id={id} text={getLocaleName(activeLocale, compact)}>
|
|
||||||
{processedLocales.map(locale => {
|
|
||||||
if (typeof locale === "object") {
|
|
||||||
return <FormListItem
|
|
||||||
rtl={locale.rtl}
|
|
||||||
checked={locale.id === currentValue}
|
|
||||||
onClick={() => {
|
|
||||||
onChange(locale.id);
|
|
||||||
}}
|
|
||||||
>{locale.name}</FormListItem>
|
|
||||||
} else {
|
|
||||||
return <FormDropdownDivider />
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
{extraChildren}
|
|
||||||
</Dropdown>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLocaleName(locale: Locale | null | undefined, compact: boolean | undefined) {
|
|
||||||
if (!locale) return "";
|
|
||||||
if (!compact) return locale.name;
|
|
||||||
if (!locale.id) return "-";
|
|
||||||
return locale.id.toLocaleUpperCase();
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user