mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	moving components to its own directory
This commit is contained in:
		
							
								
								
									
										172
									
								
								src/public/app/components/app_context.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								src/public/app/components/app_context.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,172 @@ | ||||
| import froca from "../services/froca.js"; | ||||
| import bundleService from "../services/bundle.js"; | ||||
| import RootCommandExecutor from "./root_command_executor.js"; | ||||
| import Entrypoints from "./entrypoints.js"; | ||||
| import options from "../services/options.js"; | ||||
| import utils from "../services/utils.js"; | ||||
| import zoomComponent from "./zoom.js"; | ||||
| import TabManager from "./tab_manager.js"; | ||||
| import treeService from "../services/tree.js"; | ||||
| import Component from "./component.js"; | ||||
| import keyboardActionsService from "../services/keyboard_actions.js"; | ||||
| import MobileScreenSwitcherExecutor from "./mobile_screen_switcher.js"; | ||||
| import MainTreeExecutors from "./main_tree_executors.js"; | ||||
| import toast from "../services/toast.js"; | ||||
|  | ||||
| class AppContext extends Component { | ||||
|     constructor(isMainWindow) { | ||||
|         super(); | ||||
|  | ||||
|         this.isMainWindow = isMainWindow; | ||||
|         // non-widget/layout components needed for the application | ||||
|         this.components = []; | ||||
|         this.beforeUnloadListeners = []; | ||||
|     } | ||||
|  | ||||
|     setLayout(layout) { | ||||
|         this.layout = layout; | ||||
|     } | ||||
|  | ||||
|     async start() { | ||||
|         this.initComponents(); | ||||
|  | ||||
|         this.renderWidgets(); | ||||
|  | ||||
|         await Promise.all([froca.initializedPromise, options.initializedPromise]); | ||||
|  | ||||
|         this.tabManager.loadTabs(); | ||||
|  | ||||
|         setTimeout(() => bundleService.executeStartupBundles(), 2000); | ||||
|     } | ||||
|  | ||||
|     initComponents() { | ||||
|         this.tabManager = new TabManager(); | ||||
|  | ||||
|         this.components = [ | ||||
|             this.tabManager, | ||||
|             new RootCommandExecutor(), | ||||
|             new Entrypoints(), | ||||
|             new MainTreeExecutors() | ||||
|         ]; | ||||
|  | ||||
|         if (utils.isMobile()) { | ||||
|             this.components.push(new MobileScreenSwitcherExecutor()); | ||||
|         } | ||||
|  | ||||
|         for (const component of this.components) { | ||||
|             this.child(component); | ||||
|         } | ||||
|  | ||||
|         if (utils.isElectron()) { | ||||
|             this.child(zoomComponent); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     renderWidgets() { | ||||
|         const rootWidget = this.layout.getRootWidget(this); | ||||
|         const $renderedWidget = rootWidget.render(); | ||||
|  | ||||
|         keyboardActionsService.updateDisplayedShortcuts($renderedWidget); | ||||
|  | ||||
|         $("body").append($renderedWidget); | ||||
|  | ||||
|         $renderedWidget.on('click', "[data-trigger-command]", function() { | ||||
|             const commandName = $(this).attr('data-trigger-command'); | ||||
|             const $component = $(this).closest(".component"); | ||||
|             const component = $component.prop("component"); | ||||
|  | ||||
|             component.triggerCommand(commandName, {$el: $(this)}); | ||||
|         }); | ||||
|  | ||||
|         this.child(rootWidget); | ||||
|  | ||||
|         this.triggerEvent('initialRenderComplete'); | ||||
|     } | ||||
|  | ||||
|     /** @returns {Promise} */ | ||||
|     triggerEvent(name, data) { | ||||
|         return this.handleEvent(name, data); | ||||
|     } | ||||
|  | ||||
|     /** @returns {Promise} */ | ||||
|     triggerCommand(name, data = {}) { | ||||
|         for (const executor of this.components) { | ||||
|             const fun = executor[name + "Command"]; | ||||
|  | ||||
|             if (fun) { | ||||
|                 return executor.callMethod(fun, data); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // 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 | ||||
|         console.debug(`Unhandled command ${name}, converting to event.`); | ||||
|  | ||||
|         return this.triggerEvent(name, data); | ||||
|     } | ||||
|  | ||||
|     getComponentByEl(el) { | ||||
|         return $(el).closest(".component").prop('component'); | ||||
|     } | ||||
|  | ||||
|     addBeforeUnloadListener(obj) { | ||||
|         if (typeof WeakRef !== "function") { | ||||
|             // older browsers don't support WeakRef | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this.beforeUnloadListeners.push(new WeakRef(obj)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| const appContext = new AppContext(window.glob.isMainWindow); | ||||
|  | ||||
| // we should save all outstanding changes before the page/app is closed | ||||
| $(window).on('beforeunload', () => { | ||||
|     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"; | ||||
|     } | ||||
| }); | ||||
|  | ||||
| function isNotePathInAddress() { | ||||
|     const [notePath, ntxId] = treeService.getHashValueFromAddress(); | ||||
|  | ||||
|     return notePath.startsWith("root") | ||||
|         // empty string is for empty/uninitialized tab | ||||
|         || (notePath === '' && !!ntxId); | ||||
| } | ||||
|  | ||||
| $(window).on('hashchange', function() { | ||||
|     if (isNotePathInAddress()) { | ||||
|         const [notePath, ntxId] = treeService.getHashValueFromAddress(); | ||||
|  | ||||
|         if (!notePath) { | ||||
|             console.log(`Invalid hash value "${document.location.hash}", ignoring.`); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         appContext.tabManager.switchToNoteContext(ntxId, notePath); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| export default appContext; | ||||
		Reference in New Issue
	
	Block a user