| 
									
										
										
										
											2019-08-26 20:21:43 +02:00
										 |  |  | import ws from './ws.js'; | 
					
						
							| 
									
										
										
										
											2018-03-25 21:16:57 -04:00
										 |  |  | import protectedSessionHolder from './protected_session_holder.js'; | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | import utils from './utils.js'; | 
					
						
							|  |  |  | import server from './server.js'; | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  | import treeCache from './tree_cache.js'; | 
					
						
							| 
									
										
										
										
											2019-10-20 10:00:18 +02:00
										 |  |  | import toastService from "./toast.js"; | 
					
						
							| 
									
										
										
										
											2018-03-26 23:18:50 -04:00
										 |  |  | import treeBuilder from "./tree_builder.js"; | 
					
						
							| 
									
										
										
										
											2018-12-12 20:39:56 +01:00
										 |  |  | import hoistedNoteService from '../services/hoisted_note.js'; | 
					
						
							| 
									
										
										
										
											2019-08-25 17:36:13 +02:00
										 |  |  | import optionsService from "../services/options.js"; | 
					
						
							| 
									
										
										
										
											2019-05-29 21:10:28 +02:00
										 |  |  | import bundle from "./bundle.js"; | 
					
						
							| 
									
										
										
										
											2020-01-12 11:15:23 +01:00
										 |  |  | import appContext from "./app_context.js"; | 
					
						
							| 
									
										
										
										
											2020-01-12 09:12:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-11 21:27:27 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Accepts notePath which might or might not be valid and returns an existing path as close to the original | 
					
						
							|  |  |  |  * notePath as possible. | 
					
						
							| 
									
										
										
										
											2019-10-20 13:09:00 +02:00
										 |  |  |  * @return {string|null} | 
					
						
							| 
									
										
										
										
											2019-05-11 21:27:27 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | async function resolveNotePath(notePath) { | 
					
						
							|  |  |  |     const runPath = await getRunPath(notePath); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-14 22:29:47 +02:00
										 |  |  |     return runPath ? runPath.join("/") : null; | 
					
						
							| 
									
										
										
										
											2019-05-11 21:27:27 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Accepts notePath and tries to resolve it. Part of the path might not be valid because of note moving (which causes | 
					
						
							|  |  |  |  * path change) or other corruption, in that case this will try to get some other valid path to the correct note. | 
					
						
							| 
									
										
										
										
											2019-10-20 13:09:00 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * @return {string[]} | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |  */ | 
					
						
							|  |  |  | async function getRunPath(notePath) { | 
					
						
							|  |  |  |     utils.assertArguments(notePath); | 
					
						
							| 
									
										
										
										
											2017-12-23 11:02:38 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-28 14:08:05 +02:00
										 |  |  |     notePath = notePath.split("-")[0].trim(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (notePath.length === 0) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-07-09 22:12:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     const path = notePath.split("/").reverse(); | 
					
						
							| 
									
										
										
										
											2018-05-26 16:16:34 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!path.includes("root")) { | 
					
						
							|  |  |  |         path.push('root'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-11-19 08:47:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-12 20:39:56 +01:00
										 |  |  |     const hoistedNoteId = await hoistedNoteService.getHoistedNoteId(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     const effectivePath = []; | 
					
						
							|  |  |  |     let childNoteId = null; | 
					
						
							|  |  |  |     let i = 0; | 
					
						
							| 
									
										
										
										
											2017-11-19 18:16:50 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     while (true) { | 
					
						
							|  |  |  |         if (i >= path.length) { | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-11-30 00:02:32 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |         const parentNoteId = path[i++]; | 
					
						
							| 
									
										
										
										
											2017-11-19 11:28:46 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |         if (childNoteId !== null) { | 
					
						
							| 
									
										
										
										
											2018-03-25 14:49:20 -04:00
										 |  |  |             const child = await treeCache.getNote(childNoteId); | 
					
						
							| 
									
										
										
										
											2018-11-12 23:34:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (!child) { | 
					
						
							| 
									
										
										
										
											2019-05-14 22:29:47 +02:00
										 |  |  |                 console.log("Can't find note " + childNoteId); | 
					
						
							|  |  |  |                 return; | 
					
						
							| 
									
										
										
										
											2018-11-12 23:34:22 +01:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |             const parents = await child.getParentNotes(); | 
					
						
							| 
									
										
										
										
											2017-11-19 11:28:46 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |             if (!parents) { | 
					
						
							| 
									
										
										
										
											2019-08-26 20:21:43 +02:00
										 |  |  |                 ws.logError("No parents found for " + childNoteId); | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-11-26 21:00:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |             if (!parents.some(p => p.noteId === parentNoteId)) { | 
					
						
							| 
									
										
										
										
											2018-11-14 11:17:20 +01:00
										 |  |  |                 console.debug(utils.now(), "Did not find parent " + parentNoteId + " for child " + childNoteId); | 
					
						
							| 
									
										
										
										
											2017-11-19 11:28:46 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |                 if (parents.length > 0) { | 
					
						
							| 
									
										
										
										
											2018-11-14 11:17:20 +01:00
										 |  |  |                     console.debug(utils.now(), "Available parents:", parents); | 
					
						
							| 
									
										
										
										
											2017-12-23 11:02:38 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |                     const someNotePath = await getSomeNotePath(parents[0]); | 
					
						
							| 
									
										
										
										
											2017-12-23 12:19:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |                     if (someNotePath) { // in case it's root the path may be empty
 | 
					
						
							|  |  |  |                         const pathToRoot = someNotePath.split("/").reverse(); | 
					
						
							| 
									
										
										
										
											2017-11-19 18:16:50 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |                         for (const noteId of pathToRoot) { | 
					
						
							|  |  |  |                             effectivePath.push(noteId); | 
					
						
							| 
									
										
										
										
											2017-11-30 00:02:32 -05:00
										 |  |  |                         } | 
					
						
							| 
									
										
										
										
											2018-05-27 12:26:34 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         effectivePath.push('root'); | 
					
						
							| 
									
										
										
										
											2017-11-19 11:28:46 -05:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2017-11-19 08:47:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							| 
									
										
										
										
											2019-08-26 20:21:43 +02:00
										 |  |  |                     ws.logError("No parents, can't activate node."); | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |                     return; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2017-11-19 08:47:22 -05:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-03 17:46:56 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-12 20:39:56 +01:00
										 |  |  |         effectivePath.push(parentNoteId); | 
					
						
							|  |  |  |         childNoteId = parentNoteId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (parentNoteId === hoistedNoteId) { | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-11-19 08:47:22 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     return effectivePath.reverse(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-23 11:02:38 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | async function getSomeNotePath(note) { | 
					
						
							|  |  |  |     utils.assertArguments(note); | 
					
						
							| 
									
										
										
										
											2017-11-21 20:04:06 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     const path = []; | 
					
						
							| 
									
										
										
										
											2017-11-21 20:04:06 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     let cur = note; | 
					
						
							| 
									
										
										
										
											2017-11-21 20:04:06 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     while (cur.noteId !== 'root') { | 
					
						
							|  |  |  |         path.push(cur.noteId); | 
					
						
							| 
									
										
										
										
											2018-03-24 23:00:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |         const parents = await cur.getParentNotes(); | 
					
						
							| 
									
										
										
										
											2017-12-19 21:40:48 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |         if (!parents.length) { | 
					
						
							| 
									
										
										
										
											2020-01-03 21:15:45 +01:00
										 |  |  |             console.error(`Can't find parents for note ${cur.noteId}`); | 
					
						
							| 
									
										
										
										
											2019-05-19 18:21:29 +02:00
										 |  |  |             return; | 
					
						
							| 
									
										
										
										
											2017-11-21 20:04:06 -05:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |         cur = parents[0]; | 
					
						
							| 
									
										
										
										
											2017-11-21 20:04:06 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-03 10:48:36 +01:00
										 |  |  |     path.push('root'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     return path.reverse().join('/'); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-11-04 19:28:49 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | async function sortAlphabetically(noteId) { | 
					
						
							|  |  |  |     await server.put('notes/' + noteId + '/sort'); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-18 23:41:13 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-26 20:21:43 +02:00
										 |  |  | ws.subscribeToMessages(message => { | 
					
						
							| 
									
										
										
										
											2020-02-02 22:32:44 +01:00
										 |  |  |    if (message.type === 'open-note') { | 
					
						
							| 
									
										
										
										
											2020-01-24 17:54:47 +01:00
										 |  |  |        appContext.activateOrOpenNote(message.noteId); | 
					
						
							| 
									
										
										
										
											2019-06-23 13:25:00 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |        if (utils.isElectron()) { | 
					
						
							|  |  |  |            const currentWindow = require("electron").remote.getCurrentWindow(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            currentWindow.show(); | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2018-08-01 09:26:02 +02:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-25 09:56:08 +01:00
										 |  |  | async function getParentProtectedStatus(node) { | 
					
						
							|  |  |  |     return await hoistedNoteService.isRootNode(node) ? 0 : node.getParent().data.isProtected; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function getNoteIdFromNotePath(notePath) { | 
					
						
							|  |  |  |     if (!notePath) { | 
					
						
							|  |  |  |         return null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const path = notePath.split("/"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const lastSegment = path[path.length - 1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // path could have also tabId suffix
 | 
					
						
							|  |  |  |     return lastSegment.split("-")[0]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function getNoteIdAndParentIdFromNotePath(notePath) { | 
					
						
							|  |  |  |     let parentNoteId = 'root'; | 
					
						
							|  |  |  |     let noteId = ''; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (notePath) { | 
					
						
							|  |  |  |         const path = notePath.split("/"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const lastSegment = path[path.length - 1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // path could have also tabId suffix
 | 
					
						
							|  |  |  |         noteId = lastSegment.split("-")[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (path.length > 1) { | 
					
						
							|  |  |  |             parentNoteId = path[path.length - 2]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |         parentNoteId, | 
					
						
							|  |  |  |         noteId | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | async function getNotePath(node) { | 
					
						
							|  |  |  |     if (!node) { | 
					
						
							|  |  |  |         console.error("Node is null"); | 
					
						
							|  |  |  |         return ""; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const path = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (node && !await hoistedNoteService.isRootNode(node)) { | 
					
						
							|  |  |  |         if (node.data.noteId) { | 
					
						
							|  |  |  |             path.push(node.data.noteId); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         node = node.getParent(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (node) { // null node can happen directly after unhoisting when tree is still hoisted but option has been changed already
 | 
					
						
							|  |  |  |         path.push(node.data.noteId); // root or hoisted noteId
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return path.reverse().join("/"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | async function getNoteTitle(noteId, parentNoteId = null) { | 
					
						
							|  |  |  |     utils.assertArguments(noteId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const note = await treeCache.getNote(noteId); | 
					
						
							|  |  |  |     if (!note) { | 
					
						
							|  |  |  |         return "[not found]"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let {title} = note; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (parentNoteId !== null) { | 
					
						
							|  |  |  |         const branchId = note.parentToBranch[parentNoteId]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (branchId) { | 
					
						
							|  |  |  |             const branch = treeCache.getBranch(branchId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (branch && branch.prefix) { | 
					
						
							|  |  |  |                 title = branch.prefix + ' - ' + title; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return title; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | async function getNotePathTitle(notePath) { | 
					
						
							|  |  |  |     utils.assertArguments(notePath); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const titlePath = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (notePath.startsWith('root/')) { | 
					
						
							|  |  |  |         notePath = notePath.substr(5); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // special case when we want just root's title
 | 
					
						
							|  |  |  |     if (notePath === 'root') { | 
					
						
							|  |  |  |         return await getNoteTitle(notePath); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let parentNoteId = 'root'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (const noteId of notePath.split('/')) { | 
					
						
							|  |  |  |         titlePath.push(await getNoteTitle(noteId, parentNoteId)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         parentNoteId = noteId; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return titlePath.join(' / '); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | export default { | 
					
						
							| 
									
										
										
										
											2018-03-26 22:29:14 -04:00
										 |  |  |     sortAlphabetically, | 
					
						
							| 
									
										
										
										
											2019-05-19 18:21:29 +02:00
										 |  |  |     resolveNotePath, | 
					
						
							| 
									
										
										
										
											2019-06-16 11:12:07 +02:00
										 |  |  |     getSomeNotePath, | 
					
						
							| 
									
										
										
										
											2020-01-19 18:05:06 +01:00
										 |  |  |     getRunPath, | 
					
						
							| 
									
										
										
										
											2020-01-25 09:56:08 +01:00
										 |  |  |     getParentProtectedStatus, | 
					
						
							|  |  |  |     getNotePath, | 
					
						
							|  |  |  |     getNoteIdFromNotePath, | 
					
						
							|  |  |  |     getNoteIdAndParentIdFromNotePath, | 
					
						
							|  |  |  |     getNoteTitle, | 
					
						
							|  |  |  |     getNotePathTitle | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | }; |