load README.md into preview view

This commit is contained in:
sawka
2024-05-14 12:29:41 -07:00
parent 1db615bb3a
commit 91a3394602
13 changed files with 86 additions and 12 deletions
+2 -2
View File
@@ -371,7 +371,7 @@ tasks:
- install:frontend:deps
- generate:bindings
cmds:
- npm run build -q
- yarn build
generate:bindings:
summary: Generates bindings for the frontend
@@ -417,7 +417,7 @@ tasks:
deps:
- task: install:frontend:deps
cmds:
- npm run dev -- --port {{.VITE_PORT}} --strictPort
- yarn dev -- --port {{.VITE_PORT}} --strictPort
dev:
summary: Runs the application in development mode
-2
View File
@@ -4,10 +4,8 @@
import * as React from "react";
import * as jotai from "jotai";
import { Provider } from "jotai";
import * as rx from "rxjs";
import { clsx } from "clsx";
import { TabContent } from "@/app/tab/tab";
import { v4 as uuidv4 } from "uuid";
import { globalStore, atoms } from "@/store/global";
import "/public/style.less";
+2 -1
View File
@@ -7,6 +7,7 @@ import { atoms } from "@/store/global";
import { TerminalView } from "@/app/view/term";
import { PreviewView } from "@/app/view/preview";
import { CenteredLoadingDiv } from "@/element/quickelems";
import "./block.less";
@@ -40,7 +41,7 @@ const Block = ({ blockId }: { blockId: string }) => {
</div>
</div>
<div key="content" className="block-content">
{blockElem}
<React.Suspense fallback={<CenteredLoadingDiv />}>{blockElem}</React.Suspense>
</div>
</div>
);
+12
View File
@@ -0,0 +1,12 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
.centered-loading {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
overflow: hidden;
}
+14
View File
@@ -0,0 +1,14 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import "./quickelems.less";
function CenteredLoadingDiv() {
return (
<div className="centered-loading">
<div>Loading...</div>
</div>
);
}
export { CenteredLoadingDiv };
+5 -1
View File
@@ -24,7 +24,11 @@ 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", meta: { mimetype: "text/markdown" } });
return jotai.atom({
blockid: blockId2,
view: "preview",
meta: { mimetype: "text/markdown", file: "README.md" },
});
}
if (blockId === blockId3) {
return jotai.atom({ blockid: blockId3, view: "term" });
-3
View File
@@ -8,9 +8,6 @@ import { atoms } from "@/store/global";
import "./tab.less";
const blockId1 = "44113b0c-1528-4db1-94f0-2cafa1542941";
const blockId2 = "6bd76ccb-76ae-4f29-aa64-35206767e1ac";
const TabContent = ({ tabId }: { tabId: string }) => {
const tabs = jotai.useAtomValue(atoms.tabsAtom);
const tabData = tabs.find((tab) => tab.tabid === tabId);
+9 -1
View File
@@ -5,6 +5,8 @@ import * as React from "react";
import * as jotai from "jotai";
import { atoms } from "@/store/global";
import { Markdown } from "@/element/markdown";
import * as FileService from "@/bindings/pkg/service/fileservice/FileService";
import * as util from "@/util/util";
import "./view.less";
@@ -21,10 +23,16 @@ console.log(foo);
\`\`\`
`;
const readmeAtom = jotai.atom(async () => {
const readme = await FileService.ReadFile("README.md");
return util.base64ToString(readme);
});
const MarkdownPreview = ({ blockData }: { blockData: BlockData }) => {
const readmeText = jotai.useAtomValue(readmeAtom);
return (
<div className="view-preview view-preview-markdown">
<Markdown text={markdownText} />
<Markdown text={readmeText} />
</div>
);
};
+25
View File
@@ -0,0 +1,25 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0s
import base64 from "base64-js";
function base64ToString(b64: string): string {
const stringBytes = base64.toByteArray(b64);
return new TextDecoder().decode(stringBytes);
}
function stringToBase64(input: string): string {
const stringBytes = new TextEncoder().encode(input);
return base64.fromByteArray(stringBytes);
}
function base64ToArray(b64: string): Uint8Array {
const rawStr = atob(b64);
const rtnArr = new Uint8Array(new ArrayBuffer(rawStr.length));
for (let i = 0; i < rawStr.length; i++) {
rtnArr[i] = rawStr.charCodeAt(i);
}
return rtnArr;
}
export { base64ToString, stringToBase64, base64ToArray };
+1
View File
@@ -21,6 +21,7 @@
"dependencies": {
"@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0",
"base64-js": "^1.5.1",
"clsx": "^2.1.1",
"jotai": "^2.8.0",
"react": "^18.3.1",
+10 -2
View File
@@ -4,14 +4,22 @@
package fileservice
import (
"encoding/base64"
"fmt"
"os"
"time"
"github.com/wavetermdev/thenextwave/pkg/wavebase"
)
type FileService struct{}
func (fs *FileService) ReadFile(path string) ([]byte, error) {
func (fs *FileService) ReadFile(path string) (string, error) {
path = wavebase.ExpandHomeDir(path)
return os.ReadFile(path)
barr, err := os.ReadFile(path)
if err != nil {
return "", fmt.Errorf("cannot read file %q: %w", path, err)
}
time.Sleep(2 * time.Second)
return base64.StdEncoding.EncodeToString(barr), nil
}
+1
View File
@@ -19,6 +19,7 @@
"@/util/*": ["frontend/util/*"],
"@/store/*": ["frontend/app/store/*"],
"@/element/*": ["frontend/app/element/*"],
"@/bindings/*": ["frontend/bindings/*"],
}
}
}
+5
View File
@@ -580,6 +580,11 @@ bail@^2.0.0:
resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d"
integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==
base64-js@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
browserslist@^4.22.2:
version "4.23.0"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab"