| 
									
										
										
										
											2020-01-15 21:36:01 +01:00
										 |  |  | import treeCache from "./tree_cache.js"; | 
					
						
							| 
									
										
										
										
											2020-01-19 21:12:53 +01:00
										 |  |  | import bundleService from "./bundle.js"; | 
					
						
							| 
									
										
										
										
											2020-02-15 10:41:21 +01:00
										 |  |  | import DialogCommandExecutor from "./dialog_command_executor.js"; | 
					
						
							| 
									
										
										
										
											2020-01-21 22:54:16 +01:00
										 |  |  | import Entrypoints from "./entrypoints.js"; | 
					
						
							| 
									
										
										
										
											2020-02-05 22:08:45 +01:00
										 |  |  | import options from "./options.js"; | 
					
						
							| 
									
										
										
										
											2020-02-02 22:32:44 +01:00
										 |  |  | import utils from "./utils.js"; | 
					
						
							| 
									
										
										
										
											2020-05-11 20:08:55 +02:00
										 |  |  | import zoomService from "./zoom.js"; | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  | import TabManager from "./tab_manager.js"; | 
					
						
							| 
									
										
										
										
											2020-02-09 21:13:05 +01:00
										 |  |  | import treeService from "./tree.js"; | 
					
						
							| 
									
										
										
										
											2020-02-16 19:21:17 +01:00
										 |  |  | import Component from "../widgets/component.js"; | 
					
						
							| 
									
										
										
										
											2020-02-16 20:09:59 +01:00
										 |  |  | import keyboardActionsService from "./keyboard_actions.js"; | 
					
						
							| 
									
										
										
										
											2020-04-26 09:40:02 +02:00
										 |  |  | import MobileScreenSwitcherExecutor from "../widgets/mobile_widgets/mobile_screen_switcher.js"; | 
					
						
							| 
									
										
										
										
											2020-03-17 12:28:02 +01:00
										 |  |  | import MainTreeExecutors from "./main_tree_executors.js"; | 
					
						
							| 
									
										
										
										
											2020-05-13 23:06:13 +02:00
										 |  |  | import protectedSessionHolder from "./protected_session_holder.js"; | 
					
						
							| 
									
										
										
										
											2021-02-27 23:39:02 +01:00
										 |  |  | import toast from "./toast.js"; | 
					
						
							| 
									
										
										
										
											2020-01-11 21:19:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 19:21:17 +01:00
										 |  |  | class AppContext extends Component { | 
					
						
							| 
									
										
										
										
											2020-04-25 23:52:13 +02:00
										 |  |  |     constructor(isMainWindow) { | 
					
						
							|  |  |  |         super(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.isMainWindow = isMainWindow; | 
					
						
							| 
									
										
										
										
											2020-05-20 08:54:37 +02:00
										 |  |  |         this.executors = []; | 
					
						
							| 
									
										
										
										
											2021-02-27 23:39:02 +01:00
										 |  |  |         this.beforeUnloadListeners = []; | 
					
						
							| 
									
										
										
										
											2020-04-25 23:52:13 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-01 10:41:23 +01:00
										 |  |  |     setLayout(layout) { | 
					
						
							| 
									
										
										
										
											2020-02-06 21:47:31 +01:00
										 |  |  |         this.layout = layout; | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 23:52:13 +02:00
										 |  |  |     async start() { | 
					
						
							| 
									
										
										
										
											2020-03-16 21:16:09 +01:00
										 |  |  |         await Promise.all([treeCache.initializedPromise, options.initializedPromise]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-29 23:10:45 +02:00
										 |  |  |         this.showWidgets(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 23:52:13 +02:00
										 |  |  |         this.tabManager.loadTabs(); | 
					
						
							| 
									
										
										
										
											2020-02-02 22:32:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-18 15:09:08 -05:00
										 |  |  |         setTimeout(() => bundleService.executeStartupBundles(), 2000); | 
					
						
							| 
									
										
										
										
											2020-02-02 22:04:28 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 22:04:28 +01:00
										 |  |  |     showWidgets() { | 
					
						
							| 
									
										
										
										
											2020-02-16 19:21:17 +01:00
										 |  |  |         const rootWidget = this.layout.getRootWidget(this); | 
					
						
							|  |  |  |         const $renderedWidget = rootWidget.render(); | 
					
						
							| 
									
										
										
										
											2020-01-14 21:23:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 20:09:59 +01:00
										 |  |  |         keyboardActionsService.updateDisplayedShortcuts($renderedWidget); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-09 22:31:52 +01:00
										 |  |  |         $("body").append($renderedWidget); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-05 23:58:52 +02:00
										 |  |  |         $renderedWidget.on('click', "[data-trigger-command]", function() { | 
					
						
							|  |  |  |             const commandName = $(this).attr('data-trigger-command'); | 
					
						
							|  |  |  |             const $component = $(this).closest(".component"); | 
					
						
							|  |  |  |             const component = $component.prop("component"); | 
					
						
							| 
									
										
										
										
											2020-02-09 22:31:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-06 21:24:51 +02:00
										 |  |  |             component.triggerCommand(commandName, {$el: $(this)}); | 
					
						
							| 
									
										
										
										
											2020-02-09 22:31:52 +01:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2020-02-05 22:08:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-27 10:03:14 +01:00
										 |  |  |         this.tabManager = new TabManager(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-15 10:41:21 +01:00
										 |  |  |         this.executors = [ | 
					
						
							| 
									
										
										
										
											2020-02-16 19:54:11 +01:00
										 |  |  |             this.tabManager, | 
					
						
							| 
									
										
										
										
											2020-02-27 10:03:14 +01:00
										 |  |  |             new DialogCommandExecutor(), | 
					
						
							| 
									
										
										
										
											2020-03-17 12:28:02 +01:00
										 |  |  |             new Entrypoints(), | 
					
						
							|  |  |  |             new MainTreeExecutors() | 
					
						
							| 
									
										
										
										
											2020-01-13 21:48:44 +01:00
										 |  |  |         ]; | 
					
						
							| 
									
										
										
										
											2020-02-05 22:08:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-01 15:19:16 +01:00
										 |  |  |         if (utils.isMobile()) { | 
					
						
							|  |  |  |             this.executors.push(new MobileScreenSwitcherExecutor()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-27 10:03:14 +01:00
										 |  |  |         this.child(rootWidget); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const executor of this.executors) { | 
					
						
							|  |  |  |             this.child(executor); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-02-17 22:38:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 22:08:45 +01:00
										 |  |  |         if (utils.isElectron()) { | 
					
						
							| 
									
										
										
										
											2020-05-11 20:08:55 +02:00
										 |  |  |             this.child(zoomService); | 
					
						
							| 
									
										
										
										
											2020-02-05 22:08:45 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-02-06 21:16:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 19:21:17 +01:00
										 |  |  |         this.triggerEvent('initialRenderComplete'); | 
					
						
							| 
									
										
										
										
											2020-01-11 21:19:56 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-29 19:43:19 +01:00
										 |  |  |     /** @return {Promise} */ | 
					
						
							|  |  |  |     triggerEvent(name, data) { | 
					
						
							|  |  |  |         return this.handleEvent(name, data); | 
					
						
							| 
									
										
										
										
											2020-02-01 22:29:32 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-02-15 10:41:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-29 19:43:19 +01:00
										 |  |  |     /** @return {Promise} */ | 
					
						
							| 
									
										
										
										
											2021-02-06 19:58:12 +01:00
										 |  |  |     triggerCommand(name, data = {}) { | 
					
						
							| 
									
										
										
										
											2020-02-15 10:41:21 +01:00
										 |  |  |         for (const executor of this.executors) { | 
					
						
							| 
									
										
										
										
											2020-02-29 19:43:19 +01:00
										 |  |  |             const fun = executor[name + "Command"]; | 
					
						
							| 
									
										
										
										
											2020-02-15 10:41:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-29 19:43:19 +01:00
										 |  |  |             if (fun) { | 
					
						
							|  |  |  |                 return executor.callMethod(fun, data); | 
					
						
							| 
									
										
										
										
											2020-02-15 10:41:21 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-05 23:58:52 +02:00
										 |  |  |         // this might hint at error but sometimes this is used by components which are at different places
 | 
					
						
							|  |  |  |         // in the component tree to communicate with each other
 | 
					
						
							| 
									
										
										
										
											2020-02-17 22:38:46 +01:00
										 |  |  |         console.debug(`Unhandled command ${name}, converting to event.`); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-29 19:43:19 +01:00
										 |  |  |         return this.triggerEvent(name, data); | 
					
						
							| 
									
										
										
										
											2020-02-15 10:41:21 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 19:21:17 +01:00
										 |  |  |     getComponentByEl(el) { | 
					
						
							|  |  |  |         return $(el).closest(".component").prop('component'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-02-27 23:39:02 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     addBeforeUnloadListener(obj) { | 
					
						
							|  |  |  |         if (typeof WeakRef !== "function") { | 
					
						
							|  |  |  |             // older browsers don't support WeakRef
 | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.beforeUnloadListeners.push(new WeakRef(obj)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 23:52:13 +02:00
										 |  |  | const appContext = new AppContext(window.glob.isMainWindow); | 
					
						
							| 
									
										
										
										
											2020-01-12 12:48:17 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 10:41:43 +01:00
										 |  |  | // we should save all outstanding changes before the page/app is closed
 | 
					
						
							|  |  |  | $(window).on('beforeunload', () => { | 
					
						
							| 
									
										
										
										
											2020-05-13 23:06:13 +02:00
										 |  |  |     protectedSessionHolder.resetSessionCookie(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-27 23:39:02 +01:00
										 |  |  |     let allSaved = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     appContext.beforeUnloadListeners = appContext.beforeUnloadListeners.filter(wr => !!wr.deref()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (const weakRef of appContext.beforeUnloadListeners) { | 
					
						
							|  |  |  |         const component = weakRef.deref(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!component) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!component.beforeUnloadEvent()) { | 
					
						
							|  |  |  |             console.log(`Component ${component.componentId} is not finished saving its state.`); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             toast.showMessage("Please wait for a couple of seconds for the save to finish, then you can try again.", 10000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             allSaved = false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!allSaved) { | 
					
						
							|  |  |  |         return "some string"; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-02-02 10:41:43 +01:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-03 20:07:34 +01:00
										 |  |  | function isNotePathInAddress() { | 
					
						
							| 
									
										
										
										
											2020-02-29 13:03:05 +01:00
										 |  |  |     const [notePath, tabId] = treeService.getHashValueFromAddress(); | 
					
						
							| 
									
										
										
										
											2020-02-03 20:07:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return notePath.startsWith("root") | 
					
						
							|  |  |  |         // empty string is for empty/uninitialized tab
 | 
					
						
							|  |  |  |         || (notePath === '' && !!tabId); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $(window).on('hashchange', function() { | 
					
						
							|  |  |  |     if (isNotePathInAddress()) { | 
					
						
							| 
									
										
										
										
											2020-02-09 21:13:05 +01:00
										 |  |  |         const [notePath, tabId] = treeService.getHashValueFromAddress(); | 
					
						
							| 
									
										
										
										
											2020-02-03 20:07:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-21 21:04:34 +01:00
										 |  |  |         if (!notePath) { | 
					
						
							|  |  |  |             console.log(`Invalid hash value "${document.location.hash}", ignoring.`); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-08 20:53:07 +01:00
										 |  |  |         appContext.tabManager.switchToTab(tabId, notePath); | 
					
						
							| 
									
										
										
										
											2020-02-03 20:07:34 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-11 20:08:55 +02:00
										 |  |  | export default appContext; |