Compare commits

...

31 Commits

Author SHA1 Message Date
zadam
1f95e88cfd release 0.63.2-beta 2024-02-17 22:47:50 +01:00
zadam
15677f7178 Update README.md 2024-02-16 12:16:58 +01:00
zadam
3a0bb91b77 fix 2024-02-16 11:25:23 +01:00
zadam
157f894c9b Merge pull request #4642 from henrikx/patch-1
Fix ribbon tooltips getting stuck on the screen by setting a small delay before saving attributes in attributeeditor
2024-02-16 11:02:13 +01:00
zadam
e6dec701c0 Merge remote-tracking branch 'origin/master' 2024-02-16 10:42:30 +01:00
zadam
450b52f6da JSDoc improvements 2024-02-16 10:42:25 +01:00
zadam
4ef31eaf3d Merge pull request #4635 from WantToLearnJapanese/WantToLearnJapanese-patch-unhoist-bookmark
Fix showing unhoist confirm dialogue for bookmarked notes.
2024-02-16 06:48:04 +01:00
zadam
2d865576cf Merge remote-tracking branch 'origin/master' 2024-02-16 06:46:38 +01:00
zadam
41e623b009 fix JSDoc, closes #4633 2024-02-16 06:46:32 +01:00
zadam
239786e7d1 Merge pull request #4632 from bavis-m/master
Add the -o option to the groupmod command used in start-docker.sh
2024-02-16 06:40:38 +01:00
zadam
89e1e47900 Merge remote-tracking branch 'origin/master' 2024-02-14 07:21:36 +01:00
zadam
67cb926233 PWA manifest fixes for extra auth, fixes #4611 2024-02-14 07:21:31 +01:00
henrikx
2f813dfc5d Update attribute_editor.js 2024-02-09 10:58:41 +01:00
WantToLearnJapanese
a939599223 Fix showing unhoist confirm dialogue for bookmarked notes. 2024-02-02 16:36:54 +09:00
Mark
fb10e0ad33 Add the -o option to the groupmod command used in start-docker.sh when USER_GID is set, otherwise we won't be added to existing groups (e.g. you want node to run in the users (100) group) 2024-02-01 11:56:37 -08:00
zadam
46bd5bc1ef Update README.md 2024-01-29 22:36:52 +01:00
zadam
5abfb5c08a revert unintended license changes 2024-01-28 23:09:57 +01:00
zadam
9357caeb5a activate parent note when deleting a note, #4601 2024-01-28 23:08:44 +01:00
zadam
6b58e59819 added keyboard shortcut for toggling the right pane, closes #4552 2024-01-28 08:58:40 +01:00
zadam
c6df25ece8 fix pin button shadow, closes #4595 2024-01-28 08:36:16 +01:00
zadam
ebd6276b5e CKEditor 41.0.0 2024-01-27 23:02:11 +01:00
zadam
92e8b155e4 Merge branch 'stable'
# Conflicts:
#	package.json
#	src/services/build.js
#	src/services/migration.js
2024-01-27 22:52:47 +01:00
zadam
e76093e75c release 0.62.6 2024-01-21 23:49:23 +01:00
zadam
4f8073daa7 Revert "don't tag beta images with latest #4590"
This reverts commit 47fb96faa8.
2024-01-21 23:48:56 +01:00
zadam
47fb96faa8 don't tag beta images with latest #4590 2024-01-21 23:42:57 +01:00
zadam
6e33553146 fix migration 2024-01-21 23:11:27 +01:00
zadam
807941e6a5 disable scanning for links while migration is running #4535 2024-01-21 20:50:38 +01:00
zadam
1e30c0702e add indexes sooner in the migration process to speed it up #4535 2024-01-21 11:13:45 +01:00
zadam
69b686ba3b basic emoji #4119 2024-01-21 10:44:23 +01:00
zadam
ace5660809 add special characters to CKEditor build #4119 2024-01-21 10:33:16 +01:00
zadam
8bc99fd799 downgrades to try to fix flatpak build 2024-01-12 00:17:04 +01:00
29 changed files with 728 additions and 704 deletions

View File

@@ -643,7 +643,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU Affero General Public License for more details. GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.js.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
@@ -658,4 +658,4 @@ specific requirements.
You should also get your employer (if you work as a programmer) or school, You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary. if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.js.gnu.org/licenses/>. <http://www.gnu.org/licenses/>.

View File

@@ -1,8 +1,14 @@
# Trilium Notes # Trilium Notes
## Trilium is in maintenance mode - see details in https://github.com/zadam/trilium/issues/4620
Preliminary disccusions on the successor organization are taking place in [Trilium Next discussions](https://github.com/orgs/TriliumNext/discussions).
[![Join the chat at https://gitter.im/trilium-notes/Lobby](https://badges.gitter.im/trilium-notes/Lobby.svg)](https://gitter.im/trilium-notes/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md) [![Join the chat at https://gitter.im/trilium-notes/Lobby](https://badges.gitter.im/trilium-notes/Lobby.svg)](https://gitter.im/trilium-notes/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md)
Trilium Notes is a hierarchical note taking application with focus on building large personal knowledge bases. See [screenshots](https://github.com/zadam/trilium/wiki/Screenshot-tour) for quick overview: Trilium Notes is a hierarchical note taking application with focus on building large personal knowledge bases.
See [screenshots](https://github.com/zadam/trilium/wiki/Screenshot-tour) for quick overview:
<a href="https://github.com/zadam/trilium/wiki/Screenshot-tour"><img src="https://raw.githubusercontent.com/wiki/zadam/trilium/images/screenshot.png" alt="Trilium Screenshot" width="1000"></a> <a href="https://github.com/zadam/trilium/wiki/Screenshot-tour"><img src="https://raw.githubusercontent.com/wiki/zadam/trilium/images/screenshot.png" alt="Trilium Screenshot" width="1000"></a>

View File

@@ -8,3 +8,6 @@ CREATE TABLE IF NOT EXISTS "blobs" (
ALTER TABLE notes ADD blobId TEXT DEFAULT NULL; ALTER TABLE notes ADD blobId TEXT DEFAULT NULL;
ALTER TABLE note_revisions ADD blobId TEXT DEFAULT NULL; ALTER TABLE note_revisions ADD blobId TEXT DEFAULT NULL;
CREATE INDEX IF NOT EXISTS IDX_notes_blobId on notes (blobId);
CREATE INDEX IF NOT EXISTS IDX_note_revisions_blobId on note_revisions (blobId);

View File

@@ -21,5 +21,6 @@ CREATE INDEX `IDX_revisions_utcDateCreated` ON `revisions` (`utcDateCreated`);
CREATE INDEX `IDX_revisions_utcDateLastEdited` ON `revisions` (`utcDateLastEdited`); CREATE INDEX `IDX_revisions_utcDateLastEdited` ON `revisions` (`utcDateLastEdited`);
CREATE INDEX `IDX_revisions_dateCreated` ON `revisions` (`dateCreated`); CREATE INDEX `IDX_revisions_dateCreated` ON `revisions` (`dateCreated`);
CREATE INDEX `IDX_revisions_dateLastEdited` ON `revisions` (`dateLastEdited`); CREATE INDEX `IDX_revisions_dateLastEdited` ON `revisions` (`dateLastEdited`);
CREATE INDEX IF NOT EXISTS IDX_revisions_blobId on revisions (blobId);
UPDATE entity_changes SET entityName = 'revisions' WHERE entityName = 'note_revisions'; UPDATE entity_changes SET entityName = 'revisions' WHERE entityName = 'note_revisions';

View File

@@ -19,3 +19,5 @@ CREATE INDEX IDX_attachments_ownerId_role
CREATE INDEX IDX_attachments_utcDateScheduledForErasureSince CREATE INDEX IDX_attachments_utcDateScheduledForErasureSince
on attachments (utcDateScheduledForErasureSince); on attachments (utcDateScheduledForErasureSince);
CREATE INDEX IF NOT EXISTS IDX_attachments_blobId on attachments (blobId);

View File

@@ -5,8 +5,8 @@
} }
/* /*
* CKEditor 5 (v40.1.0) content styles. * CKEditor 5 (v41.0.0) content styles.
* Generated on Mon, 20 Nov 2023 08:41:49 GMT. * Generated on Fri, 26 Jan 2024 10:23:49 GMT.
* For more information, check out https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/content-styles.html * For more information, check out https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/content-styles.html
*/ */
@@ -42,18 +42,6 @@
overflow-wrap: break-word; overflow-wrap: break-word;
position: relative; position: relative;
} }
/* @ckeditor/ckeditor5-table/theme/tablecaption.css */
.ck-content .table > figcaption {
display: table-caption;
caption-side: top;
word-break: break-word;
text-align: center;
color: var(--ck-color-selector-caption-text);
background-color: var(--ck-color-selector-caption-background);
padding: .6em;
font-size: .75em;
outline-offset: -1px;
}
/* @ckeditor/ckeditor5-table/theme/table.css */ /* @ckeditor/ckeditor5-table/theme/table.css */
.ck-content .table { .ck-content .table {
margin: 0.9em auto; margin: 0.9em auto;
@@ -87,12 +75,17 @@
.ck-content[dir="ltr"] .table th { .ck-content[dir="ltr"] .table th {
text-align: left; text-align: left;
} }
/* @ckeditor/ckeditor5-media-embed/theme/mediaembed.css */ /* @ckeditor/ckeditor5-table/theme/tablecaption.css */
.ck-content .media { .ck-content .table > figcaption {
clear: both; display: table-caption;
margin: 0.9em 0; caption-side: top;
display: block; word-break: break-word;
min-width: 15em; text-align: center;
color: var(--ck-color-selector-caption-text);
background-color: var(--ck-color-selector-caption-background);
padding: .6em;
font-size: .75em;
outline-offset: -1px;
} }
/* @ckeditor/ckeditor5-page-break/theme/pagebreak.css */ /* @ckeditor/ckeditor5-page-break/theme/pagebreak.css */
.ck-content .page-break { .ck-content .page-break {
@@ -130,6 +123,13 @@
-ms-user-select: none; -ms-user-select: none;
user-select: none; user-select: none;
} }
/* @ckeditor/ckeditor5-media-embed/theme/mediaembed.css */
.ck-content .media {
clear: both;
margin: 0.9em 0;
display: block;
min-width: 15em;
}
/* @ckeditor/ckeditor5-list/theme/todolist.css */ /* @ckeditor/ckeditor5-list/theme/todolist.css */
.ck-content .todo-list { .ck-content .todo-list {
list-style: none; list-style: none;
@@ -280,6 +280,42 @@
.ck-editor__editable.ck-content .todo-list .todo-list__label.todo-list__label_without-description input[type=checkbox] { .ck-editor__editable.ck-content .todo-list .todo-list__label.todo-list__label_without-description input[type=checkbox] {
position: absolute; position: absolute;
} }
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol {
list-style-type: decimal;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol {
list-style-type: lower-latin;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol ol {
list-style-type: lower-roman;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol ol ol {
list-style-type: upper-latin;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol ol ol ol {
list-style-type: upper-roman;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul {
list-style-type: disc;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul ul {
list-style-type: circle;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul ul ul {
list-style-type: square;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul ul ul ul {
list-style-type: square;
}
/* @ckeditor/ckeditor5-image/theme/image.css */ /* @ckeditor/ckeditor5-image/theme/image.css */
.ck-content .image { .ck-content .image {
display: table; display: table;
@@ -318,17 +354,6 @@
flex-shrink: 1; flex-shrink: 1;
max-width: 100%; max-width: 100%;
} }
/* @ckeditor/ckeditor5-image/theme/imagecaption.css */
.ck-content .image > figcaption {
display: table-caption;
caption-side: bottom;
word-break: break-word;
color: var(--ck-color-image-caption-text);
background-color: var(--ck-color-image-caption-background);
padding: .6em;
font-size: .75em;
outline-offset: -1px;
}
/* @ckeditor/ckeditor5-image/theme/imageresize.css */ /* @ckeditor/ckeditor5-image/theme/imageresize.css */
.ck-content img.image_resized { .ck-content img.image_resized {
height: auto; height: auto;
@@ -347,67 +372,16 @@
.ck-content .image.image_resized > figcaption { .ck-content .image.image_resized > figcaption {
display: block; display: block;
} }
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */ /* @ckeditor/ckeditor5-image/theme/imagecaption.css */
.ck-content .marker-yellow { .ck-content .image > figcaption {
background-color: var(--ck-highlight-marker-yellow); display: table-caption;
} caption-side: bottom;
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */ word-break: break-word;
.ck-content .marker-green { color: var(--ck-color-image-caption-text);
background-color: var(--ck-highlight-marker-green); background-color: var(--ck-color-image-caption-background);
} padding: .6em;
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */ font-size: .75em;
.ck-content .marker-pink { outline-offset: -1px;
background-color: var(--ck-highlight-marker-pink);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-blue {
background-color: var(--ck-highlight-marker-blue);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .pen-red {
color: var(--ck-highlight-pen-red);
background-color: transparent;
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .pen-green {
color: var(--ck-highlight-pen-green);
background-color: transparent;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol {
list-style-type: decimal;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol {
list-style-type: lower-latin;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol ol {
list-style-type: lower-roman;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol ol ol {
list-style-type: upper-latin;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol ol ol ol {
list-style-type: upper-roman;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul {
list-style-type: disc;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul ul {
list-style-type: circle;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul ul ul {
list-style-type: square;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul ul ul ul {
list-style-type: square;
} }
/* @ckeditor/ckeditor5-image/theme/imagestyle.css */ /* @ckeditor/ckeditor5-image/theme/imagestyle.css */
.ck-content .image-style-block-align-left, .ck-content .image-style-block-align-left,
@@ -470,6 +444,32 @@
.ck-content .image-inline.image-style-align-right { .ck-content .image-inline.image-style-align-right {
margin-left: var(--ck-inline-image-style-spacing); margin-left: var(--ck-inline-image-style-spacing);
} }
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-yellow {
background-color: var(--ck-highlight-marker-yellow);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-green {
background-color: var(--ck-highlight-marker-green);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-pink {
background-color: var(--ck-highlight-marker-pink);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-blue {
background-color: var(--ck-highlight-marker-blue);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .pen-red {
color: var(--ck-highlight-pen-red);
background-color: transparent;
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .pen-green {
color: var(--ck-highlight-pen-green);
background-color: transparent;
}
/* @ckeditor/ckeditor5-block-quote/theme/blockquote.css */ /* @ckeditor/ckeditor5-block-quote/theme/blockquote.css */
.ck-content blockquote { .ck-content blockquote {
overflow: hidden; overflow: hidden;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1022
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
"name": "trilium", "name": "trilium",
"productName": "Trilium Notes", "productName": "Trilium Notes",
"description": "Trilium Notes", "description": "Trilium Notes",
"version": "0.63.1-beta", "version": "0.63.2-beta",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
"main": "electron.js", "main": "electron.js",
"bin": { "bin": {
@@ -41,7 +41,7 @@
"@excalidraw/excalidraw": "0.16.1", "@excalidraw/excalidraw": "0.16.1",
"archiver": "6.0.1", "archiver": "6.0.1",
"async-mutex": "0.4.0", "async-mutex": "0.4.0",
"axios": "1.6.5", "axios": "1.6.2",
"better-sqlite3": "8.4.0", "better-sqlite3": "8.4.0",
"boxicons": "2.1.4", "boxicons": "2.1.4",
"chokidar": "3.5.3", "chokidar": "3.5.3",
@@ -59,10 +59,10 @@
"escape-html": "1.0.3", "escape-html": "1.0.3",
"express": "4.18.2", "express": "4.18.2",
"express-partial-content": "1.0.2", "express-partial-content": "1.0.2",
"express-rate-limit": "7.1.5", "express-rate-limit": "7.1.4",
"express-session": "1.17.3", "express-session": "1.17.3",
"force-graph": "1.43.4", "force-graph": "1.43.4",
"fs-extra": "11.2.0", "fs-extra": "11.1.1",
"helmet": "7.1.0", "helmet": "7.1.0",
"html": "1.0.0", "html": "1.0.0",
"html2plaintext": "2.1.4", "html2plaintext": "2.1.4",
@@ -76,13 +76,13 @@
"joplin-turndown-plugin-gfm": "1.0.12", "joplin-turndown-plugin-gfm": "1.0.12",
"jquery": "3.7.1", "jquery": "3.7.1",
"jquery-hotkeys": "0.2.2", "jquery-hotkeys": "0.2.2",
"jsdom": "23.2.0", "jsdom": "22.1.0",
"katex": "0.16.9", "katex": "0.16.9",
"marked": "9.1.6", "marked": "9.1.6",
"mermaid": "10.6.1", "mermaid": "10.6.1",
"mime-types": "2.1.35", "mime-types": "2.1.35",
"multer": "1.4.5-lts.1", "multer": "1.4.5-lts.1",
"node-abi": "3.52.0", "node-abi": "3.51.0",
"normalize-strings": "1.1.1", "normalize-strings": "1.1.1",
"open": "8.4.1", "open": "8.4.1",
"panzoom": "9.4.3", "panzoom": "9.4.3",
@@ -106,31 +106,31 @@
"tree-kill": "1.2.2", "tree-kill": "1.2.2",
"turndown": "7.1.2", "turndown": "7.1.2",
"unescape": "1.0.1", "unescape": "1.0.1",
"ws": "8.16.0", "ws": "8.14.2",
"xml2js": "0.6.2", "xml2js": "0.6.2",
"yauzl": "2.10.0" "yauzl": "2.10.0"
}, },
"devDependencies": { "devDependencies": {
"cross-env": "7.0.3", "cross-env": "7.0.3",
"electron": "25.9.8", "electron": "25.9.8",
"electron-builder": "24.9.1", "electron-builder": "24.6.4",
"electron-packager": "17.1.2", "electron-packager": "17.1.2",
"electron-rebuild": "3.2.9", "electron-rebuild": "3.2.9",
"eslint": "8.56.0", "eslint": "8.54.0",
"eslint-config-airbnb-base": "15.0.0", "eslint-config-airbnb-base": "15.0.0",
"eslint-config-prettier": "9.1.0", "eslint-config-prettier": "9.0.0",
"eslint-plugin-import": "2.29.1", "eslint-plugin-import": "2.29.0",
"eslint-plugin-jsonc": "2.11.2", "eslint-plugin-jsonc": "2.10.0",
"eslint-plugin-prettier": "5.0.1", "eslint-plugin-prettier": "5.0.1",
"esm": "3.2.25", "esm": "3.2.25",
"husky": "8.0.3", "husky": "8.0.3",
"jasmine": "5.1.0", "jasmine": "5.1.0",
"jsdoc": "4.0.2", "jsdoc": "4.0.2",
"jsonc-eslint-parser": "2.4.0", "jsonc-eslint-parser": "2.4.0",
"lint-staged": "15.2.0", "lint-staged": "15.1.0",
"lorem-ipsum": "2.0.8", "lorem-ipsum": "2.0.8",
"nodemon": "3.0.2", "nodemon": "3.0.1",
"prettier": "3.1.1", "prettier": "3.1.0",
"rcedit": "4.0.1", "rcedit": "4.0.1",
"webpack": "5.89.0", "webpack": "5.89.0",
"webpack-cli": "5.1.4" "webpack-cli": "5.1.4"

View File

@@ -107,6 +107,13 @@ async function deleteNotes(branchIdsToDelete, forceDeleteAllClones = false) {
return false; return false;
} }
try {
await activateParentNotePath();
}
catch (e) {
console.error(e);
}
const taskId = utils.randomString(10); const taskId = utils.randomString(10);
let counter = 0; let counter = 0;
@@ -134,6 +141,16 @@ async function deleteNotes(branchIdsToDelete, forceDeleteAllClones = false) {
return true; return true;
} }
async function activateParentNotePath() {
// this is not perfect, maybe we should find the next/previous sibling, but that's more complex
const activeContext = appContext.tabManager.getActiveContext();
const parentNotePathArr = activeContext.notePathArray.slice(0, -1);
if (parentNotePathArr.length > 0) {
activeContext.setNote(parentNotePathArr.join("/"));
}
}
async function moveNodeUpInHierarchy(node) { async function moveNodeUpInHierarchy(node) {
if (hoistedNoteService.isHoistedNode(node) if (hoistedNoteService.isHoistedNode(node)
|| hoistedNoteService.isTopLevelNode(node) || hoistedNoteService.isTopLevelNode(node)

View File

@@ -48,11 +48,11 @@ async function checkNoteAccess(notePath, noteContext) {
const hoistedNoteId = noteContext.hoistedNoteId; const hoistedNoteId = noteContext.hoistedNoteId;
if (!resolvedNotePath.includes(hoistedNoteId) && !resolvedNotePath.includes('_hidden')) { if (!resolvedNotePath.includes(hoistedNoteId) && (!resolvedNotePath.includes('_hidden') || resolvedNotePath.includes('_lbBookmarks'))) {
const requestedNote = await froca.getNote(treeService.getNoteIdFromUrl(resolvedNotePath)); const requestedNote = await froca.getNote(treeService.getNoteIdFromUrl(resolvedNotePath));
const hoistedNote = await froca.getNote(hoistedNoteId); const hoistedNote = await froca.getNote(hoistedNoteId);
if (!hoistedNote.hasAncestor('_hidden') if ((!hoistedNote.hasAncestor('_hidden') || resolvedNotePath.includes('_lbBookmarks'))
&& !await dialogService.confirm(`Requested note '${requestedNote.title}' is outside of hoisted note '${hoistedNote.title}' subtree and you must unhoist to access the note. Do you want to proceed with unhoisting?`)) { && !await dialogService.confirm(`Requested note '${requestedNote.title}' is outside of hoisted note '${hoistedNote.title}' subtree and you must unhoist to access the note. Do you want to proceed with unhoisting?`)) {
return false; return false;
} }

View File

@@ -200,7 +200,7 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget {
this.attributeDetailWidget.hide(); this.attributeDetailWidget.hide();
}); });
this.$editor.on('blur', () => this.save()); this.$editor.on('blur', () => setTimeout(() => this.save(), 100)); // Timeout to fix https://github.com/zadam/trilium/issues/4160
this.$addNewAttributeButton = this.$widget.find('.add-new-attribute-button'); this.$addNewAttributeButton = this.$widget.find('.add-new-attribute-button');
this.$addNewAttributeButton.on('click', e => this.addNewAttribute(e)); this.$addNewAttributeButton.on('click', e => this.addNewAttribute(e));

View File

@@ -8,10 +8,13 @@ export default class RightPaneContainer extends FlexContainer {
this.id('right-pane'); this.id('right-pane');
this.css('height', '100%'); this.css('height', '100%');
this.collapsible(); this.collapsible();
this.rightPaneHidden = false;
} }
isEnabled() { isEnabled() {
return super.isEnabled() return super.isEnabled()
&& !this.rightPaneHidden
&& this.children.length > 0 && this.children.length > 0
&& !!this.children.find(ch => ch.isEnabled() && ch.canBeShown()); && !!this.children.find(ch => ch.isEnabled() && ch.canBeShown());
} }
@@ -44,4 +47,10 @@ export default class RightPaneContainer extends FlexContainer {
splitService.setupRightPaneResizer(); splitService.setupRightPaneResizer();
} }
} }
toggleRightPaneEvent() {
this.rightPaneHidden = !this.rightPaneHidden;
this.reEvaluateRightPaneVisibilityCommand();
}
} }

View File

@@ -1091,7 +1091,9 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
return; return;
} }
const nodeCtx = this.#getActiveNodeCtx(); const activeNode = this.getActiveNode();
const activeNodeFocused = activeNode?.hasFocus();
const activeNotePath = activeNode ? treeService.getNotePath(activeNode) : null;
const refreshCtx = { const refreshCtx = {
noteIdsToUpdate: new Set(), noteIdsToUpdate: new Set(),
@@ -1108,7 +1110,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
await this.#executeTreeUpdates(refreshCtx, loadResults); await this.#executeTreeUpdates(refreshCtx, loadResults);
await this.#setActiveNode(nodeCtx, movedActiveNode, parentsOfAddedNodes); await this.#setActiveNode(activeNotePath, activeNodeFocused, movedActiveNode, parentsOfAddedNodes);
if (refreshCtx.noteIdsToReload.size > 0 || refreshCtx.noteIdsToUpdate.size > 0) { if (refreshCtx.noteIdsToReload.size > 0 || refreshCtx.noteIdsToUpdate.size > 0) {
// workaround for https://github.com/mar10/fancytree/issues/1054 // workaround for https://github.com/mar10/fancytree/issues/1054
@@ -1257,73 +1259,42 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
} }
} }
#getActiveNodeCtx() { async #setActiveNode(activeNotePath, activeNodeFocused, movedActiveNode, parentsOfAddedNodes) {
const nodeCtx = {
activeNotePath: null,
activeNodeFocused: null,
nextNotePath: null
};
const activeNode = this.getActiveNode();
nodeCtx.activeNodeFocused = activeNode?.hasFocus();
nodeCtx.activeNotePath = activeNode ? treeService.getNotePath(activeNode) : null;
const nextNode = activeNode ? (activeNode.getNextSibling() || activeNode.getPrevSibling() || activeNode.getParent()) : null;
nodeCtx.nextNotePath = nextNode ? treeService.getNotePath(nextNode) : null;
return nodeCtx;
}
async #setActiveNode(nodeCtx, movedActiveNode, parentsOfAddedNodes) {
if (movedActiveNode) { if (movedActiveNode) {
for (const parentNode of parentsOfAddedNodes) { for (const parentNode of parentsOfAddedNodes) {
const foundNode = (parentNode.getChildren() || []).find(child => child.data.noteId === movedActiveNode.data.noteId); const foundNode = (parentNode.getChildren() || []).find(child => child.data.noteId === movedActiveNode.data.noteId);
if (foundNode) { if (foundNode) {
nodeCtx.activeNotePath = treeService.getNotePath(foundNode); activeNotePath = treeService.getNotePath(foundNode);
break; break;
} }
} }
} }
if (!nodeCtx.activeNotePath) { if (!activeNotePath) {
return; return;
} }
let node = await this.expandToNote(nodeCtx.activeNotePath, false); let node = await this.expandToNote(activeNotePath, false);
if (node && node.data.noteId !== treeService.getNoteIdFromUrl(nodeCtx.activeNotePath)) {
if (node && node.data.noteId !== treeService.getNoteIdFromUrl(activeNotePath)) {
// if the active note has been moved elsewhere then it won't be found by the path, // if the active note has been moved elsewhere then it won't be found by the path,
// so we switch to the alternative of trying to find it by noteId // so we switch to the alternative of trying to find it by noteId
const notesById = this.getNodesByNoteId(treeService.getNoteIdFromUrl(nodeCtx.activeNotePath)); const notesById = this.getNodesByNoteId(treeService.getNoteIdFromUrl(activeNotePath));
// if there are multiple clones, then we'd rather not activate anyone // if there are multiple clones, then we'd rather not activate anyone
node = notesById.length === 1 ? notesById[0] : null; node = notesById.length === 1 ? notesById[0] : null;
} }
if (node) { if (!node) {
if (nodeCtx.activeNodeFocused) { return;
}
if (activeNodeFocused) {
// needed by Firefox: https://github.com/zadam/trilium/issues/1865 // needed by Firefox: https://github.com/zadam/trilium/issues/1865
this.tree.$container.focus(); this.tree.$container.focus();
} }
await node.setActive(true, {noEvents: true, noFocus: !nodeCtx.activeNodeFocused}); await node.setActive(true, {noEvents: true, noFocus: !activeNodeFocused});
} else {
// this is used when the original note has been deleted, and we want to move the focus to the note above/below
node = await this.expandToNote(nodeCtx.nextNotePath, false);
if (node) {
// FIXME: this is conceptually wrong
// here note tree is responsible for updating global state of the application
// this should be done by NoteContext / TabManager and note tree should only listen to
// changes in active note and just set the "active" state
// We don't await since that can bring up infinite cycles when e.g. custom widget does some backend requests which wait for max sync ID processed
appContext.tabManager.getActiveContext().setNote(nodeCtx.nextNotePath).then(() => {
const newActiveNode = this.getActiveNode();
// return focus if the previously active node was also focused
if (newActiveNode && nodeCtx.activeNodeFocused) {
newActiveNode.setFocus(true);
}
});
}
}
} }
sortChildren(node) { sortChildren(node) {

View File

@@ -30,9 +30,14 @@ const TPL = `
height: 40px; height: 40px;
width: 40px; width: 40px;
} }
.title-bar-buttons .top-btn.active{ .title-bar-buttons .top-btn.active{
background-color:var(--accented-background-color); background-color:var(--accented-background-color);
} }
.title-bar-buttons .btn.focus, .title-bar-buttons .btn:focus {
box-shadow: none;
}
</style> </style>
<!-- divs act as a hitbox for the buttons, making them clickable on corners --> <!-- divs act as a hitbox for the buttons, making them clickable on corners -->

View File

@@ -18,6 +18,8 @@ const TPL = `
<h5>Highlights List visibility</h5> <h5>Highlights List visibility</h5>
<p>You can hide the highlights widget per-note by adding a <code>#hideHighlightWidget</code> label.</p> <p>You can hide the highlights widget per-note by adding a <code>#hideHighlightWidget</code> label.</p>
<p>You can configure a keyboard shortcut for quickly toggling the right pane (including Highlights) in the Options -> Shortcuts (name "toggleRightPane").</p>
</div>`; </div>`;
export default class HighlightsListOptions extends OptionsWidget { export default class HighlightsListOptions extends OptionsWidget {

View File

@@ -11,6 +11,8 @@ const TPL = `
</div> </div>
<p>You can also use this option to effectively disable TOC by setting a very high number.</p> <p>You can also use this option to effectively disable TOC by setting a very high number.</p>
<p>You can configure a keyboard shortcut for quickly toggling the right pane (including TOC) in the Options -> Shortcuts (name "toggleRightPane").</p>
</div>`; </div>`;
export default class TableOfContentsOptions extends OptionsWidget { export default class TableOfContentsOptions extends OptionsWidget {

View File

@@ -9,14 +9,9 @@
"start_url": "/", "start_url": "/",
"icons": [ "icons": [
{ {
"src": "/assets/vX/images/app-icons/ios/apple-touch-icon.png", "src": "favicon.ico",
"sizes": "180x180", "sizes": "180x180 512x512",
"type": "image/png" "type": "image/x-icon"
},
{
"src": "/assets/vX/images/app-icons/png/512x512.png",
"sizes": "512x512",
"type": "image/png"
} }
] ]
} }

View File

@@ -3,6 +3,7 @@ body {
--ck-color-base-text: var(--main-text-color); --ck-color-base-text: var(--main-text-color);
--ck-color-base-foreground: var(--accented-background-color); --ck-color-base-foreground: var(--accented-background-color);
--ck-color-base-background: var(--main-background-color);
--ck-color-focus-border: var(--main-border-color); --ck-color-focus-border: var(--main-border-color);
--ck-color-text: var(--main-text-color); --ck-color-text: var(--main-text-color);
--ck-color-shadow-drop: var(--main-background-color); --ck-color-shadow-drop: var(--main-background-color);

View File

@@ -43,12 +43,16 @@ const optionsService = require('./options.js');
*/ */
function BackendScriptApi(currentNote, apiParams) { function BackendScriptApi(currentNote, apiParams) {
/** /**
* Note where the script started executing * Note where the script started executing (entrypoint).
* As an analogy, in C this would be the file which contains the main() function of the current process.
* @type {BNote} * @type {BNote}
*/ */
this.startNote = apiParams.startNote; this.startNote = apiParams.startNote;
/** /**
* Note where the script is currently executing. Don't mix this up with the concept of active note * Note where the script is currently executing. This comes into play when your script is spread in multiple code
* notes, the script starts in "startNote", but then through function calls may jump into another note (currentNote).
* A similar concept in C would be __FILE__
* Don't mix this up with the concept of active note.
* @type {BNote} * @type {BNote}
*/ */
this.currentNote = currentNote; this.currentNote = currentNote;
@@ -288,7 +292,7 @@ function BackendScriptApi(currentNote, apiParams) {
* @param {string} params.parentNoteId * @param {string} params.parentNoteId
* @param {string} params.title * @param {string} params.title
* @param {string|Buffer} params.content * @param {string|Buffer} params.content
* @param {NoteType} params.type - text, code, file, image, search, book, relationMap, canvas * @param {NoteType} params.type - text, code, file, image, search, book, relationMap, canvas, webView
* @param {string} [params.mime] - value is derived from default mimes for type * @param {string} [params.mime] - value is derived from default mimes for type
* @param {boolean} [params.isProtected=false] * @param {boolean} [params.isProtected=false]
* @param {boolean} [params.isExpanded=false] * @param {boolean} [params.isExpanded=false]

View File

@@ -1 +1 @@
module.exports = { buildDate:"2024-01-12T00:02:50+01:00", buildRevision: "17e063f01d3b6c7a601630feaa96191d26095650" }; module.exports = { buildDate:"2024-02-17T22:47:50+01:00", buildRevision: "15677f71785fd81298b94df70855233d1578629c" };

View File

@@ -48,6 +48,14 @@ function isEntityEventsDisabled() {
return !!namespace.get('disableEntityEvents'); return !!namespace.get('disableEntityEvents');
} }
function setMigrationRunning(running) {
namespace.set('migrationRunning', !!running);
}
function isMigrationRunning() {
return !!namespace.get('migrationRunning');
}
function disableSlowQueryLogging(disable) { function disableSlowQueryLogging(disable) {
namespace.set('disableSlowQueryLogging', disable); namespace.set('disableSlowQueryLogging', disable);
} }
@@ -102,5 +110,7 @@ module.exports = {
putEntityChange, putEntityChange,
ignoreEntityChangeIds, ignoreEntityChangeIds,
disableSlowQueryLogging, disableSlowQueryLogging,
isSlowQueryLoggingDisabled isSlowQueryLoggingDisabled,
setMigrationRunning,
isMigrationRunning
}; };

View File

@@ -494,9 +494,16 @@ const DEFAULT_KEYBOARD_ACTIONS = [
separator: "Other" separator: "Other"
}, },
{
actionName: "toggleRightPane",
defaultShortcuts: [],
description: "Toggle the display of the right pane, which includes Table of Contents and Highlights",
scope: "window"
},
{ {
actionName: "printActiveNote", actionName: "printActiveNote",
defaultShortcuts: [], defaultShortcuts: [],
description: "Print active note",
scope: "window" scope: "window"
}, },
{ {

View File

@@ -5,12 +5,13 @@ const log = require('./log.js');
const utils = require('./utils.js'); const utils = require('./utils.js');
const resourceDir = require('./resource_dir.js'); const resourceDir = require('./resource_dir.js');
const appInfo = require('./app_info.js'); const appInfo = require('./app_info.js');
const cls = require('./cls.js');
async function migrate() { async function migrate() {
const currentDbVersion = getDbVersion(); const currentDbVersion = getDbVersion();
if (currentDbVersion < 214) { if (currentDbVersion < 214) {
log.error("Direct migration from your current version is not supported. Please upgrade to the latest v0.60.X first and only then to this version."); log.error("Direct migration from your current version is not supported. Please upgrade to the latest v0.60.4 first and only then to this version.");
utils.crash(); utils.crash();
return; return;
@@ -18,7 +19,7 @@ async function migrate() {
// backup before attempting migration // backup before attempting migration
await backupService.backupNow( await backupService.backupNow(
// creating a special backup for versions 0.60.X, the changes in 0.61 are major. // creating a special backup for version 0.60.4, the changes in 0.61 are major.
currentDbVersion === 214 currentDbVersion === 214
? `before-migration-v060` ? `before-migration-v060`
: 'before-migration' : 'before-migration'
@@ -51,6 +52,9 @@ async function migrate() {
// all migrations are executed in one transaction - upgrade either succeeds, or the user can stay at the old version // all migrations are executed in one transaction - upgrade either succeeds, or the user can stay at the old version
// otherwise if half of the migrations succeed, user can't use any version - DB is too "new" for the old app, // otherwise if half of the migrations succeed, user can't use any version - DB is too "new" for the old app,
// and too old for the new app version. // and too old for the new app version.
cls.setMigrationRunning(true);
sql.transactional(() => { sql.transactional(() => {
for (const mig of migrations) { for (const mig of migrations) {
try { try {

View File

@@ -895,6 +895,11 @@ function scanForLinks(note, content) {
* Things which have to be executed after updating content, but asynchronously (separate transaction) * Things which have to be executed after updating content, but asynchronously (separate transaction)
*/ */
async function asyncPostProcessContent(note, content) { async function asyncPostProcessContent(note, content) {
if (cls.isMigrationRunning()) {
// this is rarely needed for migrations, but can cause trouble by e.g. triggering downloads
return;
}
if (note.hasStringContent() && !utils.isString(content)) { if (note.hasStringContent() && !utils.isString(content)) {
content = content.toString(); content = content.toString();
} }

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<link rel="shortcut icon" href="favicon.ico"> <link rel="shortcut icon" href="favicon.ico">
<link rel="manifest" href="manifest.webmanifest"> <link rel="manifest" crossorigin="use-credentials" href="manifest.webmanifest">
<title>Trilium Notes</title> <title>Trilium Notes</title>
</head> </head>
<body class="desktop heading-style-<%= headingStyle %>"> <body class="desktop heading-style-<%= headingStyle %>">

View File

@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="theme-color" content="#fff"> <meta name="theme-color" content="#fff">
<title>Trilium Notes</title> <title>Trilium Notes</title>
<link rel="manifest" href="manifest.webmanifest"> <link rel="manifest" crossorigin="use-credentials" href="manifest.webmanifest">
<style> <style>
.lds-roller { .lds-roller {

View File

@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
[[ ! -z "${USER_UID}" ]] && usermod -u ${USER_UID} node || echo "No USER_UID specified, leaving 1000" [[ ! -z "${USER_UID}" ]] && usermod -u ${USER_UID} node || echo "No USER_UID specified, leaving 1000"
[[ ! -z "${USER_GID}" ]] && groupmod -g ${USER_GID} node || echo "No USER_GID specified, leaving 1000" [[ ! -z "${USER_GID}" ]] && groupmod -og ${USER_GID} node || echo "No USER_GID specified, leaving 1000"
chown -R node:node /home/node chown -R node:node /home/node
exec su-exec node node ./src/www exec su-exec node node ./src/www