Compare commits

...

98 Commits

Author SHA1 Message Date
Elian Doran
28b263a445
chore(mobile/split): address requested changes
Some checks failed
Checks / main (push) Has been cancelled
2025-12-01 23:51:12 +02:00
Elian Doran
e0e9310907
feat(mobile/split): rephase open in note split if a split is already open 2025-12-01 23:46:29 +02:00
Elian Doran
f5940cbf70
feat(mobile/split): hide split button if split is already open 2025-12-01 23:36:15 +02:00
Elian Doran
bfb143bb51
Merge remote-tracking branch 'origin/main' into prototype/mobile_split 2025-12-01 23:27:58 +02:00
Adorian Doran
64662d5215 Merge branch 'main' of https://github.com/TriliumNext/Trilium
Some checks are pending
Checks / main (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Documentation / Build and Deploy Documentation (push) Waiting to run
Dev / Test development (push) Waiting to run
Dev / Build Docker image (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile) (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile.alpine) (push) Blocked by required conditions
/ Check Docker build (Dockerfile) (push) Waiting to run
/ Check Docker build (Dockerfile.alpine) (push) Waiting to run
/ Build Docker images (Dockerfile, ubuntu-24.04-arm, linux/arm64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.alpine, ubuntu-latest, linux/amd64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v7) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v8) (push) Blocked by required conditions
/ Merge manifest lists (push) Blocked by required conditions
playwright / E2E tests on linux-arm64 (push) Waiting to run
playwright / E2E tests on linux-x64 (push) Waiting to run
2025-12-01 16:33:41 +02:00
Adorian Doran
31cedad976 documentation: mark "calendar:color" as deprecated 2025-12-01 16:33:31 +02:00
Elian Doran
12ac5147d3
Merge branch 'main' of github.com:TriliumNext/Trilium 2025-12-01 14:40:25 +02:00
Elian Doran
17291ff61d
chore(deps): remove unnecessary package 2025-12-01 14:34:55 +02:00
Adorian Doran
f3e334470e style: refactor 2025-12-01 14:27:49 +02:00
Adorian Doran
9407051f1e style: refactor 2025-12-01 14:24:13 +02:00
Adorian Doran
08a6d36153 style/calendar collection/list view: use separate style for the archived events 2025-12-01 14:13:23 +02:00
Adorian Doran
f906fb9b4c Merge branch 'main' of https://github.com/TriliumNext/Trilium 2025-12-01 14:08:32 +02:00
Adorian Doran
b4a6356724 style/calendar collection/list view: fix dot colors 2025-12-01 14:08:24 +02:00
Elian Doran
8eca14069a
fix(e2e): i18n test failing to due to English selection
Some checks are pending
Checks / main (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Documentation / Build and Deploy Documentation (push) Waiting to run
Dev / Test development (push) Waiting to run
Dev / Build Docker image (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile) (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile.alpine) (push) Blocked by required conditions
/ Check Docker build (Dockerfile) (push) Waiting to run
/ Check Docker build (Dockerfile.alpine) (push) Waiting to run
/ Build Docker images (Dockerfile, ubuntu-24.04-arm, linux/arm64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.alpine, ubuntu-latest, linux/amd64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v7) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v8) (push) Blocked by required conditions
/ Merge manifest lists (push) Blocked by required conditions
playwright / E2E tests on linux-arm64 (push) Waiting to run
playwright / E2E tests on linux-x64 (push) Waiting to run
2025-12-01 14:02:32 +02:00
Elian Doran
1af0477ac0
chore(ci): fix duplicate artifact name error 2025-12-01 13:53:07 +02:00
Elian Doran
43920f12ae
feat(backlinks): use proper plural 2025-12-01 13:50:59 +02:00
Elian Doran
5a0beec6cb
fix(backlinks): not refreshed after inserting a new link 2025-12-01 13:37:15 +02:00
Elian Doran
98241fb54b
fix(promoted_attributes): value carrying over onto new notes 2025-12-01 13:37:15 +02:00
Adorian Doran
3051664228 style: fix typo 2025-12-01 13:34:36 +02:00
Adorian Doran
1ed774365c client/Kanban board collection: reorder context menu items 2025-12-01 13:33:20 +02:00
Adorian Doran
f2e33dfd58 Merge branch 'main' of https://github.com/TriliumNext/Trilium 2025-12-01 13:29:39 +02:00
Adorian Doran
90b5282b39 client/calendar collection: add "Archive note" command to the context menu 2025-12-01 13:29:28 +02:00
Elian Doran
d520fc46b9
fix(text): code blocks cannot wrap automatically (#7910) 2025-12-01 11:18:31 +00:00
Adorian Doran
e69b5988ec style: fix custom title bar buttons on the legacy theme 2025-12-01 11:48:42 +02:00
Adorian Doran
3cdc1ba794 style/calendar collection: fix colors on the legacy theme 2025-12-01 11:38:48 +02:00
Adorian Doran
25e1008c5c Merge branch 'main' of https://github.com/TriliumNext/Trilium 2025-12-01 11:24:52 +02:00
Adorian Doran
a093862311 style/calendar collection: use a separate style for archived notes 2025-12-01 11:24:39 +02:00
Elian Doran
53057ea9fc
Translations update from Hosted Weblate (#7907) 2025-12-01 08:09:22 +00:00
Francis C.
94db96de3e
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (1638 of 1638 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hans/
2025-12-01 09:04:54 +01:00
Mr Mejri
60e4fbbf75
Translated using Weblate (Persian)
Currently translated at 15.2% (18 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/fa/
2025-12-01 09:04:53 +01:00
green
d35dd67632
Translated using Weblate (Japanese)
Currently translated at 100.0% (1638 of 1638 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ja/
2025-12-01 07:28:44 +01:00
Francis C.
8813985c68
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (1638 of 1638 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hant/
2025-12-01 07:28:44 +01:00
Mr Mejri
538c98b587
Translated using Weblate (Persian)
Currently translated at 5.9% (7 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/fa/
2025-12-01 07:28:44 +01:00
Hosted Weblate
389c7029cf
Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/
2025-12-01 07:28:44 +01:00
Elian Doran
d47f9e1131
chore(deps): update dependency eslint-plugin-playwright to v2.4.0 (#7908) 2025-12-01 06:28:37 +00:00
Elian Doran
c0a8d29756
fix(deps): update dependency tsx to v4.21.0 (#7909) 2025-12-01 06:26:48 +00:00
SiriusXT
668fd34af6 fix(text): code blocks cannot wrap automatically 2025-12-01 13:55:21 +08:00
renovate[bot]
8aa08cf8fe
fix(deps): update dependency tsx to v4.21.0 2025-12-01 01:19:56 +00:00
renovate[bot]
16c04f5ae4
chore(deps): update dependency eslint-plugin-playwright to v2.4.0 2025-12-01 01:19:12 +00:00
Adorian Doran
32c16021c4 style/calendar collection: refactor
Some checks are pending
Checks / main (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Dev / Test development (push) Waiting to run
Dev / Build Docker image (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile) (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile.alpine) (push) Blocked by required conditions
/ Check Docker build (Dockerfile) (push) Waiting to run
/ Check Docker build (Dockerfile.alpine) (push) Waiting to run
/ Build Docker images (Dockerfile, ubuntu-24.04-arm, linux/arm64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.alpine, ubuntu-latest, linux/amd64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v7) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v8) (push) Blocked by required conditions
/ Merge manifest lists (push) Blocked by required conditions
playwright / E2E tests on linux-arm64 (push) Waiting to run
playwright / E2E tests on linux-x64 (push) Waiting to run
2025-12-01 03:00:38 +02:00
Adorian Doran
7713c1173a style/calendar collection: tweak the color of the today column / cell 2025-12-01 02:40:07 +02:00
Adorian Doran
8018f400c3 style/calendar collection: correct a hover color 2025-12-01 02:26:16 +02:00
Adorian Doran
79c8293881 style/calendar collection: handle dot events as normal events 2025-12-01 02:21:19 +02:00
Adorian Doran
db5652623b style/calendar collection: fix broken background color for events without a hue 2025-12-01 02:04:26 +02:00
Adorian Doran
0f7a48b323 style/calendar collection: add basic support for the legacy theme 2025-12-01 01:55:03 +02:00
Adorian Doran
415d2826c6 style/calendar collection: tweak dark theme colors 2025-11-30 23:30:30 +02:00
Adorian Doran
7787e7085e style/calendar collection: tweak dark theme colors 2025-11-30 23:22:41 +02:00
Elian Doran
4ab8417168
feat(forge): add safeguard for ARM64 better-sqlite3 binary 2025-11-30 22:57:14 +02:00
Adorian Doran
a77e76d5c6 Merge branch 'main' of https://github.com/TriliumNext/Trilium
Some checks failed
Checks / main (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Documentation / Build and Deploy Documentation (push) Waiting to run
Dev / Test development (push) Waiting to run
Dev / Build Docker image (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile) (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile.alpine) (push) Blocked by required conditions
/ Check Docker build (Dockerfile) (push) Waiting to run
/ Check Docker build (Dockerfile.alpine) (push) Waiting to run
/ Build Docker images (Dockerfile, ubuntu-24.04-arm, linux/arm64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.alpine, ubuntu-latest, linux/amd64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v7) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v8) (push) Blocked by required conditions
/ Merge manifest lists (push) Blocked by required conditions
playwright / E2E tests on linux-arm64 (push) Waiting to run
playwright / E2E tests on linux-x64 (push) Waiting to run
Deploy website / Build & deploy website (push) Has been cancelled
2025-11-30 21:33:08 +02:00
Adorian Doran
ca6660e2ff style/calendar collection: tweak appearance 2025-11-30 21:33:00 +02:00
Elian Doran
af94410c55
Merge branch 'main' of github.com:TriliumNext/Trilium 2025-11-30 21:26:50 +02:00
Elian Doran
b47bc50147
fix(revisions): double scrolling on mobile 2025-11-30 21:24:57 +02:00
Elian Doran
5ff77c16ab
feat(revisions): improve layout on mobile 2025-11-30 21:13:07 +02:00
Adorian Doran
11618260cf style/calendar collection: tweak the appearance of events without a color 2025-11-30 20:18:16 +02:00
Adorian Doran
63f9006d17 style/calendar collection: improve the support for colored notes 2025-11-30 20:08:24 +02:00
Elian Doran
7779acc7bc
refactor(client): split revisions CSS into file 2025-11-30 19:56:13 +02:00
Elian Doran
aacd92eee3
chore(popup-editor): implement switch to full editor button 2025-11-30 19:47:17 +02:00
Adorian Doran
1bf8be2874 Merge branch 'main' of https://github.com/TriliumNext/Trilium 2025-11-30 19:46:26 +02:00
Adorian Doran
66f2d0c7dc style/note colors: use a more elegant way to retrieve the theme-aware note color 2025-11-30 19:46:15 +02:00
Elian Doran
597d952254
Add British English (en-GB) translations (#7904) 2025-11-30 17:37:49 +00:00
Adorian Doran
288595ce5d Merge branch 'main' of https://github.com/TriliumNext/Trilium 2025-11-30 19:34:45 +02:00
Elian Doran
c89e8c78d3
Translations update from Hosted Weblate (#7905) 2025-11-30 17:34:39 +00:00
Adorian Doran
81a37e3fc4 client/CSS class manager: fix a bug when handling red hues 2025-11-30 19:34:31 +02:00
Elian Doran
368c590976
Translated using Weblate (English (United Kingdom))
Currently translated at 0.8% (1 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/en_GB/
2025-11-30 18:33:26 +01:00
Elian Doran
6e982e646d
Translated using Weblate (English (United Kingdom))
Currently translated at 1.6% (2 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/en_GB/
2025-11-30 18:29:39 +01:00
Elian Doran
030582b2d5
feat(i18n): add English (United Kingdom) 2025-11-30 19:14:21 +02:00
copilot-swe-agent[bot]
7dd4b10a96 Add British English (en-GB) translations for client
Co-authored-by: eliandoran <21236836+eliandoran@users.noreply.github.com>
2025-11-30 17:10:30 +00:00
copilot-swe-agent[bot]
b055e79b4c Initial plan 2025-11-30 17:02:01 +00:00
Elian Doran
ba980aa93f
Translations update from Hosted Weblate (#7903) 2025-11-30 16:59:52 +00:00
Elian Doran
15baf04ce9
Added translation using Weblate (English (United Kingdom)) 2025-11-30 17:58:03 +01:00
Elian Doran
4dc2587817
Added translation using Weblate (English (United Kingdom)) 2025-11-30 17:58:00 +01:00
Elian Doran
d5e046c289
Added translation using Weblate (English (United Kingdom)) 2025-11-30 17:57:58 +01:00
Elian Doran
ef8073ac58
Added translation using Weblate (English (United Kingdom)) 2025-11-30 17:57:56 +01:00
green
38c9d25214
Translated using Weblate (Japanese)
Currently translated at 100.0% (1637 of 1637 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ja/
2025-11-30 17:57:54 +01:00
Elian Doran
e2f0e4089f
Merge branch 'main' of github.com:TriliumNext/Trilium 2025-11-30 18:41:43 +02:00
Elian Doran
80ce2c04ed
chore(ci): apply platform changes for nightly
See https://github.com/TriliumNext/Trilium/pull/7002/files
2025-11-30 18:41:39 +02:00
Elian Doran
4ebd82beeb
feat(ckeditor5): add formatPainter (#7902) 2025-11-30 13:27:15 +00:00
SiriusXT
8cc43cd9a6 docs(user): add format painter 2025-11-30 20:08:27 +08:00
SiriusXT
15190abb69 feat(ckeditor5): add formatPainter 2025-11-30 16:53:14 +08:00
Elian Doran
0b28159e8e
fix(ribbon): formatting toolbar overrides edited notes activation (closes #7900)
Some checks are pending
Checks / main (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Documentation / Build and Deploy Documentation (push) Waiting to run
Dev / Test development (push) Waiting to run
Dev / Build Docker image (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile) (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile.alpine) (push) Blocked by required conditions
/ Check Docker build (Dockerfile) (push) Waiting to run
/ Check Docker build (Dockerfile.alpine) (push) Waiting to run
/ Build Docker images (Dockerfile, ubuntu-24.04-arm, linux/arm64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.alpine, ubuntu-latest, linux/amd64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v7) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v8) (push) Blocked by required conditions
/ Merge manifest lists (push) Blocked by required conditions
playwright / E2E tests on linux-arm64 (push) Waiting to run
playwright / E2E tests on linux-x64 (push) Waiting to run
2025-11-30 10:43:06 +02:00
Elian Doran
d9e8f8e69b
refactor(options): remove unnecessary ribbon activation option 2025-11-30 10:41:26 +02:00
Elian Doran
fa224e46bc
chore(deps): update dependency typedoc to v0.28.15 (#7897) 2025-11-30 09:41:04 +02:00
Elian Doran
06320953e8
chore(deps): update dependency webdriverio to v9.21.0 (#7898) 2025-11-30 09:40:31 +02:00
renovate[bot]
d676084cb3
chore(deps): update dependency webdriverio to v9.21.0 2025-11-30 02:49:59 +00:00
renovate[bot]
0cb5941be0
chore(deps): update dependency typedoc to v0.28.15 2025-11-30 02:49:23 +00:00
Adorian Doran
732494dfc5 client/keyboard shortcuts cheatsheet: add an edit button
Some checks are pending
Checks / main (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Dev / Test development (push) Waiting to run
Dev / Build Docker image (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile) (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile.alpine) (push) Blocked by required conditions
/ Check Docker build (Dockerfile) (push) Waiting to run
/ Check Docker build (Dockerfile.alpine) (push) Waiting to run
/ Build Docker images (Dockerfile, ubuntu-24.04-arm, linux/arm64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.alpine, ubuntu-latest, linux/amd64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v7) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v8) (push) Blocked by required conditions
/ Merge manifest lists (push) Blocked by required conditions
playwright / E2E tests on linux-arm64 (push) Waiting to run
playwright / E2E tests on linux-x64 (push) Waiting to run
Deploy website / Build & deploy website (push) Waiting to run
2025-11-30 02:54:51 +02:00
Adorian Doran
b8748b856a client/note menu: use proper style for development-only actions section header 2025-11-30 02:34:09 +02:00
Adorian Doran
cc71f15700 client/quick edit: remove fixed toolbar transparency 2025-11-30 02:17:43 +02:00
Adorian Doran
124ef640b1 client/quick edit: tweak layout 2025-11-30 02:04:40 +02:00
Adorian Doran
f5e3df0cd2 client/quick edit: add placeholder for "open in full editor" custom title bar button 2025-11-30 01:54:28 +02:00
Adorian Doran
c8431181c8 client/dialogs/custom title bar buttons: tweak 2025-11-30 01:52:55 +02:00
Adorian Doran
07fb5ab017 client/dialogs: add support for custom title bar buttons 2025-11-30 01:44:20 +02:00
Adorian Doran
6735b257b4 style/promoted color attributes: fix the layout on narrow width 2025-11-30 01:09:07 +02:00
Adorian Doran
cef242a9ce style/button group: fix the appearance of the active button 2025-11-30 00:55:34 +02:00
Elian Doran
2923d917e5
Translations update from Hosted Weblate (#7891) 2025-11-29 22:58:03 +02:00
Hosted Weblate
9a76a9069c
Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/
2025-11-29 20:01:42 +01:00
pythaac
8e1d796870
Translated using Weblate (Korean)
Currently translated at 44.7% (68 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/ko/
2025-11-29 20:01:38 +01:00
Andreas H.
8b0d4e5c3b
Translated using Weblate (German)
Currently translated at 100.0% (152 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/de/
2025-11-29 20:01:37 +01:00
86 changed files with 1620 additions and 2010 deletions

View File

@ -45,6 +45,19 @@ 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
name: e2e report ${{ matrix.arch }}
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.14",
"typedoc": "0.28.15",
"typedoc-plugin-missing-exports": "4.1.2"
}
}

View File

@ -0,0 +1,21 @@
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,22 +2,25 @@ 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 from "../services/utils.js";
import utils, { isMobile } 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(),
items: getItems(e),
selectMenuItemHandler: ({ command }) => handleLinkContextMenuItem(command, e, notePath, viewScope, hoistedNoteId)
});
}
function getItems(): MenuItem<CommandNames>[] {
function getItems(e: ContextMenuEvent): MenuItem<CommandNames>[] {
const ntxId = getNtxId(e);
const isMobileSplitOpen = isMobile() && appContext.tabManager.getNoteContextById(ntxId).getMainContext().getSubContexts().length > 1;
return [
{ title: t("link_context_menu.open_note_in_new_tab"), command: "openNoteInNewTab", uiIcon: "bx bx-link-external" },
{ title: t("link_context_menu.open_note_in_new_split"), command: "openNoteInNewSplit", uiIcon: "bx bx-dock-right" },
{ 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_window"), command: "openNoteInNewWindow", uiIcon: "bx bx-window-open" },
{ title: t("link_context_menu.open_note_in_popup"), command: "openNoteInPopup", uiIcon: "bx bx-edit" }
];
@ -46,8 +49,10 @@ function getNtxId(e: ContextMenuEvent) {
const subContexts = appContext.tabManager.getActiveContext()?.getSubContexts();
if (!subContexts) return null;
return subContexts[subContexts.length - 1].ntxId;
} else {
} else if (e.target instanceof HTMLElement) {
return getClosestNtxId(e.target);
} else {
return null;
}
}

View File

@ -39,12 +39,12 @@ function createClassForColor(colorString: string | null) {
</style>`);
registeredClasses.add(className);
if (hue) {
if (hue !== undefined) {
colorsWithHue.add(className);
}
}
return clsx(className, colorsWithHue.has(className) && "with-hue");
return clsx("use-note-color", 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;
}
function randomString(len: number) {
export function randomString(len: number) {
let text = "";
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

View File

@ -27,6 +27,9 @@
--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 *,
@ -254,6 +257,11 @@ 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;
}
@ -592,11 +600,6 @@ 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);
@ -1691,46 +1694,6 @@ 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 */
@ -2626,6 +2589,14 @@ 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,6 +76,9 @@
--mermaid-theme: dark;
--native-titlebar-background: #00000000;
--calendar-coll-event-background-saturation: 30%;
--calendar-coll-event-background-lightness: 30%;
}
body ::-webkit-calendar-picker-indicator {
@ -109,3 +112,6 @@ 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,6 +80,9 @@ 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 {
@ -92,3 +95,7 @@ html {
.board-note {
color: var(--light-theme-custom-color, inherit);
}
.use-note-color {
--custom-color: var(--light-theme-custom-color);
}

View File

@ -41,6 +41,9 @@
--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);
@ -267,6 +270,14 @@
--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;
}
/*
@ -306,3 +317,7 @@ body .todo-list input[type="checkbox"]:not(:checked):before {
--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,6 +41,9 @@
--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);
@ -265,6 +268,14 @@
--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,6 +25,7 @@
.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;
@ -55,15 +56,17 @@
font-family: boxicons;
}
.modal .modal-header .help-button {
.modal .modal-header .help-button,
.modal .modal-header .custom-title-bar-button {
margin-inline-end: 0;
font-size: calc(var(--modal-control-button-size) * .75);
font-size: calc(var(--modal-control-button-size) * .70);
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);
@ -71,6 +74,7 @@
.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,6 +146,14 @@ 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 {
}
}
.note-detail-printable:not(.word-wrap) pre code {
.ck-content:not(.word-wrap) pre code {
white-space: pre;
}

View File

@ -1448,6 +1448,14 @@ 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,7 +162,8 @@
"inPageSearch": "页面内搜索",
"newTabWithActivationNoteLink": "在新标签页打开笔记链接并激活该标签页",
"title": "资料表",
"newTabNoteLink": "在新标签页开启链接"
"newTabNoteLink": "在新标签页开启链接",
"editShortcuts": "编辑键盘快捷键"
},
"import": {
"importIntoNote": "导入到笔记",
@ -2098,12 +2099,14 @@
"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,7 +2097,6 @@
"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

@ -0,0 +1,73 @@
{
"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,6 +112,7 @@
},
"help": {
"title": "Cheatsheet",
"editShortcuts": "Edit keyboard shortcuts",
"noteNavigation": "Note navigation",
"goUpDown": "go up/down in the list of notes",
"collapseExpand": "collapse/expand node",
@ -735,8 +736,8 @@
"zoom_out_title": "Zoom Out"
},
"zpetne_odkazy": {
"backlink": "{{count}} Backlink",
"backlinks": "{{count}} Backlinks",
"backlink_one": "{{count}} Backlink",
"backlink_other": "{{count}} Backlinks",
"relation": "relation"
},
"mobile_detail_menu": {
@ -1882,6 +1883,7 @@
"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"
},
@ -2106,5 +2108,8 @@
"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,7 +2096,6 @@
"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,7 +2092,6 @@
"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,7 +312,8 @@
"moveNoteUpDown": "ノートリストでノートを上/下に移動",
"notSet": "未設定",
"goUpDown": "ノートのリストで上下する",
"editBranchPrefix": "アクティブノートのクローンの <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/tree-concepts.html#prefix\">プレフィックス</a> を編集する"
"editBranchPrefix": "アクティブノートのクローンの <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/tree-concepts.html#prefix\">プレフィックス</a> を編集する",
"editShortcuts": "キーボードショートカットを編集"
},
"import": {
"importIntoNote": "ノートにインポート",
@ -2098,12 +2099,14 @@
"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,8 +1362,9 @@
"title": "Factorul de zoom (doar pentru versiunea desktop)"
},
"zpetne_odkazy": {
"backlink": "{{count}} legături de retur",
"backlinks": "{{count}} legături de retur",
"backlink_one": "{{count}} legătură de retur",
"backlink_few": "{{count}} legături de retur",
"backlink_other": "{{count}} de legături de retur",
"relation": "relație"
},
"svg_export_button": {
@ -2097,7 +2098,6 @@
"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,7 +162,8 @@
"inPageSearch": "頁面內搜尋",
"title": "列表",
"newTabNoteLink": "在新分頁開啟筆記連結",
"newTabWithActivationNoteLink": "在新分頁開啟並切換至筆記連結"
"newTabWithActivationNoteLink": "在新分頁開啟並切換至筆記連結",
"editShortcuts": "編輯鍵盤快捷鍵"
},
"import": {
"importIntoNote": "匯入至筆記",
@ -2098,12 +2099,14 @@
"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,6 +18,7 @@ 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;
@ -310,13 +311,24 @@ function Backlinks({ note, isDefaultViewMode }: FloatingButtonContext) {
let [ popupOpen, setPopupOpen ] = useState(false);
const backlinksContainerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
function refresh() {
if (!isDefaultViewMode) return;
server.get<BacklinkCountResponse>(`note-map/${note.noteId}/backlink-count`).then(resp => {
setBacklinkCount(resp.count);
});
}, [ note ]);
}
useEffect(() => refresh(), [ note ]);
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
loadResults.getAttributeRows().some(attr =>
attr.type === "relation" &&
attr.name === "internalLink" &&
attributes.isAffecting(attr, note))
{
refresh();
}
});
// Determine the max height of the container.
const { windowHeight } = useWindowSize();

View File

@ -14,8 +14,10 @@ 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;
@ -44,6 +46,7 @@ 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}
@ -103,7 +106,8 @@ function usePromotedAttributeData(note: FNote | null | undefined, componentId: s
valueAttr.attributeId = "";
}
cells.push({ definitionAttr, definition, valueAttr, valueName });
const uniqueId = randomString(10);
cells.push({ definitionAttr, definition, valueAttr, valueName, uniqueId });
}
}
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,17 +43,6 @@ 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",
@ -65,6 +54,17 @@ 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,20 +85,3 @@ 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,11 +3,10 @@ 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 froca from "../../../services/froca";
import { note } from "mermaid/dist/rendering-util/rendering-elements/shapes/note.js";
import { getArchiveMenuItem } from "../../../menus/context_menu_utils";
import { t } from "../../../services/i18n";
export function openCalendarContextMenu(e: ContextMenuEvent, noteId: string, parentNote: FNote) {
export function openCalendarContextMenu(e: ContextMenuEvent, note: FNote, parentNote: FNote) {
e.preventDefault();
e.stopPropagation();
@ -17,15 +16,13 @@ export function openCalendarContextMenu(e: ContextMenuEvent, noteId: string, par
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 noteToDelete.getParentBranches()) {
for (const parentBranch of note.getParentBranches()) {
const parentNote = await parentBranch.getNote();
if (parentNote?.hasAncestor(parentNote.noteId)) {
branchIdToDelete = parentBranch.branchId;
@ -40,9 +37,9 @@ export function openCalendarContextMenu(e: ContextMenuEvent, noteId: string, par
{ kind: "separator" },
{
kind: "custom",
componentFn: () => NoteColorPicker({note: noteId})
componentFn: () => NoteColorPicker({note: note})
}
],
selectMenuItemHandler: ({ command }) => link_context_menu.handleLinkContextMenuItem(command, noteId),
selectMenuItemHandler: ({ command }) => link_context_menu.handleLinkContextMenuItem(command, note.noteId),
})
}

View File

@ -3,6 +3,7 @@ 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,
@ -80,7 +81,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 color = note.getLabelValue("calendar:color") ?? note.getLabelValue("color");
const colorClass = note.getColorClass();
const events: EventInput[] = [];
const calendarDisplayedAttributes = note.getLabelValue("calendar:displayedAttributes")?.split(",");
@ -108,10 +109,9 @@ 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: isArchived ? "archived" : ""
className: clsx({archived: isArchived}, colorClass)
};
if (endDate) {
eventData.end = endDate;

View File

@ -1,4 +1,21 @@
: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;
@ -7,8 +24,9 @@
padding: 10px;
}
.calendar-view a {
color: unset;
.calendar-view a,
:root .calendar-view a.fc-daygrid-event:hover {
color: var(--fc-event-text-color);
}
.search-result-widget-content .calendar-view {
@ -31,14 +49,6 @@
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;
}
@ -76,3 +86,106 @@ body.desktop:not(.zen) .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,6 +77,7 @@ 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")
};
@ -306,9 +307,11 @@ function useEventDisplayCustomization(parentNote: FNote) {
$(mainContainer ?? e.el).append($(promotedAttributesHtml));
}
e.el.addEventListener("contextmenu", (contextMenuEvent) => {
const noteId = e.event.extendedProps.noteId;
openCalendarContextMenu(contextMenuEvent, noteId, parentNote);
e.el.addEventListener("contextmenu", async (contextMenuEvent) => {
const note = await froca.getNote(e.event.extendedProps.noteId);
if (!note) return;
openCalendarContextMenu(contextMenuEvent, note, parentNote);
});
}, []);
return { eventDidMount };

View File

@ -74,13 +74,14 @@ export default class SplitNoteContainer extends FlexContainer<SplitNoteWidget> {
const subContexts = activeContext.getSubContexts();
let noteContext: NoteContext;
let noteContext: NoteContext | undefined = undefined;
if (isMobile() && subContexts.length > 1) {
noteContext = subContexts.find(s => s.ntxId !== ntxId)!;
} else {
noteContext = subContexts.find(s => s.ntxId !== ntxId);
}
if (!noteContext) {
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 .title-row > * {
margin: 5px;
.modal.popup-editor-dialog .modal-header .note-title-widget {
margin-top: 8px;
}
.modal.popup-editor-dialog .modal-body {
@ -66,12 +66,17 @@ 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: transparent;
background: var(--modal-background-color);
z-index: 998;
align-items: flex-start;
}

View File

@ -19,6 +19,8 @@ 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);
@ -60,6 +62,16 @@ 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 { CommandNames } from "../../components/app_context.js";
import appContext, { 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,6 +14,7 @@ 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}
>
@ -160,3 +161,7 @@ function Card({ title, children }: { title: string, children: ComponentChildren
</div>
)
}
function editShortcuts() {
appContext.tabManager.openContextWithNote("_optionsShortcuts", { activate: true });
}

View File

@ -0,0 +1,63 @@
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,6 +20,7 @@ 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>();
@ -137,7 +138,7 @@ export default function RevisionsDialog() {
function RevisionsList({ revisions, onSelect, currentRevision }: { revisions: RevisionItem[], onSelect: (val: string) => void, currentRevision?: RevisionItem }) {
return (
<FormList onSelect={onSelect} fullHeight>
<FormList onSelect={onSelect} fullHeight wrapperClassName="revision-list">
{revisions.map((item) =>
<FormListItem
value={item.revisionId}

View File

@ -17,26 +17,33 @@ export default function MobileDetailMenu() {
icon="bx bx-dots-vertical-rounded"
text=""
onClick={(e) => {
const ntxId = (parentComponent as BasicWidget).getClosestNtxId();
const ntxId = (parentComponent as BasicWidget | null)?.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> | false)[] = [
const items: (MenuItem<keyof CommandMappings>)[] = [
{ 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" },
{ 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" }
];
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();
}
contextMenu.show<keyof CommandMappings>({
x: e.pageX,
y: e.pageY,
items: items.filter(i => !!i),
items,
selectMenuItemHandler: async ({ command }) => {
if (command === "insertChildNote") {
note_create.createNote(appContext.tabManager.getActiveContextNotePath() ?? undefined);

View File

@ -6,15 +6,17 @@ 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 }: FormListOpts) {
export default function FormList({ children, onSelect, style, fullHeight, wrapperClassName }: FormListOpts) {
const wrapperRef = useRef<HTMLDivElement | null>(null);
const triggerRef = useRef<HTMLButtonElement | null>(null);
@ -43,7 +45,7 @@ export default function FormList({ children, onSelect, style, fullHeight }: Form
}, [ fullHeight ]);
return (
<div className="dropdownWrapper" ref={wrapperRef} style={builtinStyles}>
<div className={clsx("dropdownWrapper", wrapperClassName)} ref={wrapperRef} style={builtinStyles}>
<div className="dropdown" style={builtinStyles}>
<button
ref={triggerRef}

View File

@ -1,3 +1,4 @@
import clsx from "clsx";
import { useEffect, useRef, useMemo } from "preact/hooks";
import { t } from "../../services/i18n";
import { ComponentChildren } from "preact";
@ -7,9 +8,16 @@ 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;
/**
@ -72,7 +80,7 @@ interface ModalProps {
noFocus?: boolean;
}
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) {
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) {
const modalRef = useSyncedRef<HTMLDivElement>(externalModalRef);
const modalInstanceRef = useRef<BootstrapModal>();
const elementToFocus = useRef<Element | null>();
@ -148,7 +156,17 @@ export default function Modal({ children, className, size, title, header, footer
{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, FormListItem } from "../react/FormList";
import { FormDropdownDivider, FormListHeader, 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,8 +113,7 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
function DevelopmentActions({ note }: { note: FNote }) {
return (
<>
<FormDropdownDivider />
<FormListItem disabled>Development-only Actions</FormListItem>
<FormListHeader text="Development-only Actions" />
<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: true,
activate: () => !options.is("editedNotesOpenInRibbon"),
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: ({ note }) => (note?.getPromotedDefinitionAttributes().length === 0 || !options.is("promotedAttributesOpenInRibbon")) && options.is("editedNotesOpenInRibbon")
activate: () => options.is("editedNotesOpenInRibbon")
},
{
title: t("book_properties.book_properties"),

View File

@ -28,6 +28,7 @@ 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,6 +22,7 @@ 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,10 +1,12 @@
import { Language } from "@excalidraw/excalidraw/i18n";
import type { DISPLAYABLE_LOCALE_IDS } from "@triliumnext/commons";
export const LANGUAGE_MAPPINGS: Record<DISPLAYABLE_LOCALE_IDS, string | null> = {
export const LANGUAGE_MAPPINGS: Record<DISPLAYABLE_LOCALE_IDS, Language["code"] | 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,6 +55,7 @@ export function buildClassicToolbar(multilineToolbar: boolean) {
...TEXT_FORMATTING_GROUP,
items: ["underline", "strikethrough", "|", "superscript", "subscript", "|", "kbd"]
},
"formatPainter",
"|",
"fontColor",
"fontBackgroundColor",
@ -104,6 +105,7 @@ export function buildFloatingToolbar() {
...TEXT_FORMATTING_GROUP,
items: [ "strikethrough", "|", "superscript", "subscript", "|", "kbd" ]
},
"formatPainter",
"|",
"fontColor",
"fontBackgroundColor",

View File

@ -1,8 +1,9 @@
import path from "path";
import path, { join } 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;
@ -228,8 +229,22 @@ const config: ForgeConfig = {
// Ensure all locales that should be kept are actually present.
for (const locale of localesToKeep) {
if (!keptLocales.has(locale)) {
console.error(`Locale ${locale} was not found in the packaged app.`);
process.exit(1);
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}`);
}
}
}
},
@ -284,4 +299,20 @@ 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.20.6",
"tsx": "4.21.0",
"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");
await expect(languageCombobox).toContainText("English (United States)");
// 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");
await languageCombobox.selectOptionByText("English (United States)");
await app.currentNoteSplit.locator("button[name=restart-app-button]").click();
await expect(app.currentNoteSplit).toContainText("Language", { timeout: 15000 });
await expect(languageCombobox).toContainText("English");
await expect(languageCombobox).toContainText("English (United States)");
});

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>The <em>Floating toolbar</em> is hidden by default and only appears when
<li data-list-item-id="eafcb31c309cb140eedbb41048a0e0db1">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>A toolbar that appears when text is selected. This provides text-level
<li data-list-item-id="e59aa3103fa4c5de33075e51f8d482164">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,6 +20,8 @@
<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>
@ -33,12 +35,12 @@
</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>
<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>
@ -47,9 +49,9 @@
</td>
<td>
<ul>
<li>Bulleted lists</li>
<li>Numbered lists</li>
<li>To-do lists</li>
<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>
@ -58,8 +60,8 @@
</td>
<td>
<ul>
<li>Block quotes</li>
<li>Admonitions</li>
<li data-list-item-id="e2892dc35a0d4b7ad65daffb8f9404daa">Block quotes</li>
<li data-list-item-id="e7297e3ad1002f8de15aa0bd66c6f3f22">Admonitions</li>
</ul>
</td>
</tr>
@ -68,10 +70,10 @@
</td>
<td>
<ul>
<li>Basic tables</li>
<li>Merging cells</li>
<li>Styling tables and cells.</li>
<li>Table captions</li>
<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>
@ -80,9 +82,9 @@
</td>
<td>
<ul>
<li>Inline code</li>
<li>Code blocks</li>
<li>Keyboard shortcuts</li>
<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>
@ -91,7 +93,7 @@
</td>
<td>
<ul>
<li>Footnotes</li>
<li data-list-item-id="edf62ec004eff35cfcb7e361deef19aaf">Footnotes</li>
</ul>
</td>
</tr>
@ -100,7 +102,7 @@
</td>
<td>
<ul>
<li>Images</li>
<li data-list-item-id="ebe6277e643041403489c3ceb30c36f7f">Images</li>
</ul>
</td>
</tr>
@ -109,8 +111,8 @@
</td>
<td>
<ul>
<li>External links</li>
<li>Internal Trilium links</li>
<li data-list-item-id="e3f988be2f259bb40607cb61541955395">External links</li>
<li data-list-item-id="e3f91cc4f0cccd2c077cc306bacd68ef2">Internal Trilium links</li>
</ul>
</td>
</tr>
@ -119,7 +121,7 @@
</td>
<td>
<ul>
<li>Include note</li>
<li data-list-item-id="eac8015a64bce7b749cc67d1599062007">Include note</li>
</ul>
</td>
</tr>
@ -128,12 +130,12 @@
</td>
<td>
<ul>
<li>Symbols</li>
<li><a class="reference-link" href="#root/_help_YfYAtQBcfo5V">Math Equations</a>
<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>Mermaid diagrams</li>
<li>Horizontal ruler</li>
<li>Page break</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>
@ -142,12 +144,12 @@
</td>
<td>
<ul>
<li>Indentation
<li data-list-item-id="e0c14456cb83d483b07ea432ef9d4728e">Indentation
<ul>
<li>Markdown import</li>
<li data-list-item-id="e2029812c5e105c595590f70ee227631e">Markdown import</li>
</ul>
</li>
<li><a class="reference-link" href="#root/_help_2x0ZAX9ePtzV">Cut to subnote</a>
<li data-list-item-id="ea1ee012286e05190c89c9f4e64cf2036"><a class="reference-link" href="#root/_help_2x0ZAX9ePtzV">Cut to subnote</a>
</li>
</ul>
</td>
@ -157,16 +159,18 @@
</td>
<td>
<ul>
<li><a class="reference-link" href="#root/_help_ZlN4nump6EbW">Slash Commands</a>
<li data-list-item-id="e1ab173193a533ccf33dccfd0cb916f1f"><a class="reference-link" href="#root/_help_ZlN4nump6EbW">Slash Commands</a>
</li>
<li><a class="reference-link" href="#root/_help_KC1HB96bqqHX">Templates</a>
<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

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><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>
<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>
</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><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>
<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>
</ul>
<p>Alternatively, Markdown-like formatting can be used:</p>
<ul>
<li><strong>Bold</strong>: Type <code>**text**</code> or <code>__text__</code>
<li data-list-item-id="e90b0f040ab78084c41cd8f44045528ec"><strong>Bold</strong>: Type <code>**text**</code> or <code>__text__</code>
</li>
<li><em>Italic</em>: Type <code>*text*</code> or <code>_text_</code>
<li data-list-item-id="eebc210ee7f2b92e0885cd411c6fb8b80"><em>Italic</em>: Type <code>*text*</code> or <code>_text_</code>
</li>
<li><del>Strikethrough</del>: Type <code>~~text~~</code>
<li data-list-item-id="eb7628d2cb441576b3b3edf6c42ab84b4"><del>Strikethrough</del>: Type <code>~~text~~</code>
</li>
</ul>
<h2>Superscript, subscript</h2>
@ -89,6 +89,11 @@
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

@ -0,0 +1,45 @@
<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

@ -0,0 +1 @@
<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>

After

Width:  |  Height:  |  Size: 386 B

View File

@ -0,0 +1,7 @@
<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>

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -0,0 +1 @@
{}

View File

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

View File

@ -7,11 +7,13 @@ 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,7 +129,6 @@ 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": "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."
"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."
},
"productivity_benefits": {
"revisions_title": "Notizrevisionen",

View File

@ -0,0 +1 @@
{}

View File

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

332
docs/README-en_GB.md vendored Normal file
View File

@ -0,0 +1,332 @@
<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,50 +33,39 @@ 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.
## ⏬ دانلود
- [آخرین انتشار]{1} نسخه پایدار، برای بیشتر کاربران پیشنهاد می‌شود.
- [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
مستندات ما در چندین قالب مختلف در دسترس است:
- مستندات آنلاین: می‌توانید نسخهٔ کامل مستندات را در
[docs.triliumnotes.org](https://docs.triliumnotes.org/) مرور کنید
- ** In-App Help **: Press `F1 ` در Trilium برای دسترسی به همان اسناد به طور
مستقیم در برنامه
- ** GitHub **: از طریق [راهنمای کاربر] در این مخزن حرکت کنید
### 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)
### لینک‌های سریع
- راهنمای شروع کار
- دستورالعمل‌های نصب
- راه‌اندازی داکر
- ارتقای TriliumNext
- مفاهیم و ویژگی‌های پایه
- الگوهای پایگاه دانشی شخصی
## 🎁 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
* یادداشت‌ها می‌توانند در یک درخت با عمق دلخواه سازمان‌دهی شوند. یک یادداشت
می‌تواند در چندین نقطهٔ مختلف از درخت قرار گیرد.
* ویرایشگر یادداشت غنی WYSIWYG از جمله جداول، تصاویر و [math] [1] با علامت گذاری
[autoformat] [2]
* پشتیبانی از ویرایش [یادداشت با کد منبع][۱]، از جمله نحو برجسته
* Fast and easy [navigation between
notes](https://triliumnext.github.io/Docs/Wiki/note-navigation), full text
search and [note

View File

@ -2380,6 +2380,20 @@
"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",
@ -2393,20 +2407,6 @@
"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,45 +5207,59 @@
{
"type": "relation",
"name": "internalLink",
"value": "MMiBEQljMQh2",
"value": "DvdZhoQZY9Yd",
"isInheritable": false,
"position": 10
},
{
"type": "relation",
"name": "internalLink",
"value": "zEY4DaJG4YT5",
"value": "MMiBEQljMQh2",
"isInheritable": false,
"position": 20
},
{
"type": "relation",
"name": "internalLink",
"value": "iPIMuisry3hd",
"value": "zEY4DaJG4YT5",
"isInheritable": false,
"position": 30
},
{
"type": "relation",
"name": "internalLink",
"value": "TBwsyfadTA18",
"isInheritable": false,
"position": 40
},
{
"type": "relation",
"name": "internalLink",
"value": "oiVPnW8QfnvS",
"value": "iPIMuisry3hd",
"isInheritable": false,
"position": 50
},
{
"type": "relation",
"name": "internalLink",
"value": "QrtTYPmdd1qq",
"value": "oiVPnW8QfnvS",
"isInheritable": false,
"position": 60
},
{
"type": "relation",
"name": "internalLink",
"value": "eIg8jdvaoNNd",
"value": "QrtTYPmdd1qq",
"isInheritable": false,
"position": 70
},
{
"type": "relation",
"name": "internalLink",
"value": "eIg8jdvaoNNd",
"isInheritable": false,
"position": 80
},
{
"type": "label",
"name": "shareAlias",
@ -5259,20 +5273,6 @@
"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,6 +6244,13 @@
"value": "",
"isInheritable": false,
"position": 40
},
{
"type": "relation",
"name": "internalLink",
"value": "5wZallV2Qo1t",
"isInheritable": false,
"position": 220
}
],
"format": "markdown",
@ -6914,6 +6921,13 @@
"value": "general-formatting",
"isInheritable": false,
"position": 60
},
{
"type": "relation",
"name": "internalLink",
"value": "5wZallV2Qo1t",
"isInheritable": false,
"position": 70
}
],
"format": "markdown",
@ -8423,6 +8437,81 @@
"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. |
| `#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*) |
| `#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>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>
<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>
## Read-Only vs. Editing Mode

View File

@ -79,6 +79,10 @@ 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

@ -0,0 +1,20 @@
# 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

@ -0,0 +1 @@
<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>

After

Width:  |  Height:  |  Size: 386 B

View File

@ -0,0 +1,7 @@
<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>

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

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.3.0",
"eslint-plugin-playwright": "2.4.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.20.6",
"tsx": "4.21.0",
"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.20.1"
"webdriverio": "9.21.0"
},
"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.20.1"
"webdriverio": "9.21.0"
},
"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.20.1"
"webdriverio": "9.21.0"
},
"peerDependencies": {
"ckeditor5": "47.2.0"

View File

@ -25,7 +25,6 @@
],
"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",
@ -43,7 +42,7 @@
"typescript": "5.9.3",
"vite-plugin-svgo": "~2.0.0",
"vitest": "4.0.14",
"webdriverio": "9.20.1"
"webdriverio": "9.21.0"
},
"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.20.1"
"webdriverio": "9.21.0"
},
"peerDependencies": {
"ckeditor5": "47.2.0"

View File

@ -10,6 +10,11 @@ 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,4 +1,5 @@
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 } from "ckeditor5-premium-features";
import { SlashCommand, Template, FormatPainter } from "ckeditor5-premium-features";
import type { Plugin } from "ckeditor5";
import CutToNotePlugin from "./plugins/cuttonote.js";
import UploadimagePlugin from "./plugins/uploadimage.js";
@ -83,7 +83,8 @@ export const CORE_PLUGINS: typeof Plugin[] = [
*/
export const PREMIUM_PLUGINS: typeof Plugin[] = [
SlashCommand,
Template
Template,
FormatPainter
];
/**

View File

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

View File

@ -121,7 +121,6 @@ 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