diff --git a/Taskfile.yml b/Taskfile.yml
index 34ba76b8..45a43bae 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -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
diff --git a/frontend/app/app.tsx b/frontend/app/app.tsx
index d012c390..a5f62945 100644
--- a/frontend/app/app.tsx
+++ b/frontend/app/app.tsx
@@ -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";
diff --git a/frontend/app/block/block.tsx b/frontend/app/block/block.tsx
index 22a00fac..d6232ee0 100644
--- a/frontend/app/block/block.tsx
+++ b/frontend/app/block/block.tsx
@@ -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 }) => {
- {blockElem}
+ }>{blockElem}
);
diff --git a/frontend/app/element/quickelems.less b/frontend/app/element/quickelems.less
new file mode 100644
index 00000000..c443f31c
--- /dev/null
+++ b/frontend/app/element/quickelems.less
@@ -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;
+}
diff --git a/frontend/app/element/quickelems.tsx b/frontend/app/element/quickelems.tsx
new file mode 100644
index 00000000..9717ee43
--- /dev/null
+++ b/frontend/app/element/quickelems.tsx
@@ -0,0 +1,14 @@
+// Copyright 2024, Command Line Inc.
+// SPDX-License-Identifier: Apache-2.0
+
+import "./quickelems.less";
+
+function CenteredLoadingDiv() {
+ return (
+
+ );
+}
+
+export { CenteredLoadingDiv };
diff --git a/frontend/app/store/global.ts b/frontend/app/store/global.ts
index dcd9ff7d..55825f03 100644
--- a/frontend/app/store/global.ts
+++ b/frontend/app/store/global.ts
@@ -24,7 +24,11 @@ const blockAtomFamily = atomFamily>((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" });
diff --git a/frontend/app/tab/tab.tsx b/frontend/app/tab/tab.tsx
index dc9c2fbe..cb71ce9c 100644
--- a/frontend/app/tab/tab.tsx
+++ b/frontend/app/tab/tab.tsx
@@ -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);
diff --git a/frontend/app/view/preview.tsx b/frontend/app/view/preview.tsx
index 73ba5782..bbfa1188 100644
--- a/frontend/app/view/preview.tsx
+++ b/frontend/app/view/preview.tsx
@@ -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 (
-
+
);
};
diff --git a/frontend/util/util.ts b/frontend/util/util.ts
new file mode 100644
index 00000000..30b81906
--- /dev/null
+++ b/frontend/util/util.ts
@@ -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 };
diff --git a/package.json b/package.json
index 41f1c6fb..f4b68f3a 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/pkg/service/fileservice/fileservice.go b/pkg/service/fileservice/fileservice.go
index f2719c4d..da188bfc 100644
--- a/pkg/service/fileservice/fileservice.go
+++ b/pkg/service/fileservice/fileservice.go
@@ -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
}
diff --git a/tsconfig.json b/tsconfig.json
index 29e56263..ea96d997 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -19,6 +19,7 @@
"@/util/*": ["frontend/util/*"],
"@/store/*": ["frontend/app/store/*"],
"@/element/*": ["frontend/app/element/*"],
+ "@/bindings/*": ["frontend/bindings/*"],
}
}
}
diff --git a/yarn.lock b/yarn.lock
index a4313f61..f5dc0756 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -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"