From 7111fb6b1ee0bdd69649a57d3d0bec237f6b5221 Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Tue, 2 Aug 2022 12:43:39 +0200 Subject: [PATCH] Make index page configurable --- packages/common/package.json | 3 ++- packages/common/util.ts | 16 +++++++++++++++ packages/plugs/core/core.plug.yaml | 2 +- packages/plugs/core/page.ts | 4 ++-- packages/server/SETTINGS_template.md | 4 ++++ packages/server/express_server.ts | 29 ++++++++++++++++++++++------ packages/web/boot.ts | 14 +++++++++++--- packages/web/editor.tsx | 20 ++++++++++++------- packages/web/navigator.ts | 12 ++++++++---- packages/web/syscalls/space.ts | 2 +- 10 files changed, 81 insertions(+), 25 deletions(-) create mode 100644 packages/server/SETTINGS_template.md diff --git a/packages/common/package.json b/packages/common/package.json index 82c3ba69..a59be073 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -18,6 +18,7 @@ "@codemirror/view": "^6.0.0", "@lezer/common": "1.0.0", "@lezer/highlight": "1.0.0", - "@lezer/markdown": "1.0.1" + "@lezer/markdown": "1.0.1", + "yaml": "^1.10.2" } } diff --git a/packages/common/util.ts b/packages/common/util.ts index 5f8b3ddd..6be4781f 100644 --- a/packages/common/util.ts +++ b/packages/common/util.ts @@ -1,3 +1,5 @@ +import YAML from "yaml"; + export function safeRun(fn: () => Promise) { fn().catch((e) => { console.error(e); @@ -19,3 +21,17 @@ export function throttle(func: () => void, limit: number) { } }; } + +// TODO: This is naive, may be better to use a proper parser +const yamlSettingsRegex = /```yaml([^`]+)```/; + +export function parseYamlSettings(settingsMarkdown: string): { + [key: string]: any; +} { + const match = yamlSettingsRegex.exec(settingsMarkdown); + if (!match) { + return {}; + } + const yaml = match[1]; + return YAML.parse(yaml); +} diff --git a/packages/plugs/core/core.plug.yaml b/packages/plugs/core/core.plug.yaml index 5404932f..ff7aa3ee 100644 --- a/packages/plugs/core/core.plug.yaml +++ b/packages/plugs/core/core.plug.yaml @@ -107,7 +107,7 @@ functions: command: name: "Navigate: Home" key: "Alt-h" - page: "index" + page: "" # Hashtags indexTags: diff --git a/packages/plugs/core/page.ts b/packages/plugs/core/page.ts index 335961d8..339a5bf9 100644 --- a/packages/plugs/core/page.ts +++ b/packages/plugs/core/page.ts @@ -101,7 +101,7 @@ export async function linkQueryProvider({ export async function deletePage() { let pageName = await getCurrentPage(); console.log("Navigating to index page"); - await navigate("index"); + await navigate(""); console.log("Deleting page from space"); await deletePageSyscall(pageName); } @@ -201,7 +201,7 @@ export async function reindexCommand() { // Completion export async function pageComplete() { - let prefix = await matchBefore("\\[\\[[\\w\\s]*"); + let prefix = await matchBefore("\\[\\[[^\\]]*"); if (!prefix) { return null; } diff --git a/packages/server/SETTINGS_template.md b/packages/server/SETTINGS_template.md new file mode 100644 index 00000000..af07af71 --- /dev/null +++ b/packages/server/SETTINGS_template.md @@ -0,0 +1,4 @@ +This page contains settings for configuring SilverBullet and its plugs. Any changes outside of the yaml block will be overwritten. +```yaml +indexPage: index +``` \ No newline at end of file diff --git a/packages/server/express_server.ts b/packages/server/express_server.ts index b6da35b9..cda6c268 100644 --- a/packages/server/express_server.ts +++ b/packages/server/express_server.ts @@ -30,8 +30,8 @@ import { systemSyscalls } from "./syscalls/system"; import { plugPrefix } from "@silverbulletmd/common/spaces/constants"; import sandboxSyscalls from "@plugos/plugos/syscalls/sandbox"; - -// import globalModules from "../common/dist/global.plug.json"; +// @ts-ignore +import settingsTemplate from "bundle-text:./SETTINGS_TEMPLATE.md"; const globalModules: any = JSON.parse( readFileSync( @@ -53,6 +53,7 @@ import { storeSyscalls, ensureTable as ensureStoreTable, } from "@plugos/plugos/syscalls/store.knex_node"; +import { parseYamlSettings } from "@silverbulletmd/common/util"; const safeFilename = /^[a-zA-Z0-9_\-\.]+$/; @@ -74,6 +75,7 @@ export class ExpressServer { private server?: Server; builtinPlugDir: string; password?: string; + settings: { [key: string]: any } = {}; constructor(options: ServerOptions) { this.port = options.port; @@ -268,7 +270,7 @@ export class ExpressServer { await ensureIndexTable(this.db); await ensureStoreTable(this.db, "store"); await ensureFTSTable(this.db, "fts"); - await this.ensureIndexPage(); + await this.ensureAndLoadSettings(); // Serve static files (javascript, css, html) this.app.use("/", express.static(this.distDir)); @@ -444,11 +446,26 @@ export class ExpressServer { }); } - async ensureIndexPage() { + async ensureAndLoadSettings() { try { - await this.space.getPageMeta("index"); + await this.space.getPageMeta("SETTINGS"); } catch (e) { - await this.space.writePage("index", `Welcome to your new space!`); + await this.space.writePage("SETTINGS", settingsTemplate, true); + } + + let { text: settingsText } = await this.space.readPage("SETTINGS"); + this.settings = parseYamlSettings(settingsText); + if (!this.settings.indexPage) { + this.settings.indexPage = "index"; + } + + try { + await this.space.getPageMeta(this.settings.indexPage); + } catch (e) { + await this.space.writePage( + this.settings.indexPage, + `Welcome to your new space!` + ); } } diff --git a/packages/web/boot.ts b/packages/web/boot.ts index 9afdf699..03104936 100644 --- a/packages/web/boot.ts +++ b/packages/web/boot.ts @@ -1,5 +1,5 @@ import { Editor } from "./editor"; -import { safeRun } from "@silverbulletmd/common/util"; +import { parseYamlSettings, safeRun } from "@silverbulletmd/common/util"; import { Space } from "@silverbulletmd/common/spaces/space"; import { HttpSpacePrimitives } from "@silverbulletmd/common/spaces/http_space_primitives"; @@ -8,9 +8,10 @@ safeRun(async () => { localStorage.getItem("password") || undefined; let httpPrimitives = new HttpSpacePrimitives("", password); + let settingsPageText = ""; while (true) { try { - await httpPrimitives.getPageMeta("index"); + settingsPageText = (await httpPrimitives.readPage("SETTINGS")).text; break; } catch (e: any) { if (e.message === "Unauthorized") { @@ -29,7 +30,14 @@ safeRun(async () => { console.log("Booting..."); - let editor = new Editor(serverSpace, document.getElementById("sb-root")!, ""); + let settings = parseYamlSettings(settingsPageText); + + let editor = new Editor( + serverSpace, + document.getElementById("sb-root")!, + "", + settings.indexPage || "index" + ); await editor.init(); // @ts-ignore window.editor = editor; diff --git a/packages/web/editor.tsx b/packages/web/editor.tsx index 1a4d16dc..715b387e 100644 --- a/packages/web/editor.tsx +++ b/packages/web/editor.tsx @@ -114,12 +114,19 @@ export class Editor { private system = new System("client"); private mdExtensions: MDExt[] = []; urlPrefix: string; + indexPage: string; - constructor(space: Space, parent: Element, urlPrefix: string) { + constructor( + space: Space, + parent: Element, + urlPrefix: string, + indexPage: string + ) { this.space = space; this.urlPrefix = urlPrefix; this.viewState = initialViewState; this.viewDispatch = () => {}; + this.indexPage = indexPage; // Event hook this.eventHook = new EventHook(); @@ -146,7 +153,7 @@ export class Editor { state: this.createEditorState("", ""), parent: document.getElementById("sb-editor")!, }); - this.pageNavigator = new PathPageNavigator(urlPrefix); + this.pageNavigator = new PathPageNavigator(indexPage, urlPrefix); this.system.registerSyscalls( [], @@ -242,11 +249,7 @@ export class Editor { }, }); - if (this.pageNavigator.getCurrentPage() === "") { - await this.pageNavigator.navigate("index"); - } await this.reloadPlugs(); - await this.dispatchAppEvent("editor:init"); } @@ -558,6 +561,9 @@ export class Editor { } async navigate(name: string, pos?: number, replaceState = false) { + if (!name) { + name = this.indexPage; + } await this.pageNavigator.navigate(name, pos, replaceState); } @@ -712,7 +718,7 @@ export class Editor { dispatch({ type: "start-navigate" }); }} onHomeClick={() => { - editor.navigate("index"); + editor.navigate(""); }} onActionClick={() => { dispatch({ type: "show-palette" }); diff --git a/packages/web/navigator.ts b/packages/web/navigator.ts index 220150b9..265ad84f 100644 --- a/packages/web/navigator.ts +++ b/packages/web/navigator.ts @@ -11,20 +11,24 @@ function decodePageUrl(url: string): string { export class PathPageNavigator { navigationResolve?: () => void; - constructor(readonly root: string = "") {} + constructor(readonly indexPage: string, readonly root: string = "") {} async navigate(page: string, pos?: number, replaceState = false) { + let encodedPage = encodePageUrl(page); + if (page === this.indexPage) { + encodedPage = ""; + } if (replaceState) { window.history.replaceState( { page, pos }, page, - `${this.root}/${encodePageUrl(page)}` + `${this.root}/${encodedPage}` ); } else { window.history.pushState( { page, pos }, page, - `${this.root}/${encodePageUrl(page)}` + `${this.root}/${encodedPage}` ); } window.dispatchEvent( @@ -75,7 +79,7 @@ export class PathPageNavigator { } getCurrentPage(): string { - return decodePageUrl(this.decodeURI()[0]); + return decodePageUrl(this.decodeURI()[0]) || this.indexPage; } getCurrentPos(): number { diff --git a/packages/web/syscalls/space.ts b/packages/web/syscalls/space.ts index fd2935bc..3a23b760 100644 --- a/packages/web/syscalls/space.ts +++ b/packages/web/syscalls/space.ts @@ -23,7 +23,7 @@ export function spaceSyscalls(editor: Editor): SysCallMapping { "space.deletePage": async (ctx, name: string) => { // If we're deleting the current page, navigate to the index page if (editor.currentPage === name) { - await editor.navigate("index"); + await editor.navigate(""); } // Remove page from open pages in editor editor.openPages.delete(name);