markdown preview

This commit is contained in:
sawka
2024-05-14 09:37:41 -07:00
parent 540f2fe0c0
commit 1db615bb3a
13 changed files with 1040 additions and 9 deletions
+102
View File
@@ -0,0 +1,102 @@
.markdown {
color: var(--main-color);
font-family: var(--markdown-font);
font-size: 14px;
overflow-wrap: break-word;
&.bottom-margin {
margin-bottom: 10px;
}
.title {
color: var(--main-color);
margin-top: 16px;
margin-bottom: 8px;
}
strong {
color: var(--main-color);
}
a {
color: #32afff;
}
table {
tr th {
color: var(--main-color);
}
}
ul {
list-style-type: disc;
list-style-position: outside;
margin-left: 16px;
}
ol {
list-style-position: outside;
margin-left: 19px;
}
blockquote {
margin: 4px 10px 4px 10px;
border-radius: 3px;
background-color: var(--panel-bg-color);
padding: 2px 4px 2px 6px;
}
pre {
background-color: var(--panel-bg-color);
margin: 4px 10px 4px 10px;
padding: 0.7em;
border-radius: 4px;
code {
background-color: transparent;
padding: 0;
line-height: normal;
}
}
code {
font: var(--fixed-font);
color: var(--main-color);
border-radius: 4px;
background-color: var(--panel-bg-color);
padding: 0.15em 0.5em;
line-height: 1.5;
}
.title {
font-weight: semibold;
padding-top: 6px;
}
.title.is-1 {
border-bottom: 1px solid #777;
padding-bottom: 6px;
font-size: 2em;
}
.title.is-2 {
border-bottom: 1px solid #777;
padding-bottom: 6px;
font-size: 1.5em;
}
.title.is-3 {
font-size: 1.25em;
}
.title.is-4 {
font-size: 1em;
}
.title.is-5 {
font-size: 0.875em;
}
.title.is-6 {
font-size: 0.85em;
}
}
.markdown > *:first-child {
margin-top: 0 !important;
}
+44
View File
@@ -0,0 +1,44 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import * as React from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { clsx } from "clsx";
import "./markdown.less";
function LinkRenderer(props: any): any {
let newUrl = "https://extern?" + encodeURIComponent(props.href);
return (
<a href={newUrl} target="_blank" rel={"noopener"}>
{props.children}
</a>
);
}
function HeaderRenderer(props: any, hnum: number): any {
return <div className={clsx("title", "is-" + hnum)}>{props.children}</div>;
}
function Markdown(props: { text: string; style?: any; extraClassName?: string; codeSelect?: boolean }) {
let text = props.text;
let markdownComponents = {
a: LinkRenderer,
h1: (props) => HeaderRenderer(props, 1),
h2: (props) => HeaderRenderer(props, 2),
h3: (props) => HeaderRenderer(props, 3),
h4: (props) => HeaderRenderer(props, 4),
h5: (props) => HeaderRenderer(props, 5),
h6: (props) => HeaderRenderer(props, 6),
};
return (
<div className={clsx("markdown", props.extraClassName)} style={props.style}>
<ReactMarkdown remarkPlugins={[remarkGfm]} components={markdownComponents}>
{text}
</ReactMarkdown>
</div>
);
}
export { Markdown };
+1 -1
View File
@@ -24,7 +24,7 @@ const blockAtomFamily = atomFamily<string, jotai.Atom<BlockData>>((blockId: stri
return jotai.atom({ blockid: blockId1, view: "term" });
}
if (blockId === blockId2) {
return jotai.atom({ blockid: blockId2, view: "preview" });
return jotai.atom({ blockid: blockId2, view: "preview", meta: { mimetype: "text/markdown" } });
}
if (blockId === blockId3) {
return jotai.atom({ blockid: blockId3, view: "term" });
-6
View File
@@ -22,10 +22,4 @@
border-radius: 4px;
padding: 5px;
}
.block1 {
}
.block2 {
}
}
+27
View File
@@ -3,10 +3,37 @@
import * as React from "react";
import * as jotai from "jotai";
import { atoms } from "@/store/global";
import { Markdown } from "@/element/markdown";
import "./view.less";
const markdownText = `
# Markdown Preview
* list item 1
* list item 2
* item 3
\`\`\`
let foo = "bar";
console.log(foo);
\`\`\`
`;
const MarkdownPreview = ({ blockData }: { blockData: BlockData }) => {
return (
<div className="view-preview view-preview-markdown">
<Markdown text={markdownText} />
</div>
);
};
const PreviewView = ({ blockId }: { blockId: string }) => {
const blockData: BlockData = jotai.useAtomValue(atoms.blockAtomFamily(blockId));
if (blockData.meta?.mimetype === "text/markdown") {
return <MarkdownPreview blockData={blockData} />;
}
return (
<div className="view-preview">
<div>Preview</div>
+5
View File
@@ -18,4 +18,9 @@
overflow: hidden;
align-items: center;
justify-content: center;
&.view-preview-markdown {
align-items: start;
justify-content: start;
}
}
+1
View File
@@ -11,6 +11,7 @@ declare global {
type BlockData = {
blockid: string;
view: string;
meta?: Record<string, any>;
};
}
+2
View File
@@ -10,6 +10,7 @@ import (
"log"
"github.com/wavetermdev/thenextwave/pkg/blockstore"
"github.com/wavetermdev/thenextwave/pkg/service/fileservice"
"github.com/wavetermdev/thenextwave/pkg/wavebase"
"github.com/wailsapp/wails/v3/pkg/application"
@@ -45,6 +46,7 @@ func main() {
Description: "The Next Wave Terminal",
Bind: []any{
&GreetService{},
&fileservice.FileService{},
},
Icon: appIcon,
Assets: application.AssetOptions{
+2
View File
@@ -25,6 +25,8 @@
"jotai": "^2.8.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-markdown": "^9.0.1",
"remark-gfm": "^4.0.0",
"rxjs": "^7.8.1",
"uuid": "^9.0.1"
}
+17
View File
@@ -0,0 +1,17 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
package fileservice
import (
"os"
"github.com/wavetermdev/thenextwave/pkg/wavebase"
)
type FileService struct{}
func (fs *FileService) ReadFile(path string) ([]byte, error) {
path = wavebase.ExpandHomeDir(path)
return os.ReadFile(path)
}
+2
View File
@@ -12,6 +12,8 @@
--app-accent-color: rgb(88, 193, 66);
--panel-bg-color: rgba(31, 33, 31, 1);
--highlight-bg-color: rgba(255, 255, 255, 0.2);
--markdown-font: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif,
"Apple Color Emoji", "Segoe UI Emoji";
}
body {
+1
View File
@@ -18,6 +18,7 @@
"@/app/*": ["frontend/app/*"],
"@/util/*": ["frontend/util/*"],
"@/store/*": ["frontend/app/store/*"],
"@/element/*": ["frontend/app/element/*"],
}
}
}
+836 -2
View File
File diff suppressed because it is too large Load Diff