Compare commits

..

No commits in common. "28b263a44537e87faf9ccc0964d6fc1424953497" and "9682df62407f0ae244549e619ca4b59d0fd0f27b" have entirely different histories.

86 changed files with 2010 additions and 1620 deletions

View File

@ -45,19 +45,6 @@ jobs:
image: win-signing
shell: cmd
forge_platform: win32
# Exclude ARM64 Linux from default matrix to use native runner
exclude:
- arch: arm64
os:
name: linux
# Add ARM64 Linux with native ubuntu-24.04-arm runner for better-sqlite3 compatibility
include:
- arch: arm64
os:
name: linux
image: ubuntu-24.04-arm
shell: bash
forge_platform: linux
runs-on: ${{ matrix.os.image }}
steps:
- uses: actions/checkout@v6

View File

@ -79,7 +79,7 @@ jobs:
if: failure()
uses: actions/upload-artifact@v5
with:
name: e2e report ${{ matrix.arch }}
name: e2e report
path: apps/server-e2e/test-output
- name: Kill the server

View File

@ -16,7 +16,7 @@
"fs-extra": "11.3.2",
"react": "19.2.0",
"react-dom": "19.2.0",
"typedoc": "0.28.15",
"typedoc": "0.28.14",
"typedoc-plugin-missing-exports": "4.1.2"
}
}

View File

@ -1,21 +0,0 @@
import { t } from "../services/i18n"
import attributes from "../services/attributes"
import FNote from "../entities/fnote"
export function getArchiveMenuItem(note: FNote) {
if (!note.isArchived) {
return {
title: t("board_view.archive-note"),
uiIcon: "bx bx-archive",
handler: () => attributes.addLabel(note.noteId, "archived")
}
} else {
return {
title: t("board_view.unarchive-note"),
uiIcon: "bx bx-archive-out",
handler: async () => {
attributes.removeOwnedLabelByName(note, "archived")
}
}
}
}

View File

@ -2,25 +2,22 @@ import { t } from "../services/i18n.js";
import contextMenu, { type ContextMenuEvent, type MenuItem } from "./context_menu.js";
import appContext, { type CommandNames } from "../components/app_context.js";
import type { ViewScope } from "../services/link.js";
import utils, { isMobile } from "../services/utils.js";
import utils from "../services/utils.js";
import { getClosestNtxId } from "../widgets/widget_utils.js";
function openContextMenu(notePath: string, e: ContextMenuEvent, viewScope: ViewScope = {}, hoistedNoteId: string | null = null) {
contextMenu.show({
x: e.pageX,
y: e.pageY,
items: getItems(e),
items: getItems(),
selectMenuItemHandler: ({ command }) => handleLinkContextMenuItem(command, e, notePath, viewScope, hoistedNoteId)
});
}
function getItems(e: ContextMenuEvent): MenuItem<CommandNames>[] {
const ntxId = getNtxId(e);
const isMobileSplitOpen = isMobile() && appContext.tabManager.getNoteContextById(ntxId).getMainContext().getSubContexts().length > 1;
function getItems(): MenuItem<CommandNames>[] {
return [
{ title: t("link_context_menu.open_note_in_new_tab"), command: "openNoteInNewTab", uiIcon: "bx bx-link-external" },
{ title: !isMobileSplitOpen ? t("link_context_menu.open_note_in_new_split") : t("link_context_menu.open_note_in_other_split"), command: "openNoteInNewSplit", uiIcon: "bx bx-dock-right" },
{ title: t("link_context_menu.open_note_in_new_split"), command: "openNoteInNewSplit", uiIcon: "bx bx-dock-right" },
{ title: t("link_context_menu.open_note_in_new_window"), command: "openNoteInNewWindow", uiIcon: "bx bx-window-open" },
{ title: t("link_context_menu.open_note_in_popup"), command: "openNoteInPopup", uiIcon: "bx bx-edit" }
];
@ -49,10 +46,8 @@ function getNtxId(e: ContextMenuEvent) {
const subContexts = appContext.tabManager.getActiveContext()?.getSubContexts();
if (!subContexts) return null;
return subContexts[subContexts.length - 1].ntxId;
} else if (e.target instanceof HTMLElement) {
return getClosestNtxId(e.target);
} else {
return null;
return getClosestNtxId(e.target);
}
}

View File

@ -39,12 +39,12 @@ function createClassForColor(colorString: string | null) {
</style>`);
registeredClasses.add(className);
if (hue !== undefined) {
if (hue) {
colorsWithHue.add(className);
}
}
return clsx("use-note-color", className, colorsWithHue.has(className) && "with-hue");
return clsx(className, colorsWithHue.has(className) && "with-hue");
}
function parseColor(color: string) {

View File

@ -207,7 +207,7 @@ function toObject<T, R>(array: T[], fn: (arg0: T) => [key: string, value: R]) {
return obj;
}
export function randomString(len: number) {
function randomString(len: number) {
let text = "";
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

View File

@ -27,9 +27,6 @@
--bs-body-bg: var(--main-background-color) !important;
--ck-mention-list-max-height: 500px;
--tn-modal-max-height: 90vh;
--tree-item-light-theme-max-color-lightness: 50;
--tree-item-dark-theme-min-color-lightness: 75;
}
body#trilium-app.motion-disabled *,
@ -257,11 +254,6 @@ button.close:hover {
color: var(--hover-item-text-color);
}
button.custom-title-bar-button {
background: transparent;
border: unset;
}
.modal-content {
background-color: var(--modal-background-color) !important;
}
@ -600,6 +592,11 @@ button.btn-sm {
color: var(--left-pane-text-color);
}
.btn.active:not(.btn-primary) {
background-color: var(--button-disabled-background-color) !important;
opacity: 0.4;
}
.ck.ck-block-toolbar-button {
transform: translateX(7px);
color: var(--muted-text-color);
@ -1694,6 +1691,46 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
body.mobile .modal-dialog.modal-dialog-scrollable {
height: unset;
}
body.mobile .revisions-dialog .modal-dialog {
height: 95vh;
}
body.mobile .revisions-dialog .modal-body {
height: 100% !important;
flex-direction: column;
padding: 0;
}
body.mobile .revisions-dialog .revision-list {
height: unset;
max-height: 20vh;
border-bottom: 1px solid var(--main-border-color) !important;
padding: 0 1em;
}
body.mobile .revisions-dialog .modal-body > .revision-content-wrapper {
flex-grow: 1;
height: 100%;
overflow: auto;
margin: 0;
}
body.mobile .revisions-dialog .modal-body > .revision-content-wrapper > div:first-of-type {
flex-direction: column;
}
body.mobile .revisions-dialog .revision-title {
font-size: 1rem;
}
body.mobile .revisions-dialog .revision-title-buttons {
text-align: center;
}
body.mobile .revisions-dialog .revision-content {
padding: 0.5em;
}
}
/* Mobile, tablet mode */
@ -2589,14 +2626,6 @@ iframe.print-iframe {
width: 100%;
}
/* Calendar collection */
.calendar-view a.fc-timegrid-event,
.calendar-view a.fc-daygrid-event {
/* Workaround: set font weight only if the theme-next is not active */
font-weight: var(--root-background, 800);
}
@media (max-width: 991px) {
body.mobile {
.split-note-container-widget {

View File

@ -76,9 +76,6 @@
--mermaid-theme: dark;
--native-titlebar-background: #00000000;
--calendar-coll-event-background-saturation: 30%;
--calendar-coll-event-background-lightness: 30%;
}
body ::-webkit-calendar-picker-indicator {
@ -112,6 +109,3 @@ body .todo-list input[type="checkbox"]:not(:checked):before {
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.6) !important;
}
.use-note-color {
--custom-color: var(--dark-theme-custom-color);
}

View File

@ -80,9 +80,6 @@ html {
--mermaid-theme: default;
--native-titlebar-background: #ffffff00;
--calendar-coll-event-background-lightness: 95%;
--calendar-coll-event-background-saturation: 80%;
}
#left-pane .fancytree-node.tinted {
@ -94,8 +91,4 @@ html {
.ck-content a.reference-link > span,
.board-note {
color: var(--light-theme-custom-color, inherit);
}
.use-note-color {
--custom-color: var(--light-theme-custom-color);
}

View File

@ -41,9 +41,6 @@
--cmd-button-keyboard-shortcut-color: white;
--cmd-button-disabled-opacity: 0.5;
--button-group-active-button-background: #ffffff4e;
--button-group-active-button-text-color: white;
--icon-button-color: currentColor;
--icon-button-hover-background: var(--hover-item-background-color);
--icon-button-hover-color: var(--hover-item-text-color);
@ -270,14 +267,6 @@
--ck-editor-toolbar-button-on-color: white;
--ck-editor-toolbar-button-on-shadow: 1px 1px 2px rgba(0, 0, 0, .75);
--ck-editor-toolbar-dropdown-button-open-background: #ffffff14;
--calendar-coll-event-background-saturation: 25%;
--calendar-coll-event-background-lightness: 20%;
--calendar-coll-event-background-color: #3c3c3c;
--calendar-coll-event-text-color: white;
--calendar-coll-event-hover-filter: brightness(1.25);
--callendar-coll-event-archived-sripe-color: #00000026;
--calendar-coll-today-background-color: #ffffff08;
}
/*
@ -316,8 +305,4 @@ body .todo-list input[type="checkbox"]:not(:checked):before {
--modal-background-color: hsl(var(--custom-color-hue), 8.8%, 11.2%);
--modal-border-color: hsl(var(--custom-color-hue), 9.4%, 25.1%);
--promoted-attribute-card-background-color: hsl(var(--custom-color-hue), 13.2%, 20.8%);
}
.use-note-color {
--custom-color: var(--dark-theme-custom-color);
}

View File

@ -41,9 +41,6 @@
--cmd-button-keyboard-shortcut-color: black;
--cmd-button-disabled-opacity: 0.5;
--button-group-active-button-background: #00000026;
--button-group-active-button-text-color: black;
--icon-button-color: currentColor;
--icon-button-hover-background: var(--hover-item-background-color);
--icon-button-hover-color: var(--hover-item-text-color);
@ -268,14 +265,6 @@
--ck-editor-toolbar-button-on-color: black;
--ck-editor-toolbar-button-on-shadow: none;
--ck-editor-toolbar-dropdown-button-open-background: #0000000f;
--calendar-coll-event-background-lightness: 95%;
--calendar-coll-event-background-saturation: 80%;
--calendar-coll-event-background-color: #eaeaea;
--calendar-coll-event-text-color: black;
--calendar-coll-event-hover-filter: brightness(.95) saturate(1.25);
--callendar-coll-event-archived-sripe-color: #0000000a;
--calendar-coll-today-background-color: #00000006;
}
#left-pane .fancytree-node.tinted {

View File

@ -25,7 +25,6 @@
.modal .modal-header .btn-close,
.modal .modal-header .help-button,
.modal .modal-header .custom-title-bar-button,
#toast-container .toast .toast-header .btn-close {
display: flex;
justify-content: center;
@ -56,17 +55,15 @@
font-family: boxicons;
}
.modal .modal-header .help-button,
.modal .modal-header .custom-title-bar-button {
.modal .modal-header .help-button {
margin-inline-end: 0;
font-size: calc(var(--modal-control-button-size) * .70);
font-size: calc(var(--modal-control-button-size) * .75);
font-family: unset;
font-weight: bold;
}
.modal .modal-header .btn-close:hover,
.modal .modal-header .help-button:hover,
.modal .modal-header .custom-title-bar-button:hover,
#toast-container .toast .toast-header .btn-close:hover {
background: var(--modal-control-button-hover-background);
color: var(--modal-control-button-hover-color);
@ -74,7 +71,6 @@
.modal .modal-header .btn-close:active,
.modal .modal-header .help-button:active,
.modal .modal-header .custom-title-bar-button:active,
#toast-container .toast .toast-header .btn-close:active {
transform: scale(.85);
}

View File

@ -146,14 +146,6 @@ button.btn.btn-success kbd {
outline: 2px solid var(--input-focus-outline-color);
}
/* Button groups */
/* Active button */
:root .btn-group button.btn.active {
background-color: var(--button-group-active-button-background);
color: var(--button-group-active-button-text-color);
}
/*
* Input boxes
*/

View File

@ -643,7 +643,7 @@ html .note-detail-editable-text :not(figure, .include-note, hr):first-child {
}
}
.ck-content:not(.word-wrap) pre code {
.note-detail-printable:not(.word-wrap) pre code {
white-space: pre;
}

View File

@ -1448,14 +1448,6 @@ div.promoted-attribute-cell .multiplicity:has(span) span {
justify-content: center;
}
div.promoted-attribute-cell.promoted-attribute-label-color {
justify-content: space-between;
}
div.promoted-attribute-cell.promoted-attribute-label-color .input-group {
width: auto;
}
/*
* Floating buttons
*/

View File

@ -162,8 +162,7 @@
"inPageSearch": "页面内搜索",
"newTabWithActivationNoteLink": "在新标签页打开笔记链接并激活该标签页",
"title": "资料表",
"newTabNoteLink": "在新标签页开启链接",
"editShortcuts": "编辑键盘快捷键"
"newTabNoteLink": "在新标签页开启链接"
},
"import": {
"importIntoNote": "导入到笔记",
@ -2099,14 +2098,12 @@
"read-only-info": {
"read-only-note": "当前正在查看一个只读笔记。",
"auto-read-only-note": "这条笔记以只读模式显示便于快速加载。",
"auto-read-only-learn-more": "了解更多",
"edit-note": "编辑笔记"
},
"note-color": {
"clear-color": "清除笔记颜色",
"set-color": "设置笔记颜色",
"set-custom-color": "设置自定义笔记颜色"
},
"popup-editor": {
"maximize": "切换至完整编辑器"
}
}

View File

@ -2097,6 +2097,7 @@
"read-only-info": {
"read-only-note": "Aktuelle Notiz wird im Lese-Modus angezeigt.",
"auto-read-only-note": "Diese Notiz wird im Nur-Lesen-Modus angezeigt, um ein schnelleres Laden zu ermöglichen.",
"auto-read-only-learn-more": "Mehr erfahren",
"edit-note": "Notiz bearbeiten"
},
"calendar_view": {

View File

@ -1,73 +0,0 @@
{
"import": {
"safeImportTooltip": "Trilium <code>.zip</code> export files can contain executable scripts which may contain harmful behaviour. Safe import will deactivate automatic execution of all imported scripts. Uncheck \"Safe import\" only if the imported archive is supposed to contain executable scripts and you completely trust the contents of the import file.",
"shrinkImagesTooltip": "<p>If you check this option, Trilium will attempt to shrink the imported images by scaling and optimisation which may affect the perceived image quality. If unchecked, images will be imported without changes.</p><p>This doesn't apply to <code>.zip</code> imports with metadata since it is assumed these files are already optimised.</p>",
"codeImportedAsCode": "Import recognised code files (e.g. <code>.json</code>) as code notes if it's unclear from metadata"
},
"upload_attachments": {
"tooltip": "If you check this option, Trilium will attempt to shrink the uploaded images by scaling and optimisation which may affect the perceived image quality. If unchecked, images will be uploaded without changes."
},
"attribute_detail": {
"auto_read_only_disabled": "text/code notes can be set automatically into read mode when they are too large. You can disable this behaviour on per-note basis by adding this label to the note",
"workspace_tab_background_color": "CSS colour used in the note tab when hoisted to this note",
"color": "defines colour of the note in note tree, links etc. Use any valid CSS colour value like 'red' or #a13d5f",
"color_type": "Colour"
},
"mobile_detail_menu": {
"error_unrecognized_command": "Unrecognised command {{command}}"
},
"promoted_attributes": {
"remove_color": "Remove the colour label"
},
"max_content_width": {
"centerContent": "Keep content centred"
},
"theme": {
"auto_theme": "Legacy (Follow system colour scheme)",
"triliumnext": "Trilium (Follow system colour scheme)"
},
"search_engine": {
"custom_name_placeholder": "Customise search engine name",
"custom_url_placeholder": "Customise search engine url"
},
"highlights_list": {
"description": "You can customise the highlights list displayed in the right panel:",
"color": "Coloured text",
"bg_color": "Text with background colour"
},
"table_of_contents": {
"description": "Table of contents will appear in text notes when the note has more than a defined number of headings. You can customise this number:"
},
"custom_date_time_format": {
"description": "Customise the format of the date and time inserted via <shortcut /> or the toolbar. See <doc>Day.js docs</doc> for available format tokens."
},
"i18n": {
"title": "Localisation"
},
"attachment_detail_2": {
"unrecognized_role": "Unrecognised attachment role '{{role}}'."
},
"ai_llm": {
"reprocess_index_started": "Search index optimisation started in the background",
"index_rebuilding": "Optimising index ({{percentage}}%)",
"index_rebuild_complete": "Index optimisation complete"
},
"highlighting": {
"color-scheme": "Colour Scheme"
},
"code_theme": {
"color-scheme": "Colour scheme"
},
"call_to_action": {
"background_effects_message": "On Windows devices, background effects are now fully stable. The background effects adds a touch of colour to the user interface by blurring the background behind it. This technique is also used in other applications such as Windows Explorer."
},
"settings_appearance": {
"related_code_blocks": "Colour scheme for code blocks in text notes",
"related_code_notes": "Colour scheme for code notes"
},
"note-color": {
"clear-color": "Clear note colour",
"set-color": "Set note colour",
"set-custom-color": "Set custom note colour"
}
}

View File

@ -112,7 +112,6 @@
},
"help": {
"title": "Cheatsheet",
"editShortcuts": "Edit keyboard shortcuts",
"noteNavigation": "Note navigation",
"goUpDown": "go up/down in the list of notes",
"collapseExpand": "collapse/expand node",
@ -736,8 +735,8 @@
"zoom_out_title": "Zoom Out"
},
"zpetne_odkazy": {
"backlink_one": "{{count}} Backlink",
"backlink_other": "{{count}} Backlinks",
"backlink": "{{count}} Backlink",
"backlinks": "{{count}} Backlinks",
"relation": "relation"
},
"mobile_detail_menu": {
@ -1883,7 +1882,6 @@
"link_context_menu": {
"open_note_in_new_tab": "Open note in a new tab",
"open_note_in_new_split": "Open note in a new split",
"open_note_in_other_split": "Open note in the other split",
"open_note_in_new_window": "Open note in a new window",
"open_note_in_popup": "Quick edit"
},
@ -2108,8 +2106,5 @@
"clear-color": "Clear note color",
"set-color": "Set note color",
"set-custom-color": "Set custom note color"
},
"popup-editor": {
"maximize": "Switch to full editor"
}
}

View File

@ -2096,6 +2096,7 @@
"read-only-info": {
"read-only-note": "Actualmente, está viendo una nota de solo lectura.",
"auto-read-only-note": "Esta nota se muestra en modo de solo lectura para una carga más rápida.",
"auto-read-only-learn-more": "Para saber más",
"edit-note": "Editar nota"
},
"calendar_view": {

View File

@ -2092,6 +2092,7 @@
"read-only-info": {
"read-only-note": "Stai visualizzando una nota di sola lettura.",
"auto-read-only-note": "Questa nota viene visualizzata in modalità di sola lettura per un caricamento più rapido.",
"auto-read-only-learn-more": "Per saperne di più",
"edit-note": "Modifica nota"
},
"calendar_view": {

View File

@ -312,8 +312,7 @@
"moveNoteUpDown": "ノートリストでノートを上/下に移動",
"notSet": "未設定",
"goUpDown": "ノートのリストで上下する",
"editBranchPrefix": "アクティブノートのクローンの <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/tree-concepts.html#prefix\">プレフィックス</a> を編集する",
"editShortcuts": "キーボードショートカットを編集"
"editBranchPrefix": "アクティブノートのクローンの <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/tree-concepts.html#prefix\">プレフィックス</a> を編集する"
},
"import": {
"importIntoNote": "ノートにインポート",
@ -2099,14 +2098,12 @@
"read-only-info": {
"read-only-note": "現在、読み取り専用のノートを表示しています。",
"auto-read-only-note": "このノートは読み込みを高速化するために読み取り専用モードで表示されています。",
"auto-read-only-learn-more": "さらに詳しく",
"edit-note": "ノートを編集"
},
"note-color": {
"clear-color": "ノートの色をクリア",
"set-color": "ノートの色を設定",
"set-custom-color": "ノートの色をカスタム設定"
},
"popup-editor": {
"maximize": "フルエディターに切り替え"
}
}

View File

@ -1362,9 +1362,8 @@
"title": "Factorul de zoom (doar pentru versiunea desktop)"
},
"zpetne_odkazy": {
"backlink_one": "{{count}} legătură de retur",
"backlink_few": "{{count}} legături de retur",
"backlink_other": "{{count}} de legături de retur",
"backlink": "{{count}} legături de retur",
"backlinks": "{{count}} legături de retur",
"relation": "relație"
},
"svg_export_button": {
@ -2098,6 +2097,7 @@
"read-only-info": {
"read-only-note": "Vizualizați o notiță în modul doar în citire.",
"auto-read-only-note": "Această notiță este afișată în modul doar în citire din motive de performanță.",
"auto-read-only-learn-more": "Mai multe detalii",
"edit-note": "Editează notița"
},
"calendar_view": {

View File

@ -162,8 +162,7 @@
"inPageSearch": "頁面內搜尋",
"title": "列表",
"newTabNoteLink": "在新分頁開啟筆記連結",
"newTabWithActivationNoteLink": "在新分頁開啟並切換至筆記連結",
"editShortcuts": "編輯鍵盤快捷鍵"
"newTabWithActivationNoteLink": "在新分頁開啟並切換至筆記連結"
},
"import": {
"importIntoNote": "匯入至筆記",
@ -2099,14 +2098,12 @@
"read-only-info": {
"read-only-note": "目前正在檢視唯讀筆記。",
"auto-read-only-note": "此筆記以唯讀模式顯示以加快載入速度。",
"auto-read-only-learn-more": "了解更多",
"edit-note": "編輯筆記"
},
"note-color": {
"clear-color": "清除筆記顏色",
"set-color": "設定筆記顏色",
"set-custom-color": "設定自訂筆記顏色"
},
"popup-editor": {
"maximize": "切換至完整編輯器"
}
}

View File

@ -18,7 +18,6 @@ import froca from "../services/froca";
import NoteLink from "./react/NoteLink";
import RawHtml from "./react/RawHtml";
import { ViewTypeOptions } from "./collections/interface";
import attributes from "../services/attributes";
export interface FloatingButtonContext {
parentComponent: Component;
@ -311,24 +310,13 @@ function Backlinks({ note, isDefaultViewMode }: FloatingButtonContext) {
let [ popupOpen, setPopupOpen ] = useState(false);
const backlinksContainerRef = useRef<HTMLDivElement>(null);
function refresh() {
useEffect(() => {
if (!isDefaultViewMode) return;
server.get<BacklinkCountResponse>(`note-map/${note.noteId}/backlink-count`).then(resp => {
setBacklinkCount(resp.count);
});
}
useEffect(() => refresh(), [ note ]);
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
loadResults.getAttributeRows().some(attr =>
attr.type === "relation" &&
attr.name === "internalLink" &&
attributes.isAffecting(attr, note))
{
refresh();
}
});
}, [ note ]);
// Determine the max height of the container.
const { windowHeight } = useWindowSize();

View File

@ -14,10 +14,8 @@ import ws from "../services/ws";
import { UpdateAttributeResponse } from "@triliumnext/commons";
import attributes from "../services/attributes";
import debounce from "../services/debounce";
import { randomString } from "../services/utils";
interface Cell {
uniqueId: string;
definitionAttr: FAttribute;
definition: DefinitionObject;
valueAttr: Attribute;
@ -46,7 +44,6 @@ export default function PromotedAttributes() {
<div className="promoted-attributes-widget">
{cells && cells.length > 0 && <div className="promoted-attributes-container">
{note && cells?.map(cell => <PromotedAttributeCell
key={cell.uniqueId}
cell={cell}
cells={cells} setCells={setCells}
shouldFocus={cell === cellToFocus} setCellToFocus={setCellToFocus}
@ -106,8 +103,7 @@ function usePromotedAttributeData(note: FNote | null | undefined, componentId: s
valueAttr.attributeId = "";
}
const uniqueId = randomString(10);
cells.push({ definitionAttr, definition, valueAttr, valueName, uniqueId });
cells.push({ definitionAttr, definition, valueAttr, valueName });
}
}
setCells(cells);

View File

@ -2,9 +2,9 @@ import FNote from "../../../entities/fnote";
import NoteColorPicker from "../../../menus/custom-items/NoteColorPicker";
import contextMenu, { ContextMenuEvent } from "../../../menus/context_menu";
import link_context_menu from "../../../menus/link_context_menu";
import attributes from "../../../services/attributes";
import branches from "../../../services/branches";
import dialog from "../../../services/dialog";
import { getArchiveMenuItem } from "../../../menus/context_menu_utils";
import { t } from "../../../services/i18n";
import Api from "./api";
@ -43,6 +43,17 @@ export function openNoteContextMenu(api: Api, event: ContextMenuEvent, note: FNo
items: [
...link_context_menu.getItems(),
{ kind: "separator" },
{
title: t("board_view.move-to"),
uiIcon: "bx bx-transfer",
items: api.columns.map(columnToMoveTo => ({
title: columnToMoveTo,
enabled: columnToMoveTo !== column,
handler: () => api.changeColumn(note.noteId, columnToMoveTo)
})),
},
getArchiveMenuItem(note),
{ kind: "separator" },
{
title: t("board_view.insert-above"),
uiIcon: "bx bx-list-plus",
@ -54,17 +65,6 @@ export function openNoteContextMenu(api: Api, event: ContextMenuEvent, note: FNo
handler: () => api.insertRowAtPosition(column, branchId, "after")
},
{ kind: "separator" },
{
title: t("board_view.move-to"),
uiIcon: "bx bx-transfer",
items: api.columns.map(columnToMoveTo => ({
title: columnToMoveTo,
enabled: columnToMoveTo !== column,
handler: () => api.changeColumn(note.noteId, columnToMoveTo)
})),
},
{ kind: "separator" },
getArchiveMenuItem(note),
{
title: t("board_view.remove-from-board"),
uiIcon: "bx bx-task-x",
@ -85,3 +85,20 @@ export function openNoteContextMenu(api: Api, event: ContextMenuEvent, note: FNo
});
}
function getArchiveMenuItem(note: FNote) {
if (!note.isArchived) {
return {
title: t("board_view.archive-note"),
uiIcon: "bx bx-archive",
handler: () => attributes.addLabel(note.noteId, "archived")
}
} else {
return {
title: t("board_view.unarchive-note"),
uiIcon: "bx bx-archive-out",
handler: async () => {
attributes.removeOwnedLabelByName(note, "archived")
}
}
}
}

View File

@ -3,10 +3,11 @@ import FNote from "../../../entities/fnote";
import contextMenu, { ContextMenuEvent } from "../../../menus/context_menu";
import link_context_menu from "../../../menus/link_context_menu";
import branches from "../../../services/branches";
import { getArchiveMenuItem } from "../../../menus/context_menu_utils";
import froca from "../../../services/froca";
import { note } from "mermaid/dist/rendering-util/rendering-elements/shapes/note.js";
import { t } from "../../../services/i18n";
export function openCalendarContextMenu(e: ContextMenuEvent, note: FNote, parentNote: FNote) {
export function openCalendarContextMenu(e: ContextMenuEvent, noteId: string, parentNote: FNote) {
e.preventDefault();
e.stopPropagation();
@ -16,13 +17,15 @@ export function openCalendarContextMenu(e: ContextMenuEvent, note: FNote, parent
items: [
...link_context_menu.getItems(),
{ kind: "separator" },
getArchiveMenuItem(note),
{
title: t("calendar_view.delete_note"),
uiIcon: "bx bx-trash",
handler: async () => {
const noteToDelete = await froca.getNote(noteId);
if (!noteToDelete) return;
let branchIdToDelete: string | null = null;
for (const parentBranch of note.getParentBranches()) {
for (const parentBranch of noteToDelete.getParentBranches()) {
const parentNote = await parentBranch.getNote();
if (parentNote?.hasAncestor(parentNote.noteId)) {
branchIdToDelete = parentBranch.branchId;
@ -37,9 +40,9 @@ export function openCalendarContextMenu(e: ContextMenuEvent, note: FNote, parent
{ kind: "separator" },
{
kind: "custom",
componentFn: () => NoteColorPicker({note: note})
componentFn: () => NoteColorPicker({note: noteId})
}
],
selectMenuItemHandler: ({ command }) => link_context_menu.handleLinkContextMenuItem(command, note.noteId),
selectMenuItemHandler: ({ command }) => link_context_menu.handleLinkContextMenuItem(command, noteId),
})
}

View File

@ -3,7 +3,6 @@ import froca from "../../../services/froca";
import { formatDateToLocalISO, getCustomisableLabel, getMonthsInDateRange, offsetDate } from "./utils";
import FNote from "../../../entities/fnote";
import server from "../../../services/server";
import clsx from "clsx";
interface Event {
startDate: string,
@ -81,7 +80,7 @@ export async function buildEventsForCalendar(note: FNote, e: EventSourceFuncArg)
export async function buildEvent(note: FNote, { startDate, endDate, startTime, endTime, isArchived }: Event) {
const customTitleAttributeName = note.getLabelValue("calendar:title");
const titles = await parseCustomTitle(customTitleAttributeName, note);
const colorClass = note.getColorClass();
const color = note.getLabelValue("calendar:color") ?? note.getLabelValue("color");
const events: EventInput[] = [];
const calendarDisplayedAttributes = note.getLabelValue("calendar:displayedAttributes")?.split(",");
@ -109,9 +108,10 @@ export async function buildEvent(note: FNote, { startDate, endDate, startTime, e
start: startDate,
url: `#${note.noteId}?popup`,
noteId: note.noteId,
color: color ?? undefined,
iconClass: note.getLabelValue("iconClass"),
promotedAttributes: displayedAttributesData,
className: clsx({archived: isArchived}, colorClass)
className: isArchived ? "archived" : ""
};
if (endDate) {
eventData.end = endDate;

View File

@ -1,21 +1,4 @@
:root {
/* Default values to be overridden by themes */
--calendar-coll-event-background-lightness: 95%;
--calendar-coll-event-background-saturation: 80%;
--calendar-coll-event-background-color: var(--accented-background-color);
--calendar-coll-event-text-color: var(--main-text-color);
--calendar-coll-event-hover-filter: none;
--callendar-coll-event-archived-sripe-color: #00000013;
--calendar-coll-today-background-color: var(--more-accented-background-color);
}
.calendar-view {
--fc-event-border-color: var(--calendar-coll-event-text-color);
--fc-event-bg-color: var(--calendar-coll-event-background-color);
--fc-event-text-color: var(--calendar-coll-event-text-color);
--fc-event-selected-overlay-color: transparent;
--fc-today-bg-color: var(--calendar-coll-today-background-color);
overflow: hidden;
position: relative;
outline: 0;
@ -24,9 +7,8 @@
padding: 10px;
}
.calendar-view a,
:root .calendar-view a.fc-daygrid-event:hover {
color: var(--fc-event-text-color);
.calendar-view a {
color: unset;
}
.search-result-widget-content .calendar-view {
@ -49,6 +31,14 @@
z-index: 50;
}
.calendar-container a.fc-event {
text-decoration: none;
}
.calendar-container a.fc-event.archived {
opacity: 0.5;
}
.calendar-container .fc-button {
padding: 0.2em 0.5em;
}
@ -85,107 +75,4 @@ body.desktop:not(.zen) .calendar-view .calendar-header {
.search-result-widget-content .calendar-view .calendar-header {
padding-inline-end: unset !important;
}
/* #endregion */
/* #region Events */
/*
* week, month, year views
*/
.calendar-container a.fc-event {
text-decoration: none;
}
.calendar-container a.fc-event.archived {
opacity: .65;
}
.calendar-container a.fc-event.archived::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
--c1: transparent;
--c2: var(--callendar-coll-event-archived-sripe-color);
background: repeating-linear-gradient(45deg, var(--c1), var(--c1) 8px,
var(--c2) 8px, var(--c2) 16px);
}
.calendar-view a.fc-timegrid-event,
.calendar-view a.fc-daygrid-event,
.calendar-view .fc-daygrid-dot-event .fc-event-title {
font-weight: 500;
}
.calendar-view a.fc-timegrid-event,
.calendar-view a.fc-daygrid-event {
--border-color: transparent;
border: 2px solid;
border-left-width: 4px;
border-color: var(--border-color) var(--border-color) var(--border-color)
var(--fc-event-text-color) !important;
background: var(--fc-event-bg-color) !important;
padding-left: 8px;
}
.calendar-view .fc-timegrid-event.with-hue,
.calendar-view .fc-daygrid-event.with-hue {
--fc-event-text-color: var(--custom-color);
--fc-event-bg-color: hsl(var(--custom-color-hue),
var(--calendar-coll-event-background-saturation),
var(--calendar-coll-event-background-lightness)) !important;
}
.calendar-view a.fc-timegrid-event:focus-visible,
.calendar-view a.fc-daygrid-event:focus-visible {
outline: none;
}
.calendar-view a.fc-timegrid-event.fc-event-selected,
.calendar-view a.fc-timegrid-event.fc-event:focus,
.calendar-view a.fc-daygrid-event.fc-event-selected,
.calendar-view a.fc-daygrid-event.fc-event:focus {
--border-color: var(--custom-color, var(--input-focus-outline-color));
}
.calendar-view a.fc-timegrid-event:hover,
.calendar-view a.fc-daygrid-event:hover {
filter: var(--calendar-coll-event-hover-filter);
border-color: var(--fc-event-text-color);
text-decoration: none;
color: currentColor;
opacity: 1;
}
.calendar-view .fc-daygrid-event-dot {
display: none;
}
.calendar-view .fc-event-time {
opacity: .75;
}
/*
* List view
*/
.fc-list-table tr.fc-event.archived {
opacity: .5;
}
.fc-list-table .fc-list-event-dot {
/* Apply note colors to the list item dots */
--fc-event-border-color: var(--custom-color);
}
/* #endregion */

View File

@ -77,7 +77,6 @@ export const LOCALE_MAPPINGS: Record<DISPLAYABLE_LOCALE_IDS, (() => Promise<{ de
"pt_br": () => import("@fullcalendar/core/locales/pt-br"),
uk: () => import("@fullcalendar/core/locales/uk"),
en: null,
"en-GB": () => import("@fullcalendar/core/locales/en-gb"),
"en_rtl": null,
ar: () => import("@fullcalendar/core/locales/ar")
};
@ -307,11 +306,9 @@ function useEventDisplayCustomization(parentNote: FNote) {
$(mainContainer ?? e.el).append($(promotedAttributesHtml));
}
e.el.addEventListener("contextmenu", async (contextMenuEvent) => {
const note = await froca.getNote(e.event.extendedProps.noteId);
if (!note) return;
openCalendarContextMenu(contextMenuEvent, note, parentNote);
e.el.addEventListener("contextmenu", (contextMenuEvent) => {
const noteId = e.event.extendedProps.noteId;
openCalendarContextMenu(contextMenuEvent, noteId, parentNote);
});
}, []);
return { eventDidMount };

View File

@ -74,14 +74,13 @@ export default class SplitNoteContainer extends FlexContainer<SplitNoteWidget> {
const subContexts = activeContext.getSubContexts();
let noteContext: NoteContext | undefined = undefined;
let noteContext: NoteContext;
if (isMobile() && subContexts.length > 1) {
noteContext = subContexts.find(s => s.ntxId !== ntxId);
}
if (!noteContext) {
noteContext = subContexts.find(s => s.ntxId !== ntxId)!;
} else {
noteContext = await appContext.tabManager.openEmptyTab(null, hoistedNoteId, mainNtxId);
// remove the original position of newly created note context
const ntxIds = appContext.tabManager.children.map((c) => c.ntxId).filter((id) => id !== noteContext?.ntxId) as string[];
const ntxIds = appContext.tabManager.children.map((c) => c.ntxId).filter((id) => id !== noteContext.ntxId) as string[];
// insert the note context after the originating note context
if (!noteContext.ntxId) {

View File

@ -33,8 +33,8 @@ body.mobile .modal.popup-editor-dialog .modal-dialog {
align-items: center;
}
.modal.popup-editor-dialog .modal-header .note-title-widget {
margin-top: 8px;
.modal.popup-editor-dialog .modal-header .title-row > * {
margin: 5px;
}
.modal.popup-editor-dialog .modal-body {
@ -66,17 +66,12 @@ body.mobile .modal.popup-editor-dialog .modal-dialog {
background-color: transparent;
}
.modal.popup-editor-dialog div.promoted-attributes-container {
margin-block: 0;
}
.modal.popup-editor-dialog .classic-toolbar-widget {
position: sticky;
margin-inline: 8px;
top: 0;
inset-inline-start: 0;
inset-inline-end: 0;
background: var(--modal-background-color);
background: transparent;
z-index: 998;
align-items: flex-start;
}

View File

@ -19,8 +19,6 @@ import tree from "../../services/tree";
import froca from "../../services/froca";
import ReadOnlyNoteInfoBar from "../ReadOnlyNoteInfoBar";
import MobileEditorToolbar from "../type_widgets/text/mobile_editor_toolbar";
import { t } from "../../services/i18n";
import appContext from "../../components/app_context";
export default function PopupEditor() {
const [ shown, setShown ] = useState(false);
@ -62,16 +60,6 @@ export default function PopupEditor() {
<DialogWrapper>
<Modal
title={<TitleRow />}
customTitleBarButtons={[{
iconClassName: "bx-expand-alt",
title: t("popup-editor.maximize"),
onClick: async () => {
if (!noteContext.noteId) return;
const { noteId, hoistedNoteId } = noteContext;
await appContext.tabManager.openInNewTab(noteId, hoistedNoteId, true);
setShown(false);
}
}]}
className="popup-editor-dialog"
size="lg"
show={shown}

View File

@ -1,7 +1,7 @@
import Modal from "../react/Modal.jsx";
import { t } from "../../services/i18n.js";
import { ComponentChildren } from "preact";
import appContext, { CommandNames } from "../../components/app_context.js";
import { CommandNames } from "../../components/app_context.js";
import RawHtml from "../react/RawHtml.jsx";
import { useEffect, useState } from "preact/hooks";
import keyboard_actions from "../../services/keyboard_actions.js";
@ -14,7 +14,6 @@ export default function HelpDialog() {
return (
<Modal
title={t("help.title")} className="help-dialog use-tn-links" minWidth="90%" size="lg" scrollable
customTitleBarButtons={[{title: t("help.editShortcuts"), iconClassName: "bxs-pencil", onClick: editShortcuts}]}
onHidden={() => setShown(false)}
show={shown}
>
@ -161,7 +160,3 @@ function Card({ title, children }: { title: string, children: ComponentChildren
</div>
)
}
function editShortcuts() {
appContext.tabManager.openContextWithNote("_optionsShortcuts", { activate: true });
}

View File

@ -1,63 +0,0 @@
body.mobile .revisions-dialog {
.modal-dialog {
height: 95vh;
}
.modal-header {
display: flex;
flex-wrap: wrap;
gap: 0.25em;
font-size: 0.9em;
}
.modal-title {
flex-grow: 1;
width: 100%;
}
.modal-body {
height: fit-content !important;
flex-direction: column;
padding: 0;
}
.modal-footer {
font-size: 0.9em;
}
.revision-list {
height: fit-content !important;
max-height: 20vh;
border-bottom: 1px solid var(--main-border-color) !important;
padding: 0 1em;
flex-shrink: 0;
}
.modal-body > .revision-content-wrapper {
flex-grow: 1;
max-width: unset !important;
height: 100%;
margin: 0;
display: block !important;
}
.modal-body > .revision-content-wrapper > div:first-of-type {
flex-direction: column;
}
.revision-title {
font-size: 1rem;
}
.revision-title-buttons {
text-align: center;
display: flex;
gap: 0.25em;
flex-wrap: wrap;
}
.revision-content {
padding: 0.5em;
height: fit-content;
}
}

View File

@ -20,7 +20,6 @@ import ActionButton from "../react/ActionButton";
import options from "../../services/options";
import { useTriliumEvent } from "../react/hooks";
import { diffWords } from "diff";
import "./revisions.css";
export default function RevisionsDialog() {
const [ note, setNote ] = useState<FNote>();
@ -138,7 +137,7 @@ export default function RevisionsDialog() {
function RevisionsList({ revisions, onSelect, currentRevision }: { revisions: RevisionItem[], onSelect: (val: string) => void, currentRevision?: RevisionItem }) {
return (
<FormList onSelect={onSelect} fullHeight wrapperClassName="revision-list">
<FormList onSelect={onSelect} fullHeight>
{revisions.map((item) =>
<FormListItem
value={item.revisionId}

View File

@ -17,33 +17,26 @@ export default function MobileDetailMenu() {
icon="bx bx-dots-vertical-rounded"
text=""
onClick={(e) => {
const ntxId = (parentComponent as BasicWidget | null)?.getClosestNtxId();
const ntxId = (parentComponent as BasicWidget).getClosestNtxId();
if (!ntxId) return;
const noteContext = appContext.tabManager.getNoteContextById(ntxId);
const subContexts = noteContext.getMainContext().getSubContexts();
const isMainContext = noteContext?.isMainContext();
const note = noteContext.note;
const items: (MenuItem<keyof CommandMappings>)[] = [
const items: (MenuItem<keyof CommandMappings> | false)[] = [
{ title: t("mobile_detail_menu.insert_child_note"), command: "insertChildNote", uiIcon: "bx bx-plus", enabled: note?.type !== "search" },
{ title: t("mobile_detail_menu.delete_this_note"), command: "delete", uiIcon: "bx bx-trash", enabled: note?.noteId !== "root" },
{ kind: "separator" },
{ title: t("mobile_detail_menu.note_revisions"), command: "showRevisions", uiIcon: "bx bx-history" },
{ kind: "separator" },
subContexts.length < 2 && { title: t("create_pane_button.create_new_split"), command: "openNewNoteSplit", uiIcon: "bx bx-dock-right" },
!isMainContext && { title: t("close_pane_button.close_this_pane"), command: "closeThisNoteSplit", uiIcon: "bx bx-x" }
].filter(i => !!i) as MenuItem<keyof CommandMappings>[];
const lastItem = items.at(-1);
if (lastItem && "kind" in lastItem && lastItem.kind === "separator") {
items.pop();
}
{ title: t("create_pane_button.create_new_split"), command: "openNewNoteSplit", uiIcon: "bx bx-dock-right" },
!noteContext?.isMainContext() && { title: t("close_pane_button.close_this_pane"), command: "closeThisNoteSplit", uiIcon: "bx bx-x" }
];
contextMenu.show<keyof CommandMappings>({
x: e.pageX,
y: e.pageY,
items,
items: items.filter(i => !!i),
selectMenuItemHandler: async ({ command }) => {
if (command === "insertChildNote") {
note_create.createNote(appContext.tabManager.getActiveContextNotePath() ?? undefined);

View File

@ -6,17 +6,15 @@ import "./FormList.css";
import { CommandNames } from "../../components/app_context";
import { useStaticTooltip } from "./hooks";
import { handleRightToLeftPlacement, isMobile } from "../../services/utils";
import clsx from "clsx";
interface FormListOpts {
children: ComponentChildren;
onSelect?: (value: string) => void;
style?: CSSProperties;
wrapperClassName?: string;
fullHeight?: boolean;
}
export default function FormList({ children, onSelect, style, fullHeight, wrapperClassName }: FormListOpts) {
export default function FormList({ children, onSelect, style, fullHeight }: FormListOpts) {
const wrapperRef = useRef<HTMLDivElement | null>(null);
const triggerRef = useRef<HTMLButtonElement | null>(null);
@ -45,7 +43,7 @@ export default function FormList({ children, onSelect, style, fullHeight, wrappe
}, [ fullHeight ]);
return (
<div className={clsx("dropdownWrapper", wrapperClassName)} ref={wrapperRef} style={builtinStyles}>
<div className="dropdownWrapper" ref={wrapperRef} style={builtinStyles}>
<div className="dropdown" style={builtinStyles}>
<button
ref={triggerRef}

View File

@ -1,4 +1,3 @@
import clsx from "clsx";
import { useEffect, useRef, useMemo } from "preact/hooks";
import { t } from "../../services/i18n";
import { ComponentChildren } from "preact";
@ -8,16 +7,9 @@ import { Modal as BootstrapModal } from "bootstrap";
import { memo } from "preact/compat";
import { useSyncedRef } from "./hooks";
interface CustomTitleBarButton {
title: string;
iconClassName: string;
onClick: () => void;
}
interface ModalProps {
className: string;
title: string | ComponentChildren;
customTitleBarButtons?: (CustomTitleBarButton | null)[];
size: "xl" | "lg" | "md" | "sm";
children: ComponentChildren;
/**
@ -80,7 +72,7 @@ interface ModalProps {
noFocus?: boolean;
}
export default function Modal({ children, className, size, title, customTitleBarButtons: titleBarButtons, header, footer, footerStyle, footerAlignment, onShown, onSubmit, helpPageId, minWidth, maxWidth, zIndex, scrollable, onHidden: onHidden, modalRef: externalModalRef, formRef, bodyStyle, show, stackable, keepInDom, noFocus }: ModalProps) {
export default function Modal({ children, className, size, title, header, footer, footerStyle, footerAlignment, onShown, onSubmit, helpPageId, minWidth, maxWidth, zIndex, scrollable, onHidden: onHidden, modalRef: externalModalRef, formRef, bodyStyle, show, stackable, keepInDom, noFocus }: ModalProps) {
const modalRef = useSyncedRef<HTMLDivElement>(externalModalRef);
const modalInstanceRef = useRef<BootstrapModal>();
const elementToFocus = useRef<Element | null>();
@ -156,17 +148,7 @@ export default function Modal({ children, className, size, title, customTitleBar
{helpPageId && (
<button className="help-button" type="button" data-in-app-help={helpPageId} title={t("modal.help_title")}>?</button>
)}
{titleBarButtons?.filter((b) => b !== null).map((titleBarButton) => (
<button type="button"
className={clsx("custom-title-bar-button bx", titleBarButton.iconClassName)}
title={titleBarButton.title}
onClick={titleBarButton.onClick}>
</button>
))}
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label={t("modal.close")}></button>
</div>
{onSubmit ? (

View File

@ -1,5 +1,5 @@
import { ConvertToAttachmentResponse } from "@triliumnext/commons";
import { FormDropdownDivider, FormListHeader, FormListItem } from "../react/FormList";
import { FormDropdownDivider, FormListItem } from "../react/FormList";
import { isElectron as getIsElectron, isMac as getIsMac } from "../../services/utils";
import { ParentComponent } from "../react/react_utils";
import { t } from "../../services/i18n"
@ -113,7 +113,8 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
function DevelopmentActions({ note }: { note: FNote }) {
return (
<>
<FormListHeader text="Development-only Actions" />
<FormDropdownDivider />
<FormListItem disabled>Development-only Actions</FormListItem>
<FormListItem
icon="bx bx-printer"
onClick={() => window.open(`/?print=#root/${note.noteId}`, "_blank")}

View File

@ -26,7 +26,7 @@ export const RIBBON_TAB_DEFINITIONS: TabConfiguration[] = [
&& !(await noteContext?.isReadOnly()),
toggleCommand: "toggleRibbonTabClassicEditor",
content: FormattingToolbar,
activate: () => !options.is("editedNotesOpenInRibbon"),
activate: true,
stayInDom: true
},
{
@ -50,7 +50,7 @@ export const RIBBON_TAB_DEFINITIONS: TabConfiguration[] = [
icon: "bx bx-calendar-edit",
content: EditedNotesTab,
show: ({ note }) => note?.hasOwnedLabel("dateNote"),
activate: () => options.is("editedNotesOpenInRibbon")
activate: ({ note }) => (note?.getPromotedDefinitionAttributes().length === 0 || !options.is("promotedAttributesOpenInRibbon")) && options.is("editedNotesOpenInRibbon")
},
{
title: t("book_properties.book_properties"),

View File

@ -28,7 +28,6 @@ const LOCALE_MAPPINGS: Record<DISPLAYABLE_LOCALE_IDS, Options["locale"] | null>
de: null,
en: "en",
en_rtl: "en",
"en-GB": "en",
es: "es",
fr: "fr",
it: "it",

View File

@ -22,7 +22,6 @@ describe("Canvas i18n", () => {
if (locale.contentOnly || locale.devOnly) continue;
const languageCode = LANGUAGE_MAPPINGS[locale.id];
if (!supportedLanguageCodes.has(languageCode)) {
console.log("Supported locales:", Array.from(supportedLanguageCodes.values()).join(", "));
expect.fail(`Unable to find locale for ${locale.id} -> ${languageCode}.`)
}
}

View File

@ -1,12 +1,10 @@
import { Language } from "@excalidraw/excalidraw/i18n";
import type { DISPLAYABLE_LOCALE_IDS } from "@triliumnext/commons";
export const LANGUAGE_MAPPINGS: Record<DISPLAYABLE_LOCALE_IDS, Language["code"] | null> = {
export const LANGUAGE_MAPPINGS: Record<DISPLAYABLE_LOCALE_IDS, string | null> = {
ar: "ar-SA",
cn: "zh-CN",
de: "de-DE",
en: "en",
"en-GB": "en",
en_rtl: "en",
es: "es-ES",
fr: "fr-FR",

View File

@ -55,7 +55,6 @@ export function buildClassicToolbar(multilineToolbar: boolean) {
...TEXT_FORMATTING_GROUP,
items: ["underline", "strikethrough", "|", "superscript", "subscript", "|", "kbd"]
},
"formatPainter",
"|",
"fontColor",
"fontBackgroundColor",
@ -105,7 +104,6 @@ export function buildFloatingToolbar() {
...TEXT_FORMATTING_GROUP,
items: [ "strikethrough", "|", "superscript", "subscript", "|", "kbd" ]
},
"formatPainter",
"|",
"fontColor",
"fontBackgroundColor",

View File

@ -1,9 +1,8 @@
import path, { join } from "path";
import path from "path";
import fs from "fs-extra";
import { LOCALES } from "@triliumnext/commons";
import { PRODUCT_NAME } from "../src/app-info.js";
import type { ForgeConfig } from "@electron-forge/shared-types";
import { existsSync } from "fs";
const ELECTRON_FORGE_DIR = __dirname;
@ -229,22 +228,8 @@ const config: ForgeConfig = {
// Ensure all locales that should be kept are actually present.
for (const locale of localesToKeep) {
if (!keptLocales.has(locale)) {
throw new Error(`Locale ${locale} was not found in the packaged app.`);
}
}
// Check that the bettersqlite3 binary has the right architecture.
if (packageResult.platform === "linux" && packageResult.arch === "arm64") {
for (const outputPath of packageResult.outputPaths) {
const binaryPath = join(outputPath, "resources/app.asar.unpacked/node_modules/better-sqlite3/build/Release/better_sqlite3.node");
if (!existsSync(binaryPath)) {
throw new Error(`[better-sqlite3] Unable to find .node file at ${binaryPath}`);
}
const actualArch = getELFArch(binaryPath);
if (actualArch !== "ARM64") {
throw new Error(`[better-sqlite3] Expected ARM64 architecture but got ${actualArch} at: ${binaryPath}`);
}
console.error(`Locale ${locale} was not found in the packaged app.`);
process.exit(1);
}
}
},
@ -299,20 +284,4 @@ function getExtraResourcesForPlatform() {
return resources;
}
function getELFArch(file: string) {
const buf = fs.readFileSync(file);
if (buf[0] !== 0x7f || buf[1] !== 0x45 || buf[2] !== 0x4c || buf[3] !== 0x46) {
throw new Error("Not an ELF file");
}
const eiClass = buf[4]; // 1=32-bit, 2=64-bit
const eiMachine = buf[18]; // architecture code
if (eiMachine === 0x3E) return 'x86-64';
if (eiMachine === 0xB7) return 'ARM64';
return 'other';
}
export default config;

View File

@ -7,7 +7,7 @@
"better-sqlite3": "12.5.0",
"mime-types": "3.0.2",
"sanitize-filename": "1.6.3",
"tsx": "4.21.0",
"tsx": "4.20.6",
"yargs": "18.0.0"
},
"devDependencies": {

View File

@ -43,7 +43,7 @@ test("User can change language from settings", async ({ page, context }) => {
// Check that the default value (English) is set.
await expect(app.currentNoteSplit).toContainText("First day of the week");
const languageCombobox = app.dropdown(app.currentNoteSplit.locator(".options-section .dropdown").first());
await expect(languageCombobox).toContainText("English (United States)");
await expect(languageCombobox).toContainText("English");
// Select Chinese and ensure the translation is set.
await languageCombobox.selectOptionByText("简体中文");
@ -53,8 +53,8 @@ test("User can change language from settings", async ({ page, context }) => {
await expect(languageCombobox).toContainText("简体中文");
// Select English again.
await languageCombobox.selectOptionByText("English (United States)");
await languageCombobox.selectOptionByText("English");
await app.currentNoteSplit.locator("button[name=restart-app-button]").click();
await expect(app.currentNoteSplit).toContainText("Language", { timeout: 15000 });
await expect(languageCombobox).toContainText("English (United States)");
await expect(languageCombobox).toContainText("English");
});

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@
<p>Most of the interaction with text notes is done via the built-in toolbars.
Depending on preference, there are two different layouts:</p>
<ul>
<li data-list-item-id="eafcb31c309cb140eedbb41048a0e0db1">The <em>Floating toolbar</em> is hidden by default and only appears when
<li>The <em>Floating toolbar</em> is hidden by default and only appears when
needed. In this mode there are actually two different toolbars:
<br>
<img src="1_Text_image.png" width="496"
@ -12,7 +12,7 @@
<img src="2_Text_image.png" width="812"
height="114">
</li>
<li data-list-item-id="e59aa3103fa4c5de33075e51f8d482164">A toolbar that appears when text is selected. This provides text-level
<li>A toolbar that appears when text is selected. This provides text-level
formatting such as bold, italic, text colors, inline code, etc.
<br><em><img src="Text_image.png" width="1109" height="124"></em>
</li>
@ -20,171 +20,167 @@
<p>Fore more information see&nbsp;<a class="reference-link" href="#root/_help_nRhnJkTT8cPs">Formatting toolbar</a>.</p>
<h2>Features and formatting</h2>
<p>Here's a list of various features supported by text notes:</p>
<figure
class="table">
<table>
<thead>
<tr>
<th>Dedicated article</th>
<th>Feature</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="reference-link" href="#root/_help_Gr6xFaF6ioJ5">General formatting</a>
</td>
<td>
<ul>
<li data-list-item-id="e04c84d59d44645ee89b2a8541ed99f90">Headings (section titles, paragraph)</li>
<li data-list-item-id="e39d25bd3d8bd06185b9d259e5827d451">Font size</li>
<li data-list-item-id="e1f7e2a2f4b03449d82bdf5b5c6ea8d44">Bold, italic, underline, strike-through</li>
<li data-list-item-id="e3decae72884f65b4d538151b6a297072">Superscript, subscript</li>
<li data-list-item-id="e59adf00fef65304c163ae190fac5e92a">Font color &amp; background color</li>
<li data-list-item-id="ed3f09156147a2769e91db111c76376e2">Remove formatting</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_S6Xx8QIWTV66">Lists</a>
</td>
<td>
<ul>
<li data-list-item-id="ee87806a913900d85d8f018af81f41df8">Bulleted lists</li>
<li data-list-item-id="e3ae314e365fa418ca6e0f061d63834c5">Numbered lists</li>
<li data-list-item-id="ee84e08694165f95430046cb34f4cd123">To-do lists</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_NwBbFdNZ9h7O">Block quotes &amp; admonitions</a>
</td>
<td>
<ul>
<li data-list-item-id="e2892dc35a0d4b7ad65daffb8f9404daa">Block quotes</li>
<li data-list-item-id="e7297e3ad1002f8de15aa0bd66c6f3f22">Admonitions</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_NdowYOC1GFKS">Tables</a>
</td>
<td>
<ul>
<li data-list-item-id="eb358a4567d93f66004f4195df2dda05a">Basic tables</li>
<li data-list-item-id="e6135a555d6c63c30e4b84806a4870830">Merging cells</li>
<li data-list-item-id="e29ac76563d0998b28fb1baf94dbdac8c">Styling tables and cells.</li>
<li data-list-item-id="e372446e81fdedada64b8bed89ca93d1a">Table captions</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_UYuUB1ZekNQU">Developer-specific formatting</a>
</td>
<td>
<ul>
<li data-list-item-id="eb260b76afcbc07bd9d4ceec4e000e8a0">Inline code</li>
<li data-list-item-id="e9864352286369ebe7b41c1599f498de8">Code blocks</li>
<li data-list-item-id="ee62fb9ed7f349178e8f2a2bd9ec8cd74">Keyboard shortcuts</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_AgjCISero73a">Footnotes</a>
</td>
<td>
<ul>
<li data-list-item-id="edf62ec004eff35cfcb7e361deef19aaf">Footnotes</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_mT0HEkOsz6i1">Images</a>
</td>
<td>
<ul>
<li data-list-item-id="ebe6277e643041403489c3ceb30c36f7f">Images</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_QEAPj01N5f7w">Links</a>
</td>
<td>
<ul>
<li data-list-item-id="e3f988be2f259bb40607cb61541955395">External links</li>
<li data-list-item-id="e3f91cc4f0cccd2c077cc306bacd68ef2">Internal Trilium links</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_nBAXQFj20hS1">Include Note</a>
</td>
<td>
<ul>
<li data-list-item-id="eac8015a64bce7b749cc67d1599062007">Include note</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_CohkqWQC1iBv">Insert buttons</a>
</td>
<td>
<ul>
<li data-list-item-id="e5cdf5d3885ec0ea67f924b4b8fe5c483">Symbols</li>
<li data-list-item-id="e95082e6642ed5b1eec6e4e116b899a40"><a class="reference-link" href="#root/_help_YfYAtQBcfo5V">Math Equations</a>
</li>
<li data-list-item-id="ecbef6a358a5b8d27f0d3e08bbc750aa9">Mermaid diagrams</li>
<li data-list-item-id="e6e97ee14dd29b7ccf53227107e5dc72d">Horizontal ruler</li>
<li data-list-item-id="e6198c7c535c249faec2e8906775f11de">Page break</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_dEHYtoWWi8ct">Other features</a>
</td>
<td>
<ul>
<li data-list-item-id="e0c14456cb83d483b07ea432ef9d4728e">Indentation
<ul>
<li data-list-item-id="e2029812c5e105c595590f70ee227631e">Markdown import</li>
</ul>
</li>
<li data-list-item-id="ea1ee012286e05190c89c9f4e64cf2036"><a class="reference-link" href="#root/_help_2x0ZAX9ePtzV">Cut to subnote</a>
</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_gLt3vA97tMcp">Premium features</a>
</td>
<td>
<ul>
<li data-list-item-id="e1ab173193a533ccf33dccfd0cb916f1f"><a class="reference-link" href="#root/_help_ZlN4nump6EbW">Slash Commands</a>
</li>
<li data-list-item-id="e564b978c09fe5adf476b331b1e0640e3"><a class="reference-link" href="#root/_help_KC1HB96bqqHX">Templates</a>
</li>
<li data-list-item-id="e756306c31d9beffbba3820b6d1b9bc61"><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/iPIMuisry3hd/gLt3vA97tMcp/_help_5wZallV2Qo1t">Format Painter</a>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
</figure>
<h2>Read-Only vs. Editing Mode</h2>
<p>Text notes are usually opened in edit mode. However, they may open in
read-only mode if the note is too big or the note is explicitly marked
as read-only. For more information, see&nbsp;<a class="reference-link"
href="#root/_help_CoFPLs3dRlXc">Read-Only Notes</a>.</p>
<h2>Keyboard shortcuts</h2>
<p>There are numerous keyboard shortcuts to format the text without having
to use the mouse. For a reference of all the key combinations, see&nbsp;
<a
class="reference-link" href="#root/_help_A9Oc6YKKc65v">Keyboard Shortcuts</a>. In addition, see&nbsp;<a class="reference-link"
href="#root/_help_QrtTYPmdd1qq">Markdown-like formatting</a>&nbsp;as an alternative
to the keyboard shortcuts.</p>
<h2>Technical details</h2>
<p>For the text editing functionality, Trilium uses a commercial product
(with an open-source base) called&nbsp;<a class="reference-link" href="#root/_help_MI26XDLSAlCD">CKEditor</a>.
This brings the benefit of having a powerful WYSIWYG (What You See Is What
You Get) editor.</p>
<table>
<thead>
<tr>
<th>Dedicated article</th>
<th>Feature</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="reference-link" href="#root/_help_Gr6xFaF6ioJ5">General formatting</a>
</td>
<td>
<ul>
<li>Headings (section titles, paragraph)</li>
<li>Font size</li>
<li>Bold, italic, underline, strike-through</li>
<li>Superscript, subscript</li>
<li>Font color &amp; background color</li>
<li>Remove formatting</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_S6Xx8QIWTV66">Lists</a>
</td>
<td>
<ul>
<li>Bulleted lists</li>
<li>Numbered lists</li>
<li>To-do lists</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_NwBbFdNZ9h7O">Block quotes &amp; admonitions</a>
</td>
<td>
<ul>
<li>Block quotes</li>
<li>Admonitions</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_NdowYOC1GFKS">Tables</a>
</td>
<td>
<ul>
<li>Basic tables</li>
<li>Merging cells</li>
<li>Styling tables and cells.</li>
<li>Table captions</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_UYuUB1ZekNQU">Developer-specific formatting</a>
</td>
<td>
<ul>
<li>Inline code</li>
<li>Code blocks</li>
<li>Keyboard shortcuts</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_AgjCISero73a">Footnotes</a>
</td>
<td>
<ul>
<li>Footnotes</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_mT0HEkOsz6i1">Images</a>
</td>
<td>
<ul>
<li>Images</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_QEAPj01N5f7w">Links</a>
</td>
<td>
<ul>
<li>External links</li>
<li>Internal Trilium links</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_nBAXQFj20hS1">Include Note</a>
</td>
<td>
<ul>
<li>Include note</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_CohkqWQC1iBv">Insert buttons</a>
</td>
<td>
<ul>
<li>Symbols</li>
<li><a class="reference-link" href="#root/_help_YfYAtQBcfo5V">Math Equations</a>
</li>
<li>Mermaid diagrams</li>
<li>Horizontal ruler</li>
<li>Page break</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_dEHYtoWWi8ct">Other features</a>
</td>
<td>
<ul>
<li>Indentation
<ul>
<li>Markdown import</li>
</ul>
</li>
<li><a class="reference-link" href="#root/_help_2x0ZAX9ePtzV">Cut to subnote</a>
</li>
</ul>
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/_help_gLt3vA97tMcp">Premium features</a>
</td>
<td>
<ul>
<li><a class="reference-link" href="#root/_help_ZlN4nump6EbW">Slash Commands</a>
</li>
<li><a class="reference-link" href="#root/_help_KC1HB96bqqHX">Templates</a>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
<h2>Read-Only vs. Editing Mode</h2>
<p>Text notes are usually opened in edit mode. However, they may open in
read-only mode if the note is too big or the note is explicitly marked
as read-only. For more information, see&nbsp;<a class="reference-link"
href="#root/_help_CoFPLs3dRlXc">Read-Only Notes</a>.</p>
<h2>Keyboard shortcuts</h2>
<p>There are numerous keyboard shortcuts to format the text without having
to use the mouse. For a reference of all the key combinations, see&nbsp;
<a
class="reference-link" href="#root/_help_A9Oc6YKKc65v">Keyboard Shortcuts</a>. In addition, see&nbsp;<a class="reference-link"
href="#root/_help_QrtTYPmdd1qq">Markdown-like formatting</a>&nbsp;as an alternative
to the keyboard shortcuts.</p>
<h2>Technical details</h2>
<p>For the text editing functionality, Trilium uses a commercial product
(with an open-source base) called&nbsp;<a class="reference-link" href="#root/_help_MI26XDLSAlCD">CKEditor</a>.
This brings the benefit of having a powerful WYSIWYG (What You See Is What
You Get) editor.</p>

View File

@ -12,11 +12,11 @@
<p>Apart from using the UI, it is also possible to quickly insert headings
using the Markdown-like shortcuts:</p>
<ul>
<li data-list-item-id="e6083df2814e520e138326ef004812a46"><code>##</code> for Heading 2</li>
<li data-list-item-id="e8b8acfd06c340271cc4fe84f65e67375"><code>###</code> for Heading 3</li>
<li data-list-item-id="e19e95a52ddbcd54428ed5ab40df165a7"><code>####</code> for Heading 4</li>
<li data-list-item-id="e69788e0bd8f4459748b8df997a19fa92"><code>#####</code> for Heading 5</li>
<li data-list-item-id="eb7205b764231a314c9e9c1590c12ac1c"><code>######</code> for Heading 6</li>
<li><code>##</code> for Heading 2</li>
<li><code>###</code> for Heading 3</li>
<li><code>####</code> for Heading 4</li>
<li><code>#####</code> for Heading 5</li>
<li><code>######</code> for Heading 6</li>
</ul>
<h2>Font size</h2>
<figure class="image image-style-align-right">
@ -44,17 +44,17 @@
<p>This formatting can be easily removed using the <em>Remove formatting</em> item.</p>
<p>The following keyboard shortcuts can be used here:</p>
<ul>
<li data-list-item-id="ecda6994b8be7fe33daeccbeb8bffe20b"><kbd>Ctrl</kbd>+<kbd>B</kbd> for bold</li>
<li data-list-item-id="eaa20ab7965945937bd10a273e5fc323f"><kbd>Ctrl</kbd>+<kbd>I</kbd> for italic</li>
<li data-list-item-id="e86881b33671d3bd6930d361e4bb76767"><kbd>Ctrl</kbd>+<kbd>U</kbd> for underline</li>
<li><kbd>Ctrl</kbd>+<kbd>B</kbd> for bold</li>
<li><kbd>Ctrl</kbd>+<kbd>I</kbd> for italic</li>
<li><kbd>Ctrl</kbd>+<kbd>U</kbd> for underline</li>
</ul>
<p>Alternatively, Markdown-like formatting can be used:</p>
<ul>
<li data-list-item-id="e90b0f040ab78084c41cd8f44045528ec"><strong>Bold</strong>: Type <code>**text**</code> or <code>__text__</code>
<li><strong>Bold</strong>: Type <code>**text**</code> or <code>__text__</code>
</li>
<li data-list-item-id="eebc210ee7f2b92e0885cd411c6fb8b80"><em>Italic</em>: Type <code>*text*</code> or <code>_text_</code>
<li><em>Italic</em>: Type <code>*text*</code> or <code>_text_</code>
</li>
<li data-list-item-id="eb7628d2cb441576b3b3edf6c42ab84b4"><del>Strikethrough</del>: Type <code>~~text~~</code>
<li><del>Strikethrough</del>: Type <code>~~text~~</code>
</li>
</ul>
<h2>Superscript, subscript</h2>
@ -89,11 +89,6 @@
be manually changed back to a paragraph according to the <em>Headings</em> section.</p>
<p>When pasting content that comes with undesired formatting, an alternative
to pasting and then removing formatting is pasting as plain text via <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>V</kbd>.</p>
<h2>Format painter</h2>
<p>The&nbsp;<a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/iPIMuisry3hd/gLt3vA97tMcp/_help_5wZallV2Qo1t">Format Painter</a>&nbsp;allows
users to copy the formatting of text (such as bold, italic, Strikethrough,
etc.) and apply it to other parts of the document. It helps maintain consistent
formatting and accelerates the creation of rich content.</p>
<h2>Support for Markdown</h2>
<p>When exported to&nbsp;<a class="reference-link" href="#root/_help_Oau6X9rCuegd">Markdown</a>,
most of the general formatting is maintained such as headings, bold, italic,

View File

@ -1,45 +0,0 @@
<figure class="image image-style-align-right">
<img style="aspect-ratio:220/76;" src="Format Painter_image.png"
width="220" height="76">
</figure>
<aside class="admonition note">
<p>This is a premium feature of the editor we are using (CKEditor) and we
benefit from it thanks to an written agreement with the team. See &nbsp;
<a
class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/iPIMuisry3hd/_help_gLt3vA97tMcp">Premium features</a>&nbsp;for more information.</p>
</aside>
<p>The Format Painter is a feature in text notes that allows users to copy
the formatting of text (such as <strong>bold</strong>, <em>italic</em>, <del>Strikethrough</del>,
etc.) and apply it to other parts of the document. It helps maintain consistent
formatting and accelerates the creation of rich content.</p>
<h2>Usage Instructions</h2>
<p>Click the text that you want to copy the formatting from and use the paint
formatting toolbar button (<span><img class="image_resized" style="aspect-ratio:150/150;width:2.7%;" src="Format Painter_746436a2e1.svg" alt="Format painter" width="150" height="150">) </span>to
copy the style. Then select the target text with your mouse to apply the
formatting.</p>
<ul>
<li data-list-item-id="e9a728e8f49fb3ecf1202002dfafccabd"><strong>To copy the formatting</strong>: Place the cursor inside a text
with some formatting and click the paint formatting toolbar button. Notice
that the mouse cursor changes to the <span><img class="image_resized" style="aspect-ratio:30/20;width:3.64%;" src="Format Painter_e144e96df9.svg" alt="Format painter text cursor" width="30" height="20"></span>.</li>
<li
data-list-item-id="e745c039a3502d4e979d6dcde7876461b"><strong>To paint with the copied formatting</strong>: Click any word in
the document and the new formatting will be applied. Alternatively, instead
of clicking a single word, you can select a text fragment (like an entire
paragraph). Notice that the cursor will go back to the default one after
the formatting is applied.</li>
<li data-list-item-id="e49e547cfd4e4cbb45712bace9a6e0979"><strong>To keep painting using the same formatting</strong>: Open the
toolbar dropdown and enable the continuous painting mode. Once copied,
the same formatting can be applied multiple times in different places until
the paint formatting button is clicked (the cursor will then revert to
the regular one).</li>
</ul>
<h2>Limitations</h2>
<ol>
<li data-list-item-id="ea3e6a7c317b51341c7a83cee5387ac1e">Painting with block-level formatting (like headings or image styles) is
not supported yet. This is because, in&nbsp;<a class="reference-link" href="#root/pOsGYCXsbNQG/tC7s2alapj8V/1YeN2MzFUluU/_help_MI26XDLSAlCD">CKEditor</a>,
they are considered a part of the content rather than text formatting.</li>
<li
data-list-item-id="edbd74adb8916daaae6024d8b0ae80e32">When applying formatting to words, spaces or other Western punctuation
are used as word boundaries, which prevents proper handling of languages
that do not use space-based word segmentation.</li>
</ol>

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M3 3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1z"/><path d="M16 3.25a1.5 1.5 0 0 1 1.5 1.5v1.7a2.25 2.25 0 0 1-1.932 2.226l-4.424.632a.75.75 0 0 0-.644.743V11a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-5a1 1 0 0 1 1-1v-.95a2.25 2.25 0 0 1 1.932-2.226l4.424-.632A.75.75 0 0 0 16 6.449z"/></svg>

Before

Width:  |  Height:  |  Size: 386 B

View File

@ -1,7 +0,0 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 31 20" width="30" height="20">
<path d="M14 3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H15a1 1 0 0 1-1-1V3Z" fill="#000"/>
<path d="M27 3.25a1.5 1.5 0 0 1 1.5 1.5v1.7a2.25 2.25 0 0 1-1.932 2.226l-4.424.632a.75.75 0 0 0-.644.743V11a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H20a1 1 0 0 1-1-1v-5a1 1 0 0 1 1-1v-.95a2.25 2.25 0 0 1 1.932-2.226l4.424-.632A.75.75 0 0 0 27 6.449V3.25Z" fill="#000"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.855 2.25H27a2.5 2.5 0 0 1 2.5 2.5v1.7a3.25 3.25 0 0 1-2.79 3.216l-4.21.602a2 2 0 0 1 1 1.732v5a2 2 0 0 1-2 2H20a2 2 0 0 1-2-2v-5a2 2 0 0 1 1-1.732v-.217A3.25 3.25 0 0 1 21.129 7H15a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h10a2 2 0 0 1 1.855 1.25ZM20 10.05V11a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1h1.5a1 1 0 0 0 1-1v-5a1 1 0 0 0-1-1v-.95c0-.016 0-.033.002-.05a.75.75 0 0 1 .642-.692l4.424-.632A2.25 2.25 0 0 0 28.5 6.45V4.75a1.496 1.496 0 0 0-1.5-1.5v3.2a.75.75 0 0 1-.644.742l-4.424.632A2.25 2.25 0 0 0 20 10.05ZM15 2a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H15Z" fill="#fff"/>
<path d="M2.5 2.5A.5.5 0 0 1 3 2h2.5a.5.5 0 0 1 .354.146l.646.647.646-.647A.5.5 0 0 1 7.5 2H10a.5.5 0 0 1 0 1H7.707L7 3.707V10h.5a.5.5 0 0 1 0 1H7v4.793l.707.707H10a.5.5 0 0 1 0 1H7.5a.5.5 0 0 1-.354-.146l-.646-.647-.646.647a.5.5 0 0 1-.354.146H3a.5.5 0 0 1 0-1h2.293L6 15.793V11h-.5a.5.5 0 0 1 0-1H6V3.707L5.293 3H3a.5.5 0 0 1-.5-.5Z" fill="#000"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m5.793 3.5-.5-.5H3a.5.5 0 0 1 0-1h2.5a.5.5 0 0 1 .354.146l.145.146.501.5.646-.646A.5.5 0 0 1 7.5 2H10a.5.5 0 0 1 0 1H7.707L7 3.707V10h.5a.5.5 0 0 1 0 1H7v4.793l.707.707H10a.5.5 0 0 1 0 1H7.5a.5.5 0 0 1-.354-.146l-.646-.647-.5.5-.146.147a.5.5 0 0 1-.354.146H3a.5.5 0 0 1 0-1h2.293L6 15.793V11h-.5a.5.5 0 0 1 0-1H6V3.707L5.793 3.5Zm-.914.5L5 4.121v4.964a1.5 1.5 0 0 0 0 2.83v3.464l-.121.121H3a1.5 1.5 0 0 0 0 3h2.5a1.5 1.5 0 0 0 1-.382 1.5 1.5 0 0 0 1 .382H10a1.5 1.5 0 0 0 0-3H8.121L8 15.379v-3.464a1.5 1.5 0 0 0 0-2.83V4.121L8.121 4H10a1.5 1.5 0 0 0 0-3H7.5a1.5 1.5 0 0 0-1 .382A1.5 1.5 0 0 0 5.5 1H3a1.5 1.5 0 1 0 0 3h1.879Z" fill="#fff"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -80,6 +80,7 @@ const ALLOWED_OPTIONS = new Set<OptionNames>([
"disableTray",
"customSearchEngineName",
"customSearchEngineUrl",
"promotedAttributesOpenInRibbon",
"editedNotesOpenInRibbon",
"locale",
"formattingLocale",

View File

@ -7,13 +7,11 @@ import hidden_subtree from "./hidden_subtree.js";
import { LOCALES, type Locale, type LOCALE_IDS } from "@triliumnext/commons";
import dayjs, { Dayjs } from "dayjs";
// When adding a new locale, prefer the version with hyphen instead of underscore.
export const DAYJS_LOADER: Record<LOCALE_IDS, () => Promise<typeof import("dayjs/locale/en.js")>> = {
"ar": () => import("dayjs/locale/ar.js"),
"cn": () => import("dayjs/locale/zh-cn.js"),
"de": () => import("dayjs/locale/de.js"),
"en": () => import("dayjs/locale/en.js"),
"en-GB": () => import("dayjs/locale/en-gb.js"),
"en_rtl": () => import("dayjs/locale/en.js"),
"es": () => import("dayjs/locale/es.js"),
"fa": () => import("dayjs/locale/fa.js"),

View File

@ -129,6 +129,7 @@ const defaultOptions: DefaultOption[] = [
{ name: "logRetentionDays", value: "90", isSynced: false }, // default 90 days
{ name: "customSearchEngineName", value: "DuckDuckGo", isSynced: true },
{ name: "customSearchEngineUrl", value: "https://duckduckgo.com/?q={keyword}", isSynced: true },
{ name: "promotedAttributesOpenInRibbon", value: "true", isSynced: true },
{ name: "editedNotesOpenInRibbon", value: "true", isSynced: true },
{ name: "mfaEnabled", value: "false", isSynced: false },
{ name: "mfaMethod", value: "totp", isSynced: false },

View File

@ -21,7 +21,7 @@
"note_structure_description": "Notizen lassen sich hierarchisch anordnen. Ordner sind nicht nötig, da jede Notiz Unternotizen enthalten kann. Eine einzelne Notiz kann an mehreren Stellen in der Hierarchie hinzugefügt werden.",
"hoisting_description": "Trennen Sie Ihre persönlichen und beruflichen Notizen ganz einfach, indem Sie sie in einem Arbeitsbereich gruppieren. Dadurch wird Ihre Notizstruktur so fokussiert, dass nur ein bestimmter Satz von Notizen angezeigt wird.",
"hoisting_title": "Arbeitsbereiche und Fokusansicht",
"attributes_description": "Verwenden Sie Beziehungen zwischen Notizen oder fügen Sie Beschriftungen hinzu, um die Kategorisierung zu vereinfachen. Verwenden Sie hervorgehobene Attribute, um strukturierte Informationen einzugeben, die in Tabellen und Boards verwendet werden können."
"attributes_description": "Nutzen Sie Verbindungen zwischen Notizen oder fügen Sie Labels hinzu, um die Kategorisierung zu erleichtern. Mit hervorgehobenen („promoted“) Attributen können Sie strukturierte Informationen erfassen, die sich direkt in Tabellen und Boards verwenden lassen."
},
"productivity_benefits": {
"revisions_title": "Notizrevisionen",

View File

@ -87,8 +87,6 @@
"description_arm64": "ARM 기반 리눅스 배포판에서 aarch64 아키텍처와 호환됩니다."
},
"note_types": {
"text_title": "텍스트 노트",
"text_description": "노트는 WYSIWYG 편집기를 사용하며 표, 이미지, 수학 표현식, 구문 강조 기능의 코드 블록을 지원합니다. 특수문자를 사용한 마크다운 유사 구문이나 슬래시(/) 명령으로 텍스트 서식을 빠르게 지정할 수 있습니다.",
"code_title": "코드 노트"
"text_title": "텍스트 노트"
}
}

332
docs/README-en_GB.md vendored
View File

@ -1,332 +0,0 @@
<div align="center">
<sup>Special thanks to:</sup><br />
<a href="https://go.warp.dev/Trilium" target="_blank">
<img alt="Warp sponsorship" width="400" src="https://github.com/warpdotdev/brand-assets/blob/main/Github/Sponsor/Warp-Github-LG-03.png"><br />
Warp, built for coding with multiple AI agents<br />
</a>
<sup>Available for macOS, Linux and Windows</sup>
</div>
<hr />
# Trilium Notes
![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran)
![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\
![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium)
![GitHub Downloads (all assets, all
releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\
[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp)
[![Translation
status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/)
[English](./README.md) | [Chinese (Simplified)](./docs/README-ZH_CN.md) |
[Chinese (Traditional)](./docs/README-ZH_TW.md) | [Russian](./docs/README-ru.md)
| [Japanese](./docs/README-ja.md) | [Italian](./docs/README-it.md) |
[Spanish](./docs/README-es.md)
Trilium Notes is a free and open-source, cross-platform hierarchical note taking
application with focus on building large personal knowledge bases.
See [screenshots](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) for
quick overview:
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="./docs/app.png" alt="Trilium Screenshot" width="1000"></a>
## ⏬ Download
- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest)
stable version, recommended for most users.
- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly)
unstable development version, updated daily with the latest features and
fixes.
## 📚 Documentation
**Visit our comprehensive documentation at
[docs.triliumnotes.org](https://docs.triliumnotes.org/)**
Our documentation is available in multiple formats:
- **Online Documentation**: Browse the full documentation at
[docs.triliumnotes.org](https://docs.triliumnotes.org/)
- **In-App Help**: Press `F1` within Trilium to access the same documentation
directly in the application
- **GitHub**: Navigate through the [User
Guide](./docs/User%20Guide/User%20Guide/) in this repository
### Quick Links
- [Getting Started Guide](https://docs.triliumnotes.org/)
- [Installation
Instructions](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation.md)
- [Docker
Setup](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation/1.%20Installing%20the%20server/Using%20Docker.md)
- [Upgrading
TriliumNext](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Upgrading%20TriliumNext.md)
- [Basic Concepts and
Features](./docs/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes.md)
- [Patterns of Personal Knowledge
Base](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge)
## 🎁 Features
* Notes can be arranged into arbitrarily deep tree. Single note can be placed
into multiple places in the tree (see
[cloning](https://triliumnext.github.io/Docs/Wiki/cloning-notes))
* Rich WYSIWYG note editor including e.g. tables, images and
[math](https://triliumnext.github.io/Docs/Wiki/text-notes) with markdown
[autoformat](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)
* Support for editing [notes with source
code](https://triliumnext.github.io/Docs/Wiki/code-notes), including syntax
highlighting
* Fast and easy [navigation between
notes](https://triliumnext.github.io/Docs/Wiki/note-navigation), full text
search and [note
hoisting](https://triliumnext.github.io/Docs/Wiki/note-hoisting)
* Seamless [note
versioning](https://triliumnext.github.io/Docs/Wiki/note-revisions)
* Note [attributes](https://triliumnext.github.io/Docs/Wiki/attributes) can be
used for note organization, querying and advanced
[scripting](https://triliumnext.github.io/Docs/Wiki/scripts)
* UI available in English, German, Spanish, French, Romanian, and Chinese
(simplified and traditional)
* Direct [OpenID and TOTP
integration](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/Multi-Factor%20Authentication.md)
for more secure login
* [Synchronization](https://triliumnext.github.io/Docs/Wiki/synchronization)
with self-hosted sync server
* there's a [3rd party service for hosting synchronisation
server](https://trilium.cc/paid-hosting)
* [Sharing](https://triliumnext.github.io/Docs/Wiki/sharing) (publishing) notes
to public internet
* Strong [note
encryption](https://triliumnext.github.io/Docs/Wiki/protected-notes) with
per-note granularity
* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type
"canvas")
* [Relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map) and
[link maps](https://triliumnext.github.io/Docs/Wiki/link-map) for visualizing
notes and their relations
* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/)
* [Geo maps](./docs/User%20Guide/User%20Guide/Note%20Types/Geo%20Map.md) with
location pins and GPX tracks
* [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - see [Advanced
showcases](https://triliumnext.github.io/Docs/Wiki/advanced-showcases)
* [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) for automation
* Scales well in both usability and performance upwards of 100 000 notes
* Touch optimized [mobile
frontend](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) for
smartphones and tablets
* Built-in [dark theme](https://triliumnext.github.io/Docs/Wiki/themes), support
for user themes
* [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) and
[Markdown import & export](https://triliumnext.github.io/Docs/Wiki/markdown)
* [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) for easy
saving of web content
* Customizable UI (sidebar buttons, user-defined widgets, ...)
* [Metrics](./docs/User%20Guide/User%20Guide/Advanced%20Usage/Metrics.md), along
with a [Grafana
Dashboard](./docs/User%20Guide/User%20Guide/Advanced%20Usage/Metrics/grafana-dashboard.json)
✨ Check out the following third-party resources/communities for more TriliumNext
related goodies:
- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party
themes, scripts, plugins and more.
- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more.
## ❓Why TriliumNext?
The original Trilium developer ([Zadam](https://github.com/zadam)) has
graciously given the Trilium repository to the community project which resides
at https://github.com/TriliumNext
### ⬆Migrating from Zadam/Trilium?
There are no special migration steps to migrate from a zadam/Trilium instance to
a TriliumNext/Trilium instance. Simply [install
TriliumNext/Trilium](#-installation) as usual and it will use your existing
database.
Versions up to and including
[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are
compatible with the latest zadam/trilium version of
[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later
versions of TriliumNext/Trilium have their sync versions incremented which
prevents direct migration.
## 💬 Discuss with us
Feel free to join our official conversations. We would love to hear what
features, suggestions, or issues you may have!
- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous
discussions.)
- The `General` Matrix room is also bridged to
[XMPP](xmpp:discuss@trilium.thisgreat.party?join)
- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For
asynchronous discussions.)
- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug
reports and feature requests.)
## 🏗 Installation
### Windows / MacOS
Download the binary release for your platform from the [latest release
page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package
and run the `trilium` executable.
### Linux
If your distribution is listed in the table below, use your distribution's
package.
[![Packaging
status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions)
You may also download the binary release for your platform from the [latest
release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the
package and run the `trilium` executable.
TriliumNext is also provided as a Flatpak, but not yet published on FlatHub.
### Browser (any OS)
If you use a server installation (see below), you can directly access the web
interface (which is almost identical to the desktop app).
Currently only the latest versions of Chrome & Firefox are supported (and
tested).
### Mobile
To use TriliumNext on a mobile device, you can use a mobile web browser to
access the mobile interface of a server installation (see below).
See issue https://github.com/TriliumNext/Trilium/issues/4962 for more
information on mobile app support.
If you prefer a native Android app, you can use
[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid).
Report bugs and missing features at [their
repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to
disable automatic updates on your server installation (see below) when using
TriliumDroid since the sync version must match between Trilium and TriliumDroid.
### Server
To install TriliumNext on your own server (including via Docker from
[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server
installation docs](https://triliumnext.github.io/Docs/Wiki/server-installation).
## 💻 Contribute
### Translations
If you are a native speaker, help us translate Trilium by heading over to our
[Weblate page](https://hosted.weblate.org/engage/trilium/).
Here's the language coverage we have so far:
[![Translation
status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/)
### Code
Download the repository, install dependencies using `pnpm` and then run the
server (available at http://localhost:8080):
```shell
git clone https://github.com/TriliumNext/Trilium.git
cd Trilium
pnpm install
pnpm run server:start
```
### Documentation
Download the repository, install dependencies using `pnpm` and then run the
environment required to edit the documentation:
```shell
git clone https://github.com/TriliumNext/Trilium.git
cd Trilium
pnpm install
pnpm edit-docs:edit-docs
```
### Building the Executable
Download the repository, install dependencies using `pnpm` and then build the
desktop app for Windows:
```shell
git clone https://github.com/TriliumNext/Trilium.git
cd Trilium
pnpm install
pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32
```
For more details, see the [development
docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide).
### Developer Documentation
Please view the [documentation
guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md)
for details. If you have more questions, feel free to reach out via the links
described in the "Discuss with us" section above.
## 👏 Shoutouts
* [zadam](https://github.com/zadam) for the original concept and implementation
of the application.
* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the
application icon.
* [nriver](https://github.com/nriver) for his work on internationalisation.
* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas.
* [antoniotejada](https://github.com/nriver) for the original syntax highlight
widget.
* [Dosu](https://dosu.dev/) for providing us with the automated responses to
GitHub issues and discussions.
* [Tabler Icons](https://tabler.io/icons) for the system tray icons.
Trilium would not be possible without the technologies behind it:
* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind
text notes. We are grateful for being offered a set of the premium features.
* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with
support for huge amount of languages.
* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite
whiteboard used in Canvas notes.
* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the
mind map functionality.
* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical
maps.
* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive
table used in collections.
* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library
without real competition.
* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library.
Used in [relation
maps](https://triliumnext.github.io/Docs/Wiki/relation-map.html) and [link
maps](https://triliumnext.github.io/Docs/Wiki/note-map.html#link-map)
## 🤝 Support
Trilium is built and maintained with [hundreds of hours of
work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your
support keeps it open-source, improves features, and covers costs such as
hosting.
Consider supporting the main developer
([eliandoran](https://github.com/eliandoran)) of the application via:
- [GitHub Sponsors](https://github.com/sponsors/eliandoran)
- [PayPal](https://paypal.me/eliandoran)
- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran)
## 🔑 License
Copyright 2017-2025 zadam, Elian Doran, and other contributors
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option) any
later version.

55
docs/README-fa.md vendored
View File

@ -33,39 +33,50 @@ quick overview:
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="./docs/app.png" alt="Trilium Screenshot" width="1000"></a>
## ⏬ دانلود
- [آخرین انتشار]{1} نسخه پایدار، برای بیشتر کاربران پیشنهاد می‌شود.
## ⏬ Download
- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest)
stable version, recommended for most users.
- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly)
unstable development version, updated daily with the latest features and
fixes.
## 📚 کتابچه راهنما
## 📚 Documentation
**Visit our comprehensive documentation at
[docs.triliumnotes.org](https://docs.triliumnotes.org/)**
مستندات ما در چندین قالب مختلف در دسترس است:
- مستندات آنلاین: می‌توانید نسخهٔ کامل مستندات را در
[docs.triliumnotes.org](https://docs.triliumnotes.org/) مرور کنید
- ** In-App Help **: Press `F1 ` در Trilium برای دسترسی به همان اسناد به طور
مستقیم در برنامه
- ** GitHub **: از طریق [راهنمای کاربر] در این مخزن حرکت کنید
Our documentation is available in multiple formats:
- **Online Documentation**: Browse the full documentation at
[docs.triliumnotes.org](https://docs.triliumnotes.org/)
- **In-App Help**: Press `F1` within Trilium to access the same documentation
directly in the application
- **GitHub**: Navigate through the [User
Guide](./docs/User%20Guide/User%20Guide/) in this repository
### لینک‌های سریع
- راهنمای شروع کار
- دستورالعمل‌های نصب
- راه‌اندازی داکر
- ارتقای TriliumNext
- مفاهیم و ویژگی‌های پایه
- الگوهای پایگاه دانشی شخصی
### Quick Links
- [Getting Started Guide](https://docs.triliumnotes.org/)
- [Installation
Instructions](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation.md)
- [Docker
Setup](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation/1.%20Installing%20the%20server/Using%20Docker.md)
- [Upgrading
TriliumNext](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Upgrading%20TriliumNext.md)
- [Basic Concepts and
Features](./docs/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes.md)
- [Patterns of Personal Knowledge
Base](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge)
## 🎁 ویژگی‌ها
## 🎁 Features
* یادداشت‌ها می‌توانند در یک درخت با عمق دلخواه سازمان‌دهی شوند. یک یادداشت
می‌تواند در چندین نقطهٔ مختلف از درخت قرار گیرد.
* ویرایشگر یادداشت غنی WYSIWYG از جمله جداول، تصاویر و [math] [1] با علامت گذاری
[autoformat] [2]
* پشتیبانی از ویرایش [یادداشت با کد منبع][۱]، از جمله نحو برجسته
* Notes can be arranged into arbitrarily deep tree. Single note can be placed
into multiple places in the tree (see
[cloning](https://triliumnext.github.io/Docs/Wiki/cloning-notes))
* Rich WYSIWYG note editor including e.g. tables, images and
[math](https://triliumnext.github.io/Docs/Wiki/text-notes) with markdown
[autoformat](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)
* Support for editing [notes with source
code](https://triliumnext.github.io/Docs/Wiki/code-notes), including syntax
highlighting
* Fast and easy [navigation between
notes](https://triliumnext.github.io/Docs/Wiki/note-navigation), full text
search and [note

View File

@ -2380,20 +2380,6 @@
"isInheritable": false,
"position": 20
},
{
"type": "relation",
"name": "internalLink",
"value": "IakOLONlIfGI",
"isInheritable": false,
"position": 30
},
{
"type": "relation",
"name": "internalLink",
"value": "yTjUdsOi4CIE",
"isInheritable": false,
"position": 40
},
{
"type": "label",
"name": "iconClass",
@ -2407,6 +2393,20 @@
"value": "keyboard-shortcuts",
"isInheritable": false,
"position": 40
},
{
"type": "relation",
"name": "internalLink",
"value": "IakOLONlIfGI",
"isInheritable": false,
"position": 50
},
{
"type": "relation",
"name": "internalLink",
"value": "yTjUdsOi4CIE",
"isInheritable": false,
"position": 60
}
],
"format": "markdown",
@ -5207,58 +5207,44 @@
{
"type": "relation",
"name": "internalLink",
"value": "DvdZhoQZY9Yd",
"value": "MMiBEQljMQh2",
"isInheritable": false,
"position": 10
},
{
"type": "relation",
"name": "internalLink",
"value": "MMiBEQljMQh2",
"value": "zEY4DaJG4YT5",
"isInheritable": false,
"position": 20
},
{
"type": "relation",
"name": "internalLink",
"value": "zEY4DaJG4YT5",
"isInheritable": false,
"position": 30
},
{
"type": "relation",
"name": "internalLink",
"value": "TBwsyfadTA18",
"value": "iPIMuisry3hd",
"isInheritable": false,
"position": 40
},
{
"type": "relation",
"name": "internalLink",
"value": "iPIMuisry3hd",
"value": "oiVPnW8QfnvS",
"isInheritable": false,
"position": 50
},
{
"type": "relation",
"name": "internalLink",
"value": "oiVPnW8QfnvS",
"value": "QrtTYPmdd1qq",
"isInheritable": false,
"position": 60
},
{
"type": "relation",
"name": "internalLink",
"value": "QrtTYPmdd1qq",
"isInheritable": false,
"position": 70
},
{
"type": "relation",
"name": "internalLink",
"value": "eIg8jdvaoNNd",
"isInheritable": false,
"position": 80
"position": 70
},
{
"type": "label",
@ -5273,6 +5259,20 @@
"value": "bx bxs-keyboard",
"isInheritable": false,
"position": 80
},
{
"type": "relation",
"name": "internalLink",
"value": "DvdZhoQZY9Yd",
"isInheritable": false,
"position": 90
},
{
"type": "relation",
"name": "internalLink",
"value": "TBwsyfadTA18",
"isInheritable": false,
"position": 100
}
],
"format": "markdown",
@ -6244,13 +6244,6 @@
"value": "",
"isInheritable": false,
"position": 40
},
{
"type": "relation",
"name": "internalLink",
"value": "5wZallV2Qo1t",
"isInheritable": false,
"position": 220
}
],
"format": "markdown",
@ -6921,13 +6914,6 @@
"value": "general-formatting",
"isInheritable": false,
"position": 60
},
{
"type": "relation",
"name": "internalLink",
"value": "5wZallV2Qo1t",
"isInheritable": false,
"position": 70
}
],
"format": "markdown",
@ -8437,81 +8423,6 @@
"dataFileName": "1_Text Snippets_image.png"
}
]
},
{
"isClone": false,
"noteId": "5wZallV2Qo1t",
"notePath": [
"pOsGYCXsbNQG",
"KSZ04uQ2D1St",
"iPIMuisry3hd",
"gLt3vA97tMcp",
"5wZallV2Qo1t"
],
"title": "Format Painter",
"notePosition": 30,
"prefix": null,
"isExpanded": false,
"type": "text",
"mime": "text/html",
"attributes": [
{
"type": "relation",
"name": "internalLink",
"value": "gLt3vA97tMcp",
"isInheritable": false,
"position": 30
},
{
"type": "relation",
"name": "internalLink",
"value": "MI26XDLSAlCD",
"isInheritable": false,
"position": 40
},
{
"type": "label",
"name": "shareAlias",
"value": "format-painter",
"isInheritable": false,
"position": 50
},
{
"type": "label",
"name": "iconClass",
"value": "bx bxs-paint-roll",
"isInheritable": false,
"position": 60
}
],
"format": "markdown",
"dataFileName": "Format Painter.md",
"attachments": [
{
"attachmentId": "OY9JmG8zdGm5",
"title": "image.png",
"role": "image",
"mime": "image/png",
"position": 10,
"dataFileName": "Format Painter_image.png"
},
{
"attachmentId": "qEJy5SJMsPUh",
"title": "e144e96df9.svg",
"role": "image",
"mime": "image/svg+xml",
"position": 10,
"dataFileName": "Format Painter_e144e96df9.svg"
},
{
"attachmentId": "vZqf8QJ80XRF",
"title": "746436a2e1.svg",
"role": "image",
"mime": "image/svg+xml",
"position": 10,
"dataFileName": "Format Painter_746436a2e1.svg"
}
]
}
]
},

View File

@ -63,7 +63,7 @@ For each note of the calendar, the following attributes can be used:
| `#startTime` | The time the event starts at. If this value is missing, then the event is considered a full-day event. The format is `HH:MM` (hours in 24-hour format and minutes). |
| `#endTime` | Similar to `startTime`, it mentions the time at which the event ends (in relation with `endDate` if present, or `startDate`). |
| `#color` | Displays the event with a specified color (named such as `red`, `gray` or hex such as `#FF0000`). This will also change the color of the note in other places such as the note tree. |
| `#calendar:color` | Similar to `#color`, but applies the color only for the event in the calendar and not for other places such as the note tree. (*Deprecated*) |
| `#calendar:color` | Similar to `#color`, but applies the color only for the event in the calendar and not for other places such as the note tree. |
| `#iconClass` | If present, the icon of the note will be displayed to the left of the event title. |
| `#calendar:title` | Changes the title of an event to point to an attribute of the note other than the title, can either a label or a relation (without the `#` or `~` symbol). See _Use-cases_ for more information. |
| `#calendar:displayedAttributes` | Allows displaying the value of one or more attributes in the calendar like this:     <br> <br>![](9_Calendar_image.png)    <br> <br>`#weight="70" #Mood="Good" #calendar:displayedAttributes="weight,Mood"`   <br> <br>It can also be used with relations, case in which it will display the title of the target note:    <br> <br>`~assignee=@My assignee #calendar:displayedAttributes="assignee"` |

View File

@ -16,7 +16,7 @@ Fore more information see <a class="reference-link" href="Text/Formatting%20too
Here's a list of various features supported by text notes:
<table><thead><tr><th>Dedicated article</th><th>Feature</th></tr></thead><tbody><tr><td><a class="reference-link" href="Text/General%20formatting.md">General formatting</a></td><td><ul><li data-list-item-id="e04c84d59d44645ee89b2a8541ed99f90">Headings (section titles, paragraph)</li><li data-list-item-id="e39d25bd3d8bd06185b9d259e5827d451">Font size</li><li data-list-item-id="e1f7e2a2f4b03449d82bdf5b5c6ea8d44">Bold, italic, underline, strike-through</li><li data-list-item-id="e3decae72884f65b4d538151b6a297072">Superscript, subscript</li><li data-list-item-id="e59adf00fef65304c163ae190fac5e92a">Font color &amp; background color</li><li data-list-item-id="ed3f09156147a2769e91db111c76376e2">Remove formatting</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Lists.md">Lists</a></td><td><ul><li data-list-item-id="ee87806a913900d85d8f018af81f41df8">Bulleted lists</li><li data-list-item-id="e3ae314e365fa418ca6e0f061d63834c5">Numbered lists</li><li data-list-item-id="ee84e08694165f95430046cb34f4cd123">To-do lists</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Block%20quotes%20%26%20admonitions.md">Block quotes &amp; admonitions</a></td><td><ul><li data-list-item-id="e2892dc35a0d4b7ad65daffb8f9404daa">Block quotes</li><li data-list-item-id="e7297e3ad1002f8de15aa0bd66c6f3f22">Admonitions</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Tables.md">Tables</a></td><td><ul><li data-list-item-id="eb358a4567d93f66004f4195df2dda05a">Basic tables</li><li data-list-item-id="e6135a555d6c63c30e4b84806a4870830">Merging cells</li><li data-list-item-id="e29ac76563d0998b28fb1baf94dbdac8c">Styling tables and cells.</li><li data-list-item-id="e372446e81fdedada64b8bed89ca93d1a">Table captions</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Developer-specific%20formatting.md">Developer-specific formatting</a></td><td><ul><li data-list-item-id="eb260b76afcbc07bd9d4ceec4e000e8a0">Inline code</li><li data-list-item-id="e9864352286369ebe7b41c1599f498de8">Code blocks</li><li data-list-item-id="ee62fb9ed7f349178e8f2a2bd9ec8cd74">Keyboard shortcuts</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Footnotes.md">Footnotes</a></td><td><ul><li data-list-item-id="edf62ec004eff35cfcb7e361deef19aaf">Footnotes</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Images.md">Images</a></td><td><ul><li data-list-item-id="ebe6277e643041403489c3ceb30c36f7f">Images</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Links.md">Links</a></td><td><ul><li data-list-item-id="e3f988be2f259bb40607cb61541955395">External links</li><li data-list-item-id="e3f91cc4f0cccd2c077cc306bacd68ef2">Internal Trilium links</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Include%20Note.md">Include Note</a></td><td><ul><li data-list-item-id="eac8015a64bce7b749cc67d1599062007">Include note</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Insert%20buttons.md">Insert buttons</a></td><td><ul><li data-list-item-id="e5cdf5d3885ec0ea67f924b4b8fe5c483">Symbols</li><li data-list-item-id="e95082e6642ed5b1eec6e4e116b899a40"><a class="reference-link" href="Text/Math%20Equations.md">Math Equations</a></li><li data-list-item-id="ecbef6a358a5b8d27f0d3e08bbc750aa9">Mermaid diagrams</li><li data-list-item-id="e6e97ee14dd29b7ccf53227107e5dc72d">Horizontal ruler</li><li data-list-item-id="e6198c7c535c249faec2e8906775f11de">Page break</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Other%20features.md">Other features</a></td><td><ul><li data-list-item-id="e0c14456cb83d483b07ea432ef9d4728e">Indentation<ul><li data-list-item-id="e2029812c5e105c595590f70ee227631e">Markdown import</li></ul></li><li data-list-item-id="ea1ee012286e05190c89c9f4e64cf2036"><a class="reference-link" href="Text/Cut%20to%20subnote.md">Cut to subnote</a></li></ul></td></tr><tr><td><a class="reference-link" href="Text/Premium%20features.md">Premium features</a></td><td><ul><li data-list-item-id="e1ab173193a533ccf33dccfd0cb916f1f"><a class="reference-link" href="Text/Premium%20features/Slash%20Commands.md">Slash Commands</a></li><li data-list-item-id="e564b978c09fe5adf476b331b1e0640e3"><a class="reference-link" href="../Advanced%20Usage/Templates.md">Templates</a></li><li data-list-item-id="e756306c31d9beffbba3820b6d1b9bc61"><a class="reference-link" href="Text/Premium%20features/Format%20Painter.md">Format Painter</a></li></ul></td></tr></tbody></table>
<table><thead><tr><th>Dedicated article</th><th>Feature</th></tr></thead><tbody><tr><td><a class="reference-link" href="Text/General%20formatting.md">General formatting</a></td><td><ul><li>Headings (section titles, paragraph)</li><li>Font size</li><li>Bold, italic, underline, strike-through</li><li>Superscript, subscript</li><li>Font color &amp; background color</li><li>Remove formatting</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Lists.md">Lists</a></td><td><ul><li>Bulleted lists</li><li>Numbered lists</li><li>To-do lists</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Block%20quotes%20%26%20admonitions.md">Block quotes &amp; admonitions</a></td><td><ul><li>Block quotes</li><li>Admonitions</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Tables.md">Tables</a></td><td><ul><li>Basic tables</li><li>Merging cells</li><li>Styling tables and cells.</li><li>Table captions</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Developer-specific%20formatting.md">Developer-specific formatting</a></td><td><ul><li>Inline code</li><li>Code blocks</li><li>Keyboard shortcuts</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Footnotes.md">Footnotes</a></td><td><ul><li>Footnotes</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Images.md">Images</a></td><td><ul><li>Images</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Links.md">Links</a></td><td><ul><li>External links</li><li>Internal Trilium links</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Include%20Note.md">Include Note</a></td><td><ul><li>Include note</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Insert%20buttons.md">Insert buttons</a></td><td><ul><li>Symbols</li><li><a class="reference-link" href="Text/Math%20Equations.md">Math Equations</a></li><li>Mermaid diagrams</li><li>Horizontal ruler</li><li>Page break</li></ul></td></tr><tr><td><a class="reference-link" href="Text/Other%20features.md">Other features</a></td><td><ul><li>Indentation<ul><li>Markdown import</li></ul></li><li><a class="reference-link" href="Text/Cut%20to%20subnote.md">Cut to subnote</a></li></ul></td></tr><tr><td><a class="reference-link" href="Text/Premium%20features.md">Premium features</a></td><td><ul><li><a class="reference-link" href="Text/Premium%20features/Slash%20Commands.md">Slash Commands</a></li><li><a class="reference-link" href="../Advanced%20Usage/Templates.md">Templates</a></li></ul></td></tr></tbody></table>
## Read-Only vs. Editing Mode

View File

@ -79,10 +79,6 @@ Note that heading styles are not taken into consideration, these must be manuall
When pasting content that comes with undesired formatting, an alternative to pasting and then removing formatting is pasting as plain text via <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>V</kbd>.
## Format painter
The <a class="reference-link" href="Premium%20features/Format%20Painter.md">Format Painter</a> allows users to copy the formatting of text (such as bold, italic, Strikethrough, etc.) and apply it to other parts of the document. It helps maintain consistent formatting and accelerates the creation of rich content.
## Support for Markdown
When exported to <a class="reference-link" href="../../Basic%20Concepts%20and%20Features/Import%20%26%20Export/Markdown.md">Markdown</a>, most of the general formatting is maintained such as headings, bold, italic, underline, etc.

View File

@ -1,20 +0,0 @@
# Format Painter
<figure class="image image-style-align-right"><img style="aspect-ratio:220/76;" src="Format Painter_image.png" width="220" height="76"></figure>
> [!NOTE]
> This is a premium feature of the editor we are using (CKEditor) and we benefit from it thanks to an written agreement with the team. See  <a class="reference-link" href="../Premium%20features.md">Premium features</a> for more information.
The Format Painter is a feature in text notes that allows users to copy the formatting of text (such as **bold**, _italic_, ~~Strikethrough~~, etc.) and apply it to other parts of the document. It helps maintain consistent formatting and accelerates the creation of rich content.
## Usage Instructions
Click the text that you want to copy the formatting from and use the paint formatting toolbar button (<img class="image_resized" style="aspect-ratio:150/150;width:2.7%;" src="Format Painter_746436a2e1.svg" alt="Format painter" width="150" height="150">) to copy the style. Then select the target text with your mouse to apply the formatting.
* **To copy the formatting**: Place the cursor inside a text with some formatting and click the paint formatting toolbar button. Notice that the mouse cursor changes to the <img class="image_resized" style="aspect-ratio:30/20;width:3.64%;" src="Format Painter_e144e96df9.svg" alt="Format painter text cursor" width="30" height="20">.
* **To paint with the copied formatting**: Click any word in the document and the new formatting will be applied. Alternatively, instead of clicking a single word, you can select a text fragment (like an entire paragraph). Notice that the cursor will go back to the default one after the formatting is applied.
* **To keep painting using the same formatting**: Open the toolbar dropdown and enable the continuous painting mode. Once copied, the same formatting can be applied multiple times in different places until the paint formatting button is clicked (the cursor will then revert to the regular one).
## Limitations
1. Painting with block-level formatting (like headings or image styles) is not supported yet. This is because, in <a class="reference-link" href="../../../Advanced%20Usage/Technologies%20used/CKEditor.md">CKEditor</a>, they are considered a part of the content rather than text formatting.
2. When applying formatting to words, spaces or other Western punctuation are used as word boundaries, which prevents proper handling of languages that do not use space-based word segmentation.

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M3 3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1z"/><path d="M16 3.25a1.5 1.5 0 0 1 1.5 1.5v1.7a2.25 2.25 0 0 1-1.932 2.226l-4.424.632a.75.75 0 0 0-.644.743V11a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-5a1 1 0 0 1 1-1v-.95a2.25 2.25 0 0 1 1.932-2.226l4.424-.632A.75.75 0 0 0 16 6.449z"/></svg>

Before

Width:  |  Height:  |  Size: 386 B

View File

@ -1,7 +0,0 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 31 20" width="30" height="20">
<path d="M14 3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H15a1 1 0 0 1-1-1V3Z" fill="#000"/>
<path d="M27 3.25a1.5 1.5 0 0 1 1.5 1.5v1.7a2.25 2.25 0 0 1-1.932 2.226l-4.424.632a.75.75 0 0 0-.644.743V11a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H20a1 1 0 0 1-1-1v-5a1 1 0 0 1 1-1v-.95a2.25 2.25 0 0 1 1.932-2.226l4.424-.632A.75.75 0 0 0 27 6.449V3.25Z" fill="#000"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.855 2.25H27a2.5 2.5 0 0 1 2.5 2.5v1.7a3.25 3.25 0 0 1-2.79 3.216l-4.21.602a2 2 0 0 1 1 1.732v5a2 2 0 0 1-2 2H20a2 2 0 0 1-2-2v-5a2 2 0 0 1 1-1.732v-.217A3.25 3.25 0 0 1 21.129 7H15a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h10a2 2 0 0 1 1.855 1.25ZM20 10.05V11a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1h1.5a1 1 0 0 0 1-1v-5a1 1 0 0 0-1-1v-.95c0-.016 0-.033.002-.05a.75.75 0 0 1 .642-.692l4.424-.632A2.25 2.25 0 0 0 28.5 6.45V4.75a1.496 1.496 0 0 0-1.5-1.5v3.2a.75.75 0 0 1-.644.742l-4.424.632A2.25 2.25 0 0 0 20 10.05ZM15 2a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H15Z" fill="#fff"/>
<path d="M2.5 2.5A.5.5 0 0 1 3 2h2.5a.5.5 0 0 1 .354.146l.646.647.646-.647A.5.5 0 0 1 7.5 2H10a.5.5 0 0 1 0 1H7.707L7 3.707V10h.5a.5.5 0 0 1 0 1H7v4.793l.707.707H10a.5.5 0 0 1 0 1H7.5a.5.5 0 0 1-.354-.146l-.646-.647-.646.647a.5.5 0 0 1-.354.146H3a.5.5 0 0 1 0-1h2.293L6 15.793V11h-.5a.5.5 0 0 1 0-1H6V3.707L5.293 3H3a.5.5 0 0 1-.5-.5Z" fill="#000"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m5.793 3.5-.5-.5H3a.5.5 0 0 1 0-1h2.5a.5.5 0 0 1 .354.146l.145.146.501.5.646-.646A.5.5 0 0 1 7.5 2H10a.5.5 0 0 1 0 1H7.707L7 3.707V10h.5a.5.5 0 0 1 0 1H7v4.793l.707.707H10a.5.5 0 0 1 0 1H7.5a.5.5 0 0 1-.354-.146l-.646-.647-.5.5-.146.147a.5.5 0 0 1-.354.146H3a.5.5 0 0 1 0-1h2.293L6 15.793V11h-.5a.5.5 0 0 1 0-1H6V3.707L5.793 3.5Zm-.914.5L5 4.121v4.964a1.5 1.5 0 0 0 0 2.83v3.464l-.121.121H3a1.5 1.5 0 0 0 0 3h2.5a1.5 1.5 0 0 0 1-.382 1.5 1.5 0 0 0 1 .382H10a1.5 1.5 0 0 0 0-3H8.121L8 15.379v-3.464a1.5 1.5 0 0 0 0-2.83V4.121L8.121 4H10a1.5 1.5 0 0 0 0-3H7.5a1.5 1.5 0 0 0-1 .382A1.5 1.5 0 0 0 5.5 1H3a1.5 1.5 0 1 0 0 3h1.879Z" fill="#fff"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -53,7 +53,7 @@
"esbuild": "0.27.0",
"eslint": "9.39.1",
"eslint-config-prettier": "10.1.8",
"eslint-plugin-playwright": "2.4.0",
"eslint-plugin-playwright": "2.3.0",
"eslint-plugin-react-hooks": "7.0.1",
"happy-dom": "~20.0.0",
"http-server": "14.1.1",
@ -62,7 +62,7 @@
"react-refresh": "0.18.0",
"rollup-plugin-webpack-stats": "2.1.8",
"tslib": "2.8.1",
"tsx": "4.21.0",
"tsx": "4.20.6",
"typescript": "~5.9.0",
"typescript-eslint": "8.48.0",
"upath": "2.0.1",

View File

@ -39,7 +39,7 @@
"typescript": "5.9.3",
"vite-plugin-svgo": "~2.0.0",
"vitest": "4.0.14",
"webdriverio": "9.21.0"
"webdriverio": "9.20.1"
},
"peerDependencies": {
"ckeditor5": "47.2.0"

View File

@ -40,7 +40,7 @@
"typescript": "5.9.3",
"vite-plugin-svgo": "~2.0.0",
"vitest": "4.0.14",
"webdriverio": "9.21.0"
"webdriverio": "9.20.1"
},
"peerDependencies": {
"ckeditor5": "47.2.0"

View File

@ -42,7 +42,7 @@
"typescript": "5.9.3",
"vite-plugin-svgo": "~2.0.0",
"vitest": "4.0.14",
"webdriverio": "9.21.0"
"webdriverio": "9.20.1"
},
"peerDependencies": {
"ckeditor5": "47.2.0"

View File

@ -25,6 +25,7 @@
],
"devDependencies": {
"@ckeditor/ckeditor5-dev-build-tools": "43.1.0",
"@ckeditor/ckeditor5-dev-utils": "43.1.0",
"@ckeditor/ckeditor5-inspector": ">=4.1.0",
"@ckeditor/ckeditor5-package-tools": "5.0.1",
"@typescript-eslint/eslint-plugin": "~8.48.0",
@ -42,7 +43,7 @@
"typescript": "5.9.3",
"vite-plugin-svgo": "~2.0.0",
"vitest": "4.0.14",
"webdriverio": "9.21.0"
"webdriverio": "9.20.1"
},
"peerDependencies": {
"ckeditor5": "47.2.0"

View File

@ -42,7 +42,7 @@
"typescript": "5.9.3",
"vite-plugin-svgo": "~2.0.0",
"vitest": "4.0.14",
"webdriverio": "9.21.0"
"webdriverio": "9.20.1"
},
"peerDependencies": {
"ckeditor5": "47.2.0"

View File

@ -10,11 +10,6 @@ interface LocaleMapping {
const LOCALE_MAPPINGS: Record<DISPLAYABLE_LOCALE_IDS, LocaleMapping | null> = {
en: null,
en_rtl: null,
"en-GB": {
languageCode: "en-GB",
coreTranslation: () => import("ckeditor5/translations/en-gb.js"),
premiumFeaturesTranslation: () => import("ckeditor5-premium-features/translations/en-gb.js"),
},
ar: {
languageCode: "ar",
coreTranslation: () => import("ckeditor5/translations/ar.js"),

View File

@ -1,5 +1,4 @@
import "ckeditor5/ckeditor5.css";
import 'ckeditor5-premium-features/ckeditor5-premium-features.css';
import "./theme/code_block_toolbar.css";
import { COMMON_PLUGINS, CORE_PLUGINS, POPUP_EDITOR_PLUGINS } from "./plugins.js";
import { BalloonEditor, DecoupledEditor, FindAndReplaceEditing, FindCommand } from "ckeditor5";

View File

@ -1,5 +1,5 @@
import { Autoformat, AutoLink, BlockQuote, BlockToolbar, Bold, CKFinderUploadAdapter, Clipboard, Code, CodeBlock, Enter, FindAndReplace, Font, FontBackgroundColor, FontColor, GeneralHtmlSupport, Heading, HeadingButtonsUI, HorizontalLine, Image, ImageCaption, ImageInline, ImageResize, ImageStyle, ImageToolbar, ImageUpload, Alignment, Indent, IndentBlock, Italic, Link, List, ListProperties, Mention, PageBreak, Paragraph, ParagraphButtonUI, PasteFromOffice, PictureEditing, RemoveFormat, SelectAll, ShiftEnter, SpecialCharacters, SpecialCharactersEssentials, Strikethrough, Style, Subscript, Superscript, Table, TableCaption, TableCellProperties, TableColumnResize, TableProperties, TableSelection, TableToolbar, TextPartLanguage, TextTransformation, TodoList, Typing, Underline, Undo, Bookmark, Emoji, Notification, EmojiMention, EmojiPicker } from "ckeditor5";
import { SlashCommand, Template, FormatPainter } from "ckeditor5-premium-features";
import { SlashCommand, Template } from "ckeditor5-premium-features";
import type { Plugin } from "ckeditor5";
import CutToNotePlugin from "./plugins/cuttonote.js";
import UploadimagePlugin from "./plugins/uploadimage.js";
@ -83,8 +83,7 @@ export const CORE_PLUGINS: typeof Plugin[] = [
*/
export const PREMIUM_PLUGINS: typeof Plugin[] = [
SlashCommand,
Template,
FormatPainter
Template
];
/**

View File

@ -14,8 +14,7 @@ export interface Locale {
const UNSORTED_LOCALES = [
{ id: "cn", name: "简体中文", electronLocale: "zh_CN" },
{ id: "de", name: "Deutsch", electronLocale: "de" },
{ id: "en", name: "English (United States)", electronLocale: "en" },
{ id: "en-GB", name: "English (United Kingdom)", electronLocale: "en_GB" },
{ id: "en", name: "English", electronLocale: "en" },
{ id: "es", name: "Español", electronLocale: "es" },
{ id: "fr", name: "Français", electronLocale: "fr" },
{ id: "it", name: "Italiano", electronLocale: "it" },

View File

@ -121,6 +121,7 @@ export interface OptionDefinitions extends KeyboardShortcutsOptions<KeyboardActi
downloadImagesAutomatically: boolean;
checkForUpdates: boolean;
disableTray: boolean;
promotedAttributesOpenInRibbon: boolean;
editedNotesOpenInRibbon: boolean;
codeBlockWordWrap: boolean;
textNoteEditorMultilineToolbar: boolean;

1855
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff