the whole view is now composed from a single root widget

This commit is contained in:
zadam 2020-02-06 21:16:02 +01:00
parent 8d49249ed7
commit 92f6558e55
5 changed files with 98 additions and 120 deletions

View File

@ -17,7 +17,6 @@ import WhatLinksHereWidget from "../widgets/what_links_here.js";
import AttributesWidget from "../widgets/attributes.js"; import AttributesWidget from "../widgets/attributes.js";
import TitleBarButtonsWidget from "../widgets/title_bar_buttons.js"; import TitleBarButtonsWidget from "../widgets/title_bar_buttons.js";
import GlobalMenuWidget from "../widgets/global_menu.js"; import GlobalMenuWidget from "../widgets/global_menu.js";
import RowFlexContainer from "../widgets/row_flex_container.js";
import StandardTopWidget from "../widgets/standard_top_widget.js"; import StandardTopWidget from "../widgets/standard_top_widget.js";
import treeCache from "./tree_cache.js"; import treeCache from "./tree_cache.js";
import NotePathsWidget from "../widgets/note_paths.js"; import NotePathsWidget from "../widgets/note_paths.js";
@ -35,6 +34,7 @@ import treeService from "./tree.js";
import SidePaneContainer from "../widgets/side_pane_container.js"; import SidePaneContainer from "../widgets/side_pane_container.js";
import ZoomService from "./zoom.js"; import ZoomService from "./zoom.js";
import SidePaneToggles from "../widgets/side_pane_toggles.js"; import SidePaneToggles from "../widgets/side_pane_toggles.js";
import FlexContainer from "../widgets/flex_container.js";
class AppContext { class AppContext {
constructor() { constructor() {
@ -130,76 +130,53 @@ class AppContext {
showWidgets() { showWidgets() {
this.tabRow = new TabRowWidget(this); this.tabRow = new TabRowWidget(this);
this.noteTreeWidget = new NoteTreeWidget(this);
const topPaneWidgets = [ const rootContainer = new FlexContainer(this, { 'flex-direction': 'column', 'height': '100vh' }, [
new RowFlexContainer(this, [ new FlexContainer(this, { 'flex-direction': 'row' }, [
new GlobalMenuWidget(this), new GlobalMenuWidget(this),
this.tabRow, this.tabRow,
new TitleBarButtonsWidget(this) new TitleBarButtonsWidget(this)
]), ]),
new StandardTopWidget(this) new StandardTopWidget(this),
]; new FlexContainer(this, { 'flex-direction': 'row' }, [
new SidePaneContainer(this, 'left', [
const $topPane = $("#top-pane"); new GlobalButtonsWidget(this),
new SearchBoxWidget(this),
for (const widget of topPaneWidgets) { new SearchResultsWidget(this),
$topPane.append(widget.render()); this.noteTreeWidget
} ]),
new FlexContainer(this, { id: 'center-pane', 'flex-direction': 'column' }, [
this.noteTreeWidget = new NoteTreeWidget(this); new FlexContainer(this, { 'flex-direction': 'row' }, [
new TabCachingWidget(this, () => new NotePathsWidget(this)),
const $centerPane = $("#center-pane"); new NoteTitleWidget(this),
new RunScriptButtonsWidget(this),
const centerPaneWidgets = [ new ProtectedNoteSwitchWidget(this),
new RowFlexContainer(this, [ new NoteTypeWidget(this),
new TabCachingWidget(this, () => new NotePathsWidget(this)), new NoteActionsWidget(this)
new NoteTitleWidget(this), ]),
new RunScriptButtonsWidget(this), new TabCachingWidget(this, () => new PromotedAttributesWidget(this)),
new ProtectedNoteSwitchWidget(this), new TabCachingWidget(this, () => new NoteDetailWidget(this))
new NoteTypeWidget(this), ]),
new NoteActionsWidget(this) new SidePaneContainer(this, 'right', [
]), new NoteInfoWidget(this),
new TabCachingWidget(this, () => new PromotedAttributesWidget(this)), new TabCachingWidget(this, () => new CalendarWidget(this)),
new TabCachingWidget(this, () => new NoteDetailWidget(this)) new TabCachingWidget(this, () => new AttributesWidget(this)),
]; new TabCachingWidget(this, () => new LinkMapWidget(this)),
new TabCachingWidget(this, () => new NoteRevisionsWidget(this)),
for (const widget of centerPaneWidgets) { new TabCachingWidget(this, () => new SimilarNotesWidget(this)),
$centerPane.append(widget.render()); new TabCachingWidget(this, () => new WhatLinksHereWidget(this))
} ]),
new SidePaneToggles(this)
const leftPaneContainer = new SidePaneContainer(this, 'left', [ ])
new GlobalButtonsWidget(this),
new SearchBoxWidget(this),
new SearchResultsWidget(this),
this.noteTreeWidget
]); ]);
$centerPane.before(leftPaneContainer.render()); $("body").append(rootContainer.render());
const rightPaneContainer = new SidePaneContainer(this, 'right', [
new NoteInfoWidget(this),
new TabCachingWidget(this, () => new CalendarWidget(this)),
new TabCachingWidget(this, () => new AttributesWidget(this)),
new TabCachingWidget(this, () => new LinkMapWidget(this)),
new TabCachingWidget(this, () => new NoteRevisionsWidget(this)),
new TabCachingWidget(this, () => new SimilarNotesWidget(this)),
new TabCachingWidget(this, () => new WhatLinksHereWidget(this))
]);
$centerPane.after(rightPaneContainer.render());
const sidePaneTogglesWidget = new SidePaneToggles(this);
$centerPane.after(sidePaneTogglesWidget.render());
this.components = [ this.components = [
rootContainer,
new Entrypoints(), new Entrypoints(),
new DialogEventComponent(this), new DialogEventComponent(this)
...topPaneWidgets,
leftPaneContainer,
...centerPaneWidgets,
rightPaneContainer,
sidePaneTogglesWidget
]; ];
if (utils.isElectron()) { if (utils.isElectron()) {
@ -207,6 +184,8 @@ class AppContext {
import("./spell_check.js").then(spellCheckService => spellCheckService.initSpellCheck()); import("./spell_check.js").then(spellCheckService => spellCheckService.initSpellCheck());
} }
this.trigger('initialRenderComplete');
} }
trigger(name, data, sync = false) { trigger(name, data, sync = false) {

View File

@ -0,0 +1,29 @@
import BasicWidget from "./basic_widget.js";
export default class FlexContainer extends BasicWidget {
constructor(appContext, attrs, widgets) {
super(appContext);
this.attrs = attrs;
this.children = widgets;
}
render() {
this.$widget = $(`<div style="display: flex;">`);
for (const key in this.attrs) {
if (key === 'id') {
this.$widget.attr(key, this.attrs[key]);
}
else {
this.$widget.css(key, this.attrs[key]);
}
}
for (const widget of this.children) {
this.$widget.append(widget.render());
}
return this.$widget;
}
}

View File

@ -1,19 +0,0 @@
import BasicWidget from "./basic_widget.js";
export default class RowFlexContainer extends BasicWidget {
constructor(appContext, widgets) {
super(appContext);
this.children = widgets;
}
render() {
this.$widget = $(`<div style="display: flex; flex-direction: row;">`);
for (const widget of this.children) {
this.$widget.append(widget.render());
}
return this.$widget;
}
}

View File

@ -47,8 +47,6 @@ export default class SidePaneToggles extends BasicWidget {
this.$widget.find(".show-left-pane-button").on('click', () => this.toggleAndSave('left', true)); this.$widget.find(".show-left-pane-button").on('click', () => this.toggleAndSave('left', true));
this.$widget.find(".hide-left-pane-button").on('click', () => this.toggleAndSave('left', false)); this.$widget.find(".hide-left-pane-button").on('click', () => this.toggleAndSave('left', false));
splitService.setupSplit(this.paneVisible.left, this.paneVisible.right);
return this.$widget; return this.$widget;
} }
@ -69,4 +67,8 @@ export default class SidePaneToggles extends BasicWidget {
this.trigger('sidebarVisibilityChanged', {side, show}); this.trigger('sidebarVisibilityChanged', {side, show});
} }
initialRenderCompleteListener() {
splitService.setupSplit(this.paneVisible.left, this.paneVisible.right);
}
} }

View File

@ -10,40 +10,32 @@
<div id="toast-container" class="d-flex flex-column justify-content-center align-items-center"></div> <div id="toast-container" class="d-flex flex-column justify-content-center align-items-center"></div>
<div id="container" style="display: none;"> <div class="dropdown-menu dropdown-menu-sm" id="context-menu-container"></div>
<div id="top-pane"></div>
<div id="main-pane" style="display: flex; flex-grow: 1; flex-shrink: 1; min-height: 0;"> <% include dialogs/about.ejs %>
<div id="center-pane"></div> <% include dialogs/add_link.ejs %>
</div> <% include dialogs/attributes.ejs %>
<% include dialogs/branch_prefix.ejs %>
<div class="dropdown-menu dropdown-menu-sm" id="context-menu-container"></div> <% include dialogs/export.ejs %>
<% include dialogs/import.ejs %>
<% include dialogs/about.ejs %> <% include dialogs/jump_to_note.ejs %>
<% include dialogs/add_link.ejs %> <% include dialogs/markdown_import.ejs %>
<% include dialogs/attributes.ejs %> <% include dialogs/note_revisions.ejs %>
<% include dialogs/branch_prefix.ejs %> <% include dialogs/note_source.ejs %>
<% include dialogs/export.ejs %> <% include dialogs/options.ejs %>
<% include dialogs/import.ejs %> <% include dialogs/protected_session_password.ejs %>
<% include dialogs/jump_to_note.ejs %> <% include dialogs/recent_changes.ejs %>
<% include dialogs/markdown_import.ejs %> <% include dialogs/sql_console.ejs %>
<% include dialogs/note_revisions.ejs %> <% include dialogs/info.ejs %>
<% include dialogs/note_source.ejs %> <% include dialogs/prompt.ejs %>
<% include dialogs/options.ejs %> <% include dialogs/confirm.ejs %>
<% include dialogs/protected_session_password.ejs %> <% include dialogs/help.ejs %>
<% include dialogs/recent_changes.ejs %> <% include dialogs/note_info.ejs %>
<% include dialogs/sql_console.ejs %> <% include dialogs/link_map.ejs %>
<% include dialogs/info.ejs %> <% include dialogs/clone_to.ejs %>
<% include dialogs/prompt.ejs %> <% include dialogs/move_to.ejs %>
<% include dialogs/confirm.ejs %> <% include dialogs/backend_log.ejs %>
<% include dialogs/help.ejs %> <% include dialogs/include_note.ejs %>
<% include dialogs/note_info.ejs %>
<% include dialogs/link_map.ejs %>
<% include dialogs/clone_to.ejs %>
<% include dialogs/move_to.ejs %>
<% include dialogs/backend_log.ejs %>
<% include dialogs/include_note.ejs %>
</div>
<script type="text/javascript"> <script type="text/javascript">
window.baseApiUrl = 'api/'; window.baseApiUrl = 'api/';
@ -88,10 +80,5 @@
<link rel="stylesheet" type="text/css" href="libraries/boxicons/css/boxicons.min.css"> <link rel="stylesheet" type="text/css" href="libraries/boxicons/css/boxicons.min.css">
<script type="text/javascript">
// we hide container initally because otherwise it is rendered first without CSS and then flickers into
// final form which is pretty ugly.
$("#container").show();
</script>
</body> </body>
</html> </html>