Compare commits

...

458 Commits

Author SHA1 Message Date
zadam
2978a262f7 release 0.31.0-beta 2019-04-01 21:50:32 +02:00
zadam
f47f3461e6 show local date in revisions dialog + make it larger 2019-04-01 21:49:27 +02:00
zadam
06202c31e4 note info shows local date instead of utc date 2019-04-01 21:43:45 +02:00
zadam
925dc258a6 fix menu text color in dark themes 2019-04-01 21:38:21 +02:00
zadam
3670800a51 set cookie header only for electron calls 2019-04-01 21:18:11 +02:00
zadam
90a331b989 some style fixes and refactoring for tree context menu 2019-04-01 21:11:20 +02:00
zadam
a4c8bdeda2 fix decryption of protected note revisions 2019-03-31 22:54:38 +02:00
zadam
5bda254184 allow searching with noteId & fix combining fulltext and other conditions with OR 2019-03-31 22:23:50 +02:00
zadam
26621c0318 short search help in the tooltip 2019-03-31 21:19:10 +02:00
zadam
c6806256fd import doesn't need a full tree reload 2019-03-31 19:13:17 +02:00
zadam
f00e1235f9 tar import can now process files with out of order directories 2019-03-31 18:53:29 +02:00
zadam
51bede6541 fix detection of sync connection issue with new error code 2019-03-31 18:36:12 +02:00
zadam
75dbaa4b77 fix csrf protection on electron build 2019-03-31 12:49:42 +02:00
zadam
bec6576620 fix note cleanup 2019-03-31 11:27:19 +02:00
zadam
44551e0e8c electron build now waits for the migration before opening the window 2019-03-31 11:21:44 +02:00
zadam
67553cb40e fix ordering of note migrations 2019-03-30 22:20:18 +01:00
zadam
7cafbda7cd migration for inconsistent isProtected status across notes and note_contents 2019-03-30 22:12:18 +01:00
zadam
9a5a085103 Merge branch 'stable'
# Conflicts:
#	package-lock.json
#	src/public/javascripts/services/server.js
#	src/services/app_info.js
#	src/services/notes.js
2019-03-30 22:11:03 +01:00
zadam
cdb17ae937 release 0.30.7 2019-03-30 20:13:53 +01:00
zadam
c240fb9896 migration for inconsistent isProtected status across notes and note_contents 2019-03-30 20:09:38 +01:00
zadam
4b41eddf44 fix creating note directly as protected 2019-03-30 19:24:53 +01:00
zadam
b51ac112a2 fix loading of protected session in electron, #469 2019-03-30 18:00:08 +01:00
zadam
a1ac609b34 search input tooltip WIP 2019-03-30 17:41:53 +01:00
zadam
66e2a12f3d rename "current" to "active" based on recent refactorings 2019-03-30 10:15:19 +01:00
zadam
9f69294f7f Merge pull request #466 from capi/ctrl-shift-l
Add Ctrl+Shift+L to pre-select "add to note"
2019-03-30 10:13:31 +01:00
zadam
a5fc8d5329 moved libraries and images out of src folder 2019-03-30 09:39:58 +01:00
zadam
7bbf797caf saved search note now has refresh button, closes #369 2019-03-30 00:12:32 +01:00
zadam
f479c0e10e when note is created, it's automatically present in all cloned parents as well 2019-03-29 23:55:28 +01:00
zadam
0f32154b91 Merge remote-tracking branch 'origin/stable'
# Conflicts:
#	src/public/javascripts/services/context_menu.js
2019-03-29 23:37:36 +01:00
zadam
f2019ee5f9 slightly nicer search detail 2019-03-29 23:28:41 +01:00
zadam
89b8e2bb08 redesign of search input. Saved search is now saved under active note and doesn't need page reload 2019-03-29 23:24:41 +01:00
zadam
8fb6edad67 fix consistency checks for fulltext 2019-03-29 22:08:04 +01:00
zadam
c2e3a3fe04 release 0.30.6 2019-03-28 23:17:24 +01:00
zadam
b2052a6ccd release 0.30.6 2019-03-28 23:01:52 +01:00
zadam
a07479cd5a release 0.30.6 2019-03-28 22:49:34 +01:00
zadam
3820384f51 release 0.30.6 2019-03-28 22:35:43 +01:00
zadam
0610576e5a 0.30.6 2019-03-28 22:35:36 +01:00
zadam
efac7701eb release 0.30.6 2019-03-28 22:31:59 +01:00
zadam
905eb303bc fix protected note switching 2019-03-28 21:17:40 +01:00
zadam
27cee1cf33 fix closing of context menu on FF66, closes #468
(cherry picked from commit 3c56d29fca)
2019-03-28 20:57:11 +01:00
zadam
3c56d29fca fix closing of context menu on FF66, closes #468 2019-03-28 20:54:17 +01:00
zadam
946dae72d9 implemented consistency check for note fulltext based on hashes 2019-03-27 21:27:29 +01:00
zadam
58f71c7300 some design explanations on special handling of content 2019-03-27 21:16:13 +01:00
zadam
07e9013152 content migration fixes 2019-03-27 21:04:25 +01:00
zadam
29c60581a6 yet another refactoring of working with note's payload/content 2019-03-26 22:24:04 +01:00
zadam
4bdcf32475 repository now uses upsert instead of insert/replace 2019-03-25 22:06:17 +01:00
Martin Carpella
44c742e839 Add Ctrl+Shift+L to pre-select "add to note" 2019-03-25 21:09:15 +01:00
zadam
001bd1d004 fix csrf path so that it's valid only for current path and not whole (sub)domain 2019-03-24 23:03:30 +01:00
zadam
6c7e2f0aa1 moved "About" from options dialog to a separate dialog under global menu 2019-03-24 23:01:33 +01:00
zadam
9fc5d328b4 added CSRF protection using csurf express middleware, fixes #455 2019-03-24 22:41:53 +01:00
zadam
f6413d095c update schema -> fix creating new database from scratch 2019-03-24 21:06:38 +01:00
zadam
d66ad4319e fix focused table cell background color, closes #458 2019-03-24 20:16:05 +01:00
zadam
251fcaeb48 support for superscript and subscript, closes #462 2019-03-24 19:58:13 +01:00
zadam
3311c6336c exposed searchForNotes to backend script API 2019-03-20 22:51:13 +01:00
zadam
fc13e1fa6a added possibility to search by attached script returning note ids + some refactorings 2019-03-20 22:28:54 +01:00
zadam
9ca680f842 handle empty search note 2019-03-20 21:01:00 +01:00
zadam
616829464f refactoring of context menu items, got rid of ContextMenuItemsContainer 2019-03-19 22:56:37 +01:00
zadam
0267468cd5 deleting without reloading the whole tree (at least on frontend) 2019-03-18 23:03:41 +01:00
zadam
ca0d17d93a cloning is now done without reloading the whole tree 2019-03-18 22:33:19 +01:00
zadam
3f656ea76f refactoring and fix icon assignment 2019-03-18 22:10:10 +01:00
zadam
1faf2c6ecd fixes for some note moving edge cases, closes #454 2019-03-18 21:59:53 +01:00
zadam
33f2aaa650 note type context submenu now works end to end 2019-03-17 12:19:23 +01:00
zadam
177caec011 note type context submenu WIP 2019-03-17 11:38:27 +01:00
zadam
62650a4545 refactoring of router search code into service 2019-03-16 22:19:01 +01:00
zadam
81dc907afc ordering of search results 2019-03-16 20:52:21 +01:00
zadam
3ee33e1024 refactoring of joins for search 2019-03-16 19:57:39 +01:00
zadam
2326eb85f1 filter reimplementation, WIP 2019-03-16 16:52:58 +01:00
zadam
0885e60b80 removed obsolete isoDateXXX API methods 2019-03-14 20:49:10 +01:00
zadam
ef40c66344 renamed currentNote to activeNote to be consistent with frontend API 2019-03-14 20:21:27 +01:00
zadam
0d0464549f notes are now created with correct local dates 2019-03-13 22:43:59 +01:00
zadam
b68b0fe783 Merge branch 'master' into dev31 2019-03-13 21:53:41 +01:00
zadam
b4c6d9f800 using now session cookies to store protectedSessionId 2019-03-13 21:53:09 +01:00
zadam
24c8b39d8e release 0.30.5 2019-03-12 22:21:35 +01:00
zadam
0144dc12df current note as in note loaded into right pane is now called "active note" in frontend API 2019-03-12 21:52:19 +01:00
zadam
65684550a8 updated API docs 2019-03-12 21:42:27 +01:00
zadam
6d09931a39 add getCurrentNote() frontend API, #444 2019-03-12 21:39:35 +01:00
zadam
1c41d459f0 renamed dates in code as well 2019-03-12 20:58:31 +01:00
zadam
f65fefe7b1 migration utc dates 2019-03-11 22:58:44 +01:00
zadam
0a906b5663 updated db schema 2019-03-11 20:36:19 +01:00
zadam
dd9b7bbbb5 fix fulltext search 2019-03-11 19:50:13 +01:00
zadam
d25a1e3ed9 initial work on note fulltext (schema changes, updating...) 2019-03-10 17:02:23 +01:00
zadam
05374becfd Merge branch 'master' into dev31 2019-03-10 10:11:01 +01:00
zadam
37d2a7939c fix background/border on quick help dialog, closes #440 2019-03-09 18:57:21 +01:00
zadam
a432ad7483 fix isProtected consistency for images and files + related consistency check 2019-03-08 22:25:12 +01:00
zadam
ae17e4dc60 release 0.30.4 2019-03-07 22:40:05 +01:00
zadam
02eddc347a fix export of protected notes to tar archive, fixes #432 2019-03-07 22:00:23 +01:00
zadam
ee58bf3d5c fix bundle execution error handling 2019-03-07 20:51:55 +01:00
zadam
ecbaffa5f3 return focus back to note detail after quitting add link dialog 2019-03-07 20:45:32 +01:00
zadam
fe86c09f22 make sure date label is always created with YYYY-MM-DD and not the rest of date time 2019-03-05 20:49:39 +01:00
zadam
c8e01d6cce pretty print JSON into note content 2019-03-05 20:44:50 +01:00
zadam
fd0bd5dd00 small fixes 2019-03-05 20:38:31 +01:00
zadam
cd6d4fb527 Merge pull request #420 from jkurei/master
Querying by dateCreated and dateModified virtual attributes
2019-03-05 19:47:17 +01:00
zadam
8ed6851e85 fix image upload for ckeditor v12 2019-03-04 22:58:47 +01:00
zadam
a6fd3bfb00 placeholder for note content 2019-03-04 22:39:44 +01:00
zadam
610dd8a783 upgrade to ckeditor 12.0.0 2019-03-04 22:36:46 +01:00
zadam
7c404f03db unused param 2019-03-04 22:18:27 +01:00
zadam
ed1cf6aad5 fix passing of startNote and originEntity to backend script API 2019-03-04 21:17:34 +01:00
zadam
9703fd61e2 protected note's shield background now looks better on the dark themes 2019-03-04 20:53:57 +01:00
zadam
16790e388b recent changes should show titles of protected notes correctly when in protected session 2019-03-04 20:44:20 +01:00
zadam
b48474998b release 0.30.3-beta 2019-03-03 20:47:50 +01:00
zadam
95d8f07458 debugging info for image shrinking 2019-03-03 20:41:03 +01:00
zadam
e628c30c89 fix OPML export to include correct OPML version 2019-03-03 19:43:30 +01:00
zadam
52a8aae74f moved test enex files to separate repo 2019-03-03 19:40:47 +01:00
zadam
54b5898582 detect mime types from the filename instead of relying on upload mime type 2019-03-03 00:25:31 +01:00
zadam
64974d75d5 added sync fill for note_contents 2019-03-02 19:59:32 +01:00
zadam
bd118027fb note content is also part of hash check 2019-03-02 12:40:46 +01:00
zadam
36de217835 release 0.30.2-beta 2019-02-28 22:33:33 +01:00
zadam
b5283d58bb nicer underlining under tooltip items 2019-02-28 22:32:54 +01:00
zadam
8414d97ffa improve logging a little bit 2019-02-27 22:15:52 +01:00
zadam
9f30d4e673 fix image caption editing (#422) 2019-02-26 22:59:38 +01:00
zadam
8e0d1fa0df better contrast of links on the dark theme 2019-02-26 22:51:33 +01:00
zadam
5b251b9977 added drag & drop files on note detail 2019-02-26 21:37:15 +01:00
zadam
8b3e721028 added "explodeArchives" option to the import dialog 2019-02-25 22:38:48 +01:00
zadam
7e2a2baa5d drag & drop now uses import code 2019-02-25 22:28:15 +01:00
zadam
003eed368b unify markdown mime to text/x-markdown 2019-02-25 21:57:11 +01:00
zadam
4b1cf05c0e import images 2019-02-25 21:22:57 +01:00
zadam
d9429c4f4b import plain text file as text/html 2019-02-24 13:10:47 +01:00
zadam
b7bd94b6b0 switchable image shrinking 2019-02-24 12:25:34 +01:00
zadam
51bbc10744 switchable image shrinking 2019-02-24 12:24:28 +01:00
zadam
fb5df33ee7 new import options in the dialog, tooltips 2019-02-24 11:36:01 +01:00
zadam
d8ba0ccd7d use formdata to pass text arguments during import instead of request path 2019-02-24 09:56:00 +01:00
zadam
886ea6c68c allow import of multiple files at the same time 2019-02-24 09:34:50 +01:00
jkurei
ec384fafce Querying by dateCreated and dateModified virtual attributes 2019-02-24 01:34:23 +01:00
zadam
936f85c09e drag & drop multi file upload to note tree 2019-02-23 20:33:27 +01:00
zadam
b25deea21d fixes for relative paths 2019-02-22 23:03:20 +01:00
zadam
cf5ec44303 another fix for debian package upload 2019-02-20 23:22:04 +01:00
zadam
6f956c2415 release 0.30.1-beta 2019-02-20 23:08:36 +01:00
zadam
3533160bef fix initial document setup 2019-02-20 23:07:57 +01:00
zadam
60cbfdcabd update API docs 2019-02-20 22:24:51 +01:00
zadam
604f036a54 fix debian package upload 2019-02-20 22:10:19 +01:00
zadam
dd4f3ec264 release 0.30.0-beta 2019-02-20 21:58:31 +01:00
zadam
ff67b8a0ba initial debian package support 2019-02-20 21:58:23 +01:00
zadam
1d5fb0b646 add possibility to create week note, closes #416 2019-02-19 22:49:57 +01:00
zadam
80931a318f exposing APIs to get month and year note, #416 2019-02-19 21:29:41 +01:00
zadam
16f16cb36a fixed API for Trilium Sender, closes #415 2019-02-19 21:24:35 +01:00
zadam
899f24cde5 minor node upgrades 2019-02-17 22:56:33 +01:00
zadam
9f29521ab8 disable caching of note autocomplete for more accurate results 2019-02-17 20:59:52 +01:00
zadam
c1ce0c6b22 avoid various HTTP server issues with slashes by putting notePath into the body with POST 2019-02-17 20:49:51 +01:00
zadam
a7fce33750 OPML v2 export 2019-02-16 23:58:42 +01:00
zadam
6fd8e73150 UI for export of OPML v2, WIP 2019-02-16 23:33:40 +01:00
zadam
1359dd86c2 OPML 2 import, closes #298, #286 2019-02-16 22:13:29 +01:00
zadam
a1b610fc50 full screen help dialog 2019-02-16 19:42:58 +01:00
zadam
c849d719e9 styling for external links 2019-02-16 18:49:57 +01:00
zadam
96de2e7008 fixed saved search 2019-02-15 21:21:26 +01:00
zadam
f140b77e7c fix migration script 2019-02-15 21:10:00 +01:00
zadam
22228de63b sync changes for note content 2019-02-15 00:15:09 +01:00
zadam
b0596c9eb2 removed noteId display in the note detail, #408 2019-02-14 20:57:56 +01:00
zadam
2a2319d434 created note info dialog, closes #408 2019-02-14 20:56:33 +01:00
zadam
dad47d115f fixes for SQL console schema view 2019-02-13 23:27:00 +01:00
zadam
502026359c help page, closes #273 2019-02-13 23:06:11 +01:00
zadam
47b0e4e4d3 Save electron window size and position, closes #186 2019-02-12 22:42:40 +01:00
zadam
6c927d9159 Merge remote-tracking branch 'origin/note-content' 2019-02-12 21:14:42 +01:00
zadam
ddc79b2517 release 0.29.1 2019-02-12 20:30:07 +01:00
zadam
4c2e12d2cb upgrade to bootstrap 4.3.0 2019-02-12 20:26:28 +01:00
zadam
14f7a8b7b9 safe import implementation 2019-02-11 23:45:58 +01:00
zadam
caa7dd9619 prettier progress count 2019-02-10 22:56:14 +01:00
zadam
8aa7e2d0a0 fixes in opml export and note content loading 2019-02-10 22:45:44 +01:00
zadam
6be8a3f343 added progress also to export 2019-02-10 22:30:55 +01:00
zadam
a097cefba7 import error handling 2019-02-10 19:53:57 +01:00
zadam
e4c78f3887 added ImportContext 2019-02-10 19:36:03 +01:00
zadam
5baa251944 more changes to import reporting through WS 2019-02-10 16:59:50 +01:00
zadam
cde68abec9 progress of tar import through WS 2019-02-10 16:36:25 +01:00
zadam
51175e3676 import/export refactorign 2019-02-10 15:33:56 +01:00
zadam
45ddfef30a new import dialog 2019-02-10 14:33:13 +01:00
zadam
1e1d78999e some help dialog content 2019-02-10 12:19:48 +01:00
zadam
92fcd7b345 sql console added to global menu and now has schema info 2019-02-10 10:38:18 +01:00
zadam
e04f1cd574 help button with no help dialog yet 2019-02-09 19:48:19 +01:00
zadam
176c3a5d51 added dev tools to global menu 2019-02-09 19:25:55 +01:00
zadam
c09570cf39 global menu 2019-02-09 19:17:16 +01:00
zadam
4a093000be note content refactoring, WIP 2019-02-08 21:01:26 +01:00
zadam
6952b643ae note content refactoring, WIP 2019-02-07 22:16:40 +01:00
zadam
c487a95bc7 note content refactoring, WIP 2019-02-06 21:29:23 +01:00
zadam
8884177d9f split out note's content into separate entity, WIP 2019-02-06 20:19:25 +01:00
zadam
8b250ed523 fix upload of the same file in succession, #388 2019-02-03 17:44:06 +01:00
zadam
d8b78d8025 check reference issues only for non deleted entities 2019-02-03 16:27:26 +01:00
zadam
42112b8053 fix consistency check 2019-02-03 16:22:45 +01:00
zadam
6cc0dd5a80 release 0.29.0-beta 2019-02-03 15:44:19 +01:00
zadam
afd5f4823f added Steel Blue theme to demo document 2019-02-03 15:39:27 +01:00
zadam
b0cf82c91b fix 2019-02-03 15:37:01 +01:00
zadam
6a67cdd5af appThemeClass is redundant 2019-02-03 15:35:37 +01:00
zadam
bad7b84993 error handling in custom request handler 2019-02-03 11:15:32 +01:00
zadam
d3ca6b5ae6 styling for scrollbar which looks ugly otherwise in dark themes 2019-02-03 10:21:28 +01:00
zadam
da5009f089 main border color CSS variable 2019-02-03 10:09:59 +01:00
zadam
c08524c977 fix CSS class of user theme 2019-02-03 00:12:57 +01:00
zadam
f89537037e small styling fixes 2019-02-02 23:51:00 +01:00
zadam
c153793766 added CSS variable for disabled button background 2019-02-02 23:26:39 +01:00
zadam
0aec5927d5 added missing labels customRequestHandler, customResourceProvider to autocomplete 2019-02-02 22:33:02 +01:00
zadam
8aea9a1801 added font family CSS variables to theming API 2019-02-02 20:45:38 +01:00
zadam
73247e3220 minor library updates 2019-02-02 19:21:30 +01:00
zadam
89344a6eda final fixes and refactorings for consistency checks 2019-02-02 12:41:20 +01:00
zadam
40d2e6ea83 refactoring consistency checks WIP 2019-02-02 11:26:27 +01:00
zadam
910cfe9a17 refactoring consistency checks WIP 2019-02-02 10:38:33 +01:00
zadam
e58a80fc00 consistency checks WIP 2019-02-02 09:26:57 +01:00
zadam
4a2319cb33 refactoring of consistency checks plus some autofixers 2019-02-01 22:48:51 +01:00
zadam
5619088c41 raise payload size limit to 500 MB #395 2019-01-29 21:19:08 +01:00
zadam
60271993eb Merge pull request #392 from jkurei/ios_favicon
Better icon for iOS' homescreen
2019-01-28 23:01:12 +01:00
jkurei
6695e8b011 Better icon for iOS' homescreen 2019-01-28 22:48:01 +01:00
zadam
707df18b93 added type and mime classes on body as well #383 2019-01-28 21:42:37 +01:00
zadam
90895f1288 added noteId to file view 2019-01-27 23:10:37 +01:00
zadam
ba1ca506af change in referencing CSS resources to allow easier relative linking 2019-01-27 22:34:41 +01:00
zadam
f90ed99a40 fix leaf node having angle bracket in dark & black themes, closes #387 2019-01-27 21:54:24 +01:00
zadam
67630b1a22 options now allow selecting user theme 2019-01-27 21:18:11 +01:00
zadam
2c1580ea65 appCss/appTheme are now loaded as external CSS files instead of inline styles 2019-01-27 17:01:37 +01:00
zadam
840a0b5f64 custom handler refactoring 2019-01-27 16:37:18 +01:00
zadam
b39f6ef7ad bug fixes for custom handlers 2019-01-27 15:47:40 +01:00
zadam
fb27088fcd smaller children overview font 2019-01-27 14:26:39 +01:00
azivner
76fbff68ba added readOnly attribute which puts text editor into readonly mode #371 2019-01-27 13:10:03 +01:00
azivner
54de4d236d custom HTTP handler which triggers associated script notes WIP, #356 2019-01-27 12:28:20 +01:00
azivner
e211dd65ad exit on detection of not supported node version, #324 2019-01-26 19:59:51 +01:00
azivner
a87f4d8653 search can be triggered from URL, closes #385 2019-01-25 22:18:34 +01:00
azivner
b59c175c2e add HTML header with UTF-8 meta encoding declaration to exported HTML files, fixes #384 2019-01-25 21:34:14 +01:00
azivner
580104c4c5 using trilium's confirm dialog, small refactoring 2019-01-24 22:18:31 +01:00
zadam
0fc3053b0a Merge pull request #377 from flurmbo/master
add confirm type change dialog when note not empty
2019-01-24 22:12:09 +01:00
Phil Marshall
929e0f69c2 add confirm type change dialog when note not empty 2019-01-23 15:15:24 -06:00
azivner
e70af1300a drag and drop moves multiple items only if CTRL is pressed, active note has now bold text for more differentiation from selected note 2019-01-23 21:13:04 +01:00
azivner
4d0e46021b Mac uses CMD+Left, CMD+Right for history navigation, closes #376 2019-01-23 20:15:33 +01:00
azivner
1a9a49b739 release 0.28.3 2019-01-22 23:01:32 +01:00
azivner
2ac560c56e text note should change its icon after having new note inserted into, fixes #361 2019-01-22 21:21:44 +01:00
azivner
c23387c0fb make search dialog more responsive in narrow sidebar, fixes #367 2019-01-22 20:54:00 +01:00
azivner
0ff250fe15 font sizes were not created for new documents - fix plus migration for existing ones 2019-01-22 20:34:45 +01:00
azivner
52b1e58b26 make tree selection more visually consistent 2019-01-22 20:23:54 +01:00
azivner
484715e440 fix icon in desktop linux build, fixes #372 2019-01-22 19:49:33 +01:00
azivner
9d42c3d802 release 0.28.2 2019-01-21 22:55:12 +01:00
azivner
c654172d33 auto fixer for "undeleted branch of deleted note" consistency check 2019-01-21 22:51:49 +01:00
azivner
e17b26c883 revert consistency checks refactoring for now 2019-01-21 22:46:27 +01:00
azivner
24d02d9cf5 fix in task manager script to not error out so much on deletion 2019-01-21 22:05:37 +01:00
azivner
7208a311ac check that note is not deleted before creating a branch 2019-01-21 21:55:40 +01:00
azivner
ad7355372b issue template 2019-01-21 19:55:07 +01:00
azivner
f18b5babad uncommented issue template 2019-01-20 16:47:49 +01:00
azivner
9831ec0ca9 added issue template 2019-01-20 16:46:56 +01:00
azivner
596544eca3 fix setNoteToParent API method, closes #360 2019-01-20 16:33:09 +01:00
azivner
1f853024ee more autofixers WIP 2019-01-19 09:57:51 +01:00
azivner
0308b13460 expose app info on the backend script api #345 2019-01-18 23:57:08 +01:00
azivner
06b8a82f70 refactoring of consistency checks + some auto fixers 2019-01-18 19:32:59 +01:00
azivner
91ca07929d before we clone the note we must make sure it's not deleted 2019-01-17 23:24:59 +01:00
azivner
afabaa5fdb workaround for hidden last line on mobile 2019-01-17 21:13:53 +01:00
azivner
a6fd3fa77c release 0.28.1-beta 2019-01-17 00:03:17 +01:00
azivner
58a2c08dcd release 0.28.1-beta 2019-01-16 23:58:10 +01:00
azivner
299bbff2f4 fix too large font on mobile 2019-01-16 23:57:09 +01:00
azivner
19d8947123 runOnNoteChange fires also on the frontend, closes #340 2019-01-16 22:52:32 +01:00
azivner
35edce7523 fix crazy clipboard operation on mac setup, closes #348 2019-01-16 22:03:30 +01:00
azivner
bc4cec69a5 use local dates to create day notes, closes #337 2019-01-15 23:46:01 +01:00
azivner
cce8c1b674 create top level note and collapse tree now work relative to hoisted note, closes #343 2019-01-15 20:30:54 +01:00
azivner
aa58788769 added basic DB size diagnostic log 2019-01-15 20:00:24 +01:00
azivner
6c62ab7a52 removing logging params for slow queries 2019-01-15 19:36:04 +01:00
azivner
d6ab638b30 fix file names in github release script 2019-01-15 00:10:47 +01:00
azivner
bd4db406de release 0.28.0-beta 2019-01-14 23:51:55 +01:00
azivner
e50f9cd0a3 fix device detection in setup 2019-01-14 23:50:45 +01:00
azivner
2b64cbce2c added dark theme (to have same set of themes as before) 2019-01-13 23:25:30 +01:00
azivner
2797c942ab changes to options dialog to allow configuring font size, closes #326 2019-01-13 22:03:06 +01:00
azivner
f1c3278874 store font size in options #326 2019-01-13 21:27:32 +01:00
azivner
424c22dcde split UI to 3 different font sizes #326 2019-01-13 21:16:51 +01:00
azivner
5c223dfd12 all fonts are relative so it's easier to scale them properly 2019-01-13 21:04:08 +01:00
azivner
6a3e7a5a8e generate css classes for each mime type, #328 2019-01-13 20:14:33 +01:00
azivner
f88cdac000 fixes for black theme for relation map and code notes 2019-01-13 20:03:28 +01:00
azivner
eeead90f32 improved theme support using CSS variables, #328 2019-01-13 18:57:46 +01:00
azivner
b607857409 fix weight tracker demo to use relations instead of hardcoded noteId, fixes #329 2019-01-13 12:21:17 +01:00
azivner
9268f88bc3 frontend scripts now have startNote, currentNote and targetNote as NoteShort entities which e.g. provides easy access to relations/labels 2019-01-13 12:16:05 +01:00
azivner
f7f0560a9f simplification of script bundles on backend 2019-01-13 11:56:50 +01:00
azivner
3d8905207e fixed export with non-ASCII characters in note title, fixes #285, #331 2019-01-13 10:22:17 +01:00
azivner
dbc312010b update fancytree to 2.30.2 2019-01-13 09:24:00 +01:00
azivner
b115a7cf19 delete note through its entity instead of manually with SQL, closes #303 2019-01-13 00:24:51 +01:00
azivner
348562352c fixes in ASAR build and zipping 2019-01-12 19:48:45 +01:00
azivner
70fd917e7c build desktop versions into ASAR, closes #271 2019-01-12 00:05:13 +01:00
zadam
d2b60764cd Merge pull request #289 from perissology/electron-builder
use electron-builder for dev install
2019-01-11 23:54:11 +01:00
azivner
581b1fdaa5 trigger runOnAttributeChange, runOnNoteChange on entity deletions as well 2019-01-11 23:43:22 +01:00
azivner
3c19a712c0 active protected state button has darker background and is disabled 2019-01-11 23:29:56 +01:00
azivner
cc27f16088 store iv directly in the respective columns 2019-01-11 23:04:51 +01:00
azivner
dffdb82288 after creating new note, it is focused and now also selected so renaming is super easy, #318 2019-01-10 22:46:08 +01:00
azivner
2b32addade release 0.27.4 2019-01-10 21:31:30 +01:00
azivner
0b251530fa open recent notes autocomplete by focus so it is then closed with blur, fixes #272 2019-01-10 21:04:06 +01:00
azivner
f5b933149a Merge remote-tracking branch 'origin/master' 2019-01-10 19:53:47 +01:00
azivner
48bbfb8bdb fix activating note by noteId when hoisting, fixes #320 2019-01-10 19:53:42 +01:00
zadam
889971c4d6 Merge pull request #312 from perissology/evernote-import
Fixes evernote import errors
2019-01-09 23:41:17 +01:00
azivner
0722494d41 fix saving JSON note with invalid JSON (previously in such a case content was not updated), fixes #307 2019-01-09 23:36:17 +01:00
azivner
4b977a3306 setup keyboard shortcuts on the setup page as well, closes #267 2019-01-09 22:08:24 +01:00
azivner
3ff3021acd shortcuts for mac should use cmd instead of ctrl, closes #290 2019-01-09 21:42:16 +01:00
azivner
99e56a9c42 make sure to save the search note before refreshing the tree 2019-01-09 19:54:32 +01:00
azivner
77279dfe16 fix anonymization 2019-01-09 19:49:02 +01:00
perissology
93f8050454 use resizedImage if image optimization fails 2019-01-09 06:29:49 -08:00
perissology
31cfede7a7 enex import: attempt to get correct mime from Buffer 2019-01-09 06:29:13 -08:00
azivner
c8ec86e537 allow refreshing saved note, closes #304 2019-01-08 23:32:03 +01:00
azivner
05aee884b6 fix saving search note content #304 2019-01-08 22:48:53 +01:00
azivner
012ba9e060 don't attempt to run protected notes outside of protected session, fixes #279 2019-01-08 21:21:49 +01:00
azivner
8e8fd88857 process only whitelisted mime types as an image, fixes #288 2019-01-08 20:45:34 +01:00
azivner
523ccdad6b reload note cache after import, closes #293 2019-01-08 20:19:41 +01:00
azivner
ded3f605be fix almost invisible buttons on options page, closes #297 2019-01-08 19:47:35 +01:00
perissology
62b44e3549 use electron-builder for npm install
This will build deps as required for electron as well as the os.

This fixes the missing binding error for sqlite3 when trying to run the
electron app after a fresh npm i
2019-01-08 06:50:48 -08:00
azivner
030d12a465 stretch sync login token validity to 5 minutes #277 2019-01-07 23:29:56 +01:00
azivner
4d15628840 Merge remote-tracking branch 'origin/master' 2019-01-07 23:17:45 +01:00
azivner
81b849898c stretch body to full window width, fixes #276 2019-01-07 23:17:12 +01:00
zadam
3824486b85 Merge pull request #275 from Lee303/Dockerfile-dependency-fix
Update Dockerfile
2019-01-07 22:49:27 +01:00
Lee Spottiswood
081ab00a0a Update Dockerfile 2019-01-07 21:21:23 +00:00
zadam
04f6af5c9a Merge pull request #270 from svenefftinge/master
Make contributions easier
2019-01-07 21:46:02 +01:00
Sven Efftinge
4dc1f1f6eb Added contribute section and gitpod config 2019-01-07 12:52:02 +00:00
azivner
3930a02123 tree now uses standard font size which effectively makes it a bit larger 2019-01-06 20:59:19 +01:00
azivner
3112de105e fancytree selection/hover colors are shades of gray, border is rounded 2019-01-06 18:58:12 +01:00
azivner
3b8d7b8fba release 0.27.3 2019-01-05 22:48:11 +01:00
azivner
9fca7f09a5 link to mobile frontend 2019-01-05 22:45:18 +01:00
azivner
fd39d6b3a9 using btn-secondary instead of btn-default since that doesn't exist in BS4 2019-01-05 21:51:27 +01:00
azivner
a103886ea5 responsive setup page 2019-01-05 21:49:40 +01:00
azivner
373408e401 fix Branch reference to parent note id after parent change 2019-01-05 19:25:22 +01:00
azivner
db44c1d8e6 border color tweaks 2019-01-05 11:49:17 +01:00
azivner
95a34c9e2d small tweaks of icon alignment 2019-01-05 11:41:09 +01:00
azivner
6ce401f260 release 0.27.2-beta 2019-01-04 23:33:32 +01:00
azivner
5d74dcd256 package-lock 2019-01-04 23:33:30 +01:00
azivner
5a9fc1697b electron 4.0.1 2019-01-04 23:32:14 +01:00
azivner
927415838c using enhanceTitle event instead of renderNode per https://github.com/mar10/fancytree/issues/927 2019-01-04 20:18:07 +01:00
azivner
d72fcefdc7 fix sync of deleted notes 2019-01-04 20:10:16 +01:00
azivner
0be173a8f7 lower lastSyncedPull if server max sync ID is lower 2019-01-04 18:58:46 +01:00
azivner
c3913a8735 updating the note cache after sync 2019-01-03 23:27:10 +01:00
azivner
e2dfe1b6de fixed setup page issues which caused wrong choice to be used in the wizard 2019-01-03 22:32:36 +01:00
azivner
fec3e47eb8 serialize binary note content into base64, incremented sync version 2019-01-03 22:13:58 +01:00
azivner
d72efd2450 removed unnecessary logging of data dir which is now logged as part of app info 2019-01-03 21:46:32 +01:00
azivner
ef1c840aa7 tiny fixes 2019-01-02 22:36:06 +01:00
azivner
1581464d8c fix layout - promoted attributes should never grow beyond its content 2019-01-02 20:21:34 +01:00
azivner
9de29584a4 added data directory to options -> about 2019-01-02 20:08:41 +01:00
azivner
9e2e6fb50c fixed glitch where "unhoist" button disappears after renaming the hoisted note 2019-01-02 19:26:01 +01:00
azivner
c85979b66b it should not be possible to add note after hoisted note 2019-01-02 18:59:08 +01:00
azivner
ecdc5865a6 release 0.27.1-beta 2019-01-01 20:54:23 +01:00
azivner
1771ddb787 responsive promoted attributes view and attribute overview to make sure note content is always visible. Fixes #262 2019-01-01 20:53:18 +01:00
azivner
3ab657fe46 created concept of "detail loaded listeners" which allow scripts to execute some action after the note detail has been loaded 2019-01-01 19:32:34 +01:00
azivner
8785dae753 force reload fancytree node when child is not found 2019-01-01 18:27:36 +01:00
azivner
2f1c5b29d4 update eslint 2019-01-01 18:06:52 +01:00
azivner
7135349a10 allow deleting protected notes outside of protected session 2019-01-01 17:04:21 +01:00
azivner
66c639d5e3 frontend API addition to protect current note 2019-01-01 15:39:13 +01:00
azivner
6704b755d8 attribute overview shows only owned attributes 2019-01-01 15:29:58 +01:00
azivner
cf96baad48 release 0.27.0-beta 2018-12-30 22:38:11 +01:00
azivner
32220476aa better behavior on default loading detail / switching between tree and detail 2018-12-30 22:36:39 +01:00
azivner
86bc84a2ad better detection of float parameter in label filters, fixes #265 2018-12-30 22:09:14 +01:00
azivner
de9e0c7929 lazy loading icon for both mobile and desktop 2018-12-30 21:13:35 +01:00
azivner
6963e662ef fix layout on chrome 2018-12-30 19:15:44 +01:00
azivner
7127822e8f placeholder for empty note content 2018-12-30 19:02:42 +01:00
azivner
0a35abf68f refresh note detail view after attribute save (from full dialog, not promoted notes), closes #261 2018-12-30 15:21:53 +01:00
azivner
3f8e8f8561 fix saving branch prefix, fixes #260 2018-12-29 10:35:44 +01:00
azivner
e02eca87b0 dont toggle panes note on the first load 2018-12-29 10:19:28 +01:00
azivner
2f680c4326 tweaks, fixes, refactorings, creating new note from detail, not tree 2018-12-29 10:04:59 +01:00
azivner
0b4a44a403 layout tweaks etc. 2018-12-29 09:13:52 +01:00
azivner
89299f865c api method to detect navigation away from current page 2018-12-29 08:40:35 +01:00
azivner
f6db9a50ab "switch to desktop version" button 2018-12-29 00:09:16 +01:00
azivner
78d9fac1e6 global actions context menu, logout 2018-12-28 23:57:11 +01:00
azivner
458ed1faff mobile detection 2018-12-28 23:47:06 +01:00
azivner
0657815de5 Merge branch 'master' into mobile 2018-12-28 22:31:51 +01:00
azivner
a608832681 change to relation map note type doesn't trigger content change, related issue #258 2018-12-28 22:31:06 +01:00
azivner
d2f72529b3 context menu with delete 2018-12-28 22:05:04 +01:00
azivner
28185af158 fix layout/scrolling issues in the tree 2018-12-28 20:36:18 +01:00
azivner
7aacd01ad7 separate css layout file for mobile and desktop 2018-12-28 19:47:02 +01:00
azivner
74cc34696e unifying expander icons in both desktop and mobile 2018-12-27 22:38:19 +01:00
azivner
d4baac0bb5 mobile fixes 2018-12-27 22:36:11 +01:00
azivner
35bc1421f1 cannot edit note title when not in protected session 2018-12-27 20:22:33 +01:00
azivner
d4db265fd9 non-modal protected session password form is now done separately as a kind of detail component. Also reworked branch prefix dialog input 2018-12-27 20:04:59 +01:00
azivner
1dad919de9 working protected session in mobile 2018-12-25 10:58:40 +01:00
azivner
246dfbdcb4 fix attribute loading for mobile 2018-12-24 23:08:43 +01:00
azivner
f8d32d64f5 content scrolling 2018-12-24 22:39:17 +01:00
azivner
5dea271d6f basic responsive layout 2018-12-24 20:38:38 +01:00
azivner
eeb62a6cf2 fix keyboard shortcut setup on mobile 2018-12-24 18:39:31 +01:00
azivner
35cf8026b0 activating note opens dialog with its detail 2018-12-24 12:49:27 +01:00
azivner
e0028ab6f1 mobile frontend WIP, removing extra dependencies 2018-12-24 10:10:36 +01:00
azivner
a32645cdeb fix scrolling to the top of detail after switching note 2018-12-24 09:47:00 +01:00
azivner
812f9f6fca initial work on mobile frontend 2018-12-23 22:28:57 +01:00
azivner
f7a670ec24 responsive login page 2018-12-23 11:06:11 +01:00
azivner
d0d24f0f4a unify ejs indentation to 4 spaces 2018-12-23 10:57:40 +01:00
azivner
042f9b7f2d fix positioning of protected session password dialog 2018-12-22 23:54:06 +01:00
azivner
2d260cdbed explicit node-abi required for 4.0.0 electron build 2018-12-22 23:10:03 +01:00
azivner
6a786cad83 updated API docs 2018-12-22 22:28:49 +01:00
azivner
67019b3d6c added attributes to frontend entity model 2018-12-22 22:16:32 +01:00
azivner
1db6e59077 tooltip related changes for scripting support 2018-12-22 20:57:09 +01:00
azivner
5e4770875e upgrade to bootstrap 4.2.1 2018-12-22 10:33:50 +01:00
azivner
e9a77f3f16 image sync fixes and 4.0.0 electron 2018-12-22 09:54:09 +01:00
azivner
cbec85f295 release 0.26.1 2018-12-20 19:54:09 +01:00
azivner
14bd5d301d fix broken image sync 2018-12-20 19:51:03 +01:00
azivner
321d0e8d64 explicit error handler for connection errors 2018-12-19 21:29:35 +01:00
azivner
84e1512031 added robots.txt to public root 2018-12-19 20:56:10 +01:00
azivner
b036852b2d release 0.26.0-beta 2018-12-18 22:49:48 +01:00
azivner
f693dc31e8 mention note hoisting in the readme 2018-12-18 20:50:03 +01:00
azivner
af8f5b11b8 better error handling in request 2018-12-18 20:39:56 +01:00
azivner
8ca943f87b fix hoistedNoteId option init 2018-12-18 20:34:24 +01:00
azivner
35cc9da626 note about system proxy in the settings 2018-12-17 22:58:53 +01:00
azivner
44cc86a1a5 added support for explicit proxy 2018-12-17 22:54:54 +01:00
azivner
7c3bbfd45e using http service for sync setup as well, removed request(-promise) dependency 2018-12-17 22:12:26 +01:00
azivner
a1f939e3a0 refactoring of network code into separate service 2018-12-17 21:34:02 +01:00
azivner
4ca7886090 uniform requests through electron's net and node http/https to support different proxy setups 2018-12-16 23:30:53 +01:00
azivner
b942163748 sync with electron net API (for system proxy support) - working, but WIP 2018-12-16 21:19:12 +01:00
azivner
5b6d15acb3 note path might not always include root explicitly 2018-12-16 10:41:47 +01:00
azivner
841420360e quick unhoist link/button 2018-12-15 20:29:08 +01:00
azivner
a680bb4612 unhoist note when activating note outside of the hoisted note subtree 2018-12-13 23:28:48 +01:00
azivner
f763e13996 fix searching without hoisting 2018-12-13 21:43:13 +01:00
azivner
e73e1262ae Merge branch 'stable' into hoist 2018-12-13 21:18:44 +01:00
azivner
b774d56cf7 note titles in jump to note start from hoisted note instead of root 2018-12-13 21:18:35 +01:00
azivner
bae55f2e8b release 0.25.2 2018-12-12 21:30:06 +01:00
azivner
6c16cdb011 recent notes and jump to note are filtered by hoisted note 2018-12-12 21:28:38 +01:00
azivner
86fcbb0354 keyboard shortcut for hoisting, hoisted note is always expanded and has arrow icon 2018-12-12 20:54:58 +01:00
azivner
17d030e800 continuing work on hoisting notes 2018-12-12 20:39:56 +01:00
azivner
6fbf28b30d hoisting notes WIP 2018-12-11 21:53:56 +01:00
azivner
8171b68b18 electron 4.0 beta 9, context menu padding 2018-12-11 19:50:31 +01:00
azivner
d30e3a4052 bind standard shortcuts on both command and ctrl modifiers, #254 2018-12-10 20:44:50 +01:00
azivner
87aab7ac5b fix attributes leaking into imported notes, #241 2018-12-10 20:29:49 +01:00
azivner
c46f5805b1 removed the note from readme about missing mac build 2018-12-09 21:50:29 +01:00
azivner
dd6a29dfc0 no ia32 release upload 2018-12-09 21:34:08 +01:00
azivner
a0933c7f10 release 0.25.1-beta 2018-12-09 21:22:33 +01:00
azivner
492adc2909 fix broken drag & drop, closes 252 2018-12-09 21:18:53 +01:00
azivner
90a52f57b5 recent notes route accepts slash in the param (problem with nginx etc.) 2018-12-09 14:30:19 +01:00
azivner
a1469854e8 Allow Trilium to work from non-root document paths, closes #253 2018-12-09 13:37:28 +01:00
azivner
e2c2993255 changes in build - linux-x64 also uses prebuilt binaries compatible with glibc 2.27 so e.g. ubuntu 18.04 works again. Also dropped build for linux-ia32 2018-12-09 11:41:32 +01:00
azivner
270d63b265 deactivated cut to note functionality in ckeditor build 2018-12-08 10:54:10 +01:00
azivner
1d004be91d ckeditor upgrade to 11.2.0 2018-12-08 09:48:36 +01:00
azivner
b8a74c727e copy paste, undo, redo, select all shortcuts supported on mac build 2018-12-02 14:04:53 +01:00
azivner
c87b592277 fix in the release script 2018-12-02 08:42:11 +01:00
azivner
cfa926602a release 0.25.0-beta 2018-12-02 00:30:07 +01:00
zadam
350cb52c07 Merge pull request #249 from nicoulaj/master
fix #248: crossorigin attribute is needed when including with type="module"
2018-12-02 00:27:59 +01:00
azivner
af195beb7e initial mac support + some other build changes 2018-12-02 00:26:45 +01:00
Julien Nicoulaud
cb00d42546 fix #248: crossorigin attribute is needed when including with type="module"
For more info, see:
 * https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes
 * https://jakearchibald.com/2017/es-modules-in-browsers
2018-12-01 23:33:23 +01:00
azivner
ee0b0c3dfe minor export fixes 2018-11-30 22:43:03 +01:00
azivner
ddcb4a0e10 added another mime type for JS 2018-11-30 22:28:30 +01:00
azivner
8cbb29ee25 default location for data dir is now .local for linux and Roaming for windows 2018-11-30 19:56:20 +01:00
azivner
9da11ac144 electron 4 beta 8 2018-11-30 17:50:38 +01:00
azivner
ba7c8e77e5 add support for number precision in promoted attributes, closes #245 2018-11-30 17:36:41 +01:00
azivner
4577b03fc9 promoted attributes now use saved indicator (little check) instead of notification 2018-11-30 17:18:19 +01:00
azivner
72d83aa85e fix note cache - note entity after initialization doesn't contain ciphertext so decryption is not necessary 2018-11-30 15:51:55 +01:00
azivner
8ee80cb5f1 using dashes instead of underscores in header names to avoid the fact that nginx by default drops all headers with underscore in the header name 2018-11-30 15:49:35 +01:00
azivner
4cc08bff8b minor node updates in docker and server package 2018-11-30 13:56:36 +01:00
zadam
295cfb2d75 Merge pull request #247 from gabe565/master
Smaller Docker image
2018-11-30 13:38:47 +01:00
azivner
7775376b33 disable "cut to note" feature because of issues with CKEditor 2018-11-30 11:37:33 +01:00
azivner
9f64e994dc fix minor UI issue causing children overview not being decrypted right after entering protected session 2018-11-30 10:33:40 +01:00
azivner
ee1e4fc710 added "update pojo" stage in entity saving to avoid encrypting data on protected note directly on the entity 2018-11-30 10:20:03 +01:00
Gabe Cook
5ea62c710d Move devtron to devDependencies and update package-lock.json 2018-11-30 05:46:55 +00:00
Gabe Cook
aeca31d06a Add .git, bin, and docs to the .dockerignore 2018-11-30 05:46:49 +00:00
Gabe Cook
9cb9ea6ab5 Smaller Docker image by switching the base image to node:10.13.0-alpine and consolidating scripts 2018-11-30 05:41:53 +00:00
azivner
e37dd69827 link to Patterns of personal knowledge base 2018-11-28 22:05:23 +01:00
azivner
6c51696d1a also don't show "No results" for attr autocomplete 2018-11-27 19:43:34 +01:00
azivner
27787c8f37 attribute name and value autocompletes should not have autoselect since it's OK to enter value not in the autocomplete 2018-11-27 19:40:19 +01:00
azivner
e910595545 updated readme 2018-11-27 19:18:24 +01:00
azivner
a616739805 release 0.24.5 2018-11-27 15:34:15 +01:00
azivner
bea28de6a0 tab on autocomplete doesn't select first item, closes #243 2018-11-27 13:13:06 +01:00
azivner
4e198ca2f0 storing trilium version into export metadata 2018-11-27 10:31:55 +01:00
azivner
2fbd16a0e3 updated demo export according to latest format changes 2018-11-26 23:50:43 +01:00
azivner
76fc49f037 allow import of single HTML file too 2018-11-26 23:47:02 +01:00
azivner
139c99440f export stores note position and some other fixes 2018-11-26 23:39:43 +01:00
azivner
137b9dfa0b fix storing attributes and relinking noteIds 2018-11-26 23:19:19 +01:00
azivner
5f0fdd15eb fix adding sync entities during import 2018-11-26 22:37:59 +01:00
azivner
61e1427b83 fix matching of "b" in the note autcomplete highlighter 2018-11-26 22:35:19 +01:00
azivner
b3aa0ba47c entity events are not triggered on imported entities 2018-11-26 22:27:57 +01:00
azivner
56e2b44c25 fix import 2018-11-26 22:22:16 +01:00
azivner
4d5a17583f happy path tar import now works 2018-11-26 20:30:43 +01:00
azivner
71eda5aa3d import tar archive WIP 2018-11-26 14:47:46 +01:00
azivner
0711ea8dc8 filter out links and relations which are outside of the export 2018-11-25 22:38:09 +01:00
azivner
be206872d1 changed export model to single metadata file per exported .tar 2018-11-25 22:09:52 +01:00
azivner
fcf3fe8dcd tar export can now solve naming conflict 2018-11-25 15:17:28 +01:00
azivner
62dbd4062a on/off button for entering/leaving protected session has been changed to literal buttons 2018-11-25 14:12:33 +01:00
azivner
196e8b4380 extra icons 2018-11-25 14:05:54 +01:00
azivner
551e1255ff export WIP + some unrelated changes 2018-11-25 10:26:45 +01:00
azivner
e09b61d1ac single file export working, tar WIP 2018-11-24 20:58:38 +01:00
azivner
ee23bcc783 unified export dialog, WIP 2018-11-24 14:44:56 +01:00
azivner
3e351bd8d3 better positioning of nonmodal protected session dialog 2018-11-22 21:24:47 +01:00
azivner
0d3bc22d73 fix z-index of notification 2018-11-22 21:19:12 +01:00
azivner
d82898421e less obtrusive saved indicator, fixes #122 2018-11-22 20:25:49 +01:00
azivner
1db2f0c2c5 improved notifications, now with animations, in center and show up properly in the dialogs 2018-11-22 16:08:02 +01:00
azivner
6cd8a2203e create app icon only for electron build 2018-11-22 00:24:33 +01:00
642 changed files with 57288 additions and 59750 deletions

View File

@@ -1,4 +1,7 @@
node_modules
npm-debug.log
dist
.git
.idea
/bin
/dist
/docs
/npm-debug.log
node_modules

7
.gitpod.yml Normal file
View File

@@ -0,0 +1,7 @@
tasks:
- before: nvm install 10 && nvm use 10
init: npm install
command: npm run start
ports:
- port: 8080
onOpen: open-preview

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<dataSource name="document.db">
<database-model serializer="dbm" dbms="SQLITE" family-id="SQLITE" format-version="4.14">
<database-model serializer="dbm" dbms="SQLITE" family-id="SQLITE" format-version="4.15">
<root id="1">
<ServerVersion>3.16.1</ServerVersion>
<ServerVersion>3.25.1</ServerVersion>
</root>
<schema id="2" parent="1" name="main">
<Current>1</Current>
@@ -16,586 +16,764 @@
<table id="8" parent="2" name="branches"/>
<table id="9" parent="2" name="event_log"/>
<table id="10" parent="2" name="links"/>
<table id="11" parent="2" name="note_revisions"/>
<table id="12" parent="2" name="notes"/>
<table id="13" parent="2" name="options"/>
<table id="14" parent="2" name="recent_notes"/>
<table id="15" parent="2" name="source_ids"/>
<table id="16" parent="2" name="sqlite_master">
<table id="11" parent="2" name="note_contents"/>
<table id="12" parent="2" name="note_fulltext_config">
<WithoutRowId>1</WithoutRowId>
</table>
<table id="13" parent="2" name="note_fulltext_content"/>
<table id="14" parent="2" name="note_fulltext_data"/>
<table id="15" parent="2" name="note_fulltext_docsize"/>
<table id="16" parent="2" name="note_fulltext_idx">
<WithoutRowId>1</WithoutRowId>
</table>
<table id="17" parent="2" name="note_revisions"/>
<table id="18" parent="2" name="notes"/>
<table id="19" parent="2" name="options"/>
<table id="20" parent="2" name="recent_notes"/>
<table id="21" parent="2" name="source_ids"/>
<table id="22" parent="2" name="sqlite_master">
<System>1</System>
</table>
<table id="17" parent="2" name="sqlite_sequence">
<table id="23" parent="2" name="sqlite_sequence">
<System>1</System>
</table>
<table id="18" parent="2" name="sync"/>
<column id="19" parent="6" name="apiTokenId">
<table id="24" parent="2" name="sync"/>
<virtual-table id="25" parent="2" name="note_fulltext">
<Module>fts5</Module>
<Arguments>noteId UNINDEXED
title
titleHash UNINDEXED
content
contentHash UNINDEXED</Arguments>
</virtual-table>
<column id="26" parent="6" name="apiTokenId">
<Position>1</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="20" parent="6" name="token">
<column id="27" parent="6" name="token">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="21" parent="6" name="dateCreated">
<column id="28" parent="6" name="utcDateCreated">
<Position>3</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="22" parent="6" name="isDeleted">
<column id="29" parent="6" name="isDeleted">
<Position>4</Position>
<DataType>INT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression>
</column>
<column id="23" parent="6" name="hash">
<column id="30" parent="6" name="hash">
<Position>5</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&quot;&quot;</DefaultExpression>
</column>
<index id="24" parent="6" name="sqlite_autoindex_api_tokens_1">
<index id="31" parent="6" name="sqlite_autoindex_api_tokens_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>apiTokenId</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<key id="25" parent="6">
<key id="32" parent="6">
<ColNames>apiTokenId</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_api_tokens_1</UnderlyingIndexName>
</key>
<column id="26" parent="7" name="attributeId">
<column id="33" parent="7" name="attributeId">
<Position>1</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="27" parent="7" name="noteId">
<column id="34" parent="7" name="noteId">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="28" parent="7" name="type">
<column id="35" parent="7" name="type">
<Position>3</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="29" parent="7" name="name">
<column id="36" parent="7" name="name">
<Position>4</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="30" parent="7" name="value">
<column id="37" parent="7" name="value">
<Position>5</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&apos;&apos;</DefaultExpression>
</column>
<column id="31" parent="7" name="position">
<column id="38" parent="7" name="position">
<Position>6</Position>
<DataType>INT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression>
</column>
<column id="32" parent="7" name="dateCreated">
<column id="39" parent="7" name="utcDateCreated">
<Position>7</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="33" parent="7" name="dateModified">
<column id="40" parent="7" name="utcDateModified">
<Position>8</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="34" parent="7" name="isDeleted">
<column id="41" parent="7" name="isDeleted">
<Position>9</Position>
<DataType>INT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="35" parent="7" name="hash">
<column id="42" parent="7" name="hash">
<Position>10</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&quot;&quot;</DefaultExpression>
</column>
<column id="36" parent="7" name="isInheritable">
<column id="43" parent="7" name="isInheritable">
<Position>11</Position>
<DataType>int|0s</DataType>
<DefaultExpression>0</DefaultExpression>
</column>
<index id="37" parent="7" name="sqlite_autoindex_attributes_1">
<index id="44" parent="7" name="sqlite_autoindex_attributes_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>attributeId</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<key id="38" parent="7">
<index id="45" parent="7" name="IDX_attributes_noteId_index">
<ColNames>noteId</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<index id="46" parent="7" name="IDX_attributes_name_value">
<ColNames>name
value</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<index id="47" parent="7" name="IDX_attributes_name_index">
<ColNames>name</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<index id="48" parent="7" name="IDX_attributes_value_index">
<ColNames>value</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<key id="49" parent="7">
<ColNames>attributeId</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_attributes_1</UnderlyingIndexName>
</key>
<column id="39" parent="8" name="branchId">
<column id="50" parent="8" name="branchId">
<Position>1</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="40" parent="8" name="noteId">
<column id="51" parent="8" name="noteId">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="41" parent="8" name="parentNoteId">
<column id="52" parent="8" name="parentNoteId">
<Position>3</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="42" parent="8" name="notePosition">
<column id="53" parent="8" name="notePosition">
<Position>4</Position>
<DataType>INTEGER|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="43" parent="8" name="prefix">
<column id="54" parent="8" name="prefix">
<Position>5</Position>
<DataType>TEXT|0s</DataType>
</column>
<column id="44" parent="8" name="isExpanded">
<column id="55" parent="8" name="isExpanded">
<Position>6</Position>
<DataType>BOOLEAN|0s</DataType>
</column>
<column id="45" parent="8" name="isDeleted">
<column id="56" parent="8" name="isDeleted">
<Position>7</Position>
<DataType>INTEGER|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression>
</column>
<column id="46" parent="8" name="dateModified">
<column id="57" parent="8" name="utcDateModified">
<Position>8</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="47" parent="8" name="hash">
<column id="58" parent="8" name="utcDateCreated">
<Position>9</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="59" parent="8" name="hash">
<Position>10</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&quot;&quot;</DefaultExpression>
</column>
<column id="48" parent="8" name="dateCreated">
<Position>10</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&apos;1970-01-01T00:00:00.000Z&apos;</DefaultExpression>
</column>
<index id="49" parent="8" name="sqlite_autoindex_branches_1">
<index id="60" parent="8" name="sqlite_autoindex_branches_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>branchId</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<index id="50" parent="8" name="IDX_branches_noteId_parentNoteId">
<index id="61" parent="8" name="IDX_branches_noteId_parentNoteId">
<ColNames>noteId
parentNoteId</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<index id="51" parent="8" name="IDX_branches_noteId">
<index id="62" parent="8" name="IDX_branches_noteId">
<ColNames>noteId</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<index id="52" parent="8" name="IDX_branches_parentNoteId">
<index id="63" parent="8" name="IDX_branches_parentNoteId">
<ColNames>parentNoteId</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<key id="53" parent="8">
<key id="64" parent="8">
<ColNames>branchId</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_branches_1</UnderlyingIndexName>
</key>
<column id="54" parent="9" name="eventId">
<column id="65" parent="9" name="eventId">
<Position>1</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="55" parent="9" name="noteId">
<column id="66" parent="9" name="noteId">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
</column>
<column id="56" parent="9" name="comment">
<column id="67" parent="9" name="comment">
<Position>3</Position>
<DataType>TEXT|0s</DataType>
</column>
<column id="57" parent="9" name="dateCreated">
<column id="68" parent="9" name="utcDateCreated">
<Position>4</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<index id="58" parent="9" name="sqlite_autoindex_event_log_1">
<index id="69" parent="9" name="sqlite_autoindex_event_log_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>eventId</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<key id="59" parent="9">
<key id="70" parent="9">
<ColNames>eventId</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_event_log_1</UnderlyingIndexName>
</key>
<column id="60" parent="10" name="linkId">
<column id="71" parent="10" name="linkId">
<Position>1</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="61" parent="10" name="noteId">
<column id="72" parent="10" name="noteId">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="62" parent="10" name="targetNoteId">
<column id="73" parent="10" name="targetNoteId">
<Position>3</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="63" parent="10" name="type">
<column id="74" parent="10" name="type">
<Position>4</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="64" parent="10" name="isDeleted">
<column id="75" parent="10" name="hash">
<Position>5</Position>
<DataType>INTEGER|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression>
</column>
<column id="65" parent="10" name="dateCreated">
<Position>6</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="66" parent="10" name="dateModified">
<Position>7</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="67" parent="10" name="hash">
<Position>8</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&quot;&quot;</DefaultExpression>
</column>
<index id="68" parent="10" name="sqlite_autoindex_links_1">
<column id="76" parent="10" name="isDeleted">
<Position>6</Position>
<DataType>INTEGER|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression>
</column>
<column id="77" parent="10" name="utcDateCreated">
<Position>7</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="78" parent="10" name="utcDateModified">
<Position>8</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<index id="79" parent="10" name="sqlite_autoindex_links_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>linkId</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<key id="69" parent="10">
<index id="80" parent="10" name="IDX_links_noteId_index">
<ColNames>noteId</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<index id="81" parent="10" name="IDX_links_targetNoteId_index">
<ColNames>targetNoteId</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<key id="82" parent="10">
<ColNames>linkId</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_links_1</UnderlyingIndexName>
</key>
<column id="70" parent="11" name="noteRevisionId">
<column id="83" parent="11" name="noteId">
<Position>1</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="71" parent="11" name="noteId">
<column id="84" parent="11" name="content">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
<DefaultExpression>NULL</DefaultExpression>
</column>
<column id="85" parent="11" name="hash">
<Position>3</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&quot;&quot;</DefaultExpression>
</column>
<column id="86" parent="11" name="utcDateModified">
<Position>4</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<index id="87" parent="11" name="sqlite_autoindex_note_contents_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>noteId</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<key id="88" parent="11">
<ColNames>noteId</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_note_contents_1</UnderlyingIndexName>
</key>
<column id="89" parent="12" name="k">
<Position>1</Position>
<NotNull>1</NotNull>
</column>
<column id="90" parent="12" name="v">
<Position>2</Position>
</column>
<index id="91" parent="12" name="sqlite_autoindex_note_fulltext_config_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>k</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<key id="92" parent="12">
<ColNames>k</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_note_fulltext_config_1</UnderlyingIndexName>
</key>
<column id="93" parent="13" name="id">
<Position>1</Position>
<DataType>INTEGER|0s</DataType>
</column>
<column id="94" parent="13" name="c0">
<Position>2</Position>
</column>
<column id="95" parent="13" name="c1">
<Position>3</Position>
</column>
<column id="96" parent="13" name="c2">
<Position>4</Position>
</column>
<column id="97" parent="13" name="c3">
<Position>5</Position>
</column>
<column id="98" parent="13" name="c4">
<Position>6</Position>
</column>
<key id="99" parent="13">
<ColNames>id</ColNames>
<Primary>1</Primary>
</key>
<column id="100" parent="14" name="id">
<Position>1</Position>
<DataType>INTEGER|0s</DataType>
</column>
<column id="101" parent="14" name="block">
<Position>2</Position>
<DataType>BLOB|0s</DataType>
</column>
<key id="102" parent="14">
<ColNames>id</ColNames>
<Primary>1</Primary>
</key>
<column id="103" parent="15" name="id">
<Position>1</Position>
<DataType>INTEGER|0s</DataType>
</column>
<column id="104" parent="15" name="sz">
<Position>2</Position>
<DataType>BLOB|0s</DataType>
</column>
<key id="105" parent="15">
<ColNames>id</ColNames>
<Primary>1</Primary>
</key>
<column id="106" parent="16" name="segid">
<Position>1</Position>
<NotNull>1</NotNull>
</column>
<column id="107" parent="16" name="term">
<Position>2</Position>
<NotNull>1</NotNull>
</column>
<column id="108" parent="16" name="pgno">
<Position>3</Position>
</column>
<index id="109" parent="16" name="sqlite_autoindex_note_fulltext_idx_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>segid
term</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<key id="110" parent="16">
<ColNames>segid
term</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_note_fulltext_idx_1</UnderlyingIndexName>
</key>
<column id="111" parent="17" name="noteRevisionId">
<Position>1</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="112" parent="17" name="noteId">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="72" parent="11" name="title">
<column id="113" parent="17" name="title">
<Position>3</Position>
<DataType>TEXT|0s</DataType>
</column>
<column id="73" parent="11" name="content">
<column id="114" parent="17" name="content">
<Position>4</Position>
<DataType>TEXT|0s</DataType>
</column>
<column id="74" parent="11" name="isProtected">
<column id="115" parent="17" name="isProtected">
<Position>5</Position>
<DataType>INT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression>
</column>
<column id="75" parent="11" name="dateModifiedFrom">
<column id="116" parent="17" name="utcDateModifiedFrom">
<Position>6</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="76" parent="11" name="dateModifiedTo">
<column id="117" parent="17" name="utcDateModifiedTo">
<Position>7</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="77" parent="11" name="type">
<column id="118" parent="17" name="dateModifiedFrom">
<Position>8</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&apos;&apos;</DefaultExpression>
</column>
<column id="78" parent="11" name="mime">
<column id="119" parent="17" name="dateModifiedTo">
<Position>9</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="120" parent="17" name="type">
<Position>10</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&apos;&apos;</DefaultExpression>
</column>
<column id="79" parent="11" name="hash">
<Position>10</Position>
<column id="121" parent="17" name="mime">
<Position>11</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&apos;&apos;</DefaultExpression>
</column>
<column id="122" parent="17" name="hash">
<Position>12</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&quot;&quot;</DefaultExpression>
</column>
<index id="80" parent="11" name="sqlite_autoindex_note_revisions_1">
<index id="123" parent="17" name="sqlite_autoindex_note_revisions_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>noteRevisionId</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<index id="81" parent="11" name="IDX_note_revisions_noteId">
<index id="124" parent="17" name="IDX_note_revisions_noteId">
<ColNames>noteId</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<index id="82" parent="11" name="IDX_note_revisions_dateModifiedFrom">
<ColNames>dateModifiedFrom</ColNames>
<index id="125" parent="17" name="IDX_note_revisions_dateModifiedFrom">
<ColNames>utcDateModifiedFrom</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<index id="83" parent="11" name="IDX_note_revisions_dateModifiedTo">
<ColNames>dateModifiedTo</ColNames>
<index id="126" parent="17" name="IDX_note_revisions_dateModifiedTo">
<ColNames>utcDateModifiedTo</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<key id="84" parent="11">
<key id="127" parent="17">
<ColNames>noteRevisionId</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_note_revisions_1</UnderlyingIndexName>
</key>
<column id="85" parent="12" name="noteId">
<column id="128" parent="18" name="noteId">
<Position>1</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="86" parent="12" name="title">
<column id="129" parent="18" name="title">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&quot;note&quot;</DefaultExpression>
</column>
<column id="87" parent="12" name="content">
<column id="130" parent="18" name="isProtected">
<Position>3</Position>
<DataType>TEXT|0s</DataType>
<DefaultExpression>NULL</DefaultExpression>
</column>
<column id="88" parent="12" name="isProtected">
<Position>4</Position>
<DataType>INT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression>
</column>
<column id="89" parent="12" name="type">
<Position>5</Position>
<column id="131" parent="18" name="type">
<Position>4</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&apos;text&apos;</DefaultExpression>
</column>
<column id="90" parent="12" name="mime">
<Position>6</Position>
<column id="132" parent="18" name="mime">
<Position>5</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&apos;text/html&apos;</DefaultExpression>
</column>
<column id="91" parent="12" name="hash">
<Position>7</Position>
<column id="133" parent="18" name="hash">
<Position>6</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&quot;&quot;</DefaultExpression>
</column>
<column id="92" parent="12" name="isDeleted">
<Position>8</Position>
<column id="134" parent="18" name="isDeleted">
<Position>7</Position>
<DataType>INT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression>
</column>
<column id="93" parent="12" name="dateCreated">
<column id="135" parent="18" name="dateCreated">
<Position>8</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="136" parent="18" name="dateModified">
<Position>9</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="94" parent="12" name="dateModified">
<column id="137" parent="18" name="utcDateCreated">
<Position>10</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<index id="95" parent="12" name="sqlite_autoindex_notes_1">
<column id="138" parent="18" name="utcDateModified">
<Position>11</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<index id="139" parent="18" name="sqlite_autoindex_notes_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>noteId</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<key id="96" parent="12">
<key id="140" parent="18">
<ColNames>noteId</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_notes_1</UnderlyingIndexName>
</key>
<column id="97" parent="13" name="name">
<column id="141" parent="19" name="name">
<Position>1</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="98" parent="13" name="value">
<column id="142" parent="19" name="value">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
</column>
<column id="99" parent="13" name="dateModified">
<column id="143" parent="19" name="isSynced">
<Position>3</Position>
<DataType>INT|0s</DataType>
</column>
<column id="100" parent="13" name="isSynced">
<Position>4</Position>
<DataType>INTEGER|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression>
</column>
<column id="101" parent="13" name="hash">
<Position>5</Position>
<column id="144" parent="19" name="hash">
<Position>4</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&quot;&quot;</DefaultExpression>
</column>
<column id="102" parent="13" name="dateCreated">
<column id="145" parent="19" name="utcDateCreated">
<Position>5</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="146" parent="19" name="utcDateModified">
<Position>6</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&apos;1970-01-01T00:00:00.000Z&apos;</DefaultExpression>
</column>
<index id="103" parent="13" name="sqlite_autoindex_options_1">
<index id="147" parent="19" name="sqlite_autoindex_options_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>name</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<key id="104" parent="13">
<key id="148" parent="19">
<ColNames>name</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_options_1</UnderlyingIndexName>
</key>
<column id="105" parent="14" name="branchId">
<column id="149" parent="20" name="branchId">
<Position>1</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="106" parent="14" name="notePath">
<column id="150" parent="20" name="notePath">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="107" parent="14" name="hash">
<column id="151" parent="20" name="hash">
<Position>3</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>&quot;&quot;</DefaultExpression>
</column>
<column id="108" parent="14" name="dateCreated">
<column id="152" parent="20" name="utcDateCreated">
<Position>4</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="109" parent="14" name="isDeleted">
<column id="153" parent="20" name="isDeleted">
<Position>5</Position>
<DataType>INT|0s</DataType>
</column>
<index id="110" parent="14" name="sqlite_autoindex_recent_notes_1">
<index id="154" parent="20" name="sqlite_autoindex_recent_notes_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>branchId</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<key id="111" parent="14">
<key id="155" parent="20">
<ColNames>branchId</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_recent_notes_1</UnderlyingIndexName>
</key>
<column id="112" parent="15" name="sourceId">
<column id="156" parent="21" name="sourceId">
<Position>1</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="113" parent="15" name="dateCreated">
<column id="157" parent="21" name="utcDateCreated">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<index id="114" parent="15" name="sqlite_autoindex_source_ids_1">
<index id="158" parent="21" name="sqlite_autoindex_source_ids_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>sourceId</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<key id="115" parent="15">
<key id="159" parent="21">
<ColNames>sourceId</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_source_ids_1</UnderlyingIndexName>
</key>
<column id="116" parent="16" name="type">
<column id="160" parent="22" name="type">
<Position>1</Position>
<DataType>text|0s</DataType>
</column>
<column id="117" parent="16" name="name">
<column id="161" parent="22" name="name">
<Position>2</Position>
<DataType>text|0s</DataType>
</column>
<column id="118" parent="16" name="tbl_name">
<column id="162" parent="22" name="tbl_name">
<Position>3</Position>
<DataType>text|0s</DataType>
</column>
<column id="119" parent="16" name="rootpage">
<column id="163" parent="22" name="rootpage">
<Position>4</Position>
<DataType>integer|0s</DataType>
<DataType>int|0s</DataType>
</column>
<column id="120" parent="16" name="sql">
<column id="164" parent="22" name="sql">
<Position>5</Position>
<DataType>text|0s</DataType>
</column>
<column id="121" parent="17" name="name">
<column id="165" parent="23" name="name">
<Position>1</Position>
</column>
<column id="122" parent="17" name="seq">
<column id="166" parent="23" name="seq">
<Position>2</Position>
</column>
<column id="123" parent="18" name="id">
<column id="167" parent="24" name="id">
<Position>1</Position>
<DataType>INTEGER|0s</DataType>
<NotNull>1</NotNull>
<SequenceIdentity>1</SequenceIdentity>
</column>
<column id="124" parent="18" name="entityName">
<column id="168" parent="24" name="entityName">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="125" parent="18" name="entityId">
<column id="169" parent="24" name="entityId">
<Position>3</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="126" parent="18" name="sourceId">
<column id="170" parent="24" name="sourceId">
<Position>4</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="127" parent="18" name="syncDate">
<column id="171" parent="24" name="utcSyncDate">
<Position>5</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<index id="128" parent="18" name="IDX_sync_entityName_entityId">
<index id="172" parent="24" name="IDX_sync_entityName_entityId">
<ColNames>entityName
entityId</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<index id="129" parent="18" name="IDX_sync_syncDate">
<ColNames>syncDate</ColNames>
<index id="173" parent="24" name="IDX_sync_utcSyncDate">
<ColNames>utcSyncDate</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<key id="130" parent="18">
<key id="174" parent="24">
<ColNames>id</ColNames>
<Primary>1</Primary>
</key>

View File

@@ -1,21 +1,28 @@
FROM node:10.13.0
RUN apt-get update && apt-get install -y nasm
FROM node:10.15.3-alpine
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# Copy both package.json and package-lock.json
# where available (npm@5+)
COPY package*.json ./
COPY package.json package-lock.json ./
RUN npm install --production
# If you are building your code for production
# RUN npm install --only=production
# Install app dependencies
RUN set -x \
&& apk add --no-cache --virtual .build-dependencies \
autoconf \
automake \
g++ \
gcc \
libtool \
make \
nasm \
libpng-dev \
&& npm install --production \
&& apk del .build-dependencies
# Bundle app source
COPY . .
EXPOSE 8080
CMD [ "node", "src/www" ]
CMD [ "node", "./src/www" ]

View File

@@ -1,37 +1,49 @@
# Trilium Notes
[![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)
Trilium Notes is a hierarchical note taking application. Picture tells a thousand words:
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:
![](https://raw.githubusercontent.com/wiki/zadam/trilium/images/screenshot.png)
See other pictures in [screenshot tour](https://github.com/zadam/trilium/wiki/Screenshot-tour).
## Features
* Notes can be arranged into arbitrarily deep hierarchy (tree)
* Notes can have more than 1 parents - see [cloning](https://github.com/zadam/trilium/wiki/Cloning-notes)
* Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see [cloning](https://github.com/zadam/trilium/wiki/Cloning-notes))
* Rich WYSIWYG note editing including e.g. tables and images with markdown [autoformat](https://github.com/zadam/trilium/wiki/Text-editor#autoformat)
* Support for editing [notes with source code](https://github.com/zadam/trilium/wiki/Code-notes), including syntax highlighting
* Fast and easy [navigation between notes](https://github.com/zadam/trilium/wiki/Note-navigation)
* Fast and easy [navigation between notes](https://github.com/zadam/trilium/wiki/Note-navigation), full text search and [note hoisting](https://github.com/zadam/trilium/wiki/Note-hoisting)
* Seamless [note versioning](https://github.com/zadam/trilium/wiki/Note-revisions)
* Note [attributes](https://github.com/zadam/trilium/wiki/Attributes) can be used for note organization, querying and advanced [scripting](https://github.com/zadam/trilium/wiki/Scripts)
* [Synchronization](https://github.com/zadam/trilium/wiki/Synchronization) with self-hosted sync server
* Strong [note encryption](https://github.com/zadam/trilium/wiki/Protected-notes)
* Strong [note encryption](https://github.com/zadam/trilium/wiki/Protected-notes) with per-note granularity
* [Relation maps](https://github.com/zadam/trilium/wiki/Relation-map) for visualizing notes and their relations
* [Scripting](https://github.com/zadam/trilium/wiki/Scripts) - see [Advanced showcases](https://github.com/zadam/trilium/wiki/Advanced-showcases)
* Scales well in both usability and performance upwards of 100 000 notes
* Touch optimized [mobile frontend](https://github.com/zadam/trilium/wiki/Mobile-frontend) for smartphones and tablets
* [Night theme](https://github.com/zadam/trilium/wiki/Themes)
* [Evernote](https://github.com/zadam/trilium/wiki/Evernote-import) and [Markdown import & export](https://github.com/zadam/trilium/wiki/Markdown)
## Builds
Trilium is provided as either desktop application ([Electron](https://electronjs.org)-based) or web application hosted on your server.
Trilium is provided as either desktop application (Linux, Windows, Mac) or web application hosted on your server (Linux).
* If you want to use Trilium on the desktop, download binary release for your platform (currently Linux and Windows are supported) from [latest release](https://github.com/zadam/trilium/releases/latest), unzip the package and run ```trilium``` executable.
* If you want to use Trilium on the desktop, download binary release for your platform from [latest release](https://github.com/zadam/trilium/releases/latest), unzip the package and run ```trilium``` executable.
* If you want to install Trilium on server, follow [this page](https://github.com/zadam/trilium/wiki/Server-installation).
* Currently only recent Chrome and Firefox are supported (tested) browsers.
## Documentation
[See wiki for complete list of documentation pages.](https://github.com/zadam/trilium/wiki/)
You can also read [Patterns of personal knowledge base](https://github.com/zadam/trilium/wiki/Patterns-of-personal-knowledge-base) to get some inspiration on how you might use Trilium.
## Contribute
Use a browser based dev environment
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/zadam/trilium)
Or clone locally and run
```
npm install
npm run start
```

7
bin/build-debian.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env bash
echo "Packaging debian x64 distribution..."
VERSION=`jq -r ".version" package.json`
./node_modules/.bin/electron-installer-debian --config bin/deb-options.json --options.version=${VERSION} --arch amd64

View File

@@ -1,8 +1,5 @@
#!/usr/bin/env bash
if [[ $# -eq 0 ]] ; then
echo "Missing argument of new version"
exit 1
fi
VERSION=`jq -r ".version" package.json`
sudo docker build -t zadam/trilium:latest -t zadam/trilium:$1 .
sudo docker build -t zadam/trilium:latest -t zadam/trilium:$VERSION .

24
bin/build-linux-x64.sh Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
BUILD_DIR=./dist/trilium-linux-x64
rm -rf $BUILD_DIR
rm -r node_modules/sqlite3/lib/binding/*
cp -r bin/deps/linux-x64/sqlite/* node_modules/sqlite3/lib/binding/
./node_modules/.bin/electron-packager . --asar --out=dist --executable-name=trilium --platform=linux --arch=x64 --overwrite
mv "./dist/Trilium Notes-linux-x64" $BUILD_DIR
cp images/app-icons/png/128x128.png $BUILD_DIR/icon.png
# removing software WebGL binaries because they are pretty huge and not necessary
rm -r $BUILD_DIR/swiftshader
echo "Packaging linux x64 electron distribution..."
VERSION=`jq -r ".version" package.json`
cd dist
tar cJf trilium-linux-x64-${VERSION}.tar.xz trilium-linux-x64

32
bin/build-mac-x64.sh Executable file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/env bash
BUILD_DIR=./dist/trilium-mac-x64
rm -rf $BUILD_DIR
echo "Copying required mac binaries"
rm -r node_modules/sqlite3/lib/binding/*
rm -r node_modules/mozjpeg/vendor/*
rm -r node_modules/pngquant-bin/vendor/*
rm -r node_modules/giflossy/vendor/*
cp -r bin/deps/mac-x64/sqlite/* node_modules/sqlite3/lib/binding/
cp bin/deps/mac-x64/image/cjpeg node_modules/mozjpeg/vendor/
cp bin/deps/mac-x64/image/pngquant node_modules/pngquant-bin/vendor/
cp bin/deps/mac-x64/image/gifsicle node_modules/giflossy/vendor/
./node_modules/.bin/electron-packager . --asar --out=dist --executable-name=trilium --platform=darwin --arch=x64 --overwrite --icon=images/app-icons/mac/icon.icns
# Mac build has by default useless directory level
mv "./dist/Trilium Notes-darwin-x64" $BUILD_DIR
./bin/reset-local.sh
echo "Zipping mac x64 electron distribution..."
VERSION=`jq -r ".version" package.json`
cd dist
rm trilium-mac-x64-${VERSION}.zip
zip -r9 --symlinks trilium-mac-x64-${VERSION}.zip trilium-mac-x64

View File

@@ -1,13 +1,7 @@
#!/usr/bin/env bash
if [[ $# -eq 0 ]] ; then
echo "Missing argument of new version"
exit 1
fi
VERSION=$1
PKG_DIR=dist/trilium-linux-x64-server
NODE_VERSION=10.13.0
NODE_VERSION=10.15.3
rm -r $PKG_DIR
mkdir $PKG_DIR
@@ -30,9 +24,15 @@ cp -r ../../config-sample.ini ./
rm -r ./node_modules/electron*
rm -r ./node_modules/sqlite3/lib/binding/*
cp -r ../../bin/deps/linux-x64/sqlite/node* ./node_modules/sqlite3/lib/binding/
printf "#/bin/sh\n./node/bin/node src/www" > trilium.sh
chmod 755 trilium.sh
cd ..
7z a trilium-linux-x64-server-${VERSION}.7z trilium-linux-x64-server
VERSION=`jq -r ".version" ../package.json`
tar cJf trilium-linux-x64-server-${VERSION}.tar.xz trilium-linux-x64-server

32
bin/build-win-x64.sh Executable file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/env bash
BUILD_DIR=./dist/trilium-windows-x64
rm -rf $BUILD_DIR
echo "Copying required windows binaries"
rm -r node_modules/sqlite3/lib/binding/*
rm -r node_modules/mozjpeg/vendor/*
rm -r node_modules/pngquant-bin/vendor/*
rm -r node_modules/giflossy/vendor/*
cp -r bin/deps/win-x64/sqlite/* node_modules/sqlite3/lib/binding/
cp bin/deps/win-x64/image/cjpeg.exe node_modules/mozjpeg/vendor/
cp bin/deps/win-x64/image/pngquant.exe node_modules/pngquant-bin/vendor/
cp bin/deps/win-x64/image/gifsicle.exe node_modules/giflossy/vendor/
./node_modules/.bin/electron-packager . --asar --out=dist --executable-name=trilium --platform=win32 --arch=x64 --overwrite --icon=images/app-icons/win/icon.ico
mv "./dist/Trilium Notes-win32-x64" $BUILD_DIR
# removing software WebGL binaries because they are pretty huge and not necessary
rm -r $BUILD_DIR/swiftshader
./bin/reset-local.sh
echo "Zipping windows x64 electron distribution..."
VERSION=`jq -r ".version" package.json`
cd dist
zip -r9 trilium-windows-x64-${VERSION}.zip trilium-windows-x64

View File

@@ -8,36 +8,14 @@ echo "Deleting existing builds"
rm -r dist/*
echo "Rebuilding binaries for linux-ia32"
./node_modules/.bin/electron-rebuild --arch=ia32
bin/build-win-x64.sh
./node_modules/.bin/electron-packager . --out=dist --executable-name=trilium --platform=linux --arch=ia32 --overwrite
bin/build-mac-x64.sh
mv "./dist/Trilium Notes-linux-ia32" ./dist/trilium-linux-ia32
# building X64 linux as the last so electron-rebuild will prepare X64 binaries for local development
bin/build-linux-x64.sh
./node_modules/.bin/electron-packager . --out=dist --executable-name=trilium --platform=win32 --arch=x64 --overwrite --icon=src/public/images/app-icons/win/icon.ico
# this needs to be run after linux build
bin/build-debian.sh
mv "./dist/Trilium Notes-win32-x64" ./dist/trilium-win32-x64
# we build x64 as second so that we keep X64 binaries in node_modules for local development and server build
echo "Rebuilding binaries for linux-x64"
./node_modules/.bin/electron-rebuild --arch=x64
./node_modules/.bin/electron-packager . --out=dist --executable-name=trilium --platform=linux --arch=x64 --overwrite
mv "./dist/Trilium Notes-linux-x64" ./dist/trilium-linux-x64
echo "Copying required windows binaries"
WIN_RES_DIR=./dist/trilium-win32-x64/resources/app
cp -r bin/deps/sqlite/* $WIN_RES_DIR/node_modules/sqlite3/lib/binding/
cp bin/deps/image/cjpeg.exe $WIN_RES_DIR/node_modules/mozjpeg/vendor/
cp bin/deps/image/pngquant.exe $WIN_RES_DIR/node_modules/pngquant-bin/vendor/
cp bin/deps/image/gifsicle.exe $WIN_RES_DIR/node_modules/giflossy/vendor/
echo "Cleaning up unnecessary binaries from all builds"
rm -r ./dist/trilium-linux-ia32/resources/app/bin/deps
rm -r ./dist/trilium-linux-x64/resources/app/bin/deps
rm -r ./dist/trilium-win32-x64/resources/app/bin/deps
bin/build-server.sh

14
bin/deb-options.json Normal file
View File

@@ -0,0 +1,14 @@
{
"src": "dist/trilium-linux-x64",
"dest": "dist/",
"name": "trilium",
"productName": "Trilium Notes",
"genericName": "Note taker",
"description": "Trilium Notes is a hierarchical note taking application with focus on building large personal knowledge bases.",
"sections": "misc",
"maintainer": "zadam.apps@gmail.com",
"homepage": "https://github.com/zadam/trilium",
"bin": "trilium",
"icon": "dist/trilium-linux-x64/icon.png",
"categories": [ "Office" ]
}

BIN
bin/deps/mac-x64/image/cjpeg Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

View File

@@ -2,6 +2,6 @@
SCHEMA_FILE_PATH=db/schema.sql
sqlite3 ~/trilium-data/document.db .schema | grep -v "sqlite_sequence" > "$SCHEMA_FILE_PATH"
sqlite3 ~/trilium-data/document.db .schema | grep -v "sqlite_sequence" | grep -v "note_fulltext_" > "$SCHEMA_FILE_PATH"
echo "DB schema exported to $SCHEMA_FILE_PATH"

0
bin/generate-cert.sh Normal file → Executable file
View File

View File

@@ -1,14 +0,0 @@
#!/usr/bin/env bash
VERSION=`jq -r ".version" package.json`
cd dist
echo "Packaging linux x64 electron distribution..."
7z a trilium-linux-x64-${VERSION}.7z trilium-linux-x64
echo "Packaging linux ia32 electron distribution..."
7z a trilium-linux-ia32-${VERSION}.7z trilium-linux-ia32
echo "Packaging windows x64 electron distribution..."
7z a trilium-windows-x64-${VERSION}.7z trilium-win32-x64

View File

@@ -42,18 +42,30 @@ git push origin $TAG
bin/build.sh
bin/package.sh
LINUX_X64_BUILD=trilium-linux-x64-$VERSION.7z
LINUX_IA32_BUILD=trilium-linux-ia32-$VERSION.7z
WINDOWS_X64_BUILD=trilium-windows-x64-$VERSION.7z
SERVER_BUILD=trilium-linux-x64-server-$VERSION.7z
LINUX_X64_BUILD=trilium-linux-x64-$VERSION.tar.xz
DEBIAN_X64_BUILD=trilium_${VERSION}_amd64.deb
WINDOWS_X64_BUILD=trilium-windows-x64-$VERSION.zip
MAC_X64_BUILD=trilium-mac-x64-$VERSION.zip
SERVER_BUILD=trilium-linux-x64-server-$VERSION.tar.xz
echo "Creating release in GitHub"
EXTRA=
if [[ $TAG == *"beta"* ]]; then
EXTRA=--pre-release
fi
github-release release \
--tag $TAG \
--name "$TAG release"
--name "$TAG release" $EXTRA
echo "Uploading debian x64 package"
github-release upload \
--tag $TAG \
--name "$DEBIAN_X64_BUILD" \
--file "dist/$DEBIAN_X64_BUILD"
echo "Uploading linux x64 build"
@@ -62,13 +74,6 @@ github-release upload \
--name "$LINUX_X64_BUILD" \
--file "dist/$LINUX_X64_BUILD"
echo "Uploading linux ia32 build"
github-release upload \
--tag $TAG \
--name "$LINUX_IA32_BUILD" \
--file "dist/$LINUX_IA32_BUILD"
echo "Uploading windows x64 build"
github-release upload \
@@ -76,9 +81,14 @@ github-release upload \
--name "$WINDOWS_X64_BUILD" \
--file "dist/$WINDOWS_X64_BUILD"
echo "Packaging server version"
echo "Uploading mac x64 build"
bin/build-server.sh $VERSION
github-release upload \
--tag $TAG \
--name "$MAC_X64_BUILD" \
--file "dist/$MAC_X64_BUILD"
echo "Uploading linux x64 server build"
github-release upload \
--tag $TAG \

3
bin/reset-local.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/env bash
./node_modules/.bin/electron-rebuild --arch=x64

Binary file not shown.

View File

@@ -0,0 +1 @@
UPDATE attributes SET name = 'archived' where name = 'hideInAutocomplete';

View File

@@ -0,0 +1,2 @@
INSERT INTO options (name, value, dateCreated, dateModified, isSynced)
VALUES ('hoistedNoteId', 'root', '2018-12-11T18:31:00.874Z', '2018-12-11T18:31:00.874Z', 0);

View File

@@ -0,0 +1,62 @@
const sql = require('../../src/services/sql');
function prependIv(cipherText, ivText) {
const arr = ivText.split("").map(c => parseInt(c) || 0);
const iv = Buffer.from(arr);
const payload = Buffer.from(cipherText, 'base64');
const complete = Buffer.concat([iv, payload]);
return complete.toString('base64');
}
async function updateEncryptedDataKey() {
const encryptedDataKey = await sql.getValue("SELECT value FROM options WHERE name = 'encryptedDataKey'");
const encryptedDataKeyIv = await sql.getValue("SELECT value FROM options WHERE name = 'encryptedDataKeyIv'");
const newEncryptedDataKey = prependIv(encryptedDataKey, encryptedDataKeyIv);
await sql.execute("UPDATE options SET value = ? WHERE name = 'encryptedDataKey'", [newEncryptedDataKey]);
await sql.execute("DELETE FROM options WHERE name = 'encryptedDataKeyIv'");
await sql.execute("DELETE FROM sync WHERE entityName = 'options' AND entityId = 'encryptedDataKeyIv'");
}
async function updateNotes() {
const protectedNotes = await sql.getRows("SELECT noteId, title, content FROM notes WHERE isProtected = 1");
for (const note of protectedNotes) {
if (note.title !== null) {
note.title = prependIv(note.title, "0" + note.noteId);
}
if (note.content !== null) {
note.content = prependIv(note.content, "1" + note.noteId);
}
await sql.execute("UPDATE notes SET title = ?, content = ? WHERE noteId = ?", [note.title, note.content, note.noteId]);
}
}
async function updateNoteRevisions() {
const protectedNoteRevisions = await sql.getRows("SELECT noteRevisionId, title, content FROM note_revisions WHERE isProtected = 1");
for (const noteRevision of protectedNoteRevisions) {
if (noteRevision.title !== null) {
noteRevision.title = prependIv(noteRevision.title, "0" + noteRevision.noteRevisionId);
}
if (noteRevision.content !== null) {
noteRevision.content = prependIv(noteRevision.content, "1" + noteRevision.noteRevisionId);
}
await sql.execute("UPDATE note_revisions SET title = ?, content = ? WHERE noteRevisionId = ?", [noteRevision.title, noteRevision.content, noteRevision.noteRevisionId]);
}
}
module.exports = async () => {
await updateEncryptedDataKey();
await updateNotes();
await updateNoteRevisions();
};

View File

@@ -0,0 +1,8 @@
INSERT INTO options (name, value, dateCreated, dateModified, isSynced)
VALUES ('mainFontSize', '100', '2019-01-13T18:31:00.874Z', '2019-01-13T18:31:00.874Z', 0);
INSERT INTO options (name, value, dateCreated, dateModified, isSynced)
VALUES ('treeFontSize', '100', '2019-01-13T18:31:00.874Z', '2019-01-13T18:31:00.874Z', 0);
INSERT INTO options (name, value, dateCreated, dateModified, isSynced)
VALUES ('detailFontSize', '110', '2019-01-13T18:31:00.874Z', '2019-01-13T18:31:00.874Z', 0);

View File

@@ -0,0 +1,11 @@
INSERT INTO options (name, value, dateCreated, dateModified, isSynced)
SELECT 'mainFontSize', '100', '2019-01-13T18:31:00.874Z', '2019-01-13T18:31:00.874Z', 0
WHERE NOT EXISTS (SELECT 1 FROM options WHERE name = 'mainFontSize');
INSERT INTO options (name, value, dateCreated, dateModified, isSynced)
SELECT 'treeFontSize', '100', '2019-01-13T18:31:00.874Z', '2019-01-13T18:31:00.874Z', 0
WHERE NOT EXISTS (SELECT 1 FROM options WHERE name = 'treeFontSize');
INSERT INTO options (name, value, dateCreated, dateModified, isSynced)
SELECT 'detailFontSize', '110', '2019-01-13T18:31:00.874Z', '2019-01-13T18:31:00.874Z', 0
WHERE NOT EXISTS (SELECT 1 FROM options WHERE name = 'detailFontSize');

View File

@@ -0,0 +1,35 @@
CREATE TABLE IF NOT EXISTS "note_contents" (
`noteContentId` TEXT NOT NULL,
`noteId` TEXT NOT NULL,
`isProtected` INT NOT NULL DEFAULT 0,
`content` TEXT NULL DEFAULT NULL,
`hash` TEXT DEFAULT "" NOT NULL,
`dateCreated` TEXT NOT NULL,
`dateModified` TEXT NOT NULL,
PRIMARY KEY(`noteContentId`)
);
CREATE UNIQUE INDEX `IDX_note_contents_noteId` ON `note_contents` (`noteId`);
INSERT INTO note_contents (noteContentId, noteId, isProtected, content, dateCreated, dateModified)
SELECT 'C' || SUBSTR(noteId, 2), noteId, isProtected, content, dateCreated, dateModified FROM notes;
CREATE TABLE IF NOT EXISTS "notes_mig" (
`noteId` TEXT NOT NULL,
`title` TEXT NOT NULL DEFAULT "note",
`isProtected` INT NOT NULL DEFAULT 0,
`type` TEXT NOT NULL DEFAULT 'text',
`mime` TEXT NOT NULL DEFAULT 'text/html',
`hash` TEXT DEFAULT "" NOT NULL,
`isDeleted` INT NOT NULL DEFAULT 0,
`dateCreated` TEXT NOT NULL,
`dateModified` TEXT NOT NULL,
PRIMARY KEY(`noteId`)
);
INSERT INTO notes_mig (noteId, title, isProtected, isDeleted, dateCreated, dateModified, type, mime, hash)
SELECT noteId, title, isProtected, isDeleted, dateCreated, dateModified, type, mime, hash FROM notes;
DROP TABLE notes;
ALTER TABLE notes_mig RENAME TO notes;

View File

@@ -0,0 +1,2 @@
INSERT OR REPLACE INTO sync (entityName, entityId, sourceId, syncDate)
SELECT 'note_contents', noteContentId, '', '2019-03-02T18:07:29.182Z' FROM note_contents;

View File

@@ -0,0 +1,6 @@
UPDATE notes SET title = 'Recovered protected note', isProtected = 0 WHERE noteId IN (
SELECT noteId FROM notes JOIN note_contents USING(noteId)
WHERE notes.isProtected = 1
AND note_contents.isProtected = 0
AND notes.isDeleted = 0
)

View File

@@ -0,0 +1 @@
CREATE VIRTUAL TABLE note_fulltext USING fts5(noteId UNINDEXED, title, titleHash UNINDEXED, content, contentHash UNINDEXED);

View File

@@ -0,0 +1,10 @@
const repository = require('../../src/services/repository');
const noteFulltextService = require('../../src/services/note_fulltext');
module.exports = async () => {
const notes = await repository.getEntities('SELECT * FROM notes WHERE isDeleted = 0 AND isProtected = 0');
for (const note of notes) {
await noteFulltextService.updateNoteFulltext(note);
}
};

View File

@@ -0,0 +1,236 @@
CREATE TABLE IF NOT EXISTS "sync_mig" (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`entityName` TEXT NOT NULL,
`entityId` TEXT NOT NULL,
`sourceId` TEXT NOT NULL,
`utcSyncDate` TEXT NOT NULL);
INSERT INTO sync_mig (id, entityName, entityId, sourceId, utcSyncDate)
SELECT id, entityName, entityId, sourceId, REPLACE(syncDate, 'T', ' ') FROM sync;
DROP TABLE sync;
ALTER TABLE sync_mig RENAME TO sync;
CREATE TABLE IF NOT EXISTS "source_ids_mig" (
`sourceId` TEXT NOT NULL,
`utcDateCreated` TEXT NOT NULL,
PRIMARY KEY(`sourceId`)
);
INSERT INTO source_ids_mig (sourceId, utcDateCreated)
SELECT sourceId, REPLACE(dateCreated, 'T', ' ') FROM source_ids;
DROP TABLE source_ids;
ALTER TABLE source_ids_mig RENAME TO source_ids;
CREATE TABLE IF NOT EXISTS "note_revisions_mig" (
`noteRevisionId` TEXT NOT NULL PRIMARY KEY,
`noteId` TEXT NOT NULL,
`title` TEXT,
`content` TEXT,
`isProtected` INT NOT NULL DEFAULT 0,
`utcDateModifiedFrom` TEXT NOT NULL,
`utcDateModifiedTo` TEXT NOT NULL,
`dateModifiedFrom` TEXT NOT NULL,
`dateModifiedTo` TEXT NOT NULL,
type TEXT DEFAULT '' NOT NULL,
mime TEXT DEFAULT '' NOT NULL,
hash TEXT DEFAULT "" NOT NULL);
INSERT INTO note_revisions_mig (noteRevisionId, noteId, title, content, isProtected, utcDateModifiedFrom, utcDateModifiedTo, dateModifiedFrom, dateModifiedTo, type, mime, hash)
SELECT noteRevisionId, noteId, title, content, isProtected, REPLACE(dateModifiedFrom, 'T', ' '), REPLACE(dateModifiedTo, 'T', ' '), REPLACE(REPLACE(dateModifiedFrom, 'T', ' '), 'Z', '+0000'), REPLACE(REPLACE(dateModifiedTo, 'T', ' '), 'Z', '+0000'), type, mime, hash FROM note_revisions;
DROP TABLE note_revisions;
ALTER TABLE note_revisions_mig RENAME TO note_revisions;
CREATE TABLE IF NOT EXISTS "api_tokens_mig"
(
apiTokenId TEXT PRIMARY KEY NOT NULL,
token TEXT NOT NULL,
utcDateCreated TEXT NOT NULL,
isDeleted INT NOT NULL DEFAULT 0,
hash TEXT DEFAULT "" NOT NULL);
INSERT INTO api_tokens_mig (apiTokenId, token, utcDateCreated, isDeleted, hash)
SELECT apiTokenId, token, REPLACE(dateCreated, 'T', ' '), isDeleted, hash FROM api_tokens;
DROP TABLE api_tokens;
ALTER TABLE api_tokens_mig RENAME TO api_tokens;
CREATE TABLE IF NOT EXISTS "branches_mig" (
`branchId` TEXT NOT NULL,
`noteId` TEXT NOT NULL,
`parentNoteId` TEXT NOT NULL,
`notePosition` INTEGER NOT NULL,
`prefix` TEXT,
`isExpanded` BOOLEAN,
`isDeleted` INTEGER NOT NULL DEFAULT 0,
`utcDateModified` TEXT NOT NULL,
utcDateCreated TEXT NOT NULL,
hash TEXT DEFAULT "" NOT NULL,
PRIMARY KEY(`branchId`)
);
INSERT INTO branches_mig (branchId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, utcDateModified, utcDateCreated, hash)
SELECT branchId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, REPLACE(dateModified, 'T', ' '), REPLACE(dateCreated, 'T', ' '), hash FROM branches;
DROP TABLE branches;
ALTER TABLE branches_mig RENAME TO branches;
CREATE TABLE IF NOT EXISTS "recent_notes_mig" (
`branchId` TEXT NOT NULL PRIMARY KEY,
`notePath` TEXT NOT NULL,
hash TEXT DEFAULT "" NOT NULL,
`utcDateCreated` TEXT NOT NULL,
isDeleted INT
);
INSERT INTO recent_notes_mig (branchId, notePath, hash, utcDateCreated, isDeleted)
SELECT branchId, notePath, hash, REPLACE(dateCreated, 'T', ' '), isDeleted FROM recent_notes;
DROP TABLE recent_notes;
ALTER TABLE recent_notes_mig RENAME TO recent_notes;
CREATE TABLE IF NOT EXISTS "event_log_mig" (
`eventId` TEXT NOT NULL PRIMARY KEY,
`noteId` TEXT,
`comment` TEXT,
`utcDateCreated` TEXT NOT NULL
);
INSERT INTO event_log_mig (eventId, noteId, comment, utcDateCreated)
SELECT eventId, noteId, comment, REPLACE(dateCreated, 'T', ' ') FROM event_log;
DROP TABLE event_log;
ALTER TABLE event_log_mig RENAME TO event_log;
CREATE TABLE IF NOT EXISTS "options_mig"
(
name TEXT not null PRIMARY KEY,
value TEXT,
isSynced INTEGER default 0 not null,
hash TEXT default "" not null,
utcDateCreated TEXT not null,
utcDateModified TEXT NOT NULL
);
INSERT INTO options_mig (name, value, isSynced, hash, utcDateCreated, utcDateModified)
SELECT name, value, isSynced, hash, REPLACE(dateCreated, 'T', ' '), REPLACE(dateModified, 'T', ' ') FROM options;
DROP TABLE options;
ALTER TABLE options_mig RENAME TO options;
CREATE TABLE attributes_mig
(
attributeId TEXT not null primary key,
noteId TEXT not null,
type TEXT not null,
name TEXT not null,
value TEXT default '' not null,
position INT default 0 not null,
utcDateCreated TEXT not null,
utcDateModified TEXT not null,
isDeleted INT not null,
hash TEXT default "" not null,
isInheritable int DEFAULT 0 NULL);
INSERT INTO attributes_mig (attributeId, noteId, type, name, value, position, utcDateCreated, utcDateModified, isDeleted, hash, isInheritable)
SELECT attributeId, noteId, type, name, value, position, REPLACE(dateCreated, 'T', ' '), REPLACE(dateModified, 'T', ' '), isDeleted, hash, isInheritable FROM attributes;
DROP TABLE attributes;
ALTER TABLE attributes_mig RENAME TO attributes;
CREATE TABLE IF NOT EXISTS "links_mig" (
`linkId` TEXT NOT NULL,
`noteId` TEXT NOT NULL,
`targetNoteId` TEXT NOT NULL,
`type` TEXT NOT NULL,
`hash` TEXT DEFAULT "" NOT NULL,
`isDeleted` INTEGER NOT NULL DEFAULT 0,
`utcDateCreated` TEXT NOT NULL,
`utcDateModified` TEXT NOT NULL,
PRIMARY KEY(`linkId`)
);
INSERT INTO links_mig (linkId, noteId, targetNoteId, type, hash, isDeleted, utcDateCreated, utcDateModified)
SELECT linkId, noteId, targetNoteId, type, hash, isDeleted, REPLACE(dateCreated, 'T', ' '), REPLACE(dateModified, 'T', ' ') FROM links;
DROP TABLE links;
ALTER TABLE links_mig RENAME TO links;
CREATE TABLE IF NOT EXISTS "note_contents_mig" (
`noteContentId` TEXT NOT NULL,
`noteId` TEXT NOT NULL,
`isProtected` INT NOT NULL DEFAULT 0,
`content` TEXT NULL DEFAULT NULL,
`hash` TEXT DEFAULT "" NOT NULL,
`utcDateCreated` TEXT NOT NULL,
`utcDateModified` TEXT NOT NULL,
PRIMARY KEY(`noteContentId`)
);
INSERT INTO note_contents_mig (noteContentId, noteId, isProtected, content, hash, utcDateCreated, utcDateModified)
SELECT noteContentId, noteId, isProtected, content, hash, REPLACE(dateCreated, 'T', ' '), REPLACE(dateModified, 'T', ' ') FROM note_contents;
DROP TABLE note_contents;
ALTER TABLE note_contents_mig RENAME TO note_contents;
CREATE TABLE IF NOT EXISTS "notes_mig" (
`noteId` TEXT NOT NULL,
`title` TEXT NOT NULL DEFAULT "note",
`isProtected` INT NOT NULL DEFAULT 0,
`type` TEXT NOT NULL DEFAULT 'text',
`mime` TEXT NOT NULL DEFAULT 'text/html',
`hash` TEXT DEFAULT "" NOT NULL,
`isDeleted` INT NOT NULL DEFAULT 0,
`dateCreated` TEXT NOT NULL,
`dateModified` TEXT NOT NULL,
`utcDateCreated` TEXT NOT NULL,
`utcDateModified` TEXT NOT NULL,
PRIMARY KEY(`noteId`)
);
INSERT INTO notes_mig (noteId, title, isProtected, type, mime, hash, isDeleted, dateCreated, dateModified, utcDateCreated, utcDateModified)
SELECT noteId, title, isProtected, type, mime, hash, isDeleted, REPLACE(REPLACE(dateCreated, 'T', ' '), 'Z', '+0000'), REPLACE(REPLACE(dateModified, 'T', ' '), 'Z', '+0000'), REPLACE(dateCreated, 'T', ' '), REPLACE(dateModified, 'T', ' ') FROM notes;
DROP TABLE notes;
ALTER TABLE notes_mig RENAME TO notes;
CREATE UNIQUE INDEX `IDX_sync_entityName_entityId` ON `sync` (
`entityName`,
`entityId`
);
CREATE INDEX `IDX_sync_utcSyncDate` ON `sync` (
`utcSyncDate`
);
CREATE INDEX `IDX_note_revisions_noteId` ON `note_revisions` (
`noteId`
);
CREATE INDEX `IDX_note_revisions_dateModifiedFrom` ON `note_revisions` (
`utcDateModifiedFrom`
);
CREATE INDEX `IDX_note_revisions_dateModifiedTo` ON `note_revisions` (
`utcDateModifiedTo`
);
CREATE INDEX `IDX_branches_noteId` ON `branches` (
`noteId`
);
CREATE INDEX `IDX_branches_noteId_parentNoteId` ON `branches` (
`noteId`,
`parentNoteId`
);
CREATE INDEX IDX_branches_parentNoteId ON branches (parentNoteId);
CREATE INDEX IDX_attributes_name_value
on attributes (name, value);
CREATE INDEX IDX_links_noteId_index
on links (noteId);
CREATE INDEX IDX_links_targetNoteId_index
on links (targetNoteId);
CREATE INDEX IDX_attributes_name_index
on attributes (name);
CREATE INDEX IDX_attributes_noteId_index
on attributes (noteId);
CREATE INDEX IDX_attributes_value_index
on attributes (value);
CREATE UNIQUE INDEX `IDX_note_contents_noteId` ON `note_contents` (`noteId`);

View File

@@ -0,0 +1,13 @@
CREATE TABLE IF NOT EXISTS "note_contents_mig" (
`noteId` TEXT NOT NULL,
`content` TEXT NULL DEFAULT NULL,
`hash` TEXT DEFAULT "" NOT NULL,
`utcDateModified` TEXT NOT NULL,
PRIMARY KEY(`noteId`)
);
INSERT INTO note_contents_mig (noteId, content, hash, utcDateModified)
SELECT noteId, content, hash, utcDateModified FROM note_contents;
DROP TABLE note_contents;
ALTER TABLE note_contents_mig RENAME TO note_contents;

View File

@@ -1,19 +1,14 @@
CREATE VIRTUAL TABLE note_fulltext USING fts5(noteId UNINDEXED, title, titleHash UNINDEXED, content, contentHash UNINDEXED)
/* note_fulltext(noteId,title,titleHash,content,contentHash) */;
CREATE TABLE IF NOT EXISTS "sync" (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`entityName` TEXT NOT NULL,
`entityId` TEXT NOT NULL,
`sourceId` TEXT NOT NULL,
`syncDate` TEXT NOT NULL);
CREATE UNIQUE INDEX `IDX_sync_entityName_entityId` ON `sync` (
`entityName`,
`entityId`
);
CREATE INDEX `IDX_sync_syncDate` ON `sync` (
`syncDate`
);
`utcSyncDate` TEXT NOT NULL);
CREATE TABLE IF NOT EXISTS "source_ids" (
`sourceId` TEXT NOT NULL,
`dateCreated` TEXT NOT NULL,
`utcDateCreated` TEXT NOT NULL,
PRIMARY KEY(`sourceId`)
);
CREATE TABLE IF NOT EXISTS "note_revisions" (
@@ -22,25 +17,20 @@ CREATE TABLE IF NOT EXISTS "note_revisions" (
`title` TEXT,
`content` TEXT,
`isProtected` INT NOT NULL DEFAULT 0,
`utcDateModifiedFrom` TEXT NOT NULL,
`utcDateModifiedTo` TEXT NOT NULL,
`dateModifiedFrom` TEXT NOT NULL,
`dateModifiedTo` TEXT NOT NULL
, type TEXT DEFAULT '' NOT NULL, mime TEXT DEFAULT '' NOT NULL, hash TEXT DEFAULT "" NOT NULL);
CREATE INDEX `IDX_note_revisions_noteId` ON `note_revisions` (
`noteId`
);
CREATE INDEX `IDX_note_revisions_dateModifiedFrom` ON `note_revisions` (
`dateModifiedFrom`
);
CREATE INDEX `IDX_note_revisions_dateModifiedTo` ON `note_revisions` (
`dateModifiedTo`
);
`dateModifiedTo` TEXT NOT NULL,
type TEXT DEFAULT '' NOT NULL,
mime TEXT DEFAULT '' NOT NULL,
hash TEXT DEFAULT "" NOT NULL);
CREATE TABLE IF NOT EXISTS "api_tokens"
(
apiTokenId TEXT PRIMARY KEY NOT NULL,
token TEXT NOT NULL,
dateCreated TEXT NOT NULL,
isDeleted INT NOT NULL DEFAULT 0
, hash TEXT DEFAULT "" NOT NULL);
utcDateCreated TEXT NOT NULL,
isDeleted INT NOT NULL DEFAULT 0,
hash TEXT DEFAULT "" NOT NULL);
CREATE TABLE IF NOT EXISTS "branches" (
`branchId` TEXT NOT NULL,
`noteId` TEXT NOT NULL,
@@ -49,40 +39,34 @@ CREATE TABLE IF NOT EXISTS "branches" (
`prefix` TEXT,
`isExpanded` BOOLEAN,
`isDeleted` INTEGER NOT NULL DEFAULT 0,
`dateModified` TEXT NOT NULL, hash TEXT DEFAULT "" NOT NULL, dateCreated TEXT NOT NULL DEFAULT '1970-01-01T00:00:00.000Z',
`utcDateModified` TEXT NOT NULL,
utcDateCreated TEXT NOT NULL,
hash TEXT DEFAULT "" NOT NULL,
PRIMARY KEY(`branchId`)
);
CREATE INDEX `IDX_branches_noteId` ON `branches` (
`noteId`
);
CREATE INDEX `IDX_branches_noteId_parentNoteId` ON `branches` (
`noteId`,
`parentNoteId`
);
CREATE INDEX IDX_branches_parentNoteId ON branches (parentNoteId);
CREATE TABLE IF NOT EXISTS "recent_notes" (
`branchId` TEXT NOT NULL PRIMARY KEY,
`notePath` TEXT NOT NULL,
hash TEXT DEFAULT "" NOT NULL,
`dateCreated` TEXT NOT NULL,
`utcDateCreated` TEXT NOT NULL,
isDeleted INT
);
CREATE TABLE IF NOT EXISTS "event_log" (
`eventId` TEXT NOT NULL PRIMARY KEY,
`noteId` TEXT,
`comment` TEXT,
`dateCreated` TEXT NOT NULL
`utcDateCreated` TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS "options"
(
name TEXT not null PRIMARY KEY,
value TEXT,
dateModified INT,
isSynced INTEGER default 0 not null,
hash TEXT default "" not null,
dateCreated TEXT default '1970-01-01T00:00:00.000Z' not null
utcDateCreated TEXT not null,
utcDateModified TEXT NOT NULL
);
CREATE TABLE attributes
CREATE TABLE IF NOT EXISTS "attributes"
(
attributeId TEXT not null primary key,
noteId TEXT not null,
@@ -90,25 +74,11 @@ CREATE TABLE attributes
name TEXT not null,
value TEXT default '' not null,
position INT default 0 not null,
dateCreated TEXT not null,
dateModified TEXT not null,
utcDateCreated TEXT not null,
utcDateModified TEXT not null,
isDeleted INT not null,
hash TEXT default "" not null, isInheritable int DEFAULT 0 NULL);
CREATE INDEX IDX_attributes_name_value
on attributes (name, value);
CREATE TABLE IF NOT EXISTS "notes" (
`noteId` TEXT NOT NULL,
`title` TEXT NOT NULL DEFAULT "note",
`content` TEXT NULL DEFAULT NULL,
`isProtected` INT NOT NULL DEFAULT 0,
`type` TEXT NOT NULL DEFAULT 'text',
`mime` TEXT NOT NULL DEFAULT 'text/html',
`hash` TEXT DEFAULT "" NOT NULL,
`isDeleted` INT NOT NULL DEFAULT 0,
`dateCreated` TEXT NOT NULL,
`dateModified` TEXT NOT NULL,
PRIMARY KEY(`noteId`)
);
hash TEXT default "" not null,
isInheritable int DEFAULT 0 NULL);
CREATE TABLE IF NOT EXISTS "links" (
`linkId` TEXT NOT NULL,
`noteId` TEXT NOT NULL,
@@ -116,10 +86,50 @@ CREATE TABLE IF NOT EXISTS "links" (
`type` TEXT NOT NULL,
`hash` TEXT DEFAULT "" NOT NULL,
`isDeleted` INTEGER NOT NULL DEFAULT 0,
`dateCreated` TEXT NOT NULL,
`dateModified` TEXT NOT NULL,
`utcDateCreated` TEXT NOT NULL,
`utcDateModified` TEXT NOT NULL,
PRIMARY KEY(`linkId`)
);
CREATE TABLE IF NOT EXISTS "notes" (
`noteId` TEXT NOT NULL,
`title` TEXT NOT NULL DEFAULT "note",
`isProtected` INT NOT NULL DEFAULT 0,
`type` TEXT NOT NULL DEFAULT 'text',
`mime` TEXT NOT NULL DEFAULT 'text/html',
`hash` TEXT DEFAULT "" NOT NULL,
`isDeleted` INT NOT NULL DEFAULT 0,
`dateCreated` TEXT NOT NULL,
`dateModified` TEXT NOT NULL,
`utcDateCreated` TEXT NOT NULL,
`utcDateModified` TEXT NOT NULL,
PRIMARY KEY(`noteId`)
);
CREATE UNIQUE INDEX `IDX_sync_entityName_entityId` ON `sync` (
`entityName`,
`entityId`
);
CREATE INDEX `IDX_sync_utcSyncDate` ON `sync` (
`utcSyncDate`
);
CREATE INDEX `IDX_note_revisions_noteId` ON `note_revisions` (
`noteId`
);
CREATE INDEX `IDX_note_revisions_dateModifiedFrom` ON `note_revisions` (
`utcDateModifiedFrom`
);
CREATE INDEX `IDX_note_revisions_dateModifiedTo` ON `note_revisions` (
`utcDateModifiedTo`
);
CREATE INDEX `IDX_branches_noteId` ON `branches` (
`noteId`
);
CREATE INDEX `IDX_branches_noteId_parentNoteId` ON `branches` (
`noteId`,
`parentNoteId`
);
CREATE INDEX IDX_branches_parentNoteId ON branches (parentNoteId);
CREATE INDEX IDX_attributes_name_value
on attributes (name, value);
CREATE INDEX IDX_links_noteId_index
on links (noteId);
CREATE INDEX IDX_links_targetNoteId_index
@@ -130,3 +140,10 @@ CREATE INDEX IDX_attributes_noteId_index
on attributes (noteId);
CREATE INDEX IDX_attributes_value_index
on attributes (value);
CREATE TABLE IF NOT EXISTS "note_contents" (
`noteId` TEXT NOT NULL,
`content` TEXT NULL DEFAULT NULL,
`hash` TEXT DEFAULT "" NOT NULL,
`utcDateModified` TEXT NOT NULL,
PRIMARY KEY(`noteId`)
);

View File

@@ -28,7 +28,7 @@
<header>
<h2><span class="attribs"><span class="type-signature"></span></span>ApiToken<span class="signature">(apiTokenId, token, isDeleted, dateCreated)</span><span class="type-signature"></span></h2>
<h2><span class="attribs"><span class="type-signature"></span></span>ApiToken<span class="signature">(apiTokenId, token, isDeleted, utcDateCreated)</span><span class="type-signature"></span></h2>
<div class="class-description">ApiToken is an entity representing token used to authenticate against Trilium API from client applications. Currently used only by Trilium Sender.</div>
@@ -45,7 +45,7 @@
<h4 class="name" id="ApiToken"><span class="type-signature"></span>new ApiToken<span class="signature">(apiTokenId, token, isDeleted, dateCreated)</span><span class="type-signature"></span></h4>
<h4 class="name" id="ApiToken"><span class="type-signature"></span>new ApiToken<span class="signature">(apiTokenId, token, isDeleted, utcDateCreated)</span><span class="type-signature"></span></h4>
@@ -154,7 +154,7 @@
<tr>
<td class="name"><code>dateCreated</code></td>
<td class="name"><code>utcDateCreated</code></td>
<td class="type">

View File

@@ -28,7 +28,7 @@
<header>
<h2><span class="attribs"><span class="type-signature"></span></span>Attribute<span class="signature">(attributeId, noteId, type, name, value, position, isInheritable, isDeleted, dateCreated, dateModified)</span><span class="type-signature"></span></h2>
<h2><span class="attribs"><span class="type-signature"></span></span>Attribute<span class="signature">(attributeId, noteId, type, name, value, position, isInheritable, isDeleted, utcDateCreated, utcDateModified)</span><span class="type-signature"></span></h2>
<div class="class-description">Attribute is key value pair owned by a note.</div>
@@ -45,7 +45,7 @@
<h4 class="name" id="Attribute"><span class="type-signature"></span>new Attribute<span class="signature">(attributeId, noteId, type, name, value, position, isInheritable, isDeleted, dateCreated, dateModified)</span><span class="type-signature"></span></h4>
<h4 class="name" id="Attribute"><span class="type-signature"></span>new Attribute<span class="signature">(attributeId, noteId, type, name, value, position, isInheritable, isDeleted, utcDateCreated, utcDateModified)</span><span class="type-signature"></span></h4>
@@ -269,7 +269,7 @@
<tr>
<td class="name"><code>dateCreated</code></td>
<td class="name"><code>utcDateCreated</code></td>
<td class="type">
@@ -292,7 +292,7 @@
<tr>
<td class="name"><code>dateModified</code></td>
<td class="name"><code>utcDateModified</code></td>
<td class="type">

File diff suppressed because it is too large Load Diff

View File

@@ -28,7 +28,7 @@
<header>
<h2><span class="attribs"><span class="type-signature"></span></span>Branch<span class="signature">(branchId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified, dateCreated)</span><span class="type-signature"></span></h2>
<h2><span class="attribs"><span class="type-signature"></span></span>Branch<span class="signature">(branchId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, utcDateModified, utcDateCreated)</span><span class="type-signature"></span></h2>
<div class="class-description">Branch represents note's placement in the tree - it's essentially pair of noteId and parentNoteId.
Each note can have multiple (at least one) branches, meaning it can be placed into multiple places in the tree.</div>
@@ -46,7 +46,7 @@ Each note can have multiple (at least one) branches, meaning it can be placed in
<h4 class="name" id="Branch"><span class="type-signature"></span>new Branch<span class="signature">(branchId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified, dateCreated)</span><span class="type-signature"></span></h4>
<h4 class="name" id="Branch"><span class="type-signature"></span>new Branch<span class="signature">(branchId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, utcDateModified, utcDateCreated)</span><span class="type-signature"></span></h4>
@@ -247,7 +247,7 @@ Each note can have multiple (at least one) branches, meaning it can be placed in
<tr>
<td class="name"><code>dateModified</code></td>
<td class="name"><code>utcDateModified</code></td>
<td class="type">
@@ -270,7 +270,7 @@ Each note can have multiple (at least one) branches, meaning it can be placed in
<tr>
<td class="name"><code>dateCreated</code></td>
<td class="name"><code>utcDateCreated</code></td>
<td class="type">

View File

@@ -28,7 +28,7 @@
<header>
<h2><span class="attribs"><span class="type-signature"></span></span>Link<span class="signature">(linkId, noteId, targetNoteId, type, isDeleted, dateModified, dateCreated)</span><span class="type-signature"></span></h2>
<h2><span class="attribs"><span class="type-signature"></span></span>Link<span class="signature">(linkId, noteId, targetNoteId, type, isDeleted, utcDateModified, utcDateCreated)</span><span class="type-signature"></span></h2>
<div class="class-description">This class represents link from one note to another in the form of hyperlink or image reference. Note that
this is different concept than attribute/relation.</div>
@@ -46,7 +46,7 @@ this is different concept than attribute/relation.</div>
<h4 class="name" id="Link"><span class="type-signature"></span>new Link<span class="signature">(linkId, noteId, targetNoteId, type, isDeleted, dateModified, dateCreated)</span><span class="type-signature"></span></h4>
<h4 class="name" id="Link"><span class="type-signature"></span>new Link<span class="signature">(linkId, noteId, targetNoteId, type, isDeleted, utcDateModified, utcDateCreated)</span><span class="type-signature"></span></h4>
@@ -201,7 +201,7 @@ this is different concept than attribute/relation.</div>
<tr>
<td class="name"><code>dateModified</code></td>
<td class="name"><code>utcDateModified</code></td>
<td class="type">
@@ -224,7 +224,7 @@ this is different concept than attribute/relation.</div>
<tr>
<td class="name"><code>dateCreated</code></td>
<td class="name"><code>utcDateCreated</code></td>
<td class="type">

File diff suppressed because it is too large Load Diff

View File

@@ -28,7 +28,7 @@
<header>
<h2><span class="attribs"><span class="type-signature"></span></span>NoteRevision<span class="signature">(noteRevisionId, noteId, type, mime, title, content, isProtected, dateModifiedFrom, dateModifiedTo)</span><span class="type-signature"></span></h2>
<h2><span class="attribs"><span class="type-signature"></span></span>NoteRevision<span class="signature">(noteRevisionId, noteId, type, mime, title, content, isProtected, dateModifiedFrom, dateModifiedTo, utcDateModifiedFrom, utcDateModifiedTo)</span><span class="type-signature"></span></h2>
<div class="class-description">NoteRevision represents snapshot of note's title and content at some point in the past. It's used for seamless note versioning.</div>
@@ -45,7 +45,7 @@
<h4 class="name" id="NoteRevision"><span class="type-signature"></span>new NoteRevision<span class="signature">(noteRevisionId, noteId, type, mime, title, content, isProtected, dateModifiedFrom, dateModifiedTo)</span><span class="type-signature"></span></h4>
<h4 class="name" id="NoteRevision"><span class="type-signature"></span>new NoteRevision<span class="signature">(noteRevisionId, noteId, type, mime, title, content, isProtected, dateModifiedFrom, dateModifiedTo, utcDateModifiedFrom, utcDateModifiedTo)</span><span class="type-signature"></span></h4>
@@ -285,6 +285,52 @@
<td class="description last"></td>
</tr>
<tr>
<td class="name"><code>utcDateModifiedFrom</code></td>
<td class="type">
<span class="param-type">string</span>
</td>
<td class="description last"></td>
</tr>
<tr>
<td class="name"><code>utcDateModifiedTo</code></td>
<td class="type">
<span class="param-type">string</span>
</td>
<td class="description last"></td>
</tr>
@@ -326,7 +372,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_revision.js.html">entities/note_revision.js</a>, <a href="entities_note_revision.js.html#line22">line 22</a>
<a href="entities_note_revision.js.html">entities/note_revision.js</a>, <a href="entities_note_revision.js.html#line24">line 24</a>
</li></ul></dd>

View File

@@ -28,7 +28,7 @@
<header>
<h2><span class="attribs"><span class="type-signature"></span></span>Option<span class="signature">(name, value, isSynced, dateModified, dateCreated)</span><span class="type-signature"></span></h2>
<h2><span class="attribs"><span class="type-signature"></span></span>Option<span class="signature">(name, value, isSynced, utcDateModified, utcDateCreated)</span><span class="type-signature"></span></h2>
<div class="class-description">Option represents name-value pair, either directly configurable by the user or some system property.</div>
@@ -45,7 +45,7 @@
<h4 class="name" id="Option"><span class="type-signature"></span>new Option<span class="signature">(name, value, isSynced, dateModified, dateCreated)</span><span class="type-signature"></span></h4>
<h4 class="name" id="Option"><span class="type-signature"></span>new Option<span class="signature">(name, value, isSynced, utcDateModified, utcDateCreated)</span><span class="type-signature"></span></h4>
@@ -154,7 +154,7 @@
<tr>
<td class="name"><code>dateModified</code></td>
<td class="name"><code>utcDateModified</code></td>
<td class="type">
@@ -177,7 +177,7 @@
<tr>
<td class="name"><code>dateCreated</code></td>
<td class="name"><code>utcDateCreated</code></td>
<td class="type">

View File

@@ -28,7 +28,7 @@
<header>
<h2><span class="attribs"><span class="type-signature"></span></span>RecentNote<span class="signature">(branchId, notePath, isDeleted, dateModified)</span><span class="type-signature"></span></h2>
<h2><span class="attribs"><span class="type-signature"></span></span>RecentNote<span class="signature">(branchId, notePath, isDeleted, utcDateModified)</span><span class="type-signature"></span></h2>
<div class="class-description">RecentNote represents recently visited note.</div>
@@ -45,7 +45,7 @@
<h4 class="name" id="RecentNote"><span class="type-signature"></span>new RecentNote<span class="signature">(branchId, notePath, isDeleted, dateModified)</span><span class="type-signature"></span></h4>
<h4 class="name" id="RecentNote"><span class="type-signature"></span>new RecentNote<span class="signature">(branchId, notePath, isDeleted, utcDateModified)</span><span class="type-signature"></span></h4>
@@ -154,7 +154,7 @@
<tr>
<td class="name"><code>dateModified</code></td>
<td class="name"><code>utcDateModified</code></td>
<td class="type">

View File

@@ -37,22 +37,22 @@ const dateUtils = require('../services/date_utils');
* @param {string} apiTokenId - primary key
* @param {string} token
* @param {boolean} isDeleted - true if API token is deleted
* @param {string} dateCreated
* @param {string} utcDateCreated
*
* @extends Entity
*/
class ApiToken extends Entity {
static get entityName() { return "api_tokens"; }
static get primaryKeyName() { return "apiTokenId"; }
static get hashedProperties() { return ["apiTokenId", "token", "dateCreated", "isDeleted"]; }
static get hashedProperties() { return ["apiTokenId", "token", "utcDateCreated", "isDeleted"]; }
beforeSaving() {
if (!this.isDeleted) {
this.isDeleted = false;
}
if (!this.dateCreated) {
this.dateCreated = dateUtils.nowDate();
if (!this.utcDateCreated) {
this.utcDateCreated = dateUtils.utcNowDateTime();
}
super.beforeSaving();

View File

@@ -44,15 +44,15 @@ const sql = require('../services/sql');
* @param {int} position
* @param {boolean} isInheritable
* @param {boolean} isDeleted
* @param {string} dateCreated
* @param {string} dateModified
* @param {string} utcDateCreated
* @param {string} utcDateModified
*
* @extends Entity
*/
class Attribute extends Entity {
static get entityName() { return "attributes"; }
static get primaryKeyName() { return "attributeId"; }
static get hashedProperties() { return ["attributeId", "noteId", "type", "name", "value", "isInheritable", "isDeleted", "dateCreated"]; }
static get hashedProperties() { return ["attributeId", "noteId", "type", "name", "value", "isInheritable", "isDeleted", "utcDateCreated"]; }
constructor(row) {
super(row);
@@ -123,16 +123,21 @@ class Attribute extends Entity {
this.isDeleted = false;
}
if (!this.dateCreated) {
this.dateCreated = dateUtils.nowDate();
if (!this.utcDateCreated) {
this.utcDateCreated = dateUtils.utcNowDateTime();
}
super.beforeSaving();
if (this.isChanged) {
this.dateModified = dateUtils.nowDate();
this.utcDateModified = dateUtils.utcNowDateTime();
}
}
// cannot be static!
updatePojo(pojo) {
delete pojo.isOwned;
}
}
module.exports = Attribute;</code></pre>

View File

@@ -44,8 +44,8 @@ const sql = require('../services/sql');
* @param {string} prefix
* @param {boolean} isExpanded
* @param {boolean} isDeleted
* @param {string} dateModified
* @param {string} dateCreated
* @param {string} utcDateModified
* @param {string} utcDateCreated
*
* @extends Entity
*/
@@ -77,16 +77,21 @@ class Branch extends Entity {
this.isDeleted = false;
}
if (!this.dateCreated) {
this.dateCreated = dateUtils.nowDate();
if (!this.utcDateCreated) {
this.utcDateCreated = dateUtils.utcNowDateTime();
}
super.beforeSaving();
if (this.isChanged) {
this.dateModified = dateUtils.nowDate();
this.utcDateModified = dateUtils.utcNowDateTime();
}
}
// cannot be static!
updatePojo(pojo) {
delete pojo.origParentNoteId;
}
}
module.exports = Branch;</code></pre>

View File

@@ -36,8 +36,11 @@ class Entity {
*/
constructor(row = {}) {
for (const key in row) {
// ! is used when joint-fetching notes and note_contents objects for performance
if (!key.startsWith('!')) {
this[key] = row[key];
}
}
if ('isDeleted' in this) {
this.isDeleted = !!this.isDeleted;
@@ -51,8 +54,14 @@ class Entity {
this.hash = this.generateHash();
if (this.forcedChange) {
this.isChanged = true;
delete this.forcedChange;
}
else {
this.isChanged = origHash !== this.hash;
}
}
generateIdIfNecessary() {
if (!this[this.constructor.primaryKeyName]) {

View File

@@ -41,15 +41,15 @@ const dateUtils = require('../services/date_utils');
* @param {string} targetNoteId
* @param {string} type
* @param {boolean} isDeleted
* @param {string} dateModified
* @param {string} dateCreated
* @param {string} utcDateModified
* @param {string} utcDateCreated
*
* @extends Entity
*/
class Link extends Entity {
static get entityName() { return "links"; }
static get primaryKeyName() { return "linkId"; }
static get hashedProperties() { return ["linkId", "noteId", "targetNoteId", "type", "isDeleted", "dateCreated", "dateModified"]; }
static get hashedProperties() { return ["linkId", "noteId", "targetNoteId", "type", "isDeleted", "utcDateCreated", "utcDateModified"]; }
async getNote() {
return await repository.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]);
@@ -64,14 +64,14 @@ class Link extends Entity {
this.isDeleted = false;
}
if (!this.dateCreated) {
this.dateCreated = dateUtils.nowDate();
if (!this.utcDateCreated) {
this.utcDateCreated = dateUtils.utcNowDateTime();
}
super.beforeSaving();
if (this.isChanged) {
this.dateModified = dateUtils.nowDate();
this.utcDateModified = dateUtils.utcNowDateTime();
}
}
}

View File

@@ -32,13 +32,19 @@ const Entity = require('./entity');
const Attribute = require('./attribute');
const protectedSessionService = require('../services/protected_session');
const repository = require('../services/repository');
const sql = require('../services/sql');
const utils = require('../services/utils');
const dateUtils = require('../services/date_utils');
const noteFulltextService = require('../services/note_fulltext');
const syncTableService = require('../services/sync_table');
const LABEL = 'label';
const LABEL_DEFINITION = 'label-definition';
const RELATION = 'relation';
const RELATION_DEFINITION = 'relation-definition';
const STRING_MIME_TYPES = ["application/x-javascript"];
/**
* This represents a Note which is a central object in the Trilium Notes project.
*
@@ -46,18 +52,19 @@ const RELATION_DEFINITION = 'relation-definition';
* @property {string} type - one of "text", "code", "file" or "render"
* @property {string} mime - MIME type, e.g. "text/html"
* @property {string} title - note title
* @property {string} content - note content - e.g. HTML text for text notes, file payload for files
* @property {boolean} isProtected - true if note is protected
* @property {boolean} isDeleted - true if note is deleted
* @property {string} dateCreated
* @property {string} dateModified
* @property {string} dateCreated - local date time (with offset)
* @property {string} dateModified - local date time (with offset)
* @property {string} utcDateCreated
* @property {string} utcDateModified
*
* @extends Entity
*/
class Note extends Entity {
static get entityName() { return "notes"; }
static get primaryKeyName() { return "noteId"; }
static get hashedProperties() { return ["noteId", "title", "content", "type", "isProtected", "isDeleted"]; }
static get hashedProperties() { return ["noteId", "title", "type", "isProtected", "isDeleted"]; }
/**
* @param row - object containing database row from "notes" table
@@ -74,19 +81,78 @@ class Note extends Entity {
if (this.isProtected &amp;&amp; this.noteId) {
this.isContentAvailable = protectedSessionService.isProtectedSessionAvailable();
if (this.isContentAvailable) {
protectedSessionService.decryptNote(this);
}
this.setContent(this.content);
else {
this.title = "[protected]";
}
}
}
setContent(content) {
/** @returns {Promise&lt;*>} */
async getContent() {
if (this.content === undefined) {
this.content = await sql.getValue(`SELECT content FROM note_contents WHERE noteId = ?`, [this.noteId]);
if (this.isProtected) {
if (this.isContentAvailable) {
protectedSessionService.decryptNoteContent(this);
}
else {
this.content = "";
}
}
if (this.isStringNote()) {
this.content = this.content === null
? ""
: this.content.toString("UTF-8");
}
}
return this.content;
}
/** @returns {Promise&lt;*>} */
async getJsonContent() {
const content = await this.getContent();
return JSON.parse(content);
}
/** @returns {Promise} */
async setContent(content) {
this.content = content;
try {
this.jsonContent = JSON.parse(this.content);
const pojo = {
noteId: this.noteId,
content: content,
utcDateModified: dateUtils.utcNowDateTime(),
hash: utils.hash(this.noteId + "|" + content)
};
if (this.isProtected) {
if (this.isContentAvailable) {
protectedSessionService.encryptNoteContent(pojo);
}
catch(e) {}
else {
throw new Error(`Cannot update content of noteId=${this.noteId} since we're out of protected session.`);
}
}
await sql.upsert("note_contents", "noteId", pojo);
await syncTableService.addNoteContentSync(this.noteId);
this.forcedChange = true;
await this.save();
}
/** @returns {Promise} */
async setJsonContent(content) {
await this.setContent(JSON.stringify(content, null, '\t'));
}
/** @returns {boolean} true if this note is the root of the note tree. Root note has "root" noteId */
@@ -102,7 +168,9 @@ class Note extends Entity {
/** @returns {boolean} true if this note is JavaScript (code or attachment) */
isJavaScript() {
return (this.type === "code" || this.type === "file")
&amp;&amp; (this.mime.startsWith("application/javascript") || this.mime === "application/x-javascript");
&amp;&amp; (this.mime.startsWith("application/javascript")
|| this.mime === "application/x-javascript"
|| this.mime === "text/javascript");
}
/** @returns {boolean} true if this note is HTML */
@@ -110,6 +178,13 @@ class Note extends Entity {
return (this.type === "code" || this.type === "file" || this.type === "render") &amp;&amp; this.mime === "text/html";
}
/** @returns {boolean} true if the note has string content (not binary) */
isStringNote() {
return ["text", "code", "relation-map", "search"].includes(this.type)
|| this.mime.startsWith('text/')
|| STRING_MIME_TYPES.includes(this.mime);
}
/** @returns {string} JS script environment - either "frontend" or "backend" */
getScriptEnv() {
if (this.isHtml() || (this.isJavaScript() &amp;&amp; this.mime.endsWith('env=frontend'))) {
@@ -394,6 +469,16 @@ class Note extends Entity {
*/
async getRelationValue(name) { return await this.getAttributeValue(RELATION, name); }
/**
* @param {string} name
* @returns {Promise&lt;Note>|null} target note of the relation or null (if target is empty or note was not found)
*/
async getRelationTarget(name) {
const relation = await this.getRelation(name);
return relation ? await repository.getNote(relation.value) : null;
}
/**
* Based on enabled, label is either set or removed.
*
@@ -451,24 +536,32 @@ class Note extends Entity {
async removeRelation(name, value) { return await this.removeAttribute(RELATION, name, value); }
/**
* @param {string} name
* @returns {Promise&lt;Note>|null} target note of the relation or null (if target is empty or note was not found)
* @return {Promise&lt;string[]>} return list of all descendant noteIds of this note. Returning just noteIds because number of notes can be huge. Includes also this note's noteId
*/
async getRelationTarget(name) {
const relation = await this.getRelation(name);
return relation ? await repository.getNote(relation.value) : null;
async getDescendantNoteIds() {
return await sql.getColumn(`
WITH RECURSIVE
tree(noteId) AS (
SELECT ?
UNION
SELECT branches.noteId FROM branches
JOIN tree ON branches.parentNoteId = tree.noteId
JOIN notes ON notes.noteId = branches.noteId
WHERE notes.isDeleted = 0
AND branches.isDeleted = 0
)
SELECT noteId FROM tree`, [this.noteId]);
}
/**
* Finds child notes with given attribute name and value. Only own attributes are considered, not inherited ones
* Finds descendant notes with given attribute name and value. Only own attributes are considered, not inherited ones
*
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
* @param {string} [value] - attribute value
* @returns {Promise&lt;Note[]>}
*/
async findChildNotesWithAttribute(type, name, value) {
async getDescendantNotesWithAttribute(type, name, value) {
const params = [this.noteId, name];
let valueCondition = "";
@@ -500,22 +593,22 @@ class Note extends Entity {
}
/**
* Finds notes with given label name and value. Only own labels are considered, not inherited ones
* Finds descendant notes with given label name and value. Only own labels are considered, not inherited ones
*
* @param {string} name - label name
* @param {string} [value] - label value
* @returns {Promise&lt;Note[]>}
*/
async findChildNotesWithLabel(name, value) { return await this.findChildNotesWithAttribute(LABEL, name, value); }
async getDescendantNotesWithLabel(name, value) { return await this.getDescendantNotesWithAttribute(LABEL, name, value); }
/**
* Finds notes with given relation name and value. Only own relations are considered, not inherited ones
* Finds descendant notes with given relation name and value. Only own relations are considered, not inherited ones
*
* @param {string} name - relation name
* @param {string} [value] - relation value
* @returns {Promise&lt;Note[]>}
*/
async findChildNotesWithRelation(name, value) { return await this.findChildNotesWithAttribute(RELATION, name, value); }
async getDescendantNotesWithRelation(name, value) { return await this.getDescendantNotesWithAttribute(RELATION, name, value); }
/**
* Returns note revisions of this note.
@@ -608,31 +701,46 @@ class Note extends Entity {
}
beforeSaving() {
if (this.isJson() &amp;&amp; this.jsonContent) {
this.content = JSON.stringify(this.jsonContent, null, '\t');
}
// we do this here because encryption needs the note ID for the IV
this.generateIdIfNecessary();
if (this.isProtected) {
protectedSessionService.encryptNote(this);
}
if (!this.isDeleted) {
this.isDeleted = false;
}
if (!this.dateCreated) {
this.dateCreated = dateUtils.nowDate();
this.dateCreated = dateUtils.localNowDateTime();
}
if (!this.utcDateCreated) {
this.utcDateCreated = dateUtils.utcNowDateTime();
}
super.beforeSaving();
if (this.isChanged) {
this.dateModified = dateUtils.nowDate();
this.dateModified = dateUtils.localNowDateTime();
this.utcDateModified = dateUtils.utcNowDateTime();
}
}
// cannot be static!
updatePojo(pojo) {
if (pojo.isProtected) {
if (this.isContentAvailable) {
protectedSessionService.encryptNote(pojo);
}
else {
// updating protected note outside of protected session means we will keep original ciphertexts
delete pojo.title;
}
}
delete pojo.isContentAvailable;
delete pojo.__attributeCache;
delete pojo.content;
}
async afterSaving() {
noteFulltextService.triggerNoteFulltextUpdate(this.noteId);
}
}
module.exports = Note;</code></pre>

View File

@@ -44,13 +44,15 @@ const repository = require('../services/repository');
* @param {string} isProtected
* @param {string} dateModifiedFrom
* @param {string} dateModifiedTo
* @param {string} utcDateModifiedFrom
* @param {string} utcDateModifiedTo
*
* @extends Entity
*/
class NoteRevision extends Entity {
static get entityName() { return "note_revisions"; }
static get primaryKeyName() { return "noteRevisionId"; }
static get hashedProperties() { return ["noteRevisionId", "noteId", "title", "content", "isProtected", "dateModifiedFrom", "dateModifiedTo"]; }
static get hashedProperties() { return ["noteRevisionId", "noteId", "title", "content", "isProtected", "dateModifiedFrom", "dateModifiedTo", "utcDateModifiedFrom", "utcDateModifiedTo"]; }
constructor(row) {
super(row);

View File

@@ -37,8 +37,8 @@ const dateUtils = require('../services/date_utils');
* @param {string} name
* @param {string} value
* @param {boolean} isSynced
* @param {string} dateModified
* @param {string} dateCreated
* @param {string} utcDateModified
* @param {string} utcDateCreated
*
* @extends Entity
*/
@@ -54,10 +54,14 @@ class Option extends Entity {
}
beforeSaving() {
if (!this.utcDateCreated) {
this.utcDateCreated = dateUtils.utcNowDateTime();
}
super.beforeSaving();
if (this.isChanged) {
this.dateModified = dateUtils.nowDate();
this.utcDateModified = dateUtils.utcNowDateTime();
}
}
}

View File

@@ -37,22 +37,22 @@ const dateUtils = require('../services/date_utils');
* @param {string} branchId
* @param {string} notePath
* @param {boolean} isDeleted
* @param {string} dateModified
* @param {string} utcDateModified
*
* @extends Entity
*/
class RecentNote extends Entity {
static get entityName() { return "recent_notes"; }
static get primaryKeyName() { return "branchId"; }
static get hashedProperties() { return ["branchId", "notePath", "dateCreated", "isDeleted"]; }
static get hashedProperties() { return ["branchId", "notePath", "utcDateCreated", "isDeleted"]; }
beforeSaving() {
if (!this.isDeleted) {
this.isDeleted = false;
}
if (!this.dateCreated) {
this.dateCreated = dateUtils.nowDate();
if (!this.utcDateCreated) {
this.utcDateCreated = dateUtils.utcNowDateTime();
}
super.beforeSaving();

View File

@@ -272,7 +272,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line144">line 144</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line159">line 159</a>
</li></ul></dd>
@@ -558,7 +558,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line151">line 151</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line166">line 166</a>
</li></ul></dd>

View File

@@ -30,15 +30,17 @@
const noteService = require('./notes');
const sql = require('./sql');
const utils = require('./utils');
const dateUtils = require('./date_utils');
const attributeService = require('./attributes');
const dateNoteService = require('./date_notes');
const treeService = require('./tree');
const config = require('./config');
const repository = require('./repository');
const axios = require('axios');
const dayjs = require('dayjs');
const cloningService = require('./cloning');
const messagingService = require('./messaging');
const appInfo = require('./app_info');
const searchService = require('./search');
/**
* This is the main backend API interface for scripts. It's published in the local "api" object.
@@ -46,20 +48,23 @@ const messagingService = require('./messaging');
* @constructor
* @hideconstructor
*/
function BackendScriptApi(startNote, currentNote, originEntity) {
function BackendScriptApi(currentNote, apiParams) {
/** @property {Note} note where script started executing */
this.startNote = startNote;
/** @property {Note} note where script is currently executing */
this.startNote = apiParams.startNote;
/** @property {Note} note where script is currently executing. Don't mix this up with concept of active note */
this.currentNote = currentNote;
/** @property {Entity} entity whose event triggered this executions */
this.originEntity = originEntity;
this.originEntity = apiParams.originEntity;
for (const key in apiParams) {
this[key] = apiParams[key];
}
this.axios = axios;
this.dayjs = dayjs;
this.utils = {
unescapeHtml: utils.unescapeHtml,
isoDateTimeStr: dateUtils.dateStr,
isoDateStr: date => dateUtils.dateStr(date).substr(0, 10)
unescapeHtml: utils.unescapeHtml
};
/**
@@ -116,6 +121,16 @@ function BackendScriptApi(startNote, currentNote, originEntity) {
*/
this.getEntities = repository.getEntities;
/**
* This is a powerful search method - you can search by attributes and their values, e.g.:
* "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
*
* @method
* @param {string} searchString
* @returns ${Promise&lt;Note[]>}
*/
this.searchForNotes = searchService.searchForNotes;
/**
* Retrieves notes with given label name &amp; value
*
@@ -196,6 +211,23 @@ function BackendScriptApi(startNote, currentNote, originEntity) {
*/
this.createNote = noteService.createNote;
/**
* Creates new note according to given params and force all connected clients to refresh their tree.
*
* @method
*
* @param {string} parentNoteId - create new note under this parent
* @param {string} title
* @param {string} [content=""]
* @param {CreateNoteExtraOptions} [extraOptions={}]
* @returns {Promise&lt;{note: Note, branch: Branch}>} object contains newly created entities note and branch
*/
this.createNoteAndRefresh = async function(parentNoteId, title, content, extraOptions) {
await noteService.createNote(parentNoteId, title, content, extraOptions);
messagingService.refreshTree();
};
/**
* Log given message to trilium logs.
*
@@ -212,14 +244,42 @@ function BackendScriptApi(startNote, currentNote, originEntity) {
this.getRootCalendarNote = dateNoteService.getRootCalendarNote;
/**
* Returns day note for given date (YYYY-MM-DD format). If such note doesn't exist, it is created.
* Returns day note for given date. If such note doesn't exist, it is created.
*
* @method
* @param {string} date
* @param {string} date in YYYY-MM-DD format
* @returns {Promise&lt;Note|null>}
*/
this.getDateNote = dateNoteService.getDateNote;
/**
* Returns note for the first date of the week of the given date.
*
* @method
* @param {string} date in YYYY-MM-DD format
* @param {object} options - "startOfTheWeek" - either "monday" (default) or "sunday"
* @returns {Promise&lt;Note|null>}
*/
this.getWeekNote = dateNoteService.getWeekNote;
/**
* Returns month note for given date. If such note doesn't exist, it is created.
*
* @method
* @param {string} date in YYYY-MM format
* @returns {Promise&lt;Note|null>}
*/
this.getMonthNote = dateNoteService.getMonthNote;
/**
* Returns year note for given year. If such note doesn't exist, it is created.
*
* @method
* @param {string} year in YYYY format
* @returns {Promise&lt;Note|null>}
*/
this.getYearNote = dateNoteService.getYearNote;
/**
* @method
* @param {string} parentNoteId - this note's child notes will be sorted
@@ -253,13 +313,20 @@ function BackendScriptApi(startNote, currentNote, originEntity) {
*/
this.transactional = sql.transactional;
this.sql = sql;
/**
* Trigger tree refresh in all connected clients. This is required when some tree change happens in
* the backend.
*
* @returns {Promise&lt;void>}
*/
this.refreshTree = () => messagingService.sendMessageToAllClients({ type: 'refresh-tree' });
this.refreshTree = messagingService.refreshTree;
/**
* @return {{syncVersion, appVersion, buildRevision, dbVersion, dataDirectory, buildDate}|*} - object representing basic info about running Trilium version
*/
this.getAppInfo = () => appInfo
}
module.exports = BackendScriptApi;</code></pre>

View File

@@ -81,7 +81,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line16">line 16</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line18">line 18</a>
</li></ul></dd>
@@ -221,7 +221,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line22">line 22</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line24">line 24</a>
</li></ul></dd>
@@ -334,7 +334,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line24">line 24</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line26">line 26</a>
</li></ul></dd>
@@ -444,7 +444,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line20">line 20</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line22">line 22</a>
</li></ul></dd>
@@ -573,7 +573,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line41">line 41</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line43">line 43</a>
</li></ul></dd>
@@ -726,7 +726,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line33">line 33</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line35">line 35</a>
</li></ul></dd>
@@ -879,7 +879,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line60">line 60</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line62">line 62</a>
</li></ul></dd>
@@ -1057,7 +1057,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line197">line 197</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line199">line 199</a>
</li></ul></dd>
@@ -1188,7 +1188,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line157">line 157</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line159">line 159</a>
</li></ul></dd>
@@ -1244,6 +1244,214 @@
<h4 class="name" id="getActiveNote"><span class="type-signature"></span>getActiveNote<span class="signature">()</span><span class="type-signature"> &rarr; {<a href="NoteFull.html">NoteFull</a>}</span></h4>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line211">line 211</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<div class="param-desc">
active note (loaded into right pane)
</div>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type"><a href="NoteFull.html">NoteFull</a></span>
</dd>
</dl>
<h4 class="name" id="getActiveNoteContent"><span class="type-signature"></span>getActiveNoteContent<span class="signature">()</span><span class="type-signature"> &rarr; {string}</span></h4>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line205">line 205</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<div class="param-desc">
content of active note (loaded into right pane)
</div>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">string</span>
</dd>
</dl>
<h4 class="name" id="getCodeMimeTypes"><span class="type-signature"></span>getCodeMimeTypes<span class="signature">()</span><span class="type-signature"> &rarr; {array}</span></h4>
@@ -1292,7 +1500,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line221">line 221</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line242">line 242</a>
</li></ul></dd>
@@ -1348,110 +1556,6 @@
<h4 class="name" id="getCurrentNoteContent"><span class="type-signature"></span>getCurrentNoteContent<span class="signature">()</span><span class="type-signature"> &rarr; {string}</span></h4>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line203">line 203</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<div class="param-desc">
content of currently loaded note in the editor (HTML, code etc.)
</div>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">string</span>
</dd>
</dl>
<h4 class="name" id="getDefaultCodeMimeTypes"><span class="type-signature"></span>getDefaultCodeMimeTypes<span class="signature">()</span><span class="type-signature"> &rarr; {array}</span></h4>
@@ -1500,7 +1604,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line215">line 215</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line236">line 236</a>
</li></ul></dd>
@@ -1609,7 +1713,7 @@ if some action needs to happen on only one specific instance.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line150">line 150</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line152">line 152</a>
</li></ul></dd>
@@ -1808,7 +1912,7 @@ otherwise (by e.g. createNoteLink())
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line142">line 142</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line144">line 144</a>
</li></ul></dd>
@@ -1860,6 +1964,117 @@ otherwise (by e.g. createNoteLink())
<h4 class="name" id="isNoteStillActive"><span class="type-signature"></span>isNoteStillActive<span class="signature">()</span><span class="type-signature"> &rarr; {boolean}</span></h4>
<div class="description">
This method checks whether user navigated away from the note from which the scripts has been started.
This is necessary because script execution is async and by the time it is finished, the user might have
already navigated away from this page - the end result would be that script might return data for the wrong
note.
</div>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line222">line 222</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<div class="param-desc">
returns true if the original note is still loaded, false if user switched to another
</div>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">boolean</span>
</dd>
</dl>
<h4 class="name" id="onNoteChange"><span class="type-signature"></span>onNoteChange<span class="signature">(func)</span><span class="type-signature"></span></h4>
@@ -1957,7 +2172,7 @@ otherwise (by e.g. createNoteLink())
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line209">line 209</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line230">line 230</a>
</li></ul></dd>
@@ -2088,7 +2303,7 @@ otherwise (by e.g. createNoteLink())
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line164">line 164</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line166">line 166</a>
</li></ul></dd>
@@ -2140,6 +2355,88 @@ otherwise (by e.g. createNoteLink())
<h4 class="name" id="protectActiveNote"><span class="type-signature"></span>protectActiveNote<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line259">line 259</a>
</li></ul></dd>
</dl>
@@ -2196,7 +2493,7 @@ otherwise (by e.g. createNoteLink())
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line188">line 188</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line190">line 190</a>
</li></ul></dd>
@@ -2373,7 +2670,7 @@ Internally this serializes the anonymous function into string and sends it to ba
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line110">line 110</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line112">line 112</a>
</li></ul></dd>
@@ -2526,7 +2823,138 @@ Internally this serializes the anonymous function into string and sends it to ba
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line227">line 227</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line248">line 248</a>
</li></ul></dd>
</dl>
<h4 class="name" id="setupElementTooltip"><span class="type-signature"></span>setupElementTooltip<span class="signature">($el)</span><span class="type-signature"></span></h4>
<h5>Parameters:</h5>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>$el</code></td>
<td class="type">
<span class="param-type">object</span>
</td>
<td class="description last">jquery object on which to setup the tooltip</td>
</tr>
</tbody>
</table>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line254">line 254</a>
</li></ul></dd>
@@ -2661,7 +3089,7 @@ Internally this serializes the anonymous function into string and sends it to ba
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line180">line 180</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line182">line 182</a>
</li></ul></dd>
@@ -2796,7 +3224,7 @@ Internally this serializes the anonymous function into string and sends it to ba
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line172">line 172</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line174">line 174</a>
</li></ul></dd>

View File

@@ -199,7 +199,7 @@
<h4 class="name" id="jsonContent"><span class="type-signature"></span>jsonContent<span class="type-signature"></span></h4>
<h4 class="name" id="utcDateCreated"><span class="type-signature"></span>utcDateCreated<span class="type-signature"></span></h4>
@@ -239,7 +239,65 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_full.js.html">entities/note_full.js</a>, <a href="entities_note_full.js.html#line16">line 16</a>
<a href="entities_note_full.js.html">entities/note_full.js</a>, <a href="entities_note_full.js.html#line14">line 14</a>
</li></ul></dd>
</dl>
<h4 class="name" id="utcDateModified"><span class="type-signature"></span>utcDateModified<span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_full.js.html">entities/note_full.js</a>, <a href="entities_note_full.js.html#line17">line 17</a>
</li></ul></dd>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,86 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: entities/attribute.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: entities/attribute.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>class Attribute {
constructor(treeCache, row) {
this.treeCache = treeCache;
/** @param {string} attributeId */
this.attributeId = row.attributeId;
/** @param {string} noteId */
this.noteId = row.noteId;
/** @param {string} type */
this.type = row.type;
/** @param {string} name */
this.name = row.name;
/** @param {string} value */
this.value = row.value;
/** @param {int} position */
this.position = row.position;
/** @param {boolean} isInheritable */
this.isInheritable = row.isInheritable;
/** @param {boolean} isDeleted */
this.isDeleted = row.isDeleted;
/** @param {string} utcDateCreated */
this.utcDateCreated = row.utcDateCreated;
/** @param {string} utcDateModified */
this.utcDateModified = row.utcDateModified;
}
/** @returns {NoteShort} */
async getNote() {
return await this.treeCache.getNote(this.noteId);
}
get toString() {
return `Attribute(attributeId=${this.attributeId}, type=${this.type}, name=${this.name})`;
}
}
export default Attribute;</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Branch.html">Branch</a></li><li><a href="FrontendScriptApi.html">FrontendScriptApi</a></li><li><a href="NoteFull.html">NoteFull</a></li><li><a href="NoteShort.html">NoteShort</a></li></ul><h3><a href="global.html">Global</a></h3>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@@ -42,7 +42,7 @@ class Branch {
/** @param {string} */
this.prefix = row.prefix;
/** @param {boolean} */
this.isExpanded = row.isExpanded;
this.isExpanded = !!row.isExpanded;
}
/** @returns {NoteShort} */

View File

@@ -38,13 +38,11 @@ class NoteFull extends NoteShort {
/** @param {string} */
this.content = row.content;
if (this.content !== "" &amp;&amp; this.isJson()) {
try {
/** @param {object} */
this.jsonContent = JSON.parse(this.content);
}
catch(e) {}
}
/** @param {string} */
this.utcDateCreated = row.utcDateCreated;
/** @param {string} */
this.utcDateModified = row.utcDateModified;
}
}

View File

@@ -26,7 +26,14 @@
<section>
<article>
<pre class="prettyprint source linenums"><code>/**
<pre class="prettyprint source linenums"><code>import server from '../services/server.js';
const LABEL = 'label';
const LABEL_DEFINITION = 'label-definition';
const RELATION = 'relation';
const RELATION_DEFINITION = 'relation-definition';
/**
* This note's representation is used in note tree and is kept in TreeCache.
* Its notable omission is the note content.
*/
@@ -99,6 +106,140 @@ class NoteShort {
return await this.treeCache.getNotes(this.getChildNoteIds());
}
/**
* @param {string} [name] - attribute name to filter
* @returns {Promise&lt;Attribute[]>}
*/
async getAttributes(name) {
if (!this.attributeCache) {
this.attributeCache = await server.get('notes/' + this.noteId + '/attributes');
}
if (name) {
return this.attributeCache.filter(attr => attr.name === name);
}
else {
return this.attributeCache;
}
}
/**
* @param {string} [name] - label name to filter
* @returns {Promise&lt;Attribute[]>} all note's labels (attributes with type label), including inherited ones
*/
async getLabels(name) {
return (await this.getAttributes(name)).filter(attr => attr.type === LABEL);
}
/**
* @param {string} [name] - label name to filter
* @returns {Promise&lt;Attribute[]>} all note's label definitions, including inherited ones
*/
async getLabelDefinitions(name) {
return (await this.getAttributes(name)).filter(attr => attr.type === LABEL_DEFINITION);
}
/**
* @param {string} [name] - relation name to filter
* @returns {Promise&lt;Attribute[]>} all note's relations (attributes with type relation), including inherited ones
*/
async getRelations(name) {
return (await this.getAttributes(name)).filter(attr => attr.type === RELATION);
}
/**
* @param {string} [name] - relation name to filter
* @returns {Promise&lt;Attribute[]>} all note's relation definitions including inherited ones
*/
async getRelationDefinitions(name) {
return (await this.getAttributes(name)).filter(attr => attr.type === RELATION_DEFINITION);
}
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
* @returns {Promise&lt;boolean>} true if note has an attribute with given type and name (including inherited)
*/
async hasAttribute(type, name) {
return !!await this.getAttribute(type, name);
}
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
* @returns {Promise&lt;Attribute>} attribute of given type and name. If there's more such attributes, first is returned. Returns null if there's no such attribute belonging to this note.
*/
async getAttribute(type, name) {
const attributes = await this.getAttributes();
return attributes.find(attr => attr.type === type &amp;&amp; attr.name === name);
}
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
* @returns {Promise&lt;string>} attribute value of given type and name or null if no such attribute exists.
*/
async getAttributeValue(type, name) {
const attr = await this.getAttribute(type, name);
return attr ? attr.value : null;
}
/**
* @param {string} name - label name
* @returns {Promise&lt;boolean>} true if label exists (including inherited)
*/
async hasLabel(name) { return await this.hasAttribute(LABEL, name); }
/**
* @param {string} name - relation name
* @returns {Promise&lt;boolean>} true if relation exists (including inherited)
*/
async hasRelation(name) { return await this.hasAttribute(RELATION, name); }
/**
* @param {string} name - label name
* @returns {Promise&lt;Attribute>} label if it exists, null otherwise
*/
async getLabel(name) { return await this.getAttribute(LABEL, name); }
/**
* @param {string} name - relation name
* @returns {Promise&lt;Attribute>} relation if it exists, null otherwise
*/
async getRelation(name) { return await this.getAttribute(RELATION, name); }
/**
* @param {string} name - label name
* @returns {Promise&lt;string>} label value if label exists, null otherwise
*/
async getLabelValue(name) { return await this.getAttributeValue(LABEL, name); }
/**
* @param {string} name - relation name
* @returns {Promise&lt;string>} relation value if relation exists, null otherwise
*/
async getRelationValue(name) { return await this.getAttributeValue(RELATION, name); }
/**
* @param {string} name
* @returns {Promise&lt;Note>|null} target note of the relation or null (if target is empty or note was not found)
*/
async getRelationTarget(name) {
const relation = await this.getRelation(name);
return relation ? await repository.getNote(relation.value) : null;
}
/**
* Clear note's attributes cache to force fresh reload for next attribute request.
* Cache is note instance scoped.
*/
invalidateAttributeCache() {
this.attributeCache = null;
}
get toString() {
return `Note(noteId=${this.noteId}, title=${this.title})`;
}
@@ -107,6 +248,7 @@ class NoteShort {
const dto = Object.assign({}, this);
delete dto.treeCache;
delete dto.archived;
delete dto.attributeCache;
return dto;
}

View File

@@ -303,7 +303,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line47">line 47</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line49">line 49</a>
</li></ul></dd>

View File

@@ -34,6 +34,8 @@ import linkService from './link.js';
import treeCache from './tree_cache.js';
import noteDetailService from './note_detail.js';
import noteTypeService from './note_type.js';
import noteTooltipService from './note_tooltip.js';
import protectedSessionService from'./protected_session.js';
/**
* This is the main frontend API interface for scripts. It's published in the local "api" object.
@@ -69,7 +71,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) {
this.activateNewNote = async notePath => {
await treeService.reload();
await treeService.activateNote(notePath, true);
await treeService.activateNote(notePath, noteDetailService.focusAndSelectTitle);
};
/**
@@ -226,9 +228,28 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) {
/**
* @method
* @returns {string} content of currently loaded note in the editor (HTML, code etc.)
* @returns {string} content of active note (loaded into right pane)
*/
this.getCurrentNoteContent = noteDetailService.getCurrentNoteContent;
this.getActiveNoteContent = noteDetailService.getActiveNoteContent;
/**
* @method
* @returns {NoteFull} active note (loaded into right pane)
*/
this.getActiveNote = noteDetailService.getActiveNote;
/**
* This method checks whether user navigated away from the note from which the scripts has been started.
* This is necessary because script execution is async and by the time it is finished, the user might have
* already navigated away from this page - the end result would be that script might return data for the wrong
* note.
*
* @method
* @return {boolean} returns true if the original note is still loaded, false if user switched to another
*/
this.isNoteStillActive = () => {
return this.originEntity.noteId === noteDetailService.getActiveNoteId();
};
/**
* @method
@@ -253,6 +274,17 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) {
* @param {array} types - list of mime types to be used
*/
this.setCodeMimeTypes = noteTypeService.setCodeMimeTypes;
/**
* @method
* @param {object} $el - jquery object on which to setup the tooltip
*/
this.setupElementTooltip = noteTooltipService.setupElementTooltip;
/**
* @method
*/
this.protectActiveNote = protectedSessionService.protectNoteAndSendToServer;
}
export default FrontendScriptApi;</code></pre>

View File

@@ -3,10 +3,12 @@
const electron = require('electron');
const path = require('path');
const log = require('./src/services/log');
const sqlInit = require('./src/services/sql_init');
const cls = require('./src/services/cls');
const url = require("url");
const port = require('./src/services/port');
const appIconService = require('./src/services/app_icon');
const windowStateKeeper = require('electron-window-state');
const app = electron.app;
const globalShortcut = electron.globalShortcut;
@@ -28,14 +30,29 @@ function onClosed() {
}
async function createMainWindow() {
const win = new electron.BrowserWindow({
// initial window width & height so it's usable on 1600 * 900 display (including some extra panels etc.)
width: 1200,
height: 800,
title: 'Trilium Notes',
icon: path.join(__dirname, 'src/public/images/app-icons/png/256x256.png')
// if schema doesn't exist -> setup process
// if schema exists, then we need to wait until the migration process is finished
if (await sqlInit.schemaExists()) {
await sqlInit.dbReady;
}
const mainWindowState = windowStateKeeper({
// default window width & height so it's usable on 1600 * 900 display (including some extra panels etc.)
defaultWidth: 1200,
defaultHeight: 800
});
const win = new electron.BrowserWindow({
x: mainWindowState.x,
y: mainWindowState.y,
width: mainWindowState.width,
height: mainWindowState.height,
title: 'Trilium Notes',
icon: path.join(__dirname, 'images/app-icons/png/256x256.png')
});
mainWindowState.manage(win);
win.setMenu(null);
win.loadURL('http://localhost:' + await port);
win.on('closed', onClosed);
@@ -81,7 +98,7 @@ app.on('ready', async () => {
const dateNoteService = require('./src/services/date_notes');
const dateUtils = require('./src/services/date_utils');
const parentNote = await dateNoteService.getDateNote(dateUtils.nowDate());
const parentNote = await dateNoteService.getDateNote(dateUtils.localNowDate());
// window may be hidden / not in focus
mainWindow.focus();

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 820 B

After

Width:  |  Height:  |  Size: 820 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

Before

Width:  |  Height:  |  Size: 353 KiB

After

Width:  |  Height:  |  Size: 353 KiB

1
images/shield.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-opacity="0.03" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shield"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg>

After

Width:  |  Height:  |  Size: 296 B

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

5
issue_template.md Normal file
View File

@@ -0,0 +1,5 @@
For bug reports, please mention **version of the application** and include **log files** from following location:
* `/home/[user]/.local/share/trilium-data/log` for Linux
* `C:\Users\[user]\AppData\Roaming\trilium-data\log` for Windows Vista and up
* `/Users/[user]/Library/Application Support/trilium-data/log` for Mac OS

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

6
libraries/ckeditor/ckeditor.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -28,7 +28,7 @@
}
async function validatorJavaScript(text, options) {
if (glob.getCurrentNote().mime === 'application/json') {
if (glob.getActiveNote().mime === 'application/json') {
// eslint doesn't seem to validate pure JSON well
return [];
}

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