diff --git a/packages/plugos-silverbullet-syscall/editor.ts b/packages/plugos-silverbullet-syscall/editor.ts index d8337496..740731c1 100644 --- a/packages/plugos-silverbullet-syscall/editor.ts +++ b/packages/plugos-silverbullet-syscall/editor.ts @@ -133,3 +133,7 @@ export function prompt( ): Promise { return syscall("editor.prompt", message, defaultValue); } + +export function enableReadOnlyMode(enabled: boolean) { + return syscall("editor.enableReadOnlyMode", enabled); +} diff --git a/packages/plugs/core/cloud.ts b/packages/plugs/core/cloud.ts index 78d441e8..bef8d080 100644 --- a/packages/plugs/core/cloud.ts +++ b/packages/plugs/core/cloud.ts @@ -6,7 +6,7 @@ import { renderToText, replaceNodesMatching, } from "@silverbulletmd/common/tree"; -import type { FileMeta, PageMeta } from "@silverbulletmd/common/types"; +import type { FileMeta } from "@silverbulletmd/common/types"; import { parseMarkdown } from "@silverbulletmd/plugos-silverbullet-syscall/markdown"; const pagePrefix = "💭 "; diff --git a/packages/plugs/core/core.plug.yaml b/packages/plugs/core/core.plug.yaml index db06363e..79ceb699 100644 --- a/packages/plugs/core/core.plug.yaml +++ b/packages/plugs/core/core.plug.yaml @@ -46,6 +46,16 @@ functions: path: "./page.ts:deletePage" command: name: "Page: Delete" + + editorLoad: + path: "./editor.ts:editorLoad" + events: + - plugs:loaded + toggleReadOnlyode: + path: "./editor.ts:toggleReadOnlyMode" + command: + name: "Editor: Toggle Read Only Mode" + # Backlinks indexLinks: path: "./page.ts:indexLinks" diff --git a/packages/plugs/core/editor.ts b/packages/plugs/core/editor.ts new file mode 100644 index 00000000..61da2d92 --- /dev/null +++ b/packages/plugs/core/editor.ts @@ -0,0 +1,16 @@ +import * as clientStore from "@silverbulletmd/plugos-silverbullet-syscall/clientStore"; +import { enableReadOnlyMode } from "@silverbulletmd/plugos-silverbullet-syscall/editor"; + +export async function editorLoad() { + let readOnlyMode = await clientStore.get("readOnlyMode"); + if (readOnlyMode) { + await enableReadOnlyMode(true); + } +} + +export async function toggleReadOnlyMode() { + let readOnlyMode = await clientStore.get("readOnlyMode"); + readOnlyMode = !readOnlyMode; + await enableReadOnlyMode(readOnlyMode); + await clientStore.set("readOnlyMode", readOnlyMode); +} diff --git a/packages/web/editor.tsx b/packages/web/editor.tsx index dc5b409f..bb45e64a 100644 --- a/packages/web/editor.tsx +++ b/packages/web/editor.tsx @@ -658,7 +658,10 @@ export class Editor { contentDOM.spellcheck = true; contentDOM.setAttribute("autocorrect", "on"); contentDOM.setAttribute("autocapitalize", "on"); - contentDOM.setAttribute("contenteditable", readOnly ? "false" : "true"); + contentDOM.setAttribute( + "contenteditable", + readOnly || this.viewState.forcedROMode ? "false" : "true" + ); if (isMobileSafari() && readOnly) { console.log("Safari read only hack"); @@ -720,6 +723,15 @@ export class Editor { } }, [viewState.currentPage]); + useEffect(() => { + if (editor.editorView) { + editor.tweakEditorDOM( + editor.editorView.contentDOM, + viewState.perm === "ro" + ); + } + }, [viewState.forcedROMode]); + return ( <> {viewState.showPageNavigator && ( diff --git a/packages/web/reducer.ts b/packages/web/reducer.ts index 0d26fcae..6a9aff2f 100644 --- a/packages/web/reducer.ts +++ b/packages/web/reducer.ts @@ -163,6 +163,11 @@ export default function reducer( filterBoxOptions: [], filterBoxHelpText: "", }; + case "set-editor-ro": + return { + ...state, + forcedROMode: action.enabled, + }; } return state; } diff --git a/packages/web/syscalls/editor.ts b/packages/web/syscalls/editor.ts index 92f124d9..3dbbda63 100644 --- a/packages/web/syscalls/editor.ts +++ b/packages/web/syscalls/editor.ts @@ -192,5 +192,11 @@ export function editorSyscalls(editor: Editor): SysCallMapping { ): string | null => { return prompt(message, defaultValue); }, + "editor.enableReadOnlyMode": (ctx, enabled: boolean) => { + editor.viewDispatch({ + type: "set-editor-ro", + enabled, + }); + }, }; } diff --git a/packages/web/types.ts b/packages/web/types.ts index f7584781..8d305f54 100644 --- a/packages/web/types.ts +++ b/packages/web/types.ts @@ -8,10 +8,12 @@ export type Notification = { date: Date; }; +type EditorMode = "ro" | "rw"; + export type AppViewState = { currentPage?: string; - perm: "ro" | "rw"; - + perm: EditorMode; + forcedROMode: boolean; isLoading: boolean; showPageNavigator: boolean; showCommandPalette: boolean; @@ -40,6 +42,7 @@ export type AppViewState = { export const initialViewState: AppViewState = { perm: "rw", + forcedROMode: false, isLoading: false, showPageNavigator: false, showCommandPalette: false, @@ -93,4 +96,5 @@ export type Action = label: string; onSelect: (option: FilterOption | undefined) => void; } - | { type: "hide-filterbox" }; + | { type: "hide-filterbox" } + | { type: "set-editor-ro"; enabled: boolean };