mirror of
https://github.com/zadam/trilium.git
synced 2025-11-02 11:26:15 +01:00
feat(react/ribbon): port note language
This commit is contained in:
@@ -38,11 +38,6 @@ const TPL = /*html*/`\
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const DEFAULT_LOCALE: Locale = {
|
|
||||||
id: "",
|
|
||||||
name: t("note_language.not_set")
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class NoteLanguageWidget extends NoteContextAwareWidget {
|
export default class NoteLanguageWidget extends NoteContextAwareWidget {
|
||||||
|
|
||||||
private dropdown!: Dropdown;
|
private dropdown!: Dropdown;
|
||||||
@@ -59,7 +54,6 @@ export default class NoteLanguageWidget extends NoteContextAwareWidget {
|
|||||||
doRender() {
|
doRender() {
|
||||||
this.$widget = $(TPL);
|
this.$widget = $(TPL);
|
||||||
this.dropdown = Dropdown.getOrCreateInstance(this.$widget.find("[data-bs-toggle='dropdown']")[0]);
|
this.dropdown = Dropdown.getOrCreateInstance(this.$widget.find("[data-bs-toggle='dropdown']")[0]);
|
||||||
this.$widget.on("show.bs.dropdown", () => this.renderDropdown());
|
|
||||||
|
|
||||||
this.$noteLanguageDropdown = this.$widget.find(".note-language-dropdown")
|
this.$noteLanguageDropdown = this.$widget.find(".note-language-dropdown")
|
||||||
this.$noteLanguageDesc = this.$widget.find(".note-language-desc");
|
this.$noteLanguageDesc = this.$widget.find(".note-language-desc");
|
||||||
@@ -72,36 +66,8 @@ export default class NoteLanguageWidget extends NoteContextAwareWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const locale of this.locales) {
|
|
||||||
if (typeof locale === "object") {
|
|
||||||
const $title = $("<span>").text(locale.name);
|
|
||||||
|
|
||||||
const $link = $('<a class="dropdown-item">')
|
|
||||||
.attr("data-language", locale.id)
|
|
||||||
.append('<span class="check">✓</span> ')
|
|
||||||
.append($title)
|
|
||||||
.on("click", () => {
|
|
||||||
const languageId = $link.attr("data-language") ?? "";
|
|
||||||
this.save(languageId);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (locale.rtl) {
|
|
||||||
$link.attr("dir", "rtl");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (locale.id === this.currentLanguageId) {
|
|
||||||
$link.addClass("selected");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$noteLanguageDropdown.append($link);
|
|
||||||
} else {
|
|
||||||
this.$noteLanguageDropdown.append('<div class="dropdown-divider"></div>');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const $configureLink = $('<a class="dropdown-item">')
|
const $configureLink = $('<a class="dropdown-item">')
|
||||||
.append(`<span>${t("note_language.configure-languages")}</span>`)
|
.on("click", () => ));
|
||||||
.on("click", () => appContext.tabManager.openContextWithNote("_optionsLocalization", { activate: true }));
|
|
||||||
this.$noteLanguageDropdown.append($configureLink);
|
this.$noteLanguageDropdown.append($configureLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +80,6 @@ export default class NoteLanguageWidget extends NoteContextAwareWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async refreshWithNote(note: FNote) {
|
async refreshWithNote(note: FNote) {
|
||||||
const currentLanguageId = note.getLabelValue("language") ?? "";
|
|
||||||
const language = getLocaleById(currentLanguageId) ?? DEFAULT_LOCALE;
|
const language = getLocaleById(currentLanguageId) ?? DEFAULT_LOCALE;
|
||||||
this.currentLanguageId = currentLanguageId;
|
this.currentLanguageId = currentLanguageId;
|
||||||
this.$noteLanguageDesc.text(language.name);
|
this.$noteLanguageDesc.text(language.name);
|
||||||
@@ -132,35 +97,7 @@ export default class NoteLanguageWidget extends NoteContextAwareWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static #buildLocales() {
|
static #buildLocales() {
|
||||||
const enabledLanguages = JSON.parse(options.get("languages") ?? "[]") as string[];
|
|
||||||
const filteredLanguages = getAvailableLocales().filter((l) => typeof l !== "object" || enabledLanguages.includes(l.id));
|
|
||||||
const leftToRightLanguages = filteredLanguages.filter((l) => !l.rtl);
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,9 +82,10 @@ interface FormListItemOpts {
|
|||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
description?: string;
|
description?: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
rtl?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FormListItem({ children, icon, value, title, active, badges, disabled, checked, onClick, description, selected }: FormListItemOpts) {
|
export function FormListItem({ children, icon, value, title, active, badges, disabled, checked, onClick, description, selected, rtl }: FormListItemOpts) {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
icon = "bx bx-check";
|
icon = "bx bx-check";
|
||||||
}
|
}
|
||||||
@@ -95,6 +96,7 @@ export function FormListItem({ children, icon, value, title, active, badges, dis
|
|||||||
data-value={value} title={title}
|
data-value={value} title={title}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
dir={rtl ? "rtl" : undefined}
|
||||||
>
|
>
|
||||||
<Icon icon={icon} />
|
<Icon icon={icon} />
|
||||||
<div>
|
<div>
|
||||||
@@ -120,6 +122,6 @@ export function FormListHeader({ text }: FormListHeaderOpts) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FormDivider() {
|
export function FormDropdownDivider() {
|
||||||
return <div className="dropdown-divider" />;
|
return <div className="dropdown-divider" />;
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { useCallback, useEffect, useMemo, useState } from "preact/hooks";
|
import { useCallback, useEffect, useMemo, useState } from "preact/hooks";
|
||||||
import Dropdown from "../react/Dropdown";
|
import Dropdown from "../react/Dropdown";
|
||||||
import { NOTE_TYPES } from "../../services/note_types";
|
import { NOTE_TYPES } from "../../services/note_types";
|
||||||
import { FormDivider, FormListBadge, FormListItem } from "../react/FormList";
|
import { FormDropdownDivider, FormListBadge, FormListItem } from "../react/FormList";
|
||||||
import { t } from "../../services/i18n";
|
import { getAvailableLocales, t } from "../../services/i18n";
|
||||||
import { useNoteContext, useNoteLabel, useNoteLabelBoolean, useNoteProperty, useTriliumEventBeta, useTriliumOption } from "../react/hooks";
|
import { useNoteContext, useNoteLabel, useNoteLabelBoolean, useNoteProperty, useTriliumEventBeta, useTriliumOption, useTriliumOptionJson } from "../react/hooks";
|
||||||
import mime_types from "../../services/mime_types";
|
import mime_types from "../../services/mime_types";
|
||||||
import { NoteType, ToggleInParentResponse } from "@triliumnext/commons";
|
import { Locale, 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";
|
||||||
@@ -15,7 +15,7 @@ import FormDropdownList from "../react/FormDropdownList";
|
|||||||
import toast from "../../services/toast";
|
import toast from "../../services/toast";
|
||||||
import branches from "../../services/branches";
|
import branches from "../../services/branches";
|
||||||
import sync from "../../services/sync";
|
import sync from "../../services/sync";
|
||||||
import TemplateSwitchWidget from "../template_switch";
|
import appContext from "../../components/app_context";
|
||||||
|
|
||||||
export default function BasicPropertiesTab() {
|
export default function BasicPropertiesTab() {
|
||||||
const { note } = useNoteContext();
|
const { note } = useNoteContext();
|
||||||
@@ -28,6 +28,7 @@ export default function BasicPropertiesTab() {
|
|||||||
<BookmarkSwitch note={note} />
|
<BookmarkSwitch note={note} />
|
||||||
<SharedSwitch note={note} />
|
<SharedSwitch note={note} />
|
||||||
<TemplateSwitch note={note} />
|
<TemplateSwitch note={note} />
|
||||||
|
<NoteLanguageSwitch note={note} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -93,7 +94,7 @@ function NoteTypeWidget({ note }: { note?: FNote | null }) {
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FormDivider />
|
<FormDropdownDivider />
|
||||||
<FormListItem
|
<FormListItem
|
||||||
checked={checked}
|
checked={checked}
|
||||||
disabled
|
disabled
|
||||||
@@ -265,6 +266,70 @@ function SharedSwitch({ note }: { note?: FNote | null }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function NoteLanguageSwitch({ note }: { note?: FNote | null }) {
|
||||||
|
const [ languages ] = useTriliumOption("languages");
|
||||||
|
const DEFAULT_LOCALE = {
|
||||||
|
id: "",
|
||||||
|
name: t("note_language.not_set")
|
||||||
|
};
|
||||||
|
|
||||||
|
const [ currentNoteLanguage, setCurrentNoteLanguage ] = useNoteLabel(note, "language") ?? "";
|
||||||
|
|
||||||
|
const locales = useMemo(() => {
|
||||||
|
const enabledLanguages = JSON.parse(languages ?? "[]") as string[];
|
||||||
|
const filteredLanguages = getAvailableLocales().filter((l) => typeof l !== "object" || enabledLanguages.includes(l.id));
|
||||||
|
const leftToRightLanguages = filteredLanguages.filter((l) => !l.rtl);
|
||||||
|
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 ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="note-language-container">
|
||||||
|
<Dropdown>
|
||||||
|
{locales.map(locale => {
|
||||||
|
if (typeof locale === "object") {
|
||||||
|
return <FormListItem
|
||||||
|
rtl={locale.rtl}
|
||||||
|
selected={locale.id === currentNoteLanguage}
|
||||||
|
onClick={() => setCurrentNoteLanguage(locale.id)}
|
||||||
|
>{locale.name}</FormListItem>
|
||||||
|
} else {
|
||||||
|
return <FormDropdownDivider />
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
|
||||||
|
<FormListItem
|
||||||
|
onClick={() => appContext.tabManager.openContextWithNote("_optionsLocalization", { activate: true })}
|
||||||
|
>{t("note_language.configure-languages")}</FormListItem>
|
||||||
|
</Dropdown>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
function findTypeTitle(type?: NoteType, mime?: string | null) {
|
function findTypeTitle(type?: NoteType, mime?: string | null) {
|
||||||
if (type === "code") {
|
if (type === "code") {
|
||||||
const mimeTypes = mime_types.getMimeTypes();
|
const mimeTypes = mime_types.getMimeTypes();
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export default class BasicPropertiesWidget extends NoteContextAwareWidget {
|
|||||||
this.$widget.find(".bookmark-switch-container").append(this.bookmarkSwitchWidget.render());
|
this.$widget.find(".bookmark-switch-container").append(this.bookmarkSwitchWidget.render());
|
||||||
this.$widget.find(".shared-switch-container").append(this.sharedSwitchWidget.render());
|
this.$widget.find(".shared-switch-container").append(this.sharedSwitchWidget.render());
|
||||||
this.$widget.find(".template-switch-container").append(this.templateSwitchWidget.render());
|
this.$widget.find(".template-switch-container").append(this.templateSwitchWidget.render());
|
||||||
this.$widget.find(".note-language-container").append(this.noteLanguageWidget.render());
|
this.$widget.find(".").append(this.noteLanguageWidget.render());
|
||||||
}
|
}
|
||||||
|
|
||||||
async refreshWithNote(note: FNote) {
|
async refreshWithNote(note: FNote) {
|
||||||
|
|||||||
Reference in New Issue
Block a user