From c9bc4ad1086e420211f0b8dbe647fb9c295c7f42 Mon Sep 17 00:00:00 2001 From: zadam Date: Mon, 13 Jan 2020 21:48:44 +0100 Subject: [PATCH] widgetizing note detail WIP --- .../javascripts/services/app_context.js | 32 ++++-- .../javascripts/services/note_detail_code.js | 5 + .../javascripts/services/note_detail_text.js | 37 +++++- .../javascripts/services/tab_context.js | 98 ++-------------- src/public/javascripts/widgets/note_detail.js | 108 ++++++++++++++++++ src/public/stylesheets/style.css | 32 ------ src/views/center.ejs | 33 ------ src/views/desktop.ejs | 2 +- 8 files changed, 183 insertions(+), 164 deletions(-) create mode 100644 src/public/javascripts/widgets/note_detail.js delete mode 100644 src/views/center.ejs diff --git a/src/public/javascripts/services/app_context.js b/src/public/javascripts/services/app_context.js index 9e91ebe55..4c36d062e 100644 --- a/src/public/javascripts/services/app_context.js +++ b/src/public/javascripts/services/app_context.js @@ -10,6 +10,7 @@ import keyboardActionService from "./keyboard_actions.js"; import TabRowWidget from "./tab_row.js"; import NoteTitleWidget from "../widgets/note_title.js"; import PromotedAttributesWidget from "../widgets/promoted_attributes.js"; +import NoteDetailWidget from "../widgets/note_detail.js"; class AppContext { constructor() { @@ -29,29 +30,40 @@ class AppContext { $("#global-menu-wrapper").after(contents); - this.promotedAttributes = new PromotedAttributesWidget(this); - $("#center-pane").prepend(this.promotedAttributes.render()); - - this.noteTitleWidget = new NoteTitleWidget(this); - $("#center-pane").prepend(this.noteTitleWidget.render()); - this.noteTreeWidget = new NoteTreeWidget(this); - this.widgets = [ + const leftPaneWidgets = [ new GlobalButtonsWidget(this), new SearchBoxWidget(this), new SearchResultsWidget(this), this.noteTreeWidget ]; - for (const widget of this.widgets) { + for (const widget of leftPaneWidgets) { const $widget = widget.render(); $leftPane.append($widget); } - this.widgets.push(this.noteTitleWidget); - this.widgets.push(this.promotedAttributes); + const $centerPane = $("#center-pane"); + + const centerPaneWidgets = [ + new NoteTitleWidget(this), + new PromotedAttributesWidget(this), + new NoteDetailWidget(this) + ]; + + for (const widget of centerPaneWidgets) { + const $widget = widget.render(); + + $centerPane.append($widget); + } + + this.widgets = [ + this.tabRow, + ...leftPaneWidgets, + ...centerPaneWidgets + ]; } trigger(name, data) { diff --git a/src/public/javascripts/services/note_detail_code.js b/src/public/javascripts/services/note_detail_code.js index f34d16f8c..67ffa967f 100644 --- a/src/public/javascripts/services/note_detail_code.js +++ b/src/public/javascripts/services/note_detail_code.js @@ -5,6 +5,11 @@ import server from "./server.js"; import noteDetailService from "./note_detail.js"; import keyboardActionService from "./keyboard_actions.js"; +const TPL = ` +
+
+
`; + class NoteDetailCode { /** diff --git a/src/public/javascripts/services/note_detail_text.js b/src/public/javascripts/services/note_detail_text.js index ab48e7e1a..df770d459 100644 --- a/src/public/javascripts/services/note_detail_text.js +++ b/src/public/javascripts/services/note_detail_text.js @@ -39,13 +39,46 @@ const mentionSetup = { ] }; +const TPL = ` +
+ + +
+
+`; + class NoteDetailText { /** * @param {TabContext} ctx */ - constructor(ctx) { + constructor(ctx, $parent) { + this.$component = $(TPL); + $parent.append(this.$component); this.ctx = ctx; - this.$component = ctx.$tabContent.find('.note-detail-text'); this.$editorEl = this.$component.find('.note-detail-text-editor'); this.textEditorPromise = null; this.textEditor = null; diff --git a/src/public/javascripts/services/tab_context.js b/src/public/javascripts/services/tab_context.js index 20ae3fc8c..808ed4194 100644 --- a/src/public/javascripts/services/tab_context.js +++ b/src/public/javascripts/services/tab_context.js @@ -8,21 +8,6 @@ import optionsService from "./options.js"; import Sidebar from "./sidebar.js"; import appContext from "./app_context.js"; -const $tabContentsContainer = $("#note-tab-container"); - -const componentClasses = { - 'empty': "./note_detail_empty.js", - 'text': "./note_detail_text.js", - 'code': "./note_detail_code.js", - 'file': "./note_detail_file.js", - 'image': "./note_detail_image.js", - 'search': "./note_detail_search.js", - 'render': "./note_detail_render.js", - 'relation-map': "./note_detail_relation_map.js", - 'protected-session': "./note_detail_protected_session.js", - 'book': "./note_detail_book.js" -}; - let showSidebarInNewTab = true; optionsService.addLoadListener(options => { @@ -49,15 +34,8 @@ class TabContext { this.initialized = true; - this.$tabContent = $(".note-tab-content-template").clone(); - this.$tabContent.removeClass('note-tab-content-template'); - this.$tabContent.attr('data-tab-id', this.tabId); - this.$tabContent.hide(); + this.$tabContent = $("
"); // FIXME - $tabContentsContainer.append(this.$tabContent); - - this.$noteDetailComponents = this.$tabContent.find(".note-detail-component"); - this.$scriptArea = this.$tabContent.find(".note-detail-script-area"); this.noteChangeDisabled = false; this.isNoteChanged = false; this.attributes = new Attributes(this); @@ -69,20 +47,6 @@ class TabContext { this.sidebar = new Sidebar(this, sidebarState); } - - this.components = {}; - - await this.initComponent(); - } - - 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); - } } async setNote(note, notePath) { @@ -95,8 +59,6 @@ class TabContext { return; } - this.$scriptArea.empty(); - if (utils.isDesktop()) { this.attributes.refreshAttributes(); } else { @@ -115,7 +77,7 @@ class TabContext { this.noteChangeDisabled = true; try { - await this.renderComponent(); + } finally { this.noteChangeDisabled = false; } @@ -137,7 +99,8 @@ class TabContext { bundleService.executeRelationBundles(this.note, 'runOnNoteView', this); // after loading new note make sure editor is scrolled to the top - this.getComponent().scrollToTop(); + // FIXME + //this.getComponent().scrollToTop(); appContext.trigger('activeNoteChanged'); } @@ -146,18 +109,15 @@ class TabContext { if (!this.initialized) { await this.initTabContent(); - this.$tabContent.show(); // show immediately so that user can see something - if (this.note) { await this.setNote(this.note, this.notePath); } else { + // FIXME await this.renderComponent(); // render empty page } } - this.$tabContent.show(); - if (this.sidebar) { this.sidebar.show(); } @@ -167,18 +127,7 @@ class TabContext { } async renderComponent(disableAutoBook = false) { - await this.initComponent(disableAutoBook); - - for (const componentType in this.components) { - if (componentType !== this.type) { - this.components[componentType].cleanup(); - } - } - - this.$noteDetailComponents.hide(); - - this.getComponent().show(); - await this.getComponent().render(); + // FIXME } setTitleBar() { @@ -235,36 +184,11 @@ class TabContext { } getComponent() { - if (!this.components[this.type]) { - throw new Error("Could not find component for type: " + this.type); - } - - return this.components[this.type]; + // FIXME } getComponentType(disableAutoBook) { - if (!this.note) { - return "empty"; - } - - let type = this.note.type; - - if (type === 'text' && !disableAutoBook && utils.isHtmlEmpty(this.note.content) && this.note.hasChildren()) { - type = 'book'; - } - - if (this.note.isProtected) { - if (protectedSessionHolder.isProtectedSessionAvailable()) { - protectedSessionHolder.touchProtectedSession(); - } else { - type = 'protected-session'; - - // user shouldn't be able to edit note title - this.$noteTitle.prop("readonly", true); - } - } - - return type; + // FIXME } async activate() { @@ -272,6 +196,8 @@ class TabContext { } async saveNote() { + return; // FIXME + if (this.note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()) { return; } @@ -316,8 +242,8 @@ class TabContext { this.isNoteChanged = true; - // FIMXE: trigger noteChanged event - this.$savedIndicator.fadeOut(); + // FIXME: trigger noteChanged event + //this.$savedIndicator.fadeOut(); } async remove() { diff --git a/src/public/javascripts/widgets/note_detail.js b/src/public/javascripts/widgets/note_detail.js new file mode 100644 index 000000000..bfa45a481 --- /dev/null +++ b/src/public/javascripts/widgets/note_detail.js @@ -0,0 +1,108 @@ +import TabAwareWidget from "./tab_aware_widget.js"; +import utils from "../services/utils.js"; +import protectedSessionHolder from "../services/protected_session_holder.js"; + +const TPL = ` +
+ +
+`; + +const componentClasses = { + 'empty': "../services/note_detail_empty.js", + 'text': "../services/note_detail_text.js", + 'code': "../services/note_detail_code.js", + 'file': "../services/note_detail_file.js", + 'image': "../services/note_detail_image.js", + 'search': "../services/note_detail_search.js", + 'render': "../services/note_detail_render.js", + 'relation-map': "../services/note_detail_relation_map.js", + 'protected-session': "../services/note_detail_protected_session.js", + 'book': "../services/note_detail_book.js" +}; + +export default class NoteDetailWidget extends TabAwareWidget { + constructor(appContext) { + super(appContext); + + this.components = {}; + } + + doRender() { + this.$widget = $(TPL); + + return this.$widget; + } + + async activeTabChanged() { + 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(); + } + } + + this.$widget.find('.note-detail-component').hide(); + + this.getComponent().show(); + await this.getComponent().render(); + } + + getComponent() { + if (!this.components[this.type]) { + throw new Error("Could not find component for type: " + this.type); + } + + return this.components[this.type]; + } + + 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.$widget); + } + } + + getComponentType(disableAutoBook) { + const note = this.tabContext.note; + + if (!note) { + return "empty"; + } + + let type = note.type; + + 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); + } + } + + return type; + } +} \ No newline at end of file diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index 204dd3442..d99c1c274 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -100,14 +100,6 @@ span.fancytree-node.muted { opacity: 0.6; } width: 100%; } -.note-detail-content { - display: flex; - flex-direction: column; - flex-grow: 100; - height: 100%; - width: 100%; -} - .note-detail-component-wrapper { flex-grow: 100; position: relative; @@ -127,30 +119,6 @@ span.fancytree-node.muted { opacity: 0.6; } display: none; } -.note-detail-text h1 { font-size: 2.0em; } -.note-detail-text h2 { font-size: 1.8em; } -.note-detail-text h3 { font-size: 1.6em; } -.note-detail-text h4 { font-size: 1.4em; } -.note-detail-text h5 { font-size: 1.2em; } -.note-detail-text h6 { font-size: 1.1em; } - -.note-detail-text { - overflow: auto; - font-family: var(--detail-text-font-family); -} - -.note-detail-text-editor { - padding-top: 10px; - border: 0 !important; - box-shadow: none !important; - /* This is because with empty content height of editor is 0 and it's impossible to click into it */ - min-height: 500px; -} - -.note-detail-text p:first-child, .note-detail-text::before { - margin-top: 0; -} - /** we disable shield background when in zen mode because I couldn't get it to stay static (it kept growing with content) */ #container:not(.zen-mode) .note-tab-content.protected { diff --git a/src/views/center.ejs b/src/views/center.ejs deleted file mode 100644 index 7317f344e..000000000 --- a/src/views/center.ejs +++ /dev/null @@ -1,33 +0,0 @@ -
-
-
-
-
-
-
-
- -
-
-
- - <% include details/empty.ejs %> - - <% include details/search.ejs %> - - <% include details/render.ejs %> - - <% include details/file.ejs %> - - <% include details/image.ejs %> - - <% include details/relation_map.ejs %> - - <% include details/protected_session_password.ejs %> - - <% include details/book.ejs %> -
-
-
-
-
\ No newline at end of file diff --git a/src/views/desktop.ejs b/src/views/desktop.ejs index ededfe080..e5f87be58 100644 --- a/src/views/desktop.ejs +++ b/src/views/desktop.ejs @@ -136,7 +136,7 @@
- <% include center.ejs %> +
<% include sidebar.ejs %>