diff --git a/static/css/notes2.css b/static/css/notes2.css index 743b4b3..b4d7e02 100644 --- a/static/css/notes2.css +++ b/static/css/notes2.css @@ -92,7 +92,7 @@ button { border-right: none; } - n2-tree { + n2-sidebar { display: none; } @@ -164,7 +164,7 @@ button { border-right: 1px solid var(--line-color); - n2-tree { + n2-sidebar { .el-treenodes { margin: 24px 32px 32px 32px; } @@ -508,7 +508,7 @@ dialog.op { } #tree { - n2-tree { + n2-sidebar { .el-treenodes { height: calc(100vh - 64px - 64px); margin: 0px; diff --git a/static/js/app.mjs b/static/js/app.mjs index b444140..7a9ac52 100644 --- a/static/js/app.mjs +++ b/static/js/app.mjs @@ -1,16 +1,21 @@ import { ROOT_NODE } from 'node_store' import { CustomHTMLElement } from './lib/custom_html_element.mjs' -import { N2Tree } from 'tree' +import { N2Sidebar } from 'sidebar' import { Node } from 'node' export class App { constructor() {// {{{ this.currentNode = null - this.tree = new N2Tree() + this.sidebar = new N2Sidebar() this.crumbs = new N2Crumbs() this.crumbsElement = document.getElementById('crumbs') this.nodeUI = document.getElementById('note') + this.showNodeEventSequence = new ShowNodeEventSequence() // discard all GO_TO_NODE events + this.sidebar.render().then(sidebar => { + document.getElementById('tree').append(sidebar) + document.getElementById('tree-nodes')?.focus() + }) _mbus.subscribe('TREE_TRUNK_FETCHED', async () => { // Subscribing to the start node existing after the tree trunk is @@ -18,11 +23,8 @@ export class App { // root node itself, and the root node should be selected in the tree // after it is rendered when the site is shown without UUID in the URL. const startNode = await this.getStartNode() - _mbus.subscribe(`NODE_COMPONENT_EXIST_${startNode.UUID}`, () => { - this.goToNode(startNode.UUID, false, false) - }) - document.getElementById('tree').append(await this.tree.render()) + document.getElementById('tree').append(await this.sidebar.render()) document.getElementById('tree-nodes')?.focus() if (startNode.UUID == ROOT_NODE) @@ -85,7 +87,7 @@ export class App { if (document.activeElement.id === 'tree-nodes') { this.nodeUI.takeFocus() } else { - this.tree.focus() + this.sidebar.focus() } break @@ -184,17 +186,38 @@ export class App { node.reset() // any modifications are discarded. this.currentNode = node - this.tree.setSelected(node, dontExpand) + this.sidebar.setSelected(node, dontExpand) const ancestors = await nodeStore.getNodeAncestry(node) - _mbus.dispatch('CRUMBS_SET', ancestors, () => this.crumbsElement.replaceChildren(this.crumbs.render())) - _mbus.dispatch('NODE_UI_OPEN', node) - _mbus.dispatch('NODE_UNMODIFIED') - _mbus.dispatch('TREE_EXPANSION', { expand: false, when: 'narrow' }) // Scrolls node into view. - this.tree.makeVisible(node) + // makeVisible normally expands all ancestor nodes to make the whole chain visible. + // This is a bad idea when quickly navigating the tree, since the arrow navigation + // has collapsed nodes which the event calling goToNode can come to undo, if the + // event processing lags behind. + await this.sidebar.makeVisible(node, ancestors, dontExpand) + + _mbus.dispatch('CRUMBS_SET', ancestors, () => this.crumbsElement.replaceChildren(this.crumbs.render())) + _mbus.dispatch('NODE_UI_OPEN', { node, eventSequence: this.showNodeEventSequence.next() }) + _mbus.dispatch('TREE_EXPANSION', { expand: false, when: 'narrow' }) + _mbus.dispatch('NODE_UNMODIFIED') }//}}} + pageIsVisible(page) {// {{{ + let classList = document.querySelector('#main-page').classList + return classList.contains(page) + }// }}} +} + +class ShowNodeEventSequence { + constructor() { + this.seq = 0 + } + next() { + return ++this.seq + } + current() { + return this.seq + } } class N2Crumbs extends CustomHTMLElement { diff --git a/static/js/node_store.mjs b/static/js/node_store.mjs index bd2a331..3bd2701 100644 --- a/static/js/node_store.mjs +++ b/static/js/node_store.mjs @@ -199,9 +199,7 @@ export class NodeStore { } Promise.all(hasChildrenPromises) - .then(() => { - resolve(nodes) - }) + .then(() => resolve(nodes)) } req.onerror = (event) => reject(event.target.error) }) diff --git a/static/js/page_history.mjs b/static/js/page_history.mjs index b03c810..44061f6 100644 --- a/static/js/page_history.mjs +++ b/static/js/page_history.mjs @@ -80,8 +80,11 @@ export class N2PageHistory extends CustomHTMLElement { }) - _mbus.subscribe('NODE_UI_OPEN', async (event) => { - await this.useNode(event.detail.data) + _mbus.subscribe('SHOW_PAGE', async (event) => { + if(event.detail.data.page != 'history') + return + + await this.useNode(_app.nodeUI.node) this.render() }) diff --git a/static/js/page_node.mjs b/static/js/page_node.mjs index 9a82b90..a2ebf52 100644 --- a/static/js/page_node.mjs +++ b/static/js/page_node.mjs @@ -42,7 +42,8 @@ export class N2PageNodeUI extends CustomHTMLElement { this.marked = new MarkedPosition() _mbus.subscribe('NODE_UI_OPEN', event => { - this.node = event.detail.data + console.log(event.detail.data.eventSequence, _app.showNodeEventSequence.current()) + this.node = event.detail.data.node this.showMarkdown(true) this.render() }) @@ -376,10 +377,6 @@ export class Node { this.Children[i]._parent = this } - // Notify the tree that all children are fetched and ready to process. - //_notes2.current.tree.fetchChildrenOn(this.UUID) - _mbus.dispatch(`NODE_CHILDREN_FETCHED_${this.UUID}`) - return this.Children }//}}} setHasChildren(v) {// {{{ diff --git a/static/js/tree.mjs b/static/js/sidebar.mjs similarity index 86% rename from static/js/tree.mjs rename to static/js/sidebar.mjs index 6443455..d1263a3 100644 --- a/static/js/tree.mjs +++ b/static/js/sidebar.mjs @@ -1,7 +1,6 @@ import { ROOT_NODE } from 'node_store' import { CustomHTMLElement } from './lib/custom_html_element.mjs' import { Color, Solver } from './lib/css_colorize.mjs' -import { Node } from './page_node.mjs' // TreeExpandedHandler is responsible for collapsing or expanding // the node tree, wide view or narrow "mobile" view. @@ -59,12 +58,12 @@ class TreeExpansionHandler {// {{{ } }// }}} -export class N2Tree extends CustomHTMLElement { +export class N2Sidebar extends CustomHTMLElement { static {// {{{ this.tmpl = document.createElement('template') this.tmpl.innerHTML = `