Compare commits

...

1397 Commits

Author SHA1 Message Date
perfectra1n
d7d411caf9 feat(dev): remove ai/llm features 2026-02-07 13:04:37 -08:00
Elian Doran
2cd3d4bfb7 Simple content library for icon packs (#8650) 2026-02-07 16:52:08 +02:00
Elian Doran
9d9065c801 feat(website): add GitHub link on mid-size 2026-02-07 16:42:40 +02:00
Elian Doran
10e7fe56ab feat(website): add GitHub link on mobile 2026-02-07 16:36:53 +02:00
Elian Doran
c832e62389 fix(website): page not rendering properly on cold refresh 2026-02-07 16:29:34 +02:00
Elian Doran
328e488322 chore(website): address requested changes 2026-02-07 16:18:51 +02:00
Elian Doran
fd5a43cdb4 Translations update from Hosted Weblate (#8648) 2026-02-07 13:54:22 +02:00
Elian Doran
11c23e0b5e chore(deps): update dependency eslint to v10 (#8647) 2026-02-07 13:51:39 +02:00
Elian Doran
1170cfd4a7 fix(website): stargrazers count still not updating due to hydration 2026-02-07 13:47:25 +02:00
Elian Doran
2eddaa954e chore: address requested changes 2026-02-07 12:38:41 +02:00
Elian Doran
2c472fd03f docs(user): improve docuemntation slightly on icon packs 2026-02-07 12:37:10 +02:00
Elian Doran
16019a787e fix(website): stargazers count not updating 2026-02-07 12:27:16 +02:00
Elian Doran
717d0a75f4 chore(website): improve fit for full-height section 2026-02-07 12:20:24 +02:00
Elian Doran
cc9487bae8 chore(website): fix warnings & type issue 2026-02-07 12:17:14 +02:00
Elian Doran
5ed9ec8f46 fix(website): unnecessary horizontal scroll on md screen 2026-02-07 12:11:41 +02:00
Elian Doran
6ca37ca7f4 feat(header): improve header fit on smaller screens 2026-02-07 11:56:51 +02:00
Elian Doran
1007b8b15d fix(website): subpixel scaling causing issues at 719px 2026-02-07 11:47:30 +02:00
Elian Doran
be3a95fd54 chore(website): add resources to header 2026-02-07 11:19:46 +02:00
Elian Doran
109cb6cc3f chore(website/resources): add descriptions to fonts 2026-02-07 11:18:05 +02:00
Elian Doran
fe1509dcfc chore(website/resources): display version slightly smaller 2026-02-07 11:09:09 +02:00
Elian Doran
1797e33989 feat(website/resources): add intro blurb for icon packs 2026-02-07 11:08:03 +02:00
Elian Doran
6c504eeb3e feat(website/resources): make downloadable 2026-02-07 10:52:23 +02:00
Elian Doran
d4b16fcdd1 feat(website/resources): display icon packs 2026-02-07 10:36:00 +02:00
Elian Doran
9a08c079b5 chore(icon-pack-builder): build directly in website resource path 2026-02-07 10:24:32 +02:00
Elian Doran
98e75a7d6c chore(icon-pack-builder): generate meta alongside files 2026-02-07 10:17:58 +02:00
Elian Doran
675fd13391 chore(icon-pack-builder): add website and version meta 2026-02-07 10:15:55 +02:00
Elian Doran
e4f042aba4 fix(content_renderer): prevent iconPacks from rendering in preview 2026-02-07 09:59:53 +02:00
Elian Doran
19527845d1 fix(tree): wrong icon on multi selection with custom icons 2026-02-07 09:54:50 +02:00
Elian Doran
3aa981649c fix(icon-pack-builder): wrong icon for boxicons3-brands 2026-02-07 09:51:21 +02:00
Elian Doran
330d48f70d chore(website): create empty resources page 2026-02-07 09:42:42 +02:00
noobhjy
90e14aae99 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (1772 of 1772 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hans/
2026-02-07 02:01:52 +01:00
green
77e2ed7e01 Translated using Weblate (Japanese)
Currently translated at 100.0% (1772 of 1772 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ja/
2026-02-07 02:01:50 +01:00
renovate[bot]
f720f921c3 chore(deps): update dependency eslint to v10 2026-02-07 00:36:40 +00:00
Elian Doran
25667e84b7 fix(deps): update dependency force-graph to v1.51.1 (#8632) 2026-02-06 22:40:03 +02:00
Elian Doran
72e0d77be5 chore(i18n): fix more issues related to Irish 2026-02-06 21:44:39 +02:00
Elian Doran
9ac4b9ed4f docs(dev): refresh adding new locale 2026-02-06 21:18:29 +02:00
Elian Doran
b3b89ba05c chore(i18n): fix calendar mapping for Irish 2026-02-06 21:16:07 +02:00
Elian Doran
00dc04df25 chire(pdfjs): fix handling of Irish 2026-02-06 20:46:26 +02:00
Elian Doran
21d47c3fef chore(i18n): fix issues with ga 2026-02-06 20:24:16 +02:00
Elian Doran
66de94f050 feat(i18n): enable Irish language 2026-02-06 19:56:37 +02:00
Elian Doran
1917adb322 chore(scripts): improve messages for translation check script 2026-02-06 19:38:24 +02:00
Elian Doran
3360b29354 Translations update from Hosted Weblate (#8599) 2026-02-06 10:32:09 +02:00
aloeaqua
646d281759 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (1768 of 1768 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hant/
2026-02-05 21:44:58 +00:00
aloeaqua
e268d92d52 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (389 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/zh_Hant/
2026-02-05 21:44:57 +00:00
Aindriú Mac Giolla Eoin
fa81db2f03 Translated using Weblate (Irish)
Currently translated at 100.0% (1768 of 1768 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ga/
2026-02-05 21:44:56 +00:00
Marcel
830199ba3a Translated using Weblate (German)
Currently translated at 100.0% (1768 of 1768 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-02-05 21:44:56 +00:00
Ulices
ea8dc506d3 Translated using Weblate (Spanish)
Currently translated at 100.0% (1768 of 1768 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/es/
2026-02-05 21:44:55 +00:00
ibs-allaow
c95483ed94 Translated using Weblate (Arabic)
Currently translated at 49.1% (57 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/ar/
2026-02-05 21:44:54 +00:00
ibs-allaow
d9cb4480b2 Translated using Weblate (Arabic)
Currently translated at 59.8% (1058 of 1768 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ar/
2026-02-05 21:44:53 +00:00
ibs-allaow
c69afd6074 Translated using Weblate (Arabic)
Currently translated at 64.4% (98 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/ar/
2026-02-05 21:44:53 +00:00
ibs-allaow
f541790ab4 Translated using Weblate (Arabic)
Currently translated at 48.2% (56 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/ar/
2026-02-05 21:44:52 +00:00
green
707ac4ec36 Translated using Weblate (Japanese)
Currently translated at 100.0% (1768 of 1768 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ja/
2026-02-05 21:44:51 +00:00
noobhjy
cd55133e96 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (1768 of 1768 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hans/
2026-02-05 21:44:50 +00:00
ibs-allaow
37a91f8529 Translated using Weblate (Arabic)
Currently translated at 59.7% (1057 of 1768 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ar/
2026-02-05 21:44:49 +00:00
Aindriú Mac Giolla Eoin
0ed0fa37a1 Translated using Weblate (Irish)
Currently translated at 55.4% (981 of 1768 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ga/
2026-02-05 21:44:48 +00:00
ibs-allaow
26728b79b2 Translated using Weblate (Arabic)
Currently translated at 59.7% (1056 of 1768 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ar/
2026-02-05 21:44:47 +00:00
ibs-allaow
f7c8723539 Translated using Weblate (Arabic)
Currently translated at 63.1% (96 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/ar/
2026-02-05 21:44:47 +00:00
Hosted Weblate
c313916771 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/
2026-02-05 21:44:46 +00:00
Elian Doran
f0b30c5e91 Mobile improvements v2 (#8615) 2026-02-05 23:44:31 +02:00
Elian Doran
73e3196124 docs(user): improve documentation on mobile support 2026-02-05 23:31:12 +02:00
Elian Doran
8a7bcc316e chore(mobile): address requested changes 2026-02-05 22:25:01 +02:00
Elian Doran
a2921cb982 fix(mobile): missing snap in board view 2026-02-05 22:15:41 +02:00
Elian Doran
29ce004974 chore(mobile): add possible work-around for note switcher sometimes disappearing 2026-02-05 22:13:09 +02:00
Elian Doran
026ba5ddce chore(mobile/attachments): improve layout 2026-02-05 22:02:11 +02:00
Elian Doran
ab0585609a chore(mobile/attachments): use bottom-style menu for actions 2026-02-05 21:57:49 +02:00
Elian Doran
14a8bdb0c0 chore(launch_bar): add backdrop on mobile for dropdown menus 2026-02-05 21:53:54 +02:00
Elian Doran
397d04dd88 style(client): fix rounded corners in launcher bar dropdown 2026-02-05 21:48:38 +02:00
Elian Doran
fbb0bb7491 Revert "feat(mobile): make the sidebar gesture easier to press"
This reverts commit f8b386e42d.
2026-02-05 21:47:40 +02:00
Elian Doran
ee987dae99 refactor(client): fix typo in container 2026-02-05 21:44:48 +02:00
Elian Doran
720281a8db feat(bookmarks): support bookmark folders on mobile 2026-02-05 21:43:58 +02:00
Elian Doran
ff0c89e5a3 feat(bookmarks): collapse on mobile into single icon (closes #5464) 2026-02-05 21:28:50 +02:00
Elian Doran
442937f540 feat(bookmarks): add launcher on mobile 2026-02-05 21:20:22 +02:00
Elian Doran
dc01b787c1 fix(launch_bar): cannot create new items in mobile launch bar (fixes #8054) 2026-02-05 21:10:05 +02:00
Elian Doran
c709b5d34c chore(mobile): relocate some note actions 2026-02-05 18:42:51 +02:00
Elian Doran
f8b386e42d feat(mobile): make the sidebar gesture easier to press 2026-02-05 16:43:06 +02:00
Elian Doran
a82f8ce3ad Merge remote-tracking branch 'origin/main' into feature/mobile_improvements_v2 2026-02-05 10:28:02 +02:00
Elian Doran
529d45b762 chore(deps): update dependency @types/node to v24.10.10 (#8610) 2026-02-05 09:45:49 +02:00
Elian Doran
d31135bf21 fix(mobile): status bar color for Samsung Internet 2026-02-05 09:09:47 +02:00
Elian Doran
75a77acefe Merge remote-tracking branch 'origin/main' into feature/mobile_improvements_v2 2026-02-05 09:09:41 +02:00
renovate[bot]
715f42b6c3 fix(deps): update dependency force-graph to v1.51.1 2026-02-05 01:13:22 +00:00
Elian Doran
199bfc8a37 Adjust next theme development docu (#8616) 2026-02-04 21:50:36 +02:00
hulmgulm
e82ae762f0 More fixes 2026-02-04 20:48:36 +01:00
hulmgulm
f90cc9aff7 Adjust theme development docu 2026-02-04 20:39:58 +01:00
Elian Doran
ec915177ad feat(mobile): add search to launch bar 2026-02-04 21:36:00 +02:00
Elian Doran
5adee3e217 fix(mobile/search): missing rounded corners for bulk actions 2026-02-04 21:31:23 +02:00
Elian Doran
278d82645e feat(mobile): use safe area for bottom-aligned menus 2026-02-04 21:15:08 +02:00
Elian Doran
e66f13b471 feat(mobile/search): use bottom menus for large dropdowns 2026-02-04 21:11:43 +02:00
Elian Doran
0e2955b57e feat(mobile/search): group search buttons into split 2026-02-04 21:06:20 +02:00
Elian Doran
2a4d5ec1ec feat(mobile/search): group search options in dropdown 2026-02-04 20:55:55 +02:00
Elian Doran
07ce63de69 chore(mobile/search): remove redundant margin 2026-02-04 20:44:15 +02:00
Elian Doran
b539862eef fix(mobile/search): duplicate search parameters 2026-02-04 20:41:36 +02:00
Elian Doran
ac4be3f8a8 feat(mobile/global_menu): add option to search notes 2026-02-04 20:40:31 +02:00
Elian Doran
0dc2d07b58 fix(mobile): virtual keyboard detection not working on iOS 2026-02-04 19:09:18 +02:00
Elian Doran
b097f9dc21 fix(mobile): fixed tree overflowing container 2026-02-04 18:53:32 +02:00
Elian Doran
8aa4a97480 fix(mobile): fixed tree for launcher duplicated in split 2026-02-04 18:52:46 +02:00
Elian Doran
3e54d0ceae chore(hidden_tree): add icon to mobile tab switcher launcher 2026-02-04 18:48:37 +02:00
Elian Doran
e1cec3404a Merge remote-tracking branch 'origin/main' into feature/mobile_improvements_v2
; Conflicts:
;	apps/client/src/widgets/mobile_widgets/mobile_detail_menu.tsx
2026-02-04 18:46:38 +02:00
Elian Doran
9a2b7fbda1 Feature/mobile improvement bugs (#8614) 2026-02-04 18:45:35 +02:00
Elian Doran
e0b4ebed93 chore(mobile): address requested changes 2026-02-04 18:40:30 +02:00
Elian Doran
e00e3999c5 feat(mobile/note_actions): indicate current content language 2026-02-04 18:05:37 +02:00
Elian Doran
2cbe96d815 feat(mobile/note_actions): integrate text content language switcher 2026-02-04 18:03:17 +02:00
Elian Doran
ac3b289c9e feat(mobile): more stable fixed tree for launch bar config 2026-02-04 16:46:22 +02:00
Elian Doran
62534e0e93 chore(mobile/tab_switcher): launcher preview not looking good 2026-02-04 16:43:46 +02:00
Elian Doran
b802c3174c style(mobile): add top border to bottom bar 2026-02-04 16:29:51 +02:00
Elian Doran
aee1a6e1f0 fix(note_list): regression in the display of no previews 2026-02-04 16:28:07 +02:00
Elian Doran
46f1cd38e0 feat(mobile): enforce backdrop effects off 2026-02-04 16:24:14 +02:00
Elian Doran
7f891ef523 feat(mobile/tab_switcher): improve display for some text elements 2026-02-04 15:44:17 +02:00
Elian Doran
06af5e15cd feat(mobile/tab_switcher): consider view scope for preview 2026-02-04 15:41:15 +02:00
Elian Doran
af89a0a883 fix(new_layout): note title actions shown in non-standard view modes 2026-02-04 15:17:39 +02:00
Elian Doran
fa72eb2edb fix(mobile/tab_switcher): view mode not displayed in title 2026-02-04 14:53:00 +02:00
Elian Doran
c1ea94423b refactor(client): use CSS file for content renderer 2026-02-04 14:46:52 +02:00
Elian Doran
1e70d066bd fix(mobile/tab_switcher): wrong preview for relation map 2026-02-04 14:39:58 +02:00
Elian Doran
ab89f16e7c fix(mobile): unnecessary separator for custom note actions 2026-02-04 14:29:47 +02:00
Elian Doran
8c848a4cb5 fix(mobile): wrong context activation logic when creating new split 2026-02-04 14:04:47 +02:00
Elian Doran
e021a54d2d fix(mobile): formatting toolbar not appearing after read-only (closes #5368) 2026-02-04 13:42:30 +02:00
Elian Doran
70523574b0 refactor(client): extract mobile layout CSS to dedicated file 2026-02-04 13:37:04 +02:00
Elian Doran
66e0f1ab19 chore(mobile/tree): slightly bigger expanders 2026-02-04 13:29:45 +02:00
Elian Doran
671a05470e fix(mobile): missing badge style in tree 2026-02-04 13:24:08 +02:00
Elian Doran
99eec0c41e fix(mobile): duplicate promoted attributes 2026-02-04 13:18:26 +02:00
Elian Doran
48d06dcb06 fix(mobile): note context menu too tall in browser 2026-02-04 13:17:28 +02:00
Elian Doran
e38df0c731 fix(mobile): note paths dialog doesn't trigger clone note to location 2026-02-04 13:06:49 +02:00
Elian Doran
0f3f49915e fix(mobile): note actions should be at the bottom, not above launch bar 2026-02-04 12:24:56 +02:00
Elian Doran
416144265b fix(client): wrong positioning of modals due to mobile changes 2026-02-04 12:06:29 +02:00
renovate[bot]
2e7ced8e60 Update dependency @types/node to v24.10.10 2026-02-04 01:52:42 +00:00
Adorian Doran
fe02871e91 Merge branch 'main' of https://github.com/TriliumNext/Trilium 2026-02-04 00:45:03 +02:00
Adorian Doran
bb05aeeaf7 style/split: tweak transition for the current split indicator 2026-02-04 00:44:54 +02:00
Elian Doran
846358ccb0 Update dependency @redocly/cli to v2.15.1 (#8601) 2026-02-03 23:45:18 +02:00
Elian Doran
dabc779727 Update dependency @smithy/middleware-retry to v4.4.30 (#8602) 2026-02-03 23:45:02 +02:00
Elian Doran
08fd2ec64b Update dependency happy-dom to v20.5.0 (#8603) 2026-02-03 23:44:32 +02:00
Adorian Doran
c42c06d048 style/global menu: use proper heading for the development options section 2026-02-03 21:01:08 +02:00
Adorian Doran
e951d60800 style/options: hide collection properties 2026-02-03 20:54:56 +02:00
Elian Doran
0d8453f6a7 feat(mobile/note_actions): integrate code language switcher 2026-02-03 18:58:04 +02:00
Elian Doran
52b41b1bb0 feat(mobile/note_actions): integrate similar notes 2026-02-03 18:18:57 +02:00
Elian Doran
c7265017b3 feat(mobile/note_actions): integrate styling for note info 2026-02-03 18:09:02 +02:00
Elian Doran
634e0b6d30 feat(mobile/note_actions): integrate note info 2026-02-03 18:04:08 +02:00
renovate[bot]
1c260f5890 Update dependency happy-dom to v20.5.0 2026-02-03 01:34:19 +00:00
renovate[bot]
177aedeaae Update dependency @smithy/middleware-retry to v4.4.30 2026-02-03 01:33:28 +00:00
renovate[bot]
3f6f3d2565 Update dependency @redocly/cli to v2.15.1 2026-02-03 01:32:42 +00:00
Adorian Doran
38489dbfeb style/collapsible widget: fade content when expanding or collapsing 2026-02-03 03:03:50 +02:00
Adorian Doran
ff2a3d6a28 client/search: fix menu dropdowns getting clipped 2026-02-03 02:56:46 +02:00
Adorian Doran
2c74697fb1 style/text editor: tweak the content placeholder 2026-02-03 02:22:04 +02:00
Adorian Doran
110e9200b9 style/scrolling container: improve alignment when content centering is turned on, refactor 2026-02-03 02:11:57 +02:00
Adorian Doran
6e792f9735 style/tree/tree item icons: fix color for tinted tree items 2026-02-03 01:25:28 +02:00
Adorian Doran
51d8b13a81 style/tree: tweak the color of tree item icons for the dark color scheme 2026-02-03 01:19:47 +02:00
Adorian Doran
a05691fd07 style/tree: add a CSS variable to customize the color of tree item icons 2026-02-03 00:52:36 +02:00
Adorian Doran
d25e7915d9 style/tree/context menu: use the proper color for menu item icons 2026-02-03 00:41:41 +02:00
Elian Doran
1a025dfef3 Translations update from Hosted Weblate (#8581) 2026-02-02 22:09:13 +02:00
ibs-allaow
84cc4194aa Translated using Weblate (Arabic)
Currently translated at 61.1% (93 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/ar/
2026-02-02 21:07:55 +01:00
ibs-allaow
331a56277c Translated using Weblate (Arabic)
Currently translated at 59.7% (1055 of 1767 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ar/
2026-02-02 21:07:54 +01:00
ibs-allaow
bc2915adb9 Translated using Weblate (Arabic)
Currently translated at 42.2% (49 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/ar/
2026-02-02 21:07:53 +01:00
Elian Doran
703fe9a71b Translated using Weblate (Romanian)
Currently translated at 100.0% (389 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/ro/
2026-02-02 21:07:52 +01:00
Elian Doran
6c50664046 Translated using Weblate (Romanian)
Currently translated at 99.9% (1766 of 1767 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ro/
2026-02-02 21:07:51 +01:00
Aindriú Mac Giolla Eoin
673cbc97e1 Translated using Weblate (Irish)
Currently translated at 100.0% (389 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/ga/
2026-02-02 21:07:49 +01:00
Aindriú Mac Giolla Eoin
3e83766099 Translated using Weblate (Irish)
Currently translated at 0.1% (1 of 1767 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ga/
2026-02-02 21:07:48 +01:00
Aindriú Mac Giolla Eoin
b453589077 Translated using Weblate (Irish)
Currently translated at 100.0% (152 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/ga/
2026-02-02 21:07:47 +01:00
Hosted Weblate
654fa18ab1 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/
2026-02-02 21:07:45 +01:00
Elian Doran
7b0d91534c Add subtreeHidden and map:* attributes to labels documentation (#8594) 2026-02-02 22:07:34 +02:00
Elian Doran
8d4801bb6f Mobile: integrate new layout v1 (#8595) 2026-02-02 21:47:34 +02:00
Elian Doran
9e36f4f625 Merge branch 'main' into feature/mobile_improvements 2026-02-02 21:44:22 +02:00
Elian Doran
d83a824812 chore(client): address requested changes 2026-02-02 21:43:27 +02:00
Elian Doran
ca128f2fa9 chore(client): address requested changes 2026-02-02 21:19:35 +02:00
Elian Doran
c02642d0f9 feat(mobile/note_actions): display backlinks & note paths on same row 2026-02-02 21:16:02 +02:00
Adorian Doran
7340709111 style/quick edit: refactor 2026-02-02 21:13:16 +02:00
hulmgulm
56d0383372 Merge branch 'main' into main 2026-02-02 20:10:42 +01:00
Adorian Doran
49d33ea19a style/quick edit: allow object selection rectangle to go outside of the editor area 2026-02-02 21:10:00 +02:00
hulmgulm
979fa0359a updated texts 2026-02-02 20:08:55 +01:00
Elian Doran
c7381d058a feat(mobile/note_actions): proper styling of note paths 2026-02-02 21:05:25 +02:00
Adorian Doran
5db298f031 style/quick edit: increase the horizontal padding of the text to make space for the block toolbar button 2026-02-02 21:03:02 +02:00
Elian Doran
171d948a00 feat(mobile/note_actions): basic integration of note paths 2026-02-02 21:00:05 +02:00
Adorian Doran
facd56cdf4 style/text editor/block toolbar button: tweak 2026-02-02 20:57:38 +02:00
Elian Doran
ba17ec4be4 chore(backlinks): show multiple excerpts properly 2026-02-02 20:44:48 +02:00
Elian Doran
6c163b5479 chore(mobile/note_actions): flickerless backlinks item 2026-02-02 20:39:37 +02:00
Elian Doran
79649805b8 chore(mobile/note_actions): missing translation for backlinks 2026-02-02 20:34:52 +02:00
Elian Doran
220ca8a570 chore(mobile/note_actions): use new layout styling for backlinks 2026-02-02 20:32:06 +02:00
Adorian Doran
348c00f86d style/text editor: fix layout issues 2026-02-02 20:13:00 +02:00
Elian Doran
12b641b522 feat(mobile/note_actions): basic integration of backlinks 2026-02-02 20:10:20 +02:00
hulmgulm
6855bc1de6 Merge branch 'TriliumNext:main' into main 2026-02-02 19:09:08 +01:00
Adorian Doran
a9c5b99ae8 style/text editor/block toolbar button: fix position and z-index 2026-02-02 20:06:05 +02:00
Elian Doran
76f36e2fd3 fix(mobile/custom_note_actions): unable to close empty pane 2026-02-02 18:39:40 +02:00
Adorian Doran
afe710321c style/text editor: fix layout issues 2026-02-02 18:34:22 +02:00
Elian Doran
0d444daaca fix(mobile/custom_note_actions): note icon shown in empty note 2026-02-02 18:29:21 +02:00
Elian Doran
c8a0c9fd23 chore(mobile/custom_note_actions): text not fitting 2026-02-02 18:26:40 +02:00
Elian Doran
79f07ae923 chore(mobile/custom_note_actions): disable split orientation button 2026-02-02 18:23:54 +02:00
Elian Doran
c77e7a568b chore(mobile/custom_note_actions): duplicate open help 2026-02-02 18:11:58 +02:00
Elian Doran
ff9ec2057b chore(mobile/custom_note_actions): hide open note externally 2026-02-02 18:10:26 +02:00
Elian Doran
6a313b99e4 fix(mobile/custom_note_actions): missing file upload 2026-02-02 18:02:47 +02:00
Elian Doran
8a92370042 fix(mobile/custom_note_actions): missing separator 2026-02-02 17:57:30 +02:00
Elian Doran
411a59ec54 feat(mobile): display custom note actions in note actions 2026-02-02 17:46:18 +02:00
Elian Doran
2d4022044d chore(mobile): get rid of floating buttons 2026-02-02 17:30:35 +02:00
Elian Doran
bbc5ebd76b chore(mobile/header): improve button sizes 2026-02-02 17:06:27 +02:00
Elian Doran
e9c90fcde8 chore(mobile/header): prevent badges from shrinking 2026-02-02 17:02:32 +02:00
Elian Doran
911f78867f chore(mobile/header): make icons easier to press 2026-02-02 16:58:06 +02:00
Elian Doran
5507cc5abc chore(mobile): slightly smaller note title icon 2026-02-02 16:51:57 +02:00
Elian Doran
0e5aa401ef chore(mobile/note_icon): redundant separator 2026-02-02 16:44:08 +02:00
Elian Doran
d48473ab87 feat(mobile/note_icon): single menu for filtering & resetting 2026-02-02 16:38:12 +02:00
hulmgulm
734efaf40c Update apps/server/src/assets/doc_notes/en/User Guide/User Guide/Advanced Usage/Attributes/Labels.html
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-02-02 14:41:38 +01:00
hulmgulm
f89718d88a Add subtreeHidden and map:* attributes to Labels.html 2026-02-02 14:38:11 +01:00
Elian Doran
aa4942a0da fix(mobile/note_icon): wrong icons displayed 2026-02-02 13:45:13 +02:00
Elian Doran
90bb162a88 feat(mobile/note_icon): bigger touch area 2026-02-02 13:31:29 +02:00
Elian Doran
0382a4b30e fix(mobile/note_icon): consistent height and proper margins 2026-02-02 13:27:34 +02:00
Elian Doran
490d940cd1 feat(mobile/note_icon): improve height and fit 2026-02-02 13:23:55 +02:00
Elian Doran
b090eb9359 feat(mobile/note_icon): calculate number of columns dynamically 2026-02-02 13:22:37 +02:00
Elian Doran
cb9e67ce84 fix(mobile/note_icon): small horizontal scroll 2026-02-02 13:14:42 +02:00
Elian Doran
c4d131dd23 feat(mobile): improve note icon selector fit 2026-02-02 13:13:13 +02:00
Elian Doran
2667f266bf feat(mobile): use modal for icon selector 2026-02-02 13:05:20 +02:00
Elian Doran
8258936d6c feat(mobile): integrate icon display in header 2026-02-02 12:53:54 +02:00
Elian Doran
e4e7449078 feat(mobile): integrate inline title with title actions 2026-02-02 12:51:29 +02:00
Elian Doran
11b020e859 feat(mobile): integrate part of the new layout title row 2026-02-02 12:47:43 +02:00
Elian Doran
72d6b83ec5 docs(user): add nightly release script for Windows 2026-02-02 12:20:38 +02:00
Elian Doran
fbe5152cb3 chore(deps): update dependency webdriverio to v9.23.3 (#8583) 2026-02-02 07:48:30 +02:00
Elian Doran
6bef01f755 fix(deps): update dependency globals to v17.3.0 (#8584) 2026-02-02 07:48:17 +02:00
Elian Doran
f0d4b4a6d9 fix(deps): update dependency mind-elixir to v5.7.1 (#8585) 2026-02-02 07:48:05 +02:00
renovate[bot]
a54fe62643 fix(deps): update dependency mind-elixir to v5.7.1 2026-02-02 04:31:50 +00:00
renovate[bot]
eb4bbd49fb fix(deps): update dependency globals to v17.3.0 2026-02-02 01:52:08 +00:00
renovate[bot]
ab4f1bd4f4 chore(deps): update dependency webdriverio to v9.23.3 2026-02-02 01:51:29 +00:00
Elian Doran
f8b414c354 feat(etapi): add attachments etapi endpoint (#8578) 2026-02-01 22:34:37 +02:00
Elian Doran
82a21624c3 Translations update from Hosted Weblate (#8579) 2026-02-01 22:32:35 +02:00
Elian Doran
1b212ac720 Improved mobile note actions (#8580) 2026-02-01 22:30:45 +02:00
Elian Doran
c36ce3ea14 fix(mobile/note_actions): insert child note not working 2026-02-01 22:29:43 +02:00
Elian Doran
841fab77a8 chore(client): address requested changes 2026-02-01 22:22:25 +02:00
Elian Doran
fd6f910824 fix(mobile/note_actions): backdrop remains when closing split 2026-02-01 22:02:54 +02:00
Elian Doran
ce9ca1917d fix(mobile/note_actions): reintroduce split buttons 2026-02-01 22:01:26 +02:00
perfectra1n
c702fb273c feat(tests): add tests for new attachments endpoint 2026-02-01 11:46:03 -08:00
Elian Doran
4c72d8691b fix(mobile/note_actions): reintroduce help button 2026-02-01 21:45:43 +02:00
Elian Doran
35ac5fc514 fix(mobile/note_actions): reintroduce insert child note 2026-02-01 21:42:48 +02:00
Elian Doran
92991cc03c fix(promoted_attributes): displayed in non-default view modes 2026-02-01 21:37:20 +02:00
Elian Doran
76492475e3 fix(mobile/note_actions): find not working 2026-02-01 21:27:24 +02:00
Elian Doran
e2363d860c fix(mobile/note_actions): font too big 2026-02-01 21:25:40 +02:00
Elian Doran
c06a90913a fix(mobile/note_actions): submenus not working 2026-02-01 21:12:50 +02:00
Elian Doran
e88c0f7326 fix(mobile/note_actions): toggles on two rows 2026-02-01 21:02:46 +02:00
Elian Doran
2a4280b5bf feat(mobile/note_actions): remove bottom rounded corners 2026-02-01 20:59:50 +02:00
Elian Doran
d3c733c57f feat(mobile/note_actions): add backdrop 2026-02-01 20:57:01 +02:00
Elian Doran
f91add3cd4 chore(mobile/note_actions): position like global menu 2026-02-01 20:53:33 +02:00
Elian Doran
90e3f7508a chore(mobile): enforce new layout 2026-02-01 20:50:00 +02:00
Elian Doran
5e981da4df feat(mobile): use the desktop version of note actions 2026-02-01 20:48:55 +02:00
Aindriú Mac Giolla Eoin
2ddd5d75fc Added translation using Weblate (Irish) 2026-02-01 19:33:10 +01:00
Aindriú Mac Giolla Eoin
88f509cbb6 Added translation using Weblate (Irish) 2026-02-01 19:33:08 +01:00
Aindriú Mac Giolla Eoin
ca161bc881 Added translation using Weblate (Irish) 2026-02-01 19:33:05 +01:00
Aindriú Mac Giolla Eoin
676ca44cdf Added translation using Weblate (Irish) 2026-02-01 19:33:01 +01:00
green
5d0c91202f Translated using Weblate (Japanese)
Currently translated at 100.0% (1767 of 1767 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ja/
2026-02-01 19:32:59 +01:00
Ulices
a166f049d5 Translated using Weblate (Spanish)
Currently translated at 100.0% (389 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/es/
2026-02-01 19:32:59 +01:00
noobhjy
0dc4692dfc Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (1767 of 1767 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hans/
2026-02-01 19:32:59 +01:00
ibs-allaow
996607d096 Translated using Weblate (Arabic)
Currently translated at 59.5% (1053 of 1767 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ar/
2026-02-01 19:32:58 +01:00
Ulices
bd907ea008 Translated using Weblate (Spanish)
Currently translated at 100.0% (1767 of 1767 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/es/
2026-02-01 19:32:58 +01:00
noobhjy
b1573b1f3b Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (389 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/zh_Hans/
2026-02-01 19:32:57 +01:00
Marcel
246849ce94 Translated using Weblate (German)
Currently translated at 100.0% (1767 of 1767 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-02-01 19:32:57 +01:00
Marcel
2c2c68261a Translated using Weblate (German)
Currently translated at 100.0% (389 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/de/
2026-02-01 19:32:56 +01:00
green
e38a0361bf Translated using Weblate (Japanese)
Currently translated at 100.0% (389 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/ja/
2026-02-01 19:32:56 +01:00
ibs-allaow
cbf879bd32 Translated using Weblate (Arabic)
Currently translated at 59.2% (90 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/ar/
2026-02-01 19:32:56 +01:00
perfectra1n
808625e564 feat(etapi): add attachments etapi endpoint 2026-02-01 09:19:37 -08:00
Elian Doran
c3b4c2f7d4 fix(desktop): background effects interferes with native title bar 2026-02-01 15:47:07 +02:00
Elian Doran
14f521fdd7 Revert "chore(ci): try to fix flaky "Merge manifest lists""
This reverts commit eea4cbbd6c.
2026-02-01 11:53:57 +02:00
Elian Doran
087831df5a feat(etapi): add revisions route and "undelete" route to etapi (#8455) 2026-02-01 11:45:20 +02:00
Elian Doran
6b0542a5bf fix(deps): update dependency preact to v10.28.3 (#8570) 2026-02-01 10:11:48 +02:00
Elian Doran
ac57856f00 fix(deps): update dependency react-window to v2.2.6 (#8571) 2026-02-01 10:10:46 +02:00
renovate[bot]
2ab1587df0 fix(deps): update dependency react-window to v2.2.6 2026-02-01 00:33:14 +00:00
renovate[bot]
632aa6e003 fix(deps): update dependency preact to v10.28.3 2026-02-01 00:32:20 +00:00
Elian Doran
9142f2df4b Translations update from Hosted Weblate (#8569) 2026-01-31 22:46:57 +02:00
Elian Doran
eea4cbbd6c chore(ci): try to fix flaky "Merge manifest lists" 2026-01-31 22:34:14 +02:00
Ulices
bb31c20282 Translated using Weblate (Spanish)
Currently translated at 100.0% (1765 of 1765 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/es/
2026-01-31 21:14:06 +01:00
Elian Doran
f8ab206744 Mobile tabs v1 (#8568) 2026-01-31 22:13:58 +02:00
Elian Doran
4129b3a96e e2e(server): fix regressions after mobile tab switcher 2026-01-31 22:05:28 +02:00
Elian Doran
0de704bd3e fix(desktop): context menus no longer working 2026-01-31 21:42:39 +02:00
Elian Doran
5f20ce87a7 chore(mobile/tab_switcher): bypass weird regression in typecheck regarding React types 2026-01-31 21:17:08 +02:00
Elian Doran
ff80154fda chore(mobile/tab_switcher): address requested changes 2026-01-31 20:47:07 +02:00
Elian Doran
0d99cf9fb9 chore(mobile/tab_switcher): improve layout on tablet view 2026-01-31 20:41:53 +02:00
Elian Doran
a5306b2067 fix(mobile): modals on tablet view 2026-01-31 20:41:07 +02:00
Elian Doran
e9b826e498 chore(mobile/tab_switcher): stop auto-showing 2026-01-31 20:22:28 +02:00
Elian Doran
e7f356b87c feat(mobile/tab_switcher): display note splits 2026-01-31 20:21:11 +02:00
Elian Doran
d2abde714f chore(mobile/tab_switcher): enforce same height 2026-01-31 20:06:16 +02:00
Elian Doran
20eaa79079 fix(mobile): cover not working properly in modals 2026-01-31 20:04:00 +02:00
Elian Doran
3cb74bb844 fix(mobile): context menu won't dismiss due to missing cover 2026-01-31 20:00:56 +02:00
Elian Doran
a72d4f425a feat(mobile/tab_switcher): add context menu item for closing all tabs 2026-01-31 19:54:42 +02:00
Elian Doran
8f3545624e feat(mobile/tab_switcher): improve display of empty tabs 2026-01-31 19:46:15 +02:00
Elian Doran
8f6cfe8a04 feat(mobile/tab_switcher): improve display of collections 2026-01-31 19:43:53 +02:00
Elian Doran
bec7943e05 feat(mobile/tab_switcher): hide icon for new tab 2026-01-31 19:36:31 +02:00
Elian Doran
a486f5951e feat(mobile/tab_switcher): new tab button 2026-01-31 19:29:06 +02:00
Elian Doran
e8158aadec feat(mobile/tab_switcher): display number of tabs in launch bar 2026-01-31 19:19:39 +02:00
Elian Doran
b6f107b85b feat(mobile/tab_switcher): display number of tabs in modal title 2026-01-31 19:08:29 +02:00
Elian Doran
5abd27f252 chore(mobile/tab_switcher): improve modal fit when in browser 2026-01-31 19:04:47 +02:00
Elian Doran
39648b6df8 chore(mobile/tab_switcher): remove old tab bar 2026-01-31 19:03:15 +02:00
Elian Doran
0a7b2e3304 feat(mobile/tab_switcher): integrate into launch bar 2026-01-31 18:50:17 +02:00
Elian Doran
48db6e1756 feat(mobile/tab_switcher): button to close tab 2026-01-31 18:40:01 +02:00
Elian Doran
2a38af5db6 feat(mobile/tab_switcher): scroll to active tab 2026-01-31 18:25:01 +02:00
Elian Doran
740b1093d7 feat(mobile/tab_switcher): respect workspace background color 2026-01-31 18:09:04 +02:00
Elian Doran
6b70412f6e feat(mobile/tab_switcher): respect note color class 2026-01-31 17:50:52 +02:00
Elian Doran
43f147ec60 feat(mobile/tab_switcher): improve display of content widget & search 2026-01-31 17:31:30 +02:00
Elian Doran
bf0fc57493 feat(mobile/tab_switcher): display note icon 2026-01-31 17:29:24 +02:00
Elian Doran
325b8b886c fix(mobile/tab_switcher): clipped borders 2026-01-31 17:25:33 +02:00
Elian Doran
a02bbdc550 feat(mobile/tab_switcher): indicate active tab 2026-01-31 17:25:05 +02:00
Elian Doran
4285fd7708 feat(mobile/tab_switcher): click to activate 2026-01-31 17:14:54 +02:00
Elian Doran
96fa6eac44 fix(mobile/tab_switcher): no title if empty tab 2026-01-31 17:07:32 +02:00
Elian Doran
05fa1ef2fb feat(mobile/tab_switcher): clip note title 2026-01-31 17:04:19 +02:00
Elian Doran
13aebc060e feat(mobile/tab_switcher): display margins only for text 2026-01-31 17:01:22 +02:00
Elian Doran
1aae4098d6 feat(mobile/tab_switcher): 2026-01-31 16:54:39 +02:00
Elian Doran
3367bb2e5b feat(mobile/tab_switcher): basic rendering of tab content 2026-01-31 16:25:05 +02:00
Elian Doran
49fc5e1559 feat(mobile/tab_switcher): basic listing of tabs 2026-01-31 16:12:27 +02:00
Elian Doran
3a9b448a83 chore(mobile/tab_switcher): create empty modal 2026-01-31 15:59:38 +02:00
Elian Doran
a45fb975c0 chore(mobile/tab_switcher): add button in launch bar 2026-01-31 15:53:19 +02:00
Elian Doran
e070fc2f52 Translations update from Hosted Weblate (#8563) 2026-01-31 15:14:21 +02:00
Ulices
5f8aac31e1 Translated using Weblate (Spanish)
Currently translated at 100.0% (1764 of 1764 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/es/
2026-01-31 13:00:02 +00:00
green
07f2e2eafc Translated using Weblate (Japanese)
Currently translated at 100.0% (1764 of 1764 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ja/
2026-01-31 13:00:01 +00:00
Marcel
2b41fb7108 Translated using Weblate (German)
Currently translated at 100.0% (1764 of 1764 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-01-31 13:00:00 +00:00
Elian Doran
81c18f1869 Streamlining the collection properties (#8562) 2026-01-31 14:59:40 +02:00
Elian Doran
61fd2fe87d chore(collections): address requested changes 2026-01-31 14:13:41 +02:00
Elian Doran
054cb974f1 fix(collections): old layout floating toolbar interfering 2026-01-31 13:49:02 +02:00
Elian Doran
50a19ecd74 fix(board): clipped due to collection properties 2026-01-31 13:31:46 +02:00
Elian Doran
1232909a3b feat(geomap): integrate add button to collection properties 2026-01-31 13:26:54 +02:00
Elian Doran
9ba0e076a6 fix(calendar): buttons cut off on smaller mobile phones 2026-01-31 13:09:20 +02:00
Elian Doran
ede91c645d fix(presentation): cut off due to collection properties 2026-01-31 13:05:05 +02:00
Elian Doran
b6a91723e7 feat(presentation): integrate buttons into collection properties 2026-01-31 13:01:51 +02:00
Elian Doran
fddd73fdb1 feat(table): display action buttons on mobile 2026-01-31 12:59:09 +02:00
Elian Doran
ffbe8f9dc4 fix(table): wrong alignment of buttons 2026-01-31 12:54:11 +02:00
Elian Doran
f80763ffb4 fix(geomap): zoom buttons interfering with collection properties 2026-01-31 12:53:56 +02:00
Elian Doran
f65aa1b875 fix(collections): height affected due to collection properties 2026-01-31 12:41:52 +02:00
Elian Doran
0c4de9a5e0 feat(table): integrate footer buttons into collection properties 2026-01-31 12:41:31 +02:00
Elian Doran
1822970e23 feat(collections): integrate list/grid pagination into collection properties 2026-01-31 12:29:48 +02:00
Elian Doran
80615d0382 feat(search): integrate collection properties into search 2026-01-31 12:22:34 +02:00
Elian Doran
c1002ed52a chore(calendar): improve layout on mobile 2026-01-31 12:13:05 +02:00
Elian Doran
83e585ed35 fix(calendar): layout broken on desktop 2026-01-31 11:54:23 +02:00
Elian Doran
0e164b9daa chore(collections): fix alignment of collection properties in relation to content 2026-01-31 11:50:14 +02:00
Elian Doran
1c9f8a2540 chore(collections): add collection toolbar to all collections 2026-01-31 11:39:48 +02:00
Elian Doran
88ba4451eb chore(calendar): improve layout on mobile slightly 2026-01-31 11:33:00 +02:00
Elian Doran
305f195539 feat(calendar): dropdown-based view switcher for mobile 2026-01-31 11:27:11 +02:00
Elian Doran
fbc6b853ed chore(calendar): improve column fit on mobile 2026-01-31 11:17:26 +02:00
Elian Doran
f3bcab813a chore(calendar): minor improvements on mobile 2026-01-31 11:11:01 +02:00
Elian Doran
2fa9b2e4dd feat(mobile): add help button in note context menu 2026-01-31 11:08:41 +02:00
Elian Doran
fc756ba46e feat(collections): move help button to the title area 2026-01-31 11:00:55 +02:00
Elian Doran
85a82124b1 feat(calendar): basic header support on mobile 2026-01-31 10:53:37 +02:00
Elian Doran
b5cfbc92af chore(calendar): use text instead of icons 2026-01-31 10:34:37 +02:00
Elian Doran
e4f260e242 chore(calendar): relocate prev/next buttons 2026-01-31 10:23:24 +02:00
Elian Doran
7c6c0c1fbd feat(calendar): integrate calendar header into collection properites 2026-01-31 10:14:35 +02:00
Elian Doran
2f5f4dbebd chore(deps): update dependency @playwright/test to v1.58.1 (#8554) 2026-01-31 08:38:59 +02:00
Elian Doran
94adc6af95 fix(deps): update dependency @codemirror/view to v6.39.12 (#8555) 2026-01-31 08:36:49 +02:00
Elian Doran
e3ea703f3d fix(deps): update dependency @preact/signals to v2.6.2 (#8556) 2026-01-31 08:35:38 +02:00
Elian Doran
a14753e5f3 chore(deps): update dependency stylelint to v17.1.0 (#8558) 2026-01-31 08:34:17 +02:00
Elian Doran
2ffd55c2d8 chore(deps): update dependency dpdm to v4 (#8559) 2026-01-31 08:33:44 +02:00
renovate[bot]
ad0ee8da32 chore(deps): update dependency dpdm to v4 2026-01-31 01:16:04 +00:00
renovate[bot]
e5cfe37b17 chore(deps): update dependency stylelint to v17.1.0 2026-01-31 01:15:23 +00:00
renovate[bot]
9247dd8b17 fix(deps): update dependency @preact/signals to v2.6.2 2026-01-31 01:13:37 +00:00
renovate[bot]
2f69b1d6e1 fix(deps): update dependency @codemirror/view to v6.39.12 2026-01-31 01:12:39 +00:00
renovate[bot]
9c43930e7b chore(deps): update dependency @playwright/test to v1.58.1 2026-01-31 01:11:44 +00:00
Elian Doran
f18ecfa524 test(server): reduce number of workers even further 2026-01-30 21:47:01 +02:00
Elian Doran
b6f7453ed9 fix(web-clipper): cropped screenshot not working in some versions of Chrome (closes #8528) 2026-01-30 21:32:34 +02:00
Elian Doran
4a0b77dabb test(server): reduce server workers even further 2026-01-30 19:35:35 +02:00
Elian Doran
de7687b3ab chore(deps): audit 2026-01-30 19:27:23 +02:00
Elian Doran
85f2ec9d92 test(server): reduce parallel number of workers to avoid OOM in CI 2026-01-30 19:16:43 +02:00
Elian Doran
ed6b8dfc9b Translations update from Hosted Weblate (#8552) 2026-01-30 18:58:10 +02:00
Kim Nøglegaard
1539a6eabc Translated using Weblate (Norwegian Bokmål)
Currently translated at 43.9% (51 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/nb_NO/
2026-01-30 16:53:55 +00:00
Kim Nøglegaard
6424d96703 Translated using Weblate (Norwegian Bokmål)
Currently translated at 6.9% (27 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/nb_NO/
2026-01-30 16:53:55 +00:00
Elian Doran
15f6ac8e89 macOS Vibrancy Support (#8519) 2026-01-30 18:53:41 +02:00
Elian Doran
f9803a4694 Merge remote-tracking branch 'origin/main' into feature/vibrancy 2026-01-30 18:45:30 +02:00
Elian Doran
13de9975e3 chore(deps): update dependency @braintree/sanitize-url to v7.1.2 (#8548) 2026-01-30 11:35:27 +02:00
Elian Doran
a64c4ef66f chore(deps): update typescript-eslint monorepo to v8.54.0 (#8436) 2026-01-30 09:19:28 +02:00
Elian Doran
36e85eb3a7 chore(deps): update dependency @playwright/test to v1.58.0 (#8487) 2026-01-30 09:19:03 +02:00
Elian Doran
20ffe7e082 fix(deps): update dependency globals to v17.2.0 (#8489) 2026-01-30 09:18:52 +02:00
Elian Doran
ea1dc58b9a chore(deps): update dependency @preact/preset-vite to v2.10.3 (#8539) 2026-01-30 09:18:42 +02:00
Elian Doran
cd292ad605 chore(deps): update dependency @smithy/middleware-retry to v4.4.29 (#8540) 2026-01-30 09:17:59 +02:00
renovate[bot]
03d9a6c0e5 chore(deps): update dependency @braintree/sanitize-url to v7.1.2 2026-01-30 07:17:41 +00:00
Elian Doran
fa54a2e67c chore(deps): update dependency @redocly/cli to v2.15.0 (#8543) 2026-01-30 09:15:57 +02:00
Elian Doran
7f2530470d chore(deps): update dependency @anthropic-ai/sdk to v0.72.1 (#8549) 2026-01-30 09:15:47 +02:00
Elian Doran
a284934136 chore(deps): update dependency electron to v40.1.0 (#8550) 2026-01-30 09:15:36 +02:00
renovate[bot]
2ca6606508 fix(deps): update dependency globals to v17.2.0 2026-01-30 06:52:02 +00:00
renovate[bot]
bb1c691b34 chore(deps): update typescript-eslint monorepo to v8.54.0 2026-01-30 06:50:39 +00:00
renovate[bot]
19d3e1b11c chore(deps): update dependency electron to v40.1.0 2026-01-30 06:49:33 +00:00
renovate[bot]
e35e64caaa chore(deps): update dependency @redocly/cli to v2.15.0 2026-01-30 06:48:34 +00:00
renovate[bot]
a3cf72c76c chore(deps): update dependency @playwright/test to v1.58.0 2026-01-30 06:47:40 +00:00
renovate[bot]
710e95bdee chore(deps): update dependency @anthropic-ai/sdk to v0.72.1 2026-01-30 06:46:47 +00:00
renovate[bot]
d281fb7065 chore(deps): update dependency @smithy/middleware-retry to v4.4.29 2026-01-30 06:45:09 +00:00
renovate[bot]
e669d5041b chore(deps): update dependency @preact/preset-vite to v2.10.3 2026-01-30 06:44:20 +00:00
Elian Doran
d8d91451c8 e2e(server): fix some flakiness in support app 2026-01-30 08:11:32 +02:00
Elian Doran
b0910baaf0 chore(ci): fix warnings related to if 2026-01-30 07:46:30 +02:00
Elian Doran
ce3f70adc3 chore(deps): update dependency axios to v1.13.4 (#8541) 2026-01-29 18:55:00 +02:00
Elian Doran
c0d5c26f0c chore(deps): update dependency @electron/rebuild to v4.0.3 (#8538) 2026-01-29 09:51:11 +02:00
Elian Doran
1bf8a76cc3 Translations update from Hosted Weblate (#8546) 2026-01-29 09:50:48 +02:00
Ulices
7b1f74a413 Translated using Weblate (Spanish)
Currently translated at 100.0% (388 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/es/
2026-01-29 08:27:08 +01:00
Sergii Nechuiviter
3d2fde77a5 Translated using Weblate (Ukrainian)
Currently translated at 86.8% (132 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/uk/
2026-01-29 08:27:07 +01:00
Ulices
e4cc3bef73 Translated using Weblate (Spanish)
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/es/
2026-01-29 08:27:07 +01:00
Hosted Weblate
f384c422c4 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/
2026-01-29 08:27:06 +01:00
Elian Doran
a373d2e7e0 Vite fixes (#8537) 2026-01-29 09:26:57 +02:00
Elian Doran
1aaf630979 Merge branch 'main' into feature/vite_fixes 2026-01-29 09:05:04 +02:00
Elian Doran
b7ac3aba72 fix(deps): update dependency react-i18next to v16.5.4 (#8542) 2026-01-29 08:58:39 +02:00
Elian Doran
ed89250624 chore(deps): update dependency happy-dom to v20.4.0 (#8544) 2026-01-29 08:58:28 +02:00
Elian Doran
d9a7f0c7fe chore(deps): update dependency openai to v6.17.0 (#8545) 2026-01-29 08:58:09 +02:00
Elian Doran
a07405bec3 fix(desktop): nightly failing due to missing flatpak icon 2026-01-29 08:57:29 +02:00
renovate[bot]
4c6efeb0d8 chore(deps): update dependency openai to v6.17.0 2026-01-29 01:00:59 +00:00
renovate[bot]
501b380d5e chore(deps): update dependency happy-dom to v20.4.0 2026-01-29 01:00:12 +00:00
renovate[bot]
ddc4e34dcd fix(deps): update dependency react-i18next to v16.5.4 2026-01-29 00:58:31 +00:00
renovate[bot]
d668d9f24d chore(deps): update dependency axios to v1.13.4 2026-01-29 00:57:40 +00:00
renovate[bot]
0ec4423ad4 chore(deps): update dependency @electron/rebuild to v4.0.3 2026-01-29 00:55:00 +00:00
Elian Doran
51313ff0d5 fix(client): subdir broken due to bootstrap 2026-01-28 22:27:02 +02:00
Elian Doran
37381b7c36 chore(client): use different root mechanism with fewer issues 2026-01-28 22:23:00 +02:00
Elian Doran
6de632d117 fix(client): relative import to src 2026-01-28 22:06:19 +02:00
Elian Doran
4a8fa7293b fix(calendar): unnecessary right margin for header on new layout 2026-01-28 15:37:41 +02:00
Elian Doran
b75a2e9592 fix(calendar): lower case in header (closes #8507) 2026-01-28 14:47:06 +02:00
Elian Doran
c45c1b0f93 fix(calendar): not respecting auto formatting locale (closes #8507) 2026-01-28 14:46:24 +02:00
Elian Doran
af7057f062 fix(scripts): correctly extract current version for nightly updates 2026-01-28 10:05:04 +02:00
Elian Doran
85bf1eb4ec fix(desktop): nightly icon not respected 2026-01-28 10:03:45 +02:00
Elian Doran
bd45043a36 chore(desktop): integrate icon change for dev nightlies 2026-01-28 09:44:15 +02:00
Elian Doran
fbb41168a2 chore(scripts): build dev icon for Windows installer 2026-01-28 09:05:23 +02:00
Elian Doran
674fe4fa20 chore(scripts): build dev icon for Mac 2026-01-28 08:54:36 +02:00
Elian Doran
4db86f9322 chore(scripts): fix path for building Mac icon 2026-01-28 08:48:48 +02:00
Elian Doran
5c814155d2 chore(scripts): build dev icon for Windows 2026-01-28 08:44:35 +02:00
Elian Doran
c08fb9af16 chore(scripts): update paths in create icons 2026-01-28 08:41:55 +02:00
Elian Doran
1dac4fea9c Translations update from Hosted Weblate (#8532) 2026-01-28 07:34:25 +02:00
Marcel
ac19000ad0 Translated using Weblate (German)
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-01-28 05:06:09 +01:00
Giovi
221182389a Translated using Weblate (Italian)
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/it/
2026-01-28 05:06:09 +01:00
Elian Doran
5d5947f676 feat(call_to_action): enable background effects CTA on macOS 2026-01-27 23:31:05 +02:00
Elian Doran
8fc889ae08 chore(options): change description 2026-01-27 23:22:31 +02:00
Elian Doran
ff46493775 feat(options): add platform indicator 2026-01-27 23:17:38 +02:00
Elian Doran
a1cb3b8371 style(desktop): change material for horizontal layout 2026-01-27 16:42:52 +02:00
Elian Doran
51131433d3 chore(client): address requested changes 2026-01-27 15:56:57 +02:00
Elian Doran
eaccd641ed Translations update from Hosted Weblate (#8527) 2026-01-27 08:45:06 +02:00
Unknown
3e2b647f06 Translated using Weblate (Spanish)
Currently translated at 94.2% (1662 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/es/
2026-01-27 07:43:49 +01:00
Toto Yullian
0fbf9bafbc Translated using Weblate (Indonesian)
Currently translated at 3.2% (57 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/id/
2026-01-27 07:43:48 +01:00
Jason Kuanca
924a5e3110 Translated using Weblate (Indonesian)
Currently translated at 3.2% (57 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/id/
2026-01-27 07:43:47 +01:00
Marcel
be71a4b5c4 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/
2026-01-27 07:43:47 +01:00
Marcel
1cb5a13ea4 Translated using Weblate (German)
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-01-27 07:43:46 +01:00
Marcel
e145cd80a9 Translated using Weblate (German)
Currently translated at 100.0% (388 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/de/
2026-01-27 07:43:45 +01:00
Toto Yullian
58ea661d4b Translated using Weblate (Indonesian)
Currently translated at 38.8% (59 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/id/
2026-01-27 07:43:44 +01:00
Elian Doran
ba317eff3f chore(deps): update dependency vite-plugin-static-copy to v3.2.0 (#8486) 2026-01-27 08:43:25 +02:00
Elian Doran
ead0e14118 chore(deps): update react monorepo to v19.2.4 (#8524) 2026-01-27 08:42:58 +02:00
Elian Doran
d3dd20b50f chore(deps): update dependency eslint-plugin-playwright to v2.5.1 (#8521) 2026-01-27 08:42:31 +02:00
Elian Doran
d621fb4105 chore(deps): update dependency rollup-plugin-webpack-stats to v2.1.10 (#8522) 2026-01-27 08:42:01 +02:00
Elian Doran
a239604dad chore(deps): update pnpm to v10.28.2 (#8523) 2026-01-27 08:41:41 +02:00
renovate[bot]
f7986b9049 chore(deps): update dependency vite-plugin-static-copy to v3.2.0 2026-01-27 05:54:58 +00:00
renovate[bot]
0a34ca031a chore(deps): update react monorepo to v19.2.4 2026-01-27 01:39:04 +00:00
renovate[bot]
ce63fec413 chore(deps): update pnpm to v10.28.2 2026-01-27 01:38:17 +00:00
renovate[bot]
719451bf23 chore(deps): update dependency rollup-plugin-webpack-stats to v2.1.10 2026-01-27 01:38:02 +00:00
renovate[bot]
10a27cbe86 chore(deps): update dependency eslint-plugin-playwright to v2.5.1 2026-01-27 01:37:18 +00:00
Elian Doran
3c8a066f76 feat(desktop): handle both vertical and horizontal layouts 2026-01-26 23:28:29 +02:00
Elian Doran
6856a98d50 feat(desktop): integrate vibrancy 2026-01-26 23:21:40 +02:00
Elian Doran
120b767a68 fix(desktop): background effects not applied correctly 2026-01-26 23:10:19 +02:00
Elian Doran
8c0d4cde86 feat(desktop): basic vibrancy support 2026-01-26 23:02:14 +02:00
Elian Doran
bbf090edf0 Merge branch 'main' of github.com:TriliumNext/Trilium 2026-01-26 21:11:02 +02:00
Elian Doran
fc925a5db5 chore(web-clipper): prepare for 1.1.1 2026-01-26 21:10:30 +02:00
Elian Doran
fb76ca09bd Web Clipper Fixes (#8518) 2026-01-26 21:09:29 +02:00
Elian Doran
af6c54bac7 fix(web-clipper): context menu got broken on Firefox 2026-01-26 21:00:56 +02:00
Elian Doran
a854b04300 chore(web-clipper): rename ZIP artifacts 2026-01-26 20:47:20 +02:00
Elian Doran
5d73556127 docs(dev): mention NixOS for web clipper dev 2026-01-26 20:44:19 +02:00
Elian Doran
82ea4c1a04 docs(guide): add instructions on installing from .zip 2026-01-26 20:41:22 +02:00
Elian Doran
537d92421c chore(web-clipper): fix warning related to permissions 2026-01-26 20:20:46 +02:00
Elian Doran
c97c69900b chore(web-clipper): minor typo in "screenshot" 2026-01-26 20:10:18 +02:00
Elian Doran
ab519a4caa chore(web-clipper): rephrase "already visited" & fix spacing 2026-01-26 20:06:57 +02:00
Elian Doran
bbbdab42ca fix(web-clipper): cash not working in Chrome 2026-01-26 19:38:11 +02:00
Elian Doran
810563b3f9 fix(web-clipper): duplicate context menu error 2026-01-26 19:21:19 +02:00
Elian Doran
63cf055a0d Translations update from Hosted Weblate (#8517) 2026-01-26 18:14:29 +02:00
Hosted Weblate
442aac0466 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/
2026-01-26 17:10:32 +01:00
Elian Doran
7c9499ad7e Translations update from Hosted Weblate (#8510) 2026-01-26 18:10:06 +02:00
Jason Kuanca
a6e8e2a127 Translated using Weblate (Indonesian)
Currently translated at 21.6% (84 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/id/
2026-01-26 08:12:29 +01:00
Jason Kuanca
671e05421a Translated using Weblate (Indonesian)
Currently translated at 34.8% (53 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/id/
2026-01-26 08:12:28 +01:00
Jason Kuanca
d8c7c919d1 Translated using Weblate (Indonesian)
Currently translated at 44.8% (52 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/id/
2026-01-26 08:12:28 +01:00
Toto Yullian
5629b9a161 Translated using Weblate (Indonesian)
Currently translated at 2.8% (51 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/id/
2026-01-26 08:12:27 +01:00
Jason Kuanca
3ba853dbad Translated using Weblate (Indonesian)
Currently translated at 2.8% (51 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/id/
2026-01-26 08:12:27 +01:00
Jason Kuanca
be8dda8523 Translated using Weblate (Indonesian)
Currently translated at 2.6% (47 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/id/
2026-01-26 07:39:12 +01:00
Jason Kuanca
2e86166400 Translated using Weblate (Indonesian)
Currently translated at 21.3% (83 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/id/
2026-01-26 07:39:11 +01:00
Jason Kuanca
784ea240ca Translated using Weblate (Indonesian)
Currently translated at 42.2% (49 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/id/
2026-01-26 07:39:10 +01:00
Jason Kuanca
5b10e33e72 Translated using Weblate (Indonesian)
Currently translated at 32.2% (49 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/id/
2026-01-26 07:39:09 +01:00
Jason Kuanca
fbcf974c73 Translated using Weblate (Indonesian)
Currently translated at 1.8% (33 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/id/
2026-01-26 07:39:08 +01:00
Jason Kuanca
d844111187 Translated using Weblate (Indonesian)
Currently translated at 22.3% (34 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/id/
2026-01-26 07:39:08 +01:00
Jason Kuanca
4cac419a26 Translated using Weblate (Indonesian)
Currently translated at 31.0% (36 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/id/
2026-01-26 07:39:07 +01:00
Francis C.
1c21519960 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hant/
2026-01-26 07:39:06 +01:00
Jason Kuanca
6a70c52bd1 Translated using Weblate (Indonesian)
Currently translated at 1.3% (24 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/id/
2026-01-26 07:39:05 +01:00
Jason Kuanca
a0e6023810 Translated using Weblate (Indonesian)
Currently translated at 23.2% (27 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/id/
2026-01-26 07:39:05 +01:00
Jason Kuanca
a24ab7ca06 Translated using Weblate (Indonesian)
Currently translated at 16.4% (25 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/id/
2026-01-26 07:39:04 +01:00
MarcelWie
4979a1b224 Translated using Weblate (German)
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-01-26 07:39:03 +01:00
Antonio Sanchez Castellón
4cdf6d8292 Translated using Weblate (Spanish)
Currently translated at 94.2% (1662 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/es/
2026-01-26 07:39:02 +01:00
MarcelWie
4c51c8e8f8 Translated using Weblate (German)
Currently translated at 100.0% (116 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/de/
2026-01-26 07:39:01 +01:00
MarcelWie
1ab7b91f2e Translated using Weblate (German)
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-01-26 07:39:01 +01:00
Antonio Sanchez Castellón
7af4fbfcce Translated using Weblate (Spanish)
Currently translated at 93.5% (1650 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/es/
2026-01-26 07:39:00 +01:00
Antonio Sanchez Castellón
494e23b69f Translated using Weblate (Spanish)
Currently translated at 100.0% (116 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/es/
2026-01-26 07:38:59 +01:00
MarcelWie
a487a502f5 Translated using Weblate (German)
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-01-26 07:38:59 +01:00
MarcelWie
2b7a7a8767 Translated using Weblate (German)
Currently translated at 100.0% (388 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/de/
2026-01-26 07:38:58 +01:00
MarcelWie
0c72bd1539 Translated using Weblate (German)
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-01-26 07:38:57 +01:00
MarcelWie
9462ccc650 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/
2026-01-26 07:38:56 +01:00
MarcelWie
81d964d3e8 Translated using Weblate (German)
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-01-26 07:38:55 +01:00
MarcelWie
27bf41e0ce Translated using Weblate (German)
Currently translated at 100.0% (388 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/de/
2026-01-26 07:38:55 +01:00
MarcelWie
78b0773a28 Translated using Weblate (German)
Currently translated at 100.0% (116 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/de/
2026-01-26 07:38:54 +01:00
MarcelWie
3b76239f65 Translated using Weblate (German)
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-01-26 07:38:53 +01:00
Elian Doran
edd11d847a chore(deps): update dependency axios to v1.13.3 (#8511) 2026-01-26 08:38:35 +02:00
Elian Doran
0df0f8a4c9 chore(deps): update dependency happy-dom to v20.3.9 (#8512) 2026-01-26 08:37:25 +02:00
Elian Doran
0f5ee0888a fix(deps): update dependency katex to v0.16.28 (#8513) 2026-01-26 08:37:03 +02:00
renovate[bot]
30ead4080a fix(deps): update dependency katex to v0.16.28 2026-01-26 01:16:42 +00:00
renovate[bot]
9224029a16 chore(deps): update dependency happy-dom to v20.3.9 2026-01-26 01:16:05 +00:00
renovate[bot]
4ce841dc8a chore(deps): update dependency axios to v1.13.3 2026-01-26 01:15:19 +00:00
Elian Doran
d639de03c3 Translations update from Hosted Weblate (#8509) 2026-01-25 23:18:47 +02:00
MarcelWie
0cf34fb874 Translated using Weblate (German)
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-01-25 22:11:45 +01:00
Elian Doran
241147c762 fix(ci): token for web-clipper release 2026-01-25 21:40:19 +02:00
Elian Doran
99eb481ed4 Merge branch 'main' of https://github.com/TriliumNext/Trilium 2026-01-25 21:38:27 +02:00
Elian Doran
2d126c9cec feat(ci): create release for web-clipper 2026-01-25 21:38:01 +02:00
Elian Doran
7aec858ade chore(web-clipper): missing offscreen.html in sources 2026-01-25 21:37:49 +02:00
Elian Doran
ac7a107a9a Translations update from Hosted Weblate (#8506) 2026-01-25 21:30:28 +02:00
MarcelWie
c2c9b6819c Translated using Weblate (German)
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-01-25 20:27:39 +01:00
Vitalii Hlas
7159ea5927 Translated using Weblate (Ukrainian)
Currently translated at 91.4% (1613 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/uk/
2026-01-25 20:27:38 +01:00
Vitalii Hlas
44bf837310 Translated using Weblate (Ukrainian)
Currently translated at 76.3% (116 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/uk/
2026-01-25 20:27:37 +01:00
Hosted Weblate
28368a3e0d 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/
2026-01-25 20:27:36 +01:00
Hosted Weblate
1a92eeac69 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/
2026-01-25 20:27:35 +01:00
Elian Doran
411c062463 chore(web-clipper): rewire TS config for sources ZIP 2026-01-25 21:20:07 +02:00
Elian Doran
18d1b8cbfe chore(web-clipper): add README for Firefox submission 2026-01-25 21:19:43 +02:00
Elian Doran
8322e4278a Merge branch 'main' of https://github.com/TriliumNext/Trilium 2026-01-25 20:53:30 +02:00
Elian Doran
4b70bb6778 chore(web-clipper): bump version to v1.1.0 2026-01-25 20:45:06 +02:00
Elian Doran
c9c9daf30c Translations update from Hosted Weblate (#8505) 2026-01-25 20:40:44 +02:00
Hosted Weblate
b26d9c0303 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/
2026-01-25 19:34:13 +01:00
Elian Doran
376e6dc6d7 Translations update from Hosted Weblate (#8504) 2026-01-25 20:30:44 +02:00
Hosted Weblate
34d3c318d6 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/
2026-01-25 19:27:25 +01:00
Elian Doran
6cbed20d5c Translations update from Hosted Weblate (#8501) 2026-01-25 20:27:08 +02:00
Vitalii Hlas
96acd7f921 Translated using Weblate (Ukrainian)
Currently translated at 38.8% (59 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/uk/
2026-01-25 19:25:45 +01:00
Vitalii Hlas
7439b9ca65 Translated using Weblate (Ukrainian)
Currently translated at 50.0% (58 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/uk/
2026-01-25 19:25:44 +01:00
Elian Doran
9eb24c6fc2 Translated using Weblate (Romanian)
Currently translated at 99.9% (1762 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ro/
2026-01-25 17:53:29 +01:00
Vitalii Hlas
595d30feb7 Translated using Weblate (Ukrainian)
Currently translated at 97.9% (380 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/uk/
2026-01-25 17:53:25 +01:00
Vitalii Hlas
836b5feaae Translated using Weblate (Ukrainian)
Currently translated at 91.3% (1611 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/uk/
2026-01-25 17:53:24 +01:00
Vitalii Hlas
5ca0830b88 Translated using Weblate (Ukrainian)
Currently translated at 29.6% (45 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/uk/
2026-01-25 17:53:23 +01:00
Vitalii Hlas
46057fa03b Translated using Weblate (Ukrainian)
Currently translated at 40.5% (47 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/uk/
2026-01-25 17:53:21 +01:00
Toto Yullian
ba46ba77b4 Translated using Weblate (Indonesian)
Currently translated at 1.1% (20 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/id/
2026-01-25 14:37:36 +01:00
noobhjy
e348a9b907 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hans/
2026-01-25 14:37:35 +01:00
green
aaaf8c1e2b Translated using Weblate (Japanese)
Currently translated at 100.0% (1763 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ja/
2026-01-25 11:52:12 +01:00
Toto Yullian
41a85a78db Translated using Weblate (Indonesian)
Currently translated at 1.0% (19 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/id/
2026-01-25 11:52:12 +01:00
Elian Doran
554aa1cd64 Translated using Weblate (Romanian)
Currently translated at 94.6% (1669 of 1763 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ro/
2026-01-25 11:52:11 +01:00
Elian Doran
853822ec8a chore(deps): update dependency @redocly/cli to v2.14.9 (#8485) 2026-01-25 12:03:52 +02:00
Elian Doran
087dfa179e Web Clipper (#8494) 2026-01-25 12:02:28 +02:00
Elian Doran
65a769c5bd Merge branch 'main' into webclipper/tooling 2026-01-25 11:14:23 +02:00
Elian Doran
0bbb4ddb21 Translations update from Hosted Weblate (#8499) 2026-01-25 09:44:57 +02:00
pythaac
cb0eeee8cc Translated using Weblate (Korean)
Currently translated at 100.0% (152 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/ko/
2026-01-25 08:43:55 +01:00
Elian Doran
75d35e3ade fix(deps): update codemirror themes to v6.2.4 (#8496) 2026-01-25 09:43:48 +02:00
renovate[bot]
99e22a5636 fix(deps): update codemirror themes to v6.2.4 2026-01-25 01:58:44 +00:00
Elian Doran
b7b367b5a3 chore(webclipper): address requested changes 2026-01-24 23:54:26 +02:00
Elian Doran
4927b01d96 chore(webclipper): fix typecheck 2026-01-24 23:13:27 +02:00
Elian Doran
e2e5d485d7 docs(dev): add some information on web clipper 2026-01-24 21:35:54 +02:00
Elian Doran
ada22e4966 docs(user): update web clipper 2026-01-24 21:24:14 +02:00
Elian Doran
1cf93ff0de chore(web-clipper): add data_collection_permissions for Firefox 2026-01-24 19:25:16 +02:00
Elian Doran
199962233b chore(web-clipper): use friendly ID for Firefox 2026-01-24 19:04:38 +02:00
Elian Doran
743a6f3466 ci(web-clipper): disable compression level for artifact 2026-01-24 18:12:02 +02:00
Elian Doran
625062a268 ci(web-clipper): no files uploaded 2026-01-24 17:57:30 +02:00
Elian Doran
cb0fabf273 ci(web-clipper): fail if no files found 2026-01-24 17:43:11 +02:00
Elian Doran
4c978d8622 ci(web-clipper): fail if no files found 2026-01-24 17:41:51 +02:00
Elian Doran
d0f441ec74 ci(web-clipper): generate .zip files on change 2026-01-24 17:40:18 +02:00
Elian Doran
9d347ff3d9 chore(web-clipper): update help URL 2026-01-24 17:25:09 +02:00
Elian Doran
c2a758dd4a chore(web-clipper): address requested changes 2026-01-24 17:23:06 +02:00
Elian Doran
bba69e98ae fix(web-clipper): warning about offscreen permission in MV2 2026-01-24 17:07:53 +02:00
Elian Doran
53e3d65c52 fix(web-clipper): handling of dev port 2026-01-24 17:01:03 +02:00
Elian Doran
a2a37a0b54 chore(web-clipper): integrate old manifest 2026-01-24 16:46:04 +02:00
Elian Doran
1fb360e34f chore(web-clipper): remove polyfill 2026-01-24 16:40:00 +02:00
Elian Doran
680817d81c fix(web-clipper): duplicate context menu entry 2026-01-24 16:39:00 +02:00
Elian Doran
bf736977ab chore(web-clipper): don't render offscreen for MV2 2026-01-24 16:26:16 +02:00
Elian Doran
28ed93dcdc refactor(web-clipper): use @-imports 2026-01-24 16:22:43 +02:00
Elian Doran
785ace64ad feat(web-clipper): use new Trilium icon for now 2026-01-24 16:20:36 +02:00
Elian Doran
ac109c2ece feat(web-clipper): support manifest V2 for Firefox 2026-01-24 16:07:15 +02:00
Elian Doran
1e82043999 fix(web-clipper): saving links not working under MV3 2026-01-24 15:42:04 +02:00
Elian Doran
e37487a1cf feat(web-clipper): handle manifest V3 2026-01-24 15:28:47 +02:00
Elian Doran
a9b8ffd94c chore(web-clipper): fix package lock 2026-01-24 14:26:05 +02:00
Elian Doran
4011771b64 chore(web-clipper): port the remaining files to TypeScript 2026-01-24 14:01:58 +02:00
Elian Doran
266494ba8c chore(web-clipper): port most files to TypeScript 2026-01-24 13:20:27 +02:00
Elian Doran
2e144fac5e chore(web-clipper): set up for TypeScript 2026-01-24 12:35:31 +02:00
Elian Doran
423038100e fix(web-clipper): undefined variable in popup 2026-01-24 12:12:51 +02:00
Elian Doran
75e88c69bd fix(web-clipper): createLink not defined in popup 2026-01-24 12:12:07 +02:00
Elian Doran
f0b1319f95 refactor(web-clipper): remove unnecessary libraries 2026-01-24 11:54:00 +02:00
Elian Doran
59f2fc8d03 fix(web-clipper): clipping whole page not working 2026-01-24 11:53:26 +02:00
Elian Doran
5d07a079ef feat(web-clipper): improve error handling for content entrypoint 2026-01-24 11:46:07 +02:00
Elian Doran
b5ff71b1a0 fix(web-clipper): missing utils import 2026-01-24 11:25:32 +02:00
Elian Doran
c0a2ae99cf fix(web-clipper): toast not working 2026-01-24 11:13:17 +02:00
Elian Doran
5600a707d3 chore(web-clipper): reintegrate name and description 2026-01-24 11:00:54 +02:00
Elian Doran
17f906fb65 chore(web-clipper): reintegrate icon 2026-01-24 10:58:20 +02:00
Elian Doran
276b3f834b fix(web-clipper): triliumServerFacade is not defined 2026-01-24 10:47:41 +02:00
Elian Doran
a9218960e9 fix(web-clipper): the storage API will not work with a temporary addon ID 2026-01-24 10:40:16 +02:00
Elian Doran
957590523c fix(web-clipper): integrate trilium server facade 2026-01-24 10:29:53 +02:00
Elian Doran
22308a101e fix(web-clipper): missing permissions 2026-01-24 10:18:59 +02:00
Elian Doran
ab95f6dcc2 fix(web-clipper): script imports 2026-01-24 10:08:29 +02:00
Elian Doran
cb8b968637 chore(web-clipper): make entrypoints actually run 2026-01-24 09:59:46 +02:00
Elian Doran
e4d319c7a1 chore(web-clipper): define entrypoints 2026-01-24 09:50:25 +02:00
Elian Doran
f8e5f31970 chore(web-clipper): install WXT 2026-01-24 09:45:05 +02:00
Elian Doran
5113e2ab97 chore(web-clipper): create package JSON 2026-01-24 09:42:02 +02:00
Elian Doran
6ae1cc18e2 chore(web-clipper): remove IDEA file 2026-01-24 09:37:03 +02:00
Elian Doran
256ad05d2d Merge branch 'main' of https://github.com/TriliumNext/Trilium 2026-01-24 09:36:18 +02:00
Elian Doran
1b0a53a441 feat(notes): add default icon for doc files 2026-01-24 09:29:11 +02:00
Elian Doran
430ef62a2d feat(notes): add default icon for GIF 2026-01-24 09:24:35 +02:00
renovate[bot]
cd7daee771 chore(deps): update dependency @redocly/cli to v2.14.9 2026-01-24 06:31:00 +00:00
Elian Doran
50aeda8ee8 chore(deps): update dependency cheerio to v1.2.0 (#8488) 2026-01-24 08:28:34 +02:00
renovate[bot]
1520c696a3 chore(deps): update dependency cheerio to v1.2.0 2026-01-24 01:39:45 +00:00
Elian Doran
f63f6244a1 fix: update nixpkgs to grab elector v40 (#8483) 2026-01-23 22:20:43 +02:00
Wael Nasreddine
8611d4a67a fix: update nixpkgs to grab elector v40 2026-01-23 08:31:30 -08:00
Elian Doran
c48bd9a5c3 fix(canvas): saving on start due to library change 2026-01-23 18:12:11 +02:00
Elian Doran
dba985b308 fix(canvas): saving on start due to mismatch in version number 2026-01-23 18:07:11 +02:00
Elian Doran
a51a831fe8 fix(canvas): background color not saved (closes #8325) 2026-01-23 17:56:04 +02:00
Elian Doran
44142e980d fix(quick_edit): not working when content is centered (closes #8371) 2026-01-23 17:17:41 +02:00
Elian Doran
7f83226f84 Calendar improvements (#8478) 2026-01-23 16:25:18 +02:00
Elian Doran
e3fdae8932 chore: address requested changes 2026-01-23 15:02:33 +02:00
Elian Doran
78c62be823 test(client): fix broken tests after change in attributes 2026-01-23 14:57:33 +02:00
Elian Doran
e51cea88bf feat(calendar): don't trigger refresh on delete 2026-01-23 12:47:02 +02:00
Elian Doran
d7409bec49 feat(calendar): don't trigger refresh on rename 2026-01-23 12:35:08 +02:00
Elian Doran
17b1f599ff feat(calendar): don't trigger refresh on event change 2026-01-23 12:24:35 +02:00
Elian Doran
81c85d712e chore(calendar): create note with attributes atomically 2026-01-23 12:11:06 +02:00
Elian Doran
2eae8bbb64 Revert "chore(calendar): remove automatic fetching on note creation"
This reverts commit 2a61f51e06.
2026-01-23 12:05:12 +02:00
Elian Doran
2a61f51e06 chore(calendar): remove automatic fetching on note creation 2026-01-23 11:58:57 +02:00
Elian Doran
3e3c3e3bb4 fix(calendar): redundant refresh when adding new item 2026-01-23 11:38:18 +02:00
Elian Doran
7b41a89b8e chore(deps): update dependency happy-dom to v20.3.7 (#8470) 2026-01-23 09:39:54 +02:00
renovate[bot]
36429da6da chore(deps): update dependency happy-dom to v20.3.7 2026-01-23 07:09:50 +00:00
Elian Doran
30f6ab5976 chore(deps): update dependency @ckeditor/ckeditor5-dev-build-tools to v54.3.2 (#8441) 2026-01-23 09:09:16 +02:00
Elian Doran
99a46f2a85 fix(deps): update dependency lodash-es to v4.17.23 [security] (#8454) 2026-01-23 09:08:39 +02:00
Elian Doran
6754b1f2e1 fix(deps): update dependency @preact/signals to v2.6.1 (#8457) 2026-01-23 09:08:25 +02:00
Elian Doran
122ad2b771 chore(deps): update dependency @redocly/cli to v2.14.7 (#8468) 2026-01-23 09:08:01 +02:00
Elian Doran
714e8ade1a chore(deps): update vitest monorepo to v4.0.18 (#8471) 2026-01-23 09:07:30 +02:00
Elian Doran
4a6ea38be0 chore(deps): update dependency express-session to v1.19.0 (#8472) 2026-01-23 09:06:31 +02:00
Elian Doran
8bc7f0b71f Translations update from Hosted Weblate (#8476) 2026-01-23 09:05:39 +02:00
Hosted Weblate
9a912c16ad 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/
2026-01-23 07:51:59 +01:00
Elian Doran
10a84a1356 chore(deps): update dependency @smithy/middleware-retry to v4.4.27 (#8469) 2026-01-23 08:51:48 +02:00
Wael Nasreddine
901201a7af chore: pnpm2nix to use our copy of flake-utils 2026-01-22 18:59:03 -08:00
renovate[bot]
a57a1dfc47 chore(deps): update dependency express-session to v1.19.0 2026-01-23 00:42:22 +00:00
renovate[bot]
577780cb90 chore(deps): update vitest monorepo to v4.0.18 2026-01-23 00:41:33 +00:00
renovate[bot]
b45eef9140 chore(deps): update dependency @smithy/middleware-retry to v4.4.27 2026-01-23 00:40:10 +00:00
renovate[bot]
907853bbba chore(deps): update dependency @redocly/cli to v2.14.7 2026-01-23 00:39:32 +00:00
Elian Doran
17f3ffd00c fix(mermaid): preview not rendering when read-only (closes #8419) 2026-01-22 20:56:58 +02:00
Elian Doran
8b86e17ac8 fix(client): race condition in syntax highlight (closes #8464) 2026-01-22 20:03:46 +02:00
Elian Doran
d6b6832a1d fix(promoted_attributes): checkbox not displaying initial value properly (closes #8062) 2026-01-22 08:15:40 +02:00
Elian Doran
9dfc1cdc4c fix(render): not refreshing on attribute change (closes #8321) 2026-01-22 08:10:29 +02:00
Elian Doran
673c39d798 Revert "feat(options/advanced): add description for experimental"
This reverts commit fc2ab91280.
2026-01-22 08:05:49 +02:00
renovate[bot]
8ca84d183c fix(deps): update dependency lodash-es to v4.17.23 [security] 2026-01-22 02:03:34 +00:00
renovate[bot]
9577aa2abe fix(deps): update dependency @preact/signals to v2.6.1 2026-01-22 01:45:37 +00:00
perfectra1n
280697f2f7 Revert "feat(etapi): resolve suggestions for norms from gemini"
This reverts commit 0650be664d.
2026-01-21 16:37:02 -08:00
perfectra1n
0650be664d feat(etapi): resolve suggestions for norms from gemini 2026-01-21 16:33:42 -08:00
perfectra1n
60c61f553a feat(etapi): put filtering for revisions mainly in the db layer 2026-01-21 16:30:37 -08:00
perfectra1n
022c967781 feat(etapi): add revisions route and "undelete" route to etapi 2026-01-21 16:25:17 -08:00
Elian Doran
227be184ac fix(shortcuts): overlap on azerty due to key matches 2026-01-21 22:34:36 +02:00
Elian Doran
d677f65eeb chore(deps): update dependency happy-dom to v20.3.4 (#8433) 2026-01-21 19:32:41 +02:00
Elian Doran
92f86bcca2 chore(deps): update dependency @smithy/middleware-retry to v4.4.26 (#8442) 2026-01-21 19:31:35 +02:00
Elian Doran
2015068d9e fix(deps): update dependency @zumer/snapdom to v2.0.2 (#8443) 2026-01-21 19:30:35 +02:00
renovate[bot]
8a280c2f9d chore(deps): update dependency happy-dom to v20.3.4 2026-01-21 17:07:19 +00:00
Elian Doran
34fd6f9502 chore(deps): update dependency lightningcss to v1.31.1 (#8444) 2026-01-21 19:05:45 +02:00
Elian Doran
02acb36e47 chore(deps): update dependency node-abi to v4.26.0 (#8445) 2026-01-21 19:03:13 +02:00
Elian Doran
280c0e0348 fix(deps): update dependency @preact/signals to v2.6.0 (#8446) 2026-01-21 18:27:23 +02:00
Elian Doran
8528f0d848 fix(deps): update dependency i18next to v25.8.0 (#8447) 2026-01-21 18:26:53 +02:00
renovate[bot]
917e881faa chore(deps): update dependency @ckeditor/ckeditor5-dev-build-tools to v54.3.2 2026-01-21 10:43:23 +00:00
renovate[bot]
96b1efcfdc chore(deps): update dependency lightningcss to v1.31.1 2026-01-21 06:17:33 +00:00
renovate[bot]
794e03b2cb fix(deps): update dependency i18next to v25.8.0 2026-01-21 01:37:06 +00:00
renovate[bot]
a285c46b97 fix(deps): update dependency @preact/signals to v2.6.0 2026-01-21 01:36:23 +00:00
renovate[bot]
4da6294ef2 chore(deps): update dependency node-abi to v4.26.0 2026-01-21 01:35:35 +00:00
renovate[bot]
16ed9a7e8e fix(deps): update dependency @zumer/snapdom to v2.0.2 2026-01-21 01:34:07 +00:00
renovate[bot]
798efbc22f chore(deps): update dependency @smithy/middleware-retry to v4.4.26 2026-01-21 01:33:18 +00:00
Elian Doran
60c789b6c7 fix(client): production affected by cache of index JS 2026-01-20 16:33:46 +02:00
Elian Doran
f83d95136d fix(codemirror): ctrl+enter generates newline 2026-01-20 16:11:40 +02:00
Elian Doran
f96ed0af26 Revert "fix(shortcuts): triggering in bubbling phase, not capturing"
This reverts commit 711828d6b4.
2026-01-20 15:16:51 +02:00
Elian Doran
1539664026 Revert "test(client): fix broken tests after change in shortcut behaviour"
This reverts commit e33950e000.
2026-01-20 15:16:32 +02:00
Elian Doran
8aff775d0e chore(deps): update pnpm to v10.28.1 (#8435) 2026-01-20 12:12:26 +02:00
Elian Doran
94248eafe9 chore(deps): update dependency vite-plugin-static-copy to v3.1.5 (#8434) 2026-01-20 12:12:06 +02:00
Elian Doran
02335bba3f chore(deps): update dependency turnish to v1.8.0 (#8437) 2026-01-20 12:11:38 +02:00
renovate[bot]
dad9578b83 chore(deps): update dependency turnish to v1.8.0 2026-01-20 01:16:12 +00:00
renovate[bot]
c043788b09 chore(deps): update pnpm to v10.28.1 2026-01-20 01:15:00 +00:00
renovate[bot]
e5bc416b46 chore(deps): update dependency vite-plugin-static-copy to v3.1.5 2026-01-20 01:14:50 +00:00
Elian Doran
c97f52da36 docs(user): mention breaking change update for scripts 2026-01-19 19:02:54 +02:00
Elian Doran
1661c3292a fix(deps): update dependency jquery to v4 (#8424) 2026-01-19 18:53:11 +02:00
Elian Doran
4e80c07630 Translations update from Hosted Weblate (#8427) 2026-01-19 18:42:06 +02:00
Elian Doran
d43309947e fix(client): polyfill removed jQuery methods 2026-01-19 18:39:22 +02:00
Baris Konag
c7cc702c4a Translated using Weblate (Turkish)
Currently translated at 10.5% (16 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/tr/
2026-01-19 17:22:17 +01:00
Baris Konag
c304753ffc Translated using Weblate (Turkish)
Currently translated at 4.3% (17 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/tr/
2026-01-19 17:22:17 +01:00
Toto Yullian
da59c14231 Translated using Weblate (Indonesian)
Currently translated at 18.1% (21 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/id/
2026-01-19 17:22:16 +01:00
Hosted Weblate
e0b3e41c9e 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/
2026-01-19 17:22:15 +01:00
Elian Doran
5d1a63bce0 fix(print): crash when printing presentation 2026-01-19 14:55:33 +02:00
Elian Doran
84cf4ef4a3 fix(print): only first page is shown 2026-01-19 13:51:27 +02:00
Elian Doran
ec4b6f0a90 chore(deps): update dependency happy-dom to v20.3.3 (#8426) 2026-01-19 08:48:02 +02:00
renovate[bot]
60dbdbeb71 chore(deps): update dependency happy-dom to v20.3.3 2026-01-19 02:05:32 +00:00
Elian Doran
418a546583 fix(print): clicking inside print preview hides it 2026-01-18 22:39:09 +02:00
Elian Doran
e6380b87b6 fix(print): some collections not rendered at all 2026-01-18 22:26:13 +02:00
Elian Doran
1d3d214101 fix(print): not printing at all 2026-01-18 22:05:16 +02:00
Elian Doran
a38067560b SQL console improvements (#8418) 2026-01-18 18:52:14 +02:00
Elian Doran
eac7235199 chore(sql_console): address requested changes 2026-01-18 18:38:14 +02:00
Elian Doran
4c55e857b8 fix(server): build failing due to import 2026-01-18 18:33:48 +02:00
Elian Doran
e33950e000 test(client): fix broken tests after change in shortcut behaviour 2026-01-18 18:22:21 +02:00
Elian Doran
fc0ccbfcf5 chore(sql_console): address requested changes 2026-01-18 18:19:35 +02:00
Elian Doran
4a82bbb035 docs(user): update SQL console based on new interaction 2026-01-18 18:06:30 +02:00
Elian Doran
57d894e765 feat(sql_console): enable read-only for saved notes 2026-01-18 17:47:09 +02:00
Elian Doran
97dfad419c docs(user): refresh photo for SQL console 2026-01-18 17:35:01 +02:00
Elian Doran
bfc521fdc0 fix(sql_console): enforce vertical layout 2026-01-18 17:11:03 +02:00
Elian Doran
197fa90176 style(sql_console): improve style for frozen cell 2026-01-18 13:09:46 +02:00
Elian Doran
0844914e11 style(sql_console): improve style for highlighted range 2026-01-18 13:05:18 +02:00
Elian Doran
c376b0bbe2 style(sql_console): improve filter spacing 2026-01-18 12:35:42 +02:00
Elian Doran
4491086c55 style(sql_console): improve header & footer inputs 2026-01-18 12:34:00 +02:00
Elian Doran
791697369d style(sql_console): remove background for footer 2026-01-18 12:22:53 +02:00
Elian Doran
28d0bfd229 chore(sql_console): reducing padding in footer 2026-01-18 12:12:05 +02:00
Elian Doran
8182a04eae fix(sql_console): not refreshing when switching between notes 2026-01-18 12:09:01 +02:00
Elian Doran
711828d6b4 fix(shortcuts): triggering in bubbling phase, not capturing 2026-01-18 12:07:23 +02:00
Elian Doran
69e88c1d9f chore(sql_console): set gutter color 2026-01-18 11:48:34 +02:00
Elian Doran
748b87da9a feat(sql_console): improve display for statements 2026-01-18 11:34:31 +02:00
Elian Doran
94dca4cd87 feat(sql_console): report errors inline 2026-01-18 11:13:31 +02:00
Elian Doran
7179701e0f feat(sql_console): improve no results 2026-01-18 10:58:32 +02:00
Elian Doran
af5061646c feat(sql_console): add not yet executed message 2026-01-18 10:36:44 +02:00
Elian Doran
9c4163ad3a feat(sql_console): page size selector 2026-01-18 10:24:55 +02:00
Elian Doran
46c3f5296a chore(sql_console): full-height table 2026-01-18 10:20:15 +02:00
Elian Doran
ebadcfd844 feat(sql_console): enable pagination 2026-01-18 10:14:55 +02:00
Elian Doran
b7d4947462 Merge remote-tracking branch 'origin/main' into feature/sql_console_improvements 2026-01-18 10:08:48 +02:00
Elian Doran
a599526dea chore(deps): update dependency @smithy/middleware-retry to v4.4.24 (#8420) 2026-01-18 08:34:59 +02:00
Elian Doran
c4f166fe12 chore(deps): update dependency webdriverio to v9.23.2 (#8421) 2026-01-18 08:34:19 +02:00
Elian Doran
a8ae91aa3b Translations update from Hosted Weblate (#8425) 2026-01-18 08:33:02 +02:00
Elian Doran
82b3692acb fix(deps): update dependency better-sqlite3 to v12.6.2 (#8422) 2026-01-18 08:32:12 +02:00
Hosted Weblate
432c054b68 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/
2026-01-18 06:25:42 +00:00
Elian Doran
dcd8bfa255 fix(deps): update dependency mind-elixir to v5.6.1 (#8423) 2026-01-18 08:25:28 +02:00
renovate[bot]
c287a2ae97 fix(deps): update dependency mind-elixir to v5.6.1 2026-01-18 05:39:59 +00:00
renovate[bot]
8fdadb3798 fix(deps): update dependency jquery to v4 2026-01-18 01:40:46 +00:00
renovate[bot]
3fce4fc66c fix(deps): update dependency better-sqlite3 to v12.6.2 2026-01-18 01:39:14 +00:00
renovate[bot]
d83d7ed106 chore(deps): update dependency webdriverio to v9.23.2 2026-01-18 01:38:26 +00:00
renovate[bot]
1b812f1886 chore(deps): update dependency @smithy/middleware-retry to v4.4.24 2026-01-18 01:37:35 +00:00
Elian Doran
56fcc7adcc chore(sql_console): fix lint warnings 2026-01-17 22:41:55 +02:00
Elian Doran
fb0c7359f1 chore(sql_console): fix typecheck issue 2026-01-17 22:39:32 +02:00
Elian Doran
4c4e5b85e9 chore(sql_console): integrate table reference 2026-01-17 22:38:18 +02:00
Elian Doran
476247beb5 feat(sql_console): increase size for results 2026-01-17 22:29:20 +02:00
Elian Doran
2c87f609f3 feat(sql_console): add filter 2026-01-17 22:13:13 +02:00
Elian Doran
bc79ff6845 feat(sql_console): row numbers 2026-01-17 22:09:24 +02:00
Elian Doran
f10373d54f feat(sql_console): add clipboard 2026-01-17 22:02:47 +02:00
Elian Doran
630d16b722 feat(sql_console): enable sorting 2026-01-17 21:47:02 +02:00
Elian Doran
769f3db21c feat(sql_console): make columns resizable 2026-01-17 21:45:10 +02:00
Elian Doran
c6896a4b33 feat(sql_console): reduce column width 2026-01-17 21:43:21 +02:00
Elian Doran
7c18025098 feat(sql_console): reduce spacing to fit more content 2026-01-17 21:41:06 +02:00
Elian Doran
6ae74b3181 feat(sql_console): make scrolls and headers always visible 2026-01-17 21:35:58 +02:00
Elian Doran
2ecfbbf284 feat(sql_console): improve fit & solve build error 2026-01-17 21:26:44 +02:00
Elian Doran
781de9a1fb feat(sql_console): basic integration of Tabulator 2026-01-17 21:22:22 +02:00
Elian Doran
6972a4b901 fix(note_detail): preview leaks between mermaid & SQL console 2026-01-17 20:58:26 +02:00
Elian Doran
52ed1750ac fix(sql_console): runtime error for inline title 2026-01-17 20:52:53 +02:00
Elian Doran
9010e0b1ce chore(sql_console): reverse preview and code sections 2026-01-17 20:44:03 +02:00
Elian Doran
5053e74447 fix(sql_console): note type switcher showing up 2026-01-17 20:41:45 +02:00
Elian Doran
f294276849 fix(sql_console): full-height not respected 2026-01-17 20:38:44 +02:00
Elian Doran
0740788cc8 chore(sql_console): link stylesheet 2026-01-17 20:32:28 +02:00
Elian Doran
9bac07ce62 chore(sql_console): integrate results into preview of split 2026-01-17 20:29:15 +02:00
Elian Doran
3d8289d394 chore(note_detail): get code editor to show 2026-01-17 20:12:16 +02:00
Elian Doran
5a60fdad8a chore(note_detail): map SQL console to own type widget 2026-01-17 20:09:25 +02:00
Elian Doran
62cca5a96b Merge branch 'main' of https://github.com/TriliumNext/Trilium 2026-01-17 18:57:03 +02:00
Elian Doran
74548d638e docs(user): sync 2026-01-17 18:13:40 +02:00
Elian Doran
e0ccf30f4f docs(user): add missing links from Evernote documentation 2026-01-17 17:59:30 +02:00
Elian Doran
d2c6081537 feat(edit-docs): remove data-list-item-id 2026-01-17 17:54:10 +02:00
Elian Doran
bd933f2c4c Translations update from Hosted Weblate (#8416) 2026-01-17 17:43:15 +02:00
Yatrik Patel
1d898d618e Translated using Weblate (Hindi)
Currently translated at 7.7% (30 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/hi/
2026-01-17 15:40:43 +00:00
Yatrik Patel
11c8e5b3b2 Translated using Weblate (Hindi)
Currently translated at 35.5% (54 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/hi/
2026-01-17 15:40:43 +00:00
Hosted Weblate
fe4c3ffecb 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/
2026-01-17 15:40:42 +00:00
Elian Doran
334a96186e chore(deps): update dependency electron to v40 (#8415) 2026-01-17 17:40:34 +02:00
Elian Doran
34b2df705b Fixes to Markdown export (#8417) 2026-01-17 14:19:36 +02:00
Elian Doran
5a7fc1c8b6 chore(markdown): address requested changes 2026-01-17 13:22:24 +02:00
Elian Doran
fabab6abb1 refactor(export/markdown): spacing issues 2026-01-17 13:16:21 +02:00
Elian Doran
0c9c20c0c5 docs(user): fix escapes 2026-01-17 13:11:53 +02:00
Elian Doran
67cc1113b1 chore(export/markdown): render emphasis with underscore 2026-01-17 13:05:29 +02:00
Elian Doran
3aacd255f4 chore(export/markdown): add test for jQuery-like text inside table 2026-01-17 12:58:24 +02:00
renovate[bot]
ccfda21413 chore(deps): update dependency electron to v40 2026-01-17 10:53:59 +00:00
Elian Doran
46c88506cc chore(deps): update dependency ejs to v4 (#8396) 2026-01-17 12:52:06 +02:00
Elian Doran
51157e1979 fix(export/markdown): error due to namespace usage 2026-01-17 12:47:34 +02:00
Elian Doran
bfb6d975ff fix(export/markdown): type error due to blankReplacement signature change 2026-01-17 12:46:55 +02:00
Elian Doran
aa01bc1457 feat(markdown): switch to turnish instead of turndown 2026-01-17 12:44:30 +02:00
Elian Doran
5600f1b7b1 chore(deps): update dependency node-abi to v4.25.0 (#8414) 2026-01-17 12:17:38 +02:00
Elian Doran
a169db807c fix(server): crashing due to EJS handling 2026-01-17 12:17:15 +02:00
Elian Doran
f40348daff chore(deps): update dependency happy-dom to v20.3.1 (#8405) 2026-01-17 12:09:57 +02:00
renovate[bot]
f63042ef87 chore(deps): update dependency ejs to v4 2026-01-17 10:01:09 +00:00
renovate[bot]
d148c9d1c6 chore(deps): update dependency node-abi to v4.25.0 2026-01-17 10:00:12 +00:00
renovate[bot]
f72929ca13 chore(deps): update dependency happy-dom to v20.3.1 2026-01-17 09:59:13 +00:00
Elian Doran
cc3e3ca4d4 fix(deps): update ckeditor monorepo to v47.4.0 (#8395) 2026-01-17 11:55:54 +02:00
Elian Doran
8fad664a6d Translations update from Hosted Weblate (#8413) 2026-01-16 23:16:08 +02:00
Kf637
f1946c1386 Translated using Weblate (Norwegian Bokmål)
Currently translated at 6.7% (26 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/nb_NO/
2026-01-16 22:08:01 +01:00
Kf637
ea8bd0136f Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (152 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/nb_NO/
2026-01-16 22:08:00 +01:00
Elian Doran
4a3f72ae50 Translations update from Hosted Weblate (#8411) 2026-01-16 19:14:11 +02:00
Hosted Weblate
c944762ef6 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/
2026-01-16 14:25:37 +00:00
Elian Doran
f6924d7fda feat(import/zip): remove extension from title for PDF imports 2026-01-16 16:25:15 +02:00
Elian Doran
3a0880fcd6 feat(import/single): remove extension from title for PDF imports 2026-01-16 12:01:11 +02:00
Elian Doran
df62dc87b2 feat(notes): add default icon for PDFs 2026-01-16 11:47:42 +02:00
Elian Doran
d42679315e refactor(server): use common logic for icons 2026-01-16 11:42:37 +02:00
Elian Doran
2a19be5ab6 refactor(client): extract fnote icon logic in commons 2026-01-16 09:35:51 +02:00
renovate[bot]
33bbe994d7 fix(deps): update ckeditor monorepo to v47.4.0 2026-01-16 06:55:00 +00:00
Elian Doran
04c598caea build(deps): bump diff from 4.0.2 to 8.0.3 (#8390) 2026-01-16 08:50:51 +02:00
Elian Doran
3577688bf9 fix(deps): update dependency @codemirror/view to v6.39.11 (#8392) 2026-01-16 08:50:34 +02:00
Elian Doran
e0439655df chore(deps): update dependency @smithy/middleware-retry to v4.4.23 (#8403) 2026-01-16 08:47:12 +02:00
Elian Doran
84f944f78a chore(deps): update dependency @types/node to v24.10.9 (#8404) 2026-01-16 08:46:51 +02:00
Elian Doran
022b6df959 chore(deps): update dependency stylelint to v17 (#8406) 2026-01-16 08:46:18 +02:00
renovate[bot]
9e3e92669f chore(deps): update dependency stylelint to v17 2026-01-16 00:58:48 +00:00
renovate[bot]
35b96a71fc chore(deps): update dependency @types/node to v24.10.9 2026-01-16 00:51:41 +00:00
renovate[bot]
4b78de6726 chore(deps): update dependency @smithy/middleware-retry to v4.4.23 2026-01-16 00:51:08 +00:00
Elian Doran
4771e02909 chore(deps): update dependency happy-dom to v20.3.0 (#8393) 2026-01-15 08:49:43 +02:00
Elian Doran
03dffdb65f chore(deps): update node.js to v24.13.0 (#8394) 2026-01-15 08:49:01 +02:00
Elian Doran
859a3948cd Translations update from Hosted Weblate (#8398) 2026-01-15 08:09:44 +02:00
Hasan Kara
161aa625e6 Translated using Weblate (Turkish)
Currently translated at 9.2% (14 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/tr/
2026-01-15 04:09:54 +01:00
Hasan Kara
28fd945e80 Translated using Weblate (Turkish)
Currently translated at 3.6% (14 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/tr/
2026-01-15 04:09:53 +01:00
renovate[bot]
748fb0bf05 chore(deps): update node.js to v24.13.0 2026-01-15 02:00:34 +00:00
renovate[bot]
98e1d0afd9 chore(deps): update dependency happy-dom to v20.3.0 2026-01-15 02:00:27 +00:00
renovate[bot]
9c61ce1835 fix(deps): update dependency @codemirror/view to v6.39.11 2026-01-15 01:59:39 +00:00
dependabot[bot]
c3a5705be0 build(deps): bump diff from 4.0.2 to 8.0.3
Bumps [diff](https://github.com/kpdecker/jsdiff) from 4.0.2 to 8.0.3.
- [Changelog](https://github.com/kpdecker/jsdiff/blob/master/release-notes.md)
- [Commits](https://github.com/kpdecker/jsdiff/compare/v4.0.2...v8.0.3)

---
updated-dependencies:
- dependency-name: diff
  dependency-version: 8.0.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-14 22:53:04 +00:00
Elian Doran
9d0fa9f7ca Fix sorting (#7878) 2026-01-14 17:18:41 +02:00
Elian Doran
cc4ceb975e fix(tree): not reacting to note reordering (e.g. sort) 2026-01-14 17:15:29 +02:00
Elian Doran
8a6495a0bd Translations update from Hosted Weblate (#8386) 2026-01-14 16:48:46 +02:00
Elian Doran
1d95392d22 docs(user): improve Evernote documentation 2026-01-14 16:06:58 +02:00
Hosted Weblate
93dd08d629 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/
2026-01-14 14:06:53 +00:00
Elian Doran
f466367c4d Translations update from Hosted Weblate (#8384) 2026-01-14 07:48:07 +02:00
Yatrik Patel
924d495d2e Translated using Weblate (Hindi)
Currently translated at 7.2% (28 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/hi/
2026-01-14 05:42:20 +00:00
Hosted Weblate
0b5c1b648b 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/
2026-01-14 05:42:19 +00:00
Elian Doran
03ec39f52a chore(deps): update dependency @smithy/middleware-retry to v4.4.22 (#8377) 2026-01-14 07:42:05 +02:00
Elian Doran
f3ae1bf12c fix(deps): update dependency react-i18next to v16.5.3 (#8378) 2026-01-14 07:41:51 +02:00
Elian Doran
6d61cf41d9 chore(deps): update dependency @ckeditor/ckeditor5-dev-build-tools to v54.3.0 (#8379) 2026-01-14 07:41:35 +02:00
Elian Doran
333679523b fix(deps): update codemirror (#8381) 2026-01-14 07:41:17 +02:00
Elian Doran
1cd3a361f6 chore(deps): update node.js to v24.13.0 (#8380) 2026-01-14 07:41:03 +02:00
renovate[bot]
7405627663 fix(deps): update codemirror 2026-01-14 01:03:37 +00:00
renovate[bot]
2c4fb6c0d0 chore(deps): update node.js to v24.13.0 2026-01-14 01:02:53 +00:00
renovate[bot]
3e284208ef chore(deps): update dependency @ckeditor/ckeditor5-dev-build-tools to v54.3.0 2026-01-14 01:01:57 +00:00
renovate[bot]
42b7f4c795 fix(deps): update dependency react-i18next to v16.5.3 2026-01-14 01:01:06 +00:00
renovate[bot]
d445209eeb chore(deps): update dependency @smithy/middleware-retry to v4.4.22 2026-01-14 01:00:18 +00:00
Elian Doran
ed1bf17add feat(i18n): add workflow to check translation coverage (#8376) 2026-01-13 23:06:10 +02:00
Elian Doran
4800f2a172 chore(ci/i18n): add permissions 2026-01-13 22:56:27 +02:00
Elian Doran
e7ff364c01 chore(i18n): trigger on workflow change 2026-01-13 22:52:51 +02:00
Elian Doran
79ca299726 feat(i18n): add workflow to check translation coverage 2026-01-13 22:49:46 +02:00
Elian Doran
9d7ba48a6a Translations update from Hosted Weblate (#8375) 2026-01-13 22:28:17 +02:00
Gishky
9329665919 Translated using Weblate (English (United Kingdom))
Currently translated at 1.9% (34 of 1759 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/en_GB/
2026-01-13 21:23:46 +01:00
Gishky
f6821bce03 Translated using Weblate (German)
Currently translated at 100.0% (1759 of 1759 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-01-13 21:23:45 +01:00
Gishky
a7aedf93ab 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/
2026-01-13 21:23:45 +01:00
Elian Doran
4ffcf01452 fix: mac alt shortcuts (#8369) 2026-01-13 22:23:38 +02:00
Elian Doran
618459d353 feat(flake): provide .#edit-docs as a standalone docs editor (#8350) 2026-01-13 22:22:58 +02:00
Elian Doran
6436c16449 Fix race condition in edit-docs Electron ready event (#8344) 2026-01-13 22:20:22 +02:00
Elian Doran
1bec457004 Translations update from Hosted Weblate (#8374) 2026-01-13 21:58:13 +02:00
Hosted Weblate
3e541e37fe 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/
2026-01-13 20:44:40 +01:00
Elian Doran
a41b78d36f feat(ux): show more helpful output when users encounter permissions issues within the data directory (#8273) 2026-01-13 21:44:30 +02:00
Elian Doran
79c50f3b4c fix(deps): update dependency react-i18next to v16.5.2 (#8348) 2026-01-13 13:38:55 +02:00
Elian Doran
0f54b01cdd chore(deps): update dependency @smithy/middleware-retry to v4.4.20 (#8362) 2026-01-13 10:45:41 +02:00
Elian Doran
41f2b03711 chore(deps): update dependency @redocly/cli to v2.14.5 (#8361) 2026-01-13 10:33:06 +02:00
Elian Doran
0be76f982c Merge branch 'main' into renovate/smithy-middleware-retry-4.x 2026-01-13 10:33:02 +02:00
Elian Doran
5deb277672 chore(deps): update vitest monorepo to v4.0.17 (#8363) 2026-01-13 10:32:25 +02:00
Elian Doran
3d15c9e94c Translations update from Hosted Weblate (#8370) 2026-01-13 10:22:31 +02:00
noobhjy
1363f94621 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (1759 of 1759 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hans/
2026-01-13 08:14:58 +00:00
Kim Nøglegaard
abdcd6cc0c Translated using Weblate (Norwegian Bokmål)
Currently translated at 6.4% (25 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/nb_NO/
2026-01-13 08:14:58 +00:00
nvno
dc8abed2f3 Translated using Weblate (Portuguese)
Currently translated at 99.6% (1753 of 1759 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/pt/
2026-01-13 08:14:57 +00:00
Kim Nøglegaard
892c2cd838 Translated using Weblate (Norwegian Bokmål)
Currently translated at 2.3% (41 of 1759 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/nb_NO/
2026-01-13 08:14:56 +00:00
Hosted Weblate
2796b29138 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/
2026-01-13 08:14:55 +00:00
Elian Doran
05620a129f chore(deps): update electron-forge monorepo to v7.11.1 (#8366) 2026-01-13 10:14:48 +02:00
renovate[bot]
cb11955a44 chore(deps): update vitest monorepo to v4.0.17 2026-01-13 08:12:19 +00:00
Elian Doran
c3623a15fb fix(ci): website workflow failing due to postinstall scripts 2026-01-13 10:09:51 +02:00
Wael Nasreddine
0273c64bbf Build edit-docs as standalone package using makeApp
Changed edit-docs from a simple wrapper script to a properly built Nix
package using makeApp, similar to how desktop and server are built.

Changes:
- Added build script to apps/edit-docs/package.json
- Created apps/edit-docs/scripts/build.ts based on desktop's build script
- Added edit-docs:build task to root package.json
- Changed flake.nix to use makeApp which:
  - Builds edit-docs with all dependencies bundled
  - Creates a standalone trilium-edit-docs executable
  - Can be installed with 'nix profile install' and run from any directory

This makes edit-docs truly reusable - it can now be installed and run
from any project without requiring the Trilium source tree.
2026-01-12 22:08:27 -08:00
Wael Nasreddine
5b37140ffa Fix race condition in edit-docs Electron ready event
The edit-docs tool would hang on startup when the Electron 'ready' event
fired before the event listener was registered. This race condition occurred
because:

1. startElectron() creates a deferred promise and registers a 'ready' listener
2. The 'ready' event fires asynchronously at some point during app initialization
3. If async work (like config loading) delays the listener registration,
   Electron may already be ready when app.on('ready', ...) is called
4. Once fired, the 'ready' event doesn't fire again, leaving the listener
   waiting forever

The fix checks electron.app.isReady() before registering the listener:
- If already ready: execute the handler immediately
- If not ready: register the listener as before

This ensures the initialization sequence completes regardless of timing.

The issue became apparent while working on making edit-docs reusable from
other projects (see #8343), where config loading added enough async delay
to consistently trigger the race condition.

Related: https://github.com/TriliumNext/Trilium/issues/8343
2026-01-12 22:08:27 -08:00
Wael Nasreddine
fb4d63b049 Add --config, --help, and --version flags to edit-docs
- Implement --config (-c) flag to allow custom configuration file paths.
- Add --help (-h) flag to display tool usage and available options.
- Add --version (-v) flag to display the current Trilium version.
- Update electron-start.mts to correctly pass command-line arguments to Electron.
- Synchronize edit-docs version with the root package.json via update-version.ts.
- Resolve config paths relative to the configuration file's directory.

This makes edit-docs more robust and easier to use from external projects
and immutable environments like Nix.
2026-01-12 22:08:27 -08:00
Wael Nasreddine
015e41e792 fix(edit-docs): Minify meta for format==share 2026-01-12 22:08:27 -08:00
Wael Nasreddine
8e47f33329 Refactor edit-docs to use edit-docs-config.yaml
This removes hardcoded configuration from edit-docs.ts and replaces
it with dynamic loading from edit-docs-config.yaml.

Changes:
- Removed BASE_URL and NOTE_MAPPINGS constants
- Removed DOCS_ROOT and USER_GUIDE_ROOT environment variable dependencies
- Added js-yaml for YAML parsing
- Config paths are resolved relative to repository root

The tool now reads configuration from edit-docs-config.yaml, making it
easier to customize without code changes. The pnpm script is simplified
since it no longer needs to pass complex environment variables.
2026-01-12 22:08:27 -08:00
Elian Doran
ad4a8ec5f4 chore(deps): use pinned versions 2026-01-13 07:40:20 +02:00
renovate[bot]
56356f9c61 fix(deps): update dependency react-i18next to v16.5.2 2026-01-13 05:38:17 +00:00
Elian Doran
abda0f9111 chore(deps): update dependency happy-dom to v20.1.0 (#8307) 2026-01-13 07:35:35 +02:00
Elian Doran
c2a9d21198 fix(deps): update dependency i18next to v25.7.4 (#8305) 2026-01-13 07:34:54 +02:00
Elian Doran
59ffa1fa93 fix(deps): update dependency diff to v8.0.3 (#8364) 2026-01-13 07:33:16 +02:00
Elian Doran
d056185368 chore(deps): update dependency eslint-plugin-playwright to v2.5.0 (#8365) 2026-01-13 07:32:37 +02:00
Elian Doran
251c1f6471 chore(deps): update typescript-eslint monorepo to v8.53.0 (#8367) 2026-01-13 07:32:15 +02:00
Chloe Lee
9efca9827e Merge branch 'main' into fix/mac-alt-shortcuts 2026-01-13 10:54:30 +08:00
renovate[bot]
f5e2129ad4 chore(deps): update typescript-eslint monorepo to v8.53.0 2026-01-13 01:17:33 +00:00
renovate[bot]
6c8e6f2429 chore(deps): update electron-forge monorepo to v7.11.1 2026-01-13 01:16:59 +00:00
renovate[bot]
9b4b1a393e chore(deps): update dependency eslint-plugin-playwright to v2.5.0 2026-01-13 01:16:28 +00:00
renovate[bot]
028334407c fix(deps): update dependency diff to v8.0.3 2026-01-13 01:15:54 +00:00
renovate[bot]
b93540b40d chore(deps): update dependency @smithy/middleware-retry to v4.4.20 2026-01-13 01:14:27 +00:00
renovate[bot]
9e7eba5eab chore(deps): update dependency @redocly/cli to v2.14.5 2026-01-13 01:13:45 +00:00
Elian Doran
fcfa64ae52 Translations update from Hosted Weblate (#8358) 2026-01-12 19:29:13 +02:00
Hosted Weblate
62f5b800b6 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/
2026-01-12 17:28:06 +00:00
Elian Doran
5b910cce56 fix: add "latex" alias for math command (#8357) 2026-01-12 19:27:50 +02:00
chloelee767
a5e8c8f573 add tests 2026-01-13 00:05:07 +08:00
Atmois
2c8edb413e fix: add "latex" alias for math command 2026-01-12 16:02:45 +00:00
chloelee767
644cc27fa7 fix alt shortcuts on mac not triggering 2026-01-12 23:05:42 +08:00
Elian Doran
71d3eb4fde Translations update from Hosted Weblate (#8340) 2026-01-12 07:58:21 +02:00
Elian Doran
7c2340d60e Apply suggestion from @gemini-code-assist[bot]
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-01-12 07:55:25 +02:00
Elian Doran
24013ef020 Apply suggestion from @gemini-code-assist[bot]
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-01-12 07:55:16 +02:00
renovate[bot]
72d9e846b7 fix(deps): update dependency i18next to v25.7.4 2026-01-12 05:55:15 +00:00
Yatrik Patel
b572ea0954 Translated using Weblate (Hindi)
Currently translated at 12.0% (14 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/hi/
2026-01-12 06:51:45 +01:00
Francis C.
060257fa06 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (1759 of 1759 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hant/
2026-01-12 06:51:44 +01:00
Yatrik Patel
1c6bb0a20e Translated using Weblate (Hindi)
Currently translated at 6.9% (27 of 388 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/hi/
2026-01-12 06:51:43 +01:00
Hosted Weblate
1479109582 Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/
2026-01-12 06:51:42 +01:00
Yatrik Patel
13f4e38f48 Translated using Weblate (Hindi)
Currently translated at 6.6% (26 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/hi/
2026-01-12 06:51:41 +01:00
Yatrik Patel
5cbde8d32a Translated using Weblate (Hindi)
Currently translated at 1.1% (20 of 1759 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/hi/
2026-01-12 06:51:40 +01:00
Yatrik Patel
f3e3ef2f7d Translated using Weblate (Hindi)
Currently translated at 37.5% (57 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/hi/
2026-01-12 06:51:39 +01:00
Yatrik Patel
0a58f8108a Translated using Weblate (Hindi)
Currently translated at 10.3% (12 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/hi/
2026-01-12 06:51:38 +01:00
green
768213438a Translated using Weblate (Japanese)
Currently translated at 100.0% (1759 of 1759 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ja/
2026-01-12 06:51:38 +01:00
Kim Nøglegaard
00e0eb6f8a Translated using Weblate (Norwegian Bokmål)
Currently translated at 2.8% (11 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/nb_NO/
2026-01-12 06:51:37 +01:00
Kim Nøglegaard
3abea13d79 Translated using Weblate (Norwegian Bokmål)
Currently translated at 1.8% (33 of 1759 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/nb_NO/
2026-01-12 06:51:36 +01:00
noobhjy
67ab7f0c1e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (1757 of 1759 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hans/
2026-01-12 06:51:35 +01:00
Kim Nøglegaard
b38e8e27b2 Translated using Weblate (Norwegian Bokmål)
Currently translated at 2.5% (10 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/nb_NO/
2026-01-12 06:51:34 +01:00
Kim Nøglegaard
a70c103b93 Translated using Weblate (Norwegian Bokmål)
Currently translated at 1.4% (26 of 1759 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/nb_NO/
2026-01-12 06:51:34 +01:00
Yatrik Patel
b83c3090f7 Translated using Weblate (Hindi)
Currently translated at 1.0% (19 of 1759 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/hi/
2026-01-12 06:51:33 +01:00
Bart Louwers
59ee38e7a6 Translated using Weblate (Dutch)
Currently translated at 23.0% (35 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/nl/
2026-01-12 06:51:32 +01:00
Bart Louwers
890fe5929b Translated using Weblate (Dutch)
Currently translated at 4.2% (75 of 1751 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/nl/
2026-01-12 06:51:31 +01:00
nvno
56cc312565 Translated using Weblate (Portuguese)
Currently translated at 91.5% (1603 of 1751 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/pt/
2026-01-12 06:51:30 +01:00
Elian Doran
9dfd015a27 fix(deps): update dependency preact to v10.28.2 [security] (#8301) 2026-01-12 07:51:22 +02:00
Elian Doran
04618dcdab fix(deps): update dependency react-window to v2.2.5 (#8353) 2026-01-12 07:50:09 +02:00
Elian Doran
f408e15c32 chore(deps): update dependency typedoc to v0.28.16 (#8352) 2026-01-12 07:49:20 +02:00
renovate[bot]
00e60c147c fix(deps): update dependency react-window to v2.2.5 2026-01-12 00:58:16 +00:00
renovate[bot]
ad6fd64226 chore(deps): update dependency typedoc to v0.28.16 2026-01-12 00:57:28 +00:00
renovate[bot]
6595fd9c10 chore(deps): update dependency happy-dom to v20.1.0 2026-01-11 14:43:06 +00:00
Elian Doran
a268507b80 chore(deps): update dependency ws to v8.19.0 (#8276) 2026-01-11 16:41:38 +02:00
renovate[bot]
9e847f67f2 chore(deps): update dependency ws to v8.19.0 2026-01-11 14:27:35 +00:00
renovate[bot]
df4992122b fix(deps): update dependency preact to v10.28.2 [security] 2026-01-11 14:26:08 +00:00
Elian Doran
a325ba7b8f chore(deps): update dependency @types/node to v24.10.7 (#8347) 2026-01-11 16:23:31 +02:00
Elian Doran
26e64ae7d0 Lightweight: Bootstrap index EJS (#8283) 2026-01-11 15:45:25 +02:00
renovate[bot]
d793774f51 chore(deps): update dependency @types/node to v24.10.7 2026-01-11 13:32:09 +00:00
Elian Doran
c5f2b5c177 fix(deps): update dependency react-window to v2.2.4 (#8275) 2026-01-11 15:31:53 +02:00
Elian Doran
b2f782f2a3 fix(deps): update dependency node-html-parser to v7.0.2 (#8306) 2026-01-11 15:31:24 +02:00
Elian Doran
b65b31ca4d chore(deps): update dependency vite to v7.3.1 (#8304) 2026-01-11 15:29:23 +02:00
Elian Doran
64827dcdcf fix(deps): update dependency mind-elixir to v5.5.0 (#8278) 2026-01-11 15:28:42 +02:00
Elian Doran
96d5d07087 chore(deps): update dependency @redocly/cli to v2.14.4 (#8316) 2026-01-11 15:27:44 +02:00
Elian Doran
ffd0f4727a chore(deps): update typescript-eslint monorepo to v8.52.0 (#8277) 2026-01-11 15:26:38 +02:00
Elian Doran
e33cd86d30 chore(deps): update dependency supertest to v7.2.2 (#8291) 2026-01-11 15:25:53 +02:00
Elian Doran
fc85c23a67 fix(deps): update dependency @codemirror/view to v6.39.9 (#8289) 2026-01-11 15:25:17 +02:00
Elian Doran
a55c8fb210 chore(deps): update dependency sax to v1.4.4 (#8317) 2026-01-11 15:24:44 +02:00
Elian Doran
19b865a5b4 chore(deps): update dependency express-openid-connect to v2.19.4 (#8327) 2026-01-11 15:24:10 +02:00
Elian Doran
61d90dda36 chore(deps): update dependency @smithy/middleware-retry to v4.4.19 (#8303) 2026-01-11 14:15:07 +02:00
Elian Doran
a4b1f06475 chore(deps): update dependency eslint-plugin-playwright to v2.4.1 (#8326) 2026-01-11 14:14:10 +02:00
Elian Doran
49704ea928 chore(deps): update dependency openai to v6.16.0 (#8328) 2026-01-11 14:13:32 +02:00
Elian Doran
a73df362d5 fix(deps): update dependency better-sqlite3 to v12.6.0 (#8349) 2026-01-11 14:13:06 +02:00
renovate[bot]
f42010e22a fix(deps): update dependency mind-elixir to v5.5.0 2026-01-11 10:28:35 +00:00
renovate[bot]
0b85e0fe2d fix(deps): update dependency better-sqlite3 to v12.6.0 2026-01-11 10:27:40 +00:00
renovate[bot]
c7f0720237 chore(deps): update typescript-eslint monorepo to v8.52.0 2026-01-11 10:26:45 +00:00
renovate[bot]
cc3031eaad chore(deps): update dependency supertest to v7.2.2 2026-01-11 10:25:13 +00:00
renovate[bot]
2850c7808c chore(deps): update dependency openai to v6.16.0 2026-01-11 10:24:24 +00:00
renovate[bot]
30bbcd866f fix(deps): update dependency react-window to v2.2.4 2026-01-11 10:22:53 +00:00
renovate[bot]
55b6f322ac fix(deps): update dependency node-html-parser to v7.0.2 2026-01-11 10:21:22 +00:00
Elian Doran
4518c9bb99 Merge remote-tracking branch 'origin/main' into lightweight/bootstrap_ejs 2026-01-11 12:20:17 +02:00
renovate[bot]
c551c863f4 fix(deps): update dependency @codemirror/view to v6.39.9 2026-01-11 10:19:51 +00:00
renovate[bot]
3c25f8b4f3 chore(deps): update dependency vite to v7.3.1 2026-01-11 10:19:14 +00:00
renovate[bot]
d3c37556c3 chore(deps): update dependency sax to v1.4.4 2026-01-11 10:18:42 +00:00
renovate[bot]
cf60fcd6c1 chore(deps): update dependency express-openid-connect to v2.19.4 2026-01-11 10:18:10 +00:00
renovate[bot]
97075ff91b chore(deps): update dependency eslint-plugin-playwright to v2.4.1 2026-01-11 10:17:37 +00:00
renovate[bot]
ce57a43d90 chore(deps): update dependency @smithy/middleware-retry to v4.4.19 2026-01-11 10:15:52 +00:00
renovate[bot]
33485369c3 chore(deps): update dependency @redocly/cli to v2.14.4 2026-01-11 10:15:00 +00:00
Elian Doran
7fcd93a61b e2e(server): fix broken e2e test after MathTex integration 2026-01-11 11:55:49 +02:00
Elian Doran
3d4b84c7c4 e2e(server): format file 2026-01-11 11:49:49 +02:00
Elian Doran
61eb4017dd Vite performance improvement (#8345) 2026-01-11 11:28:36 +02:00
Elian Doran
b4df4aaf0d chore(client): address requested changes 2026-01-11 11:06:59 +02:00
Elian Doran
244294f699 Revert "chore(scripts): remove analyze-perf"
This reverts commit 94d4a307cf.
2026-01-11 10:55:47 +02:00
Elian Doran
d609ee028e chore(client): get rid of workspace projects from optimizeDeps 2026-01-11 10:55:13 +02:00
Elian Doran
8dc8b046fb chore(client): reintroduce live refresh 2026-01-11 00:55:42 +02:00
Elian Doran
349203e300 chore(client): remove dependency to @preact/preset-vite 2026-01-11 00:35:11 +02:00
Elian Doran
83a8f07998 chore(client): change vite config 2026-01-11 00:33:40 +02:00
Elian Doran
94d4a307cf chore(scripts): remove analyze-perf 2026-01-11 00:21:38 +02:00
Elian Doran
2e35e0a830 chore(client): re-enable source maps 2026-01-11 00:21:32 +02:00
Elian Doran
ecdb819067 chore(scripts): address requested changes 2026-01-11 00:11:13 +02:00
Elian Doran
e2cf0c6e3e chore(client): disable preact preset-vite 2026-01-10 23:27:14 +02:00
Elian Doran
5dd600a291 chore(client): shared config 2026-01-10 23:09:51 +02:00
Elian Doran
df1beb1ffb chore(client): set up LightningCSS 2026-01-10 23:04:04 +02:00
Elian Doran
7773059ac0 chore(client): optimize babel 2026-01-10 22:40:20 +02:00
Elian Doran
a238fc16b2 chore(client): add more optimize deps 2026-01-10 22:26:01 +02:00
Elian Doran
e298f5ea6f chore(client): optimize dependencies more aggressively 2026-01-10 22:12:41 +02:00
Elian Doran
a5512267c1 feat(ckeditor5): lazy-load premium features 2026-01-10 21:54:35 +02:00
Elian Doran
f503c4ca6c feat(ckeditor5-math): use dynamic import to reduce loading time 2026-01-10 21:49:16 +02:00
Elian Doran
c834c01c8e chore(scripts): improve performance analysis script by timing out earlier 2026-01-10 21:48:27 +02:00
Elian Doran
1f72ab9593 chore(scripts): spawn process automatically 2026-01-10 21:20:13 +02:00
Elian Doran
c7d446f4aa chore(scripts): display time in seconds 2026-01-10 21:13:34 +02:00
Elian Doran
fb1530423d chore(scripts): add more categories to analyze performance 2026-01-10 21:12:35 +02:00
Elian Doran
545464efee chore(scripts): add a script to anlayze performance logs 2026-01-10 21:10:56 +02:00
Elian Doran
29d0223fd1 chore(server): address requested changes 2026-01-10 20:45:03 +02:00
Elian Doran
00852277f2 fix(server): some routes not working on prod 2026-01-10 20:43:43 +02:00
Elian Doran
edfe23d88c fix(server): server-side images not served in dev mode 2026-01-10 19:58:05 +02:00
Elian Doran
2b8a7a28d9 Merge remote-tracking branch 'origin/main' into lightweight/bootstrap_ejs 2026-01-10 19:51:05 +02:00
Elian Doran
7f29480237 Revert "refactor(client): get rid of runtime in favor of bootstrap script"
This reverts commit 2e845a9faa.
2026-01-10 19:51:03 +02:00
Elian Doran
61ac482946 Revert "chore(server): remove runtime from login"
This reverts commit 455edbfb5d.
2026-01-10 19:48:14 +02:00
Elian Doran
de6a6cbb07 feat(tree): open notes in new window from tree (#8269) 2026-01-10 19:37:12 +02:00
Elian Doran
2dcb003909 chore(deps): update pnpm to v10.28.0 (#8329) 2026-01-10 19:36:34 +02:00
Elian Doran
d5c934a518 add logseq to supported protocols (#8320) 2026-01-10 19:36:03 +02:00
Elian Doran
779909837c Allow hiding children from tree (especially for collections) (#8335) 2026-01-10 18:32:41 +02:00
Elian Doran
a4cb375a0f test(client): fix broken tests 2026-01-10 18:21:38 +02:00
Elian Doran
e2da8c28ca fix(tree): spotlighted note has + button & insert child context menu 2026-01-10 18:21:16 +02:00
Elian Doran
7808848f05 Translations update from Hosted Weblate (#8339) 2026-01-10 18:02:07 +02:00
Elian Doran
7c05109645 Merge remote-tracking branch 'origin/main' into feature/hide_from_tree 2026-01-10 18:01:05 +02:00
Hosted Weblate
8f9e89b73b 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/
2026-01-10 15:59:25 +00:00
Elian Doran
861a61a4d8 Tree performance improvement (#8274) 2026-01-10 17:59:08 +02:00
Elian Doran
52d4083814 chore(tree): address requested changes 2026-01-10 17:46:45 +02:00
Elian Doran
0272189b22 fix(tree): performance issue due to batch update 2026-01-10 17:32:06 +02:00
Elian Doran
ddba0e823c fix(tree): tree is updated on note content updates 2026-01-10 17:32:02 +02:00
Elian Doran
be81acb9e7 feat(tree): respect motion settings instead of always disabling animation 2026-01-10 16:11:15 +02:00
Elian Doran
3bb97385c9 fix(client): a case where inheritance boolean is not correct 2026-01-10 13:17:44 +02:00
Elian Doran
a72cec0494 chore(client): address a few requested changes 2026-01-10 13:06:13 +02:00
Elian Doran
cb02198c6f docs(user): document hiding the subtree 2026-01-10 12:57:11 +02:00
Elian Doran
298d438230 Merge branch 'feature/tree_performance_improvement' into feature/hide_from_tree 2026-01-10 12:34:44 +02:00
Elian Doran
cb2f7932dd Merge remote-tracking branch 'origin/main' into feature/tree_performance_improvement 2026-01-10 12:34:26 +02:00
Elian Doran
3354bd669f fix(client/tree): toast displayed when doing operations outside of tree 2026-01-10 12:32:55 +02:00
Elian Doran
8ad779be66 fix(client/load_results): component ID not preserved for attributes & branches 2026-01-10 12:26:08 +02:00
Elian Doran
f462034868 fix(client/tree): toast not appearing when inserted via paste 2026-01-10 11:55:49 +02:00
Elian Doran
26c25cd4cd fix(client): edge case not handled when parent note overrides to false 2026-01-10 11:25:00 +02:00
Elian Doran
6398830c2d test(client): attribute toggling 2026-01-10 11:15:21 +02:00
Elian Doran
0b065063f2 refactor(client): use same logic for setting boolean with inheritance 2026-01-10 10:37:19 +02:00
Elian Doran
a3a9de6fdd feat(collections): add setting to hide subtree 2026-01-10 10:34:06 +02:00
Elian Doran
d77d30f29e fix(note_tree): subtree hidden cannot be overridden through inheritance 2026-01-10 10:17:09 +02:00
Elian Doran
5cabc6379d fix(note_tree): not reacting to changes in subtreeHidden 2026-01-10 10:14:15 +02:00
Elian Doran
af537e6a48 feat(tree): add option to hide or show subtree 2026-01-10 10:08:50 +02:00
Elian Doran
faf3797663 feat(tree): disable insert child note if subnotes are hidden 2026-01-10 09:57:09 +02:00
Elian Doran
db57f3ff62 feat(tree): add tooltip when moving into hidden subtree 2026-01-10 09:53:23 +02:00
Elian Doran
0f77caad69 feat(tree): hide items dragged into a subtreeHidden 2026-01-10 09:40:19 +02:00
renovate[bot]
751b91e1b8 chore(deps): update pnpm to v10.28.0 2026-01-10 00:41:10 +00:00
Elian Doran
968a17fbfb fix(tree): alignment of note count badge 2026-01-10 00:55:33 +02:00
Elian Doran
712e87b39f feat(tree): distinguish spotlighted node 2026-01-10 00:52:11 +02:00
Elian Doran
0b40b42315 fix(tree): random exceptions when switching between two spotlighted notes 2026-01-10 00:42:24 +02:00
Elian Doran
62996b1162 feat(tree): remove spotlighted note after switching to another one 2026-01-10 00:38:28 +02:00
Elian Doran
b67ccc6091 feat(tree): basic spotlight support for hidden child 2026-01-10 00:15:59 +02:00
Elian Doran
211d2dcf99 feat(collections): hide children by default for some collection types 2026-01-09 20:06:49 +02:00
Elian Doran
ee52e16a75 feat(tree): add title for subnote count badge 2026-01-09 19:15:57 +02:00
Elian Doran
0c27bd25fa chore(tree): align child count to the right 2026-01-09 17:03:56 +02:00
Elian Doran
b6a6e78d01 feat(tree): hide add button if subtree is hidden 2026-01-09 16:59:55 +02:00
Elian Doran
92e6a29e70 feat(tree): display number of children if subtree is hidden 2026-01-09 16:54:04 +02:00
Elian Doran
acc8cee7cd Merge remote-tracking branch 'origin/feature/tree_performance_improvement' into feature/hide_from_tree 2026-01-09 16:38:56 +02:00
Elian Doran
afefbe154b feat(tree): hide arrow if children are hidden 2026-01-09 16:37:11 +02:00
SngAbc
83fa55b7d9 Merge branch 'main' into feat/tree/new_window 2026-01-09 22:35:30 +08:00
Elian Doran
4f6c10d995 feat(tree): allow hiding child notes via attribute 2026-01-09 16:32:55 +02:00
Elian Doran
ed972d2601 e2e(server): math popup fails on CI 2026-01-09 12:13:39 +02:00
Elian Doran
6b57ee5654 e2e(server): flakiness in tab_bar 2026-01-09 11:54:16 +02:00
contributor
e469af1ca5 add logseq to supported protocols 2026-01-09 11:51:49 +02:00
Elian Doran
6d41f076c2 Merge branch 'main' of https://github.com/TriliumNext/Trilium 2026-01-09 11:25:26 +02:00
Elian Doran
8cff591746 fix(toc): unnecessary <ol> when no children 2026-01-09 11:25:24 +02:00
Elian Doran
b3ccf89094 Translations update from Hosted Weblate (#8315) 2026-01-09 00:06:09 +02:00
Ulices
d31c6b1627 Translated using Weblate (Spanish)
Currently translated at 100.0% (152 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/es/
2026-01-08 23:01:53 +01:00
Yatrik Patel
1481356d1f Translated using Weblate (Hindi)
Currently translated at 36.8% (56 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/hi/
2026-01-08 23:01:52 +01:00
Ulices
a54661fd0a Translated using Weblate (Spanish)
Currently translated at 93.8% (1643 of 1751 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/es/
2026-01-08 23:01:49 +01:00
Elian Doran
ae4a3f10ae fix(toc): equations not rendered in new layout 2026-01-08 21:26:04 +02:00
Elian Doran
fe3160e7a1 e2e(server): adapt tests to new layout directly 2026-01-08 20:32:54 +02:00
Elian Doran
66659d4786 e2e(server): flaky test in PDF 2026-01-08 20:11:21 +02:00
Elian Doran
0b25b09040 feat(ci): check version consistency before releasing 2026-01-08 19:49:29 +02:00
Elian Doran
0d41cc2660 Merge remote-tracking branch 'origin/stable' 2026-01-08 19:42:10 +02:00
Elian Doran
f5e8822718 chore(release): prepare for v0.101.3 2026-01-08 19:38:21 +02:00
Elian Doran
bdc220ec12 Merge remote-tracking branch 'origin/stable' 2026-01-08 18:19:16 +02:00
Elian Doran
3eb68e5271 Stable fixes (#8310) 2026-01-08 18:16:55 +02:00
Elian Doran
521952ebcc test(client): remove debug statements 2026-01-08 18:10:00 +02:00
Elian Doran
034091a696 docs(release): prepare for v0.101.2 2026-01-08 18:08:34 +02:00
Elian Doran
ae881101d8 fix(note_list): archived notes displayed in empty grid card (closes #8184) 2026-01-08 17:23:40 +02:00
Elian Doran
b11a30c49c fix(launcher_bar): crashing if there is a non-launcher note (closes #8218) 2026-01-08 16:55:51 +02:00
Elian Doran
4625efda7f fix(note_list): skip rendering of included notes for performance (closes #8017) 2026-01-08 16:50:27 +02:00
Elian Doran
3c168d750d fix(client): cycle in include causing infinite loop (closes #8294) 2026-01-08 16:44:35 +02:00
Elian Doran
5cc7b259ce fix(client): max content width not preserved (closes #8065) 2026-01-08 15:59:57 +02:00
Elian Doran
f7ae046b20 fix(mermaid): error container not scrollable (closes #8299) 2026-01-08 15:52:19 +02:00
Elian Doran
02f43d6239 fix(mermaid): code not scrollable (closes #8299) 2026-01-08 15:33:16 +02:00
Elian Doran
53e1fa1047 fix(mermaid) diagrams not saving content and SVG attachment (#8220) 2026-01-08 15:22:07 +02:00
Elian Doran
b1dc0e234f fix(popupEditor): fix closing of popupEditor when inserting note link (#8224) 2026-01-08 15:21:23 +02:00
Elian Doran
9d380dd828 fix(sql_console): cannot copy table data (#8268) 2026-01-08 15:20:36 +02:00
Elian Doran
1f77540dbb fix(text): Title is not selected when creating a note via the launcher (#8292) 2026-01-08 15:20:14 +02:00
Elian Doran
455edbfb5d chore(server): remove runtime from login 2026-01-07 23:31:28 +02:00
Elian Doran
7288b66d27 chore(client): address requested changes 2026-01-07 23:04:34 +02:00
Elian Doran
3d72ec80bb refactor(client): get rid of any 2026-01-07 22:01:35 +02:00
Elian Doran
f2a74df511 feat(client): use hashes for assets 2026-01-07 21:49:05 +02:00
Elian Doran
68c6052d10 chore(client): remove useless manual chunk 2026-01-07 21:39:35 +02:00
Elian Doran
c4edb56bd4 fix(server): not starting due to serving of assets 2026-01-07 21:38:44 +02:00
Elian Doran
b6a3fe7cfb chore(client): get rid of translation issue 2026-01-07 21:18:09 +02:00
Elian Doran
7a088c5b7d refactor(client): handle everything in bootstrap 2026-01-07 21:11:38 +02:00
Elian Doran
2e845a9faa refactor(client): get rid of runtime in favor of bootstrap script 2026-01-07 21:08:19 +02:00
Elian Doran
ac3ae0dbbe chore(client): fix type issues 2026-01-07 21:02:27 +02:00
Elian Doran
a3fc13de3a refactor(client): extract bootstrap script into separate file 2026-01-07 21:00:40 +02:00
Elian Doran
ee6cbc710c chore(server): remove font size globs 2026-01-07 20:52:27 +02:00
Elian Doran
18d701525e fix(client): print broken due to lack of query forwarding
; Conflicts:
;	apps/client/src/index.html
2026-01-07 20:52:04 +02:00
Elian Doran
e47c848ec8 chore(server): reintegrate mobile layout 2026-01-07 20:51:33 +02:00
Elian Doran
cd64548299 fix(client): load custom fonts 2026-01-07 20:51:29 +02:00
Elian Doran
8645d053de fix(client): ckeditor theme not loaded properly 2026-01-07 20:51:24 +02:00
Elian Doran
91f2dabed7 Merge remote-tracking branch 'origin/main' into lightweight/bootstrap_ejs
; Conflicts:
;	apps/client/src/widgets/layout/StatusBar.tsx
2026-01-07 20:51:17 +02:00
Elian Doran
716612680d Translations update from Hosted Weblate (#8293) 2026-01-07 19:35:42 +02:00
Michael
3800fb85eb Translated using Weblate (German)
Currently translated at 95.4% (1672 of 1751 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-01-07 18:32:56 +01:00
Rafa Osuna
d807984be4 Translated using Weblate (Spanish)
Currently translated at 92.7% (1624 of 1751 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/es/
2026-01-07 18:32:56 +01:00
Giovi
2c92ae8898 Translated using Weblate (Italian)
Currently translated at 100.0% (1751 of 1751 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/it/
2026-01-07 18:32:55 +01:00
Argann Bonneau
3d8cbc81c4 Translated using Weblate (French)
Currently translated at 94.5% (1656 of 1751 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/fr/
2026-01-07 18:32:54 +01:00
Yatrik Patel
d747c94450 Translated using Weblate (Hindi)
Currently translated at 3.4% (4 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/hi/
2026-01-07 18:32:53 +01:00
pythaac
a627d1f96e Translated using Weblate (Korean)
Currently translated at 76.3% (116 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/ko/
2026-01-07 18:32:53 +01:00
Yatrik Patel
869db5e478 Translated using Weblate (Hindi)
Currently translated at 0.9% (17 of 1751 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/hi/
2026-01-07 18:32:52 +01:00
Yatrik Patel
73e94d385e Translated using Weblate (Hindi)
Currently translated at 5.9% (23 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/hi/
2026-01-07 18:32:51 +01:00
Kim Nøglegaard
8f4ebeb335 Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (152 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/nb_NO/
2026-01-07 18:32:51 +01:00
Yatrik Patel
263ee864be Translated using Weblate (Hindi)
Currently translated at 9.2% (14 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/hi/
2026-01-07 18:32:50 +01:00
Elian Doran
f078732624 fix(text): Title is not selected when creating a note via the launcher (#8292) 2026-01-07 19:32:37 +02:00
SngAbc
fac1f6b16c fix(text): Title is not focused when creating a note via the launcher
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-01-07 10:33:17 +08:00
SiriusXT
a5841c1423 fix(text): Title is not focused when creating a note via the launcher 2026-01-07 10:11:24 +08:00
Elian Doran
aaca18003d Translations update from Hosted Weblate (#8279) 2026-01-06 13:54:24 +02:00
Kim Nøglegaard
5ec521b024 Translated using Weblate (Norwegian Bokmål)
Currently translated at 68.4% (104 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/nb_NO/
2026-01-06 04:01:53 +01:00
Yatrik Patel
b3c0be7559 Translated using Weblate (Hindi)
Currently translated at 3.0% (12 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/hi/
2026-01-06 04:01:51 +01:00
Máté Zsólya
d52b735b99 Translated using Weblate (Hungarian)
Currently translated at 1.9% (34 of 1751 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/hu/
2026-01-06 04:01:49 +01:00
Yatrik Patel
639b1f2863 Translated using Weblate (Hindi)
Currently translated at 5.9% (9 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/hi/
2026-01-06 04:01:47 +01:00
Elian Doran
aff4f7e010 feat(tree): disable animation for performance 2026-01-06 01:34:02 +02:00
Elian Doran
dec4dafba6 feat(tree): avoid async 2026-01-06 01:26:56 +02:00
Elian Doran
d0cdcfc32c refactor(tree): use loop for mini optimisation 2026-01-06 01:21:43 +02:00
Elian Doran
0867b81c7a feat(tree): use template for create child to improve performance 2026-01-06 01:13:31 +02:00
Elian Doran
bde6068f2d refactor(tree): extract enchance title into separate method 2026-01-06 01:07:37 +02:00
Elian Doran
47fd2affa4 feat(tree): use direct DOM manipulation instead of jQuery 2026-01-06 00:59:32 +02:00
perfectra1n
2dd541e1d0 fix(tests): update data_dir tests for new EEXIST graceful handling 2026-01-05 14:34:52 -08:00
Elian Doran
7f2cc885fe Feat(math): Improve legacy math input with MathLive (#7842) 2026-01-06 00:12:38 +02:00
Elian Doran
19a365a370 fix(sql_console): cannot copy table data (#8268) 2026-01-06 00:10:11 +02:00
Elian Doran
9a50da328e chore(deps): update dependency rollup-plugin-webpack-stats to v2.1.9 (#8265) 2026-01-05 23:53:05 +02:00
Elian Doran
181e36a7c1 Merge remote-tracking branch 'origin/main' into Meinzzzz/main
; Conflicts:
;	.gitignore
2026-01-05 23:46:12 +02:00
Elian Doran
178508d245 Merge branch 'main' into fix/sql_select_text 2026-01-05 23:43:29 +02:00
Elian Doran
8157ef5e74 Merge branch 'main' into feat/show-helpful-permission-error-output 2026-01-05 23:43:20 +02:00
Elian Doran
d132d084cf Merge branch 'main' into renovate/rollup-plugin-webpack-stats-2.x 2026-01-05 23:43:06 +02:00
Elian Doran
494b55d685 fix(ckeditor): missing pl locale 2026-01-05 23:39:36 +02:00
perfectra1n
0185dd0d18 feat(ux): implement suggestions from gemini just to make sure 2026-01-05 11:55:14 -08:00
perfectra1n
142ed42d90 feat(ux): show more helpful output when users encounter permissions issues within the data directory 2026-01-05 11:38:18 -08:00
Elian Doran
51513d3779 fix(status_bar): count not refreshing properly after change 2026-01-05 21:03:32 +02:00
SiriusXT
5b95b9875b feat(tree): open notes in new window from tree 2026-01-05 19:27:44 +08:00
Elian Doran
688d197472 chore(client): set up body classes 2026-01-05 11:55:51 +02:00
Elian Doran
b745fb476e chore(client): get icons to load 2026-01-05 11:50:21 +02:00
Elian Doran
047b5a85d2 chore(client): load stylesheets 2026-01-05 11:48:19 +02:00
Elian Doran
370a0c6a05 feat(client): get desktop to start 2026-01-05 11:40:53 +02:00
Elian Doran
0d4558fee1 feat(client): get glob to be populated 2026-01-05 11:37:03 +02:00
Elian Doran
76526e0a96 feat(server): bootstrap route 2026-01-05 11:22:10 +02:00
Elian Doran
70093e0a7d feat(server): render static Vite HTML 2026-01-05 11:07:40 +02:00
SngAbc
458398f2ca Merge branch 'main' into fix/sql_select_text 2026-01-05 13:51:45 +08:00
SngAbc
7a6cc4f51e fix(sql_console): cannot copy table data
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-01-05 12:16:16 +08:00
SiriusXT
f4ccce7de5 fix(sql_console): cannot copy table data 2026-01-05 11:23:50 +08:00
renovate[bot]
f8b5417d6c chore(deps): update dependency rollup-plugin-webpack-stats to v2.1.9 2026-01-05 01:03:52 +00:00
Elian Doran
13ce8cf498 fix(note_list): the note list cannot open the context menu. (#8254) 2026-01-04 23:49:25 +02:00
Elian Doran
6c2afc086c feat(i18n): add Polish 2026-01-04 23:38:51 +02:00
Elian Doran
93d50712a9 chore(scripts): fix typecheck issue 2026-01-04 23:38:51 +02:00
Elian Doran
ed91a44928 feat(scripts): check translation coverage 2026-01-04 23:38:50 +02:00
Elian Doran
cd10e66fbb chore(scripts): build scripts not working properly on Windows 2026-01-04 23:38:50 +02:00
Elian Doran
d6aa126fcc Translations update from Hosted Weblate (#8264) 2026-01-04 22:34:38 +02:00
noobhjy
3308c7bdf4 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (1751 of 1751 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hans/
2026-01-04 20:01:53 +00:00
Francis C.
56341a1a73 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (1751 of 1751 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hant/
2026-01-04 20:01:52 +00:00
green
0857e1a536 Translated using Weblate (Japanese)
Currently translated at 100.0% (1751 of 1751 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ja/
2026-01-04 20:01:50 +00:00
Kim Nøglegaard
5d6b25a29e Translated using Weblate (Norwegian Bokmål)
Currently translated at 57.2% (87 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/nb_NO/
2026-01-04 20:01:49 +00:00
Elian Doran
5bc15a5448 PDFjs v1 final tweaks (#8256) 2026-01-04 21:21:51 +02:00
Elian Doran
51a19d0544 docs(user): add missing slug 2026-01-04 21:11:13 +02:00
Elian Doran
fb4e912ed0 chore(pdfjs): address requested changes 2026-01-04 21:08:39 +02:00
Elian Doran
20c2652013 chore(server): set up environment for starting Nginx proxy with subdir 2026-01-04 20:33:54 +02:00
Elian Doran
971d6ad9e3 chore(pdfjs): use version-based system for cache busting 2026-01-04 20:06:11 +02:00
Elian Doran
757fc7a7fe chore(pdfjs): embed sandbox file 2026-01-04 18:50:40 +02:00
Elian Doran
e4d0a4554a feat(client/note_list): use built-in PDF viewer 2026-01-04 18:40:17 +02:00
Elian Doran
dfab7dbc4b fix(note_list): missing margin in button 2026-01-04 18:39:23 +02:00
Elian Doran
0039f4c155 feat(pdfjs): replace blob instead of creating a new revision every time 2026-01-04 17:25:56 +02:00
Elian Doran
23f7dc63b8 feat(pdfjs): enable editing features only if in main editor 2026-01-04 17:11:16 +02:00
Elian Doran
e485b75a44 fix(pdfjs): saves as soon as document is opened 2026-01-04 17:06:41 +02:00
Elian Doran
dbef57d329 chore(deps): update dependency webdriverio to v9.23.0 (#8258) 2026-01-04 10:36:47 +02:00
SiriusXT
c650441655 Merge branch 'main' into fix/note_list 2026-01-04 10:49:46 +08:00
SiriusXT
e573a8af77 chore(note_grid): remove unused tree import 2026-01-04 10:48:45 +08:00
SiriusXT
b23252d046 fix(note_grid): the note grid cannot open the context menu 2026-01-04 10:25:43 +08:00
renovate[bot]
2f7448dbd4 chore(deps): update dependency webdriverio to v9.23.0 2026-01-04 02:13:34 +00:00
Adorian Doran
9bf4aa2968 readme: update screenshot 2026-01-04 00:28:00 +02:00
Elian Doran
d78a7bad3b feat(import/markdown): handle bash as sh 2026-01-03 23:30:38 +02:00
Elian Doran
b812177e78 docs(user): add spellcheck=false to inline code 2026-01-03 23:28:28 +02:00
Elian Doran
4710a6af41 feat(export/markdown): add spellcheck=false to inline code 2026-01-03 23:19:58 +02:00
Elian Doran
a613980ea4 docs(user): add missing jsx / HTML code blocks 2026-01-03 22:56:23 +02:00
Elian Doran
20ae1f844b feat(markdown): support html, jsx in code blocks 2026-01-03 22:44:48 +02:00
Elian Doran
69511134e5 refactor(client/pdf): handle blob request on client side 2026-01-03 20:54:28 +02:00
Elian Doran
75952563e4 Translations update from Hosted Weblate (#8255) 2026-01-03 20:31:35 +02:00
Elian Doran
21cf5e1df7 chore(client/pdf): use custom spaced update hook 2026-01-03 20:29:54 +02:00
Hosted Weblate
9df5505989 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/
2026-01-03 18:03:22 +00:00
Kim Nøglegaard
1809d59193 Translated using Weblate (Norwegian Bokmål)
Currently translated at 43.4% (66 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/nb_NO/
2026-01-03 18:03:20 +00:00
Francis C.
feaa54d660 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (1745 of 1745 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hant/
2026-01-03 18:03:20 +00:00
noobhjy
c94bd41162 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (1743 of 1745 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hans/
2026-01-03 18:03:19 +00:00
Elian Doran
f1f3e66537 Save indicator (#8249) 2026-01-03 20:03:12 +02:00
Elian Doran
80363cdc73 chore(client/save_indicator): fix some spacing issues 2026-01-03 19:53:46 +02:00
Elian Doran
02e08fdf12 chore(client/save_indicator): address requested changes 2026-01-03 19:47:33 +02:00
Elian Doran
42283b2469 doc(user): mention the save status indicator 2026-01-03 19:40:39 +02:00
Elian Doran
d3b598a5b2 fix(client/save_indicator): not visible on light theme 2026-01-03 19:39:16 +02:00
Elian Doran
0dd3a03c6b chore(client): fix type issue 2026-01-03 19:30:52 +02:00
Elian Doran
2144888447 Merge remote-tracking branch 'origin/main' into feature/save_indicator 2026-01-03 19:24:51 +02:00
Elian Doran
b2549066dc PDF.js refinement (#8247) 2026-01-03 19:24:28 +02:00
Elian Doran
cd1f3aa9a7 chore(client): address self-review 2026-01-03 10:05:44 +02:00
Elian Doran
1674401342 Merge remote-tracking branch 'origin/main' into feature/pdfjs_refinement 2026-01-03 09:57:42 +02:00
Elian Doran
7ba8dbbf6e fix(deps): update dependency mind-elixir to v5.4.0 (#8253) 2026-01-03 09:53:36 +02:00
Elian Doran
ad27d9ed0e chore(deps): update dependency @redocly/cli to v2.14.3 (#8252) 2026-01-03 09:53:03 +02:00
renovate[bot]
482d2f9624 fix(deps): update dependency mind-elixir to v5.4.0 2026-01-03 01:46:19 +00:00
renovate[bot]
824ef704d4 chore(deps): update dependency @redocly/cli to v2.14.3 2026-01-03 01:45:28 +00:00
Adorian Doran
58b73cfc7d Merge branch 'main' of https://github.com/TriliumNext/Trilium 2026-01-03 02:25:07 +02:00
Adorian Doran
0465fea2db style/pdf viewer: improve appearance 2026-01-03 02:24:59 +02:00
Elian Doran
39b75e3561 Translations update from Hosted Weblate (#8248) 2026-01-03 00:10:42 +02:00
Elian Doran
2933db9b16 feat(save_indicator): fade out after a few seconds 2026-01-02 23:53:14 +02:00
Kim Nøglegaard
d94914046b Translated using Weblate (Norwegian Bokmål)
Currently translated at 23.0% (35 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/nb_NO/
2026-01-02 21:51:24 +00:00
Kim Nøglegaard
9cf384b14b Translated using Weblate (Norwegian Bokmål)
Currently translated at 20.3% (31 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/nb_NO/
2026-01-02 21:51:23 +00:00
Kim Nøglegaard
614a2f0ccb Translated using Weblate (Norwegian Bokmål)
Currently translated at 3.2% (5 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/nb_NO/
2026-01-02 21:51:23 +00:00
Yatrik Patel
5cecc72384 Translated using Weblate (Hindi)
Currently translated at 2.8% (11 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/hi/
2026-01-02 21:51:22 +00:00
Yatrik Patel
3ad37fb602 Translated using Weblate (Hindi)
Currently translated at 5.2% (8 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/hi/
2026-01-02 21:51:21 +00:00
noobhjy
42b048c2bf Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (1742 of 1745 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hans/
2026-01-02 21:51:21 +00:00
Kim Nøglegaard
a01bf3dfa1 Translated using Weblate (Norwegian Bokmål)
Currently translated at 2.0% (8 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/nb_NO/
2026-01-02 21:51:20 +00:00
Yatrik Patel
ad60988553 Translated using Weblate (Hindi)
Currently translated at 0.7% (13 of 1745 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/hi/
2026-01-02 21:51:19 +00:00
green
c9ae4e4cc6 Translated using Weblate (Japanese)
Currently translated at 100.0% (1745 of 1745 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ja/
2026-01-02 21:51:18 +00:00
Kim Nøglegaard
d2639851d5 Translated using Weblate (Norwegian Bokmål)
Currently translated at 0.6% (11 of 1745 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/nb_NO/
2026-01-02 21:51:18 +00:00
Hosted Weblate
8dc5f9cfa4 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/
2026-01-02 21:51:17 +00:00
Adorian Doran
d99a408e04 style/pdf viewer: add support for background effects 2026-01-02 23:51:07 +02:00
Elian Doran
5f14861682 feat(save_indicator): indicate errors 2026-01-02 23:22:33 +02:00
Adorian Doran
8f8493f3ec client/note split: allow enabling background effects according to the MIME type 2026-01-02 23:06:08 +02:00
Elian Doran
62af66b5ae feat(save_indicator): report saving and saved states 2026-01-02 22:53:18 +02:00
Elian Doran
e8d1fa7447 chore(save_indicator): basic infrastructure to display state 2026-01-02 22:44:29 +02:00
Adorian Doran
ee03871405 style/pdf viewer: remove irrelevant elements 2026-01-02 22:28:33 +02:00
Elian Doran
345378d97f feat(save_indicator): add tooltip for each of the states 2026-01-02 22:14:58 +02:00
Elian Doran
07a463ee52 feat(save_indicator): improve display of some states 2026-01-02 22:10:41 +02:00
Elian Doran
3157047160 chore(save_indicator): add opacity 2026-01-02 22:00:25 +02:00
Elian Doran
a1dda3b578 chore(save_indicator): prepare icon and title 2026-01-02 21:58:13 +02:00
Elian Doran
e161ffce57 fix(client/pdf): not always focusing on click 2026-01-02 21:20:29 +02:00
Adorian Doran
0c1859dc43 style/note splits: highlight the active split only in a multi-split view 2026-01-02 20:59:51 +02:00
Elian Doran
e4dcc0f768 chore(client): fix typecheck issues 2026-01-02 20:45:28 +02:00
Elian Doran
74ab591214 chore(package): automatically build share theme & PDF viewer 2026-01-02 20:38:18 +02:00
Elian Doran
7bd7996893 feat(revisions): use customized PDF viewer 2026-01-02 20:17:27 +02:00
Elian Doran
505ae4eeb5 chore(revisions): remove "Preview" heading 2026-01-02 20:02:39 +02:00
Elian Doran
951d6d3ce3 feat(revisions): display PDF preview for revisions 2026-01-02 20:02:13 +02:00
Elian Doran
5ff7764699 style(revisions): prevent revision list from overflowing 2026-01-02 19:49:20 +02:00
Elian Doran
0d74998625 style(revisions): prevent buttons from overflowing 2026-01-02 19:47:07 +02:00
Elian Doran
29b70a12bd feat(revisions): display video preview for revisions 2026-01-02 19:44:23 +02:00
Elian Doran
d84150e97b feat(revisions): display audio preview for revisions 2026-01-02 19:21:51 +02:00
Elian Doran
2b2ef4251f style(revisions): minor spacing adjustments to file table 2026-01-02 18:44:06 +02:00
Elian Doran
2840ea0f38 chore(revisions): display a message when a preview is not available 2026-01-02 18:42:05 +02:00
Elian Doran
542d485267 fix(revisions): missing meta information about revisions 2026-01-02 18:34:45 +02:00
Elian Doran
cdd4fbc81d refactor(client): fix lint warnings in revisions modal 2026-01-02 18:23:04 +02:00
Elian Doran
bfdddab0a0 refactor(client): format revisions dialog 2026-01-02 18:20:55 +02:00
Elian Doran
44d1d01105 fix(pdfjs): preferences don't account for ntxId or noteId 2026-01-02 18:08:25 +02:00
Elian Doran
120bb09171 fix(pdfjs): saving doesn't account for ntxId or noteId 2026-01-02 17:57:43 +02:00
Elian Doran
b7af99c671 refactor(pdfjs): add type safety for messages 2026-01-02 17:57:28 +02:00
Elian Doran
869e0b3973 docs(user): mention updates to the new PDF functions 2026-01-02 12:49:30 +02:00
Elian Doran
b68613dee4 feat(share): integrate custom pdf.js viewer 2026-01-02 12:13:31 +02:00
Elian Doran
ce0f32e7d5 chore(client/pdfjs): remove open file 2026-01-02 11:44:33 +02:00
Elian Doran
78bc9b59c2 chore(client/pdfjs): remove download button from toolbar 2026-01-02 11:41:58 +02:00
Elian Doran
23cf3d2923 feat(client/pdfjs): rewrite download button 2026-01-02 11:40:32 +02:00
Elian Doran
335136f3a3 fix(deps): update dependency preact-render-to-string to v6.6.5 (#8240) 2026-01-02 11:13:42 +02:00
renovate[bot]
11dd7aef09 fix(deps): update dependency preact-render-to-string to v6.6.5 2026-01-02 09:09:55 +00:00
Elian Doran
2d1769e2f9 fix: toggling right pane visibility incorrectly affects all windows (#8226) 2026-01-02 11:08:27 +02:00
Elian Doran
21e26147b0 fix(deps): update dependency react-i18next to v16.5.1 (#8241) 2026-01-02 11:06:38 +02:00
Elian Doran
ba301f8c12 fix(deps): update dependency globals to v17 (#8242) 2026-01-02 11:06:13 +02:00
SiriusXT
3420374649 fix: toggling right pane visibility incorrectly affects all windows 2026-01-02 11:31:59 +08:00
SiriusXT
644d3a181f fix: toggling right pane visibility incorrectly affects all windows 2026-01-02 11:08:49 +08:00
SiriusXT
4be3011a8a fix: toggling right pane visibility incorrectly affects all windows 2026-01-02 10:30:15 +08:00
SiriusXT
5aa0a956dd fix: toggling right pane visibility incorrectly affects all windows 2026-01-02 10:25:34 +08:00
renovate[bot]
7fdb1bdce8 fix(deps): update dependency globals to v17 2026-01-02 01:53:43 +00:00
renovate[bot]
57c6cef2bd fix(deps): update dependency react-i18next to v16.5.1 2026-01-02 01:52:49 +00:00
Elian Doran
e5599adca1 feat(share): Add support for shareJs in static website export (#8173) 2026-01-02 00:39:36 +02:00
Elian Doran
ab392ffb7f Translations update from Hosted Weblate (#8239) 2026-01-02 00:38:23 +02:00
Hosted Weblate
7585d4b258 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/
2026-01-01 22:37:01 +00:00
Elian Doran
ff82d9c38c Clean up Vite (#8238) 2026-01-02 00:36:46 +02:00
Elian Doran
920fde69bb chore: add missing space from imports 2026-01-02 00:21:50 +02:00
Elian Doran
053812e5f0 e2e(server): wrong import 2026-01-02 00:14:07 +02:00
Elian Doran
c2f59c4b6c test(server): type error 2026-01-02 00:07:04 +02:00
Elian Doran
06980fe9b5 chore(tsconfig): fix empty type 2026-01-02 00:04:52 +02:00
Elian Doran
3f5616f1fc chore(vitest): fix node:test import 2026-01-02 00:03:45 +02:00
Elian Doran
b6af3b70b0 test(client): increase a timeout for local run 2026-01-01 23:57:43 +02:00
Elian Doran
d8e4547988 chore(vitest): get rid of warning about number of projects 2026-01-01 23:56:26 +02:00
Elian Doran
34f649155e chore(vite): remove vite/global for other projects 2026-01-01 23:44:17 +02:00
Elian Doran
11779fe3e3 chore(vite): remove vite/global for commons 2026-01-01 23:43:59 +02:00
Elian Doran
032cde67b0 chore(vite): remove vite/global for express-partial-content 2026-01-01 23:42:02 +02:00
Elian Doran
229636a796 chore(vite): remove vite/global for server 2026-01-01 23:39:53 +02:00
Elian Doran
da9c9ac346 chore(vite): remove vite/importMeta from spec types 2026-01-01 23:34:39 +02:00
Elian Doran
3fecc4c648 chore(vite): remove vite/client from spec types 2026-01-01 23:33:21 +02:00
Elian Doran
98cefcf77b fix(desktop/pdfjs): not working due to build script 2026-01-01 23:13:21 +02:00
Elian Doran
413ee81ffa Translations update from Hosted Weblate (#8234) 2026-01-01 22:51:03 +02:00
Yatrik Patel
578ca8785e Translated using Weblate (Hindi)
Currently translated at 0.5% (10 of 1740 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/hi/
2026-01-01 20:49:31 +00:00
Yatrik Patel
da4112c078 Translated using Weblate (Hindi)
Currently translated at 2.0% (8 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/hi/
2026-01-01 20:49:30 +00:00
Yatrik Patel
704c7c881d Translated using Weblate (Hindi)
Currently translated at 4.6% (7 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/hi/
2026-01-01 20:49:29 +00:00
Elian Doran
63b6abdb9d PDF.js sidebar experiments for new layout (#8212) 2026-01-01 22:49:15 +02:00
Elian Doran
2e936a3d5c test(pdfjs): disable for now as there are no tests 2026-01-01 22:31:49 +02:00
Elian Doran
606574e18e chore(pdjs): address self-review 2026-01-01 22:15:40 +02:00
Elian Doran
1021879167 chore(client/pdfjs): add some missing translations 2026-01-01 22:15:31 +02:00
Elian Doran
dc4aa9c607 feat(ui): implement tooltips for share icons and clone icons (#8211) 2026-01-01 21:13:01 +02:00
Elian Doran
b2c3d78773 Fix excessive noteContext calls (#8233) 2026-01-01 21:09:39 +02:00
Elian Doran
8d3a0b5295 test(pdfjs): replace beforeAll with beforeEach 2026-01-01 21:06:03 +02:00
lzinga
9879d07bec fix(widget): remove redundant note context update in useLegacyWidget 2026-01-01 11:05:30 -08:00
Elian Doran
7bfce851e7 fix(mermaid) diagrams not saving content and SVG attachment (#8220) 2026-01-01 20:58:56 +02:00
Elian Doran
34e81881ec fix(popupEditor): fix closing of popupEditor when inserting note link (#8224) 2026-01-01 20:56:04 +02:00
Lucas
0143d6c60d Merge branch 'TriliumNext:main' into fix/layout-calls 2026-01-01 10:55:25 -08:00
Elian Doran
267c2bc907 Translations update from Hosted Weblate (#8231) 2026-01-01 19:25:36 +02:00
Yatrik Patel
316f27d88c Translated using Weblate (Hindi)
Currently translated at 0.1% (2 of 1736 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/hi/
2026-01-01 17:39:40 +01:00
Yatrik Patel
452b56f470 Translated using Weblate (Hindi)
Currently translated at 2.6% (4 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/hi/
2026-01-01 17:39:40 +01:00
Jan Klass
43aeaa4455 Translated using Weblate (German)
Currently translated at 96.1% (1669 of 1736 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2026-01-01 17:39:40 +01:00
Yatrik Patel
08b7a6985e Translated using Weblate (Hindi)
Currently translated at 1.0% (4 of 389 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/hi/
2026-01-01 17:39:40 +01:00
dirlligafu
4bbd8e28c1 Translated using Weblate (French)
Currently translated at 95.3% (1656 of 1736 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/fr/
2026-01-01 17:39:40 +01:00
Yatrik Patel
fcf4c09389 Translated using Weblate (Hindi)
Currently translated at 1.7% (2 of 116 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/hi/
2026-01-01 17:39:40 +01:00
Elian Doran
2c323cbe80 fix(client): color with uppercase causing exception (closes #8232) 2026-01-01 18:39:31 +02:00
Elian Doran
7ec7b6bd7b chore(pdfjs): manage requested changes 2026-01-01 12:36:33 +02:00
Elian Doran
b2378f2a53 test(server/pdf): move beforeAll 2026-01-01 12:19:51 +02:00
Elian Doran
8bf8d85bb7 test(server/pdf): switching to another note 2026-01-01 11:23:24 +02:00
Elian Doran
676173e895 test(server/pdf): layer listing works 2026-01-01 11:06:29 +02:00
Elian Doran
d8649c87e0 test(server/pdf): attachment listing works 2026-01-01 01:06:26 +02:00
Elian Doran
b9456ca466 test(server/pdf): basic page navigation test 2026-01-01 00:35:39 +02:00
Elian Doran
cfccbb8927 test(server/pdf): basic table of contents test 2025-12-31 23:40:32 +02:00
Elian Doran
a18578362a Merge remote-tracking branch 'origin/main' into feature/pdfjs_sidebar_experiments 2025-12-31 22:55:37 +02:00
Elian Doran
2f9f94dee0 fix(server): pdfjs not available in dist 2025-12-31 22:46:55 +02:00
Elian Doran
c84e45ddee test(pdfjs): set up basic vitest 2025-12-31 21:18:27 +02:00
Lucas
ea558d8c9d Merge branch 'TriliumNext:main' into fix/layout-calls 2025-12-31 07:33:11 -08:00
lzinga
b936a35b63 fix(widget): prevent unnecessary refresh by checking note context change 2025-12-31 07:31:22 -08:00
Elian Doran
b4ef4c2143 chore(pdfjs): fix code scanning issues 2025-12-31 17:27:58 +02:00
Elian Doran
0ff4756ef4 chore(pdfjs): fix typecheck issues 2025-12-31 17:00:56 +02:00
Elian Doran
94204b4739 style(pdf_pages): slight improvement to page layout 2025-12-31 16:45:11 +02:00
Elian Doran
bf3a2b768e chore(pdfjs): set proper target origin when posting messages 2025-12-31 16:37:51 +02:00
SiriusXT
5fb7badfb4 fix(rightPane): toggling right pane visibility incorrectly affects all windows 2025-12-31 19:54:31 +08:00
Elian Doran
239d56f9a3 fix(deps): update dependency @codemirror/view to v6.39.8 (#8222) 2025-12-31 10:38:22 +02:00
Elian Doran
9163fc23f4 chore(deps): update dependency @redocly/cli to v2.14.2 (#8221) 2025-12-31 10:37:30 +02:00
Elian Doran
d225c28fde chore(deps): update pnpm to v10.27.0 (#8223) 2025-12-31 10:29:28 +02:00
SiriusXT
8a3f02e845 fix(popupEditor): fix closing of popupEditor when inserting note link 2025-12-31 14:12:38 +08:00
renovate[bot]
d0dc92c891 chore(deps): update pnpm to v10.27.0 2025-12-31 02:34:03 +00:00
renovate[bot]
8d660f5a2f fix(deps): update dependency @codemirror/view to v6.39.8 2025-12-31 02:33:52 +00:00
renovate[bot]
b41b4e77b2 chore(deps): update dependency @redocly/cli to v2.14.2 2025-12-31 02:33:14 +00:00
lzinga
267a37d3bd feat(component): add removeChild method for cleanup of child components
feat(hooks): improve useLegacyWidget cleanup and memoization logic
2025-12-30 13:59:46 -08:00
Lucas
0cf23c7d7c Update apps/client/src/widgets/type_widgets/helpers/SvgSplitEditor.tsx
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-12-30 11:56:34 -08:00
lzinga
a632486229 fix(mermaid) diagrams not saving content and SVG attachment 2025-12-30 11:35:48 -08:00
Elian Doran
64a518a00b chore(deps): update typescript-eslint monorepo to v8.51.0 (#8214) 2025-12-30 12:07:14 +02:00
Elian Doran
2f3a914027 Translations update from Hosted Weblate (#8213) 2025-12-30 12:06:27 +02:00
Elian Doran
7182d32d9c Merge remote-tracking branch 'origin/main' into feature/pdfjs_sidebar_experiments 2025-12-30 11:47:00 +02:00
green
18381c5d32 Translated using Weblate (Japanese)
Currently translated at 100.0% (1736 of 1736 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ja/
2025-12-30 09:00:07 +01:00
Kuzma Simonov
79327073b4 Translated using Weblate (Russian)
Currently translated at 100.0% (1736 of 1736 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ru/
2025-12-30 09:00:06 +01:00
Giovi
018f2fd789 Translated using Weblate (Italian)
Currently translated at 100.0% (1736 of 1736 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/it/
2025-12-30 09:00:06 +01:00
noobhjy
3889392aed Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (1736 of 1736 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hans/
2025-12-30 09:00:05 +01:00
Elian Doran
bd976a25f1 style(next): use border for focus instead 2025-12-30 09:59:46 +02:00
Elian Doran
01f05ac6fd fix(pdf): active context not changed when clicking preview 2025-12-30 09:47:02 +02:00
Elian Doran
52292cb5a5 style(next): indicate active note context 2025-12-30 09:31:03 +02:00
perfectra1n
c6dd1ba0ca fix(types): resolve typecheck issue with note_tree 2025-12-29 18:25:55 -08:00
renovate[bot]
84f069087c chore(deps): update typescript-eslint monorepo to v8.51.0 2025-12-30 01:05:53 +00:00
Elian Doran
76cfced60f chore(pdfjs): fix partially removed method 2025-12-30 01:43:07 +02:00
Elian Doran
5c2aea0a6b chore: remove LLM generated doc 2025-12-30 01:40:34 +02:00
Elian Doran
7a883c62df Merge remote-tracking branch 'origin/main' into feature/pdfjs_sidebar_experiments 2025-12-30 01:40:03 +02:00
Elian Doran
ff97461ff8 PDF.js integration (part I) (#8206) 2025-12-30 01:39:09 +02:00
Elian Doran
51b0eb74a5 chore(pdfjs): address requested changes 2025-12-30 01:37:44 +02:00
Elian Doran
2304407986 chore(pdfjs): address origin concerns 2025-12-30 01:27:05 +02:00
Elian Doran
a1ebdc3004 chore(pdfjs): integrate into typecheck 2025-12-30 01:23:19 +02:00
Elian Doran
fef30f4bea chore(client): fix typecheck 2025-12-30 01:20:29 +02:00
Elian Doran
eee8d9ab7c feat(pdfjs): optionally hide left sidebar 2025-12-30 01:09:45 +02:00
perfectra1n
4f2678d321 feat(ui): implement tooltips for share icons and clone icons
asdf
2025-12-29 14:42:34 -08:00
Elian Doran
c473fba628 refactor(right_pane): move PDF-specific components in own dir 2025-12-30 00:17:29 +02:00
Elian Doran
9a9cd8e6a5 feat(right_pane): add count in title for PDF items 2025-12-30 00:16:45 +02:00
Elian Doran
f5a89aa81a feat(right_pane): hide PDF attachments/layers when not needed 2025-12-30 00:10:23 +02:00
Elian Doran
3c1beab725 fix(pdf_pages): fix a few type errors 2025-12-30 00:00:03 +02:00
Elian Doran
79f03ad3ac fix(pdf_layers): toggling layers and updating state not working 2025-12-29 23:57:52 +02:00
Elian Doran
574138a1fb refactor(pdf_layers): get layers to show 2025-12-29 23:08:35 +02:00
Elian Doran
6513e2cfca refactor(pdf_attachments): deduplicate font size 2025-12-29 23:04:02 +02:00
Elian Doran
43a749b6a7 feat(right_pane): display attachments 2025-12-29 22:56:06 +02:00
Elian Doran
c1d6b3121a fix(pdf_pages): pages not updating between notes 2025-12-29 22:50:48 +02:00
Elian Doran
0d9c8ae4df style(pdf_pages): page numbers within pages 2025-12-29 22:46:20 +02:00
Elian Doran
62d8c089ed chore(pdf_pages): remove logs 2025-12-29 22:43:17 +02:00
Elian Doran
971a76ce11 style(pdf_pages): render in multiple columns 2025-12-29 22:39:38 +02:00
Elian Doran
cb33404122 feat(client/right_pane): use intersection observer for performance 2025-12-29 22:36:03 +02:00
Elian Doran
bcf72f4624 feat(client/right_pane): display pages 2025-12-29 22:34:36 +02:00
Elian Doran
77ad6950e8 feat(client/right_pane): highlight current heading 2025-12-29 22:11:25 +02:00
Elian Doran
e2d29aadca refactor(pdfjs): extract toc logic to separate file 2025-12-29 21:58:11 +02:00
Elian Doran
64ca04ad07 feat(client/right_pane): jump to heading 2025-12-29 21:55:47 +02:00
Elian Doran
b6506a9331 chore(client/right_pane): get table of contents to show 2025-12-29 21:49:02 +02:00
Elian Doran
fd7222242a chore(pdf): process PDF outline 2025-12-29 21:44:49 +02:00
Elian Doran
e36049cd43 chore(client/right_pane): get raw ToC data to show up 2025-12-29 21:44:15 +02:00
Elian Doran
257f6c5994 chore(client/right_pane): inject title into PDF toc sidebar 2025-12-29 21:28:17 +02:00
Elian Doran
9098bfb63a chore(client): prototype implementation to communicate data through note context 2025-12-29 21:26:52 +02:00
Wael Nasreddine
118d22c4ec Merge branch 'main' into static-implement-sharejs 2025-12-29 11:02:07 -08:00
Elian Doran
758df0d85a fix(share): Prevent crashing if candidate note is null (#8164) 2025-12-29 20:43:12 +02:00
Elian Doran
59bbd902fc feat(share): Render JS Frontend files as-is with extension .js (#8172) 2025-12-29 20:41:46 +02:00
Elian Doran
fffab73061 feat(pdfjs): auto-watch dev 2025-12-29 19:23:56 +02:00
Elian Doran
0a9ce84cf2 feat(client/pdf): respect locale 2025-12-29 19:10:14 +02:00
Elian Doran
07a1734d4b chore(pdfjs): copy locales during build 2025-12-29 19:09:03 +02:00
Elian Doran
6e41d3591d chore(pdfjs): add locales 2025-12-29 19:06:08 +02:00
Elian Doran
4134e5054a fix(client/pdf): not refreshing when uploading new revision 2025-12-29 17:02:22 +02:00
Elian Doran
bb374a5ce2 fix(client/pdf): blob reloaded when saving 2025-12-29 16:46:30 +02:00
Elian Doran
359f398afa feat(pdfjs): debounce saving view config 2025-12-29 16:19:21 +02:00
Elian Doran
84425e86e9 feat(client/pdf): filter out view config by fingerprint 2025-12-29 16:15:38 +02:00
Elian Doran
ebf725c949 feat(client/pdf): store and restore page position 2025-12-29 15:55:47 +02:00
Elian Doran
fc0ea36cf3 chore(pdfjs): first attempt at intercepting store 2025-12-29 14:06:59 +02:00
Elian Doran
7836de3f08 fix(client/pdf): form elements not detected for save 2025-12-29 13:29:04 +02:00
Elian Doran
406232c478 chore(pdfjs): log event bus 2025-12-29 13:23:54 +02:00
Elian Doran
9e0c29496f refactor(pdfjs): use TypeScript for the custom script 2025-12-29 13:14:00 +02:00
Elian Doran
480954ee87 feat(pdfjs): react to dark mode 2025-12-29 12:51:43 +02:00
Elian Doran
94039bd9b1 chore(pdfjs): improve toolbar contrast 2025-12-29 12:40:43 +02:00
Elian Doran
667eaca9f2 feat(pdfjs): improve style to better match Trilium 2025-12-29 12:35:49 +02:00
Elian Doran
446822a7ae chore(client/pdf): inject some CSS variables 2025-12-29 12:21:44 +02:00
Elian Doran
f09a3e06f4 refactor(client/pdf): split into own component 2025-12-29 12:01:47 +02:00
Elian Doran
7c4a56f5f2 chore(deps): add missing pdfjs dependency 2025-12-29 11:10:12 +02:00
Elian Doran
08f6a32c34 fix(client/pdfjs): not reacting to all changes 2025-12-29 10:33:57 +02:00
Elian Doran
3e255fa647 feat(client/pdf): add debouncing 2025-12-29 10:15:15 +02:00
Elian Doran
c0a90402ef feat(client/pdf): save annotations by uploading new revision 2025-12-29 09:51:54 +02:00
Elian Doran
5e42627bce chore(client/pdf): basic reaction to annotations 2025-12-29 02:00:59 +02:00
Elian Doran
41bcf9524a feat(client/pdf): integrate pdf.js 2025-12-29 01:16:56 +02:00
Elian Doran
914cf10911 chore(pdfjs): get icons to show up 2025-12-29 01:11:04 +02:00
Elian Doran
855d4d139d chore(pdfjs): get to actually render something 2025-12-29 01:03:16 +02:00
Elian Doran
abb7b0f8c8 feat(server): serve pdfjs over static route 2025-12-29 00:50:59 +02:00
Elian Doran
d78ad52662 chore(pdfjs): copy viewer to dist 2025-12-29 00:45:57 +02:00
Elian Doran
25b4bcd311 chore(pdfjs): create empty package 2025-12-29 00:26:37 +02:00
Wael Nasreddine
1d3e971ed7 Merge branch 'static-correct-type' into static-implement-sharejs
* static-correct-type:
  improve the protected note handling
  be loosy and honor startsWith application/javascript
2025-12-25 23:01:30 -08:00
Wael Nasreddine
3d1f6c4f91 be loosy and honor startsWith application/javascript 2025-12-25 22:54:14 -08:00
Wael Nasreddine
8368969932 implement the second part of the sharejs 2025-12-25 22:06:30 -08:00
Wael Nasreddine
cb016c4307 Address Gemini's comment 2025-12-25 16:26:58 -08:00
Wael Nasreddine
7c7797d35a fix(share/prev_next): Prevent crashing if candide page is null
When a note is not visible, attempting to export it ends up crashing the
server with this error:

```
TypeError: ejs:193
    191|
    192|                 <% if (hasTree) { %>
 >> 193|                     <%- include("prev_next", { note: note, subRoot: subRoot }) %>
    194|                 <% } %>
    195|             </footer>
    196|         </div>
ejs:1
 >> 1| <%
    2|     // TODO: code cleanup + putting this behind a toggle/attribute
    3|     const previousNote = (() => {
    4|         // If we are at the subRoot, there is no previous
Cannot read properties of undefined (reading 'hasVisibleChildren')
    at eval (eval at compile (/usr/src/app/main.cjs:553:203), <anonymous>:27:26)
    at eval (eval at compile (/usr/src/app/main.cjs:553:203), <anonymous>:34:7)
    at d (/usr/src/app/main.cjs:557:265)
    at g (/usr/src/app/main.cjs:557:251)
    at eval (eval at compile (/usr/src/app/main.cjs:553:203), <anonymous>:293:17)
    at d (/usr/src/app/main.cjs:557:265)
    at as.render (/usr/src/app/main.cjs:532:458)
    at Omr (/usr/src/app/main.cjs:581:109552)
    at Rmr (/usr/src/app/main.cjs:581:107637)
    at $W.prepareContent (/usr/src/app/main.cjs:653:28) {
  path: ''
```

fixes #8002
fixes #8162
2025-12-25 16:11:01 -08:00
meinzzzz
87ab41c80c Fix shift+tab behavior in MathInputView 2025-12-23 18:02:40 +01:00
Meinzzzz
d2391f94c0 Fix offline math rendering by bundling local fonts 2025-12-15 21:32:50 +01:00
Meinzzzz
050ddb8c55 Improve css to fix tooltips 2025-12-15 20:17:58 +01:00
Meinzzzz
bc23e0984a Undo unnecessary formatting changes 2025-12-14 22:00:56 +01:00
Meinzzzz
07de353207 Adding comments and improving code quality in math input views 2025-12-14 20:21:42 +01:00
Meinzzzz
c02491d2e6 Remove unnecessary any casts in math plugin 2025-12-12 23:09:20 +01:00
Meinzzzz
a6ede8f905 Improve mathinputview 2025-12-12 21:33:59 +01:00
Meinzzzz
22941a9ce0 Fix sync issues 2025-12-12 19:48:09 +01:00
Meinzzzz
633a09d414 Fix sync bug 2025-12-11 23:06:13 +01:00
Meinzzzz
29f0881c5a Fix clicking issue in Mathfield 2025-12-10 22:44:02 +01:00
Meinzzzz
60debca37b Improve comments 2025-12-10 18:36:34 +01:00
Meinzzzz
30ea81d0fb Improve virtual keyboard logic and fix Tab issues 2025-12-08 22:59:08 +01:00
Meinzzzz
b1d92c4fe6 Fix Tab issues 2025-12-08 22:39:12 +01:00
Meinzzzz
70f46de2d8 MathLive virtual keyboard only appears when focusing the mathfield 2025-12-08 20:30:07 +01:00
Meinzzzz
f1b2d0b870 Increas Mathfield font size and ensure virtual keyboard appears above CKEditor 2025-12-08 20:22:52 +01:00
Meinzzzz
8a385972fc Close Virtual Keyboard when Mathinput is closed 2025-12-08 18:49:06 +01:00
Meinzzzz
28dd85c1d1 Merge upstream changes and resolve conflicts 2025-12-07 23:51:41 +01:00
meinzzzz
827c8e0e72 Refactor: Combine MathLive and LaTeX inputs into one single component 2025-12-07 23:19:48 +01:00
meinzzzz
162c076a14 Improve MathLive integration and lazy loading 2025-12-02 22:30:37 +01:00
meinzzzz
9386465de7 Added mathrender error class for better error handling in math rendering 2025-12-02 22:29:20 +01:00
meinzzzz
acca22f3a1 Improve Synchronization Between Mathlive and rawlatex input 2025-12-02 22:28:16 +01:00
Romain DEP.
a1c0314334 chore(sorting): add test cases for previous commit and increase test coverage 2025-11-28 23:28:14 +01:00
Romain DEP.
3ecdcd9ea0 fix(sorting): BC! give precedence to #top notes over #sortFolderFirst 2025-11-28 23:22:20 +01:00
meinzzzz
f8d84814e0 Fix differential d problems 2025-11-26 23:02:34 +01:00
meinzzzz
c46cf41842 Small improvements 2025-11-26 22:48:57 +01:00
meinzzzz
64ab1c4116 Imrovement for Latex 2025-11-26 22:29:29 +01:00
meinzzzz
a6de1041c7 Fix bug in math rendering where old content was not cleared 2025-11-26 21:59:33 +01:00
meinzzzz
c8d34e65ea Improve max window size 2025-11-26 21:49:09 +01:00
meinzzzz
51db729546 Improve and simplify Mathfield integration 2025-11-25 23:27:06 +01:00
meinzzzz
d2052ad236 Disable mathlive sound effects 2025-11-24 21:51:59 +01:00
meinzzzz
9c4301467f Remove unused icons from ckeditor5-math package 2025-11-24 19:46:04 +01:00
meinzzzz
e7355dc0e4 remove gitignore unneccesary changes 2025-11-24 18:43:52 +01:00
meinzzzz
4110fec94f Removed unnecessary declare keyboard 2025-11-24 18:28:59 +01:00
meinzzzz
d5e601eae9 Simpliyfied resize logic for math input form and improved css 2025-11-24 17:56:18 +01:00
meinzzzz
4f044c4a57 Use icons form CKEditor5 icons, instead of testing icons. 2025-11-23 22:43:07 +01:00
meinzzzz
5821c350e1 Fixing class property initialization order 2025-11-23 17:58:51 +01:00
meinzzzz
edba8188fe Fix dark selection colors in MathLive math-field 2025-11-23 13:44:28 +01:00
meinzzzz
1471a72633 refactor: avoid recursive updates in mathLiveInput by normalizing value before updateing 2025-11-23 13:34:22 +01:00
meinzzzz
56834cb88a Improve MathLive and Raw LaTeX input views to propagate mousedown events 2025-11-23 13:29:26 +01:00
meinzzzz
a0f16f9184 Fix typos in mathform.css 2025-11-23 13:09:56 +01:00
meinzzzz
de80eb4806 Improve mathform.css styling for better visual integration 2025-11-22 22:42:34 +01:00
meinzzzz
48a4b81fbe remove automated screenshot files 2025-11-22 21:40:55 +01:00
meinzzzz
e225794f72 Better window focus handling in MathFormView 2025-11-22 21:35:37 +01:00
meinzzzz
4eef30f8b5 Fix names 2025-11-22 00:20:20 +01:00
meinzzzz
569b09609d Remove mathlive dependency and chunking 2025-11-22 00:01:14 +01:00
meinzzzz
39838c25c2 Fixed chaching problems 2025-11-21 23:50:49 +01:00
meinzzzz
49e90c08a9 Better Names for Math UI Components 2025-11-20 22:45:21 +01:00
meinzzzz
e777b06fb8 Math 2025-11-20 18:53:39 +01:00
meinzzzz
497ec2ac74 Merge branch 'main' of https://github.com/Meinzzzz/Trilium-Mathlive 2025-11-20 18:00:18 +01:00
meinzzzz
c5d282d203 Mathlive 2025-11-20 00:09:10 +01:00
1065 changed files with 142952 additions and 89939 deletions

View File

@@ -12,7 +12,7 @@ jobs:
steps:
- name: Check if PRs have conflicts
uses: eps1lon/actions-label-merge-conflict@v3
if: github.repository == ${{ vars.REPO_MAIN }}
if: ${{ github.repository == vars.REPO_MAIN }}
with:
dirtyLabel: "merge-conflicts"
repoToken: "${{ secrets.MERGE_CONFLICT_LABEL_PAT }}"

View File

@@ -67,7 +67,7 @@ jobs:
- name: Deploy
uses: ./.github/actions/deploy-to-cloudflare-pages
if: github.repository == ${{ vars.REPO_MAIN }}
if: ${{ github.repository == vars.REPO_MAIN }}
with:
project_name: "trilium-docs"
comment_body: "📚 Documentation preview is ready"

30
.github/workflows/i18n.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Internationalization
on:
push:
branches:
- "weblate:*"
workflow_dispatch:
pull_request:
paths:
- "apps/client/src/translations/**"
- ".github/workflows/i18n.yml"
permissions:
contents: read
jobs:
i18n-check:
name: Check i18n translations
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v4
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
node-version: 24
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Check translations
run: pnpm tsx scripts/translation/check-translation-coverage.ts

View File

@@ -26,7 +26,7 @@ permissions:
jobs:
nightly-electron:
if: github.repository == ${{ vars.REPO_MAIN }}
if: ${{ github.repository == vars.REPO_MAIN }}
name: Deploy nightly
strategy:
fail-fast: false
@@ -109,7 +109,7 @@ jobs:
path: apps/desktop/upload
nightly-server:
if: github.repository == ${{ vars.REPO_MAIN }}
if: ${{ github.repository == vars.REPO_MAIN }}
name: Deploy server nightly
strategy:
fail-fast: false

View File

@@ -11,6 +11,14 @@ concurrency:
cancel-in-progress: true
jobs:
sanity-check:
name: Sanity Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Check version consistency
run: pnpm tsx ${{ github.workspace }}/scripts/check-version-consistency.ts ${{ github.ref_name }}
make-electron:
name: Make Electron
strategy:

69
.github/workflows/web-clipper.yml vendored Normal file
View File

@@ -0,0 +1,69 @@
name: Deploy web clipper extension
on:
push:
branches:
- main
paths:
- "apps/web-clipper/**"
tags:
- "web-clipper-v*"
pull_request:
paths:
- "apps/web-clipper/**"
permissions:
contents: write
discussions: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
name: Build web clipper extension
permissions:
contents: read
deployments: write
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v4
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
node-version: 24
cache: "pnpm"
- name: Install dependencies
run: pnpm install --filter web-clipper --frozen-lockfile --ignore-scripts
- name: Build the web clipper extension
run: |
pnpm --filter web-clipper zip
pnpm --filter web-clipper zip:firefox
- name: Upload build artifacts
uses: actions/upload-artifact@v6
if: ${{ !startsWith(github.ref, 'refs/tags/web-clipper-v') }}
with:
name: web-clipper-extension
path: apps/web-clipper/.output/*.zip
include-hidden-files: true
if-no-files-found: error
compression-level: 0
- name: Release web clipper extension
uses: softprops/action-gh-release@v2.5.0
if: ${{ startsWith(github.ref, 'refs/tags/web-clipper-v') }}
with:
draft: false
fail_on_unmatched_files: true
files: apps/web-clipper/.output/*.zip
discussion_category_name: Releases
make_latest: false
token: ${{ secrets.RELEASE_PAT }}

View File

@@ -34,7 +34,7 @@ jobs:
cache: "pnpm"
- name: Install dependencies
run: pnpm install --filter website --frozen-lockfile
run: pnpm install --filter website --frozen-lockfile --ignore-scripts
- name: Build the website
run: pnpm website:build

1
.gitignore vendored
View File

@@ -51,3 +51,4 @@ upload
# docs
site/
apps/*/coverage
scripts/translation/.language*.json

2
.nvmrc
View File

@@ -1 +1 @@
24.12.0
24.13.0

View File

@@ -42,5 +42,8 @@
},
"eslint.rules.customizations": [
{ "rule": "*", "severity": "warn" }
],
"cSpell.words": [
"Trilium"
]
}
}

View File

@@ -165,6 +165,17 @@ pnpm install
pnpm edit-docs:edit-docs
```
Alternatively, if you have Nix installed:
```shell
# Run directly
nix run .#edit-docs
# Or install to your profile
nix profile install .#edit-docs
trilium-edit-docs
```
### Building the Executable
Download the repository, install dependencies using `pnpm` and then build the desktop app for Windows:
```shell

View File

@@ -9,14 +9,14 @@
"keywords": [],
"author": "Elian Doran <contact@eliandoran.me>",
"license": "AGPL-3.0-only",
"packageManager": "pnpm@10.26.2",
"packageManager": "pnpm@10.28.2",
"devDependencies": {
"@redocly/cli": "2.14.1",
"@redocly/cli": "2.15.1",
"archiver": "7.0.1",
"fs-extra": "11.3.3",
"react": "19.2.3",
"react-dom": "19.2.3",
"typedoc": "0.28.15",
"react": "19.2.4",
"react-dom": "19.2.4",
"typedoc": "0.28.16",
"typedoc-plugin-missing-exports": "4.1.2"
}
}

30
apps/client/index.html Normal file
View File

@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="favicon.ico">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, interactive-widget=resizes-content" />
<link rel="manifest" crossorigin="use-credentials" href="manifest.webmanifest">
<title>Trilium Notes</title>
</head>
<body id="trilium-app">
<noscript>Trilium requires JavaScript to be enabled.</noscript>
<div id="context-menu-cover"></div>
<div class="dropdown-menu dropdown-menu-sm" id="context-menu-container" style="display: none"></div>
<!-- Required to match the PWA's top bar color with the theme -->
<!-- This works even when the user directly changes --root-background in CSS -->
<div id="background-color-tracker" style="position: absolute; visibility: hidden; color: var(--root-background); transition: color 1ms;"></div>
<script src="./src/index.ts" type="module"></script>
<!-- Required for correct loading of scripts in Electron -->
<script>
if (typeof module === 'object') {window.module = module; module = undefined;}
</script>
</body>
</html>

View File

@@ -1,6 +1,6 @@
{
"name": "@triliumnext/client",
"version": "0.101.1",
"version": "0.101.3",
"description": "JQuery-based client for TriliumNext, used for both web and desktop (via Electron)",
"private": true,
"license": "AGPL-3.0-only",
@@ -27,14 +27,14 @@
"@mermaid-js/layout-elk": "0.2.0",
"@mind-elixir/node-menu": "5.0.1",
"@popperjs/core": "2.11.8",
"@preact/signals": "2.5.1",
"@preact/signals": "2.6.2",
"@triliumnext/ckeditor5": "workspace:*",
"@triliumnext/codemirror": "workspace:*",
"@triliumnext/commons": "workspace:*",
"@triliumnext/highlightjs": "workspace:*",
"@triliumnext/share-theme": "workspace:*",
"@triliumnext/split.js": "workspace:*",
"@zumer/snapdom": "2.0.1",
"@zumer/snapdom": "2.0.2",
"autocomplete.js": "0.38.1",
"bootstrap": "5.3.8",
"boxicons": "2.1.4",
@@ -42,26 +42,26 @@
"color": "5.0.3",
"debounce": "3.0.0",
"draggabilly": "3.0.0",
"force-graph": "1.51.0",
"globals": "16.5.0",
"i18next": "25.7.3",
"force-graph": "1.51.1",
"globals": "17.3.0",
"i18next": "25.8.0",
"i18next-http-backend": "3.0.2",
"jquery": "3.7.1",
"jquery": "4.0.0",
"jquery.fancytree": "2.38.5",
"jsplumb": "2.15.6",
"katex": "0.16.27",
"katex": "0.16.28",
"knockout": "3.5.1",
"leaflet": "1.9.4",
"leaflet-gpx": "2.2.0",
"mark.js": "8.11.1",
"marked": "17.0.1",
"mermaid": "11.12.2",
"mind-elixir": "5.3.8",
"mind-elixir": "5.7.1",
"normalize.css": "8.0.1",
"panzoom": "9.4.3",
"preact": "10.28.1",
"react-i18next": "16.5.0",
"react-window": "2.2.3",
"preact": "10.28.3",
"react-i18next": "16.5.4",
"react-window": "2.2.6",
"reveal.js": "5.2.1",
"svg-pan-zoom": "3.6.2",
"tabulator-tables": "6.3.1",
@@ -69,7 +69,7 @@
},
"devDependencies": {
"@ckeditor/ckeditor5-inspector": "5.0.0",
"@preact/preset-vite": "2.10.2",
"@prefresh/vite": "2.4.11",
"@types/bootstrap": "5.2.10",
"@types/jquery": "3.5.33",
"@types/leaflet": "1.9.21",
@@ -78,8 +78,9 @@
"@types/reveal.js": "5.2.2",
"@types/tabulator-tables": "6.3.1",
"copy-webpack-plugin": "13.0.1",
"happy-dom": "20.0.11",
"happy-dom": "20.5.0",
"lightningcss": "1.31.1",
"script-loader": "0.7.2",
"vite-plugin-static-copy": "3.1.4"
"vite-plugin-static-copy": "3.2.0"
}
}

View File

@@ -1,12 +1,12 @@
import type { CKTextEditor } from "@triliumnext/ckeditor5";
import type CodeMirror from "@triliumnext/codemirror";
import { SqlExecuteResults } from "@triliumnext/commons";
import { SqlExecuteResponse } from "@triliumnext/commons";
import type { NativeImage, TouchBar } from "electron";
import { ColumnComponent } from "tabulator-tables";
import type { Attribute } from "../services/attribute_parser.js";
import froca from "../services/froca.js";
import { initLocale,t } from "../services/i18n.js";
import { initLocale, t } from "../services/i18n.js";
import keyboardActionsService from "../services/keyboard_actions.js";
import linkService, { type ViewScope } from "../services/link.js";
import type LoadResults from "../services/load_results.js";
@@ -101,8 +101,6 @@ export type CommandMappings = {
showRevisions: CommandData & {
noteId?: string | null;
};
showLlmChat: CommandData;
createAiChat: CommandData;
showOptions: CommandData & {
section: string;
};
@@ -154,6 +152,7 @@ export type CommandMappings = {
};
openInTab: ContextMenuCommandData;
openNoteInSplit: ContextMenuCommandData;
openNoteInWindow: ContextMenuCommandData;
openNoteInPopup: ContextMenuCommandData;
toggleNoteHoisting: ContextMenuCommandData;
insertNoteAfter: ContextMenuCommandData;
@@ -382,7 +381,8 @@ export type CommandMappings = {
reloadTextEditor: CommandData;
chooseNoteType: CommandData & {
callback: ChooseNoteTypeCallback
}
};
customDownload: CommandData;
};
type EventMappings = {
@@ -408,7 +408,7 @@ type EventMappings = {
addNewLabel: CommandData;
addNewRelation: CommandData;
sqlQueryResults: CommandData & {
results: SqlExecuteResults;
response: SqlExecuteResponse;
};
readOnlyTemporarilyDisabled: {
noteContext: NoteContext;
@@ -473,6 +473,11 @@ type EventMappings = {
noteContextRemoved: {
ntxIds: string[];
};
contextDataChanged: {
noteContext: NoteContext;
key: string;
value: unknown;
};
exportSvg: { ntxId: string | null | undefined; };
exportPng: { ntxId: string | null | undefined; };
geoMapCreateChildNote: {

View File

@@ -57,6 +57,18 @@ export class TypedComponent<ChildT extends TypedComponent<ChildT>> {
return this;
}
/**
* Removes a child component from this component's children array.
* This is used for cleanup when a widget is unmounted to prevent event listener accumulation.
*/
removeChild(component: ChildT) {
const index = this.children.indexOf(component);
if (index !== -1) {
this.children.splice(index, 1);
component.parent = undefined;
}
}
handleEvent<T extends EventNames>(name: T, data: EventData<T>): Promise<unknown[] | unknown> | null | undefined {
try {
const callMethodPromise = this.initialized ? this.initialized.then(() => this.callMethod((this as any)[`${name}Event`], data)) : this.callMethod((this as any)[`${name}Event`], data);

View File

@@ -1,16 +1,17 @@
import utils from "../services/utils.js";
import { CreateChildrenResponse, SqlExecuteResponse } from "@triliumnext/commons";
import bundleService from "../services/bundle.js";
import dateNoteService from "../services/date_notes.js";
import froca from "../services/froca.js";
import { t } from "../services/i18n.js";
import linkService from "../services/link.js";
import protectedSessionHolder from "../services/protected_session_holder.js";
import server from "../services/server.js";
import toastService from "../services/toast.js";
import utils from "../services/utils.js";
import ws from "../services/ws.js";
import appContext, { type NoteCommandData } from "./app_context.js";
import Component from "./component.js";
import toastService from "../services/toast.js";
import ws from "../services/ws.js";
import bundleService from "../services/bundle.js";
import froca from "../services/froca.js";
import linkService from "../services/link.js";
import { t } from "../services/i18n.js";
import { CreateChildrenResponse, SqlExecuteResponse } from "@triliumnext/commons";
export default class Entrypoints extends Component {
constructor() {
@@ -187,13 +188,8 @@ export default class Entrypoints extends Component {
} else if (note.mime.endsWith("env=backend")) {
await server.post(`script/run/${note.noteId}`);
} else if (note.mime === "text/x-sqlite;schema=trilium") {
const resp = await server.post<SqlExecuteResponse>(`sql/execute/${note.noteId}`);
if (!resp.success) {
toastService.showError(t("entrypoints.sql-error", { message: resp.error }));
}
await appContext.triggerEvent("sqlQueryResults", { ntxId: ntxId, results: resp.results });
const response = await server.post<SqlExecuteResponse>(`sql/execute/${note.noteId}`);
await appContext.triggerEvent("sqlQueryResults", { ntxId, response });
}
toastService.showMessage(t("entrypoints.note-executed"));

View File

@@ -12,6 +12,7 @@ import server from "../services/server.js";
import treeService from "../services/tree.js";
import utils from "../services/utils.js";
import { ReactWrappedWidget } from "../widgets/basic_widget.js";
import type { HeadingContext } from "../widgets/sidebar/TableOfContents.js";
import appContext, { type EventData, type EventListener } from "./app_context.js";
import Component from "./component.js";
@@ -22,6 +23,31 @@ export interface SetNoteOpts {
export type GetTextEditorCallback = (editor: CKTextEditor) => void;
export type SaveState = "saved" | "saving" | "unsaved" | "error";
export interface NoteContextDataMap {
toc: HeadingContext;
pdfPages: {
totalPages: number;
currentPage: number;
scrollToPage(page: number): void;
requestThumbnail(page: number): void;
};
pdfAttachments: {
attachments: PdfAttachment[];
downloadAttachment(filename: string): void;
};
pdfLayers: {
layers: PdfLayer[];
toggleLayer(layerId: string, visible: boolean): void;
};
saveState: {
state: SaveState;
};
}
type ContextDataKey = keyof NoteContextDataMap;
class NoteContext extends Component implements EventListener<"entitiesReloaded"> {
ntxId: string | null;
hoistedNoteId: string;
@@ -32,6 +58,13 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded">
parentNoteId?: string | null;
viewScope?: ViewScope;
/**
* Metadata storage for UI components (e.g., table of contents, PDF page list, code outline).
* This allows type widgets to publish data that sidebar/toolbar components can consume.
* Data is automatically cleared when navigating to a different note.
*/
private contextData: Map<string, unknown> = new Map();
constructor(ntxId: string | null = null, hoistedNoteId: string = "root", mainNtxId: string | null = null) {
super();
@@ -91,6 +124,22 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded">
this.viewScope = opts.viewScope;
({ noteId: this.noteId, parentNoteId: this.parentNoteId } = treeService.getNoteIdAndParentIdFromUrl(resolvedNotePath));
// Clear context data when switching notes and notify subscribers
const oldKeys = Array.from(this.contextData.keys());
this.contextData.clear();
if (oldKeys.length > 0) {
// Notify subscribers asynchronously to avoid blocking navigation
window.setTimeout(() => {
for (const key of oldKeys) {
this.triggerEvent("contextDataChanged", {
noteContext: this,
key,
value: undefined
});
}
}, 0);
}
this.saveToRecentNotes(resolvedNotePath);
protectedSessionHolder.touchProtectedSessionIfNecessary(this.note);
@@ -443,6 +492,52 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded">
return title;
}
/**
* Set metadata for this note context (e.g., table of contents, PDF pages, code outline).
* This data can be consumed by sidebar/toolbar components.
*
* @param key - Unique identifier for the data type (e.g., "toc", "pdfPages", "codeOutline")
* @param value - The data to store (will be cleared when switching notes)
*/
setContextData<K extends ContextDataKey>(key: K, value: NoteContextDataMap[K]): void {
this.contextData.set(key, value);
// Trigger event so subscribers can react
this.triggerEvent("contextDataChanged", {
noteContext: this,
key,
value
});
}
/**
* Get metadata for this note context.
*
* @param key - The data key to retrieve
* @returns The stored data, or undefined if not found
*/
getContextData<K extends ContextDataKey>(key: K): NoteContextDataMap[K] | undefined {
return this.contextData.get(key) as NoteContextDataMap[K] | undefined;
}
/**
* Check if context data exists for a given key.
*/
hasContextData(key: ContextDataKey): boolean {
return this.contextData.has(key);
}
/**
* Clear specific context data.
*/
clearContextData(key: ContextDataKey): void {
this.contextData.delete(key);
this.triggerEvent("contextDataChanged", {
noteContext: this,
key,
value: undefined
});
}
}
export function openInCurrentNoteContext(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent | React.PointerEvent<HTMLCanvasElement> | null, notePath: string, viewScope?: ViewScope) {

View File

@@ -1,10 +1,8 @@
import dateNoteService from "../services/date_notes.js";
import froca from "../services/froca.js";
import noteCreateService from "../services/note_create.js";
import openService from "../services/open.js";
import options from "../services/options.js";
import protectedSessionService from "../services/protected_session.js";
import toastService from "../services/toast.js";
import treeService from "../services/tree.js";
import utils, { openInReusableSplit } from "../services/utils.js";
import appContext, { type CommandListenerData } from "./app_context.js";
@@ -248,34 +246,4 @@ export default class RootCommandExecutor extends Component {
}
}
async createAiChatCommand() {
try {
// Create a new AI Chat note at the root level
const rootNoteId = "root";
const result = await noteCreateService.createNote(rootNoteId, {
title: "New AI Chat",
type: "aiChat",
content: JSON.stringify({
messages: [],
title: "New AI Chat"
})
});
if (!result.note) {
toastService.showError("Failed to create AI Chat note");
return;
}
await appContext.tabManager.openTabWithNoteWithHoisting(result.note.noteId, {
activate: true
});
toastService.showMessage("Created new AI Chat note");
}
catch (e) {
console.error("Error creating AI Chat note:", e);
toastService.showError(`Failed to create AI Chat note: ${(e as Error).message}`);
}
}
}

View File

@@ -46,10 +46,6 @@ if (utils.isElectron()) {
electronContextMenu.setupContextMenu();
}
if (utils.isPWA()) {
initPWATopbarColor();
}
function initOnElectron() {
const electron: typeof Electron = utils.dynamicRequire("electron");
electron.ipcRenderer.on("globalShortcut", async (event, actionName) => appContext.triggerCommand(actionName));
@@ -99,15 +95,22 @@ function initFullScreenDetection(currentWindow: Electron.BrowserWindow) {
}
function initTransparencyEffects(style: CSSStyleDeclaration, currentWindow: Electron.BrowserWindow) {
const material = style.getPropertyValue("--background-material").trim();
if (window.glob.platform === "win32") {
const material = style.getPropertyValue("--background-material");
// TriliumNextTODO: find a nicer way to make TypeScript happy unfortunately TS did not like Array.includes here
const bgMaterialOptions = ["auto", "none", "mica", "acrylic", "tabbed"] as const;
const foundBgMaterialOption = bgMaterialOptions.find((bgMaterialOption) => material === bgMaterialOption);
if (foundBgMaterialOption) {
currentWindow.setBackgroundMaterial(foundBgMaterialOption);
}
}
if (window.glob.platform === "darwin") {
const bgMaterialOptions = [ "popover", "tooltip", "titlebar", "selection", "menu", "sidebar", "header", "sheet", "window", "hud", "fullscreen-ui", "content", "under-window", "under-page" ] as const;
const foundBgMaterialOption = bgMaterialOptions.find((bgMaterialOption) => material === bgMaterialOption);
if (foundBgMaterialOption) {
currentWindow.setVibrancy(foundBgMaterialOption);
}
}
}
/**
@@ -127,20 +130,3 @@ function initDarkOrLightMode(style: CSSStyleDeclaration) {
const { nativeTheme } = utils.dynamicRequire("@electron/remote") as typeof ElectronRemote;
nativeTheme.themeSource = themeSource;
}
function initPWATopbarColor() {
const tracker = $("#background-color-tracker");
if (tracker.length) {
const applyThemeColor = () => {
let meta = $("meta[name='theme-color']");
if (!meta.length) {
meta = $(`<meta name="theme-color">`).appendTo($("head"));
}
meta.attr("content", tracker.css("color"));
};
tracker.on("transitionend", applyThemeColor);
applyThemeColor();
}
}

View File

@@ -1,4 +1,4 @@
import { MIME_TYPES_DICT } from "@triliumnext/commons";
import { getNoteIcon } from "@triliumnext/commons";
import cssClassManager from "../services/css_class_manager.js";
import type { Froca } from "../services/froca-interface.js";
@@ -8,36 +8,17 @@ import search from "../services/search.js";
import server from "../services/server.js";
import utils from "../services/utils.js";
import type FAttachment from "./fattachment.js";
import type { AttributeType,default as FAttribute } from "./fattribute.js";
import type { AttributeType, default as FAttribute } from "./fattribute.js";
const LABEL = "label";
const RELATION = "relation";
export const NOTE_TYPE_ICONS = {
file: "bx bx-file",
image: "bx bx-image",
code: "bx bx-code",
render: "bx bx-extension",
search: "bx bx-file-find",
relationMap: "bx bxs-network-chart",
book: "bx bx-book",
noteMap: "bx bxs-network-chart",
mermaid: "bx bx-selection",
canvas: "bx bx-pen",
webView: "bx bx-globe-alt",
launcher: "bx bx-link",
doc: "bx bxs-file-doc",
contentWidget: "bx bxs-widget",
mindMap: "bx bx-sitemap",
aiChat: "bx bx-bot"
};
/**
* There are many different Note types, some of which are entirely opaque to the
* end user. Those types should be used only for checking against, they are
* not for direct use.
*/
export type NoteType = "file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code" | "mindMap" | "aiChat";
export type NoteType = "file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code" | "mindMap";
export interface NotePathRecord {
isArchived: boolean;
@@ -582,32 +563,18 @@ export default class FNote {
}
getIcon() {
return `tn-icon ${this.#getIconInternal()}`;
}
#getIconInternal() {
const iconClassLabels = this.getLabels("iconClass");
const workspaceIconClass = this.getWorkspaceIconClass();
if (iconClassLabels && iconClassLabels.length > 0) {
return iconClassLabels[0].value;
} else if (workspaceIconClass) {
return workspaceIconClass;
} else if (this.noteId === "root") {
return "bx bx-home-alt-2";
}
if (this.noteId === "_share") {
return "bx bx-share-alt";
} else if (this.type === "text") {
if (this.isFolder()) {
return "bx bx-folder";
}
return "bx bx-note";
} else if (this.type === "code") {
const correspondingMimeType = MIME_TYPES_DICT.find(m => m.mime === this.mime);
return correspondingMimeType?.icon ?? NOTE_TYPE_ICONS.code;
}
return NOTE_TYPE_ICONS[this.type];
const icon = getNoteIcon({
noteId: this.noteId,
type: this.type,
mime: this.mime,
iconClass: iconClassLabels.length > 0 ? iconClassLabels[0].value : undefined,
workspaceIconClass,
isFolder: this.isFolder.bind(this)
});
return `tn-icon ${icon}`;
}
getColorClass() {
@@ -616,7 +583,9 @@ export default class FNote {
}
isFolder() {
return this.type === "search" || this.getFilteredChildBranches().length > 0;
if (this.isLabelTruthy("subtreeHidden")) return false;
if (this.type === "search") return true;
return this.getFilteredChildBranches().length > 0;
}
getFilteredChildBranches() {

View File

@@ -0,0 +1,131 @@
async function bootstrap() {
showSplash();
await setupGlob();
await Promise.all([
initJQuery(),
loadBootstrapCss()
]);
loadStylesheets();
loadIcons();
setBodyAttributes();
await loadScripts();
hideSplash();
}
async function initJQuery() {
const $ = (await import("jquery")).default;
window.$ = $;
window.jQuery = $;
// Polyfill removed jQuery methods for autocomplete.js compatibility
($ as any).isArray = Array.isArray;
($ as any).isFunction = function(obj: any) { return typeof obj === 'function'; };
($ as any).isPlainObject = function(obj: any) {
if (obj == null || typeof obj !== 'object') { return false; }
const proto = Object.getPrototypeOf(obj);
if (proto === null) { return true; }
const Ctor = Object.prototype.hasOwnProperty.call(proto, 'constructor') && proto.constructor;
return typeof Ctor === 'function' && Ctor === Object;
};
}
async function setupGlob() {
const response = await fetch(`./bootstrap${window.location.search}`);
const json = await response.json();
window.global = globalThis; /* fixes https://github.com/webpack/webpack/issues/10035 */
window.glob = {
...json,
activeDialog: null
};
}
async function loadBootstrapCss() {
// We have to selectively import Bootstrap CSS based on text direction.
if (glob.isRtl) {
await import("bootstrap/dist/css/bootstrap.rtl.min.css");
} else {
await import("bootstrap/dist/css/bootstrap.min.css");
}
}
function loadStylesheets() {
const { device, assetPath, themeCssUrl, themeUseNextAsBase } = window.glob;
const cssToLoad: string[] = [];
if (device !== "print") {
cssToLoad.push(`${assetPath}/stylesheets/ckeditor-theme.css`);
cssToLoad.push(`api/fonts`);
cssToLoad.push(`${assetPath}/stylesheets/theme-light.css`);
if (themeCssUrl) {
cssToLoad.push(themeCssUrl);
}
if (themeUseNextAsBase === "next") {
cssToLoad.push(`${assetPath}/stylesheets/theme-next.css`);
} else if (themeUseNextAsBase === "next-dark") {
cssToLoad.push(`${assetPath}/stylesheets/theme-next-dark.css`);
} else if (themeUseNextAsBase === "next-light") {
cssToLoad.push(`${assetPath}/stylesheets/theme-next-light.css`);
}
cssToLoad.push(`${assetPath}/stylesheets/style.css`);
}
for (const href of cssToLoad) {
const linkEl = document.createElement("link");
linkEl.href = href;
linkEl.rel = "stylesheet";
document.head.appendChild(linkEl);
}
}
function loadIcons() {
const styleEl = document.createElement("style");
styleEl.innerText = window.glob.iconPackCss;
document.head.appendChild(styleEl);
}
function setBodyAttributes() {
const { device, headingStyle, layoutOrientation, platform, isElectron, hasNativeTitleBar, hasBackgroundEffects, currentLocale } = window.glob;
const classesToSet = [
device,
`heading-style-${headingStyle}`,
`layout-${layoutOrientation}`,
`platform-${platform}`,
isElectron && "electron",
hasNativeTitleBar && "native-titlebar",
hasBackgroundEffects && "background-effects"
].filter(Boolean) as string[];
for (const classToSet of classesToSet) {
document.body.classList.add(classToSet);
}
document.body.lang = currentLocale.id;
document.body.dir = currentLocale.rtl ? "rtl" : "ltr";
}
async function loadScripts() {
switch (glob.device) {
case "mobile":
await import("./mobile.js");
break;
case "print":
await import("./print.js");
break;
case "desktop":
default:
await import("./desktop.js");
break;
}
}
function showSplash() {
// hide body to reduce flickering on the startup. This is done through JS and not CSS to not hide <noscript>
document.body.style.display = "none";
}
function hideSplash() {
document.body.style.display = "block";
}
bootstrap();

View File

@@ -46,8 +46,6 @@ import ScrollPadding from "../widgets/scroll_padding.js";
import SearchResult from "../widgets/search_result.jsx";
import SharedInfo from "../widgets/shared_info.jsx";
import RightPanelContainer from "../widgets/sidebar/RightPanelContainer.jsx";
import SqlResults from "../widgets/sql_result.js";
import SqlTableSchemas from "../widgets/sql_table_schemas.js";
import TabRowWidget from "../widgets/tab_row.js";
import TabHistoryNavigationButtons from "../widgets/TabHistoryNavigationButtons.jsx";
import TitleBarButtons from "../widgets/title_bar_buttons.jsx";
@@ -163,11 +161,9 @@ export default class DesktopLayout {
.child(<SharedInfo />)
)
.optChild(!isNewLayout, <PromotedAttributes />)
.child(<SqlTableSchemas />)
.child(<NoteDetail />)
.child(<NoteList media="screen" />)
.child(<SearchResult />)
.child(<SqlResults />)
.child(<ScrollPadding />)
)
.child(<ApiLog />)

View File

@@ -0,0 +1,76 @@
#background-color-tracker {
color: var(--main-background-color) !important;
}
span.keyboard-shortcut,
kbd {
display: none;
}
.dropdown-menu {
font-size: larger;
}
.action-button {
background: none;
border: none;
cursor: pointer;
font-size: 1.25em;
padding-inline-start: 0.5em;
padding-inline-end: 0.5em;
color: var(--main-text-color);
}
.quick-search {
margin: 0;
}
.quick-search .dropdown-menu {
max-width: 350px;
}
/* #region Tree */
.tree-wrapper {
max-height: 100%;
margin-top: 0px;
overflow-y: auto;
contain: content;
padding-inline-start: 10px;
}
.fancytree-title {
margin-inline-start: 0.6em !important;
}
.fancytree-node {
padding: 5px;
}
span.fancytree-expander {
width: 24px !important;
margin-inline-end: 5px;
}
.fancytree-loading span.fancytree-expander {
width: 24px;
height: 32px;
}
.fancytree-loading span.fancytree-expander:after {
width: 20px;
height: 20px;
margin-top: 4px;
border-width: 2px;
border-style: solid;
}
.tree-wrapper .collapse-tree-button,
.tree-wrapper .scroll-to-active-note-button,
.tree-wrapper .tree-settings-button {
position: fixed;
margin-inline-end: 16px;
display: none;
}
.tree-wrapper .unhoist-button {
font-size: 200%;
}
/* #endregion */

View File

@@ -1,128 +1,41 @@
import { applyModals } from "./layout_commons.js";
import { MOBILE_FLOATING_BUTTONS } from "../widgets/FloatingButtonsDefinitions.jsx";
import { useNoteContext } from "../widgets/react/hooks.jsx";
import CloseZenModeButton from "../widgets/close_zen_button.js";
import FilePropertiesTab from "../widgets/ribbon/FilePropertiesTab.jsx";
import FlexContainer from "../widgets/containers/flex_container.js";
import FloatingButtons from "../widgets/FloatingButtons.jsx";
import "./mobile_layout.css";
import type AppContext from "../components/app_context.js";
import GlobalMenuWidget from "../widgets/buttons/global_menu.js";
import MobileDetailMenu from "../widgets/mobile_widgets/mobile_detail_menu.js";
import CloseZenModeButton from "../widgets/close_zen_button.js";
import NoteList from "../widgets/collections/NoteList.jsx";
import FlexContainer from "../widgets/containers/flex_container.js";
import RootContainer from "../widgets/containers/root_container.js";
import ScrollingContainer from "../widgets/containers/scrolling_container.js";
import SplitNoteContainer from "../widgets/containers/split_note_container.js";
import FindWidget from "../widgets/find.js";
import LauncherContainer from "../widgets/launch_bar/LauncherContainer.jsx";
import InlineTitle from "../widgets/layout/InlineTitle.jsx";
import NoteBadges from "../widgets/layout/NoteBadges.jsx";
import NoteTitleActions from "../widgets/layout/NoteTitleActions.jsx";
import MobileDetailMenu from "../widgets/mobile_widgets/mobile_detail_menu.js";
import ScreenContainer from "../widgets/mobile_widgets/screen_container.js";
import SidebarContainer from "../widgets/mobile_widgets/sidebar_container.js";
import ToggleSidebarButton from "../widgets/mobile_widgets/toggle_sidebar_button.jsx";
import NoteIconWidget from "../widgets/note_icon.jsx";
import NoteTitleWidget from "../widgets/note_title.js";
import ContentHeader from "../widgets/containers/content_header.js";
import NoteTreeWidget from "../widgets/note_tree.js";
import NoteWrapperWidget from "../widgets/note_wrapper.js";
import NoteDetail from "../widgets/NoteDetail.jsx";
import QuickSearchWidget from "../widgets/quick_search.js";
import ReadOnlyNoteInfoBar from "../widgets/ReadOnlyNoteInfoBar.jsx";
import RootContainer from "../widgets/containers/root_container.js";
import ScreenContainer from "../widgets/mobile_widgets/screen_container.js";
import ScrollingContainer from "../widgets/containers/scrolling_container.js";
import { useNoteContext } from "../widgets/react/hooks.jsx";
import StandaloneRibbonAdapter from "../widgets/ribbon/components/StandaloneRibbonAdapter.jsx";
import FilePropertiesTab from "../widgets/ribbon/FilePropertiesTab.jsx";
import SearchDefinitionTab from "../widgets/ribbon/SearchDefinitionTab.jsx";
import SearchResult from "../widgets/search_result.jsx";
import SharedInfoWidget from "../widgets/shared_info.js";
import SidebarContainer from "../widgets/mobile_widgets/sidebar_container.js";
import StandaloneRibbonAdapter from "../widgets/ribbon/components/StandaloneRibbonAdapter.jsx";
import TabRowWidget from "../widgets/tab_row.js";
import ToggleSidebarButton from "../widgets/mobile_widgets/toggle_sidebar_button.jsx";
import type AppContext from "../components/app_context.js";
import NoteDetail from "../widgets/NoteDetail.jsx";
import MobileEditorToolbar from "../widgets/type_widgets/text/mobile_editor_toolbar.jsx";
import PromotedAttributes from "../widgets/PromotedAttributes.jsx";
import SplitNoteContainer from "../widgets/containers/split_note_container.js";
import LauncherContainer from "../widgets/launch_bar/LauncherContainer.jsx";
const MOBILE_CSS = `
<style>
span.keyboard-shortcut,
kbd {
display: none;
}
.dropdown-menu {
font-size: larger;
}
.action-button {
background: none;
border: none;
cursor: pointer;
font-size: 1.25em;
padding-inline-start: 0.5em;
padding-inline-end: 0.5em;
color: var(--main-text-color);
}
.quick-search {
margin: 0;
}
.quick-search .dropdown-menu {
max-width: 350px;
}
</style>`;
const FANCYTREE_CSS = `
<style>
.tree-wrapper {
max-height: 100%;
margin-top: 0px;
overflow-y: auto;
contain: content;
padding-inline-start: 10px;
}
.fancytree-custom-icon {
font-size: 2em;
}
.fancytree-title {
font-size: 1.5em;
margin-inline-start: 0.6em !important;
}
.fancytree-node {
padding: 5px;
}
.fancytree-node .fancytree-expander:before {
font-size: 2em !important;
}
span.fancytree-expander {
width: 24px !important;
margin-inline-end: 5px;
}
.fancytree-loading span.fancytree-expander {
width: 24px;
height: 32px;
}
.fancytree-loading span.fancytree-expander:after {
width: 20px;
height: 20px;
margin-top: 4px;
border-width: 2px;
border-style: solid;
}
.tree-wrapper .collapse-tree-button,
.tree-wrapper .scroll-to-active-note-button,
.tree-wrapper .tree-settings-button {
position: fixed;
margin-inline-end: 16px;
display: none;
}
.tree-wrapper .unhoist-button {
font-size: 200%;
}
</style>`;
import { applyModals } from "./layout_commons.js";
export default class MobileLayout {
getRootWidget(appContext: typeof AppContext) {
const rootContainer = new RootContainer(true)
.setParent(appContext)
.class("horizontal-layout")
.cssBlock(MOBILE_CSS)
.child(new FlexContainer("column").id("mobile-sidebar-container"))
.child(
new FlexContainer("row")
@@ -136,7 +49,7 @@ export default class MobileLayout {
.css("padding-inline-start", "0")
.css("padding-inline-end", "0")
.css("contain", "content")
.child(new FlexContainer("column").filling().id("mobile-sidebar-wrapper").child(new QuickSearchWidget()).child(new NoteTreeWidget().cssBlock(FANCYTREE_CSS)))
.child(new FlexContainer("column").filling().id("mobile-sidebar-wrapper").child(new QuickSearchWidget()).child(new NoteTreeWidget()))
)
.child(
new ScreenContainer("detail", "row")
@@ -147,30 +60,28 @@ export default class MobileLayout {
new NoteWrapperWidget()
.child(
new FlexContainer("row")
.class("title-row note-split-title")
.contentSized()
.css("font-size", "larger")
.css("align-items", "center")
.child(<ToggleSidebarButton />)
.child(<NoteIconWidget />)
.child(<NoteTitleWidget />)
.child(<NoteBadges />)
.child(<MobileDetailMenu />)
)
.child(<FloatingButtons items={MOBILE_FLOATING_BUTTONS} />)
.child(<PromotedAttributes />)
.child(
new ScrollingContainer()
.filling()
.contentSized()
.child(new ContentHeader()
.child(<ReadOnlyNoteInfoBar />)
.child(<SharedInfoWidget />)
)
.child(<InlineTitle />)
.child(<NoteTitleActions />)
.child(<NoteDetail />)
.child(<NoteList media="screen" />)
.child(<StandaloneRibbonAdapter component={SearchDefinitionTab} />)
.child(<SearchResult />)
.child(<FilePropertiesWrapper />)
)
.child(<MobileEditorToolbar />)
.child(new FindWidget())
)
)
)
@@ -179,7 +90,6 @@ export default class MobileLayout {
new FlexContainer("column")
.contentSized()
.id("mobile-bottom-bar")
.child(new TabRowWidget().css("height", "40px"))
.child(new FlexContainer("row")
.class("horizontal")
.css("height", "53px")
@@ -194,11 +104,11 @@ export default class MobileLayout {
}
function FilePropertiesWrapper() {
const { note } = useNoteContext();
const { note, ntxId } = useNoteContext();
return (
<div>
{note?.type === "file" && <FilePropertiesTab note={note} />}
{note?.type === "file" && <FilePropertiesTab note={note} ntxId={ntxId} />}
</div>
);
}

View File

@@ -1,8 +1,9 @@
import { KeyboardActionNames } from "@triliumnext/commons";
import { h, JSX, render } from "preact";
import keyboardActionService, { getActionSync } from "../services/keyboard_actions.js";
import note_tooltip from "../services/note_tooltip.js";
import utils from "../services/utils.js";
import { h, JSX, render } from "preact";
export interface ContextMenuOptions<T> {
x: number;
@@ -62,17 +63,17 @@ export type ContextMenuEvent = PointerEvent | MouseEvent | JQuery.ContextMenuEve
class ContextMenu {
private $widget: JQuery<HTMLElement>;
private $cover: JQuery<HTMLElement>;
private $cover?: JQuery<HTMLElement>;
private options?: ContextMenuOptions<any>;
private isMobile: boolean;
constructor() {
this.$widget = $("#context-menu-container");
this.$cover = $("#context-menu-cover");
this.$widget.addClass("dropend");
this.isMobile = utils.isMobile();
if (this.isMobile) {
this.$cover = $("#context-menu-cover");
this.$cover.on("click", () => this.hide());
} else {
$(document).on("click", (e) => this.hide());
@@ -91,7 +92,7 @@ class ContextMenu {
}
this.$widget.toggleClass("mobile-bottom-menu", !this.options.forcePositionOnMobile);
this.$cover.addClass("show");
this.$cover?.addClass("show");
$("body").addClass("context-menu-shown");
this.$widget.empty();
@@ -140,16 +141,14 @@ class ContextMenu {
} else {
left = this.options.x - contextMenuWidth + CONTEXT_MENU_OFFSET;
}
} else if (contextMenuWidth && this.options.x + contextMenuWidth - CONTEXT_MENU_OFFSET > clientWidth - CONTEXT_MENU_PADDING) {
// Overflow: right
left = clientWidth - contextMenuWidth - CONTEXT_MENU_PADDING;
} else if (this.options.x - CONTEXT_MENU_OFFSET < CONTEXT_MENU_PADDING) {
// Overflow: left
left = CONTEXT_MENU_PADDING;
} else {
if (contextMenuWidth && this.options.x + contextMenuWidth - CONTEXT_MENU_OFFSET > clientWidth - CONTEXT_MENU_PADDING) {
// Overflow: right
left = clientWidth - contextMenuWidth - CONTEXT_MENU_PADDING;
} else if (this.options.x - CONTEXT_MENU_OFFSET < CONTEXT_MENU_PADDING) {
// Overflow: left
left = CONTEXT_MENU_PADDING;
} else {
left = this.options.x - CONTEXT_MENU_OFFSET;
}
left = this.options.x - CONTEXT_MENU_OFFSET;
}
this.$widget
@@ -249,7 +248,7 @@ class ContextMenu {
if ("uiIcon" in item || "checked" in item) {
const icon = (item.checked ? "bx bx-check" : item.uiIcon);
if (icon) {
$icon.addClass(icon);
$icon.addClass([icon, "tn-icon"]);
} else {
$icon.append("&nbsp;");
}
@@ -261,7 +260,7 @@ class ContextMenu {
.append(item.title);
if ("badges" in item && item.badges) {
for (let badge of item.badges) {
for (const badge of item.badges) {
const badgeElement = $(`<span class="badge">`).text(badge.title);
if (badge.className) {
@@ -352,7 +351,7 @@ class ContextMenu {
async hide() {
this.options?.onHide?.();
this.$widget.removeClass("show");
this.$cover.removeClass("show");
this.$cover?.removeClass("show");
$("body").removeClass("context-menu-shown");
this.$widget.hide();
}

View File

@@ -1,12 +1,12 @@
import treeService from "../services/tree.js";
import froca from "../services/froca.js";
import contextMenu, { type MenuCommandItem, type MenuItem } from "./context_menu.js";
import dialogService from "../services/dialog.js";
import server from "../services/server.js";
import { t } from "../services/i18n.js";
import type { ContextMenuCommandData,FilteredCommandNames } from "../components/app_context.js";
import type { SelectMenuItemEventListener } from "../components/events.js";
import dialogService from "../services/dialog.js";
import froca from "../services/froca.js";
import { t } from "../services/i18n.js";
import server from "../services/server.js";
import treeService from "../services/tree.js";
import type NoteTreeWidget from "../widgets/note_tree.js";
import type { FilteredCommandNames, ContextMenuCommandData } from "../components/app_context.js";
import contextMenu, { type MenuCommandItem, type MenuItem } from "./context_menu.js";
type LauncherCommandNames = FilteredCommandNames<ContextMenuCommandData>;
@@ -32,8 +32,8 @@ export default class LauncherContextMenu implements SelectMenuItemEventListener<
const note = this.node.data.noteId ? await froca.getNote(this.node.data.noteId) : null;
const parentNoteId = this.node.getParent().data.noteId;
const isVisibleRoot = note?.noteId === "_lbVisibleLaunchers";
const isAvailableRoot = note?.noteId === "_lbAvailableLaunchers";
const isVisibleRoot = note?.noteId === "_lbVisibleLaunchers" || note?.noteId === "_lbMobileVisibleLaunchers";
const isAvailableRoot = note?.noteId === "_lbAvailableLaunchers" || note?.noteId === "_lbMobileAvailableLaunchers";
const isVisibleItem = parentNoteId === "_lbVisibleLaunchers" || parentNoteId === "_lbMobileVisibleLaunchers";
const isAvailableItem = parentNoteId === "_lbAvailableLaunchers" || parentNoteId === "_lbMobileAvailableLaunchers";
const isItem = isVisibleItem || isAvailableItem;

View File

@@ -1,21 +1,21 @@
import NoteColorPicker from "./custom-items/NoteColorPicker.jsx";
import treeService from "../services/tree.js";
import froca from "../services/froca.js";
import clipboard from "../services/clipboard.js";
import noteCreateService from "../services/note_create.js";
import contextMenu, { type MenuCommandItem, type MenuItem } from "./context_menu.js";
import appContext, { type ContextMenuCommandData, type FilteredCommandNames } from "../components/app_context.js";
import type { SelectMenuItemEventListener } from "../components/events.js";
import type FAttachment from "../entities/fattachment.js";
import attributes from "../services/attributes.js";
import { executeBulkActions } from "../services/bulk_action.js";
import clipboard from "../services/clipboard.js";
import dialogService from "../services/dialog.js";
import froca from "../services/froca.js";
import { t } from "../services/i18n.js";
import noteCreateService from "../services/note_create.js";
import noteTypesService from "../services/note_types.js";
import server from "../services/server.js";
import toastService from "../services/toast.js";
import dialogService from "../services/dialog.js";
import { t } from "../services/i18n.js";
import type NoteTreeWidget from "../widgets/note_tree.js";
import type FAttachment from "../entities/fattachment.js";
import type { SelectMenuItemEventListener } from "../components/events.js";
import treeService from "../services/tree.js";
import utils from "../services/utils.js";
import attributes from "../services/attributes.js";
import { executeBulkActions } from "../services/bulk_action.js";
import type NoteTreeWidget from "../widgets/note_tree.js";
import contextMenu, { type MenuCommandItem, type MenuItem } from "./context_menu.js";
import NoteColorPicker from "./custom-items/NoteColorPicker.jsx";
// TODO: Deduplicate once client/server is well split.
interface ConvertToAttachmentResponse {
@@ -72,6 +72,8 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
const noSelectedNotes = selNodes.length === 0 || (selNodes.length === 1 && selNodes[0] === this.node);
const notSearch = note?.type !== "search";
const hasSubtreeHidden = note?.isLabelTruthy("subtreeHidden") ?? false;
const isSpotlighted = this.node.extraClasses.includes("spotlighted-node");
const notOptionsOrHelp = !note?.noteId.startsWith("_options") && !note?.noteId.startsWith("_help");
const parentNotSearch = !parentNote || parentNote.type !== "search";
const insertNoteAfterEnabled = isNotRoot && !isHoisted && parentNotSearch;
@@ -79,17 +81,18 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
const items: (MenuItem<TreeCommandNames> | null)[] = [
{ title: t("tree-context-menu.open-in-a-new-tab"), command: "openInTab", shortcut: "Ctrl+Click", uiIcon: "bx bx-link-external", enabled: noSelectedNotes },
{ title: t("tree-context-menu.open-in-a-new-split"), command: "openNoteInSplit", uiIcon: "bx bx-dock-right", enabled: noSelectedNotes },
{ title: t("tree-context-menu.open-in-a-new-window"), command: "openNoteInWindow", uiIcon: "bx bx-window-open", enabled: noSelectedNotes },
{ title: t("tree-context-menu.open-in-popup"), command: "openNoteInPopup", uiIcon: "bx bx-edit", enabled: noSelectedNotes },
isHoisted
? null
: {
title: `${t("tree-context-menu.hoist-note")}`,
command: "toggleNoteHoisting",
keyboardShortcut: "toggleNoteHoisting",
uiIcon: "bx bxs-chevrons-up",
enabled: noSelectedNotes && notSearch
},
title: `${t("tree-context-menu.hoist-note")}`,
command: "toggleNoteHoisting",
keyboardShortcut: "toggleNoteHoisting",
uiIcon: "bx bxs-chevrons-up",
enabled: noSelectedNotes && notSearch
},
!isHoisted || !isNotRoot
? null
: { title: t("tree-context-menu.unhoist-note"), command: "toggleNoteHoisting", keyboardShortcut: "toggleNoteHoisting", uiIcon: "bx bx-door-open" },
@@ -112,7 +115,7 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
keyboardShortcut: "createNoteInto",
uiIcon: "bx bx-plus",
items: notSearch ? await noteTypesService.getNoteTypeItems("insertChildNote") : null,
enabled: notSearch && noSelectedNotes && notOptionsOrHelp,
enabled: notSearch && noSelectedNotes && notOptionsOrHelp && !hasSubtreeHidden && !isSpotlighted,
columns: 2
},
@@ -150,8 +153,17 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
{ kind: "separator" },
{ title: t("tree-context-menu.expand-subtree"), command: "expandSubtree", keyboardShortcut: "expandSubtree", uiIcon: "bx bx-expand", enabled: noSelectedNotes },
{ title: t("tree-context-menu.collapse-subtree"), command: "collapseSubtree", keyboardShortcut: "collapseSubtree", uiIcon: "bx bx-collapse", enabled: noSelectedNotes },
!hasSubtreeHidden && { title: t("tree-context-menu.expand-subtree"), command: "expandSubtree", keyboardShortcut: "expandSubtree", uiIcon: "bx bx-expand", enabled: noSelectedNotes },
!hasSubtreeHidden && { title: t("tree-context-menu.collapse-subtree"), command: "collapseSubtree", keyboardShortcut: "collapseSubtree", uiIcon: "bx bx-collapse", enabled: noSelectedNotes },
{
title: hasSubtreeHidden ? t("tree-context-menu.show-subtree") : t("tree-context-menu.hide-subtree"),
uiIcon: "bx bx-show",
handler: async () => {
const note = await froca.getNote(this.node.data.noteId);
if (!note) return;
attributes.setBooleanWithInheritance(note, "subtreeHidden", !hasSubtreeHidden);
}
},
{
title: t("tree-context-menu.sort-by"),
command: "sortChildNotes",
@@ -164,7 +176,7 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
{ title: t("tree-context-menu.copy-note-path-to-clipboard"), command: "copyNotePathToClipboard", uiIcon: "bx bx-directions", enabled: true },
{ title: t("tree-context-menu.recent-changes-in-subtree"), command: "recentChangesInSubtree", uiIcon: "bx bx-history", enabled: noSelectedNotes && notOptionsOrHelp }
]
].filter(Boolean) as MenuItem<TreeCommandNames>[]
},
{ kind: "separator" },
@@ -292,25 +304,30 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
noteCreateService.createNote(parentNotePath, {
target: "after",
targetBranchId: this.node.data.branchId,
type: type,
isProtected: isProtected,
templateNoteId: templateNoteId
type,
isProtected,
templateNoteId
});
} else if (command === "insertChildNote") {
const parentNotePath = treeService.getNotePath(this.node);
noteCreateService.createNote(parentNotePath, {
type: type,
type,
isProtected: this.node.data.isProtected,
templateNoteId: templateNoteId
templateNoteId
});
} else if (command === "openNoteInSplit") {
const subContexts = appContext.tabManager.getActiveContext()?.getSubContexts();
const { ntxId } = subContexts?.[subContexts.length - 1] ?? {};
this.treeWidget.triggerCommand("openNewNoteSplit", { ntxId, notePath });
} else if (command === "openNoteInWindow") {
appContext.triggerCommand("openInWindow", {
notePath,
hoistedNoteId: appContext.tabManager.getActiveContext()?.hoistedNoteId
});
} else if (command === "openNoteInPopup") {
appContext.triggerCommand("openInPopup", { noteIdOrPath: notePath })
appContext.triggerCommand("openInPopup", { noteIdOrPath: notePath });
} else if (command === "convertNoteToAttachment") {
if (!(await dialogService.confirm(t("tree-context-menu.convert-to-attachment-confirm")))) {
return;
@@ -332,11 +349,11 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
toastService.showMessage(t("tree-context-menu.converted-to-attachments", { count: converted }));
} else if (command === "copyNotePathToClipboard") {
navigator.clipboard.writeText("#" + notePath);
navigator.clipboard.writeText(`#${ notePath}`);
} else if (command) {
this.treeWidget.triggerCommand<TreeCommandNames>(command, {
node: this.node,
notePath: notePath,
notePath,
noteId: this.node.data.noteId,
selectedOrActiveBranchIds: this.treeWidget.getSelectedOrActiveBranchIds(this.node),
selectedOrActiveNoteIds: this.treeWidget.getSelectedOrActiveNoteIds(this.node)

View File

@@ -29,7 +29,9 @@ async function main() {
const froca = (await import("./services/froca")).default;
const note = await froca.getNote(noteId);
render(<App note={note} noteId={noteId} />, document.body);
const bodyWrapper = document.createElement("div");
render(<App note={note} noteId={noteId} />, bodyWrapper);
document.body.appendChild(bodyWrapper);
}
function App({ note, noteId }: { note: FNote | null | undefined, noteId: string }) {

View File

@@ -8,6 +8,17 @@ async function loadBootstrap() {
}
}
// Polyfill removed jQuery methods for autocomplete.js compatibility
($ as any).isArray = Array.isArray;
($ as any).isFunction = function(obj: any) { return typeof obj === 'function'; };
($ as any).isPlainObject = function(obj: any) {
if (obj == null || typeof obj !== 'object') { return false; }
const proto = Object.getPrototypeOf(obj);
if (proto === null) { return true; }
const Ctor = Object.prototype.hasOwnProperty.call(proto, 'constructor') && proto.constructor;
return typeof Ctor === 'function' && Ctor === Object;
};
(window as any).$ = $;
(window as any).jQuery = $;
await loadBootstrap();

View File

@@ -0,0 +1,139 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { buildNote } from "../test/easy-froca";
import { setBooleanWithInheritance } from "./attributes";
import froca from "./froca";
import server from "./server.js";
// Spy on server methods to track calls
// @ts-expect-error the generic typing is causing issues here
server.put = vi.fn(async <T> (url: string, data?: T) => ({} as T));
// @ts-expect-error the generic typing is causing issues here
server.remove = vi.fn(async <T> (url: string) => ({} as T));
describe("Set boolean with inheritance", () => {
beforeEach(() => {
vi.clearAllMocks();
});
it("doesn't call server if value matches directly", async () => {
const noteWithLabel = buildNote({
title: "New note",
"#foo": ""
});
const noteWithoutLabel = buildNote({
title: "New note"
});
await setBooleanWithInheritance(noteWithLabel, "foo", true);
await setBooleanWithInheritance(noteWithoutLabel, "foo", false);
expect(server.put).not.toHaveBeenCalled();
expect(server.remove).not.toHaveBeenCalled();
});
it("sets boolean normally without inheritance", async () => {
const standaloneNote = buildNote({
title: "New note"
});
await setBooleanWithInheritance(standaloneNote, "foo", true);
expect(server.put).toHaveBeenCalledWith(`notes/${standaloneNote.noteId}/set-attribute`, {
type: "label",
name: "foo",
value: "",
isInheritable: false
}, undefined);
});
it("removes boolean normally without inheritance", async () => {
const standaloneNote = buildNote({
title: "New note",
"#foo": ""
});
const attributeId = standaloneNote.getLabel("foo")!.attributeId;
await setBooleanWithInheritance(standaloneNote, "foo", false);
expect(server.remove).toHaveBeenCalledWith(`notes/${standaloneNote.noteId}/attributes/${attributeId}`);
});
it("doesn't call server if value matches inherited", async () => {
const parentNote = buildNote({
title: "Parent note",
"#foo(inheritable)": "",
"children": [
{
title: "Child note"
}
]
});
const childNote = froca.getNoteFromCache(parentNote.children[0])!;
expect(childNote.isLabelTruthy("foo")).toBe(true);
await setBooleanWithInheritance(childNote, "foo", true);
expect(server.put).not.toHaveBeenCalled();
expect(server.remove).not.toHaveBeenCalled();
});
it("overrides boolean with inheritance", async () => {
const parentNote = buildNote({
title: "Parent note",
"#foo(inheritable)": "",
"children": [
{
title: "Child note"
}
]
});
const childNote = froca.getNoteFromCache(parentNote.children[0])!;
expect(childNote.isLabelTruthy("foo")).toBe(true);
await setBooleanWithInheritance(childNote, "foo", false);
expect(server.put).toHaveBeenCalledWith(`notes/${childNote.noteId}/set-attribute`, {
type: "label",
name: "foo",
value: "false",
isInheritable: false
}, undefined);
});
it("overrides boolean with inherited false", async () => {
const parentNote = buildNote({
title: "Parent note",
"#foo(inheritable)": "false",
"children": [
{
title: "Child note"
}
]
});
const childNote = froca.getNoteFromCache(parentNote.children[0])!;
expect(childNote.isLabelTruthy("foo")).toBe(false);
await setBooleanWithInheritance(childNote, "foo", true);
expect(server.put).toHaveBeenCalledWith(`notes/${childNote.noteId}/set-attribute`, {
type: "label",
name: "foo",
value: "",
isInheritable: false
}, undefined);
});
it("deletes override boolean with inherited false with already existing value", async () => {
const parentNote = buildNote({
title: "Parent note",
"#foo(inheritable)": "false",
"children": [
{
title: "Child note",
"#foo": "false",
}
]
});
const childNote = froca.getNoteFromCache(parentNote.children[0])!;
expect(childNote.isLabelTruthy("foo")).toBe(false);
await setBooleanWithInheritance(childNote, "foo", true);
expect(server.put).toBeCalledWith(`notes/${childNote.noteId}/set-attribute`, {
type: "label",
name: "foo",
value: "",
isInheritable: false
}, undefined);
});
});

View File

@@ -1,36 +1,67 @@
import server from "./server.js";
import froca from "./froca.js";
import type FNote from "../entities/fnote.js";
import type { AttributeRow } from "./load_results.js";
import { AttributeType } from "@triliumnext/commons";
import type FNote from "../entities/fnote.js";
import froca from "./froca.js";
import type { AttributeRow } from "./load_results.js";
import server from "./server.js";
async function addLabel(noteId: string, name: string, value: string = "", isInheritable = false) {
await server.put(`notes/${noteId}/attribute`, {
type: "label",
name: name,
value: value,
name,
value,
isInheritable
});
}
export async function setLabel(noteId: string, name: string, value: string = "", isInheritable = false) {
export async function setLabel(noteId: string, name: string, value: string = "", isInheritable = false, componentId?: string) {
await server.put(`notes/${noteId}/set-attribute`, {
type: "label",
name: name,
value: value,
isInheritable
});
name,
value,
isInheritable,
}, componentId);
}
export async function setRelation(noteId: string, name: string, value: string = "", isInheritable = false) {
await server.put(`notes/${noteId}/set-attribute`, {
type: "relation",
name: name,
value: value,
name,
value,
isInheritable
});
}
/**
* Sets a boolean label on the given note, taking inheritance into account. If the desired value matches the inherited
* value, any owned label will be removed to allow the inherited value to take effect. If the desired value differs
* from the inherited value, an owned label will be created or updated to reflect the desired value.
*
* When checking if the boolean value is set, don't use `note.hasLabel`; instead use `note.isLabelTruthy`.
*
* @param note the note on which to set the boolean label.
* @param labelName the name of the label to set.
* @param value the boolean value to set for the label.
*/
export async function setBooleanWithInheritance(note: FNote, labelName: string, value: boolean) {
const actualValue = note.isLabelTruthy(labelName);
if (actualValue === value) return;
const hasInheritedValue = !note.hasOwnedLabel(labelName) && note.hasLabel(labelName);
if (hasInheritedValue) {
if (value) {
setLabel(note.noteId, labelName, "");
} else {
// Label is inherited - override to false.
setLabel(note.noteId, labelName, "false");
}
} else if (value) {
setLabel(note.noteId, labelName, "");
} else {
removeOwnedLabelByName(note, labelName);
}
}
async function removeAttributeById(noteId: string, attributeId: string) {
await server.remove(`notes/${noteId}/attributes/${attributeId}`);
}
@@ -86,15 +117,15 @@ function removeOwnedRelationByName(note: FNote, relationName: string) {
* @param name the name of the attribute to set.
* @param value the value of the attribute to set.
*/
export async function setAttribute(note: FNote, type: "label" | "relation", name: string, value: string | null | undefined) {
export async function setAttribute(note: FNote, type: "label" | "relation", name: string, value: string | null | undefined, componentId?: string) {
if (value !== null && value !== undefined) {
// Create or update the attribute.
await server.put(`notes/${note.noteId}/set-attribute`, { type, name, value });
await server.put(`notes/${note.noteId}/set-attribute`, { type, name, value }, componentId);
} else {
// Remove the attribute if it exists on the server but we don't define a value for it.
const attributeId = note.getAttribute(type, name)?.attributeId;
if (attributeId) {
await server.remove(`notes/${note.noteId}/attributes/${attributeId}`);
await server.remove(`notes/${note.noteId}/attributes/${attributeId}`, componentId);
}
}
}
@@ -142,6 +173,7 @@ export default {
setLabel,
setRelation,
setAttribute,
setBooleanWithInheritance,
removeAttributeById,
removeOwnedLabelByName,
removeOwnedRelationByName,

View File

@@ -1,12 +1,12 @@
import utils from "./utils.js";
import server from "./server.js";
import toastService, { type ToastOptionsWithRequiredId } from "./toast.js";
import appContext from "../components/app_context.js";
import type { ResolveOptions } from "../widgets/dialogs/delete_notes.js";
import froca from "./froca.js";
import hoistedNoteService from "./hoisted_note.js";
import ws from "./ws.js";
import appContext from "../components/app_context.js";
import { t } from "./i18n.js";
import type { ResolveOptions } from "../widgets/dialogs/delete_notes.js";
import server from "./server.js";
import toastService, { type ToastOptionsWithRequiredId } from "./toast.js";
import utils from "./utils.js";
import ws from "./ws.js";
// TODO: Deduplicate type with server
interface Response {
@@ -66,7 +66,7 @@ async function moveAfterBranch(branchIdsToMove: string[], afterBranchId: string)
}
}
async function moveToParentNote(branchIdsToMove: string[], newParentBranchId: string) {
async function moveToParentNote(branchIdsToMove: string[], newParentBranchId: string, componentId?: string) {
const newParentBranch = froca.getBranch(newParentBranchId);
if (!newParentBranch) {
return;
@@ -86,7 +86,7 @@ async function moveToParentNote(branchIdsToMove: string[], newParentBranchId: st
continue;
}
const resp = await server.put<Response>(`branches/${branchIdToMove}/move-to/${newParentBranchId}`);
const resp = await server.put<Response>(`branches/${branchIdToMove}/move-to/${newParentBranchId}`, undefined, componentId);
if (!resp.success) {
toastService.showError(resp.message);
@@ -103,7 +103,7 @@ async function moveToParentNote(branchIdsToMove: string[], newParentBranchId: st
* @param moveToParent whether to automatically go to the parent note path after a succesful delete. Usually makes sense if deleting the active note(s).
* @returns promise that returns false if the operation was cancelled or there was nothing to delete, true if the operation succeeded.
*/
async function deleteNotes(branchIdsToDelete: string[], forceDeleteAllClones = false, moveToParent = true) {
async function deleteNotes(branchIdsToDelete: string[], forceDeleteAllClones = false, moveToParent = true, componentId?: string) {
branchIdsToDelete = filterRootNote(branchIdsToDelete);
if (branchIdsToDelete.length === 0) {
@@ -139,9 +139,9 @@ async function deleteNotes(branchIdsToDelete: string[], forceDeleteAllClones = f
const branch = froca.getBranch(branchIdToDelete);
if (deleteAllClones && branch) {
await server.remove(`notes/${branch.noteId}${query}`);
await server.remove(`notes/${branch.noteId}${query}`, componentId);
} else {
await server.remove(`branches/${branchIdToDelete}${query}`);
await server.remove(`branches/${branchIdToDelete}${query}`, componentId);
}
}

View File

@@ -0,0 +1,9 @@
.rendered-content.no-preview > div {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
height: 100%;
font-size: 500%;
flex-grow: 1;
}

View File

@@ -1,18 +1,21 @@
import renderService from "./render.js";
import "./content_renderer.css";
import { normalizeMimeTypeForCKEditor } from "@triliumnext/commons";
import WheelZoom from 'vanilla-js-wheel-zoom';
import FAttachment from "../entities/fattachment.js";
import FNote from "../entities/fnote.js";
import imageContextMenuService from "../menus/image_context_menu.js";
import { t } from "../services/i18n.js";
import renderText from "./content_renderer_text.js";
import renderDoc from "./doc_renderer.js";
import { loadElkIfNeeded, postprocessMermaidSvg } from "./mermaid.js";
import openService from "./open.js";
import protectedSessionService from "./protected_session.js";
import protectedSessionHolder from "./protected_session_holder.js";
import openService from "./open.js";
import utils from "./utils.js";
import FNote from "../entities/fnote.js";
import FAttachment from "../entities/fattachment.js";
import imageContextMenuService from "../menus/image_context_menu.js";
import renderService from "./render.js";
import { applySingleBlockSyntaxHighlight } from "./syntax_highlight.js";
import { loadElkIfNeeded, postprocessMermaidSvg } from "./mermaid.js";
import renderDoc from "./doc_renderer.js";
import { t } from "../services/i18n.js";
import WheelZoom from 'vanilla-js-wheel-zoom';
import { normalizeMimeTypeForCKEditor } from "@triliumnext/commons";
import renderText from "./content_renderer_text.js";
import utils from "./utils.js";
let idCounter = 1;
@@ -22,6 +25,12 @@ export interface RenderOptions {
imageHasZoom?: boolean;
/** If enabled, it will prevent the default behavior in which an empty note would display a list of children. */
noChildrenList?: boolean;
/** If enabled, it will prevent rendering of included notes. */
noIncludedNotes?: boolean;
/** If enabled, it will include archived notes when rendering children list. */
includeArchivedNotes?: boolean;
/** Set of note IDs that have already been seen during rendering to prevent infinite recursion. */
seenNoteIds?: Set<string>;
}
const CODE_MIME_TYPES = new Set(["application/json"]);
@@ -64,18 +73,9 @@ export async function getRenderedContent(this: {} | { ctx: string }, entity: FNo
$renderedContent.append($("<div>").append("<div>This note is protected and to access it you need to enter password.</div>").append("<br/>").append($button));
} else if (entity instanceof FNote) {
$renderedContent
.css("display", "flex")
.css("flex-direction", "column");
$renderedContent.addClass("no-preview");
$renderedContent.append(
$("<div>")
.css("display", "flex")
.css("justify-content", "space-around")
.css("align-items", "center")
.css("height", "100%")
.css("font-size", "500%")
.css("flex-grow", "1")
.append($("<span>").addClass(entity.getIcon()))
$("<div>").append($("<span>").addClass(entity.getIcon()))
);
if (entity.type === "webView" && entity.hasLabel("webViewSrc")) {
@@ -152,7 +152,7 @@ function renderImage(entity: FNote | FAttachment, $renderedContent: JQuery<HTMLE
const $img = $("<img>")
.attr("src", url || "")
.attr("id", "attachment-image-" + idCounter++)
.attr("id", `attachment-image-${idCounter++}`)
.css("max-width", "100%");
$renderedContent.append($img);
@@ -193,7 +193,7 @@ function renderFile(entity: FNote | FAttachment, type: string, $renderedContent:
if (type === "pdf") {
const $pdfPreview = $('<iframe class="pdf-preview" style="width: 100%; flex-grow: 100;"></iframe>');
$pdfPreview.attr("src", openService.getUrlForDownload(`api/${entityType}/${entityId}/open`));
$pdfPreview.attr("src", openService.getUrlForDownload(`pdfjs/web/viewer.html?file=../../api/${entityType}/${entityId}/open`));
$content.append($pdfPreview);
} else if (type === "audio") {
@@ -217,28 +217,28 @@ function renderFile(entity: FNote | FAttachment, type: string, $renderedContent:
// in attachment list
const $downloadButton = $(`
<button class="file-download btn btn-primary" type="button">
<span class="bx bx-download"></span>
<span class="tn-icon bx bx-download"></span>
${t("file_properties.download")}
</button>
`);
const $openButton = $(`
<button class="file-open btn btn-primary" type="button">
<span class="bx bx-link-external"></span>
<span class="tn-icon bx bx-link-external"></span>
${t("file_properties.open")}
</button>
`);
$downloadButton.on("click", (e) => {
e.stopPropagation();
openService.downloadFileNote(entity.noteId)
openService.downloadFileNote(entity, null, null);
});
$openButton.on("click", async (e) => {
const iconEl = $openButton.find("> .bx");
iconEl.removeClass("bx bx-link-external");
iconEl.addClass("bx bx-loader spin");
e.stopPropagation();
await openService.openNoteExternally(entity.noteId, entity.mime)
await openService.openNoteExternally(entity.noteId, entity.mime);
iconEl.removeClass("bx bx-loader spin");
iconEl.addClass("bx bx-link-external");
});
@@ -266,7 +266,7 @@ async function renderMermaid(note: FNote | FAttachment, $renderedContent: JQuery
try {
await loadElkIfNeeded(mermaid, content);
const { svg } = await mermaid.mermaidAPI.render("in-mermaid-graph-" + idCounter++, content);
const { svg } = await mermaid.mermaidAPI.render(`in-mermaid-graph-${idCounter++}`, content);
$renderedContent.append($(postprocessMermaidSvg(svg)));
} catch (e) {
@@ -285,10 +285,11 @@ function getRenderingType(entity: FNote | FAttachment) {
}
const mime = "mime" in entity && entity.mime;
const isIconPack = entity instanceof FNote && entity.hasLabel("iconPack");
if (type === "file" && mime === "application/pdf") {
type = "pdf";
} else if ((type === "file" || type === "viewConfig") && mime && CODE_MIME_TYPES.has(mime)) {
} else if ((type === "file" || type === "viewConfig") && mime && CODE_MIME_TYPES.has(mime) && !isIconPack) {
type = "code";
} else if (type === "file" && mime && mime.startsWith("audio/")) {
type = "audio";

View File

@@ -0,0 +1,132 @@
import { trimIndentation } from "@triliumnext/commons";
import { describe, expect, it } from "vitest";
import { buildNote } from "../test/easy-froca";
import renderText from "./content_renderer_text";
describe("Text content renderer", () => {
it("renders included note", async () => {
const contentEl = document.createElement("div");
const includedNote = buildNote({
title: "Included note",
content: "<p>This is the included note.</p>"
});
const note = buildNote({
title: "New note",
content: trimIndentation`
<p>
Hi there
</p>
<section class="include-note" data-note-id="${includedNote.noteId}" data-box-size="medium">
&nbsp;
</section>
`
});
await renderText(note, $(contentEl));
expect(contentEl.querySelectorAll("section.include-note").length).toBe(1);
expect(contentEl.querySelectorAll("section.include-note p").length).toBe(1);
});
it("skips rendering included note", async () => {
const contentEl = document.createElement("div");
const includedNote = buildNote({
title: "Included note",
content: "<p>This is the included note.</p>"
});
const note = buildNote({
title: "New note",
content: trimIndentation`
<p>
Hi there
</p>
<section class="include-note" data-note-id="${includedNote.noteId}" data-box-size="medium">
&nbsp;
</section>
`
});
await renderText(note, $(contentEl), { noIncludedNotes: true });
expect(contentEl.querySelectorAll("section.include-note").length).toBe(0);
});
it("doesn't enter infinite loop on direct recursion", async () => {
const contentEl = document.createElement("div");
const note = buildNote({
title: "New note",
id: "Y7mBwmRjQyb4",
content: trimIndentation`
<p>
Hi there
</p>
<section class="include-note" data-note-id="Y7mBwmRjQyb4" data-box-size="medium">
&nbsp;
</section>
<section class="include-note" data-note-id="Y7mBwmRjQyb4" data-box-size="medium">
&nbsp;
</section>
`
});
await renderText(note, $(contentEl));
expect(contentEl.querySelectorAll("section.include-note").length).toBe(0);
});
it("doesn't enter infinite loop on indirect recursion", async () => {
const contentEl = document.createElement("div");
buildNote({
id: "first",
title: "Included note",
content: trimIndentation`\
<p>This is the included note.</p>
<section class="include-note" data-note-id="second" data-box-size="medium">
&nbsp;
</section>
`
});
const note = buildNote({
id: "second",
title: "New note",
content: trimIndentation`
<p>
Hi there
</p>
<section class="include-note" data-note-id="first" data-box-size="medium">
&nbsp;
</section>
`
});
await renderText(note, $(contentEl));
expect(contentEl.querySelectorAll("section.include-note").length).toBe(1);
});
it("renders children list when note is empty", async () => {
const contentEl = document.createElement("div");
const parentNote = buildNote({
title: "Parent note",
children: [
{ title: "Child note 1" },
{ title: "Child note 2" }
]
});
await renderText(parentNote, $(contentEl));
const items = contentEl.querySelectorAll("a");
expect(items.length).toBe(2);
expect(items[0].textContent).toBe("Child note 1");
expect(items[1].textContent).toBe("Child note 2");
});
it("skips archived notes in children list", async () => {
const contentEl = document.createElement("div");
const parentNote = buildNote({
title: "Parent note",
children: [
{ title: "Child note 1" },
{ title: "Child note 2", "#archived": "" },
{ title: "Child note 3" }
]
});
await renderText(parentNote, $(contentEl));
const items = contentEl.querySelectorAll("a");
expect(items.length).toBe(2);
expect(items[0].textContent).toBe("Child note 1");
expect(items[1].textContent).toBe("Child note 3");
});
});

View File

@@ -15,7 +15,14 @@ export default async function renderText(note: FNote | FAttachment, $renderedCon
if (blob && !isHtmlEmpty(blob.content)) {
$renderedContent.append($('<div class="ck-content">').html(blob.content));
await renderIncludedNotes($renderedContent[0]);
const seenNoteIds = options.seenNoteIds ?? new Set<string>();
seenNoteIds.add("noteId" in note ? note.noteId : note.attachmentId);
if (!options.noIncludedNotes) {
await renderIncludedNotes($renderedContent[0], seenNoteIds);
} else {
$renderedContent.find("section.include-note").remove();
}
if ($renderedContent.find("span.math-tex").length > 0) {
renderMathInElement($renderedContent[0], { trust: true });
@@ -35,11 +42,11 @@ export default async function renderText(note: FNote | FAttachment, $renderedCon
await rewriteMermaidDiagramsInContainer($renderedContent[0] as HTMLDivElement);
await formatCodeBlocks($renderedContent);
} else if (note instanceof FNote && !options.noChildrenList) {
await renderChildrenList($renderedContent, note);
await renderChildrenList($renderedContent, note, options.includeArchivedNotes ?? false);
}
}
async function renderIncludedNotes(contentEl: HTMLElement) {
async function renderIncludedNotes(contentEl: HTMLElement, seenNoteIds: Set<string>) {
// TODO: Consider duplicating with server's share/content_renderer.ts.
const includeNoteEls = contentEl.querySelectorAll("section.include-note");
@@ -66,7 +73,15 @@ async function renderIncludedNotes(contentEl: HTMLElement) {
continue;
}
const renderedContent = (await content_renderer.getRenderedContent(note)).$renderedContent;
if (seenNoteIds.has(noteId)) {
console.warn(`Skipping inclusion of ${noteId} to avoid circular reference.`);
includeNoteEl.remove();
continue;
}
const renderedContent = (await content_renderer.getRenderedContent(note, {
seenNoteIds
})).$renderedContent;
includeNoteEl.replaceChildren(...renderedContent);
}
}
@@ -98,7 +113,7 @@ export async function applyInlineMermaid(container: HTMLDivElement) {
}
}
async function renderChildrenList($renderedContent: JQuery<HTMLElement>, note: FNote) {
async function renderChildrenList($renderedContent: JQuery<HTMLElement>, note: FNote, includeArchivedNotes: boolean) {
let childNoteIds = note.getChildNoteIds();
if (!childNoteIds.length) {
@@ -108,14 +123,16 @@ async function renderChildrenList($renderedContent: JQuery<HTMLElement>, note: F
$renderedContent.css("padding", "10px");
$renderedContent.addClass("text-with-ellipsis");
// just load the first 10 child notes
if (childNoteIds.length > 10) {
childNoteIds = childNoteIds.slice(0, 10);
}
// just load the first 10 child notes
const childNotes = await froca.getNotes(childNoteIds);
for (const childNote of childNotes) {
if (childNote.isArchived && !includeArchivedNotes) continue;
$renderedContent.append(
await link.createLink(`${note.noteId}/${childNote.noteId}`, {
showTooltip: false,

View File

@@ -0,0 +1,14 @@
import { describe, expect, it } from "vitest";
import { getReadableTextColor } from "./css_class_manager";
describe("getReadableTextColor", () => {
it("doesn't crash for invalid color", () => {
expect(getReadableTextColor("RandomColor")).toBe("#000");
});
it("tolerates different casing", () => {
expect(getReadableTextColor("Blue"))
.toBe(getReadableTextColor("blue"));
});
});

View File

@@ -1,21 +1,22 @@
import clsx from "clsx";
import {readCssVar} from "../utils/css-var";
import Color, { ColorInstance } from "color";
import {readCssVar} from "../utils/css-var";
const registeredClasses = new Set<string>();
const colorsWithHue = new Set<string>();
// Read the color lightness limits defined in the theme as CSS variables
const lightThemeColorMaxLightness = readCssVar(
document.documentElement,
"tree-item-light-theme-max-color-lightness"
).asNumber(70);
document.documentElement,
"tree-item-light-theme-max-color-lightness"
).asNumber(70);
const darkThemeColorMinLightness = readCssVar(
document.documentElement,
"tree-item-dark-theme-min-color-lightness"
).asNumber(50);
document.documentElement,
"tree-item-dark-theme-min-color-lightness"
).asNumber(50);
function createClassForColor(colorString: string | null) {
if (!colorString?.trim()) return "";
@@ -27,7 +28,7 @@ function createClassForColor(colorString: string | null) {
if (!registeredClasses.has(className)) {
const adjustedColor = adjustColorLightness(color, lightThemeColorMaxLightness!,
darkThemeColorMinLightness!);
darkThemeColorMinLightness!);
const hue = getHue(color);
$("head").append(`<style>
@@ -48,9 +49,9 @@ function createClassForColor(colorString: string | null) {
return clsx("use-note-color", className, colorsWithHue.has(className) && "with-hue");
}
function parseColor(color: string) {
export function parseColor(color: string) {
try {
return Color(color);
return Color(color.toLowerCase());
} catch (ex) {
console.error(ex);
}
@@ -76,7 +77,7 @@ function adjustColorLightness(color: ColorInstance, lightThemeMaxLightness: numb
}
/** Returns the hue of the specified color, or undefined if the color is grayscale. */
function getHue(color: ColorInstance) {
export function getHue(color: ColorInstance) {
const hslColor = color.hsl();
if (hslColor.saturationl() > 0) {
return hslColor.hue();
@@ -84,8 +85,8 @@ function getHue(color: ColorInstance) {
}
export function getReadableTextColor(bgColor: string) {
const colorInstance = Color(bgColor);
return colorInstance.isLight() ? "#000" : "#fff";
const colorInstance = parseColor(bgColor);
return !colorInstance || colorInstance?.isLight() ? "#000" : "#fff";
}
export default {

View File

@@ -1,5 +1,6 @@
import { t } from "./i18n";
import options from "./options";
import { isMobile } from "./utils";
export interface ExperimentalFeature {
id: string;
@@ -21,7 +22,7 @@ let enabledFeatures: Set<ExperimentalFeatureId> | null = null;
export function isExperimentalFeatureEnabled(featureId: ExperimentalFeatureId): boolean {
if (featureId === "new-layout") {
return options.is("newLayout");
return (isMobile() || options.is("newLayout"));
}
return getEnabledFeatures().has(featureId);
@@ -29,7 +30,7 @@ export function isExperimentalFeatureEnabled(featureId: ExperimentalFeatureId):
export function getEnabledExperimentalFeatureIds() {
const values = [ ...getEnabledFeatures().values() ];
if (options.is("newLayout")) {
if (isMobile() || options.is("newLayout")) {
values.push("new-layout");
}
return values;

View File

@@ -17,8 +17,7 @@ export const byNoteType: Record<Exclude<NoteType, "book">, string | null> = {
render: null,
search: null,
text: null,
webView: null,
aiChat: null
webView: null
};
export const byBookType: Record<ViewTypeOptions, string | null> = {

View File

@@ -1,4 +1,5 @@
import type { AttachmentRow, EtapiTokenRow, NoteType, OptionNames } from "@triliumnext/commons";
import type { AttributeType } from "../entities/fattribute.js";
import type { EntityChange } from "../server_types.js";
@@ -135,7 +136,14 @@ export default class LoadResults {
}
getBranchRows() {
return this.branchRows.map((row) => this.getEntityRow("branches", row.branchId)).filter((branch) => !!branch);
return this.branchRows.map((row) => {
const branch = this.getEntityRow("branches", row.branchId);
if (branch) {
// Merge the componentId from the tracked row with the entity data
return { ...branch, componentId: row.componentId };
}
return null;
}).filter((branch) => !!branch) as BranchRow[];
}
addNoteReordering(parentNoteId: string, componentId: string) {
@@ -153,7 +161,14 @@ export default class LoadResults {
getAttributeRows(componentId = "none"): AttributeRow[] {
return this.attributeRows
.filter((row) => row.componentId !== componentId)
.map((row) => this.getEntityRow("attributes", row.attributeId))
.map((row) => {
const attr = this.getEntityRow("attributes", row.attributeId);
if (attr) {
// Merge the componentId from the tracked row with the entity data
return { ...attr, componentId: row.componentId };
}
return null;
})
.filter((attr) => !!attr) as AttributeRow[];
}

View File

@@ -53,7 +53,6 @@ export const NOTE_TYPES: NoteTypeMapping[] = [
{ type: "file", title: t("note_types.file"), reserved: true },
{ type: "image", title: t("note_types.image"), reserved: true },
{ type: "launcher", mime: "", title: t("note_types.launcher"), reserved: true },
{ type: "aiChat", mime: "application/json", title: t("note_types.ai-chat"), reserved: true }
];
/** The maximum age in days for a template to be marked with the "New" badge */

View File

@@ -1,6 +1,8 @@
import utils from "./utils.js";
import Component from "../components/component.js";
import FNote from "../entities/fnote.js";
import options from "./options.js";
import server from "./server.js";
import utils from "./utils.js";
type ExecFunction = (command: string, cb: (err: string, stdout: string, stderror: string) => void) => void;
@@ -36,9 +38,14 @@ function download(url: string) {
}
}
export function downloadFileNote(noteId: string) {
const url = `${getFileUrl("notes", noteId)}?${Date.now()}`; // don't use cache
export function downloadFileNote(note: FNote, parentComponent: Component | null, ntxId: string | null | undefined) {
if (note.type === "file" && note.mime === "application/pdf" && parentComponent) {
// Special handling, manages its own downloading process.
parentComponent.triggerEvent("customDownload", { ntxId });
return;
}
const url = `${getFileUrl("notes", note.noteId)}?${Date.now()}`; // don't use cache
download(url);
}
@@ -97,7 +104,7 @@ async function openCustom(type: string, entityId: string, mime: string) {
// Note that the path separator must be \ instead of /
filePath = filePath.replace(/\//g, "\\");
}
const command = `rundll32.exe shell32.dll,OpenAs_RunDLL ` + filePath;
const command = `rundll32.exe shell32.dll,OpenAs_RunDLL ${filePath}`;
exec(command, (err, stdout, stderr) => {
if (err) {
console.error("Open Note custom: ", err);
@@ -131,10 +138,10 @@ export function getUrlForDownload(url: string) {
if (utils.isElectron()) {
// electron needs absolute URL, so we extract current host, port, protocol
return `${getHost()}/${url}`;
} else {
// web server can be deployed on subdomain, so we need to use a relative path
return url;
}
// web server can be deployed on subdomain, so we need to use a relative path
return url;
}
function canOpenInBrowser(mime: string) {

View File

@@ -85,13 +85,15 @@ async function remove<T>(url: string, componentId?: string) {
return await call<T>("DELETE", url, componentId);
}
async function upload(url: string, fileToUpload: File) {
async function upload(url: string, fileToUpload: File, componentId?: string) {
const formData = new FormData();
formData.append("upload", fileToUpload);
return await $.ajax({
url: window.glob.baseApiUrl + url,
headers: await getHeaders(),
headers: await getHeaders(componentId ? {
"trilium-component-id": componentId
} : undefined),
data: formData,
type: "PUT",
timeout: 60 * 60 * 1000,

View File

@@ -1,5 +1,6 @@
import { describe, expect, it, vi, beforeEach, afterEach } from "vitest";
import shortcuts, { keyMatches, matchesShortcut, isIMEComposing } from "./shortcuts.js";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import shortcuts, { isIMEComposing, keyMatches, matchesShortcut } from "./shortcuts.js";
// Mock utils module
vi.mock("./utils.js", () => ({
@@ -61,9 +62,10 @@ describe("shortcuts", () => {
});
describe("keyMatches", () => {
const createKeyboardEvent = (key: string, code?: string) => ({
const createKeyboardEvent = (key: string, code?: string, extraProps: Partial<KeyboardEvent> = {}) => ({
key,
code: code || `Key${key.toUpperCase()}`
code: code || `Key${key.toUpperCase()}`,
...extraProps
} as KeyboardEvent);
it("should match regular letter keys using key code", () => {
@@ -100,6 +102,26 @@ describe("shortcuts", () => {
expect(consoleSpy).toHaveBeenCalled();
consoleSpy.mockRestore();
});
it("should match azerty keys", () => {
const event = createKeyboardEvent("A", "KeyQ");
expect(keyMatches(event, "a")).toBe(true);
expect(keyMatches(event, "q")).toBe(false);
});
it("should match letter keys using code when key is a special character (macOS Alt behavior)", () => {
// On macOS, pressing Option/Alt + A produces 'å' as the key, but code is still 'KeyA'
const macOSAltAEvent = createKeyboardEvent("å", "KeyA", { altKey: true });
expect(keyMatches(macOSAltAEvent, "a")).toBe(true);
// Option + H produces '˙'
const macOSAltHEvent = createKeyboardEvent("˙", "KeyH", { altKey: true });
expect(keyMatches(macOSAltHEvent, "h")).toBe(true);
// Option + S produces 'ß'
const macOSAltSEvent = createKeyboardEvent("ß", "KeyS", { altKey: true });
expect(keyMatches(macOSAltSEvent, "s")).toBe(true);
});
});
describe("matchesShortcut", () => {
@@ -200,6 +222,42 @@ describe("shortcuts", () => {
expect(consoleSpy).toHaveBeenCalled();
consoleSpy.mockRestore();
});
it("matches azerty", () => {
const event = createKeyboardEvent({
key: "a",
code: "KeyQ",
ctrlKey: true
});
expect(matchesShortcut(event, "Ctrl+A")).toBe(true);
});
it("should match Alt+letter shortcuts on macOS where key is a special character", () => {
// On macOS, pressing Option/Alt + A produces 'å' but code remains 'KeyA'
const macOSAltAEvent = createKeyboardEvent({
key: "å",
code: "KeyA",
altKey: true
});
expect(matchesShortcut(macOSAltAEvent, "alt+a")).toBe(true);
// Option/Alt + H produces '˙'
const macOSAltHEvent = createKeyboardEvent({
key: "˙",
code: "KeyH",
altKey: true
});
expect(matchesShortcut(macOSAltHEvent, "alt+h")).toBe(true);
// Combined with Ctrl: Ctrl+Alt+S where Alt produces 'ß'
const macOSCtrlAltSEvent = createKeyboardEvent({
key: "ß",
code: "KeyS",
ctrlKey: true,
altKey: true
});
expect(matchesShortcut(macOSCtrlAltSEvent, "ctrl+alt+s")).toBe(true);
});
});
describe("bindGlobalShortcut", () => {

View File

@@ -213,7 +213,13 @@ export function keyMatches(e: KeyboardEvent, key: string): boolean {
}
// For letter keys, use the physical key code for consistency
// On macOS, Option/Alt key produces special characters, so we must use e.code
if (key.length === 1 && key >= 'a' && key <= 'z') {
if (e.altKey) {
// e.code is like "KeyA", "KeyB", etc.
const expectedCode = `Key${key.toUpperCase()}`;
return e.code === expectedCode || e.key.toLowerCase() === key.toLowerCase();
}
return e.key.toLowerCase() === key.toLowerCase();
}

View File

@@ -1,22 +1,30 @@
import type { SaveState } from "../components/note_context";
import { getErrorMessage } from "./utils";
type Callback = () => Promise<void> | void;
export type StateCallback = (state: SaveState) => void;
export default class SpacedUpdate {
private updater: Callback;
private lastUpdated: number;
private changed: boolean;
private updateInterval: number;
private changeForbidden?: boolean;
private stateCallback?: StateCallback;
constructor(updater: Callback, updateInterval = 1000) {
constructor(updater: Callback, updateInterval = 1000, stateCallback?: StateCallback) {
this.updater = updater;
this.lastUpdated = Date.now();
this.changed = false;
this.updateInterval = updateInterval;
this.stateCallback = stateCallback;
}
scheduleUpdate() {
if (!this.changeForbidden) {
this.changed = true;
this.stateCallback?.("unsaved");
setTimeout(() => this.triggerUpdate());
}
}
@@ -26,10 +34,13 @@ export default class SpacedUpdate {
this.changed = false; // optimistic...
try {
this.stateCallback?.("saving");
await this.updater();
this.stateCallback?.("saved");
} catch (e) {
this.changed = true;
this.stateCallback?.("error");
logError(getErrorMessage(e));
throw e;
}
}
@@ -59,15 +70,22 @@ export default class SpacedUpdate {
this.updateInterval = interval;
}
triggerUpdate() {
async triggerUpdate() {
if (!this.changed) {
return;
}
if (Date.now() - this.lastUpdated > this.updateInterval) {
this.updater();
this.stateCallback?.("saving");
try {
await this.updater();
this.stateCallback?.("saved");
this.changed = false;
} catch (e) {
this.stateCallback?.("error");
logError(getErrorMessage(e));
}
this.lastUpdated = Date.now();
this.changed = false;
} else {
// update isn't triggered but changes are still pending, so we need to schedule another check
this.scheduleUpdate();

View File

@@ -1,10 +1,11 @@
import { ensureMimeTypes, highlight, highlightAuto, loadTheme, Themes, type AutoHighlightResult, type HighlightResult, type Theme } from "@triliumnext/highlightjs";
import { MimeType } from "@triliumnext/commons";
import { type AutoHighlightResult, ensureMimeTypes, highlight, highlightAuto, type HighlightResult, loadTheme, type Theme,Themes } from "@triliumnext/highlightjs";
import { copyText, copyTextWithToast } from "./clipboard_ext.js";
import { t } from "./i18n.js";
import mime_types from "./mime_types.js";
import options from "./options.js";
import { t } from "./i18n.js";
import { copyText, copyTextWithToast } from "./clipboard_ext.js";
import { isShare } from "./utils.js";
import { MimeType } from "@triliumnext/commons";
let highlightingLoaded = false;
@@ -76,13 +77,15 @@ export async function applySingleBlockSyntaxHighlight($codeBlock: JQuery<HTMLEle
}
export async function ensureMimeTypesForHighlighting(mimeTypeHint?: string) {
if (highlightingLoaded) {
if (!mimeTypeHint && highlightingLoaded) {
return;
}
// Load theme.
const currentThemeName = String(options.get("codeBlockTheme"));
await loadHighlightingTheme(currentThemeName);
if (!highlightingLoaded) {
const currentThemeName = String(options.get("codeBlockTheme"));
await loadHighlightingTheme(currentThemeName);
}
// Load mime types.
let mimeTypes: MimeType[];
@@ -94,7 +97,7 @@ export async function ensureMimeTypesForHighlighting(mimeTypeHint?: string) {
enabled: true,
mime: mimeTypeHint.replace("-", "/")
}
]
];
} else {
mimeTypes = mime_types.getMimeTypes();
}
@@ -124,9 +127,9 @@ export function isSyntaxHighlightEnabled() {
if (!isShare) {
const theme = options.get("codeBlockTheme");
return !!theme && theme !== "none";
} else {
return true;
}
return true;
}
/**

View File

@@ -187,13 +187,15 @@ export function formatSize(size: number | null | undefined) {
return "";
}
size = Math.max(Math.round(size / 1024), 1);
if (size < 1024) {
return `${size} KiB`;
if (size === 0) {
return "0 B";
}
return `${Math.round(size / 102.4) / 10} MiB`;
const k = 1024;
const sizes = ["B", "KiB", "MiB", "GiB"];
const i = Math.floor(Math.log(size) / Math.log(k));
return `${Math.round((size / Math.pow(k, i)) * 100) / 100} ${sizes[i]}`;
}
function toObject<T, R>(array: T[], fn: (arg0: T) => [key: string, value: R]) {

View File

@@ -133,49 +133,6 @@ async function handleMessage(event: MessageEvent<any>) {
appContext.triggerEvent("apiLogMessages", { noteId: message.noteId, messages: message.messages });
} else if (message.type === "toast") {
toastService.showMessage(message.message);
} else if (message.type === "llm-stream") {
// ENHANCED LOGGING FOR DEBUGGING
console.log(`[WS-CLIENT] >>> RECEIVED LLM STREAM MESSAGE <<<`);
console.log(`[WS-CLIENT] Message details: sessionId=${message.sessionId}, hasContent=${!!message.content}, contentLength=${message.content ? message.content.length : 0}, hasThinking=${!!message.thinking}, hasToolExecution=${!!message.toolExecution}, isDone=${!!message.done}`);
if (message.content) {
console.log(`[WS-CLIENT] CONTENT PREVIEW: "${message.content.substring(0, 50)}..."`);
}
// Create the event with detailed logging
console.log(`[WS-CLIENT] Creating CustomEvent 'llm-stream-message'`);
const llmStreamEvent = new CustomEvent('llm-stream-message', { detail: message });
// Dispatch to multiple targets to ensure delivery
try {
console.log(`[WS-CLIENT] Dispatching event to window`);
window.dispatchEvent(llmStreamEvent);
console.log(`[WS-CLIENT] Event dispatched to window`);
// Also try document for completeness
console.log(`[WS-CLIENT] Dispatching event to document`);
document.dispatchEvent(new CustomEvent('llm-stream-message', { detail: message }));
console.log(`[WS-CLIENT] Event dispatched to document`);
} catch (err) {
console.error(`[WS-CLIENT] Error dispatching event:`, err);
}
// Debug current listeners (though we can't directly check for specific event listeners)
console.log(`[WS-CLIENT] Active event listeners should receive this message now`);
// Detailed logging based on message type
if (message.content) {
console.log(`[WS-CLIENT] Content message: ${message.content.length} chars`);
} else if (message.thinking) {
console.log(`[WS-CLIENT] Thinking update: "${message.thinking}"`);
} else if (message.toolExecution) {
console.log(`[WS-CLIENT] Tool execution: action=${message.toolExecution.action}, tool=${message.toolExecution.tool || 'unknown'}`);
if (message.toolExecution.result) {
console.log(`[WS-CLIENT] Tool result preview: "${String(message.toolExecution.result).substring(0, 50)}..."`);
}
} else if (message.done) {
console.log(`[WS-CLIENT] Completion signal received`);
}
} else if (message.type === "execute-script") {
// TODO: Remove after porting the file
// @ts-ignore

View File

@@ -1,450 +0,0 @@
/* LLM Chat Panel Styles */
.note-context-chat {
background-color: var(--main-background-color);
}
/* Message Styling */
.chat-message {
margin-bottom: 1rem;
}
.message-avatar {
width: 36px;
height: 36px;
border-radius: 50%;
font-size: 1.25rem;
flex-shrink: 0;
}
.user-avatar {
background-color: var(--input-background-color);
color: var(--cmd-button-icon-color);
}
.assistant-avatar {
background-color: var(--subtle-border-color, var(--main-border-color));
color: var(--hover-item-text-color);
}
.message-content {
max-width: calc(100% - 50px);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
color: var(--main-text-color);
}
.user-content {
border-radius: 0.5rem 0.5rem 0 0.5rem !important;
background-color: var(--input-background-color) !important;
}
.assistant-content {
border-radius: 0.5rem 0.5rem 0.5rem 0 !important;
background-color: var(--main-background-color);
border: 1px solid var(--subtle-border-color, var(--main-border-color));
}
/* Tool Execution Styling */
.tool-execution-info {
margin-top: 0.75rem;
margin-bottom: 1.5rem;
border: 1px solid var(--subtle-border-color);
border-radius: 0.5rem;
overflow: hidden;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
background-color: var(--main-background-color);
/* Add a subtle transition effect */
transition: all 0.2s ease-in-out;
}
.tool-execution-status {
background-color: var(--accented-background-color, rgba(0, 0, 0, 0.03)) !important;
border-radius: 0 !important;
padding: 0.5rem !important;
max-height: 250px !important;
overflow-y: auto;
}
.tool-execution-status .d-flex {
border-bottom: 1px solid var(--subtle-border-color);
padding-bottom: 0.5rem;
margin-bottom: 0.5rem;
}
.tool-step {
padding: 0.5rem;
margin-bottom: 0.75rem;
border-radius: 0.375rem;
background-color: var(--main-background-color);
border: 1px solid var(--subtle-border-color);
transition: background-color 0.2s ease;
}
.tool-step:hover {
background-color: rgba(0, 0, 0, 0.01);
}
.tool-step:last-child {
margin-bottom: 0;
}
/* Tool step specific styling */
.tool-step.executing {
background-color: rgba(0, 123, 255, 0.05);
border-color: rgba(0, 123, 255, 0.2);
}
.tool-step.result {
background-color: rgba(40, 167, 69, 0.05);
border-color: rgba(40, 167, 69, 0.2);
}
.tool-step.error {
background-color: rgba(220, 53, 69, 0.05);
border-color: rgba(220, 53, 69, 0.2);
}
/* Tool result formatting */
.tool-result pre {
margin: 0.5rem 0;
padding: 0.5rem;
background-color: rgba(0, 0, 0, 0.03);
border-radius: 0.25rem;
overflow: auto;
max-height: 300px;
}
.tool-result code {
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
font-size: 0.9em;
}
.tool-args code {
display: block;
padding: 0.5rem;
background-color: rgba(0, 0, 0, 0.03);
border-radius: 0.25rem;
margin-top: 0.25rem;
font-size: 0.85em;
color: var(--muted-text-color);
white-space: pre-wrap;
overflow: auto;
max-height: 100px;
}
/* Tool Execution in Chat Styling */
.chat-tool-execution {
padding: 0 0 0 36px; /* Aligned with message content, accounting for avatar width */
width: 100%;
margin-bottom: 1rem;
}
.tool-execution-container {
background-color: var(--accented-background-color, rgba(245, 247, 250, 0.7));
border: 1px solid var(--subtle-border-color);
border-radius: 0.375rem;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
overflow: hidden;
max-width: calc(100% - 20px);
transition: all 0.3s ease;
}
.tool-execution-container.collapsed {
display: none;
}
.tool-execution-header {
background-color: var(--main-background-color);
border-bottom: 1px solid var(--subtle-border-color);
margin-bottom: 0.5rem;
color: var(--muted-text-color);
font-weight: 500;
padding: 0.6rem 0.8rem;
cursor: pointer;
transition: background-color 0.2s ease;
}
.tool-execution-header:hover {
background-color: var(--hover-item-background-color, rgba(0, 0, 0, 0.03));
}
.tool-execution-toggle {
color: var(--muted-text-color) !important;
background: transparent !important;
padding: 0.2rem 0.4rem !important;
transition: transform 0.2s ease;
}
.tool-execution-toggle:hover {
color: var(--main-text-color) !important;
}
.tool-execution-toggle i.bx-chevron-down {
transform: rotate(0deg);
transition: transform 0.3s ease;
}
.tool-execution-toggle i.bx-chevron-right {
transform: rotate(-90deg);
transition: transform 0.3s ease;
}
.tool-execution-chat-steps {
padding: 0.5rem;
max-height: 300px;
overflow-y: auto;
}
/* Make error text more visible */
.text-danger {
color: #dc3545 !important;
}
/* Sources Styling */
.sources-container {
background-color: var(--accented-background-color, var(--main-background-color));
border-top: 1px solid var(--main-border-color);
color: var(--main-text-color);
}
.source-item {
transition: all 0.2s ease;
background-color: var(--main-background-color);
border-color: var(--subtle-border-color, var(--main-border-color)) !important;
}
.source-item:hover {
background-color: var(--link-hover-background, var(--hover-item-background-color));
}
.source-link {
color: var(--link-color, var(--hover-item-text-color));
text-decoration: none;
display: block;
width: 100%;
}
.source-link:hover {
color: var(--link-hover-color, var(--hover-item-text-color));
}
/* Input Area Styling */
.note-context-chat-form {
background-color: var(--main-background-color);
border-top: 1px solid var(--main-border-color);
}
.context-option-container {
padding: 0.5rem 0;
border-bottom: 1px solid var(--subtle-border-color, var(--main-border-color));
color: var(--main-text-color);
}
.chat-input-container {
padding-top: 0.5rem;
}
.note-context-chat-input {
border-color: var(--subtle-border-color, var(--main-border-color));
background-color: var(--input-background-color) !important;
color: var(--input-text-color) !important;
resize: none;
transition: all 0.2s ease;
min-height: 50px;
max-height: 150px;
}
.note-context-chat-input:focus {
border-color: var(--input-focus-outline-color, var(--main-border-color));
box-shadow: 0 0 0 0.25rem var(--input-focus-outline-color, rgba(13, 110, 253, 0.25));
}
.note-context-chat-send-button {
width: 40px;
height: 40px;
align-self: flex-end;
background-color: var(--cmd-button-background-color) !important;
color: var(--cmd-button-text-color) !important;
}
/* Loading Indicator */
.loading-indicator {
align-items: center;
justify-content: center;
padding: 1rem;
color: var(--muted-text-color);
}
/* Thinking display styles */
.llm-thinking-container {
margin: 1rem 0;
animation: fadeInUp 0.3s ease-out;
}
.thinking-bubble {
background-color: var(--accented-background-color, var(--main-background-color));
border: 1px solid var(--subtle-border-color, var(--main-border-color));
border-radius: 0.75rem;
padding: 0.75rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
position: relative;
overflow: hidden;
transition: all 0.2s ease;
}
.thinking-bubble:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.thinking-bubble::before {
content: '';
position: absolute;
top: 0;
inset-inline-start: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, var(--hover-item-background-color, rgba(0, 0, 0, 0.03)), transparent);
animation: shimmer 2s infinite;
opacity: 0.5;
}
.thinking-header {
cursor: pointer;
transition: all 0.2s ease;
border-radius: 0.375rem;
}
.thinking-header:hover {
background-color: var(--hover-item-background-color, rgba(0, 0, 0, 0.03));
padding: 0.25rem;
margin: -0.25rem;
}
.thinking-dots {
display: flex;
gap: 3px;
align-items: center;
}
.thinking-dots span {
width: 6px;
height: 6px;
background-color: var(--link-color, var(--hover-item-text-color));
border-radius: 50%;
animation: thinkingPulse 1.4s infinite ease-in-out;
}
.thinking-dots span:nth-child(1) {
animation-delay: -0.32s;
}
.thinking-dots span:nth-child(2) {
animation-delay: -0.16s;
}
.thinking-dots span:nth-child(3) {
animation-delay: 0s;
}
.thinking-label {
font-weight: 500;
color: var(--link-color, var(--hover-item-text-color)) !important;
}
.thinking-toggle {
color: var(--muted-text-color) !important;
transition: transform 0.2s ease;
background: transparent !important;
border: none !important;
}
.thinking-toggle:hover {
color: var(--main-text-color) !important;
}
.thinking-toggle.expanded {
transform: rotate(180deg);
}
.thinking-content {
margin-top: 0.75rem;
padding-top: 0.75rem;
border-top: 1px solid var(--subtle-border-color, var(--main-border-color));
animation: expandDown 0.3s ease-out;
}
.thinking-text {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
font-size: 0.875rem;
line-height: 1.5;
color: var(--main-text-color);
white-space: pre-wrap;
word-wrap: break-word;
background-color: var(--input-background-color);
padding: 0.75rem;
border-radius: 0.5rem;
border: 1px solid var(--subtle-border-color, var(--main-border-color));
max-height: 300px;
overflow-y: auto;
transition: border-color 0.2s ease;
}
.thinking-text:hover {
border-color: var(--main-border-color);
}
/* Animations */
@keyframes thinkingPulse {
0%, 80%, 100% {
transform: scale(0.8);
opacity: 0.6;
}
40% {
transform: scale(1);
opacity: 1;
}
}
@keyframes shimmer {
0% {
inset-inline-start: -100%;
}
100% {
inset-inline-start: 100%;
}
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes expandDown {
from {
opacity: 0;
max-height: 0;
}
to {
opacity: 1;
max-height: 300px;
}
}
/* Responsive adjustments */
@media (max-width: 768px) {
.thinking-bubble {
margin: 0.5rem 0;
padding: 0.5rem;
}
.thinking-text {
font-size: 0.8rem;
padding: 0.5rem;
max-height: 200px;
}
}

View File

@@ -28,7 +28,7 @@
--bs-body-color: var(--main-text-color) !important;
--bs-body-bg: var(--main-background-color) !important;
--ck-mention-list-max-height: 500px;
--tn-modal-max-height: 90vh;
--tn-modal-max-height: 90svh;
--tree-item-light-theme-max-color-lightness: 50;
--tree-item-dark-theme-min-color-lightness: 75;
@@ -111,6 +111,7 @@ body.mobile #root-widget.virtual-keyboard-opened #mobile-bottom-bar {
}
#mobile-bottom-bar {
border-top: 1px solid var(--main-border-color);
padding-bottom: var(--mobile-bottom-offset);
}
@@ -224,10 +225,6 @@ body.mobile .modal .modal-dialog {
width: 100%;
}
body.mobile .modal .modal-content {
border-radius: var(--bs-modal-border-radius) var(--bs-modal-border-radius) 0 0;
}
.component {
contain: size;
}
@@ -413,6 +410,7 @@ body.desktop .tabulator-popup-container,
.dropdown-menu.static {
box-shadow: unset;
backdrop-filter: unset !important;
}
.dropend .dropdown-toggle::after {
@@ -458,7 +456,7 @@ body.desktop .tabulator-popup-container,
visibility: hidden;
}
body.desktop .dropdown-menu:not(#context-menu-container) .dropdown-item,
.dropdown-menu:not(#context-menu-container) .dropdown-item,
body.desktop .dropdown-menu .dropdown-toggle,
body #context-menu-container .dropdown-item > span,
body.mobile .dropdown .dropdown-submenu > span {
@@ -466,6 +464,15 @@ body.mobile .dropdown .dropdown-submenu > span {
align-items: center;
}
body.mobile .dropdown .dropdown-submenu {
flex-wrap: wrap;
& > span {
flex-grow: 1;
}
}
.dropdown-item span.keyboard-shortcut,
.dropdown-item *:not(.keyboard-shortcut) > kbd {
flex-grow: 1;
@@ -1255,7 +1262,7 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href
inset-inline-start: 0;
inset-inline-end: 0;
bottom: 0;
z-index: 1000;
z-index: 2500;
background: rgba(0, 0, 0, 0.1);
}
@@ -1534,7 +1541,8 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
@media (max-width: 991px) {
body.mobile #launcher-pane .dropdown.global-menu > .dropdown-menu.show,
body.mobile #launcher-container .dropdown > .dropdown-menu.show {
body.mobile #launcher-container .dropdown > .dropdown-menu.show,
body.mobile .dropdown-menu.mobile-bottom-menu.show {
--dropdown-bottom: calc(var(--mobile-bottom-offset) + var(--launcher-pane-size));
position: fixed !important;
bottom: var(--dropdown-bottom) !important;
@@ -1546,6 +1554,16 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
max-height: calc(var(--tn-modal-max-height) - var(--dropdown-bottom));
}
body.mobile #launcher-container .dropdown > .dropdown-menu.show {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
body.mobile .dropdown-menu.mobile-bottom-menu.show {
--dropdown-bottom: 0px;
padding-bottom: calc(max(var(--menu-padding-size), env(safe-area-inset-bottom))) !important;
}
#mobile-sidebar-container {
position: fixed;
top: 0;
@@ -1614,6 +1632,7 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
body.mobile .modal-content {
overflow-y: auto;
border-radius: var(--bs-modal-border-radius) var(--bs-modal-border-radius) 0 0;
}
body.mobile .modal-footer {
@@ -1669,39 +1688,16 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
#detail-container {
background: var(--main-background-color);
}
}
@media (max-width: 991px) {
body.mobile.force-fixed-tree #mobile-sidebar-wrapper {
padding-top: 0;
position: static;
height: 40vh;
width: 100vw;
transform: none !important;
background-color: var(--left-pane-background-color) !important;
border-bottom: 0.5px solid var(--main-border-color);
}
body.mobile {
.modal-dialog {
margin: var(--bs-modal-margin);
max-width: 80%;
}
body.mobile.force-fixed-tree #mobile-sidebar-container {
display: none !important;
}
body.mobile.force-fixed-tree #mobile-sidebar-wrapper .quick-search {
display: none;
}
body.mobile.force-fixed-tree .component > button.bx-sidebar {
visibility: hidden;
padding: 0;
width: 6px;
}
body.mobile.force-fixed-tree #mobile-rest-container {
flex-direction: column !important;
}
body.mobile.force-fixed-tree #detail-container {
flex-grow: 1;
.modal-content {
height: 100%;
}
}
}
@@ -2617,14 +2613,14 @@ iframe.print-iframe {
}
}
#root-widget.virtual-keyboard-opened .note-split:not(:focus-within) {
#root-widget.virtual-keyboard-opened .note-split:not(.active) {
max-height: 80px;
opacity: 0.4;
}
}
}
body.desktop .title-row {
.title-row {
height: 50px;
min-height: 50px;
align-items: center;

View File

@@ -14,13 +14,13 @@
--row-moving-background-color: var(--accented-background-color);
--row-text-color: var(--main-text-color);
--row-delimiter-color: var(--more-accented-background-color);
--cell-horiz-padding-size: 8px;
--cell-vert-padding-size: 8px;
--cell-editable-hover-outline-color: var(--main-border-color);
--cell-read-only-text-color: var(--muted-text-color);
--cell-editing-border-color: var(--main-border-color);
--cell-editing-border-width: 2px;
--cell-editing-background-color: var(--ck-color-selector-focused-cell-background);
@@ -40,10 +40,42 @@
border-bottom: var(--col-header-bottom-border);
background: var(--col-header-background-color);
color: var(--col-header-text-color);
}
font-weight: normal;
.tabulator .tabulator-col-content {
padding: 8px 4px !important;
.tabulator-col.tabulator-range-highlight {
background: inherit;
color: inherit;
font-weight: bold;
}
.tabulator-col-content {
padding: 0 !important;
.tabulator-col-title-holder {
padding: 8px 4px;
}
&:has(.tabulator-header-filter) {
.tabulator-col-title-holder {
padding: 4px;
padding-bottom: 0;
}
}
.tabulator-header-filter {
background: var(--main-background-color);
padding: 2px 1px;
input {
background: var(--main-background-color);
color: var(--main-text-color);
border: 1px solid var(--button-border-color);
border-radius: 3px;
outline: none;
padding: 2px;
}
}
}
}
@media (hover: hover) and (pointer: fine) {
@@ -80,7 +112,6 @@
.tabulator-tableholder {
padding-top: 10px;
height: unset !important; /* Don't extend on the full height */
}
/* Rows */
@@ -99,6 +130,14 @@
border-top: none;
border-bottom: 1px solid var(--row-delimiter-color);
color: var(--row-text-color);
&:last-of-type {
border-bottom: none;
}
&.tabulator-range-highlight > .tabulator-cell.tabulator-frozen {
font-weight: bold;
}
}
.tabulator-row.tabulator-row-odd {
@@ -120,11 +159,14 @@
margin-inline-end: var(--cell-editing-border-width);
}
.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left,
.tabulator-row .tabulator-cell {
border-inline-end-color: transparent;
}
.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left {
border-inline-end-color: var(--main-border-color);
}
.tabulator-row .tabulator-cell:not(.tabulator-editable) {
color: var(--cell-read-only-text-color);
}
@@ -174,10 +216,6 @@
margin: 0;
}
.tabulator .tabulator-footer {
color: var(--main-text-color);
}
/* Context menus */
.tabulator-popup-container {
@@ -192,8 +230,27 @@
}
/* Footer */
:root .tabulator .tabulator-footer {
border-top: unset;
background: transparent;
color: var(--main-text-color);
border-top: 1px solid var(--main-border-color);
padding: 10px 0;
}
.tabulator-page {
background: var(--button-background-color);
color: var(--button-text-color);
border: 1px solid var(--button-border-color);
border-radius: var(--button-border-radius);
&:hover {
border-color: var(--hover-item-border-color);
color: var(--button-text-color);
}
}
select {
background: var(--button-background-color);
color: var(--input-text-color);
border: 1px solid var(--button-border-color);
}
}

View File

@@ -134,6 +134,7 @@
--left-pane-collapsed-border-color: #0009;
--left-pane-background-color: #1f1f1f;
--left-pane-text-color: #aaaaaa;
--left-pane-icon-color: #c5c5c5;
--left-pane-item-hover-background: #ffffff0d;
--left-pane-item-selected-background: #ffffff25;
--left-pane-item-selected-color: #dfdfdf;

View File

@@ -127,6 +127,7 @@
--left-pane-collapsed-border-color: #0000000d;
--left-pane-background-color: #f2f2f2;
--left-pane-text-color: #383838;
--left-pane-icon-color: currentColor;
--left-pane-item-hover-background: rgba(0, 0, 0, 0.032);
--left-pane-item-selected-background: white;
--left-pane-item-selected-color: black;

View File

@@ -17,6 +17,8 @@
*/
:root {
color-scheme: var(--theme-style);
--main-font-family: "Inter", sans-serif;
--main-font-size: normal;

View File

@@ -1,122 +0,0 @@
/* LLM Chat Launcher Widget Styles */
.note-context-chat {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
}
.note-context-chat-container {
flex-grow: 1;
overflow-y: auto;
padding: 15px;
}
.chat-message {
display: flex;
margin-bottom: 15px;
max-width: 85%;
}
.chat-message.user-message {
margin-inline-start: auto;
}
.chat-message.assistant-message {
margin-inline-end: auto;
}
.message-avatar {
width: 32px;
height: 32px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-inline-end: 8px;
}
.user-message .message-avatar {
background-color: var(--primary-color);
color: white;
}
.assistant-message .message-avatar {
background-color: var(--secondary-color);
color: white;
}
.message-content {
background-color: var(--more-accented-background-color);
border-radius: 12px;
padding: 10px 15px;
max-width: calc(100% - 40px);
}
.user-message .message-content {
background-color: var(--accented-background-color);
}
.message-content pre {
background-color: var(--code-background-color);
border-radius: 5px;
padding: 10px;
overflow-x: auto;
max-width: 100%;
}
.message-content code {
background-color: var(--code-background-color);
padding: 2px 4px;
border-radius: 3px;
}
.loading-indicator {
display: flex;
align-items: center;
margin: 10px 0;
color: var(--muted-text-color);
}
.sources-container {
background-color: var(--accented-background-color);
border-top: 1px solid var(--main-border-color);
padding: 8px;
}
.sources-list {
font-size: 0.9em;
}
.source-item {
padding: 4px 0;
}
.source-link {
color: var(--link-color);
text-decoration: none;
}
.source-link:hover {
text-decoration: underline;
}
.note-context-chat-form {
display: flex;
background-color: var(--main-background-color);
border-top: 1px solid var(--main-border-color);
padding: 10px;
}
.note-context-chat-input {
resize: vertical;
min-height: 44px;
max-height: 200px;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.chat-message {
max-width: 95%;
}
}

View File

@@ -47,9 +47,14 @@
}
/* The toolbar show / hide button for the current text block */
.ck.ck-block-toolbar-button {
:root .ck.ck-block-toolbar-button {
--ck-color-block-toolbar-button: var(--muted-text-color);
--ck-color-button-on-background: transparent;
--ck-color-button-on-color: currentColor;
--ck-color-button-on-color: var(--ck-editor-toolbar-button-on-color);
translate: -40% 0;
min-width: 0;
padding: 0;
z-index: 1600;
}
:root .ck.ck-toolbar .ck-button:not(.ck-disabled):active,
@@ -517,6 +522,10 @@ button.ck.ck-button:is(.ck-button-action, .ck-button-save, .ck-button-cancel).ck
* EDITOR'S CONTENT
*/
.note-detail-editable-text-editor > .ck-placeholder {
opacity: .5;
}
/*
* Code Blocks
*/

View File

@@ -57,12 +57,12 @@
height: 18px;
}
/*
/*
* SEARCH PAGE
*/
/* Button bar */
.search-definition-widget .search-setting-table tbody:last-child div {
.search-definition-widget .search-setting-table .search-actions-container {
justify-content: flex-end;
gap: 8px;
}
@@ -143,7 +143,7 @@
/*
* OPTIONS PAGES
*/
:root {
--options-card-min-width: 500px;
--options-card-max-width: 900px;
@@ -156,6 +156,10 @@
--preferred-max-content-width: var(--options-card-max-width);
}
.note-split.options .collection-properties {
visibility: hidden;
}
/* Create a gap at the top of the option pages */
.note-detail-content-widget-content.options>*:first-child {
margin-top: var(--options-first-item-top-margin, 1em);
@@ -331,4 +335,4 @@ nav.options-section-tabs + .options-section {
.etapi-options-section div {
height: auto !important;
}
}

View File

@@ -40,13 +40,30 @@ body.mobile {
/* #region Mica */
/* Quirk: --background-material is read before "theme-supports-background-effects" class
* is applied. Apply the matterial even if the theme doesn't support it. */
body.background-effects.platform-win32 {
/* Quirk: --background-material is read before "theme-supports-background-effects" class
* is applied. Apply the matterial even if the theme doesn't support it. */
--background-material: tabbed;
&.layout-vertical {
--background-material: mica;
}
&.layout-horizontal {
--background-material: tabbed;
}
}
body.background-effects.theme-supports-background-effects.platform-win32 {
body.background-effects.platform-darwin {
/** Reference: https://developer.apple.com/documentation/appkit/nsvisualeffectview?preferredLanguage=objc **/
&.layout-vertical {
--background-material: under-window;
}
&.layout-horizontal {
--background-material: hud;
}
}
body.background-effects.theme-supports-background-effects {
--launcher-pane-horiz-border-color: var(--launcher-pane-horiz-border-color-bgfx);
--launcher-pane-horiz-background-color: var(--launcher-pane-horiz-background-color-bgfx);
--launcher-pane-vert-background-color: var(--launcher-pane-vert-background-color-bgfx);
@@ -56,33 +73,29 @@ body.background-effects.theme-supports-background-effects.platform-win32 {
--root-background: transparent;
}
body.background-effects.platform-win32.layout-vertical {
--background-material: mica;
}
body.background-effects.theme-supports-background-effects.platform-win32.layout-vertical {
body.background-effects.theme-supports-background-effects.layout-vertical {
--left-pane-background-color: var(--window-background-color-bgfx);
--center-pane-background-color-bgfx: var(--center-pane-vert-layout-background-color-bgfx);
--right-pane-background-color: var(--right-pane-background-color-bgfx);
}
body.background-effects.theme-supports-background-effects.platform-win32.layout-horizontal {
body.background-effects.theme-supports-background-effects.layout-horizontal {
--center-pane-background-color-bgfx: var(--center-pane-horiz-layout-background-color-bgfx);
--gutter-color: var(--left-pane-background-color);
}
body.background-effects.theme-supports-background-effects.platform-win32,
body.background-effects.theme-supports-background-effects.platform-win32 #root-widget {
body.background-effects.theme-supports-background-effects,
body.background-effects.theme-supports-background-effects #root-widget {
background: var(--window-background-color-bgfx) !important;
}
body.background-effects.theme-supports-background-effects.platform-win32.layout-horizontal #horizontal-main-container,
body.background-effects.theme-supports-background-effects.platform-win32.layout-vertical #vertical-main-container {
body.background-effects.theme-supports-background-effects.layout-horizontal #horizontal-main-container,
body.background-effects.theme-supports-background-effects.layout-vertical #vertical-main-container {
background-color: var(--root-background);
}
/* Note split with background effects */
body.background-effects.theme-supports-background-effects.platform-win32 #center-pane .note-split.bgfx {
body.background-effects.theme-supports-background-effects #center-pane .note-split.bgfx {
--note-split-background-color: var(--center-pane-background-color-bgfx);
}
@@ -726,18 +739,12 @@ body[dir=rtl] #left-pane span.fancytree-node.protected > span.fancytree-custom-i
transform: translateX(-25%);
}
body.mobile .fancytree-expander::before,
body.mobile .fancytree-title,
body.mobile .fancytree-node > span {
font-size: 1rem !important;
}
@media (max-width: 991px) {
body.mobile #mobile-sidebar-container {
background-color: rgba(0, 0, 0, 0.5);
}
body.mobile:not(.force-fixed-tree) #mobile-sidebar-wrapper {
body.mobile #mobile-sidebar-wrapper {
border-top-right-radius: 12px;
border-bottom-right-radius: 12px;
border-inline-end: 1px solid var(--subtle-border-color);
@@ -756,9 +763,9 @@ body.mobile .fancytree-node > span {
#left-pane .fancytree-custom-icon {
margin-top: 0; /* Use this to align the icon with the tree view item's caption */
color: var(--custom-color, var(--left-pane-icon-color));
}
#left-pane span.fancytree-active .fancytree-title {
font-weight: normal;
}
@@ -767,7 +774,7 @@ body.mobile .fancytree-node > span {
background: var(--left-pane-item-hover-background);
}
#left-pane span.fancytree-node.shared .fancytree-title::after {
#left-pane .note-indicator-icon.shared-indicator {
opacity: 0.5;
}
@@ -1054,7 +1061,7 @@ body.layout-horizontal .tab-row-widget-container {
overflow: hidden;
}
body.desktop:not(.background-effects.platform-win32) #root-widget.horizontal-layout {
body.desktop:not(.background-effects) #root-widget.horizontal-layout {
background-color: var(--root-background) !important;
}
@@ -1259,8 +1266,16 @@ body.layout-horizontal #rest-pane > .classic-toolbar-widget {
#center-pane .note-split {
padding-top: 2px;
background-color: var(--note-split-background-color, var(--main-background-color));
transition: border-color 150ms ease-out;
border: 2px solid transparent;
}
/* The active split in a multi-split view */
#center-pane > .split-note-container-widget:has(> .note-split.visible ~ .note-split.visible) > .note-split.active {
border-color: var(--link-selection-outline-color);
}
body:not(.background-effects) #center-pane .note-split {
animation: note-entrance 100ms linear;
}
@@ -1301,7 +1316,7 @@ body.mobile .note-title {
margin-inline-start: 0;
}
.title-row {
body.desktop .title-row {
/* Aligns the "Create new split" button with the note menu button (the three dots button) */
padding-inline-end: 3px;
}

View File

@@ -148,29 +148,28 @@ span.fancytree-node.protected > span.fancytree-custom-icon {
filter: drop-shadow(2px 2px 2px var(--main-text-color));
}
span.fancytree-node.multiple-parents.shared .fancytree-title::after {
/* Note indicator icons (clone, shared) - real DOM elements for tooltip support */
.note-indicator-icon {
font-family: "boxicons" !important;
font-size: smaller;
content: " \eb3d\ec03";
margin-inline-start: 4px;
opacity: 0.8;
cursor: help;
}
span.fancytree-node.multiple-parents .fancytree-title::after {
font-family: "boxicons" !important;
font-size: smaller;
content: " \eb3d"; /* lookup code for "link-alt" in boxicons.css */
.note-indicator-icon.clone-indicator::before {
content: "\eb3d"; /* bx-link-alt */
}
body.experimental-feature-new-layout span.fancytree-node.multiple-parents .fancytree-title::after {
content: " \ed82";
.note-indicator-icon.shared-indicator::before {
content: "\ec03"; /* bx-share-alt */
}
body.experimental-feature-new-layout .note-indicator-icon.clone-indicator::before {
content: "\ed82";
opacity: 0.5;
}
span.fancytree-node.shared .fancytree-title::after {
font-family: "boxicons" !important;
font-size: smaller;
content: " \ec03"; /* lookup code for "share-alt" in boxicons.css */
}
span.fancytree-node.fancytree-active-clone:not(.fancytree-active) .fancytree-title {
font-weight: bold;
}
@@ -207,6 +206,7 @@ span.fancytree-selected .fancytree-title {
}
span.fancytree-selected .fancytree-custom-icon::before {
font-family: "boxicons";
content: "\eb43";
border: 1px solid var(--main-border-color);
border-radius: 3px;

View File

@@ -69,24 +69,6 @@ export function buildNote(noteDef: NoteDefinition) {
});
note.getBlob = async () => blob;
// Manage children.
if (noteDef.children) {
for (const childDef of noteDef.children) {
const childNote = buildNote(childDef);
const branchId = `${note.noteId}_${childNote.noteId}`;
const branch = new FBranch(froca, {
branchId,
noteId: childNote.noteId,
parentNoteId: note.noteId,
notePosition: childNotePosition,
fromSearchNote: false
});
froca.branches[branchId] = branch;
note.addChild(childNote.noteId, branchId, false);
childNotePosition += 10;
}
}
let position = 0;
for (const [ key, value ] of Object.entries(noteDef)) {
const attributeId = utils.randomString(12);
@@ -136,5 +118,25 @@ export function buildNote(noteDef: NoteDefinition) {
}
noteAttributeCache.attributes[note.noteId].push(attribute);
}
// Manage children.
if (noteDef.children) {
for (const childDef of noteDef.children) {
const childNote = buildNote(childDef);
const branchId = `${note.noteId}_${childNote.noteId}`;
const branch = new FBranch(froca, {
branchId,
noteId: childNote.noteId,
parentNoteId: note.noteId,
notePosition: childNotePosition,
fromSearchNote: false
});
froca.branches[branchId] = branch;
note.addChild(childNote.noteId, branchId, false);
childNote.addParent(note.noteId, branchId, false);
childNotePosition += 10;
}
}
return note;
}

File diff suppressed because it is too large Load Diff

View File

@@ -64,8 +64,7 @@
"restore_button": "Restaura",
"delete_button": "Suprimeix",
"download_button": "Descarrega",
"mime": "MIME: ",
"preview": "Vista prèvia:"
"mime": "MIME: "
},
"sort_child_notes": {
"title": "títol",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,73 +1,71 @@
{
"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"
}
"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}}'."
},
"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"
},
"about": {
"title": "About Trilium Notes"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,50 @@
{
"about": {
"title": "ट्रिलियम नोट्स के बारें में"
"title": "ट्रिलियम नोट्स के बारें में",
"build_date": "निर्माण की तारीख:",
"app_version": "ऐप वर्ज़न:",
"db_version": "DB वर्ज़न:",
"build_revision": "बिल्ड रिविज़न:"
},
"toast": {
"widget-error": {
"title": "एक विजेट को इनिशियलाइज़ करने में विफल रहा"
},
"bundle-error": {
"title": "एक कस्टम स्क्रिप्ट लोड करने में विफल रहा"
},
"widget-list-error": {
"title": "सर्वर से विजेट्स की सूची प्राप्त करने में विफल"
},
"open-script-note": "स्क्रिप्ट नोट खोलें"
},
"update_available": {
"update_available": "उपलब्ध अद्यतन"
},
"code_buttons": {
"execute_button_title": "स्क्रिप्ट एक्सीक्यूट करें",
"trilium_api_docs_button_title": "ट्रिलियम एपीआई डॉक्स खोलें",
"save_to_note_button_title": "नोट में सेव करें"
},
"hide_floating_buttons_button": {
"button_title": "बटन छुपाएं"
},
"show_floating_buttons_button": {
"button_title": "बटन दिखाएं"
},
"add_link": {
"note": "नोट"
},
"bulk_actions": {
"other": "अन्य"
},
"clone_to": {
"search_for_note_by_its_name": "नोट क नाम से नोट खोजें"
},
"confirm": {
"also_delete_note": "नोट भी डिलीट करें"
},
"delete_notes": {
"delete_notes_preview": "नोट्स प्रिव्यू डिलीट करें"
}
}

View File

@@ -21,7 +21,13 @@
},
"bundle-error": {
"title": "Nem sikerült betölteni az egyéni szkriptet",
"message": "A(z) \"{{id}}\" azonosítójú, \"{{title}}\" című jegyzetből származó szkript nem hajtható végre a következő ok miatt:\n\n{{message}}"
"message": "A skript nem hajtható végre a következő ok miatt:\n\n{{message}}"
},
"widget-list-error": {
"title": "A Widget-ek letöltése sikertelen volt"
},
"widget-render-error": {
"title": "Nem sikerült renderelni a React widget-et"
}
},
"add_link": {

View File

@@ -11,8 +11,8 @@
},
"toast": {
"critical-error": {
"title": "Kesalahan kritis",
"message": "Telah terjadi kesalahan kritis yang mencegah aplikasi klien untuk memulai:\n\n{{message}}\n\nHal ini kemungkinan besar disebabkan oleh skrip yang gagal secara tidak terduga. Coba jalankan aplikasi dalam mode aman dan atasi masalahnya."
"title": "Eror kritikal",
"message": "Telah terjadi eror kritikal yang mencegah aplikasi klien untuk memulai:\n\n{{message}}\n\nHal ini kemungkinan besar disebabkan oleh skrip yang gagal secara tidak terduga. Coba jalankan aplikasi dalam mode aman dan atasi masalahnya."
},
"widget-error": {
"title": "Gagal menginisialisasi widget",
@@ -21,12 +21,65 @@
},
"bundle-error": {
"title": "Gagal memuat skrip kustom",
"message": "Skrip dari catatan dengan ID \"{{id}}\", berjudul \"{{title}}\" tidak dapat dijalankan karena:\n\n{{message}}"
}
"message": "Skrip tidak dapat dijalankan:\n\n{{message}}"
},
"widget-list-error": {
"title": "Gagal mendapatkan daftar widget dari server"
},
"open-script-note": "Buka skrip catatan",
"widget-render-error": {
"title": "Gagal render widget React custom"
},
"widget-missing-parent": "Widget custom '{{property}}' tidak terdefinisi.\n\nJika skrip ini bermaksud untuk bisa dijalankan tanpa elemen UI, gunakanlah '#run=frontendStartup'.",
"scripting-error": "Skrip custom eror : {{title}}"
},
"add_link": {
"add_link": "Tambah tautan",
"help_on_links": "Bantuan pada tautan",
"note": "Catatan"
"note": "Catatan",
"search_note": "cari catatan berdasarkan nama",
"link_title_mirrors": "judul tautan mencerminkan judul catatan saat ini",
"link_title_arbitrary": "judul tautan dapat diubah secara bebas",
"link_title": "Judul tautan",
"button_add_link": "Tambah tautan"
},
"branch_prefix": {
"edit_branch_prefix_multiple": "Edit prefiks cabang untuk {{count}} cabang",
"help_on_tree_prefix": "Bantuan pada prefiks pohon catatan",
"prefix": "Prefiks: ",
"save": "Simpan",
"branch_prefix_saved": "Prefiks cabang telah disimpan.",
"branch_prefix_saved_multiple": "Prefix cabang telah disimpan pada {{count}} cabang.",
"affected_branches": "Cabang terdampak ({{count}}):"
},
"bulk_actions": {
"bulk_actions": "Aksi borongan",
"affected_notes": "Catatan terdampak",
"include_descendants": "Sertakan anakan dari catatan yang dipilih",
"available_actions": "Pilihan aksi",
"chosen_actions": "Aksi terpilih",
"execute_bulk_actions": "Eksekusi aksi borongan",
"bulk_actions_executed": "Aksi borongan telah di eksekusi dengan sukses.",
"none_yet": "Belum ada... tambahkan aksi dengan memilih salah satu dari aksi di atas.",
"labels": "Label-label"
},
"confirm": {
"cancel": "Batal",
"ok": "Oke",
"are_you_sure_remove_note": "Apakah anda yakin mau membuang catatan \"{{title}}\" dari peta relasi? ",
"if_you_dont_check": "Jika Anda tidak mencentang ini, catatan hanya akan dihapus dari peta relasi.",
"also_delete_note": "Hapus juga catatannya"
},
"delete_notes": {
"delete_notes_preview": "Hapus pratinjau catatan",
"close": "Tutup",
"delete_all_clones_description": "Hapus seluruh duplikat (bisa dikembalikan di menu revisi)",
"erase_notes_description": "Penghapusan normal hanya menandai catatan sebagai dihapus dan dapat dipulihkan (melalui dialog versi revisi) dalam jangka waktu tertentu. Mencentang opsi ini akan menghapus catatan secara permanen seketika dan catatan tidak akan bisa dipulihkan kembali.",
"erase_notes_warning": "Hapus catatan secara permanen (tidak bisa dikembalikan), termasuk semua duplikat. Aksi akan memaksa aplikasi untuk mengulang kembali.",
"notes_to_be_deleted": "Catatan-catatan berikut akan dihapuskan ({{notesCount}})",
"no_note_to_delete": "Tidak ada Catatan yang akan dihapus (hanya duplikat)."
},
"clone_to": {
"clone_notes_to": "Duplikat catatan ke…"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1,82 @@
{}
{
"about": {
"title": "Om Trilium Notes",
"app_version": "App versjon:",
"db_version": "DB versjon:",
"sync_version": "Synk versjon:",
"build_date": "Byggdato:",
"build_revision": "Bygg versjon:",
"data_directory": "Datamappe:",
"homepage": "Hjemmeside:"
},
"experimental_features": {
"new_layout_description": "Prøv det nye grensesnittet for et mer moderne utseende og forbedret brukervenlighet. Det må påregnes betydelige endringer i kommende versjoner."
},
"cpu_arch_warning": {
"recommendation": "For den beste brukeropplevelsen, vennligst last ned den tilpassede ARM64-versjonen av TriliumNext fra siden for utgivelser."
},
"zpetne_odkazy": {
"backlink_one": "{{count}} Tilbakelenke",
"backlink_other": "{{count}} Tilbakelenker"
},
"add_link": {
"note": "Notat"
},
"branch_prefix": {
"prefix": "Prefiks : ",
"save": "Lagre"
},
"bulk_actions": {
"labels": "Etiketter",
"relations": "Relasjoner",
"notes": "Notater",
"other": "Andre"
},
"confirm": {
"confirmation": "Bekreftelse",
"cancel": "Avbryt",
"ok": "OK"
},
"delete_notes": {
"close": "Lukk",
"cancel": "Avbryt",
"ok": "OK"
},
"export": {
"close": "Lukk",
"export": "Eksporter"
},
"note_type_chooser": {
"templates": "Maler"
},
"help": {
"title": "Hurtigveiledning",
"troubleshooting": "Feilsøking",
"other": "Andre"
},
"import": {
"options": "Alternativer",
"import": "Importer"
},
"include_note": {
"label_note": "Notat"
},
"prompt": {
"title": "Ledetekst",
"ok": "OK",
"defaultTitle": "Ledetekst"
},
"info": {
"closeButton": "Lukk",
"okButton": "OK"
},
"markdown_import": {
"import_button": "Importer"
},
"protected_session_password": {
"close_label": "Lukk"
},
"recent_changes": {
"undelete_link": "gjenopprett"
}
}

View File

@@ -12,7 +12,7 @@
"toast": {
"critical-error": {
"title": "Kritische Error",
"message": "Een kritieke fout heeft plaatsgevonden waardoor de cliënt zich aanmeldt vanaf het begin:\n\n84X\n\nDit is waarschijnlijk veroorzaakt door een script dat op een onverwachte manier faalt. Probeer de sollicitatie in veilige modus te starten en de kwestie aan te spreken."
"message": "Een kritieke fout heeft plaatsgevonden waardoor de applicatie niet kon opstarten:\n\n{{message}}\n\nDit is waarschijnlijk veroorzaakt door een onverwachte fout in een script. Probeer de applicatie op te starten in veilige modus en het probleem op te lossen."
},
"widget-error": {
"title": "Starten widget mislukt",
@@ -22,7 +22,16 @@
"bundle-error": {
"title": "Custom script laden mislukt",
"message": "Script van notitie met ID \"{{id}}\", getiteld \"{{title}}\" kon niet worden uitgevoerd vanwege:\n\n{{message}}"
}
},
"scripting-error": "Error met script: {{title}}",
"widget-list-error": {
"title": "Kon geen lijst met widgets ophalen van de server"
},
"widget-render-error": {
"title": "React-widget kon niet geladen worden"
},
"widget-missing-parent": "Widget heeft niet het verplichte '{{property}}'-veld gedefinieerd.\n\nAls dit script is bedoeld om zonder interface te draaien, gebruik dan in plaats daarvan '#run=frontendStartup'.",
"open-script-note": "Open scriptnotitie"
},
"add_link": {
"add_link": "Voeg link toe",
@@ -41,7 +50,8 @@
"help_on_tree_prefix": "Help bij boomvoorvoegsel",
"prefix": "Voorvoegsel: ",
"edit_branch_prefix_multiple": "Bewerk zijtakvoorvoegsel voor {{count}} zijtakken",
"branch_prefix_saved_multiple": "Vertakkingsvoorvoegsel opgeslagen voor {{count}} vertakkingen."
"branch_prefix_saved_multiple": "Vertakkingsvoorvoegsel opgeslagen voor {{count}} vertakkingen.",
"affected_branches": "Aangetaste takken ({{count}}):"
},
"bulk_actions": {
"bulk_actions": "Bulk acties",
@@ -54,7 +64,8 @@
"labels": "Labels",
"relations": "Relaties",
"notes": "Notities",
"other": "Andere"
"other": "Andere",
"include_descendants": "Tel afstammelingen van de geselecteerde notities mee"
},
"calendar": {
"april": "April",
@@ -78,5 +89,35 @@
},
"show_toc_widget_button": {
"show_toc": "Laat Inhoudsopgave zien"
},
"status_bar": {
"note_paths_one": "{{count}} pad",
"note_paths_other": "{{count}} paden",
"note_paths_title": "Notitiepaden",
"code_note_switcher": "Verander de taalmodus"
},
"attributes_panel": {
"title": "Notitie-attributen"
},
"right_pane": {
"empty_message": "Geen informatie voor deze notitie",
"empty_button": "Verberg dit paneel",
"toggle": "Schakel rechterpaneel in/uit",
"custom_widget_go_to_source": "Go naar de broncode"
},
"pdf": {
"attachments_one": "{{count}} bijlage",
"attachments_other": "{{count}} bijlagen",
"layers_one": "{{count}} laag",
"layers_other": "{{count}} lagen",
"pages_one": "{{count}} pagina",
"pages_other": "{{count}} pagina's",
"pages_alt": "Pagina {{pageNumber}}",
"pages_loading": "Laden..."
},
"clone_to": {
"clone_notes_to": "Kloon de notities naar...",
"help_on_links": "Hulp op links",
"notes_to_clone": "Notities om te klonen"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -271,7 +271,6 @@
"download_button": "Preuzmi",
"mime": "MIME: ",
"file_size": "Veličina datoteke:",
"preview": "Pregled:",
"preview_not_available": "Pregled nije dostupan za ovaj tip beleške."
},
"sort_child_notes": {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -69,7 +69,7 @@ declare namespace Fancytree {
debug(msg: any): void;
/** Expand (or collapse) all parent nodes. */
expandAll(flag?: boolean, options?: Object): void;
expandAll(flag?: boolean, options?: object): void;
/** [ext-filter] Dimm or hide whole branches.
* @returns {integer} count
@@ -221,6 +221,7 @@ declare namespace Fancytree {
branchId: string;
isProtected: boolean;
noteType: NoteType;
subtreeHidden: boolean;
}
interface FancytreeNewNode extends FancytreeNodeData {
@@ -369,7 +370,7 @@ declare namespace Fancytree {
* @param mode 'before', 'after', or 'child' (default='child')
* @param init NodeData (or simple title string)
*/
editCreateNode(mode?: string, init?: Object): void;
editCreateNode(mode?: string, init?: object): void;
/** [ext-edit] Stop inline editing.
*
@@ -526,7 +527,7 @@ declare namespace Fancytree {
*
* @param opts passed to `setExpanded()`. Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true}
*/
makeVisible(opts?: Object): JQueryPromise<any>;
makeVisible(opts?: object): JQueryPromise<any>;
/** Move this node to targetNode.
*
@@ -589,25 +590,25 @@ declare namespace Fancytree {
* @param effects animation options.
* @param options {topNode: null, effects: ..., parent: ...} this node will remain visible in any case, even if `this` is outside the scroll pane.
*/
scrollIntoView(effects?: boolean, options?: Object): JQueryPromise<any>;
scrollIntoView(effects?: boolean, options?: object): JQueryPromise<any>;
/**
* @param effects animation options.
* @param options {topNode: null, effects: ..., parent: ...} this node will remain visible in any case, even if `this` is outside the scroll pane.
*/
scrollIntoView(effects?: Object, options?: Object): JQueryPromise<any>;
scrollIntoView(effects?: object, options?: object): JQueryPromise<any>;
/**
* @param flag pass false to deactivate
* @param opts additional options. Defaults to {noEvents: false}
*/
setActive(flag?: boolean, opts?: Object): JQueryPromise<any>;
setActive(flag?: boolean, opts?: object): JQueryPromise<any>;
/**
* @param flag pass false to collapse.
* @param opts additional options. Defaults to {noAnimation:false, noEvents:false}
*/
setExpanded(flag?: boolean, opts?: Object): JQueryPromise<any>;
setExpanded(flag?: boolean, opts?: object): JQueryPromise<any>;
/**
* Set keyboard focus to this node.
@@ -1109,7 +1110,7 @@ declare namespace Fancytree {
/** class names added to the node markup (separate with space) */
extraClasses?: string | undefined;
/** all properties from will be copied to `node.data` */
data?: Object | undefined;
data?: object | undefined;
/** Will be added as title attribute of the node's icon span,thus enabling a tooltip. */
iconTooltip?: string | undefined;
@@ -1160,7 +1161,7 @@ declare namespace Fancytree {
escapeHtml(s: string): string;
getEventTarget(event: Event): Object;
getEventTarget(event: Event): object;
getEventTargetType(event: Event): string;
@@ -1179,7 +1180,7 @@ declare namespace Fancytree {
parseHtml($ul: JQuery): NodeData[];
/** Add Fancytree extension definition to the list of globally available extensions. */
registerExtension(definition: Object): void;
registerExtension(definition: object): void;
unescapeHtml(s: string): string;

121
apps/client/src/types-pdfjs.d.ts vendored Normal file
View File

@@ -0,0 +1,121 @@
type HistoryData = {
files: {
fingerprint: string;
page: number;
zoom: string;
scrollLeft: number;
scrollTop: number;
rotation: number;
sidebarView: number;
}[];
};
interface Window {
/**
* By default, pdf.js will try to store information about the opened PDFs such as zoom and scroll position in local storage.
* The Trilium alternative is to use attachments stored at note level.
* This variable represents the direct content used by the pdf.js viewer in its local storage key, but in plain JS object format.
* The variable must be set early at startup, before pdf.js fully initializes.
*/
TRILIUM_VIEW_HISTORY_STORE?: HistoryData;
/**
* If set to true, hides the pdf.js viewer default sidebar containing the outline, page navigation, etc.
* This needs to be set early in the main method.
*/
TRILIUM_HIDE_SIDEBAR?: boolean;
TRILIUM_NOTE_ID: string;
TRILIUM_NTX_ID: string | null | undefined;
}
interface PdfOutlineItem {
title: string;
level: number;
dest: unknown;
id: string;
items: PdfOutlineItem[];
}
interface WithContext {
ntxId: string;
noteId: string | null | undefined;
}
interface PdfDocumentModifiedMessage extends WithContext {
type: "pdfjs-viewer-document-modified";
}
interface PdfDocumentBlobResultMessage extends WithContext {
type: "pdfjs-viewer-blob";
data: Uint8Array<ArrayBufferLike>;
}
interface PdfSaveViewHistoryMessage extends WithContext {
type: "pdfjs-viewer-save-view-history";
data: string;
}
interface PdfViewerTocMessage {
type: "pdfjs-viewer-toc";
data: PdfOutlineItem[];
}
interface PdfViewerActiveHeadingMessage {
type: "pdfjs-viewer-active-heading";
headingId: string;
}
interface PdfViewerPageInfoMessage {
type: "pdfjs-viewer-page-info";
totalPages: number;
currentPage: number;
}
interface PdfViewerCurrentPageMessage {
type: "pdfjs-viewer-current-page";
currentPage: number;
}
interface PdfViewerThumbnailMessage {
type: "pdfjs-viewer-thumbnail";
pageNumber: number;
dataUrl: string;
}
interface PdfAttachment {
filename: string;
size: number;
}
interface PdfViewerAttachmentsMessage {
type: "pdfjs-viewer-attachments";
attachments: PdfAttachment[];
downloadAttachment?: (fileName: string) => void;
}
interface PdfLayer {
id: string;
name: string;
visible: boolean;
}
interface PdfViewerLayersMessage {
type: "pdfjs-viewer-layers";
layers: PdfLayer[];
toggleLayer?: (layerId: string, visible: boolean) => void;
}
type PdfMessageEvent = MessageEvent<
PdfDocumentModifiedMessage
| PdfSaveViewHistoryMessage
| PdfViewerTocMessage
| PdfViewerActiveHeadingMessage
| PdfViewerPageInfoMessage
| PdfViewerCurrentPageMessage
| PdfViewerThumbnailMessage
| PdfViewerAttachmentsMessage
| PdfViewerLayersMessage
| PdfDocumentBlobResultMessage
>;

View File

@@ -1,4 +1,4 @@
import { IconRegistry } from "@triliumnext/commons";
import { IconRegistry, Locale } from "@triliumnext/commons";
import appContext, { AppContext } from "./components/app_context";
import type FNote from "./entities/fnote";
@@ -47,14 +47,25 @@ interface CustomGlobals {
platform?: typeof process.platform;
linter: typeof lint;
hasNativeTitleBar: boolean;
hasBackgroundEffects: boolean;
isElectron: boolean;
isRtl: boolean;
iconRegistry: IconRegistry;
themeCssUrl: string;
themeUseNextAsBase?: "next" | "next-light" | "next-dark";
iconPackCss: string;
headingStyle: "plain" | "underline" | "markdown";
layoutOrientation: "vertical" | "horizontal";
currentLocale: Locale;
}
type RequireMethod = (moduleName: string) => any;
declare global {
interface Window {
$: JQueryStatic;
jQuery: JQueryStatic;
logError(message: string);
logInfo(message: string);

View File

@@ -0,0 +1,83 @@
.tn-backlinks-widget .backlinks-items {
list-style-type: none;
margin: 0;
padding: 0;
position: static;
width: unset;
> li {
--border-radius: 8px;
max-width: 600px;
padding: 10px 20px;
background: var(--card-background-color);
& + li {
margin-top: 2px;
}
&:first-child {
border-radius: var(--border-radius) var(--border-radius) 0 0;
}
&:last-child {
border-radius: 0 0 var(--border-radius) var(--border-radius);
}
/* Card header */
& > span:first-child {
display: block;
> span {
display: flex;
flex-wrap: wrap;
align-items: center;
/* Note path */
> small {
flex: 100%;
order: -1;
font-size: .65rem;
.note-path {
padding: 0;
}
}
/* Note icon */
> .tn-icon {
color: var(--menu-item-icon-color);
}
/* Note title */
> a {
margin-inline-start: 4px;
color: currentColor;
font-weight: 500;
}
}
}
/* Card content - excerpt */
.backlink-excerpt {
all: unset; /* TODO: Remove after disposing the old style from FloatingButtons.css */
display: block;
margin: 8px 0;
border-radius: 4px;
background: var(--quick-search-result-content-background);
padding: 8px;
font-size: .75rem;
a {
background: transparent;
color: var(--quick-search-result-highlight-color);
text-decoration: underline;
}
p {
margin: 0;
}
}
}
}

View File

@@ -1,3 +1,5 @@
import "./Backlinks.css";
import { BacklinkCountResponse, BacklinksResponse, SaveSqlConsoleResponse } from "@triliumnext/commons";
import { VNode } from "preact";
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "preact/hooks";
@@ -7,7 +9,6 @@ import Component from "../components/component";
import NoteContext from "../components/note_context";
import FNote from "../entities/fnote";
import attributes from "../services/attributes";
import { isExperimentalFeatureEnabled } from "../services/experimental_features";
import froca from "../services/froca";
import { t } from "../services/i18n";
import { copyImageReferenceToClipboard } from "../services/image";
@@ -55,21 +56,12 @@ export const DESKTOP_FLOATING_BUTTONS: FloatingButtonsList = [
OpenTriliumApiDocsButton,
SaveToNoteButton,
RelationMapButtons,
GeoMapButtons,
CopyImageReferenceButton,
ExportImageButtons,
InAppHelpButton,
Backlinks
];
export const MOBILE_FLOATING_BUTTONS: FloatingButtonsList = [
RefreshBackendLogButton,
EditButton,
RelationMapButtons,
ExportImageButtons,
Backlinks
];
/**
* Floating buttons that should be hidden in popup editor (Quick edit).
*/
@@ -99,9 +91,10 @@ function SwitchSplitOrientationButton({ note, isReadOnly, isDefaultViewMode }: F
/>;
}
function ToggleReadOnlyButton({ note, viewType, isDefaultViewMode }: FloatingButtonContext) {
function ToggleReadOnlyButton({ note, isDefaultViewMode }: FloatingButtonContext) {
const [ isReadOnly, setReadOnly ] = useNoteLabelBoolean(note, "readOnly");
const isEnabled = ([ "mermaid", "mindMap", "canvas" ].includes(note.type) || viewType === "geoMap")
const isSavedSqlite = note.isTriliumSqlite() && !note.isHiddenCompletely();
const isEnabled = ([ "mermaid", "mindMap", "canvas" ].includes(note.type) || isSavedSqlite)
&& note.isContentAvailable() && isDefaultViewMode;
return isEnabled && <FloatingButton
@@ -243,17 +236,6 @@ function RelationMapButtons({ note, isDefaultViewMode, triggerEvent }: FloatingB
);
}
function GeoMapButtons({ triggerEvent, viewType, isReadOnly }: FloatingButtonContext) {
const isEnabled = viewType === "geoMap" && !isReadOnly;
return isEnabled && (
<FloatingButton
icon="bx bx-plus-circle"
text={t("geo-map.create-child-note-title")}
onClick={() => triggerEvent("geoMapCreateChildNote")}
/>
);
}
function CopyImageReferenceButton({ note, isDefaultViewMode }: FloatingButtonContext) {
const hiddenImageCopyRef = useRef<HTMLDivElement>(null);
const isEnabled = (
@@ -305,7 +287,7 @@ function ExportImageButtons({ note, triggerEvent, isDefaultViewMode }: FloatingB
function InAppHelpButton({ note }: FloatingButtonContext) {
const helpUrl = getHelpUrlForNote(note);
const isEnabled = !!helpUrl;
const isEnabled = note.type !== "book" && !!helpUrl;
return isEnabled && (
<FloatingButton

View File

@@ -3,6 +3,30 @@
font-family: var(--detail-font-family);
font-size: var(--detail-font-size);
contain: none;
&.fixed-tree {
display: flex;
flex-direction: column;
height: 100%;
.fixed-note-tree-container {
height: 60%;
border-bottom: 1px solid var(--main-border-color);
overflow: auto;
.tree-wrapper {
padding: 0;
}
.tree {
padding: 0;
}
ul {
margin: 0;
}
}
}
}
body.prefers-centered-content .note-detail {
@@ -12,4 +36,4 @@ body.prefers-centered-content .note-detail {
.note-detail > * {
contain: none;
}
}

View File

@@ -1,5 +1,6 @@
import "./NoteDetail.css";
import clsx from "clsx";
import { isValidElement, VNode } from "preact";
import { useEffect, useRef, useState } from "preact/hooks";
@@ -12,8 +13,9 @@ import { t } from "../services/i18n";
import protected_session_holder from "../services/protected_session_holder";
import toast from "../services/toast.js";
import { dynamicRequire, isElectron, isMobile } from "../services/utils";
import NoteTreeWidget from "./note_tree";
import { ExtendedNoteType, TYPE_MAPPINGS, TypeWidget } from "./note_types";
import { useNoteContext, useTriliumEvent } from "./react/hooks";
import { useLegacyWidget, useNoteContext, useTriliumEvent } from "./react/hooks";
import { NoteListWithLinks } from "./react/NoteList";
import { TypeWidgetProps } from "./type_widgets/type_widget";
@@ -36,6 +38,7 @@ export default function NoteDetail() {
const [ noteTypesToRender, setNoteTypesToRender ] = useState<{ [ key in ExtendedNoteType ]?: (props: TypeWidgetProps) => VNode }>({});
const [ activeNoteType, setActiveNoteType ] = useState<ExtendedNoteType>();
const widgetRequestId = useRef(0);
const hasFixedTree = note && noteContext?.hoistedNoteId === "_lbMobileRoot" && isMobile() && note.noteId.startsWith("_lbMobile");
const props: TypeWidgetProps = {
note: note!,
@@ -119,13 +122,6 @@ export default function NoteDetail() {
}
});
// Fixed tree for launch bar config on mobile.
useEffect(() => {
if (!isMobile) return;
const hasFixedTree = noteContext?.hoistedNoteId === "_lbMobileRoot";
document.body.classList.toggle("force-fixed-tree", hasFixedTree);
}, [ note ]);
// Handle toast notifications.
useEffect(() => {
if (!isElectron()) return;
@@ -215,8 +211,13 @@ export default function NoteDetail() {
return (
<div
ref={containerRef}
class={`note-detail ${isFullHeight ? "full-height" : ""}`}
class={clsx("component note-detail", {
"full-height": isFullHeight,
"fixed-tree": hasFixedTree
})}
>
{hasFixedTree && <FixedTree noteContext={noteContext} />}
{Object.entries(noteTypesToRender).map(([ itemType, Element ]) => {
return <NoteDetailWrapper
Element={Element}
@@ -231,6 +232,11 @@ export default function NoteDetail() {
);
}
function FixedTree({ noteContext }: { noteContext: NoteContext }) {
const [ treeEl ] = useLegacyWidget(() => new NoteTreeWidget(), { noteContext });
return <div class="fixed-note-tree-container">{treeEl}</div>;
}
/**
* Wraps a single note type widget, in order to keep it in the DOM even after the user has switched away to another note type. This allows faster loading of the same note type again. The properties are cached, so that they are updated only
* while the widget is visible, to avoid rendering in the background. When not visible, the DOM element is simply hidden.
@@ -265,9 +271,13 @@ function useNoteInfo() {
const [ note, setNote ] = useState<FNote | null | undefined>();
const [ type, setType ] = useState<ExtendedNoteType>();
const [ mime, setMime ] = useState<string>();
const refreshIdRef = useRef(0);
function refresh() {
const refreshId = ++refreshIdRef.current;
getExtendedWidgetType(actualNote, noteContext).then(type => {
if (refreshId !== refreshIdRef.current) return;
setNote(actualNote);
setType(type);
setMime(actualNote?.mime);
@@ -318,6 +328,8 @@ export async function getExtendedWidgetType(note: FNote | null | undefined, note
resultingType = "noteMap";
} else if (type === "text" && (await noteContext?.isReadOnly())) {
resultingType = "readOnlyText";
} else if (note.isTriliumSqlite()) {
resultingType = "sqlConsole";
} else if ((type === "code" || type === "mermaid") && (await noteContext?.isReadOnly())) {
resultingType = "readOnlyCode";
} else if (type === "text") {
@@ -342,9 +354,8 @@ export function checkFullHeight(noteContext: NoteContext | undefined, type: Exte
// https://github.com/zadam/trilium/issues/2522
const isBackendNote = noteContext?.noteId === "_backendLog";
const isSqlNote = noteContext.note?.mime === "text/x-sqlite;schema=trilium";
const isFullHeightNoteType = type && TYPE_MAPPINGS[type].isFullHeight;
return (!noteContext?.hasNoteList() && isFullHeightNoteType && !isSqlNote)
return (!noteContext?.hasNoteList() && isFullHeightNoteType)
|| noteContext?.viewScope?.viewMode === "attachments"
|| isBackendNote;
}
@@ -358,8 +369,8 @@ function showToast(type: "printing" | "exporting_pdf", progress: number = 0) {
});
}
function handlePrintReport(printReport: PrintReport) {
if (printReport.type === "collection" && printReport.ignoredNoteIds.length > 0) {
function handlePrintReport(printReport?: PrintReport) {
if (printReport?.type === "collection" && printReport.ignoredNoteIds.length > 0) {
toast.showPersistent({
id: "print-report",
icon: "bx bx-collection",

View File

@@ -5,6 +5,7 @@ import clsx from "clsx";
import { ComponentChild, HTMLInputTypeAttribute, InputHTMLAttributes, MouseEventHandler, TargetedEvent, TargetedInputEvent } from "preact";
import { Dispatch, StateUpdater, useEffect, useRef, useState } from "preact/hooks";
import NoteContext from "../components/note_context";
import FAttribute from "../entities/fattribute";
import FNote from "../entities/fnote";
import { Attribute } from "../services/attribute_parser";
@@ -40,8 +41,8 @@ type OnChangeEventData = TargetedEvent<HTMLInputElement, Event> | InputEvent | J
type OnChangeListener = (e: OnChangeEventData) => Promise<void>;
export default function PromotedAttributes() {
const { note, componentId } = useNoteContext();
const [ cells, setCells ] = usePromotedAttributeData(note, componentId);
const { note, componentId, noteContext } = useNoteContext();
const [ cells, setCells ] = usePromotedAttributeData(note, componentId, noteContext);
return <PromotedAttributesContent note={note} componentId={componentId} cells={cells} setCells={setCells} />;
}
@@ -74,12 +75,12 @@ export function PromotedAttributesContent({ note, componentId, cells, setCells }
*
* The cells are returned as a state since they can also be altered internally if needed, for example to add a new empty cell.
*/
export function usePromotedAttributeData(note: FNote | null | undefined, componentId: string): [ Cell[] | undefined, Dispatch<StateUpdater<Cell[] | undefined>> ] {
export function usePromotedAttributeData(note: FNote | null | undefined, componentId: string, noteContext: NoteContext | undefined): [ Cell[] | undefined, Dispatch<StateUpdater<Cell[] | undefined>> ] {
const [ viewType ] = useNoteLabel(note, "viewType");
const [ cells, setCells ] = useState<Cell[]>();
function refresh() {
if (!note || viewType === "table") {
if (!note || viewType === "table" || noteContext?.viewScope?.viewMode !== "default") {
setCells([]);
return;
}
@@ -124,7 +125,7 @@ export function usePromotedAttributeData(note: FNote | null | undefined, compone
setCells(cells);
}
useEffect(refresh, [ note, viewType ]);
useEffect(refresh, [ note, viewType, noteContext ]);
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
if (loadResults.getAttributeRows(componentId).find((attr) => attributes.isAffecting(attr, note))) {
refresh();
@@ -217,6 +218,7 @@ function LabelInput({ inputId, ...props }: CellProps & { inputId: string }) {
id={inputId}
type={LABEL_MAPPINGS[definition.labelType ?? "text"]}
value={valueAttr.value}
checked={definition.labelType === "boolean" ? valueAttr.value === "true" : undefined}
placeholder={t("promoted_attributes.unset-field-placeholder")}
data-attribute-id={valueAttr.attributeId}
data-attribute-type={valueAttr.type}

View File

@@ -29,7 +29,6 @@ export default function GlobalMenu({ isHorizontalLayout }: { isHorizontalLayout:
const isVerticalLayout = !isHorizontalLayout;
const parentComponent = useContext(ParentComponent);
const { isUpdateAvailable, latestVersion } = useTriliumUpdateStatus();
const isMobileLocal = isMobile();
const logoRef = useRef<SVGSVGElement>(null);
useStaticTooltip(logoRef);
@@ -44,9 +43,12 @@ export default function GlobalMenu({ isHorizontalLayout }: { isHorizontalLayout:
</div>}
</>}
noDropdownListStyle
onShown={isMobileLocal ? () => document.getElementById("context-menu-cover")?.classList.add("show", "global-menu-cover") : undefined}
onHidden={isMobileLocal ? () => document.getElementById("context-menu-cover")?.classList.remove("show", "global-menu-cover") : undefined}
mobileBackdrop
>
{isMobile() && <>
<MenuItem command="searchNotes" icon="bx bx-search" text={t("global_menu.search_notes")} />
<FormDropdownDivider />
</>}
<MenuItem command="openNewWindow" icon="bx bx-window-open" text={t("global_menu.open_new_window")} />
<MenuItem command="showShareSubtree" icon="bx bx-share-alt" text={t("global_menu.show_shared_notes_subtree")} />
@@ -107,8 +109,7 @@ function BrowserOnlyOptions() {
function DevelopmentOptions({ dropStart }: { dropStart: boolean }) {
return <>
<FormDropdownDivider />
<FormListItem disabled>Development Options</FormListItem>
<FormListHeader text="Development Options" />
<FormDropdownSubmenu icon="bx bx-test-tube" title="Experimental features" dropStart={dropStart}>
{experimentalFeatures.map((feature) => (
<ExperimentalFeatureToggle key={feature.id} experimentalFeature={feature as ExperimentalFeature} />

View File

@@ -1,11 +1,17 @@
import clsx from "clsx";
import { t } from "../../services/i18n";
import options from "../../services/options";
import ActionButton from "../react/ActionButton";
import { useTriliumOptionBool } from "../react/hooks";
import { useState, useCallback } from "preact/hooks";
import { useTriliumEvent } from "../react/hooks";
export default function RightPaneToggle() {
const [ rightPaneVisible, setRightPaneVisible ] = useTriliumOptionBool("rightPaneVisible");
const [ rightPaneVisible, setRightPaneVisible ] = useState(options.is("rightPaneVisible"));
useTriliumEvent("toggleRightPane", useCallback(() => {
setRightPaneVisible(current => !current);
}, []));
return (
<ActionButton
@@ -15,7 +21,7 @@ export default function RightPaneToggle() {
)}
text={t("right_pane.toggle")}
icon="bx bx-sidebar"
onClick={() => setRightPaneVisible(!rightPaneVisible)}
triggerCommand="toggleRightPane"
/>
);
}

View File

@@ -1,7 +1,7 @@
.note-list-widget {
min-height: 0;
max-width: var(--max-content-width); /* Inherited from .note-split */
overflow: auto;
contain: none !important;
}
@@ -11,10 +11,6 @@ body.prefers-centered-content .note-list-widget:not(.full-height) {
margin-inline: auto;
}
.note-list-widget .note-list {
padding-block: 10px;
}
.note-list-widget.full-height,
.note-list-widget.full-height .note-list-widget-content {
height: 100%;
@@ -25,8 +21,12 @@ body.prefers-centered-content .note-list-widget:not(.full-height) {
}
/* #region Pagination */
.note-list-pager span.current-page {
text-decoration: underline;
font-weight: bold;
.note-list-pager {
font-size: 1rem;
span.current-page {
text-decoration: underline;
font-weight: bold;
}
}
/* #endregion */
/* #endregion */

View File

@@ -1,7 +1,7 @@
import "./NoteList.css";
import { WebSocketMessage } from "@triliumnext/commons";
import { VNode } from "preact";
import { Component, VNode } from "preact";
import { lazy, Suspense } from "preact/compat";
import { useEffect, useRef, useState } from "preact/hooks";
@@ -11,7 +11,8 @@ import froca from "../../services/froca";
import { subscribeToMessages, unsubscribeToMessage as unsubscribeFromMessage } from "../../services/ws";
import { useNoteContext, useNoteLabel, useNoteLabelBoolean, useNoteProperty, useTriliumEvent } from "../react/hooks";
import { allViewTypes, ViewModeMedia, ViewModeProps, ViewTypeOptions } from "./interface";
import ViewModeStorage from "./view_mode_storage";
import ViewModeStorage, { type ViewModeStorageType } from "./view_mode_storage";
interface NoteListProps {
note: FNote | null | undefined;
notePath: string | null | undefined;
@@ -119,7 +120,9 @@ export function CustomNoteList({ note, viewType, isEnabled: shouldEnable, notePa
}
const ComponentToRender = viewType && props && isEnabled && (
props.media === "print" ? ViewComponents[viewType].print : ViewComponents[viewType].normal
props.media === "print"
? ViewComponents[viewType].print ?? ViewComponents[viewType].normal
: ViewComponents[viewType].normal
);
return (
@@ -215,7 +218,7 @@ export function useNoteIds(note: FNote | null | undefined, viewType: ViewTypeOpt
return noteIds;
}
export function useViewModeConfig<T extends object>(note: FNote | null | undefined, viewType: ViewTypeOptions | undefined) {
export function useViewModeConfig<T extends object>(note: FNote | null | undefined, viewType: ViewModeStorageType | undefined) {
const [ viewConfig, setViewConfig ] = useState<{
config: T | undefined;
storeFn: (data: T) => void;

View File

@@ -2,25 +2,28 @@
position: relative;
height: 100%;
user-select: none;
overflow-x: auto;
display: flex;
flex-direction: column;
--card-font-size: 0.9em;
--card-line-height: 1.2;
--card-padding: 0.6em;
}
body.mobile .board-view {
scroll-snap-type: x mandatory;
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
}
.board-view-container {
height: 100%;
display: flex;
gap: 1em;
padding: 1em;
padding-inline: 12px;
padding-block: 4px;
align-items: flex-start;
overflow-x: auto;
}
body.mobile .board-view-container {
scroll-snap-type: x mandatory;
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
}
.board-view-container .board-column {
@@ -352,4 +355,4 @@ body.mobile .board-view-container .board-column {
font-size: 0.9em;
max-width: 200px;
word-wrap: break-word;
}
}

Some files were not shown because too many files have changed in this diff Show More