2020-01-12 12:48:17 +01:00
|
|
|
import server from "./server.js";
|
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-02-05 22:08:45 +01:00
|
|
|
import ZoomService from "./zoom.js";
|
2020-02-06 21:47:31 +01:00
|
|
|
import Layout from "../widgets/layout.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-01-11 21:19:56 +01:00
|
|
|
|
2020-01-12 09:57:28 +01:00
|
|
|
class AppContext {
|
2020-02-06 21:47:31 +01:00
|
|
|
constructor(layout) {
|
|
|
|
this.layout = layout;
|
2020-02-07 21:08:55 +01:00
|
|
|
this.tabManager = new TabManager(this);
|
2020-02-08 20:53:07 +01:00
|
|
|
this.components = [];
|
2020-02-15 10:41:21 +01:00
|
|
|
this.executors = [];
|
2020-01-12 19:05:09 +01:00
|
|
|
}
|
|
|
|
|
2020-02-05 22:08:45 +01:00
|
|
|
async start() {
|
|
|
|
options.load(await server.get('options'));
|
|
|
|
|
2020-02-02 22:04:28 +01:00
|
|
|
this.showWidgets();
|
|
|
|
|
2020-02-07 21:08:55 +01:00
|
|
|
this.tabManager.loadTabs();
|
2020-02-02 22:32:44 +01:00
|
|
|
|
2020-02-02 22:04:28 +01:00
|
|
|
bundleService.executeStartupBundles();
|
|
|
|
}
|
2020-01-12 19:05:09 +01:00
|
|
|
|
2020-02-02 22:04:28 +01:00
|
|
|
showWidgets() {
|
2020-02-06 21:47:31 +01:00
|
|
|
const rootContainer = this.layout.getRootWidget(this);
|
2020-02-09 22:31:52 +01:00
|
|
|
const $renderedWidget = rootContainer.render();
|
2020-01-14 21:23:32 +01:00
|
|
|
|
2020-02-09 22:31:52 +01:00
|
|
|
$("body").append($renderedWidget);
|
|
|
|
|
|
|
|
$renderedWidget.on('click', "[data-trigger-event]", e => {
|
|
|
|
const eventName = $(e.target).attr('data-trigger-event');
|
|
|
|
|
|
|
|
this.trigger(eventName);
|
|
|
|
});
|
2020-02-05 22:08:45 +01:00
|
|
|
|
2020-01-20 22:35:52 +01:00
|
|
|
this.components = [
|
2020-02-08 20:53:07 +01:00
|
|
|
this.tabManager,
|
2020-02-06 21:16:02 +01:00
|
|
|
rootContainer,
|
2020-02-15 10:41:21 +01:00
|
|
|
new Entrypoints(this)
|
|
|
|
];
|
|
|
|
|
|
|
|
this.executors = [
|
|
|
|
new DialogCommandExecutor(this, this)
|
2020-01-13 21:48:44 +01:00
|
|
|
];
|
2020-02-05 22:08:45 +01:00
|
|
|
|
|
|
|
if (utils.isElectron()) {
|
2020-02-15 09:43:47 +01:00
|
|
|
this.components.push(new ZoomService(this, this));
|
2020-02-05 22:08:45 +01:00
|
|
|
|
|
|
|
import("./spell_check.js").then(spellCheckService => spellCheckService.initSpellCheck());
|
|
|
|
}
|
2020-02-06 21:16:02 +01:00
|
|
|
|
|
|
|
this.trigger('initialRenderComplete');
|
2020-01-11 21:19:56 +01:00
|
|
|
}
|
|
|
|
|
2020-02-12 20:31:31 +01:00
|
|
|
async trigger(name, data) {
|
2020-01-12 23:03:55 +01:00
|
|
|
this.eventReceived(name, data);
|
|
|
|
|
2020-02-12 20:31:31 +01:00
|
|
|
const promises = [];
|
|
|
|
|
2020-01-21 22:54:16 +01:00
|
|
|
for (const component of this.components) {
|
2020-02-12 20:31:31 +01:00
|
|
|
promises.push(component.eventReceived(name, data));
|
2020-01-15 21:36:01 +01:00
|
|
|
}
|
2020-02-12 20:31:31 +01:00
|
|
|
|
|
|
|
await Promise.all(promises);
|
2020-01-11 21:19:56 +01:00
|
|
|
}
|
|
|
|
|
2020-02-12 20:31:31 +01:00
|
|
|
async eventReceived(name, data) {
|
2020-01-12 23:03:55 +01:00
|
|
|
const fun = this[name + 'Listener'];
|
|
|
|
|
|
|
|
if (typeof fun === 'function') {
|
2020-02-12 20:31:31 +01:00
|
|
|
await fun.call(this, data);
|
2020-01-12 23:03:55 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-01 22:29:32 +01:00
|
|
|
async protectedSessionStartedListener() {
|
|
|
|
await treeCache.loadInitialTree();
|
|
|
|
|
|
|
|
this.trigger('treeCacheReloaded');
|
|
|
|
}
|
2020-02-15 10:41:21 +01:00
|
|
|
|
|
|
|
async triggerCommand(name, data) {
|
|
|
|
for (const executor of this.executors) {
|
|
|
|
const fun = executor[name + 'Command'];
|
|
|
|
|
|
|
|
const called = await this.callMethod(executor, fun, data);
|
|
|
|
|
|
|
|
if (called) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
console.error(`Unhandled command ${name}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
async callMethod(thiz, fun, data) {
|
|
|
|
if (typeof fun !== 'function') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
await fun.call(thiz, data);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2020-01-12 19:05:09 +01:00
|
|
|
}
|
|
|
|
|
2020-02-06 21:47:31 +01:00
|
|
|
const layout = new Layout();
|
|
|
|
|
|
|
|
const appContext = new AppContext(layout);
|
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', () => {
|
|
|
|
appContext.trigger('beforeUnload');
|
|
|
|
});
|
|
|
|
|
2020-02-03 20:07:34 +01:00
|
|
|
function isNotePathInAddress() {
|
|
|
|
const [notePath, tabId] = getHashValueFromAddress();
|
|
|
|
|
|
|
|
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-02-08 20:53:07 +01:00
|
|
|
appContext.tabManager.switchToTab(tabId, notePath);
|
2020-02-03 20:07:34 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-01-12 09:57:28 +01:00
|
|
|
export default appContext;
|