Flexible LHS and RHS with flex
parent
a7cd3ea7e0
commit
1b0048cdcf
|
@ -32,14 +32,22 @@ export function flashNotification(message: string): Promise<void> {
|
|||
return syscall("editor.flashNotification", message);
|
||||
}
|
||||
|
||||
export function showRhs(html: string): Promise<void> {
|
||||
return syscall("editor.showRhs", html);
|
||||
export function showRhs(html: string, flex = 1): Promise<void> {
|
||||
return syscall("editor.showRhs", html, flex);
|
||||
}
|
||||
|
||||
export function hideRhs(): Promise<void> {
|
||||
return syscall("editor.hideRhs");
|
||||
}
|
||||
|
||||
export function showLhs(html: string, flex = 1): Promise<void> {
|
||||
return syscall("editor.showLhs", html, flex);
|
||||
}
|
||||
|
||||
export function hideLhs(): Promise<void> {
|
||||
return syscall("editor.hideLhs");
|
||||
}
|
||||
|
||||
export function insertAtPos(text: string, pos: number): Promise<void> {
|
||||
return syscall("editor.insertAtPos", text, pos);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ functions:
|
|||
path: "./markdown.ts:togglePreview"
|
||||
command:
|
||||
name: "Toggle Markdown Preview"
|
||||
key: Ctrl-p
|
||||
mac: Cmd-p
|
||||
preview:
|
||||
path: "./markdown.ts:updateMarkdownPreview"
|
||||
env: client
|
||||
|
|
|
@ -48,7 +48,7 @@ export async function updateMarkdownPreview() {
|
|||
}
|
||||
});
|
||||
let html = md.render(renderMarkdown(mdTree));
|
||||
await showRhs(`<html><body>${html}</body></html>`);
|
||||
await showRhs(`<html><body>${html}</body></html>`, 1);
|
||||
}
|
||||
|
||||
async function hideMarkdownPreview() {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import {useEffect, useRef} from "react";
|
||||
// @ts-ignore
|
||||
import iframeHtml from "bundle-text:./panel.html";
|
||||
import {Simulate} from "react-dom/test-utils";
|
||||
|
||||
export function Panel({ html }: { html: string }) {
|
||||
export function Panel({ html, flex }: { html: string; flex: number }) {
|
||||
const iFrameRef = useRef<HTMLIFrameElement>(null);
|
||||
useEffect(() => {
|
||||
function loadContent() {
|
||||
|
@ -25,7 +24,7 @@ export function Panel({ html }: { html: string }) {
|
|||
};
|
||||
}, [html]);
|
||||
return (
|
||||
<div className="panel">
|
||||
<div className="panel" style={{ flex }}>
|
||||
<iframe srcDoc={iframeHtml} ref={iFrameRef} />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Notification } from "../types";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faFileLines } from "@fortawesome/free-solid-svg-icons";
|
||||
import {Notification} from "../types";
|
||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||
import {faFileLines} from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
function prettyName(s: string | undefined): string {
|
||||
if (!s) {
|
||||
|
@ -14,14 +14,20 @@ export function TopBar({
|
|||
unsavedChanges,
|
||||
notifications,
|
||||
onClick,
|
||||
lhs,
|
||||
rhs,
|
||||
}: {
|
||||
pageName?: string;
|
||||
unsavedChanges: boolean;
|
||||
notifications: Notification[];
|
||||
onClick: () => void;
|
||||
lhs?: React.ReactNode;
|
||||
rhs?: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div id="top" onClick={onClick}>
|
||||
{lhs}
|
||||
<div className="main">
|
||||
<div className="inner">
|
||||
<span className={`icon ${unsavedChanges ? "unsaved" : "saved"}`}>
|
||||
<FontAwesomeIcon icon={faFileLines} />
|
||||
|
@ -36,5 +42,7 @@ export function TopBar({
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
{rhs}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -314,20 +314,19 @@ export class Editor implements AppEventDispatcher {
|
|||
mac: "Cmd-i",
|
||||
run: commands.insertMarker("_"),
|
||||
},
|
||||
{
|
||||
key: "Ctrl-p",
|
||||
mac: "Cmd-p",
|
||||
run: (): boolean => {
|
||||
window.open(location.href, "_blank")!.focus();
|
||||
return true;
|
||||
},
|
||||
},
|
||||
// {
|
||||
// key: "Ctrl-p",
|
||||
// mac: "Cmd-p",
|
||||
// run: (): boolean => {
|
||||
// window.open(location.href, "_blank")!.focus();
|
||||
// return true;
|
||||
// },
|
||||
// },
|
||||
{
|
||||
key: "Ctrl-k",
|
||||
mac: "Cmd-k",
|
||||
run: (): boolean => {
|
||||
this.viewDispatch({ type: "start-navigate" });
|
||||
// asynchornously will dispatch pageListUpdate event
|
||||
this.space.updatePageListAsync();
|
||||
return true;
|
||||
},
|
||||
|
@ -463,7 +462,7 @@ export class Editor implements AppEventDispatcher {
|
|||
}, [viewState.currentPage]);
|
||||
|
||||
return (
|
||||
<div className={viewState.showRHS ? "rhs-open" : ""}>
|
||||
<>
|
||||
{viewState.showPageNavigator && (
|
||||
<PageNavigator
|
||||
allPages={viewState.allPages}
|
||||
|
@ -493,7 +492,6 @@ export class Editor implements AppEventDispatcher {
|
|||
commands={viewState.commands}
|
||||
/>
|
||||
)}
|
||||
{viewState.showRHS && <Panel html={viewState.rhsHTML} />}
|
||||
<TopBar
|
||||
pageName={viewState.currentPage}
|
||||
notifications={viewState.notifications}
|
||||
|
@ -501,10 +499,28 @@ export class Editor implements AppEventDispatcher {
|
|||
onClick={() => {
|
||||
dispatch({ type: "start-navigate" });
|
||||
}}
|
||||
rhs={
|
||||
!!viewState.showRHS && (
|
||||
<div className="panel" style={{ flex: viewState.showRHS }} />
|
||||
)
|
||||
}
|
||||
lhs={
|
||||
!!viewState.showLHS && (
|
||||
<div className="panel" style={{ flex: viewState.showLHS }} />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<div id="main">
|
||||
{!!viewState.showLHS && (
|
||||
<Panel html={viewState.lhsHTML} flex={viewState.showLHS} />
|
||||
)}
|
||||
<div id="editor" />
|
||||
<StatusBar editorView={editor.editorView} />
|
||||
{!!viewState.showRHS && (
|
||||
<Panel html={viewState.rhsHTML} flex={viewState.showRHS} />
|
||||
)}
|
||||
</div>
|
||||
<StatusBar editorView={editor.editorView} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Action, AppViewState } from "./types";
|
||||
import {Action, AppViewState} from "./types";
|
||||
|
||||
export default function reducer(
|
||||
state: AppViewState,
|
||||
|
@ -71,15 +71,27 @@ export default function reducer(
|
|||
case "show-rhs":
|
||||
return {
|
||||
...state,
|
||||
showRHS: true,
|
||||
showRHS: action.flex,
|
||||
rhsHTML: action.html,
|
||||
};
|
||||
case "hide-rhs":
|
||||
return {
|
||||
...state,
|
||||
showRHS: false,
|
||||
showRHS: 0,
|
||||
rhsHTML: "",
|
||||
};
|
||||
case "show-lhs":
|
||||
return {
|
||||
...state,
|
||||
showLHS: action.flex,
|
||||
lhsHTML: action.html,
|
||||
};
|
||||
case "hide-lhs":
|
||||
return {
|
||||
...state,
|
||||
showLHS: 0,
|
||||
lhsHTML: "",
|
||||
};
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
@import "constants.scss";
|
||||
|
||||
div.rhs-open #editor .cm-editor .cm-content {
|
||||
max-width: 550px;
|
||||
}
|
||||
//div.rhs-open #editor .cm-editor .cm-content {
|
||||
// max-width: 550px;
|
||||
//}
|
||||
|
||||
.cm-editor {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: var(--ident);
|
||||
overflow-y: hidden;
|
||||
|
||||
.cm-content {
|
||||
font-family: var(--editor-font);
|
||||
|
@ -15,34 +14,8 @@ div.rhs-open #editor .cm-editor .cm-content {
|
|||
max-width: $max-editor-width;
|
||||
}
|
||||
|
||||
.other-cursor {
|
||||
display: inline-block;
|
||||
width: 2px;
|
||||
margin-right: -2px;
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
.cursor-label-container {
|
||||
// display: none;
|
||||
position: relative;
|
||||
top: 2ch;
|
||||
float: left;
|
||||
width: 120px;
|
||||
height: 2.2ch;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
color: #fff;
|
||||
border: gray 1px solid;
|
||||
background-color: purple;
|
||||
// font-size: 0.5em;
|
||||
}
|
||||
|
||||
.cursor-label-container label {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 0.7em;
|
||||
&.cm-focused {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.cm-selectionBackground {
|
||||
|
|
|
@ -14,43 +14,37 @@
|
|||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.panel {
|
||||
position: absolute;
|
||||
top: $top-bar-height + 1px;
|
||||
bottom: $bottom-bar-height;
|
||||
right: 0;
|
||||
width: 50%;
|
||||
z-index: 20;
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
#root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#top {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
height: $top-bar-height;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: rgb(213, 213, 213);
|
||||
border-bottom: rgb(193, 193, 193) 1px solid;
|
||||
color: rgb(55, 55, 55);
|
||||
|
||||
.main {
|
||||
flex: 2;
|
||||
|
||||
.inner {
|
||||
padding-top: 12px;
|
||||
max-width: $max-editor-width;
|
||||
font-size: 28px;
|
||||
margin: auto;
|
||||
padding-top: 12px;
|
||||
font-size: 28px;
|
||||
|
||||
.status {
|
||||
float: right;
|
||||
|
@ -78,41 +72,54 @@ body {
|
|||
color: #e19502;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#editor {
|
||||
position: absolute;
|
||||
top: $top-bar-height;
|
||||
bottom: $bottom-bar-height;
|
||||
left: 0;
|
||||
right: 0;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
.panel {
|
||||
flex: 1;
|
||||
|
||||
div.rhs-open #editor {
|
||||
right: 50%;
|
||||
}
|
||||
|
||||
div.rhs-open #top .inner {
|
||||
max-width: 550px;
|
||||
padding-right: 50%;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $max-editor-width) {
|
||||
.cm-editor .cm-content {
|
||||
margin: 0 10px !important;
|
||||
}
|
||||
}
|
||||
|
||||
#main {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-grow: 1;
|
||||
height: 0;
|
||||
|
||||
.panel {
|
||||
flex: 1;
|
||||
border-left: 1px solid #eee;
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#editor {
|
||||
overflow-y: scroll;
|
||||
flex: 2;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//@media only screen and (max-width: $max-editor-width) {
|
||||
// .cm-editor .cm-content {
|
||||
// margin: 0 10px !important;
|
||||
// }
|
||||
//}
|
||||
|
||||
#bottom {
|
||||
height: $bottom-bar-height;
|
||||
background-color: #ccc;
|
||||
position: fixed;
|
||||
height: 25px;
|
||||
text-align: right;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: rgb(213, 213, 213);
|
||||
border-top: rgb(193, 193, 193) 1px solid;
|
||||
|
||||
|
|
|
@ -51,17 +51,30 @@ export function editorSyscalls(editor: Editor): SysCallMapping {
|
|||
"editor.flashNotification": (ctx, message: string) => {
|
||||
editor.flashNotification(message);
|
||||
},
|
||||
"editor.showRhs": (ctx, html: string) => {
|
||||
"editor.showRhs": (ctx, html: string, flex: number) => {
|
||||
editor.viewDispatch({
|
||||
type: "show-rhs",
|
||||
html: html,
|
||||
flex,
|
||||
html,
|
||||
});
|
||||
},
|
||||
"editor.hideRhs": (ctx, html: string) => {
|
||||
"editor.hideRhs": (ctx) => {
|
||||
editor.viewDispatch({
|
||||
type: "hide-rhs",
|
||||
});
|
||||
},
|
||||
"editor.showLhs": (ctx, html: string, flex: number) => {
|
||||
editor.viewDispatch({
|
||||
type: "show-lhs",
|
||||
flex,
|
||||
html,
|
||||
});
|
||||
},
|
||||
"editor.hideLhs": (ctx) => {
|
||||
editor.viewDispatch({
|
||||
type: "hide-lhs",
|
||||
});
|
||||
},
|
||||
"editor.insertAtPos": (ctx, text: string, pos: number) => {
|
||||
editor.editorView!.dispatch({
|
||||
changes: {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { AppCommand } from "./hooks/command";
|
||||
import { PageMeta } from "../common/types";
|
||||
import {AppCommand} from "./hooks/command";
|
||||
import {PageMeta} from "../common/types";
|
||||
|
||||
export const slashCommandRegexp = /\/[\w\-]*/;
|
||||
|
||||
|
@ -14,8 +14,10 @@ export type AppViewState = {
|
|||
showPageNavigator: boolean;
|
||||
showCommandPalette: boolean;
|
||||
unsavedChanges: boolean;
|
||||
showRHS: boolean;
|
||||
showLHS: number; // 0 = hide, > 0 = flex
|
||||
showRHS: number; // 0 = hide, > 0 = flex
|
||||
rhsHTML: string;
|
||||
lhsHTML: string;
|
||||
allPages: Set<PageMeta>;
|
||||
commands: Map<string, AppCommand>;
|
||||
notifications: Notification[];
|
||||
|
@ -25,8 +27,10 @@ export const initialViewState: AppViewState = {
|
|||
showPageNavigator: false,
|
||||
showCommandPalette: false,
|
||||
unsavedChanges: false,
|
||||
showRHS: false,
|
||||
rhsHTML: "<h1>Loading...</h1>",
|
||||
showLHS: 0,
|
||||
showRHS: 0,
|
||||
rhsHTML: "",
|
||||
lhsHTML: "",
|
||||
allPages: new Set(),
|
||||
commands: new Map(),
|
||||
notifications: [],
|
||||
|
@ -44,5 +48,7 @@ export type Action =
|
|||
| { type: "hide-palette" }
|
||||
| { type: "show-notification"; notification: Notification }
|
||||
| { type: "dismiss-notification"; id: number }
|
||||
| { type: "show-rhs"; html: string }
|
||||
| { type: "hide-rhs" };
|
||||
| { type: "show-rhs"; html: string; flex: number }
|
||||
| { type: "hide-rhs" }
|
||||
| { type: "show-lhs"; html: string; flex: number }
|
||||
| { type: "hide-lhs" };
|
||||
|
|
Loading…
Reference in New Issue