diff --git a/src/public/javascripts/desktop.js b/src/public/javascripts/desktop.js index e668db053..64c7a15a9 100644 --- a/src/public/javascripts/desktop.js +++ b/src/public/javascripts/desktop.js @@ -141,7 +141,7 @@ async function printActiveNote() { await libraryLoader.requireLibrary(libraryLoader.PRINT_THIS); - $tabContext.$tabContent.find('.note-detail-component:visible').printThis({ + $tabContext.$tabContent.find('.note-detail-printable:visible').printThis({ header: $("

").text($tabContext.note && $tabContext.note.title).prop('outerHTML') , importCSS: false, loadCSS: [ diff --git a/src/public/javascripts/services/tab_context.js b/src/public/javascripts/services/tab_context.js index 0e165a3b4..a3a5abf65 100644 --- a/src/public/javascripts/services/tab_context.js +++ b/src/public/javascripts/services/tab_context.js @@ -60,6 +60,11 @@ class TabContext extends Component { bundleService.executeRelationBundles(this.note, 'runOnNoteView', this); + if (this.note.isProtected && protectedSessionHolder.isProtectedSessionAvailable()) { + // FIXME: there are probably more places where this should be done + protectedSessionHolder.touchProtectedSession(); + } + this.trigger('tabNoteSwitched', {tabId: this.tabId}); } diff --git a/src/public/javascripts/widgets/note_detail.js b/src/public/javascripts/widgets/note_detail.js index 7c2121a0c..12e457e31 100644 --- a/src/public/javascripts/widgets/note_detail.js +++ b/src/public/javascripts/widgets/note_detail.js @@ -16,25 +16,25 @@ const TPL = ` `; -const componentClasses = { - 'empty': "./detail/note_detail_empty.js", - 'text': "./detail/note_detail_text.js", - 'code': "./detail/note_detail_code.js", - 'file': "./detail/note_detail_file.js", - 'image': "./detail/note_detail_image.js", - 'search': "./detail/note_detail_search.js", - 'render': "./detail/note_detail_render.js", - 'relation-map': "./detail/note_detail_relation_map.js", - 'protected-session': "./detail/note_detail_protected_session.js", - 'book': "./detail/note_detail_book.js" +const typeWidgetClasses = { + 'empty': "./type_widgets/note_detail_empty.js", + 'text': "./type_widgets/text.js", + 'code': "./type_widgets/code.js", + 'file': "./type_widgets/file.js", + 'image': "./type_widgets/note_detail_image.js", + 'search': "./type_widgets/note_detail_search.js", + 'render': "./type_widgets/note_detail_render.js", + 'relation-map': "./type_widgets/note_detail_relation_map.js", + 'protected-session': "./type_widgets/note_detail_protected_session.js", + 'book': "./type_widgets/note_detail_book.js" }; export default class NoteDetailWidget extends TabAwareWidget { constructor(appContext) { super(appContext); - this.components = {}; - this.componentPromises = {}; + this.typeWidgets = {}; + this.typeWidgetPromises = {}; } doRender() { @@ -43,18 +43,23 @@ export default class NoteDetailWidget extends TabAwareWidget { return this.$widget; } - async noteSwitched() { - await this.initComponent(/**disableAutoBook*/); + async refresh() { + this.type = this.getWidgetType(/*disableAutoBook*/); - for (const componentType in this.components) { - if (componentType !== this.type) { - this.components[componentType].cleanup(); + if (!(this.type in this.typeWidgetPromises)) { + this.typeWidgetPromises[this.type] = this.initWidgetType(this.type); + } + + await this.typeWidgetPromises[this.type]; + + for (const typeWidget of Object.values(this.typeWidgets)) { + if (typeWidget.constructor.getType() !== this.type) { + typeWidget.cleanup(); + typeWidget.toggle(false); } } - this.$widget.find('.note-detail-component').hide(); - - this.getComponent().show(); + this.getTypeWidget().toggle(true); this.setupClasses(); } @@ -75,36 +80,26 @@ export default class NoteDetailWidget extends TabAwareWidget { this.$widget.toggleClass("protected", note.isProtected); } - getComponent() { - if (!this.components[this.type]) { - throw new Error("Could not find component for type: " + this.type); + getTypeWidget() { + if (!this.typeWidgets[this.type]) { + throw new Error("Could not find typeWidget for type: " + this.type); } - return this.components[this.type]; - } - - async initComponent(disableAutoBook = false) { - this.type = this.getComponentType(disableAutoBook); - - if (!(this.type in this.componentPromises)) { - this.componentPromises[this.type] = this.reallyInitComponent(this.type); - } - - await this.componentPromises[this.type]; + return this.typeWidgets[this.type]; } - async reallyInitComponent(type) { - const clazz = await import(componentClasses[type]); + async initWidgetType(type) { + const clazz = await import(typeWidgetClasses[type]); - this.components[this.type] = new clazz.default(this.appContext); - this.children.push(this.components[this.type]); + this.typeWidgets[this.type] = new clazz.default(this.appContext); + this.children.push(this.typeWidgets[this.type]); - this.components[this.type].renderTo(this.$widget); + this.typeWidgets[this.type].renderTo(this.$widget); - this.components[this.type].eventReceived('setTabContext', {tabContext: this.tabContext}); + this.typeWidgets[this.type].eventReceived('setTabContext', {tabContext: this.tabContext}); } - getComponentType(disableAutoBook) { + getWidgetType(disableAutoBook) { const note = this.tabContext.note; if (!note) { @@ -113,20 +108,15 @@ export default class NoteDetailWidget extends TabAwareWidget { let type = note.type; - if (type === 'text' && !disableAutoBook && utils.isHtmlEmpty(note.content) && note.hasChildren()) { + if (type === 'text' && !disableAutoBook + && utils.isHtmlEmpty(note.content) + && note.hasChildren()) { + type = 'book'; } - if (note.isProtected) { - if (protectedSessionHolder.isProtectedSessionAvailable()) { - protectedSessionHolder.touchProtectedSession(); - } else { - type = 'protected-session'; - - // FIXME - // user shouldn't be able to edit note title - //this.$noteTitle.prop("readonly", true); - } + if (note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()) { + type = 'protected-session'; } return type; diff --git a/src/public/javascripts/widgets/note_title.js b/src/public/javascripts/widgets/note_title.js index bf6fb2cba..b8d3c8b49 100644 --- a/src/public/javascripts/widgets/note_title.js +++ b/src/public/javascripts/widgets/note_title.js @@ -135,6 +135,10 @@ export default class NoteTitleWidget extends TabAwareWidget { this.$noteTitle.val(note.title); + if (note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()) { + this.$noteTitle.prop("readonly", true); + } + this.$protectButton.toggleClass("active", note.isProtected); this.$protectButton.prop("disabled", note.isProtected); this.$unprotectButton.toggleClass("active", !note.isProtected); diff --git a/src/public/javascripts/widgets/detail/note_detail_code.js b/src/public/javascripts/widgets/type_widgets/code.js similarity index 80% rename from src/public/javascripts/widgets/detail/note_detail_code.js rename to src/public/javascripts/widgets/type_widgets/code.js index 50a6b5d82..e02bb9e7e 100644 --- a/src/public/javascripts/widgets/detail/note_detail_code.js +++ b/src/public/javascripts/widgets/type_widgets/code.js @@ -4,14 +4,16 @@ import toastService from "../../services/toast.js"; import server from "../../services/server.js"; import noteDetailService from "../../services/note_detail.js"; import keyboardActionService from "../../services/keyboard_actions.js"; -import TabAwareWidget from "../tab_aware_widget.js"; +import TypeWidget from "./type_widget.js"; const TPL = ` -
+
`; -class NoteDetailCode extends TabAwareWidget { +class CodeTypeWidget extends TypeWidget { + static getType() { return "code"; } + doRender() { this.$widget = $(TPL); this.$editor = this.$widget.find('.note-detail-code-editor'); @@ -58,22 +60,19 @@ class NoteDetailCode extends TabAwareWidget { //this.onNoteChange(() => this.tabContext.noteChanged()); } - refresh() { - // lazy loading above can take time and tab might have been already switched to another note - if (this.tabContext.note && this.tabContext.note.type === 'code') { - // CodeMirror breaks pretty badly on null so even though it shouldn't happen (guarded by consistency check) - // we provide fallback - this.codeEditor.setValue(this.tabContext.note.content || ""); + doRefresh() { + // CodeMirror breaks pretty badly on null so even though it shouldn't happen (guarded by consistency check) + // we provide fallback + this.codeEditor.setValue(this.tabContext.note.content || ""); - const info = CodeMirror.findModeByMIME(this.tabContext.note.mime); + const info = CodeMirror.findModeByMIME(this.tabContext.note.mime); - if (info) { - this.codeEditor.setOption("mode", info.mime); - CodeMirror.autoLoadMode(this.codeEditor, info.mode); - } - - this.show(); + if (info) { + this.codeEditor.setOption("mode", info.mime); + CodeMirror.autoLoadMode(this.codeEditor, info.mode); } + + this.show(); } show() { @@ -127,4 +126,4 @@ class NoteDetailCode extends TabAwareWidget { } } -export default NoteDetailCode; \ No newline at end of file +export default CodeTypeWidget; \ No newline at end of file diff --git a/src/public/javascripts/widgets/detail/note_detail_file.js b/src/public/javascripts/widgets/type_widgets/file.js similarity index 95% rename from src/public/javascripts/widgets/detail/note_detail_file.js rename to src/public/javascripts/widgets/type_widgets/file.js index 52bfebbfe..1069eef53 100644 --- a/src/public/javascripts/widgets/detail/note_detail_file.js +++ b/src/public/javascripts/widgets/type_widgets/file.js @@ -2,10 +2,10 @@ import utils from "../../services/utils.js"; import server from "../../services/server.js"; import toastService from "../../services/toast.js"; import noteDetailService from "../../services/note_detail.js"; -import TabAwareWidget from "../tab_aware_widget.js"; +import TypeWidget from "./type_widget.js"; const TPL = ` -
+