diff --git a/config.yaml b/config.yaml index 2a73f9c..0a46a05 100644 --- a/config.yaml +++ b/config.yaml @@ -4,13 +4,12 @@ language: en vault: root: public - cleanup: true - -view: - index: - notfound: + cleanup: false metadata: hidden: - example - foo/bar.md + routes: + index: + error: diff --git a/src/scripts/app.js b/src/scripts/app.js index c65498c..79917cf 100644 --- a/src/scripts/app.js +++ b/src/scripts/app.js @@ -1,6 +1,6 @@ import { Engine } from './search' import { Index, State } from './object' -import router, { Routes } from './router' +import router from './router' import zettelkasten from './zettelkasten' import { marked } from 'marked' @@ -60,6 +60,21 @@ export default () => ({ `; } + + fallback() { + this.value = ` +
+
+ + + +
+ NOT FOUND +
+
+
+ `; + } }, graph: new class extends State { @@ -80,8 +95,8 @@ export default () => ({ >
@@ -140,43 +155,41 @@ export default () => ({ async init() { this.content.transition(async () => { this.index = await Index.fromPack(); - this.router.start(); - console.log(this.index); + this.content.value = ''; // clear init state + this.load.apply(this); + + this.router.start(this.index.metadata.routes); }); - Routes.index = () => { - let [url, view] = this.index.createView(); + this.router.route = (path) => { + let view = this.index.getObject(path); - this.graph.transition(async () => { - const { Engine } = await import('./graph'); - let engine = Engine.fromIndex(this.index); - - return engine.createInstance(url); - }); - - this.navigation.transition(() => { - let [tree, searchable] = this.index.createTree(); - let search = this.search.engine.getInstance(); - - search.addAllAsync(searchable); - return tree.render(false); - }); - - this.content.transition(() => { - return view?.render() ?? ''; - }); - - return url; + this.content.value = view?.render(); + return Boolean(view); } - Routes.other = path => { - this.content.transition(() => { - let [,view] = this.index.createView(path); - return view.render(); - }); - } + this.router.on('error', () => { + this.content.fallback(); + }); marked.use(zettelkasten()); }, + async load() { + this.graph.transition(async () => { + const { Engine } = await import('./graph'); + let engine = Engine.fromIndex(this.index); + let node = engine.createInstance(); + + return node; + }); + + this.navigation.transition(() => { + let [tree, searchable] = this.index.createTree(); + let search = this.search.engine.getInstance(); + + search.addAllAsync(searchable); + return tree.render(false); + }); + } }) diff --git a/src/scripts/graph.js b/src/scripts/graph.js index 1fd649e..45b91cc 100644 --- a/src/scripts/graph.js +++ b/src/scripts/graph.js @@ -48,7 +48,7 @@ export class Engine { return new Engine(graph); } - createInstance(url) { + createInstance() { let settings = { allowInvalidContainer: true }; let container = document.createElement('div'); @@ -59,9 +59,8 @@ export class Engine { this.setupInteraction(); this.setupGraphStyle(); - let camera = this.instance.getCamera(); - router.emit('retrieve', { path: url }); - camera.animate({ ratio: 1 }, { easing: "linear", duration: 200 }); + let path = router.last('retrieve')?.params?.path; + setTimeout(() => router.emit('retrieve', { path }), 500); return container; } @@ -201,6 +200,12 @@ export class Engine { }); } + panover(path) { + let camera = this.instance.getCamera(); + router.emit('graphview update', { path }); + camera.animate({ ratio: 0.5 }, { easing: "linear", duration: 200 }); + } + dispose() { this.layout.kill(); this.instance.kill(); diff --git a/src/scripts/object.js b/src/scripts/object.js index cb9d8d0..6936dfb 100644 --- a/src/scripts/object.js +++ b/src/scripts/object.js @@ -53,9 +53,8 @@ class BaseNode extends BaseObject { } export class Index extends BaseObject { - constructor(view, metadata, object, links = {}) { + constructor(metadata, object, links = {}) { super(); - this.view = view; this.metadata = metadata; this.object = object; this.links = links; @@ -64,13 +63,7 @@ export class Index extends BaseObject { static Metadata(x) { return { hidden: x?.hidden, - } - } - - static View(x) { - return { - index: x?.index, - notfound: x?.notfound + routes: x?.routes, } } @@ -151,27 +144,6 @@ export class Index extends BaseObject { return [root, searchable]; } - - createView(path = '') { - let entry = this.getObject(path); - let view = this.view; - - if (! path) { - path = view.index ?? ''; - entry = this.getObject(path); - - if (!entry) return [path, Document.Blank()]; - } - - if (! entry) { - path = view.notfound ?? ''; - entry = this.getObject(path); - - if (!entry) return [path, Document.NotFound()]; - } - - return [path, entry]; - } } export class Folder extends BaseNode { @@ -242,10 +214,12 @@ export class Folder extends BaseNode { return `
{ let isFromNav = navigate; + let path = window.location.pathname; + active?.setAttribute('data-active', false); - active = $el.querySelector(\`[data-path="\${url}"]\`); + active = $el.querySelector(\`[data-path="\${path}"]\`); active?.setAttribute('data-active', true); if (isFromNav) return; @@ -278,29 +252,6 @@ export class Document extends BaseNode { this.links = []; } - static NotFound() { - return { - render: () => ` -
-
- - - -
- NOT FOUND -
-
-
- ` - } - } - - static Blank() { - return { - render: () => '' - } - } - fullname() { return this.name + '.md'; } @@ -312,13 +263,7 @@ export class Document extends BaseNode { let title = this.metadata.title ?? this.name; document.title = `${title} - ${appName}`; - return ` -
-
${title}
-
- ${marked(this.content)} -
-
+ let sidebar = () => `