mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	moved tab related stuff to tab manager from app context
This commit is contained in:
		| @@ -56,7 +56,7 @@ window.glob.loadIncludedNote = async (noteId, el) => { | |||||||
| }; | }; | ||||||
| // this is required by CKEditor when uploading images | // this is required by CKEditor when uploading images | ||||||
| window.glob.noteChanged = () => { | window.glob.noteChanged = () => { | ||||||
|     const activeTabContext = appContext.getActiveTabContext(); |     const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||||
|  |  | ||||||
|     if (activeTabContext) { |     if (activeTabContext) { | ||||||
|         activeTabContext.noteChanged(); |         activeTabContext.noteChanged(); | ||||||
| @@ -65,7 +65,7 @@ window.glob.noteChanged = () => { | |||||||
| window.glob.refreshTree = treeService.reload; | window.glob.refreshTree = treeService.reload; | ||||||
|  |  | ||||||
| // required for ESLint plugin | // required for ESLint plugin | ||||||
| window.glob.getActiveTabNote = () => appContext.getActiveTabNote(); | window.glob.getActiveTabNote = () => appContext.tabManager.getActiveTabNote(); | ||||||
| window.glob.requireLibrary = libraryLoader.requireLibrary; | window.glob.requireLibrary = libraryLoader.requireLibrary; | ||||||
| window.glob.ESLINT = libraryLoader.ESLINT; | window.glob.ESLINT = libraryLoader.ESLINT; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -92,7 +92,7 @@ function AttributesModel() { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     this.loadAttributes = async function() { |     this.loadAttributes = async function() { | ||||||
|         const noteId = appContext.getActiveTabNoteId(); |         const noteId = appContext.tabManager.getActiveTabNoteId(); | ||||||
|  |  | ||||||
|         const attributes = await server.get('notes/' + noteId + '/attributes'); |         const attributes = await server.get('notes/' + noteId + '/attributes'); | ||||||
|  |  | ||||||
| @@ -138,7 +138,7 @@ function AttributesModel() { | |||||||
|  |  | ||||||
|         self.updateAttributePositions(); |         self.updateAttributePositions(); | ||||||
|  |  | ||||||
|         const noteId = appContext.getActiveTabNoteId(); |         const noteId = appContext.tabManager.getActiveTabNoteId(); | ||||||
|  |  | ||||||
|         const attributesToSave = self.ownedAttributes() |         const attributesToSave = self.ownedAttributes() | ||||||
|             .map(attribute => attribute()) |             .map(attribute => attribute()) | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ export async function showDialog() { | |||||||
|                 return false; |                 return false; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             appContext.getActiveTabContext().setNote(suggestion.path); |             appContext.tabManager.getActiveTabContext().setNote(suggestion.path); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|     noteAutocompleteService.showRecentNotes($autoComplete); |     noteAutocompleteService.showRecentNotes($autoComplete); | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ export async function showDialog() { | |||||||
| } | } | ||||||
|  |  | ||||||
| $dialog.on('shown.bs.modal', () => { | $dialog.on('shown.bs.modal', () => { | ||||||
|     const note = appContext.getActiveTabNote(); |     const note = appContext.tabManager.getActiveTabNote(); | ||||||
|  |  | ||||||
|     linkMapService = new LinkMapService(note, $linkMapContainer, getOptions()); |     linkMapService = new LinkMapService(note, $linkMapContainer, getOptions()); | ||||||
|     linkMapService.render(); |     linkMapService.render(); | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ async function convertMarkdownToHtml(text) { | |||||||
| } | } | ||||||
|  |  | ||||||
| export async function importMarkdownInline() { | export async function importMarkdownInline() { | ||||||
|     if (appContext.getActiveTabNoteType() !== 'text') { |     if (appContext.tabManager.getActiveTabNoteType() !== 'text') { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ export async function showDialog() { | |||||||
|  |  | ||||||
|     $dialog.modal(); |     $dialog.modal(); | ||||||
|  |  | ||||||
|     const activeTabContext = appContext.getActiveTabContext(); |     const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||||
|     const {note} = activeTabContext; |     const {note} = activeTabContext; | ||||||
|     const noteComplement = await activeTabContext.getNoteComplement(); |     const noteComplement = await activeTabContext.getNoteComplement(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ let note; | |||||||
| let noteRevisionId; | let noteRevisionId; | ||||||
|  |  | ||||||
| export async function showCurrentNoteRevisions() { | export async function showCurrentNoteRevisions() { | ||||||
|     await showNoteRevisionsDialog(appContext.getActiveTabNoteId()); |     await showNoteRevisionsDialog(appContext.tabManager.getActiveTabNoteId()); | ||||||
| } | } | ||||||
|  |  | ||||||
| export async function showNoteRevisionsDialog(noteId, noteRevisionId) { | export async function showNoteRevisionsDialog(noteId, noteRevisionId) { | ||||||
| @@ -42,7 +42,7 @@ async function loadNoteRevisions(noteId, noteRevId) { | |||||||
|     $list.empty(); |     $list.empty(); | ||||||
|     $content.empty(); |     $content.empty(); | ||||||
|  |  | ||||||
|     note = appContext.getActiveTabNote(); |     note = appContext.tabManager.getActiveTabNote(); | ||||||
|     revisionItems = await server.get(`notes/${noteId}/revisions`); |     revisionItems = await server.get(`notes/${noteId}/revisions`); | ||||||
|  |  | ||||||
|     for (const item of revisionItems) { |     for (const item of revisionItems) { | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ export function showDialog() { | |||||||
|  |  | ||||||
|     $dialog.modal(); |     $dialog.modal(); | ||||||
|  |  | ||||||
|     const noteText = appContext.getActiveTabNote().content; |     const noteText = appContext.tabManager.getActiveTabNote().content; | ||||||
|  |  | ||||||
|     $noteSource.text(formatHtml(noteText)); |     $noteSource.text(formatHtml(noteText)); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -55,7 +55,7 @@ export async function showDialog() { | |||||||
|  |  | ||||||
|                                 await treeCache.reloadNotes([change.noteId]); |                                 await treeCache.reloadNotes([change.noteId]); | ||||||
|  |  | ||||||
|                                 appContext.getActiveTabContext().setNote(change.noteId); |                                 appContext.tabManager.getActiveTabContext().setNote(change.noteId); | ||||||
|                             } |                             } | ||||||
|                         }); |                         }); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
| import TabContext from "./tab_context.js"; |  | ||||||
| import server from "./server.js"; | import server from "./server.js"; | ||||||
| import treeCache from "./tree_cache.js"; | import treeCache from "./tree_cache.js"; | ||||||
| import bundleService from "./bundle.js"; | import bundleService from "./bundle.js"; | ||||||
| @@ -6,28 +5,15 @@ import DialogEventComponent from "./dialog_events.js"; | |||||||
| import Entrypoints from "./entrypoints.js"; | import Entrypoints from "./entrypoints.js"; | ||||||
| import options from "./options.js"; | import options from "./options.js"; | ||||||
| import utils from "./utils.js"; | import utils from "./utils.js"; | ||||||
| import treeService from "./tree.js"; |  | ||||||
| import ZoomService from "./zoom.js"; | import ZoomService from "./zoom.js"; | ||||||
| import Layout from "../widgets/layout.js"; | import Layout from "../widgets/layout.js"; | ||||||
| import SpacedUpdate from "./spaced_update.js"; | import TabManager from "./tab_manager.js"; | ||||||
|  |  | ||||||
| class AppContext { | class AppContext { | ||||||
|     constructor(layout) { |     constructor(layout) { | ||||||
|         this.layout = layout; |         this.layout = layout; | ||||||
|         this.components = []; |         this.tabManager = new TabManager(this); | ||||||
|         /** @type {TabContext[]} */ |         this.components = [this.tabManager]; | ||||||
|         this.tabContexts = []; |  | ||||||
|         this.activeTabId = null; |  | ||||||
|  |  | ||||||
|         this.tabsUpdate = new SpacedUpdate(async () => { |  | ||||||
|             const openTabs = this.tabContexts |  | ||||||
|                 .map(tc => tc.getTabState()) |  | ||||||
|                 .filter(t => !!t); |  | ||||||
|  |  | ||||||
|             await server.put('options', { |  | ||||||
|                 openTabs: JSON.stringify(openTabs) |  | ||||||
|             }); |  | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async start() { |     async start() { | ||||||
| @@ -35,80 +21,11 @@ class AppContext { | |||||||
|  |  | ||||||
|         this.showWidgets(); |         this.showWidgets(); | ||||||
|  |  | ||||||
|         this.loadTabs(); |         this.tabManager.loadTabs(); | ||||||
|  |  | ||||||
|         bundleService.executeStartupBundles(); |         bundleService.executeStartupBundles(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async loadTabs() { |  | ||||||
|         const openTabs = options.getJson('openTabs') || []; |  | ||||||
|  |  | ||||||
|         await treeCache.initializedPromise; |  | ||||||
|  |  | ||||||
|         // if there's notePath in the URL, make sure it's open and active |  | ||||||
|         // (useful, among others, for opening clipped notes from clipper) |  | ||||||
|         if (window.location.hash) { |  | ||||||
|             const notePath = window.location.hash.substr(1); |  | ||||||
|             const noteId = treeService.getNoteIdFromNotePath(notePath); |  | ||||||
|  |  | ||||||
|             if (noteId && await treeCache.noteExists(noteId)) { |  | ||||||
|                 for (const tab of openTabs) { |  | ||||||
|                     tab.active = false; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 const foundTab = openTabs.find(tab => noteId === treeService.getNoteIdFromNotePath(tab.notePath)); |  | ||||||
|  |  | ||||||
|                 if (foundTab) { |  | ||||||
|                     foundTab.active = true; |  | ||||||
|                 } |  | ||||||
|                 else { |  | ||||||
|                     openTabs.push({ |  | ||||||
|                         notePath: notePath, |  | ||||||
|                         active: true |  | ||||||
|                     }); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         let filteredTabs = []; |  | ||||||
|  |  | ||||||
|         for (const openTab of openTabs) { |  | ||||||
|             const noteId = treeService.getNoteIdFromNotePath(openTab.notePath); |  | ||||||
|  |  | ||||||
|             if (await treeCache.noteExists(noteId)) { |  | ||||||
|                 // note doesn't exist so don't try to open tab for it |  | ||||||
|                 filteredTabs.push(openTab); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (utils.isMobile()) { |  | ||||||
|             // mobile frontend doesn't have tabs so show only the active tab |  | ||||||
|             filteredTabs = filteredTabs.filter(tab => tab.active); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (filteredTabs.length === 0) { |  | ||||||
|             filteredTabs.push({ |  | ||||||
|                 notePath: 'root', |  | ||||||
|                 active: true |  | ||||||
|             }); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (!filteredTabs.find(tab => tab.active)) { |  | ||||||
|             filteredTabs[0].active = true; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.tabsUpdate.allowUpdateWithoutChange(() => { |  | ||||||
|             for (const tab of filteredTabs) { |  | ||||||
|                 const tabContext = this.openEmptyTab(); |  | ||||||
|                 tabContext.setNote(tab.notePath); |  | ||||||
|  |  | ||||||
|                 if (tab.active) { |  | ||||||
|                     this.activateTab(tabContext.tabId); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     showWidgets() { |     showWidgets() { | ||||||
|         const rootContainer = this.layout.getRootWidget(this); |         const rootContainer = this.layout.getRootWidget(this); | ||||||
|  |  | ||||||
| @@ -145,210 +62,20 @@ class AppContext { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     tabNoteSwitchedListener({tabId}) { |  | ||||||
|         if (tabId === this.activeTabId) { |  | ||||||
|             this._setCurrentNotePathToHash(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     _setCurrentNotePathToHash() { |  | ||||||
|         const activeTabContext = this.getActiveTabContext(); |  | ||||||
|  |  | ||||||
|         if (activeTabContext && activeTabContext.notePath) { |  | ||||||
|             document.location.hash = (activeTabContext.notePath || "") + "-" + activeTabContext.tabId; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** @return {TabContext[]} */ |  | ||||||
|     getTabContexts() { |  | ||||||
|         return this.tabContexts; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** @returns {TabContext} */ |  | ||||||
|     getTabContextById(tabId) { |  | ||||||
|         return this.tabContexts.find(tc => tc.tabId === tabId); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** @returns {TabContext} */ |  | ||||||
|     getActiveTabContext() { |  | ||||||
|         return this.getTabContextById(this.activeTabId); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** @returns {string|null} */ |  | ||||||
|     getActiveTabNotePath() { |  | ||||||
|         const activeContext = this.getActiveTabContext(); |  | ||||||
|         return activeContext ? activeContext.notePath : null; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** @return {NoteShort} */ |  | ||||||
|     getActiveTabNote() { |  | ||||||
|         const activeContext = this.getActiveTabContext(); |  | ||||||
|         return activeContext ? activeContext.note : null; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** @return {string|null} */ |  | ||||||
|     getActiveTabNoteId() { |  | ||||||
|         const activeNote = this.getActiveTabNote(); |  | ||||||
|  |  | ||||||
|         return activeNote ? activeNote.noteId : null; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** @return {string|null} */ |  | ||||||
|     getActiveTabNoteType() { |  | ||||||
|         const activeNote = this.getActiveTabNote(); |  | ||||||
|  |  | ||||||
|         return activeNote ? activeNote.type : null; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     async switchToTab(tabId, notePath) { |  | ||||||
|         const tabContext = this.tabContexts.find(tc => tc.tabId === tabId) |  | ||||||
|                          || this.openEmptyTab(); |  | ||||||
|  |  | ||||||
|         this.activateTab(tabContext.tabId); |  | ||||||
|         await tabContext.setNote(notePath); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     getTab(newTab, state) { |  | ||||||
|         if (!this.getActiveTabContext() || newTab) { |  | ||||||
|             // if it's a new tab explicitly by user then it's in background |  | ||||||
|             const ctx = new TabContext(this, state); |  | ||||||
|             this.tabContexts.push(ctx); |  | ||||||
|             this.components.push(ctx); |  | ||||||
|  |  | ||||||
|             return ctx; |  | ||||||
|         } else { |  | ||||||
|             return this.getActiveTabContext(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     async openAndActivateEmptyTab() { |  | ||||||
|         const tabContext = this.openEmptyTab(); |  | ||||||
|  |  | ||||||
|         await this.activateTab(tabContext.tabId); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     openEmptyTab() { |  | ||||||
|         const tabContext = new TabContext(this); |  | ||||||
|         this.tabContexts.push(tabContext); |  | ||||||
|         this.components.push(tabContext); |  | ||||||
|         return tabContext; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     async activateOrOpenNote(noteId) { |  | ||||||
|         for (const tabContext of this.getTabContexts()) { |  | ||||||
|             if (tabContext.note && tabContext.note.noteId === noteId) { |  | ||||||
|                 await tabContext.activate(); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // if no tab with this note has been found we'll create new tab |  | ||||||
|  |  | ||||||
|         const tabContext = this.openEmptyTab(); |  | ||||||
|         await tabContext.setNote(noteId); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     hoistedNoteChangedListener({hoistedNoteId}) { |     hoistedNoteChangedListener({hoistedNoteId}) { | ||||||
|         if (hoistedNoteId === 'root') { |         if (hoistedNoteId === 'root') { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         for (const tc of this.tabContexts) { |         for (const tc of this.tabManager.getTabContexts()) { | ||||||
|             if (tc.notePath && !tc.notePath.split("/").includes(hoistedNoteId)) { |             if (tc.notePath && !tc.notePath.split("/").includes(hoistedNoteId)) { | ||||||
|                 this.removeTab(tc.tabId); |                 this.tabManager.removeTab(tc.tabId); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (this.tabContexts.length === 0) { |         if (this.tabManager.getTabContexts().length === 0) { | ||||||
|             this.openAndActivateEmptyTab(); |             this.tabManager.openAndActivateEmptyTab(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         this.saveOpenTabs(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     openTabsChangedListener() { |  | ||||||
|         this.tabsUpdate.scheduleUpdate(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     activateTab(tabId) { |  | ||||||
|         if (tabId === this.activeTabId) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         const oldActiveTabId = this.activeTabId; |  | ||||||
|  |  | ||||||
|         this.activeTabId = tabId; |  | ||||||
|  |  | ||||||
|         this.trigger('activeTabChanged', { oldActiveTabId, newActiveTabId: tabId }); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     newTabListener() { |  | ||||||
|         this.openAndActivateEmptyTab(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     async removeTab(tabId) { |  | ||||||
|         const tabContextToRemove = this.tabContexts.find(tc => tc.tabId === tabId); |  | ||||||
|  |  | ||||||
|         if (!tabContextToRemove) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         await this.trigger('beforeTabRemove', {tabId}, true); |  | ||||||
|  |  | ||||||
|         if (this.tabContexts.length === 1) { |  | ||||||
|             this.openAndActivateEmptyTab(); |  | ||||||
|         } |  | ||||||
|         else { |  | ||||||
|             this.activateNextTabListener(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.tabContexts = this.tabContexts.filter(tc => tc.tabId === tabId); |  | ||||||
|  |  | ||||||
|         this.trigger('tabRemoved', {tabId}); |  | ||||||
|  |  | ||||||
|         this.openTabsChangedListener(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     tabReorderListener({tabIdsInOrder}) { |  | ||||||
|         const order = {}; |  | ||||||
|  |  | ||||||
|         for (const i in tabIdsInOrder) { |  | ||||||
|             order[tabIdsInOrder[i]] = i; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.tabContexts.sort((a, b) => order[a.tabId] < order[b.tabId] ? -1 : 1); |  | ||||||
|  |  | ||||||
|         this.openTabsChangedListener(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     activateNextTabListener() { |  | ||||||
|         const oldIdx = this.tabContexts.findIndex(tc => tc.tabId === this.activeTabId); |  | ||||||
|         const newActiveTabId = this.tabContexts[oldIdx === this.tabContexts.length - 1 ? 0 : oldIdx + 1].tabId; |  | ||||||
|  |  | ||||||
|         this.activateTab(newActiveTabId); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     activatePreviousTabListener() { |  | ||||||
|         const oldIdx = this.tabContexts.findIndex(tc => tc.tabId === this.activeTabId); |  | ||||||
|         const newActiveTabId = this.tabContexts[oldIdx === 0 ? this.tabContexts.length - 1 : oldIdx - 1].tabId; |  | ||||||
|  |  | ||||||
|         this.activateTab(newActiveTabId); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     closeActiveTabListener() { |  | ||||||
|         this.removeTab(this.activeTabId); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     openNewTabListener() { |  | ||||||
|         this.openAndActivateEmptyTab(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     removeAllTabsListener() { |  | ||||||
|         // TODO |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     removeAllTabsExceptForThis() { |  | ||||||
|         // TODO |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async protectedSessionStartedListener() { |     async protectedSessionStartedListener() { | ||||||
|   | |||||||
| @@ -71,14 +71,14 @@ export default class Entrypoints extends Component { | |||||||
|         await treeService.expandToNote(note.noteId); |         await treeService.expandToNote(note.noteId); | ||||||
|  |  | ||||||
|         const tabContext = appContext.openEmptyTab(); |         const tabContext = appContext.openEmptyTab(); | ||||||
|         appContext.activateTab(tabContext.tabId); |         appContext.tabManager.activateTab(tabContext.tabId); | ||||||
|         await tabContext.setNote(note.noteId); |         await tabContext.setNote(note.noteId); | ||||||
|  |  | ||||||
|         appContext.trigger('focusAndSelectTitle'); |         appContext.trigger('focusAndSelectTitle'); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     toggleNoteHoistingListener() { |     toggleNoteHoistingListener() { | ||||||
|         const note = appContext.getActiveTabNote(); |         const note = appContext.tabManager.getActiveTabNote(); | ||||||
|  |  | ||||||
|         hoistedNoteService.getHoistedNoteId().then(async hoistedNoteId => { |         hoistedNoteService.getHoistedNoteId().then(async hoistedNoteId => { | ||||||
|             if (note.noteId === hoistedNoteId) { |             if (note.noteId === hoistedNoteId) { | ||||||
|   | |||||||
| @@ -48,7 +48,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte | |||||||
|      * @returns {Promise<void>} |      * @returns {Promise<void>} | ||||||
|      */ |      */ | ||||||
|     this.activateNote = async notePath => { |     this.activateNote = async notePath => { | ||||||
|         await appContext.getActiveTabContext().setNote(notePath); |         await appContext.tabManager.getActiveTabContext().setNote(notePath); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -60,7 +60,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte | |||||||
|     this.activateNewNote = async notePath => { |     this.activateNewNote = async notePath => { | ||||||
|         await ws.waitForMaxKnownSyncId(); |         await ws.waitForMaxKnownSyncId(); | ||||||
|  |  | ||||||
|         await appContext.getActiveTabContext().setNote(notePath); |         await appContext.tabManager.getActiveTabContext().setNote(notePath); | ||||||
|         appContext.trigger('focusAndSelectTitle'); |         appContext.trigger('focusAndSelectTitle'); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| @@ -285,7 +285,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte | |||||||
|      * @method |      * @method | ||||||
|      * @returns {NoteShort} active note (loaded into right pane) |      * @returns {NoteShort} active note (loaded into right pane) | ||||||
|      */ |      */ | ||||||
|     this.getActiveTabNote = appContext.getActiveTabNote; |     this.getActiveTabNote = appContext.tabManager.getActiveTabNote; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * See https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html for a documentation on the returned instance. |      * See https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html for a documentation on the returned instance. | ||||||
| @@ -299,7 +299,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte | |||||||
|      * @method |      * @method | ||||||
|      * @returns {Promise<string|null>} returns note path of active note or null if there isn't active note |      * @returns {Promise<string|null>} returns note path of active note or null if there isn't active note | ||||||
|      */ |      */ | ||||||
|     this.getActiveTabNotePath = appContext.getActiveTabNotePath; |     this.getActiveTabNotePath = appContext.tabManager.getActiveTabNotePath; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * This method checks whether user navigated away from the note from which the scripts has been started. |      * This method checks whether user navigated away from the note from which the scripts has been started. | ||||||
|   | |||||||
| @@ -65,7 +65,7 @@ ws.subscribeToMessages(async message => { | |||||||
|         toastService.showPersistent(toast); |         toastService.showPersistent(toast); | ||||||
|  |  | ||||||
|         if (message.result.importedNoteId) { |         if (message.result.importedNoteId) { | ||||||
|             await appContext.getActiveTabContext.setNote(message.result.importedNoteId); |             await appContext.tabManager.getActiveTabContext.setNote(message.result.importedNoteId); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ server.get('keyboard-shortcuts-for-notes').then(shortcutForNotes => { | |||||||
| 		utils.bindGlobalShortcut(shortcut, async () => { | 		utils.bindGlobalShortcut(shortcut, async () => { | ||||||
| 			const treeService = (await import("./tree.js")).default; | 			const treeService = (await import("./tree.js")).default; | ||||||
|  |  | ||||||
| 			appContext.getActiveTabContext().setNote(shortcutForNotes[shortcut]); | 			appContext.tabManager.getActiveTabContext().setNote(shortcutForNotes[shortcut]); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -78,11 +78,11 @@ function goToLink(e) { | |||||||
|     if (notePath) { |     if (notePath) { | ||||||
|         if ((e.which === 1 && e.ctrlKey) || e.which === 2) { |         if ((e.which === 1 && e.ctrlKey) || e.which === 2) { | ||||||
|             const tabContext = appContext.openEmptyTab(); |             const tabContext = appContext.openEmptyTab(); | ||||||
|             appContext.activateTab(tabContext.tabId); |             appContext.tabManager.activateTab(tabContext.tabId); | ||||||
|             tabContext.setNote(notePath); |             tabContext.setNote(notePath); | ||||||
|         } |         } | ||||||
|         else if (e.which === 1) { |         else if (e.which === 1) { | ||||||
|             const activeTabContext = appContext.getActiveTabContext(); |             const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||||
|             activeTabContext.setNote(notePath) |             activeTabContext.setNote(notePath) | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
| @@ -121,7 +121,7 @@ function newTabContextMenu(e) { | |||||||
|             if (cmd === 'openNoteInNewTab') { |             if (cmd === 'openNoteInNewTab') { | ||||||
|                 const tabContext = appContext.openEmptyTab(); |                 const tabContext = appContext.openEmptyTab(); | ||||||
|                 tabContext.setNote(notePath); |                 tabContext.setNote(notePath); | ||||||
|                 appContext.activateTab(tabContext.tabId); |                 appContext.tabManager.activateTab(tabContext.tabId); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
| @@ -143,7 +143,7 @@ $(document).on('mousedown', '.note-detail-text a', function (e) { | |||||||
|         if (notePath) { |         if (notePath) { | ||||||
|             const tabContext = appContext.openEmptyTab(); |             const tabContext = appContext.openEmptyTab(); | ||||||
|             tabContext.setNote(notePath); |             tabContext.setNote(notePath); | ||||||
|             appContext.activateTab(tabContext.tabId); |             appContext.tabManager.activateTab(tabContext.tabId); | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|             const address = $link.attr('href'); |             const address = $link.attr('href'); | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ const SELECTED_PATH_KEY = "data-note-path"; | |||||||
| async function autocompleteSource(term, cb) { | async function autocompleteSource(term, cb) { | ||||||
|     const result = await server.get('autocomplete' |     const result = await server.get('autocomplete' | ||||||
|         + '?query=' + encodeURIComponent(term) |         + '?query=' + encodeURIComponent(term) | ||||||
|         + '&activeNoteId=' + appContext.getActiveTabNoteId()); |         + '&activeNoteId=' + appContext.tabManager.getActiveTabNoteId()); | ||||||
|  |  | ||||||
|     if (result.length === 0) { |     if (result.length === 0) { | ||||||
|         result.push({ |         result.push({ | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ async function createNote(parentNoteId, options = {}) { | |||||||
|         options.isProtected = false; |         options.isProtected = false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (appContext.getActiveTabNoteType() !== 'text') { |     if (appContext.tabManager.getActiveTabNoteType() !== 'text') { | ||||||
|         options.saveSelection = false; |         options.saveSelection = false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -48,7 +48,7 @@ async function createNote(parentNoteId, options = {}) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (options.activate) { |     if (options.activate) { | ||||||
|         const activeTabContext = appContext.getActiveTabContext(); |         const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||||
|         activeTabContext.setNote(note.noteId); |         activeTabContext.setNote(note.noteId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -76,7 +76,7 @@ async function duplicateNote(noteId, parentNoteId) { | |||||||
|  |  | ||||||
|     await ws.waitForMaxKnownSyncId(); |     await ws.waitForMaxKnownSyncId(); | ||||||
|  |  | ||||||
|     await appContext.activateOrOpenNote(note.noteId); |     await appContext.tabManager.activateOrOpenNote(note.noteId); | ||||||
|  |  | ||||||
|     const origNote = await treeCache.getNote(noteId); |     const origNote = await treeCache.getNote(noteId); | ||||||
|     toastService.showMessage(`Note "${origNote.title}" has been duplicated`); |     toastService.showMessage(`Note "${origNote.title}" has been duplicated`); | ||||||
|   | |||||||
| @@ -69,20 +69,20 @@ async function enterProtectedSessionOnServer(password) { | |||||||
| } | } | ||||||
|  |  | ||||||
| async function protectNoteAndSendToServer() { | async function protectNoteAndSendToServer() { | ||||||
|     if (!appContext.getActiveTabNote() || appContext.getActiveTabNote().isProtected) { |     if (!appContext.tabManager.getActiveTabNote() || appContext.tabManager.getActiveTabNote().isProtected) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     await enterProtectedSession(); |     await enterProtectedSession(); | ||||||
|  |  | ||||||
|     const note = appContext.getActiveTabNote(); |     const note = appContext.tabManager.getActiveTabNote(); | ||||||
|     note.isProtected = true; |     note.isProtected = true; | ||||||
|  |  | ||||||
|     await appContext.getActiveTabContext().saveNote(); |     await appContext.tabManager.getActiveTabContext().saveNote(); | ||||||
| } | } | ||||||
|  |  | ||||||
| async function unprotectNoteAndSendToServer() { | async function unprotectNoteAndSendToServer() { | ||||||
|     const activeNote = appContext.getActiveTabNote(); |     const activeNote = appContext.tabManager.getActiveTabNote(); | ||||||
|  |  | ||||||
|     if (!activeNote.isProtected) { |     if (!activeNote.isProtected) { | ||||||
|         toastService.showAndLogError(`Note ${activeNote.noteId} is not protected`); |         toastService.showAndLogError(`Note ${activeNote.noteId} is not protected`); | ||||||
| @@ -101,7 +101,7 @@ async function unprotectNoteAndSendToServer() { | |||||||
|  |  | ||||||
|     activeNote.isProtected = false; |     activeNote.isProtected = false; | ||||||
|  |  | ||||||
|     await appContext.getActiveTabContext().saveNote(); |     await appContext.tabManager.getActiveTabContext().saveNote(); | ||||||
| } | } | ||||||
|  |  | ||||||
| async function protectSubtree(noteId, protect) { | async function protectSubtree(noteId, protect) { | ||||||
|   | |||||||
							
								
								
									
										272
									
								
								src/public/javascripts/services/tab_manager.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										272
									
								
								src/public/javascripts/services/tab_manager.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,272 @@ | |||||||
|  | import Component from "../widgets/component.js"; | ||||||
|  | import SpacedUpdate from "./spaced_update.js"; | ||||||
|  | import server from "./server.js"; | ||||||
|  | import options from "./options.js"; | ||||||
|  | import treeCache from "./tree_cache.js"; | ||||||
|  | import treeService from "./tree.js"; | ||||||
|  | import utils from "./utils.js"; | ||||||
|  | import TabContext from "./tab_context.js"; | ||||||
|  |  | ||||||
|  | export default class TabManager extends Component { | ||||||
|  |     constructor(appContext) { | ||||||
|  |         super(appContext); | ||||||
|  |  | ||||||
|  |         /** @type {TabContext[]} */ | ||||||
|  |         this.tabContexts = []; | ||||||
|  |         this.activeTabId = null; | ||||||
|  |  | ||||||
|  |         this.tabsUpdate = new SpacedUpdate(async () => { | ||||||
|  |             const openTabs = this.tabContexts | ||||||
|  |                 .map(tc => tc.getTabState()) | ||||||
|  |                 .filter(t => !!t); | ||||||
|  |  | ||||||
|  |             await server.put('options', { | ||||||
|  |                 openTabs: JSON.stringify(openTabs) | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async loadTabs() { | ||||||
|  |         const openTabs = options.getJson('openTabs') || []; | ||||||
|  |  | ||||||
|  |         await treeCache.initializedPromise; | ||||||
|  |  | ||||||
|  |         // if there's notePath in the URL, make sure it's open and active | ||||||
|  |         // (useful, among others, for opening clipped notes from clipper) | ||||||
|  |         if (window.location.hash) { | ||||||
|  |             const notePath = window.location.hash.substr(1); | ||||||
|  |             const noteId = treeService.getNoteIdFromNotePath(notePath); | ||||||
|  |  | ||||||
|  |             if (noteId && await treeCache.noteExists(noteId)) { | ||||||
|  |                 for (const tab of openTabs) { | ||||||
|  |                     tab.active = false; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 const foundTab = openTabs.find(tab => noteId === treeService.getNoteIdFromNotePath(tab.notePath)); | ||||||
|  |  | ||||||
|  |                 if (foundTab) { | ||||||
|  |                     foundTab.active = true; | ||||||
|  |                 } | ||||||
|  |                 else { | ||||||
|  |                     openTabs.push({ | ||||||
|  |                         notePath: notePath, | ||||||
|  |                         active: true | ||||||
|  |                     }); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         let filteredTabs = []; | ||||||
|  |  | ||||||
|  |         for (const openTab of openTabs) { | ||||||
|  |             const noteId = treeService.getNoteIdFromNotePath(openTab.notePath); | ||||||
|  |  | ||||||
|  |             if (await treeCache.noteExists(noteId)) { | ||||||
|  |                 // note doesn't exist so don't try to open tab for it | ||||||
|  |                 filteredTabs.push(openTab); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (utils.isMobile()) { | ||||||
|  |             // mobile frontend doesn't have tabs so show only the active tab | ||||||
|  |             filteredTabs = filteredTabs.filter(tab => tab.active); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (filteredTabs.length === 0) { | ||||||
|  |             filteredTabs.push({ | ||||||
|  |                 notePath: 'root', | ||||||
|  |                 active: true | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (!filteredTabs.find(tab => tab.active)) { | ||||||
|  |             filteredTabs[0].active = true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this.tabsUpdate.allowUpdateWithoutChange(() => { | ||||||
|  |             for (const tab of filteredTabs) { | ||||||
|  |                 const tabContext = this.openEmptyTab(); | ||||||
|  |                 tabContext.setNote(tab.notePath); | ||||||
|  |  | ||||||
|  |                 if (tab.active) { | ||||||
|  |                     this.activateTab(tabContext.tabId); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     tabNoteSwitchedListener({tabId}) { | ||||||
|  |         if (tabId === this.activeTabId) { | ||||||
|  |             this._setCurrentNotePathToHash(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     _setCurrentNotePathToHash() { | ||||||
|  |         const activeTabContext = this.getActiveTabContext(); | ||||||
|  |  | ||||||
|  |         if (activeTabContext && activeTabContext.notePath) { | ||||||
|  |             document.location.hash = (activeTabContext.notePath || "") + "-" + activeTabContext.tabId; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** @return {TabContext[]} */ | ||||||
|  |     getTabContexts() { | ||||||
|  |         return this.tabContexts; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** @returns {TabContext} */ | ||||||
|  |     getTabContextById(tabId) { | ||||||
|  |         return this.tabContexts.find(tc => tc.tabId === tabId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** @returns {TabContext} */ | ||||||
|  |     getActiveTabContext() { | ||||||
|  |         return this.getTabContextById(this.activeTabId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** @returns {string|null} */ | ||||||
|  |     getActiveTabNotePath() { | ||||||
|  |         const activeContext = this.getActiveTabContext(); | ||||||
|  |         return activeContext ? activeContext.notePath : null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** @return {NoteShort} */ | ||||||
|  |     getActiveTabNote() { | ||||||
|  |         const activeContext = this.getActiveTabContext(); | ||||||
|  |         return activeContext ? activeContext.note : null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** @return {string|null} */ | ||||||
|  |     getActiveTabNoteId() { | ||||||
|  |         const activeNote = this.getActiveTabNote(); | ||||||
|  |  | ||||||
|  |         return activeNote ? activeNote.noteId : null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** @return {string|null} */ | ||||||
|  |     getActiveTabNoteType() { | ||||||
|  |         const activeNote = this.getActiveTabNote(); | ||||||
|  |  | ||||||
|  |         return activeNote ? activeNote.type : null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async switchToTab(tabId, notePath) { | ||||||
|  |         const tabContext = this.tabContexts.find(tc => tc.tabId === tabId) | ||||||
|  |             || this.openEmptyTab(); | ||||||
|  |  | ||||||
|  |         this.activateTab(tabContext.tabId); | ||||||
|  |         await tabContext.setNote(notePath); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async openAndActivateEmptyTab() { | ||||||
|  |         const tabContext = this.openEmptyTab(); | ||||||
|  |  | ||||||
|  |         await this.activateTab(tabContext.tabId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     openEmptyTab() { | ||||||
|  |         const tabContext = new TabContext(this.appContext); | ||||||
|  |         this.tabContexts.push(tabContext); | ||||||
|  |         this.children.push(tabContext); | ||||||
|  |         return tabContext; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async activateOrOpenNote(noteId) { | ||||||
|  |         for (const tabContext of this.getTabContexts()) { | ||||||
|  |             if (tabContext.note && tabContext.note.noteId === noteId) { | ||||||
|  |                 await tabContext.activate(); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // if no tab with this note has been found we'll create new tab | ||||||
|  |  | ||||||
|  |         const tabContext = this.openEmptyTab(); | ||||||
|  |         await tabContext.setNote(noteId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     openTabsChangedListener() { | ||||||
|  |         this.tabsUpdate.scheduleUpdate(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     activateTab(tabId) { | ||||||
|  |         if (tabId === this.activeTabId) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         const oldActiveTabId = this.activeTabId; | ||||||
|  |  | ||||||
|  |         this.activeTabId = tabId; | ||||||
|  |  | ||||||
|  |         this.trigger('activeTabChanged', { oldActiveTabId, newActiveTabId: tabId }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     newTabListener() { | ||||||
|  |         this.openAndActivateEmptyTab(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async removeTab(tabId) { | ||||||
|  |         const tabContextToRemove = this.tabContexts.find(tc => tc.tabId === tabId); | ||||||
|  |  | ||||||
|  |         if (!tabContextToRemove) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         await this.trigger('beforeTabRemove', {tabId}, true); | ||||||
|  |  | ||||||
|  |         if (this.tabContexts.length === 1) { | ||||||
|  |             this.openAndActivateEmptyTab(); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             this.activateNextTabListener(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this.children = this.tabContexts = this.tabContexts.filter(tc => tc.tabId === tabId); | ||||||
|  |  | ||||||
|  |         this.trigger('tabRemoved', {tabId}); | ||||||
|  |  | ||||||
|  |         this.openTabsChangedListener(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     tabReorderListener({tabIdsInOrder}) { | ||||||
|  |         const order = {}; | ||||||
|  |  | ||||||
|  |         for (const i in tabIdsInOrder) { | ||||||
|  |             order[tabIdsInOrder[i]] = i; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this.tabContexts.sort((a, b) => order[a.tabId] < order[b.tabId] ? -1 : 1); | ||||||
|  |  | ||||||
|  |         this.openTabsChangedListener(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     activateNextTabListener() { | ||||||
|  |         const oldIdx = this.tabContexts.findIndex(tc => tc.tabId === this.activeTabId); | ||||||
|  |         const newActiveTabId = this.tabContexts[oldIdx === this.tabContexts.length - 1 ? 0 : oldIdx + 1].tabId; | ||||||
|  |  | ||||||
|  |         this.activateTab(newActiveTabId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     activatePreviousTabListener() { | ||||||
|  |         const oldIdx = this.tabContexts.findIndex(tc => tc.tabId === this.activeTabId); | ||||||
|  |         const newActiveTabId = this.tabContexts[oldIdx === 0 ? this.tabContexts.length - 1 : oldIdx - 1].tabId; | ||||||
|  |  | ||||||
|  |         this.activateTab(newActiveTabId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     closeActiveTabListener() { | ||||||
|  |         this.removeTab(this.activeTabId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     openNewTabListener() { | ||||||
|  |         this.openAndActivateEmptyTab(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     removeAllTabsListener() { | ||||||
|  |         // TODO | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     removeAllTabsExceptForThis() { | ||||||
|  |         // TODO | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -139,7 +139,7 @@ async function sortAlphabetically(noteId) { | |||||||
|  |  | ||||||
| ws.subscribeToMessages(message => { | ws.subscribeToMessages(message => { | ||||||
|    if (message.type === 'open-note') { |    if (message.type === 'open-note') { | ||||||
|        appContext.activateOrOpenNote(message.noteId); |        appContext.tabManager.activateOrOpenNote(message.noteId); | ||||||
|  |  | ||||||
|        if (utils.isElectron()) { |        if (utils.isElectron()) { | ||||||
|            const currentWindow = require("electron").remote.getCurrentWindow(); |            const currentWindow = require("electron").remote.getCurrentWindow(); | ||||||
|   | |||||||
| @@ -103,7 +103,7 @@ class TreeContextMenu { | |||||||
|  |  | ||||||
|         if (cmd === 'openInTab') { |         if (cmd === 'openInTab') { | ||||||
|             const tabContext = appContext.openEmptyTab(); |             const tabContext = appContext.openEmptyTab(); | ||||||
|             appContext.activateTab(tabContext.tabId); |             appContext.tabManager.activateTab(tabContext.tabId); | ||||||
|             tabContext.setNote(notePath); |             tabContext.setNote(notePath); | ||||||
|         } |         } | ||||||
|         else if (cmd.startsWith("insertNoteAfter")) { |         else if (cmd.startsWith("insertNoteAfter")) { | ||||||
|   | |||||||
| @@ -58,7 +58,7 @@ export default class CalendarWidget extends CollapsibleWidget { | |||||||
|             const note = await dateNoteService.getDateNote(date); |             const note = await dateNoteService.getDateNote(date); | ||||||
|  |  | ||||||
|             if (note) { |             if (note) { | ||||||
|                 appContext.getActiveTabContext().setNote(note.noteId); |                 appContext.tabManager.getActiveTabContext().setNote(note.noteId); | ||||||
|             } |             } | ||||||
|             else { |             else { | ||||||
|                 alert("Cannot find day note"); |                 alert("Cannot find day note"); | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ export default class NoteDetailWidget extends TabAwareWidget { | |||||||
|         this.$widget.on("dragleave", e => e.preventDefault()); |         this.$widget.on("dragleave", e => e.preventDefault()); | ||||||
|  |  | ||||||
|         this.$widget.on("drop", async e => { |         this.$widget.on("drop", async e => { | ||||||
|             const activeNote = this.appContext.getActiveTabNote(); |             const activeNote = this.appContext.tabManager.getActiveTabNote(); | ||||||
|  |  | ||||||
|             if (!activeNote) { |             if (!activeNote) { | ||||||
|                 return; |                 return; | ||||||
|   | |||||||
| @@ -89,7 +89,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|                     else if (event.ctrlKey) { |                     else if (event.ctrlKey) { | ||||||
|                         const tabContext = appContext.openEmptyTab(); |                         const tabContext = appContext.openEmptyTab(); | ||||||
|                         treeService.getNotePath(node).then(notePath => tabContext.setNote(notePath)); |                         treeService.getNotePath(node).then(notePath => tabContext.setNote(notePath)); | ||||||
|                         appContext.activateTab(tabContext.tabId); |                         appContext.tabManager.activateTab(tabContext.tabId); | ||||||
|                     } |                     } | ||||||
|                     else { |                     else { | ||||||
|                         node.setActive(); |                         node.setActive(); | ||||||
| @@ -106,7 +106,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|  |  | ||||||
|                 const notePath = await treeService.getNotePath(data.node); |                 const notePath = await treeService.getNotePath(data.node); | ||||||
|  |  | ||||||
|                 const activeTabContext = this.appContext.getActiveTabContext(); |                 const activeTabContext = this.appContext.tabManager.getActiveTabContext(); | ||||||
|                 await activeTabContext.setNote(notePath); |                 await activeTabContext.setNote(notePath); | ||||||
|             }, |             }, | ||||||
|             expand: (event, data) => this.setExpandedToServer(data.node.data.branchId, true), |             expand: (event, data) => this.setExpandedToServer(data.node.data.branchId, true), | ||||||
| @@ -286,7 +286,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async scrollToActiveNoteListener() { |     async scrollToActiveNoteListener() { | ||||||
|         const activeContext = appContext.getActiveTabContext(); |         const activeContext = appContext.tabManager.getActiveTabContext(); | ||||||
|  |  | ||||||
|         if (activeContext && activeContext.notePath) { |         if (activeContext && activeContext.notePath) { | ||||||
|             this.tree.setFocus(); |             this.tree.setFocus(); | ||||||
| @@ -466,7 +466,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|  |  | ||||||
|                         const notePath = await treeService.getNotePath(newActive); |                         const notePath = await treeService.getNotePath(newActive); | ||||||
|  |  | ||||||
|                         appContext.getActiveTabContext().setNote(notePath); |                         appContext.tabManager.getActiveTabContext().setNote(notePath); | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                     node.remove(); |                     node.remove(); | ||||||
| @@ -526,7 +526,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         const activateNotePath = appContext.getActiveTabNotePath(); |         const activateNotePath = appContext.tabManager.getActiveTabNotePath(); | ||||||
|  |  | ||||||
|         if (activateNotePath) { |         if (activateNotePath) { | ||||||
|             const node = await this.getNodeFromPath(activateNotePath); |             const node = await this.getNodeFromPath(activateNotePath); | ||||||
|   | |||||||
| @@ -168,7 +168,7 @@ export default class SearchBoxWidget extends BasicWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     searchInSubtreeListener({noteId}) { |     searchInSubtreeListener({noteId}) { | ||||||
|         noteId = noteId || appContext.getActiveTabNoteId(); |         noteId = noteId || appContext.tabManager.getActiveTabNoteId(); | ||||||
|  |  | ||||||
|         this.toggle(true); |         this.toggle(true); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -68,7 +68,7 @@ export default class TabAwareWidget extends BasicWidget { | |||||||
|     refreshWithNote(note, notePath) {} |     refreshWithNote(note, notePath) {} | ||||||
|  |  | ||||||
|     activeTabChangedListener() { |     activeTabChangedListener() { | ||||||
|         this.tabContext = this.appContext.getActiveTabContext(); |         this.tabContext = this.appContext.tabManager.getActiveTabContext(); | ||||||
|  |  | ||||||
|         this.activeTabChanged(); |         this.activeTabChanged(); | ||||||
|     } |     } | ||||||
| @@ -79,7 +79,7 @@ export default class TabAwareWidget extends BasicWidget { | |||||||
|  |  | ||||||
|     lazyLoadedListener() { |     lazyLoadedListener() { | ||||||
|         if (!this.tabContext) { // has not been loaded yet |         if (!this.tabContext) { // has not been loaded yet | ||||||
|             this.tabContext = this.appContext.getActiveTabContext(); |             this.tabContext = this.appContext.tabManager.getActiveTabContext(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         this.refresh(); |         this.refresh(); | ||||||
|   | |||||||
| @@ -490,7 +490,7 @@ export default class TabRowWidget extends BasicWidget { | |||||||
|             this.draggabillies.push(draggabilly); |             this.draggabillies.push(draggabilly); | ||||||
|  |  | ||||||
|             draggabilly.on('pointerDown', _ => { |             draggabilly.on('pointerDown', _ => { | ||||||
|                 this.appContext.activateTab(tabEl.getAttribute('data-tab-id')); |                 this.appContext.tabManager.activateTab(tabEl.getAttribute('data-tab-id')); | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
|             draggabilly.on('dragStart', _ => { |             draggabilly.on('dragStart', _ => { | ||||||
| @@ -585,7 +585,7 @@ export default class TabRowWidget extends BasicWidget { | |||||||
|     tabNoteSwitchedListener({tabId}) { |     tabNoteSwitchedListener({tabId}) { | ||||||
|         const $tab = this.getTabById(tabId); |         const $tab = this.getTabById(tabId); | ||||||
|  |  | ||||||
|         const {note} = this.appContext.getTabContextById(tabId); |         const {note} = this.appContext.tabManager.getTabContextById(tabId); | ||||||
|  |  | ||||||
|         this.updateTab($tab, note); |         this.updateTab($tab, note); | ||||||
|     } |     } | ||||||
| @@ -609,7 +609,7 @@ export default class TabRowWidget extends BasicWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async entitiesReloadedListener({loadResults}) { |     async entitiesReloadedListener({loadResults}) { | ||||||
|         for (const tabContext of this.appContext.getTabContexts()) { |         for (const tabContext of this.appContext.tabManager.getTabContexts()) { | ||||||
|             if (loadResults.isNoteReloaded(tabContext.noteId)) { |             if (loadResults.isNoteReloaded(tabContext.noteId)) { | ||||||
|                 const $tab = this.getTabById(tabContext.tabId); |                 const $tab = this.getTabById(tabContext.tabId); | ||||||
|  |  | ||||||
| @@ -619,7 +619,7 @@ export default class TabRowWidget extends BasicWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     treeCacheReloadedListener() { |     treeCacheReloadedListener() { | ||||||
|         for (const tabContext of this.appContext.getTabContexts()) { |         for (const tabContext of this.appContext.tabManager.getTabContexts()) { | ||||||
|             const $tab = this.getTabById(tabContext.tabId); |             const $tab = this.getTabById(tabContext.tabId); | ||||||
|  |  | ||||||
|             this.updateTab($tab, tabContext.note); |             this.updateTab($tab, tabContext.note); | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ export default class EmptyTypeWidget extends TypeWidget { | |||||||
|                     return false; |                     return false; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 appContext.getActiveTabContext().setNote(suggestion.path); |                 appContext.tabManager.getActiveTabContext().setNote(suggestion.path); | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
|         noteAutocompleteService.showRecentNotes(this.$autoComplete); |         noteAutocompleteService.showRecentNotes(this.$autoComplete); | ||||||
|   | |||||||
| @@ -91,7 +91,7 @@ export default class TextTypeWidget extends TypeWidget { | |||||||
|             if (match) { |             if (match) { | ||||||
|                 const noteId = match[1]; |                 const noteId = match[1]; | ||||||
|  |  | ||||||
|                 appContext.getActiveTabContext().setNote(noteId); |                 appContext.tabManager.getActiveTabContext().setNote(noteId); | ||||||
|             } |             } | ||||||
|             else { |             else { | ||||||
|                 window.open(src, '_blank'); |                 window.open(src, '_blank'); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user