2019-08-26 20:21:43 +02:00
import ws from './ws.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' ;
2018-12-12 20:39:56 +01:00
import hoistedNoteService from '../services/hoisted_note.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
/ * *
2019-10-20 13:09:00 +02:00
* @ return { string | null }
2019-05-11 21:27:27 +02:00
* /
async function resolveNotePath ( notePath ) {
2020-08-24 23:33:27 +02:00
const runPath = await resolveNotePathToSegments ( notePath ) ;
2019-05-11 21:27:27 +02:00
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
/ * *
2020-08-24 23:33: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 . Part of the path might not be valid because of note moving ( which causes
2018-03-25 11:09:17 -04:00
* 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
* /
2020-08-24 23:33:27 +02:00
async function resolveNotePathToSegments ( notePath , logErrors = true ) {
2018-03-25 11:09:17 -04:00
utils . assertArguments ( notePath ) ;
2017-12-23 11:02:38 -05:00
2020-08-24 23:33:27 +02:00
// we might get notePath with the tabId suffix, remove it if present
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-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 ) {
2020-08-24 23:33:27 +02:00
console . log ( ` Can't find note ${ childNoteId } ` ) ;
2019-05-14 22:29:47 +02:00
return ;
2018-11-12 23:34:22 +01:00
}
2020-03-18 22:35:54 +01:00
const parents = child . getParentNotes ( ) ;
2017-11-19 11:28:46 -05:00
2020-08-24 23:33:27 +02:00
if ( ! parents . length ) {
if ( logErrors ) {
2020-10-19 22:10:25 +02:00
ws . logError ( ` No parents found for ${ childNoteId } ( ${ child . title } ) for path ${ notePath } ` ) ;
2020-08-24 23:33:27 +02:00
}
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 ) ) {
2020-06-10 23:43:59 +02:00
if ( logErrors ) {
2020-10-12 21:05:34 +02:00
const parent = treeCache . getNoteFromCache ( parentNoteId ) ;
console . log ( utils . now ( ) , ` Did not find parent ${ parentNoteId } ( ${ parent ? parent . title : 'n/a' } ) for child ${ childNoteId } ( ${ child . title } ), available parents: ${ parents . map ( p => ` ${ p . noteId } ( ${ p . title } ) ` ) } ` ) ;
2020-06-10 23:43:59 +02:00
}
2017-11-19 11:28:46 -05:00
2020-08-24 23:33:27 +02:00
const someNotePath = getSomeNotePath ( parents [ 0 ] ) ;
2017-11-19 18:16:50 -05:00
2020-08-24 23:33:27 +02:00
if ( someNotePath ) { // in case it's root the path may be empty
const pathToRoot = someNotePath . split ( "/" ) . reverse ( ) ;
2018-05-27 12:26:34 -04:00
2020-08-24 23:33:27 +02:00
for ( const noteId of pathToRoot ) {
effectivePath . push ( noteId ) ;
2017-11-19 11:28:46 -05:00
}
2018-03-25 11:09:17 -04:00
}
2020-06-10 23:43:59 +02:00
2020-08-24 23:33:27 +02:00
break ;
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 ;
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
2020-05-09 14:25:27 +02:00
function getSomeNotePath ( note ) {
2018-03-25 11:09:17 -04:00
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
2020-03-18 22:35:54 +01:00
const parents = cur . getParentNotes ( ) ;
2017-12-19 21:40:48 -05:00
2018-03-25 11:09:17 -04:00
if ( ! parents . length ) {
2020-10-12 21:05:34 +02:00
logError ( ` 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 ) {
2020-08-24 23:33:27 +02:00
await server . put ( ` notes/ ${ noteId } /sort ` ) ;
2018-03-25 11:09:17 -04:00
}
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-02-07 21:08:55 +01:00
appContext . tabManager . activateOrOpenNote ( message . noteId ) ;
2019-06-23 13:25:00 +02:00
if ( utils . isElectron ( ) ) {
2020-04-12 14:22:51 +02:00
const currentWindow = utils . dynamicRequire ( "electron" ) . remote . getCurrentWindow ( ) ;
2019-06-23 13:25:00 +02:00
currentWindow . show ( ) ;
}
}
2018-08-01 09:26:02 +02:00
} ) ;
2020-02-10 20:57:56 +01:00
function getParentProtectedStatus ( node ) {
return hoistedNoteService . isRootNode ( node ) ? 0 : node . getParent ( ) . data . isProtected ;
2020-01-25 09:56:08 +01:00
}
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 ] ;
}
2020-09-13 21:12:22 +02:00
async function getBranchIdFromNotePath ( notePath ) {
const { noteId , parentNoteId } = getNoteIdAndParentIdFromNotePath ( notePath ) ;
return await treeCache . getBranchId ( parentNoteId , noteId ) ;
}
2020-01-25 09:56:08 +01:00
function getNoteIdAndParentIdFromNotePath ( notePath ) {
2020-05-17 21:07:54 +02:00
if ( notePath === 'root' ) {
return {
noteId : 'root' ,
parentNoteId : 'none'
} ;
}
2020-01-25 09:56:08 +01:00
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
2020-09-13 21:12:22 +02:00
} ;
2020-01-25 09:56:08 +01:00
}
2020-02-10 20:57:56 +01:00
function getNotePath ( node ) {
2020-01-25 09:56:08 +01:00
if ( ! node ) {
2020-10-12 21:05:34 +02:00
logError ( "Node is null" ) ;
2020-01-25 09:56:08 +01:00
return "" ;
}
const path = [ ] ;
2020-02-10 20:57:56 +01:00
while ( node && ! hoistedNoteService . isRootNode ( node ) ) {
2020-01-25 09:56:08 +01:00
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 ) {
2020-08-24 23:33:27 +02:00
title = ` ${ branch . prefix } - ${ title } ` ;
2020-01-25 09:56:08 +01:00
}
}
}
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 ( ' / ' ) ;
}
2020-02-09 21:13:05 +01:00
function getHashValueFromAddress ( ) {
const str = document . location . hash ? document . location . hash . substr ( 1 ) : "" ; // strip initial #
return str . split ( "-" ) ;
}
2020-04-07 22:53:03 +02:00
function parseNotePath ( notePath ) {
let noteIds = notePath . split ( '/' ) ;
if ( noteIds [ 0 ] !== 'root' ) {
noteIds = [ 'root' ] . concat ( noteIds ) ;
}
return noteIds ;
}
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 ,
2020-08-24 23:33:27 +02:00
resolveNotePathToSegments ,
2019-06-16 11:12:07 +02:00
getSomeNotePath ,
2020-01-25 09:56:08 +01:00
getParentProtectedStatus ,
getNotePath ,
getNoteIdFromNotePath ,
getNoteIdAndParentIdFromNotePath ,
2020-09-13 21:12:22 +02:00
getBranchIdFromNotePath ,
2020-01-25 09:56:08 +01:00
getNoteTitle ,
2020-02-09 21:13:05 +01:00
getNotePathTitle ,
2020-04-07 22:53:03 +02:00
getHashValueFromAddress ,
parseNotePath
2020-05-09 14:25:27 +02:00
} ;