1
0

Fixes #34: adding modal panel and refactored API

This commit is contained in:
Zef Hemel 2022-09-30 16:59:57 +02:00
parent 99c1b41d89
commit ac008f54ea
9 changed files with 164 additions and 151 deletions

View File

@ -61,40 +61,17 @@ export function filterBox(
return syscall("editor.filterBox", label, options, helpText, placeHolder); return syscall("editor.filterBox", label, options, helpText, placeHolder);
} }
export function showRhs( export function showPanel(
id: "lhs" | "rhs" | "bhs" | "modal",
mode: number,
html: string, html: string,
script?: string, script: string
flex = 1
): Promise<void> { ): Promise<void> {
return syscall("editor.showRhs", html, script, flex); return syscall("editor.showPanel", id, mode, html, script);
} }
export function hideRhs(): Promise<void> { export function hidePanel(id: "lhs" | "rhs" | "bhs" | "modal"): Promise<void> {
return syscall("editor.hideRhs"); return syscall("editor.hidePanel", id);
}
export function showLhs(
html: string,
script?: string,
flex = 1
): Promise<void> {
return syscall("editor.showLhs", html, script, flex);
}
export function hideLhs(): Promise<void> {
return syscall("editor.hideLhs");
}
export function showBhs(
html: string,
script?: string,
flex = 1
): Promise<void> {
return syscall("editor.showBhs", html, script, flex);
}
export function hideBhs(): Promise<void> {
return syscall("editor.hideBhs");
} }
export function insertAtPos(text: string, pos: number): Promise<void> { export function insertAtPos(text: string, pos: number): Promise<void> {
@ -137,3 +114,43 @@ export function prompt(
export function enableReadOnlyMode(enabled: boolean) { export function enableReadOnlyMode(enabled: boolean) {
return syscall("editor.enableReadOnlyMode", enabled); return syscall("editor.enableReadOnlyMode", enabled);
} }
// DEPRECATED in favor of showPanel and hidePanel
export function showRhs(
html: string,
script?: string,
flex = 1
): Promise<void> {
return syscall("editor.showRhs", html, script, flex);
}
export function hideRhs(): Promise<void> {
return syscall("editor.hideRhs");
}
export function showLhs(
html: string,
script?: string,
flex = 1
): Promise<void> {
return syscall("editor.showLhs", html, script, flex);
}
export function hideLhs(): Promise<void> {
return syscall("editor.hideLhs");
}
export function showBhs(
html: string,
script?: string,
flex = 1
): Promise<void> {
return syscall("editor.showBhs", html, script, flex);
}
export function hideBhs(): Promise<void> {
return syscall("editor.hideBhs");
}
// End deprecation

View File

@ -3,6 +3,7 @@ import {
getText, getText,
hideBhs, hideBhs,
showBhs, showBhs,
showPanel,
} from "@silverbulletmd/plugos-silverbullet-syscall/editor"; } from "@silverbulletmd/plugos-silverbullet-syscall/editor";
import { parseMarkdown } from "@silverbulletmd/plugos-silverbullet-syscall/markdown"; import { parseMarkdown } from "@silverbulletmd/plugos-silverbullet-syscall/markdown";
import { getServerLogs } from "@silverbulletmd/plugos-silverbullet-syscall/sandbox"; import { getServerLogs } from "@silverbulletmd/plugos-silverbullet-syscall/sandbox";
@ -19,7 +20,9 @@ export async function showLogsCommand() {
let clientLogs = await getLogs(); let clientLogs = await getLogs();
let serverLogs = await getServerLogs(); let serverLogs = await getServerLogs();
await showBhs( await showPanel(
"modal",
100,
` `
<style> <style>
#client-log-header { #client-log-header {

View File

@ -2,16 +2,13 @@ import { useEffect, useRef } from "react";
// @ts-ignore // @ts-ignore
import iframeHtml from "bundle-text:./panel.html"; import iframeHtml from "bundle-text:./panel.html";
import { Editor } from "../editor"; import { Editor } from "../editor";
import { PanelConfig } from "../types";
export function Panel({ export function Panel({
html, config,
script,
flex,
editor, editor,
}: { }: {
html: string; config: PanelConfig;
script?: string;
flex: number;
editor: Editor; editor: Editor;
}) { }) {
const iFrameRef = useRef<HTMLIFrameElement>(null); const iFrameRef = useRef<HTMLIFrameElement>(null);
@ -20,8 +17,8 @@ export function Panel({
if (iFrameRef.current?.contentWindow) { if (iFrameRef.current?.contentWindow) {
iFrameRef.current.contentWindow.postMessage({ iFrameRef.current.contentWindow.postMessage({
type: "html", type: "html",
html: html, html: config.html,
script: script, script: config.script,
}); });
} }
} }
@ -34,7 +31,7 @@ export function Panel({
return () => { return () => {
iframe.onload = null; iframe.onload = null;
}; };
}, [html]); }, [config.html, config.script]);
useEffect(() => { useEffect(() => {
let messageListener = (evt: any) => { let messageListener = (evt: any) => {
@ -54,7 +51,7 @@ export function Panel({
}, []); }, []);
return ( return (
<div className="sb-panel" style={{ flex }}> <div className="sb-panel" style={{ flex: config.mode }}>
<iframe srcDoc={iframeHtml} ref={iFrameRef} /> <iframe srcDoc={iframeHtml} ref={iFrameRef} />
</div> </div>
); );

View File

@ -61,7 +61,6 @@ import sandboxSyscalls from "@plugos/plugos/syscalls/sandbox";
import { eventSyscalls } from "@plugos/plugos/syscalls/event"; import { eventSyscalls } from "@plugos/plugos/syscalls/event";
import { storeSyscalls } from "./syscalls/store"; import { storeSyscalls } from "./syscalls/store";
import { inlineImagesPlugin } from "./inline_image"; import { inlineImagesPlugin } from "./inline_image";
import { ConsoleLogger } from "@plugos/plugos/environments/custom_logger";
import { fulltextSyscalls } from "./syscalls/fulltext"; import { fulltextSyscalls } from "./syscalls/fulltext";
class PageState { class PageState {
@ -801,43 +800,42 @@ export class Editor {
dispatch({ type: "show-palette" }); dispatch({ type: "show-palette" });
}} }}
rhs={ rhs={
!!viewState.showRHS && ( !!viewState.panels.rhs.mode && (
<div className="panel" style={{ flex: viewState.showRHS }} /> <div
className="panel"
style={{ flex: viewState.panels.rhs.mode }}
/>
) )
} }
lhs={ lhs={
!!viewState.showLHS && ( !!viewState.panels.lhs.mode && (
<div className="panel" style={{ flex: viewState.showLHS }} /> <div
className="panel"
style={{ flex: viewState.panels.lhs.mode }}
/>
) )
} }
/> />
<div id="sb-main"> <div id="sb-main">
{!!viewState.showLHS && ( {!!viewState.panels.lhs.mode && (
<Panel <Panel config={viewState.panels.lhs} editor={editor} />
html={viewState.lhsHTML}
script={viewState.lhsScript}
flex={viewState.showLHS}
editor={editor}
/>
)} )}
<div id="sb-editor" /> <div id="sb-editor" />
{!!viewState.showRHS && ( {!!viewState.panels.rhs.mode && (
<Panel <Panel config={viewState.panels.rhs} editor={editor} />
html={viewState.rhsHTML}
script={viewState.rhsScript}
flex={viewState.showRHS}
editor={editor}
/>
)} )}
</div> </div>
{!!viewState.showBHS && ( {!!viewState.panels.modal.mode && (
<div
className="sb-modal"
style={{ inset: `${viewState.panels.modal.mode}px` }}
>
<Panel config={viewState.panels.modal} editor={editor} />
</div>
)}
{!!viewState.panels.bhs.mode && (
<div className="sb-bhs"> <div className="sb-bhs">
<Panel <Panel config={viewState.panels.bhs} editor={editor} />
html={viewState.bhsHTML}
script={viewState.bhsScript}
flex={1}
editor={editor}
/>
</div> </div>
)} )}
</> </>

View File

@ -102,48 +102,23 @@ export default function reducer(
...state, ...state,
notifications: state.notifications.filter((n) => n.id !== action.id), notifications: state.notifications.filter((n) => n.id !== action.id),
}; };
case "show-rhs": case "show-panel":
return { return {
...state, ...state,
showRHS: action.flex, panels: {
rhsHTML: action.html, ...state.panels,
rhsScript: action.script, [action.id]: action.config,
},
}; };
case "hide-rhs": case "hide-panel":
return { return {
...state, ...state,
showRHS: 0, panels: {
rhsHTML: "", ...state.panels,
rhsScript: undefined, [action.id]: {},
}; },
case "show-lhs":
return {
...state,
showLHS: action.flex,
lhsHTML: action.html,
lhsScript: action.script,
};
case "hide-lhs":
return {
...state,
showLHS: 0,
lhsHTML: "",
lhsScript: undefined,
};
case "show-bhs":
return {
...state,
showBHS: action.flex,
bhsHTML: action.html,
bhsScript: action.script,
};
case "hide-bhs":
return {
...state,
showBHS: 0,
bhsHTML: "",
bhsScript: undefined,
}; };
case "show-filterbox": case "show-filterbox":
return { return {
...state, ...state,

View File

@ -135,3 +135,20 @@
} }
} }
} }
.sb-modal {
position: absolute;
z-index: 100;
.sb-panel {
height: 100%;
iframe {
border: 0;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
}
}

View File

@ -17,6 +17,11 @@
border-top: rgb(193, 193, 193) 1px solid; border-top: rgb(193, 193, 193) 1px solid;
} }
.sb-modal {
border: 1px solid #000;
background-color: #fff;
}
.sb-notifications { .sb-notifications {
font-family: "iA-Mono"; font-family: "iA-Mono";
} }

View File

@ -27,7 +27,7 @@ function ensureAnchor(expr: any, start: boolean) {
} }
export function editorSyscalls(editor: Editor): SysCallMapping { export function editorSyscalls(editor: Editor): SysCallMapping {
return { const syscalls: SysCallMapping = {
"editor.getCurrentPage": (): string => { "editor.getCurrentPage": (): string => {
return editor.currentPage!; return editor.currentPage!;
}, },
@ -76,44 +76,43 @@ export function editorSyscalls(editor: Editor): SysCallMapping {
): Promise<FilterOption | undefined> => { ): Promise<FilterOption | undefined> => {
return editor.filterBox(label, options, helpText, placeHolder); return editor.filterBox(label, options, helpText, placeHolder);
}, },
"editor.showRhs": (ctx, html: string, script: string, flex: number) => { "editor.showPanel": (
ctx,
id: string,
mode: number,
html: string,
script: string
) => {
editor.viewDispatch({ editor.viewDispatch({
type: "show-rhs", type: "show-panel",
flex, id: id as any,
html, config: { html, script, mode },
script,
}); });
}, },
"editor.hidePanel": (ctx, id: string) => {
editor.viewDispatch({
type: "hide-panel",
id: id as any,
});
},
// Deprecated in favor of using "hidePanel" and "showPanel"
"editor.showRhs": (ctx, html: string, script: string, flex: number) => {
syscalls["editor.showPanel"](ctx, "rhs", flex, html, script);
},
"editor.hideRhs": (ctx) => { "editor.hideRhs": (ctx) => {
editor.viewDispatch({ syscalls["editor.hidePanel"](ctx, "rhs");
type: "hide-rhs",
});
}, },
"editor.showLhs": (ctx, html: string, script: string, flex: number) => { "editor.showLhs": (ctx, html: string, script: string, flex: number) => {
editor.viewDispatch({ syscalls["editor.showPanel"](ctx, "lhs", flex, html, script);
type: "show-lhs",
flex,
html,
script,
});
}, },
"editor.hideLhs": (ctx) => { "editor.hideLhs": (ctx) => {
editor.viewDispatch({ syscalls["editor.hidePanel"](ctx, "lhs");
type: "hide-lhs",
});
}, },
"editor.showBhs": (ctx, html: string, script: string, flex: number) => { "editor.showBhs": (ctx, html: string, script: string, flex: number) => {
editor.viewDispatch({ syscalls["editor.showPanel"](ctx, "bhs", flex, html, script);
type: "show-bhs",
flex,
html,
script,
});
}, },
"editor.hideBhs": (ctx) => { "editor.hideBhs": (ctx) => {
editor.viewDispatch({ syscalls["editor.hidePanel"](ctx, "bhs");
type: "hide-bhs",
});
}, },
"editor.insertAtPos": (ctx, text: string, pos: number) => { "editor.insertAtPos": (ctx, text: string, pos: number) => {
editor.editorView!.dispatch({ editor.editorView!.dispatch({
@ -199,4 +198,6 @@ export function editorSyscalls(editor: Editor): SysCallMapping {
}); });
}, },
}; };
return syscalls;
} }

View File

@ -10,6 +10,14 @@ export type Notification = {
type EditorMode = "ro" | "rw"; type EditorMode = "ro" | "rw";
export type PanelMode = number;
export type PanelConfig = {
mode?: PanelMode;
html?: string;
script?: string;
};
export type AppViewState = { export type AppViewState = {
currentPage?: string; currentPage?: string;
perm: EditorMode; perm: EditorMode;
@ -18,15 +26,7 @@ export type AppViewState = {
showPageNavigator: boolean; showPageNavigator: boolean;
showCommandPalette: boolean; showCommandPalette: boolean;
unsavedChanges: boolean; unsavedChanges: boolean;
showLHS: number; // 0 = hide, > 0 = flex panels: { [key: string]: PanelConfig };
showRHS: number; // 0 = hide, > 0 = flex
showBHS: number;
rhsHTML: string;
lhsHTML: string;
bhsHTML: string;
rhsScript?: string;
lhsScript?: string;
bhsScript?: string;
allPages: Set<PageMeta>; allPages: Set<PageMeta>;
commands: Map<string, AppCommand>; commands: Map<string, AppCommand>;
notifications: Notification[]; notifications: Notification[];
@ -47,12 +47,12 @@ export const initialViewState: AppViewState = {
showPageNavigator: false, showPageNavigator: false,
showCommandPalette: false, showCommandPalette: false,
unsavedChanges: false, unsavedChanges: false,
showLHS: 0, panels: {
showRHS: 0, lhs: {},
showBHS: 0, rhs: {},
rhsHTML: "", bhs: {},
lhsHTML: "", modal: {},
bhsHTML: "", },
allPages: new Set(), allPages: new Set(),
commands: new Map(), commands: new Map(),
recentCommands: new Map(), recentCommands: new Map(),
@ -81,12 +81,12 @@ export type Action =
| { type: "hide-palette" } | { type: "hide-palette" }
| { type: "show-notification"; notification: Notification } | { type: "show-notification"; notification: Notification }
| { type: "dismiss-notification"; id: number } | { type: "dismiss-notification"; id: number }
| { type: "show-rhs"; html: string; flex: number; script?: string } | {
| { type: "hide-rhs" } type: "show-panel";
| { type: "show-lhs"; html: string; flex: number; script?: string } id: "rhs" | "lhs" | "bhs" | "modal";
| { type: "hide-lhs" } config: PanelConfig;
| { type: "show-bhs"; html: string; flex: number; script?: string } }
| { type: "hide-bhs" } | { type: "hide-panel"; id: string }
| { type: "command-run"; command: string } | { type: "command-run"; command: string }
| { | {
type: "show-filterbox"; type: "show-filterbox";