mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	Compare commits
	
		
			13 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 69cbfaae17 | ||
|  | aebce8f12b | ||
|  | 045ca1f0bf | ||
|  | bf2db6eac7 | ||
|  | cf84114f91 | ||
|  | 6426157bb3 | ||
|  | 332fc16852 | ||
|  | da2cd57428 | ||
|  | de9bab1181 | ||
|  | 136375cf11 | ||
|  | eabc7f80b7 | ||
|  | 6405d6e066 | ||
|  | f6d481a9e2 | 
							
								
								
									
										10
									
								
								bin/build.sh
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								bin/build.sh
									
									
									
									
									
								
							| @@ -8,9 +8,15 @@ cp -r ../trilium-node-binaries/sqlite/* node_modules/sqlite3/lib/binding/ | ||||
|  | ||||
| cp -r ../trilium-node-binaries/scrypt/* node_modules/scrypt/bin/ | ||||
|  | ||||
| ./node_modules/.bin/electron-rebuild | ||||
| ./node_modules/.bin/electron-rebuild --arch=ia32 | ||||
|  | ||||
| ./node_modules/.bin/electron-packager . --out=dist --platform=linux,win32 --overwrite | ||||
| ./node_modules/.bin/electron-packager . --out=dist --platform=linux --arch=ia32 --overwrite | ||||
|  | ||||
| ./node_modules/.bin/electron-rebuild --arch=x64 | ||||
|  | ||||
| ./node_modules/.bin/electron-packager . --out=dist --platform=linux --arch=x64 --overwrite | ||||
|  | ||||
| ./node_modules/.bin/electron-packager . --out=dist --platform=win32 --arch=x64 --overwrite | ||||
|  | ||||
| # can't copy this before the packaging because the same file name is used for both linux and windows build | ||||
| cp ../trilium-node-binaries/scrypt.node ./dist/trilium-win32-x64/resources/app/node_modules/scrypt/build/Release/ | ||||
|   | ||||
| @@ -4,8 +4,11 @@ VERSION=`jq -r ".version" package.json` | ||||
|  | ||||
| cd dist | ||||
|  | ||||
| echo "Packaging windows electron distribution..." | ||||
| 7z a trilium-windows-${VERSION}.7z trilium-win32-x64 | ||||
| echo "Packaging linux x64 electron distribution..." | ||||
| 7z a trilium-linux-x64-${VERSION}.7z trilium-linux-x64 | ||||
|  | ||||
| echo "Packaging linux electron distribution..." | ||||
| 7z a trilium-linux-${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 | ||||
| @@ -44,8 +44,9 @@ bin/build.sh | ||||
|  | ||||
| bin/package.sh | ||||
|  | ||||
| LINUX_BUILD=trilium-linux-$VERSION.7z | ||||
| WINDOWS_BUILD=trilium-windows-$VERSION.7z | ||||
| LINUX_X64_BUILD=trilium-linux-x64-$VERSION.7z | ||||
| LINUX_IA32_BUILD=trilium-linux-ia32-$VERSION.7z | ||||
| WINDOWS_X64_BUILD=trilium-windows-x64-$VERSION.7z | ||||
|  | ||||
| echo "Creating release in GitHub" | ||||
|  | ||||
| @@ -53,18 +54,25 @@ github-release release \ | ||||
|     --tag $TAG \ | ||||
|     --name "$TAG release" | ||||
|  | ||||
| echo "Uploading linux build" | ||||
| echo "Uploading linux x64 build" | ||||
|  | ||||
| github-release upload \ | ||||
|     --tag $TAG \ | ||||
|     --name "$LINUX_BUILD" \ | ||||
|     --file "dist/$LINUX_BUILD" | ||||
|     --name "$LINUX_X64_BUILD" \ | ||||
|     --file "dist/$LINUX_X64_BUILD" | ||||
|  | ||||
| echo "Uploading windows build" | ||||
| echo "Uploading linux ia32 build" | ||||
|  | ||||
| github-release upload \ | ||||
|     --tag $TAG \ | ||||
|     --name "$WINDOWS_BUILD" \ | ||||
|     --file "dist/$WINDOWS_BUILD" | ||||
|     --name "$LINUX_IA32_BUILD" \ | ||||
|     --file "dist/$LINUX_IA32_BUILD" | ||||
|  | ||||
| echo "Uploading windows x64 build" | ||||
|  | ||||
| github-release upload \ | ||||
|     --tag $TAG \ | ||||
|     --name "$WINDOWS_X64_BUILD" \ | ||||
|     --file "dist/$WINDOWS_X64_BUILD" | ||||
|  | ||||
| echo "Release finished!" | ||||
							
								
								
									
										1
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								index.js
									
									
									
									
									
								
							| @@ -21,6 +21,7 @@ function createMainWindow() { | ||||
|     const win = new electron.BrowserWindow({ | ||||
|         width: 1200, | ||||
|         height: 900, | ||||
|         title: 'Trilium Notes', | ||||
|         icon: path.join(__dirname, 'public/images/app-icons/png/256x256.png') | ||||
|     }); | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| { | ||||
|   "name": "trilium", | ||||
|   "description": "Trilium Notes", | ||||
|   "version": "0.1.0", | ||||
|   "version": "0.1.2", | ||||
|   "scripts": { | ||||
|     "start": "node ./bin/www", | ||||
|     "test-electron": "xo", | ||||
|   | ||||
| @@ -57,6 +57,42 @@ $(document).bind('keydown', 'ctrl+f', () => { | ||||
|     } | ||||
| }); | ||||
|  | ||||
| $(document).bind('keydown', "ctrl+shift+left", () => { | ||||
|     const node = noteTree.getCurrentNode(); | ||||
|     node.navigate($.ui.keyCode.LEFT, true); | ||||
|  | ||||
|     $("#note-detail").focus(); | ||||
|  | ||||
|     return false; | ||||
| }); | ||||
|  | ||||
| $(document).bind('keydown', "ctrl+shift+right", () => { | ||||
|     const node = noteTree.getCurrentNode(); | ||||
|     node.navigate($.ui.keyCode.RIGHT, true); | ||||
|  | ||||
|     $("#note-detail").focus(); | ||||
|  | ||||
|     return false; | ||||
| }); | ||||
|  | ||||
| $(document).bind('keydown', "ctrl+shift+up", () => { | ||||
|     const node = noteTree.getCurrentNode(); | ||||
|     node.navigate($.ui.keyCode.UP, true); | ||||
|  | ||||
|     $("#note-detail").focus(); | ||||
|  | ||||
|     return false; | ||||
| }); | ||||
|  | ||||
| $(document).bind('keydown', "ctrl+shift+down", () => { | ||||
|     const node = noteTree.getCurrentNode(); | ||||
|     node.navigate($.ui.keyCode.DOWN, true); | ||||
|  | ||||
|     $("#note-detail").focus(); | ||||
|  | ||||
|     return false; | ||||
| }); | ||||
|  | ||||
| $(window).on('beforeunload', () => { | ||||
|     // this makes sure that when user e.g. reloads the page or navigates away from the page, the note's content is saved | ||||
|     // this sends the request asynchronously and doesn't wait for result | ||||
|   | ||||
| @@ -128,6 +128,9 @@ const noteEditor = (function() { | ||||
|         setNoteBackgroundIfProtected(currentNote); | ||||
|         noteTree.setNoteTreeBackgroundBasedOnProtectedStatus(noteId); | ||||
|  | ||||
|         // after loading new note make sure editor is scrolled to the top | ||||
|         noteDetailWrapperEl.scrollTop(0); | ||||
|  | ||||
|         showAppIfHidden(); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -4,6 +4,7 @@ const noteTree = (function() { | ||||
|     const treeEl = $("#tree"); | ||||
|     const parentListEl = $("#parent-list"); | ||||
|     const parentListListEl = $("#parent-list-list"); | ||||
|     const noteDetailEl = $("#note-detail"); | ||||
|  | ||||
|     let startNotePath = null; | ||||
|     let notesTreeMap = {}; | ||||
| @@ -59,23 +60,6 @@ const noteTree = (function() { | ||||
|         return treeUtils.getNotePath(node); | ||||
|     } | ||||
|  | ||||
|     function getCurrentNoteId() { | ||||
|         const node = getCurrentNode(); | ||||
|  | ||||
|         return node ? node.data.note_id : null; | ||||
|     } | ||||
|  | ||||
|     function getCurrentClones() { | ||||
|         const noteId = getCurrentNoteId(); | ||||
|  | ||||
|         if (noteId) { | ||||
|             return getNodesByNoteId(noteId); | ||||
|         } | ||||
|         else { | ||||
|             return []; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function getNodesByNoteTreeId(noteTreeId) { | ||||
|         assertArguments(noteTreeId); | ||||
|  | ||||
| @@ -185,13 +169,15 @@ const noteTree = (function() { | ||||
|             const noteTreeId = getNoteTreeId(parentNoteId, noteId); | ||||
|             const noteTree = notesTreeMap[noteTreeId]; | ||||
|  | ||||
|             const title = (noteTree.prefix ? (noteTree.prefix + " - ") : "") + noteIdToTitle[noteTree.note_id]; | ||||
|  | ||||
|             const node = { | ||||
|                 note_id: noteTree.note_id, | ||||
|                 parent_note_id: noteTree.parent_note_id, | ||||
|                 note_tree_id: noteTree.note_tree_id, | ||||
|                 is_protected: noteTree.is_protected, | ||||
|                 prefix: noteTree.prefix, | ||||
|                 title: (noteTree.prefix ? (noteTree.prefix + " - ") : "") + noteIdToTitle[noteTree.note_id], | ||||
|                 title: escapeHtml(title), | ||||
|                 extraClasses: getExtraClasses(noteTree), | ||||
|                 refKey: noteTree.note_id, | ||||
|                 expanded: noteTree.is_expanded | ||||
| @@ -432,6 +418,30 @@ const noteTree = (function() { | ||||
|             "alt+-": node => { | ||||
|                 collapseTree(node); | ||||
|             }, | ||||
|             "ctrl+c": node => { | ||||
|                 contextMenu.copy(node); | ||||
|  | ||||
|                 showMessage("Note copied into clipboard."); | ||||
|  | ||||
|                 return false; | ||||
|             }, | ||||
|             "ctrl+x": node => { | ||||
|                 contextMenu.cut(node); | ||||
|  | ||||
|                 showMessage("Note cut into clipboard."); | ||||
|  | ||||
|                 return false; | ||||
|             }, | ||||
|             "ctrl+v": node => { | ||||
|                 contextMenu.pasteInto(node); | ||||
|  | ||||
|                 showMessage("Note pasted from clipboard into current note."); | ||||
|  | ||||
|                 return false; | ||||
|             }, | ||||
|             "ctrl+return": node => { | ||||
|                 noteDetailEl.focus(); | ||||
|             }, | ||||
|             // code below shouldn't be necessary normally, however there's some problem with interaction with context menu plugin | ||||
|             // after opening context menu, standard shortcuts don't work, but they are detected here | ||||
|             // so we essentially takeover the standard handling with our implementation. | ||||
| @@ -513,57 +523,6 @@ const noteTree = (function() { | ||||
|                 mode: "hide"       // Grayout unmatched nodes (pass "hide" to remove unmatched node instead) | ||||
|             }, | ||||
|             dnd: dragAndDropSetup, | ||||
|             keydown: (event, data) => { | ||||
|                 const node = data.node; | ||||
|                 // Eat keyboard events, when a menu is open | ||||
|                 if ($(".contextMenu:visible").length > 0) | ||||
|                     return false; | ||||
|  | ||||
|                 switch (event.which) { | ||||
|                     // Open context menu on [Space] key (simulate right click) | ||||
|                     case 32: // [Space] | ||||
|                         $(node.span).trigger("mousedown", { | ||||
|                             preventDefault: true, | ||||
|                             button: 2 | ||||
|                         }) | ||||
|                             .trigger("mouseup", { | ||||
|                                 preventDefault: true, | ||||
|                                 pageX: node.span.offsetLeft, | ||||
|                                 pageY: node.span.offsetTop, | ||||
|                                 button: 2 | ||||
|                             }); | ||||
|                         return false; | ||||
|  | ||||
|                     // Handle Ctrl+C, +X and +V | ||||
|                     case 67: | ||||
|                         if (event.ctrlKey) { // Ctrl+C | ||||
|                             contextMenu.copy(node); | ||||
|  | ||||
|                             showMessage("Note copied into clipboard."); | ||||
|  | ||||
|                             return false; | ||||
|                         } | ||||
|                         break; | ||||
|                     case 88: | ||||
|                         if (event.ctrlKey) { // Ctrl+X | ||||
|                             contextMenu.cut(node); | ||||
|  | ||||
|                             showMessage("Note cut into clipboard."); | ||||
|  | ||||
|                             return false; | ||||
|                         } | ||||
|                         break; | ||||
|                     case 86: | ||||
|                         if (event.ctrlKey) { // Ctrl+V | ||||
|                             contextMenu.pasteInto(node); | ||||
|  | ||||
|                             showMessage("Note pasted from clipboard into current note."); | ||||
|  | ||||
|                             return false; | ||||
|                         } | ||||
|                         break; | ||||
|                 } | ||||
|             }, | ||||
|             lazyLoad: function(event, data){ | ||||
|                 const node = data.node.data; | ||||
|  | ||||
|   | ||||
| @@ -29,10 +29,12 @@ const treeChanges = (function() { | ||||
|         await server.put('notes/' + node.data.note_tree_id + '/move-to/' + toNode.data.note_id); | ||||
|  | ||||
|         changeNode(node, node => { | ||||
|             node.moveTo(toNode); | ||||
|  | ||||
|             // first expand which will force lazy load and only then move the node | ||||
|             // if this is not expanded before moving, then lazy load won't happen because it already contains node | ||||
|             toNode.setExpanded(true); | ||||
|  | ||||
|             node.moveTo(toNode); | ||||
|  | ||||
|             toNode.folder = true; | ||||
|             toNode.renderTitle(); | ||||
|         }); | ||||
|   | ||||
| @@ -37,7 +37,7 @@ const treeUtils = (function() { | ||||
|  | ||||
|         const title = (prefix ? (prefix + " - ") : "") + noteTitle; | ||||
|  | ||||
|         node.setTitle(title); | ||||
|         node.setTitle(escapeHtml(title)); | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|   | ||||
| @@ -93,4 +93,8 @@ function isTopLevelNode(node) { | ||||
|  | ||||
| function isRootNode(node) { | ||||
|     return node.key === "root_1"; | ||||
| } | ||||
|  | ||||
| function escapeHtml(str) { | ||||
|     return $('<div/>').text(str).html(); | ||||
| } | ||||
| @@ -74,6 +74,12 @@ span.fancytree-node.fancytree-active-clone:not(.fancytree-active) .fancytree-tit | ||||
|     font-weight: bold; | ||||
| } | ||||
|  | ||||
| /* By default not focused active tree item is not easily visible, this makes it more visible */ | ||||
| span.fancytree-active:not(.fancytree-focused) .fancytree-title { | ||||
|     background-color: #ddd !important; | ||||
|     border-color: #555 !important; | ||||
| } | ||||
|  | ||||
| .ui-autocomplete { | ||||
|     max-height: 300px; | ||||
|     overflow-y: auto; | ||||
|   | ||||
| @@ -3,12 +3,9 @@ | ||||
| const migration = require('./migration'); | ||||
| const sql = require('./sql'); | ||||
| const utils = require('./utils'); | ||||
| const options = require('./options'); | ||||
|  | ||||
| async function checkAuth(req, res, next) { | ||||
|     const username = await options.getOption('username'); | ||||
|  | ||||
|     if (!username) { | ||||
|     if (!await sql.isUserInitialized()) { | ||||
|         res.redirect("setup"); | ||||
|     } | ||||
|     else if (!req.session.loggedIn && !utils.isElectron()) { | ||||
| @@ -53,9 +50,7 @@ async function checkApiAuthForMigrationPage(req, res, next) { | ||||
| } | ||||
|  | ||||
| async function checkAppNotInitialized(req, res, next) { | ||||
|     const username = await options.getOption('username'); | ||||
|  | ||||
|     if (username) { | ||||
|     if (await sql.isUserInitialized()) { | ||||
|         res.status(400).send("App already initialized."); | ||||
|     } | ||||
|     else { | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| module.exports = { build_date:"2017-12-26T22:59:46-05:00", build_revision: "ae337e45009c3938dddcbb3452b271f97eb80bce" }; | ||||
| module.exports = { build_date:"2017-12-28T21:17:25-05:00", build_revision: "aebce8f12b87e7c3d5dbd23e75918f3d01a4cc64" }; | ||||
|   | ||||
| @@ -4,8 +4,9 @@ const ini = require('ini'); | ||||
| const fs = require('fs'); | ||||
| const dataDir = require('./data_dir'); | ||||
| const path = require('path'); | ||||
| const resource_dir = require('./resource_dir'); | ||||
|  | ||||
| const configSampleFilePath = path.resolve(__dirname, "..", "config-sample.ini"); | ||||
| const configSampleFilePath = path.resolve(resource_dir.RESOURCE_DIR, "config-sample.ini"); | ||||
|  | ||||
| const configFilePath = dataDir.TRILIUM_DATA_DIR + '/config.ini'; | ||||
|  | ||||
|   | ||||
| @@ -3,14 +3,7 @@ const sql = require('./sql'); | ||||
| const options = require('./options'); | ||||
| const fs = require('fs-extra'); | ||||
| const log = require('./log'); | ||||
| const path = require('path'); | ||||
|  | ||||
| const MIGRATIONS_DIR = path.resolve(__dirname, "..", "migrations"); | ||||
|  | ||||
| if (!fs.existsSync(MIGRATIONS_DIR)) { | ||||
|     log.error("Could not find migration directory: " + MIGRATIONS_DIR); | ||||
|     process.exit(1); | ||||
| } | ||||
| const resource_dir = require('./resource_dir'); | ||||
|  | ||||
| async function migrate() { | ||||
|     const migrations = []; | ||||
| @@ -20,7 +13,7 @@ async function migrate() { | ||||
|  | ||||
|     const currentDbVersion = parseInt(await options.getOption('db_version')); | ||||
|  | ||||
|     fs.readdirSync(MIGRATIONS_DIR).forEach(file => { | ||||
|     fs.readdirSync(resource_dir.MIGRATIONS_DIR).forEach(file => { | ||||
|         const match = file.match(/([0-9]{4})__([a-zA-Z0-9_ ]+)\.(sql|js)/); | ||||
|  | ||||
|         if (match) { | ||||
| @@ -53,7 +46,7 @@ async function migrate() { | ||||
|  | ||||
|             await sql.doInTransaction(async () => { | ||||
|                 if (mig.type === 'sql') { | ||||
|                     const migrationSql = fs.readFileSync(MIGRATIONS_DIR + "/" + mig.file).toString('utf8'); | ||||
|                     const migrationSql = fs.readFileSync(resource_dir.MIGRATIONS_DIR + "/" + mig.file).toString('utf8'); | ||||
|  | ||||
|                     console.log("Migration with SQL script: " + migrationSql); | ||||
|  | ||||
| @@ -62,7 +55,7 @@ async function migrate() { | ||||
|                 else if (mig.type === 'js') { | ||||
|                     console.log("Migration with JS module"); | ||||
|  | ||||
|                     const migrationModule = require("../" + MIGRATIONS_DIR + "/" + mig.file); | ||||
|                     const migrationModule = require("../" + resource_dir.MIGRATIONS_DIR + "/" + mig.file); | ||||
|                     await migrationModule(db); | ||||
|                 } | ||||
|                 else { | ||||
|   | ||||
							
								
								
									
										25
									
								
								services/resource_dir.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								services/resource_dir.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| const log = require('./log'); | ||||
| const path = require('path'); | ||||
| const fs = require('fs'); | ||||
|  | ||||
| const RESOURCE_DIR = path.resolve(__dirname, ".."); | ||||
|  | ||||
| const MIGRATIONS_DIR = path.resolve(RESOURCE_DIR, "migrations"); | ||||
|  | ||||
| if (!fs.existsSync(MIGRATIONS_DIR)) { | ||||
|     log.error("Could not find migration directory: " + MIGRATIONS_DIR); | ||||
|     process.exit(1); | ||||
| } | ||||
|  | ||||
| const DB_INIT_DIR = path.resolve(RESOURCE_DIR, "db"); | ||||
|  | ||||
| if (!fs.existsSync(DB_INIT_DIR)) { | ||||
|     log.error("Could not find DB initialization directory: " + DB_INIT_DIR); | ||||
|     process.exit(1); | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|     RESOURCE_DIR, | ||||
|     MIGRATIONS_DIR, | ||||
|     DB_INIT_DIR | ||||
| }; | ||||
| @@ -4,8 +4,8 @@ const log = require('./log'); | ||||
| const dataDir = require('./data_dir'); | ||||
| const fs = require('fs'); | ||||
| const sqlite = require('sqlite'); | ||||
| const utils = require('./utils'); | ||||
| const app_info = require('./app_info'); | ||||
| const resource_dir = require('./resource_dir'); | ||||
|  | ||||
| async function createConnection() { | ||||
|     return await sqlite.open(dataDir.DOCUMENT_PATH, {Promise}); | ||||
| @@ -28,9 +28,9 @@ const dbReady = new Promise((resolve, reject) => { | ||||
|         if (tableResults.length !== 1) { | ||||
|             log.info("Connected to db, but schema doesn't exist. Initializing schema ..."); | ||||
|  | ||||
|             const schema = fs.readFileSync('db/schema.sql', 'UTF-8'); | ||||
|             const notesSql = fs.readFileSync('db/main_notes.sql', 'UTF-8'); | ||||
|             const notesTreeSql = fs.readFileSync('db/main_notes_tree.sql', 'UTF-8'); | ||||
|             const schema = fs.readFileSync(resource_dir.DB_INIT_DIR + '/schema.sql', 'UTF-8'); | ||||
|             const notesSql = fs.readFileSync(resource_dir.DB_INIT_DIR + '/main_notes.sql', 'UTF-8'); | ||||
|             const notesTreeSql = fs.readFileSync(resource_dir.DB_INIT_DIR + '/main_notes_tree.sql', 'UTF-8'); | ||||
|  | ||||
|             await doInTransaction(async () => { | ||||
|                 await executeScript(schema); | ||||
| @@ -49,9 +49,7 @@ const dbReady = new Promise((resolve, reject) => { | ||||
|             // the database | ||||
|         } | ||||
|         else { | ||||
|             const username = await getFirstValue("SELECT opt_value FROM options WHERE opt_name = 'username'"); | ||||
|  | ||||
|             if (!username) { | ||||
|             if (!await isUserInitialized()) { | ||||
|                 log.info("Login/password not initialized. DB not ready."); | ||||
|  | ||||
|                 return; | ||||
| @@ -235,8 +233,15 @@ async function isDbUpToDate() { | ||||
|     return upToDate; | ||||
| } | ||||
|  | ||||
| async function isUserInitialized() { | ||||
|     const username = await getFirstValue("SELECT opt_value FROM options WHERE opt_name = 'username'"); | ||||
|  | ||||
|     return !!username; | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|     dbReady, | ||||
|     isUserInitialized, | ||||
|     insert, | ||||
|     replace, | ||||
|     getFirstValue, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user