More caching, first tree navigation with up/down.
This commit is contained in:
parent
0bd5d08edf
commit
82f09dcb1d
8 changed files with 317 additions and 151 deletions
|
@ -27,7 +27,7 @@ html {
|
||||||
display: grid;
|
display: grid;
|
||||||
position: relative;
|
position: relative;
|
||||||
justify-items: center;
|
justify-items: center;
|
||||||
margin-bottom: 32px;
|
margin-bottom: 8px;
|
||||||
margin-left: 24px;
|
margin-left: 24px;
|
||||||
margin-right: 24px;
|
margin-right: 24px;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,11 @@ html {
|
||||||
width: 128px;
|
width: 128px;
|
||||||
left: -20px;
|
left: -20px;
|
||||||
}
|
}
|
||||||
|
#tree .icons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
#tree .node {
|
#tree .node {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 24px min-content;
|
grid-template-columns: 24px min-content;
|
||||||
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 121 KiB |
49
static/images/icon_refresh.svg
Normal file
49
static/images/icon_refresh.svg
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="4.2333398mm"
|
||||||
|
height="5.8208399mm"
|
||||||
|
viewBox="0 0 4.2333398 5.8208399"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:version="1.3.2 (091e20e, 2023-11-25)"
|
||||||
|
sodipodi:docname="icon_refresh.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#9e9e9e"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:zoom="0.83651094"
|
||||||
|
inkscape:cx="7.7703706"
|
||||||
|
inkscape:cy="11.356695"
|
||||||
|
inkscape:window-width="1916"
|
||||||
|
inkscape:window-height="1161"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs1" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-102.65833,-145.52083)">
|
||||||
|
<title
|
||||||
|
id="title1">sync</title>
|
||||||
|
<path
|
||||||
|
d="m 104.775,150.01875 a 1.5875,1.5875 0 0 1 -1.5875,-1.5875 c 0,-0.26458 0.0661,-0.52123 0.18521,-0.74083 l -0.38629,-0.3863 c -0.20638,0.32544 -0.32809,0.71173 -0.32809,1.12713 a 2.1166667,2.1166667 0 0 0 2.11667,2.11667 v 0.79375 l 1.05833,-1.05834 -1.05833,-1.05833 m 0,-2.91042 v -0.79375 l -1.05833,1.05834 1.05833,1.05833 v -0.79375 a 1.5875,1.5875 0 0 1 1.5875,1.5875 c 0,0.26458 -0.0661,0.52123 -0.18521,0.74083 l 0.38629,0.38629 c 0.20638,-0.32543 0.32809,-0.71172 0.32809,-1.12712 a 2.1166667,2.1166667 0 0 0 -2.11667,-2.11667 z"
|
||||||
|
id="path1"
|
||||||
|
style="stroke-width:0.264583;fill:#f9f9f9" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -209,6 +209,9 @@ export class NodeUI extends Component {
|
||||||
return
|
return
|
||||||
|
|
||||||
switch (evt.key.toUpperCase()) {
|
switch (evt.key.toUpperCase()) {
|
||||||
|
case 'T':
|
||||||
|
_notes2.current.tree.treeDiv.current?.focus()
|
||||||
|
break
|
||||||
/*
|
/*
|
||||||
case 'C':
|
case 'C':
|
||||||
this.showPage('node')
|
this.showPage('node')
|
||||||
|
@ -342,6 +345,10 @@ export class Node {
|
||||||
this._content = this.data.Content
|
this._content = this.data.Content
|
||||||
this._modified = false
|
this._modified = false
|
||||||
|
|
||||||
|
this._sibling_before = null
|
||||||
|
this._sibling_after = null
|
||||||
|
this._parent = null
|
||||||
|
|
||||||
/*
|
/*
|
||||||
this.RenderMarkdown = signal(nodeData.RenderMarkdown)
|
this.RenderMarkdown = signal(nodeData.RenderMarkdown)
|
||||||
this.Markdown = false
|
this.Markdown = false
|
||||||
|
@ -371,10 +378,45 @@ export class Node {
|
||||||
async fetchChildren() {//{{{
|
async fetchChildren() {//{{{
|
||||||
if (this._children_fetched)
|
if (this._children_fetched)
|
||||||
return this.Children
|
return this.Children
|
||||||
|
|
||||||
|
|
||||||
this.Children = await nodeStore.getTreeNodes(this.UUID, this.Level + 1)
|
this.Children = await nodeStore.getTreeNodes(this.UUID, this.Level + 1)
|
||||||
|
|
||||||
this._children_fetched = true
|
this._children_fetched = true
|
||||||
|
|
||||||
|
// Children are sorted to allow for storing siblings befare and after.
|
||||||
|
// These are used with keyboard navigation in the tree.
|
||||||
|
this.Children.sort(Node.sort)
|
||||||
|
|
||||||
|
const numChildren = this.Children.length
|
||||||
|
for (let i = 0; i < numChildren; i++) {
|
||||||
|
if (i > 0)
|
||||||
|
this.Children[i]._sibling_before = this.Children[i - 1]
|
||||||
|
if (i < numChildren - 1)
|
||||||
|
this.Children[i]._sibling_after = this.Children[i + 1]
|
||||||
|
this.Children[i]._parent = this
|
||||||
|
}
|
||||||
|
|
||||||
return this.Children
|
return this.Children
|
||||||
}//}}}
|
}//}}}
|
||||||
|
hasChildren() {//{{{
|
||||||
|
return this.Children.length > 0
|
||||||
|
}//}}}
|
||||||
|
getSiblingBefore() {// {{{
|
||||||
|
return this._sibling_before
|
||||||
|
}// }}}
|
||||||
|
getSiblingAfter() {// {{{
|
||||||
|
return this._sibling_after
|
||||||
|
}// }}}
|
||||||
|
getParent() {//{{{
|
||||||
|
return this._parent
|
||||||
|
}//}}}
|
||||||
|
isLastSibling() {//{{{
|
||||||
|
return this._sibling_after === null
|
||||||
|
}//}}}
|
||||||
|
isFirstSibling() {//{{{
|
||||||
|
return this._sibling_before === null
|
||||||
|
}//}}}
|
||||||
content() {//{{{
|
content() {//{{{
|
||||||
/* TODO - implement crypto
|
/* TODO - implement crypto
|
||||||
if (this.CryptoKeyID != 0 && !this._decrypted)
|
if (this.CryptoKeyID != 0 && !this._decrypted)
|
||||||
|
|
|
@ -222,10 +222,16 @@ export class NodeStore {
|
||||||
}//}}}
|
}//}}}
|
||||||
async getTreeNodes(parent, newLevel) {//{{{
|
async getTreeNodes(parent, newLevel) {//{{{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
// Parent of toplevel nodes is '' in indexedDB,
|
||||||
|
// but can also be set to the ROOT_NODE uuid.
|
||||||
|
let storeParent = parent
|
||||||
|
if (parent === ROOT_NODE)
|
||||||
|
storeParent = ''
|
||||||
|
|
||||||
const trx = this.db.transaction('nodes', 'readonly')
|
const trx = this.db.transaction('nodes', 'readonly')
|
||||||
const nodeStore = trx.objectStore('nodes')
|
const nodeStore = trx.objectStore('nodes')
|
||||||
const index = nodeStore.index('byParent')
|
const index = nodeStore.index('byParent')
|
||||||
const req = index.getAll(parent)
|
const req = index.getAll(storeParent)
|
||||||
req.onsuccess = (event) => {
|
req.onsuccess = (event) => {
|
||||||
const nodes = []
|
const nodes = []
|
||||||
for (const i in event.target.result) {
|
for (const i in event.target.result) {
|
||||||
|
|
|
@ -47,7 +47,10 @@ export class Notes2 extends Component {
|
||||||
this.setState({ startNode: node })
|
this.setState({ startNode: node })
|
||||||
})
|
})
|
||||||
}//}}}
|
}//}}}
|
||||||
async goToNode(nodeUUID, dontPush) {//{{{
|
async goToNode(nodeUUID, dontPush, dontExpand) {//{{{
|
||||||
|
if (nodeUUID === null || nodeUUID === undefined)
|
||||||
|
return
|
||||||
|
|
||||||
// Don't switch notes until saved.
|
// Don't switch notes until saved.
|
||||||
if (this.nodeUI.current.nodeModified.value) {
|
if (this.nodeUI.current.nodeModified.value) {
|
||||||
if (!confirm("Changes not saved. Do you want to discard changes?"))
|
if (!confirm("Changes not saved. Do you want to discard changes?"))
|
||||||
|
@ -63,7 +66,7 @@ export class Notes2 extends Component {
|
||||||
const ancestors = await nodeStore.getNodeAncestry(node)
|
const ancestors = await nodeStore.getNodeAncestry(node)
|
||||||
this.nodeUI.current.setNode(node)
|
this.nodeUI.current.setNode(node)
|
||||||
this.nodeUI.current.setCrumbs(ancestors)
|
this.nodeUI.current.setCrumbs(ancestors)
|
||||||
this.tree.setSelected(node)
|
this.tree.setSelected(node, dontExpand)
|
||||||
}//}}}
|
}//}}}
|
||||||
logout() {//{{{
|
logout() {//{{{
|
||||||
localStorage.removeItem('session.UUID')
|
localStorage.removeItem('session.UUID')
|
||||||
|
@ -79,6 +82,7 @@ class Tree extends Component {
|
||||||
this.treeTrunk = []
|
this.treeTrunk = []
|
||||||
this.selectedNode = null
|
this.selectedNode = null
|
||||||
this.expandedNodes = {} // keyed on UUID
|
this.expandedNodes = {} // keyed on UUID
|
||||||
|
this.treeDiv = createRef()
|
||||||
|
|
||||||
this.props.app.tree = this
|
this.props.app.tree = this
|
||||||
|
|
||||||
|
@ -90,12 +94,17 @@ class Tree extends Component {
|
||||||
return html`<${TreeNode} key=${`treenode_${node.UUID}`} tree=${this} node=${node} ref=${this.treeNodeComponents[node.UUID]} selected=${node.UUID === app.state.startNode?.UUID} />`
|
return html`<${TreeNode} key=${`treenode_${node.UUID}`} tree=${this} node=${node} ref=${this.treeNodeComponents[node.UUID]} selected=${node.UUID === app.state.startNode?.UUID} />`
|
||||||
})
|
})
|
||||||
return html`
|
return html`
|
||||||
<div id="tree">
|
<div id="tree" ref=${this.treeDiv} tabindex="0">
|
||||||
<div id="logo" onclick=${() => _notes2.current.goToNode(ROOT_NODE)}><img src="/images/${_VERSION}/logo.svg" /></div>
|
<div id="logo" onclick=${() => _notes2.current.goToNode(ROOT_NODE)}><img src="/images/${_VERSION}/logo.svg" /></div>
|
||||||
|
<div class="icons">
|
||||||
|
<img src="/images/${_VERSION}/icon_refresh.svg" />
|
||||||
|
</div>
|
||||||
${renderedTreeTrunk}
|
${renderedTreeTrunk}
|
||||||
</div>`
|
</div>`
|
||||||
}//}}}
|
}//}}}
|
||||||
componentDidMount() {//{{{
|
componentDidMount() {//{{{
|
||||||
|
this.treeDiv.current.addEventListener('keydown', event => this.keyHandler(event))
|
||||||
|
|
||||||
// This will show and select the treenode that is selected in the node UI.
|
// This will show and select the treenode that is selected in the node UI.
|
||||||
const node = _notes2.current?.nodeUI.current?.node.value
|
const node = _notes2.current?.nodeUI.current?.node.value
|
||||||
if (node === null)
|
if (node === null)
|
||||||
|
@ -105,14 +114,14 @@ class Tree extends Component {
|
||||||
}//}}}
|
}//}}}
|
||||||
|
|
||||||
populateFirstLevel(callback = null) {//{{{
|
populateFirstLevel(callback = null) {//{{{
|
||||||
nodeStore.getTreeNodes('', 0)
|
nodeStore.get(ROOT_NODE)
|
||||||
.then(async res => {
|
.then(node => node.fetchChildren())
|
||||||
res.sort(Node.sort)
|
.then(children => {
|
||||||
this.treeNodeComponents = {}
|
this.treeNodeComponents = {}
|
||||||
this.treeTrunk = []
|
this.treeTrunk = []
|
||||||
for (const node of res) {
|
for (const node of children) {
|
||||||
// The root node isn't supposed to be shown in the tree.
|
// The root node isn't supposed to be shown in the tree.
|
||||||
if (node.UUID === '00000000-0000-0000-0000-000000000000')
|
if (node.UUID === ROOT_NODE)
|
||||||
continue
|
continue
|
||||||
if (node.ParentUUID === '')
|
if (node.ParentUUID === '')
|
||||||
this.treeTrunk.push(node)
|
this.treeTrunk.push(node)
|
||||||
|
@ -124,7 +133,7 @@ class Tree extends Component {
|
||||||
})
|
})
|
||||||
.catch(e => { console.log(e); console.log(e.type, e.error); alert(e.error) })
|
.catch(e => { console.log(e); console.log(e.type, e.error); alert(e.error) })
|
||||||
}//}}}
|
}//}}}
|
||||||
setSelected(node) {//{{{
|
setSelected(node, dontExpand) {//{{{
|
||||||
// The previously selected node, if any, needs to be rerendered
|
// The previously selected node, if any, needs to be rerendered
|
||||||
// to not retain its 'selected' class.
|
// to not retain its 'selected' class.
|
||||||
const prevUUID = this.selectedNode?.UUID
|
const prevUUID = this.selectedNode?.UUID
|
||||||
|
@ -135,8 +144,8 @@ class Tree extends Component {
|
||||||
// And now the newly selected node is rerendered.
|
// And now the newly selected node is rerendered.
|
||||||
this.treeNodeComponents[node.UUID]?.current.forceUpdate()
|
this.treeNodeComponents[node.UUID]?.current.forceUpdate()
|
||||||
|
|
||||||
// Expanding selected nodes... I don't know...
|
if (!dontExpand)
|
||||||
this.setNodeExpanded(node.UUID, true)
|
this.setNodeExpanded(node.UUID, true)
|
||||||
}//}}}
|
}//}}}
|
||||||
isSelected(node) {//{{{
|
isSelected(node) {//{{{
|
||||||
return this.selectedNode?.UUID === node.UUID
|
return this.selectedNode?.UUID === node.UUID
|
||||||
|
@ -154,7 +163,7 @@ class Tree extends Component {
|
||||||
return
|
return
|
||||||
|
|
||||||
// Start the chain of by expanding the top node.
|
// Start the chain of by expanding the top node.
|
||||||
this.setNodeExpanded(ancestry[ancestry.length-1].UUID, true)
|
this.setNodeExpanded(ancestry[ancestry.length - 1].UUID, true)
|
||||||
}//}}}
|
}//}}}
|
||||||
getNodeExpanded(UUID) {//{{{
|
getNodeExpanded(UUID) {//{{{
|
||||||
if (this.expandedNodes[UUID] === undefined)
|
if (this.expandedNodes[UUID] === undefined)
|
||||||
|
@ -166,6 +175,95 @@ class Tree extends Component {
|
||||||
this.getNodeExpanded(UUID)
|
this.getNodeExpanded(UUID)
|
||||||
this.expandedNodes[UUID].value = value
|
this.expandedNodes[UUID].value = value
|
||||||
}//}}}
|
}//}}}
|
||||||
|
getParentNodeWithNextSibling(node) {//{{{
|
||||||
|
let currNode = node
|
||||||
|
while (currNode !== null && currNode.UUID !== ROOT_NODE && currNode.getSiblingAfter() === null) {
|
||||||
|
currNode = currNode.getParent()
|
||||||
|
}
|
||||||
|
return currNode?.getSiblingAfter()
|
||||||
|
}//}}}
|
||||||
|
|
||||||
|
async keyHandler(event) {//{{{
|
||||||
|
let handled = true
|
||||||
|
let nodeExpanded = false
|
||||||
|
let siblingBefore = null
|
||||||
|
let siblingExpanded = false
|
||||||
|
let parent = null
|
||||||
|
const n = this.selectedNode
|
||||||
|
|
||||||
|
switch (event.key) {
|
||||||
|
case 'j':
|
||||||
|
case 'ArrowDown':
|
||||||
|
nodeExpanded = this.getNodeExpanded(n.UUID)
|
||||||
|
|
||||||
|
// Last node, not expanded, so it matters not whether it has children or not.
|
||||||
|
// Traverse upward to nearest parent with next sibling.
|
||||||
|
if (!nodeExpanded && n.isLastSibling()) {
|
||||||
|
const wantedNode = this.getParentNodeWithNextSibling(n)
|
||||||
|
if (wantedNode?.UUID === ROOT_NODE)
|
||||||
|
break
|
||||||
|
await _notes2.current.goToNode(wantedNode?.UUID, true, true)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeExpanded && n.isLastSibling() && !n.hasChildren()) {
|
||||||
|
const wantedNode = this.getParentNodeWithNextSibling(n)
|
||||||
|
await _notes2.current.goToNode(wantedNode?.UUID, true, true)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// Node not expanded. Go to this node's next sibling.
|
||||||
|
// GoToNode will abort if given null.
|
||||||
|
if (!nodeExpanded || !n.hasChildren()) {
|
||||||
|
await _notes2.current.goToNode(n.getSiblingAfter()?.UUID, true, true)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Node is expanded.
|
||||||
|
// Children will be visually beneath this node, if any.
|
||||||
|
if (nodeExpanded && n.hasChildren()) {
|
||||||
|
await _notes2.current.goToNode(n.Children[0].UUID, true, true)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'k':
|
||||||
|
case 'ArrowUp':
|
||||||
|
siblingBefore = n.getSiblingBefore()
|
||||||
|
if (siblingBefore !== null)
|
||||||
|
siblingExpanded = this.getNodeExpanded(siblingBefore.UUID)
|
||||||
|
|
||||||
|
if (n.isFirstSibling()) {
|
||||||
|
parent = n.getParent()
|
||||||
|
if (parent?.UUID === ROOT_NODE)
|
||||||
|
break
|
||||||
|
await _notes2.current.goToNode(parent?.UUID, true, true)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (siblingBefore !== null && siblingExpanded && siblingBefore.hasChildren()) {
|
||||||
|
await _notes2.current.goToNode(siblingBefore.Children[siblingBefore.Children.length - 1]?.UUID, true, true)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (siblingBefore) {
|
||||||
|
await _notes2.current.goToNode(siblingBefore.UUID, true, true)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
case 'ArrowLeft':
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
handled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handled) {
|
||||||
|
event.preventDefault()
|
||||||
|
event.stopPropagation()
|
||||||
|
}
|
||||||
|
}//}}}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TreeNode extends Component {
|
class TreeNode extends Component {
|
||||||
|
|
|
@ -50,7 +50,7 @@ html {
|
||||||
display: grid;
|
display: grid;
|
||||||
position: relative;
|
position: relative;
|
||||||
justify-items: center;
|
justify-items: center;
|
||||||
margin-bottom: 32px;
|
margin-bottom: 8px;
|
||||||
margin-left: 24px;
|
margin-left: 24px;
|
||||||
margin-right: 24px;
|
margin-right: 24px;
|
||||||
img {
|
img {
|
||||||
|
@ -60,6 +60,12 @@ html {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
.node {
|
.node {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 24px min-content;
|
grid-template-columns: 24px min-content;
|
||||||
|
|
|
@ -7,19 +7,26 @@ const CACHED_ASSETS = [
|
||||||
'/css/{{ .VERSION }}/notes2.css',
|
'/css/{{ .VERSION }}/notes2.css',
|
||||||
|
|
||||||
'/js/{{ .VERSION }}/lib/preact/preact.mjs',
|
'/js/{{ .VERSION }}/lib/preact/preact.mjs',
|
||||||
'/js/{{ .VERSION }}/lib/htm/htm.mjs',
|
|
||||||
'/js/{{ .VERSION }}/lib/preact/devtools.mjs',
|
'/js/{{ .VERSION }}/lib/preact/devtools.mjs',
|
||||||
'/js/{{ .VERSION }}/lib/signals/signals.mjs',
|
'/js/{{ .VERSION }}/lib/signals/signals.mjs',
|
||||||
'/js/{{ .VERSION }}/lib/signals/signals-core.mjs',
|
'/js/{{ .VERSION }}/lib/signals/signals-core.mjs',
|
||||||
'/js/{{ .VERSION }}/lib/preact/hooks.mjs',
|
'/js/{{ .VERSION }}/lib/preact/hooks.mjs',
|
||||||
|
'/js/{{ .VERSION }}/lib/preact/debug.mjs',
|
||||||
|
'/js/{{ .VERSION }}/lib/htm/htm.mjs',
|
||||||
|
'/js/{{ .VERSION }}/lib/fullcalendar.min.js',
|
||||||
|
'/js/{{ .VERSION }}/lib/node_modules/marked/marked.min.js',
|
||||||
|
'/js/{{ .VERSION }}/lib/sjcl.js',
|
||||||
|
|
||||||
'/js/{{ .VERSION }}/api.mjs',
|
'/js/{{ .VERSION }}/api.mjs',
|
||||||
|
'/js/{{ .VERSION }}/node.mjs',
|
||||||
'/js/{{ .VERSION }}/node_store.mjs',
|
'/js/{{ .VERSION }}/node_store.mjs',
|
||||||
'/js/{{ .VERSION }}/notes2.mjs',
|
'/js/{{ .VERSION }}/notes2.mjs',
|
||||||
|
'/js/{{ .VERSION }}/sync.mjs',
|
||||||
'/js/{{ .VERSION }}/key.mjs',
|
'/js/{{ .VERSION }}/key.mjs',
|
||||||
'/js/{{ .VERSION }}/crypto.mjs',
|
'/js/{{ .VERSION }}/crypto.mjs',
|
||||||
'/js/{{ .VERSION }}/checklist.mjs',
|
'/js/{{ .VERSION }}/checklist.mjs',
|
||||||
|
|
||||||
|
'/images/{{ .VERSION }}/logo.svg',
|
||||||
'/images/{{ .VERSION }}/leaf.svg',
|
'/images/{{ .VERSION }}/leaf.svg',
|
||||||
'/images/{{ .VERSION }}/collapsed.svg',
|
'/images/{{ .VERSION }}/collapsed.svg',
|
||||||
'/images/{{ .VERSION }}/expanded.svg',
|
'/images/{{ .VERSION }}/expanded.svg',
|
||||||
|
|
Loading…
Add table
Reference in a new issue