This commit is contained in:
zadam 2020-01-18 18:01:16 +01:00
parent b25c1d6fa8
commit b00a9f4415
12 changed files with 91 additions and 102 deletions

6
package-lock.json generated
View File

@ -2777,9 +2777,9 @@
},
"dependencies": {
"@types/node": {
"version": "10.17.11",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.11.tgz",
"integrity": "sha512-dNd2pp8qTzzNLAs3O8nH3iU9DG9866KHq9L3ISPB7DOGERZN81nW/5/g/KzMJpCU8jrbCiMRBzV9/sCEdRosig==",
"version": "10.17.13",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz",
"integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==",
"dev": true
}
}

View File

@ -127,6 +127,8 @@ class AppContext {
activateNote(notePath) {
const activeTabContext = this.getActiveTabContext();
console.log("Setting activeTabContext to " + notePath);
activeTabContext.setNote(notePath);
this._setTitleBar();
@ -209,36 +211,6 @@ class AppContext {
}
}
async showTab(tabId) {
for (const ctx of this.tabContexts) {
if (ctx.tabId === tabId) {
await ctx.show();
} else {
ctx.hide();
}
}
const oldActiveNode = this.getMainNoteTree().getActiveNode();
if (oldActiveNode) {
oldActiveNode.setActive(false);
}
const newActiveTabContext = this.getActiveTabContext();
if (newActiveTabContext && newActiveTabContext.notePath) {
const newActiveNode = await this.getMainNoteTree().getNodeFromPath(newActiveTabContext.notePath);
if (newActiveNode) {
if (!newActiveNode.isVisible()) {
await this.getMainNoteTree().expandToNote(newActiveTabContext.notePath);
}
newActiveNode.setActive(true, {noEvents: true});
}
}
}
/**
* @return {NoteTreeWidget}
*/
@ -343,10 +315,6 @@ class AppContext {
this.openEmptyTab();
}
async activeTabChangedListener({tabId}) {
await this.showTab(tabId);
}
async tabRemoveListener({tabId}) {
this.tabContexts.filter(nc => nc.tabId === tabId)
.forEach(tc => tc.remove());

View File

@ -44,13 +44,9 @@ class TabContext extends Component {
this.tabRow.updateTab(this.$tab[0], {title: this.note.title});
if (!this.initialized) {
return;
}
this.setupClasses();
this.cleanup(); // esp. on windows autocomplete is not getting closed automatically
//this.cleanup(); // esp. on windows autocomplete is not getting closed automatically
setTimeout(async () => {
// we include the note into recent list only if the user stayed on the note at least 5 seconds
@ -64,11 +60,10 @@ class TabContext extends Component {
bundleService.executeRelationBundles(this.note, 'runOnNoteView', this);
appContext.trigger('activeNoteChanged');
this.trigger('tabNoteSwitched', {tabId: this.tabId});
}
async show() {
await this.setNote(this.notePath);
}
hide() {

View File

@ -1,28 +1,20 @@
import Component from "./component.js";
class BasicWidget extends Component {
constructor(appContext) {
super(appContext);
this.widgetId = `widget-${this.constructor.name}`;
}
renderTo($parent) {
this.$parent = $parent;
$parent.append(this.render());
}
render() {
// actual rendering is async
this.$widget = this.doRender();
// $widget.attr('id', this.widgetId);
return this.$widget;
return this.doRender();
}
/**
* for overriding
*/
doRender() {}
async doRender() {}
toggle(show) {
this.$widget.toggle(show);

View File

@ -1,16 +1,22 @@
export default class Component {
/** @param {AppContext} appContext */
constructor(appContext) {
this.componentId = `component-${this.constructor.name}`;
this.appContext = appContext;
/** @type Component[] */
this.children = [];
this.initialized = Promise.resolve();
}
eventReceived(name, data) {
async eventReceived(name, data) {
await this.initialized;
console.log(`Received ${name} to ${this.componentId}`);
const fun = this[name + 'Listener'];
if (typeof fun === 'function') {
fun.call(this, data);
await fun.call(this, data);
}
for (const child of this.children) {

View File

@ -73,11 +73,9 @@ const TPL = `
`;
class NoteDetailText extends TabAwareWidget {
render() {
doRender() {
this.$widget = $(TPL);
this.$editor = this.$widget.find('.note-detail-text-editor');
this.textEditorPromise = null;
this.textEditor = null;
this.$widget.on("dblclick", "img", e => {
const $img = $(e.target);
@ -95,26 +93,11 @@ class NoteDetailText extends TabAwareWidget {
}
});
if (!this.textEditorPromise) {
this.textEditorPromise = this.initEditor();
}
this.initialized = this.initEditor();
return this.$widget;
}
async activeNoteChanged() {
await this.textEditorPromise;
// lazy loading above can take time and tab might have been already switched to another note
if (this.tabContext.note && this.tabContext.note.type === 'text') {
this.textEditor.isReadOnly = await this.isReadOnly();
this.$widget.show();
this.textEditor.setData(this.tabContext.note.content);
}
}
async initEditor() {
await libraryLoader.requireLibrary(libraryLoader.CKEDITOR);
@ -133,7 +116,7 @@ class NoteDetailText extends TabAwareWidget {
// display of $widget in both branches.
this.$widget.show();
const textEditorInstance = await BalloonEditor.create(this.$editor[0], {
this.textEditor = await BalloonEditor.create(this.$editor[0], {
placeholder: "Type the content of your note here ...",
mention: mentionSetup,
codeBlock: {
@ -143,12 +126,19 @@ class NoteDetailText extends TabAwareWidget {
if (glob.isDev && ENABLE_INSPECTOR) {
await import('../../libraries/ckeditor/inspector.js');
CKEditorInspector.attach(textEditorInstance);
CKEditorInspector.attach(this.textEditor);
}
}
this.textEditor = textEditorInstance;
async noteSwitched() {
// lazy loading above can take time and tab might have been already switched to another note
if (this.tabContext.note && this.tabContext.note.type === 'text') {
this.textEditor.isReadOnly = await this.isReadOnly();
//this.onNoteChange(() => this.tabContext.noteChanged());
this.$widget.show();
this.textEditor.setData(this.tabContext.note.content);
}
}
getContent() {

View File

@ -34,6 +34,7 @@ export default class NoteDetailWidget extends TabAwareWidget {
super(appContext);
this.components = {};
this.componentPromises = {};
}
doRender() {
@ -42,13 +43,10 @@ export default class NoteDetailWidget extends TabAwareWidget {
return this.$widget;
}
async activeTabChanged() {
async noteSwitched() {
await this.initComponent(/**disableAutoBook*/);
for (const componentType in this.components) {
// FIXME
this.components[componentType].ctx = this.tabContext;
if (componentType !== this.type) {
this.components[componentType].cleanup();
}
@ -57,7 +55,6 @@ export default class NoteDetailWidget extends TabAwareWidget {
this.$widget.find('.note-detail-component').hide();
this.getComponent().show();
await this.getComponent().render();
this.setupClasses();
}
@ -89,14 +86,24 @@ export default class NoteDetailWidget extends TabAwareWidget {
async initComponent(disableAutoBook = false) {
this.type = this.getComponentType(disableAutoBook);
if (!(this.type in this.components)) {
const clazz = await import(componentClasses[this.type]);
this.components[this.type] = new clazz.default(this);
this.children.push(this.components[this.type]);
this.$widget.append(this.components[this.type].render());
if (!(this.type in this.componentPromises)) {
this.componentPromises[this.type] = this.reallyInitComponent(this.type);
}
await this.componentPromises[this.type];
}
async reallyInitComponent(type) {
const clazz = await import(componentClasses[type]);
this.components[this.type] = new clazz.default(this.appContext);
this.children.push(this.components[this.type]);
this.components[this.type].renderTo(this.$widget);
this.components[this.type].setTabContext(this.tabContext);
this.components[this.type].eventReceived('tabNoteSwitched', {tabId: this.tabContext.tabId});
}
getComponentType(disableAutoBook) {

View File

@ -13,6 +13,7 @@ import TreeContextMenu from "../services/tree_context_menu.js";
import treeChangesService from "../services/branches.js";
import ws from "../services/ws.js";
import appContext from "../services/app_context.js";
import TabAwareWidget from "./tab_aware_widget.js";
const TPL = `
<div class="tree">
@ -29,7 +30,7 @@ const TPL = `
</div>
`;
export default class NoteTreeWidget extends BasicWidget {
export default class NoteTreeWidget extends TabAwareWidget {
constructor(appContext) {
super(appContext);
@ -402,6 +403,26 @@ export default class NoteTreeWidget extends BasicWidget {
collapseTreeListener() { this.collapseTree(); }
async activeTabChanged() {
const oldActiveNode = this.getActiveNode();
if (oldActiveNode) {
oldActiveNode.setActive(false);
}
if (this.tabContext && this.tabContext.notePath) {
const newActiveNode = await this.getNodeFromPath(this.tabContext.notePath);
if (newActiveNode) {
if (!newActiveNode.isVisible()) {
await this.expandToNote(this.tabContext.notePath);
}
newActiveNode.setActive(true, {noEvents: true});
}
}
}
async notesReloadedListener({ noteIds, activateNotePath }) {
for (const noteId of noteIds) {
for (const node of this.getNodesByNoteId(noteId)) {

View File

@ -28,11 +28,11 @@ const TPL = `
export default class PromotedAttributesWidget extends TabAwareWidget {
doRender() {
const $widget = $(TPL);
this.$widget = $(TPL);
this.$container = $widget.find(".promoted-attributes");
this.$container = this.$widget.find(".promoted-attributes");
return $widget;
return this.$widget;
}
async activeTabChanged() {

View File

@ -33,7 +33,7 @@ class StandardWidget extends TabAwareWidget {
//getPosition() { return this.widgetOptions.position; }
render() {
const widgetInstanceId = this.widgetId + "-" + utils.randomString(10);
const widgetInstanceId = this.componentId + "-" + utils.randomString(10);
this.$widget = $(WIDGET_TPL);
this.$widget.find('[data-target]').attr('data-target', "#" + widgetInstanceId);

View File

@ -1,13 +1,21 @@
import BasicWidget from "./basic_widget.js";
export default class TabAwareWidget extends BasicWidget {
constructor(appContext, tabContext = null) {
super(appContext);
setTabContext(tabContext) {
/** @var {TabContext} */
this.tabContext = tabContext;
this.eventReceived('tabNoteSwitched', {tabId: this.tabContext.tabId});
}
tabNoteSwitchedListener({tabId}) {
if (this.tabContext && tabId === this.tabContext.tabId) {
this.noteSwitched();
}
}
noteSwitched() {}
// to override
activeTabChanged() {}

View File

@ -23,8 +23,10 @@ export default class TabCachingWidget extends TabAwareWidget {
if (!widget) {
widget = this.widgets[this.tabContext.tabId] = this.widgetFactory();
this.children.push(widget);
widget.renderTo(this.$parent);
widget.activeTabChangedListener();
widget.setTabContext(this.tabContext);
}
widget.toggle(true);