Editor refactor: extract UI
This commit is contained in:
parent
c5849f881b
commit
e92ed2c5be
@ -1,5 +1,5 @@
|
|||||||
import { safeRun } from "../common/util.ts";
|
import { safeRun } from "../common/util.ts";
|
||||||
import { Editor } from "./editor.tsx";
|
import { Editor } from "./editor.ts";
|
||||||
|
|
||||||
safeRun(async () => {
|
safeRun(async () => {
|
||||||
console.log("Booting");
|
console.log("Booting");
|
||||||
|
@ -10,7 +10,7 @@ import assetSyscalls from "../plugos/syscalls/asset.ts";
|
|||||||
import { eventSyscalls } from "../plugos/syscalls/event.ts";
|
import { eventSyscalls } from "../plugos/syscalls/event.ts";
|
||||||
import { storeSyscalls } from "../plugos/syscalls/store.dexie_browser.ts";
|
import { storeSyscalls } from "../plugos/syscalls/store.dexie_browser.ts";
|
||||||
import { SysCallMapping, System } from "../plugos/system.ts";
|
import { SysCallMapping, System } from "../plugos/system.ts";
|
||||||
import type { Editor } from "./editor.tsx";
|
import type { Editor } from "./editor.ts";
|
||||||
import { CodeWidgetHook } from "./hooks/code_widget.ts";
|
import { CodeWidgetHook } from "./hooks/code_widget.ts";
|
||||||
import { CommandHook } from "./hooks/command.ts";
|
import { CommandHook } from "./hooks/command.ts";
|
||||||
import { SlashCommandHook } from "./hooks/slash_command.ts";
|
import { SlashCommandHook } from "./hooks/slash_command.ts";
|
||||||
@ -74,7 +74,7 @@ export class ClientSystem {
|
|||||||
this.commandHook = new CommandHook();
|
this.commandHook = new CommandHook();
|
||||||
this.commandHook.on({
|
this.commandHook.on({
|
||||||
commandsUpdated: (commandMap) => {
|
commandsUpdated: (commandMap) => {
|
||||||
this.editor.viewDispatch({
|
this.editor.ui.viewDispatch({
|
||||||
type: "update-commands",
|
type: "update-commands",
|
||||||
commands: commandMap,
|
commands: commandMap,
|
||||||
});
|
});
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
syntaxTree,
|
syntaxTree,
|
||||||
WidgetType,
|
WidgetType,
|
||||||
} from "../deps.ts";
|
} from "../deps.ts";
|
||||||
import { Editor } from "../editor.tsx";
|
import { Editor } from "../editor.ts";
|
||||||
import { decoratorStateField, isCursorInRange } from "./util.ts";
|
import { decoratorStateField, isCursorInRange } from "./util.ts";
|
||||||
|
|
||||||
type AdmonitionType = "note" | "warning";
|
type AdmonitionType = "note" | "warning";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { ClickEvent } from "../../plug-api/app_event.ts";
|
import type { ClickEvent } from "../../plug-api/app_event.ts";
|
||||||
import type { Extension } from "../deps.ts";
|
import type { Extension } from "../deps.ts";
|
||||||
import type { Editor } from "../editor.tsx";
|
import type { Editor } from "../editor.ts";
|
||||||
import { blockquotePlugin } from "./block_quote.ts";
|
import { blockquotePlugin } from "./block_quote.ts";
|
||||||
import { admonitionPlugin } from "./admonition.ts";
|
import { admonitionPlugin } from "./admonition.ts";
|
||||||
import { directivePlugin } from "./directive.ts";
|
import { directivePlugin } from "./directive.ts";
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { commandLinkRegex } from "../../common/markdown_parser/parser.ts";
|
import { commandLinkRegex } from "../../common/markdown_parser/parser.ts";
|
||||||
import { ClickEvent } from "$sb/app_event.ts";
|
import { ClickEvent } from "$sb/app_event.ts";
|
||||||
import { Decoration, syntaxTree } from "../deps.ts";
|
import { Decoration, syntaxTree } from "../deps.ts";
|
||||||
import { Editor } from "../editor.tsx";
|
import { Editor } from "../editor.ts";
|
||||||
import {
|
import {
|
||||||
ButtonWidget,
|
ButtonWidget,
|
||||||
decoratorStateField,
|
decoratorStateField,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { EditorView, syntaxTree, ViewPlugin, ViewUpdate } from "../deps.ts";
|
import { EditorView, syntaxTree, ViewPlugin, ViewUpdate } from "../deps.ts";
|
||||||
import { maximumAttachmentSize } from "../../common/types.ts";
|
import { maximumAttachmentSize } from "../../common/types.ts";
|
||||||
import { Editor } from "../editor.tsx";
|
import { Editor } from "../editor.ts";
|
||||||
|
|
||||||
// We use turndown to convert HTML to Markdown
|
// We use turndown to convert HTML to Markdown
|
||||||
import TurndownService from "https://cdn.skypack.dev/turndown@7.1.1";
|
import TurndownService from "https://cdn.skypack.dev/turndown@7.1.1";
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { WidgetContent } from "../../plug-api/app_event.ts";
|
import { WidgetContent } from "../../plug-api/app_event.ts";
|
||||||
import { panelHtml } from "../components/panel.tsx";
|
import { panelHtml } from "../components/panel.tsx";
|
||||||
import { Decoration, EditorState, syntaxTree, WidgetType } from "../deps.ts";
|
import { Decoration, EditorState, syntaxTree, WidgetType } from "../deps.ts";
|
||||||
import type { Editor } from "../editor.tsx";
|
import type { Editor } from "../editor.ts";
|
||||||
import { CodeWidgetCallback } from "../hooks/code_widget.ts";
|
import { CodeWidgetCallback } from "../hooks/code_widget.ts";
|
||||||
import {
|
import {
|
||||||
decoratorStateField,
|
decoratorStateField,
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
import { decoratorStateField } from "./util.ts";
|
import { decoratorStateField } from "./util.ts";
|
||||||
|
|
||||||
import type { Space } from "../space.ts";
|
import type { Space } from "../space.ts";
|
||||||
import type { Editor } from "../editor.tsx";
|
import type { Editor } from "../editor.ts";
|
||||||
|
|
||||||
class InlineImageWidget extends WidgetType {
|
class InlineImageWidget extends WidgetType {
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
import { renderMarkdownToHtml } from "../../plugs/markdown/markdown_render.ts";
|
import { renderMarkdownToHtml } from "../../plugs/markdown/markdown_render.ts";
|
||||||
import { ParseTree } from "$sb/lib/tree.ts";
|
import { ParseTree } from "$sb/lib/tree.ts";
|
||||||
import { lezerToParseTree } from "../../common/markdown_parser/parse_tree.ts";
|
import { lezerToParseTree } from "../../common/markdown_parser/parse_tree.ts";
|
||||||
import type { Editor } from "../editor.tsx";
|
import type { Editor } from "../editor.ts";
|
||||||
|
|
||||||
class TableViewWidget extends WidgetType {
|
class TableViewWidget extends WidgetType {
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { pageLinkRegex } from "../../common/markdown_parser/parser.ts";
|
import { pageLinkRegex } from "../../common/markdown_parser/parser.ts";
|
||||||
import { ClickEvent } from "../../plug-api/app_event.ts";
|
import { ClickEvent } from "../../plug-api/app_event.ts";
|
||||||
import { Decoration, syntaxTree } from "../deps.ts";
|
import { Decoration, syntaxTree } from "../deps.ts";
|
||||||
import { Editor } from "../editor.tsx";
|
import { Editor } from "../editor.ts";
|
||||||
import {
|
import {
|
||||||
decoratorStateField,
|
decoratorStateField,
|
||||||
invisibleDecoration,
|
invisibleDecoration,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useRef } from "../deps.ts";
|
import { useEffect, useRef } from "../deps.ts";
|
||||||
import { Editor } from "../editor.tsx";
|
import { Editor } from "../editor.ts";
|
||||||
import { PanelConfig } from "../types.ts";
|
import { PanelConfig } from "../types.ts";
|
||||||
|
|
||||||
export const panelHtml = `<!DOCTYPE html>
|
export const panelHtml = `<!DOCTYPE html>
|
||||||
|
@ -54,6 +54,7 @@ import { isValidPageName } from "$sb/lib/page.ts";
|
|||||||
import { ClientSystem } from "./client_system.ts";
|
import { ClientSystem } from "./client_system.ts";
|
||||||
import { createEditorState } from "./editor_state.ts";
|
import { createEditorState } from "./editor_state.ts";
|
||||||
import { OpenPages } from "./open_pages.ts";
|
import { OpenPages } from "./open_pages.ts";
|
||||||
|
import { MainUI } from "./editor_ui.tsx";
|
||||||
const frontMatterRegex = /^---\n(([^\n]|\n)*?)---\n/;
|
const frontMatterRegex = /^---\n(([^\n]|\n)*?)---\n/;
|
||||||
|
|
||||||
const autoSaveInterval = 1000;
|
const autoSaveInterval = 1000;
|
||||||
@ -71,8 +72,6 @@ declare global {
|
|||||||
// TODO: Oh my god, need to refactor this
|
// TODO: Oh my god, need to refactor this
|
||||||
export class Editor {
|
export class Editor {
|
||||||
editorView?: EditorView;
|
editorView?: EditorView;
|
||||||
viewState: AppViewState = initialViewState;
|
|
||||||
viewDispatch: (action: Action) => void = () => {};
|
|
||||||
pageNavigator?: PathPageNavigator;
|
pageNavigator?: PathPageNavigator;
|
||||||
|
|
||||||
space: Space;
|
space: Space;
|
||||||
@ -99,6 +98,8 @@ export class Editor {
|
|||||||
|
|
||||||
// Event bus used to communicate between components
|
// Event bus used to communicate between components
|
||||||
eventHook: EventHook;
|
eventHook: EventHook;
|
||||||
|
|
||||||
|
ui: MainUI;
|
||||||
openPages: OpenPages;
|
openPages: OpenPages;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -184,7 +185,8 @@ export class Editor {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
this.render(parent);
|
this.ui = new MainUI(this);
|
||||||
|
this.ui.render(parent);
|
||||||
|
|
||||||
this.editorView = new EditorView({
|
this.editorView = new EditorView({
|
||||||
state: createEditorState(this, "", "", false),
|
state: createEditorState(this, "", "", false),
|
||||||
@ -211,19 +213,22 @@ export class Editor {
|
|||||||
if (ev.touches.length === 2) {
|
if (ev.touches.length === 2) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
this.viewDispatch({ type: "start-navigate" });
|
this.ui.viewDispatch({ type: "start-navigate" });
|
||||||
}
|
}
|
||||||
// Launch the command palette using a three-finger tap
|
// Launch the command palette using a three-finger tap
|
||||||
if (ev.touches.length === 3) {
|
if (ev.touches.length === 3) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
this.viewDispatch({ type: "show-palette", context: this.getContext() });
|
this.ui.viewDispatch({
|
||||||
|
type: "show-palette",
|
||||||
|
context: this.getContext(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentPage(): string | undefined {
|
get currentPage(): string | undefined {
|
||||||
return this.viewState.currentPage;
|
return this.ui.viewState.currentPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
@ -239,7 +244,7 @@ export class Editor {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
pageListUpdated: (pages) => {
|
pageListUpdated: (pages) => {
|
||||||
this.viewDispatch({
|
this.ui.viewDispatch({
|
||||||
type: "pages-listed",
|
type: "pages-listed",
|
||||||
pages: pages,
|
pages: pages,
|
||||||
});
|
});
|
||||||
@ -338,10 +343,10 @@ export class Editor {
|
|||||||
// Reset for next sync cycle
|
// Reset for next sync cycle
|
||||||
this.system.plugsUpdated = false;
|
this.system.plugsUpdated = false;
|
||||||
|
|
||||||
this.viewDispatch({ type: "sync-change", synced: true });
|
this.ui.viewDispatch({ type: "sync-change", synced: true });
|
||||||
});
|
});
|
||||||
this.eventHook.addLocalListener("sync:error", (name) => {
|
this.eventHook.addLocalListener("sync:error", (name) => {
|
||||||
this.viewDispatch({ type: "sync-change", synced: false });
|
this.ui.viewDispatch({ type: "sync-change", synced: false });
|
||||||
});
|
});
|
||||||
this.eventHook.addLocalListener("sync:conflict", (name) => {
|
this.eventHook.addLocalListener("sync:conflict", (name) => {
|
||||||
this.flashNotification(
|
this.flashNotification(
|
||||||
@ -384,8 +389,8 @@ export class Editor {
|
|||||||
() => {
|
() => {
|
||||||
if (this.currentPage) {
|
if (this.currentPage) {
|
||||||
if (
|
if (
|
||||||
!this.viewState.unsavedChanges ||
|
!this.ui.viewState.unsavedChanges ||
|
||||||
this.viewState.uiOptions.forcedROMode
|
this.ui.viewState.uiOptions.forcedROMode
|
||||||
) {
|
) {
|
||||||
// No unsaved changes, or read-only mode, not gonna save
|
// No unsaved changes, or read-only mode, not gonna save
|
||||||
return resolve();
|
return resolve();
|
||||||
@ -398,7 +403,7 @@ export class Editor {
|
|||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
.then(async (meta) => {
|
.then(async (meta) => {
|
||||||
this.viewDispatch({ type: "page-saved" });
|
this.ui.viewDispatch({ type: "page-saved" });
|
||||||
await this.dispatchAppEvent(
|
await this.dispatchAppEvent(
|
||||||
"editor:pageSaved",
|
"editor:pageSaved",
|
||||||
this.currentPage,
|
this.currentPage,
|
||||||
@ -425,7 +430,7 @@ export class Editor {
|
|||||||
|
|
||||||
flashNotification(message: string, type: "info" | "error" = "info") {
|
flashNotification(message: string, type: "info" | "error" = "info") {
|
||||||
const id = Math.floor(Math.random() * 1000000);
|
const id = Math.floor(Math.random() * 1000000);
|
||||||
this.viewDispatch({
|
this.ui.viewDispatch({
|
||||||
type: "show-notification",
|
type: "show-notification",
|
||||||
notification: {
|
notification: {
|
||||||
id,
|
id,
|
||||||
@ -436,7 +441,7 @@ export class Editor {
|
|||||||
});
|
});
|
||||||
setTimeout(
|
setTimeout(
|
||||||
() => {
|
() => {
|
||||||
this.viewDispatch({
|
this.ui.viewDispatch({
|
||||||
type: "dismiss-notification",
|
type: "dismiss-notification",
|
||||||
id: id,
|
id: id,
|
||||||
});
|
});
|
||||||
@ -448,7 +453,7 @@ export class Editor {
|
|||||||
progressTimeout?: number;
|
progressTimeout?: number;
|
||||||
|
|
||||||
showProgress(progressPerc: number) {
|
showProgress(progressPerc: number) {
|
||||||
this.viewDispatch({
|
this.ui.viewDispatch({
|
||||||
type: "set-progress",
|
type: "set-progress",
|
||||||
progressPerc,
|
progressPerc,
|
||||||
});
|
});
|
||||||
@ -457,7 +462,7 @@ export class Editor {
|
|||||||
}
|
}
|
||||||
this.progressTimeout = setTimeout(
|
this.progressTimeout = setTimeout(
|
||||||
() => {
|
() => {
|
||||||
this.viewDispatch({
|
this.ui.viewDispatch({
|
||||||
type: "set-progress",
|
type: "set-progress",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -472,14 +477,14 @@ export class Editor {
|
|||||||
placeHolder = "",
|
placeHolder = "",
|
||||||
): Promise<FilterOption | undefined> {
|
): Promise<FilterOption | undefined> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.viewDispatch({
|
this.ui.viewDispatch({
|
||||||
type: "show-filterbox",
|
type: "show-filterbox",
|
||||||
label,
|
label,
|
||||||
options,
|
options,
|
||||||
placeHolder,
|
placeHolder,
|
||||||
helpText,
|
helpText,
|
||||||
onSelect: (option: any) => {
|
onSelect: (option: any) => {
|
||||||
this.viewDispatch({ type: "hide-filterbox" });
|
this.ui.viewDispatch({ type: "hide-filterbox" });
|
||||||
this.focus();
|
this.focus();
|
||||||
resolve(option);
|
resolve(option);
|
||||||
},
|
},
|
||||||
@ -492,12 +497,12 @@ export class Editor {
|
|||||||
defaultValue = "",
|
defaultValue = "",
|
||||||
): Promise<string | undefined> {
|
): Promise<string | undefined> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.viewDispatch({
|
this.ui.viewDispatch({
|
||||||
type: "show-prompt",
|
type: "show-prompt",
|
||||||
message,
|
message,
|
||||||
defaultValue,
|
defaultValue,
|
||||||
callback: (value: string | undefined) => {
|
callback: (value: string | undefined) => {
|
||||||
this.viewDispatch({ type: "hide-prompt" });
|
this.ui.viewDispatch({ type: "hide-prompt" });
|
||||||
this.focus();
|
this.focus();
|
||||||
resolve(value);
|
resolve(value);
|
||||||
},
|
},
|
||||||
@ -509,11 +514,11 @@ export class Editor {
|
|||||||
message: string,
|
message: string,
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.viewDispatch({
|
this.ui.viewDispatch({
|
||||||
type: "show-confirm",
|
type: "show-confirm",
|
||||||
message,
|
message,
|
||||||
callback: (value: boolean) => {
|
callback: (value: boolean) => {
|
||||||
this.viewDispatch({ type: "hide-confirm" });
|
this.ui.viewDispatch({ type: "hide-confirm" });
|
||||||
this.focus();
|
this.focus();
|
||||||
resolve(value);
|
resolve(value);
|
||||||
},
|
},
|
||||||
@ -547,7 +552,7 @@ export class Editor {
|
|||||||
this,
|
this,
|
||||||
this.currentPage,
|
this.currentPage,
|
||||||
editorView.state.sliceDoc(),
|
editorView.state.sliceDoc(),
|
||||||
this.viewState.currentPageMeta?.perm === "ro",
|
this.ui.viewState.currentPageMeta?.perm === "ro",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (editorView.contentDOM) {
|
if (editorView.contentDOM) {
|
||||||
@ -658,7 +663,7 @@ export class Editor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.viewDispatch({
|
this.ui.viewDispatch({
|
||||||
type: "page-loading",
|
type: "page-loading",
|
||||||
name: pageName,
|
name: pageName,
|
||||||
});
|
});
|
||||||
@ -692,7 +697,7 @@ export class Editor {
|
|||||||
const stateRestored = this.openPages.restoreState(pageName);
|
const stateRestored = this.openPages.restoreState(pageName);
|
||||||
this.space.watchPage(pageName);
|
this.space.watchPage(pageName);
|
||||||
|
|
||||||
this.viewDispatch({
|
this.ui.viewDispatch({
|
||||||
type: "page-loaded",
|
type: "page-loaded",
|
||||||
meta: doc.meta,
|
meta: doc.meta,
|
||||||
});
|
});
|
||||||
@ -737,220 +742,8 @@ export class Editor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewComponent() {
|
|
||||||
const [viewState, dispatch] = useReducer(reducer, initialViewState);
|
|
||||||
this.viewState = viewState;
|
|
||||||
this.viewDispatch = dispatch;
|
|
||||||
|
|
||||||
// deno-lint-ignore no-this-alias
|
|
||||||
const editor = this;
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (viewState.currentPage) {
|
|
||||||
document.title = viewState.currentPage;
|
|
||||||
}
|
|
||||||
}, [viewState.currentPage]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (editor.editorView) {
|
|
||||||
editor.tweakEditorDOM(
|
|
||||||
editor.editorView.contentDOM,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [viewState.uiOptions.forcedROMode]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
this.rebuildEditorState();
|
|
||||||
this.dispatchAppEvent("editor:modeswitch");
|
|
||||||
}, [viewState.uiOptions.vimMode]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
document.documentElement.dataset.theme = viewState.uiOptions.darkMode
|
|
||||||
? "dark"
|
|
||||||
: "light";
|
|
||||||
}, [viewState.uiOptions.darkMode]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Need to dispatch a resize event so that the top_bar can pick it up
|
|
||||||
globalThis.dispatchEvent(new Event("resize"));
|
|
||||||
}, [viewState.panels]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{viewState.showPageNavigator && (
|
|
||||||
<PageNavigator
|
|
||||||
allPages={viewState.allPages}
|
|
||||||
currentPage={this.currentPage}
|
|
||||||
completer={this.miniEditorComplete.bind(this)}
|
|
||||||
vimMode={viewState.uiOptions.vimMode}
|
|
||||||
darkMode={viewState.uiOptions.darkMode}
|
|
||||||
onNavigate={(page) => {
|
|
||||||
dispatch({ type: "stop-navigate" });
|
|
||||||
setTimeout(() => {
|
|
||||||
editor.focus();
|
|
||||||
});
|
|
||||||
if (page) {
|
|
||||||
safeRun(async () => {
|
|
||||||
await editor.navigate(page);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{viewState.showCommandPalette && (
|
|
||||||
<CommandPalette
|
|
||||||
onTrigger={(cmd) => {
|
|
||||||
dispatch({ type: "hide-palette" });
|
|
||||||
setTimeout(() => {
|
|
||||||
editor.focus();
|
|
||||||
});
|
|
||||||
if (cmd) {
|
|
||||||
dispatch({ type: "command-run", command: cmd.command.name });
|
|
||||||
cmd
|
|
||||||
.run()
|
|
||||||
.catch((e: any) => {
|
|
||||||
console.error("Error running command", e.message);
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
// Always be focusing the editor after running a command
|
|
||||||
editor.focus();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
commands={this.getCommandsByContext(viewState)}
|
|
||||||
vimMode={viewState.uiOptions.vimMode}
|
|
||||||
darkMode={viewState.uiOptions.darkMode}
|
|
||||||
completer={this.miniEditorComplete.bind(this)}
|
|
||||||
recentCommands={viewState.recentCommands}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{viewState.showFilterBox && (
|
|
||||||
<FilterList
|
|
||||||
label={viewState.filterBoxLabel}
|
|
||||||
placeholder={viewState.filterBoxPlaceHolder}
|
|
||||||
options={viewState.filterBoxOptions}
|
|
||||||
vimMode={viewState.uiOptions.vimMode}
|
|
||||||
darkMode={viewState.uiOptions.darkMode}
|
|
||||||
allowNew={false}
|
|
||||||
completer={this.miniEditorComplete.bind(this)}
|
|
||||||
helpText={viewState.filterBoxHelpText}
|
|
||||||
onSelect={viewState.filterBoxOnSelect}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{viewState.showPrompt && (
|
|
||||||
<Prompt
|
|
||||||
message={viewState.promptMessage!}
|
|
||||||
defaultValue={viewState.promptDefaultValue}
|
|
||||||
vimMode={viewState.uiOptions.vimMode}
|
|
||||||
darkMode={viewState.uiOptions.darkMode}
|
|
||||||
completer={this.miniEditorComplete.bind(this)}
|
|
||||||
callback={(value) => {
|
|
||||||
dispatch({ type: "hide-prompt" });
|
|
||||||
viewState.promptCallback!(value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{viewState.showConfirm && (
|
|
||||||
<Confirm
|
|
||||||
message={viewState.confirmMessage!}
|
|
||||||
callback={(value) => {
|
|
||||||
dispatch({ type: "hide-confirm" });
|
|
||||||
viewState.confirmCallback!(value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<TopBar
|
|
||||||
pageName={viewState.currentPage}
|
|
||||||
notifications={viewState.notifications}
|
|
||||||
synced={viewState.synced}
|
|
||||||
unsavedChanges={viewState.unsavedChanges}
|
|
||||||
isLoading={viewState.isLoading}
|
|
||||||
vimMode={viewState.uiOptions.vimMode}
|
|
||||||
darkMode={viewState.uiOptions.darkMode}
|
|
||||||
progressPerc={viewState.progressPerc}
|
|
||||||
completer={editor.miniEditorComplete.bind(editor)}
|
|
||||||
onRename={async (newName) => {
|
|
||||||
if (!newName) {
|
|
||||||
// Always move cursor to the start of the page
|
|
||||||
editor.editorView?.dispatch({
|
|
||||||
selection: { anchor: 0 },
|
|
||||||
});
|
|
||||||
editor.focus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log("Now renaming page to...", newName);
|
|
||||||
await editor.system.system.loadedPlugs.get("core")!.invoke(
|
|
||||||
"renamePage",
|
|
||||||
[{ page: newName }],
|
|
||||||
);
|
|
||||||
editor.focus();
|
|
||||||
}}
|
|
||||||
actionButtons={[
|
|
||||||
{
|
|
||||||
icon: HomeIcon,
|
|
||||||
description: `Go home (Alt-h)`,
|
|
||||||
callback: () => {
|
|
||||||
editor.navigate("");
|
|
||||||
},
|
|
||||||
href: "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: BookIcon,
|
|
||||||
description: `Open page (${isMacLike() ? "Cmd-k" : "Ctrl-k"})`,
|
|
||||||
callback: () => {
|
|
||||||
dispatch({ type: "start-navigate" });
|
|
||||||
this.space.updatePageList();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: TerminalIcon,
|
|
||||||
description: `Run command (${isMacLike() ? "Cmd-/" : "Ctrl-/"})`,
|
|
||||||
callback: () => {
|
|
||||||
dispatch({ type: "show-palette", context: this.getContext() });
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
rhs={!!viewState.panels.rhs.mode && (
|
|
||||||
<div
|
|
||||||
className="panel"
|
|
||||||
style={{ flex: viewState.panels.rhs.mode }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
lhs={!!viewState.panels.lhs.mode && (
|
|
||||||
<div
|
|
||||||
className="panel"
|
|
||||||
style={{ flex: viewState.panels.lhs.mode }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<div id="sb-main">
|
|
||||||
{!!viewState.panels.lhs.mode && (
|
|
||||||
<Panel config={viewState.panels.lhs} editor={editor} />
|
|
||||||
)}
|
|
||||||
<div id="sb-editor" />
|
|
||||||
{!!viewState.panels.rhs.mode && (
|
|
||||||
<Panel config={viewState.panels.rhs} editor={editor} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{!!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">
|
|
||||||
<Panel config={viewState.panels.bhs} editor={editor} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async runCommandByName(name: string, ...args: any[]) {
|
async runCommandByName(name: string, ...args: any[]) {
|
||||||
const cmd = this.viewState.commands.get(name);
|
const cmd = this.ui.viewState.commands.get(name);
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
await cmd.run();
|
await cmd.run();
|
||||||
} else {
|
} else {
|
||||||
@ -958,12 +751,7 @@ export class Editor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render(container: Element) {
|
getCommandsByContext(
|
||||||
const ViewComponent = this.ViewComponent.bind(this);
|
|
||||||
preactRender(<ViewComponent />, container);
|
|
||||||
}
|
|
||||||
|
|
||||||
private getCommandsByContext(
|
|
||||||
state: AppViewState,
|
state: AppViewState,
|
||||||
): Map<string, AppCommand> {
|
): Map<string, AppCommand> {
|
||||||
const commands = new Map(state.commands);
|
const commands = new Map(state.commands);
|
@ -49,7 +49,7 @@ import {
|
|||||||
xmlLanguage,
|
xmlLanguage,
|
||||||
yamlLanguage,
|
yamlLanguage,
|
||||||
} from "../common/deps.ts";
|
} from "../common/deps.ts";
|
||||||
import { Editor } from "./editor.tsx";
|
import { Editor } from "./editor.ts";
|
||||||
import { vim } from "./deps.ts";
|
import { vim } from "./deps.ts";
|
||||||
import { inlineImagesPlugin } from "./cm_plugins/inline_image.ts";
|
import { inlineImagesPlugin } from "./cm_plugins/inline_image.ts";
|
||||||
import { cleanModePlugins } from "./cm_plugins/clean.ts";
|
import { cleanModePlugins } from "./cm_plugins/clean.ts";
|
||||||
@ -107,11 +107,15 @@ export function createEditorState(
|
|||||||
doc: text,
|
doc: text,
|
||||||
extensions: [
|
extensions: [
|
||||||
// Not using CM theming right now, but some extensions depend on the "dark" thing
|
// Not using CM theming right now, but some extensions depend on the "dark" thing
|
||||||
EditorView.theme({}, { dark: editor.viewState.uiOptions.darkMode }),
|
EditorView.theme({}, {
|
||||||
|
dark: editor.ui.viewState.uiOptions.darkMode,
|
||||||
|
}),
|
||||||
// Enable vim mode, or not
|
// Enable vim mode, or not
|
||||||
[...editor.viewState.uiOptions.vimMode ? [vim({ status: true })] : []],
|
|
||||||
[
|
[
|
||||||
...readOnly || editor.viewState.uiOptions.forcedROMode
|
...editor.ui.viewState.uiOptions.vimMode ? [vim({ status: true })] : [],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
...readOnly || editor.ui.viewState.uiOptions.forcedROMode
|
||||||
? [readonlyMode()]
|
? [readonlyMode()]
|
||||||
: [],
|
: [],
|
||||||
],
|
],
|
||||||
@ -309,7 +313,7 @@ export function createEditorState(
|
|||||||
key: "Ctrl-k",
|
key: "Ctrl-k",
|
||||||
mac: "Cmd-k",
|
mac: "Cmd-k",
|
||||||
run: (): boolean => {
|
run: (): boolean => {
|
||||||
editor.viewDispatch({ type: "start-navigate" });
|
editor.ui.viewDispatch({ type: "start-navigate" });
|
||||||
editor.space.updatePageList();
|
editor.space.updatePageList();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -319,7 +323,7 @@ export function createEditorState(
|
|||||||
key: "Ctrl-/",
|
key: "Ctrl-/",
|
||||||
mac: "Cmd-/",
|
mac: "Cmd-/",
|
||||||
run: (): boolean => {
|
run: (): boolean => {
|
||||||
editor.viewDispatch({
|
editor.ui.viewDispatch({
|
||||||
type: "show-palette",
|
type: "show-palette",
|
||||||
context: editor.getContext(),
|
context: editor.getContext(),
|
||||||
});
|
});
|
||||||
@ -330,7 +334,7 @@ export function createEditorState(
|
|||||||
key: "Ctrl-.",
|
key: "Ctrl-.",
|
||||||
mac: "Cmd-.",
|
mac: "Cmd-.",
|
||||||
run: (): boolean => {
|
run: (): boolean => {
|
||||||
editor.viewDispatch({
|
editor.ui.viewDispatch({
|
||||||
type: "show-palette",
|
type: "show-palette",
|
||||||
context: editor.getContext(),
|
context: editor.getContext(),
|
||||||
});
|
});
|
||||||
@ -415,7 +419,7 @@ export function createEditorState(
|
|||||||
class {
|
class {
|
||||||
update(update: ViewUpdate): void {
|
update(update: ViewUpdate): void {
|
||||||
if (update.docChanged) {
|
if (update.docChanged) {
|
||||||
editor.viewDispatch({ type: "page-changed" });
|
editor.ui.viewDispatch({ type: "page-changed" });
|
||||||
editor.debouncedUpdateEvent();
|
editor.debouncedUpdateEvent();
|
||||||
editor.save().catch((e) => console.error("Error saving", e));
|
editor.save().catch((e) => console.error("Error saving", e));
|
||||||
}
|
}
|
||||||
|
246
web/editor_ui.tsx
Normal file
246
web/editor_ui.tsx
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
import { isMacLike, safeRun } from "../common/util.ts";
|
||||||
|
import { Confirm, Prompt } from "./components/basic_modals.tsx";
|
||||||
|
import { CommandPalette } from "./components/command_palette.tsx";
|
||||||
|
import { FilterList } from "./components/filter.tsx";
|
||||||
|
import { PageNavigator } from "./components/page_navigator.tsx";
|
||||||
|
import { TopBar } from "./components/top_bar.tsx";
|
||||||
|
import reducer from "./reducer.ts";
|
||||||
|
import { Action, AppViewState, initialViewState } from "./types.ts";
|
||||||
|
import {
|
||||||
|
BookIcon,
|
||||||
|
HomeIcon,
|
||||||
|
preactRender,
|
||||||
|
TerminalIcon,
|
||||||
|
useEffect,
|
||||||
|
useReducer,
|
||||||
|
} from "./deps.ts";
|
||||||
|
import type { Editor } from "./editor.ts";
|
||||||
|
import { Panel } from "./components/panel.tsx";
|
||||||
|
import { h } from "./deps.ts";
|
||||||
|
|
||||||
|
export class MainUI {
|
||||||
|
viewState: AppViewState = initialViewState;
|
||||||
|
viewDispatch: (action: Action) => void = () => {};
|
||||||
|
|
||||||
|
constructor(private editor: Editor) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewComponent() {
|
||||||
|
const [viewState, dispatch] = useReducer(reducer, initialViewState);
|
||||||
|
this.viewState = viewState;
|
||||||
|
this.viewDispatch = dispatch;
|
||||||
|
|
||||||
|
const editor = this.editor;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (viewState.currentPage) {
|
||||||
|
document.title = viewState.currentPage;
|
||||||
|
}
|
||||||
|
}, [viewState.currentPage]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (editor.editorView) {
|
||||||
|
editor.tweakEditorDOM(
|
||||||
|
editor.editorView.contentDOM,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, [viewState.uiOptions.forcedROMode]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
this.editor.rebuildEditorState();
|
||||||
|
this.editor.dispatchAppEvent("editor:modeswitch");
|
||||||
|
}, [viewState.uiOptions.vimMode]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.documentElement.dataset.theme = viewState.uiOptions.darkMode
|
||||||
|
? "dark"
|
||||||
|
: "light";
|
||||||
|
}, [viewState.uiOptions.darkMode]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Need to dispatch a resize event so that the top_bar can pick it up
|
||||||
|
globalThis.dispatchEvent(new Event("resize"));
|
||||||
|
}, [viewState.panels]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{viewState.showPageNavigator && (
|
||||||
|
<PageNavigator
|
||||||
|
allPages={viewState.allPages}
|
||||||
|
currentPage={editor.currentPage}
|
||||||
|
completer={editor.miniEditorComplete.bind(editor)}
|
||||||
|
vimMode={viewState.uiOptions.vimMode}
|
||||||
|
darkMode={viewState.uiOptions.darkMode}
|
||||||
|
onNavigate={(page) => {
|
||||||
|
dispatch({ type: "stop-navigate" });
|
||||||
|
setTimeout(() => {
|
||||||
|
editor.focus();
|
||||||
|
});
|
||||||
|
if (page) {
|
||||||
|
safeRun(async () => {
|
||||||
|
await editor.navigate(page);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{viewState.showCommandPalette && (
|
||||||
|
<CommandPalette
|
||||||
|
onTrigger={(cmd) => {
|
||||||
|
dispatch({ type: "hide-palette" });
|
||||||
|
setTimeout(() => {
|
||||||
|
editor.focus();
|
||||||
|
});
|
||||||
|
if (cmd) {
|
||||||
|
dispatch({ type: "command-run", command: cmd.command.name });
|
||||||
|
cmd
|
||||||
|
.run()
|
||||||
|
.catch((e: any) => {
|
||||||
|
console.error("Error running command", e.message);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
// Always be focusing the editor after running a command
|
||||||
|
editor.focus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
commands={editor.getCommandsByContext(viewState)}
|
||||||
|
vimMode={viewState.uiOptions.vimMode}
|
||||||
|
darkMode={viewState.uiOptions.darkMode}
|
||||||
|
completer={editor.miniEditorComplete.bind(editor)}
|
||||||
|
recentCommands={viewState.recentCommands}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{viewState.showFilterBox && (
|
||||||
|
<FilterList
|
||||||
|
label={viewState.filterBoxLabel}
|
||||||
|
placeholder={viewState.filterBoxPlaceHolder}
|
||||||
|
options={viewState.filterBoxOptions}
|
||||||
|
vimMode={viewState.uiOptions.vimMode}
|
||||||
|
darkMode={viewState.uiOptions.darkMode}
|
||||||
|
allowNew={false}
|
||||||
|
completer={editor.miniEditorComplete.bind(editor)}
|
||||||
|
helpText={viewState.filterBoxHelpText}
|
||||||
|
onSelect={viewState.filterBoxOnSelect}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{viewState.showPrompt && (
|
||||||
|
<Prompt
|
||||||
|
message={viewState.promptMessage!}
|
||||||
|
defaultValue={viewState.promptDefaultValue}
|
||||||
|
vimMode={viewState.uiOptions.vimMode}
|
||||||
|
darkMode={viewState.uiOptions.darkMode}
|
||||||
|
completer={editor.miniEditorComplete.bind(editor)}
|
||||||
|
callback={(value) => {
|
||||||
|
dispatch({ type: "hide-prompt" });
|
||||||
|
viewState.promptCallback!(value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{viewState.showConfirm && (
|
||||||
|
<Confirm
|
||||||
|
message={viewState.confirmMessage!}
|
||||||
|
callback={(value) => {
|
||||||
|
dispatch({ type: "hide-confirm" });
|
||||||
|
viewState.confirmCallback!(value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<TopBar
|
||||||
|
pageName={viewState.currentPage}
|
||||||
|
notifications={viewState.notifications}
|
||||||
|
synced={viewState.synced}
|
||||||
|
unsavedChanges={viewState.unsavedChanges}
|
||||||
|
isLoading={viewState.isLoading}
|
||||||
|
vimMode={viewState.uiOptions.vimMode}
|
||||||
|
darkMode={viewState.uiOptions.darkMode}
|
||||||
|
progressPerc={viewState.progressPerc}
|
||||||
|
completer={editor.miniEditorComplete.bind(editor)}
|
||||||
|
onRename={async (newName) => {
|
||||||
|
if (!newName) {
|
||||||
|
// Always move cursor to the start of the page
|
||||||
|
editor.editorView?.dispatch({
|
||||||
|
selection: { anchor: 0 },
|
||||||
|
});
|
||||||
|
editor.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("Now renaming page to...", newName);
|
||||||
|
await editor.system.system.loadedPlugs.get("core")!.invoke(
|
||||||
|
"renamePage",
|
||||||
|
[{ page: newName }],
|
||||||
|
);
|
||||||
|
editor.focus();
|
||||||
|
}}
|
||||||
|
actionButtons={[
|
||||||
|
{
|
||||||
|
icon: HomeIcon,
|
||||||
|
description: `Go home (Alt-h)`,
|
||||||
|
callback: () => {
|
||||||
|
editor.navigate("");
|
||||||
|
},
|
||||||
|
href: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: BookIcon,
|
||||||
|
description: `Open page (${isMacLike() ? "Cmd-k" : "Ctrl-k"})`,
|
||||||
|
callback: () => {
|
||||||
|
dispatch({ type: "start-navigate" });
|
||||||
|
editor.space.updatePageList();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: TerminalIcon,
|
||||||
|
description: `Run command (${isMacLike() ? "Cmd-/" : "Ctrl-/"})`,
|
||||||
|
callback: () => {
|
||||||
|
dispatch({
|
||||||
|
type: "show-palette",
|
||||||
|
context: editor.getContext(),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
rhs={!!viewState.panels.rhs.mode && (
|
||||||
|
<div
|
||||||
|
className="panel"
|
||||||
|
style={{ flex: viewState.panels.rhs.mode }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
lhs={!!viewState.panels.lhs.mode && (
|
||||||
|
<div
|
||||||
|
className="panel"
|
||||||
|
style={{ flex: viewState.panels.lhs.mode }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<div id="sb-main">
|
||||||
|
{!!viewState.panels.lhs.mode && (
|
||||||
|
<Panel config={viewState.panels.lhs} editor={editor} />
|
||||||
|
)}
|
||||||
|
<div id="sb-editor" />
|
||||||
|
{!!viewState.panels.rhs.mode && (
|
||||||
|
<Panel config={viewState.panels.rhs} editor={editor} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{!!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">
|
||||||
|
<Panel config={viewState.panels.bhs} editor={editor} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render(container: Element) {
|
||||||
|
// const ViewComponent = this.ui.ViewComponent.bind(this.ui);
|
||||||
|
preactRender(h(this.ViewComponent.bind(this), {}), container);
|
||||||
|
}
|
||||||
|
}
|
@ -53,12 +53,15 @@ export class CommandHook extends EventEmitter<CommandHookEvents>
|
|||||||
}
|
}
|
||||||
|
|
||||||
apply(system: System<CommandHookT>): void {
|
apply(system: System<CommandHookT>): void {
|
||||||
this.buildAllCommands(system);
|
|
||||||
system.on({
|
system.on({
|
||||||
plugLoaded: () => {
|
plugLoaded: () => {
|
||||||
this.buildAllCommands(system);
|
this.buildAllCommands(system);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
// On next tick
|
||||||
|
setTimeout(() => {
|
||||||
|
this.buildAllCommands(system);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
validateManifest(manifest: Manifest<CommandHookT>): string[] {
|
validateManifest(manifest: Manifest<CommandHookT>): string[] {
|
||||||
|
@ -2,7 +2,7 @@ import { Hook, Manifest } from "../../plugos/types.ts";
|
|||||||
import { System } from "../../plugos/system.ts";
|
import { System } from "../../plugos/system.ts";
|
||||||
import { Completion, CompletionContext, CompletionResult } from "../deps.ts";
|
import { Completion, CompletionContext, CompletionResult } from "../deps.ts";
|
||||||
import { safeRun } from "../../common/util.ts";
|
import { safeRun } from "../../common/util.ts";
|
||||||
import { Editor } from "../editor.tsx";
|
import { Editor } from "../editor.ts";
|
||||||
import { syntaxTree } from "../deps.ts";
|
import { syntaxTree } from "../deps.ts";
|
||||||
|
|
||||||
export type SlashCommandDef = {
|
export type SlashCommandDef = {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Editor } from "../editor.tsx";
|
import { Editor } from "../editor.ts";
|
||||||
import {
|
import {
|
||||||
EditorView,
|
EditorView,
|
||||||
foldAll,
|
foldAll,
|
||||||
@ -81,14 +81,14 @@ export function editorSyscalls(editor: Editor): SysCallMapping {
|
|||||||
html: string,
|
html: string,
|
||||||
script: string,
|
script: string,
|
||||||
) => {
|
) => {
|
||||||
editor.viewDispatch({
|
editor.ui.viewDispatch({
|
||||||
type: "show-panel",
|
type: "show-panel",
|
||||||
id: id as any,
|
id: id as any,
|
||||||
config: { html, script, mode },
|
config: { html, script, mode },
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"editor.hidePanel": (_ctx, id: string) => {
|
"editor.hidePanel": (_ctx, id: string) => {
|
||||||
editor.viewDispatch({
|
editor.ui.viewDispatch({
|
||||||
type: "hide-panel",
|
type: "hide-panel",
|
||||||
id: id as any,
|
id: id as any,
|
||||||
});
|
});
|
||||||
@ -169,10 +169,10 @@ export function editorSyscalls(editor: Editor): SysCallMapping {
|
|||||||
return editor.confirm(message);
|
return editor.confirm(message);
|
||||||
},
|
},
|
||||||
"editor.getUiOption": (_ctx, key: string): any => {
|
"editor.getUiOption": (_ctx, key: string): any => {
|
||||||
return (editor.viewState.uiOptions as any)[key];
|
return (editor.ui.viewState.uiOptions as any)[key];
|
||||||
},
|
},
|
||||||
"editor.setUiOption": (_ctx, key: string, value: any) => {
|
"editor.setUiOption": (_ctx, key: string, value: any) => {
|
||||||
editor.viewDispatch({
|
editor.ui.viewDispatch({
|
||||||
type: "set-ui-option",
|
type: "set-ui-option",
|
||||||
key,
|
key,
|
||||||
value,
|
value,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Editor } from "../editor.tsx";
|
import { Editor } from "../editor.ts";
|
||||||
import { SysCallMapping } from "../../plugos/system.ts";
|
import { SysCallMapping } from "../../plugos/system.ts";
|
||||||
import { AttachmentMeta, PageMeta } from "../types.ts";
|
import { AttachmentMeta, PageMeta } from "../types.ts";
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { SysCallMapping } from "../../plugos/system.ts";
|
import { SysCallMapping } from "../../plugos/system.ts";
|
||||||
import type { Editor } from "../editor.tsx";
|
import type { Editor } from "../editor.ts";
|
||||||
|
|
||||||
export function syncSyscalls(editor: Editor): SysCallMapping {
|
export function syncSyscalls(editor: Editor): SysCallMapping {
|
||||||
return {
|
return {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { Plug } from "../../plugos/plug.ts";
|
import type { Plug } from "../../plugos/plug.ts";
|
||||||
import { SysCallMapping, System } from "../../plugos/system.ts";
|
import { SysCallMapping, System } from "../../plugos/system.ts";
|
||||||
import type { Editor } from "../editor.tsx";
|
import type { Editor } from "../editor.ts";
|
||||||
import { CommandDef } from "../hooks/command.ts";
|
import { CommandDef } from "../hooks/command.ts";
|
||||||
|
|
||||||
export function systemSyscalls(
|
export function systemSyscalls(
|
||||||
|
Loading…
Reference in New Issue
Block a user