Skip to content

Commit ef5a59e

Browse files
authored
tsunami app builder 2 (#2486)
1 parent 4276906 commit ef5a59e

38 files changed

+1269
-229
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,6 @@
6161
"QF1003": false
6262
},
6363
"directoryFilters": ["-tsunami/frontend/scaffold"]
64-
}
64+
},
65+
"tailwindCSS.lint.suggestCanonicalClasses": "ignore"
6566
}

emain/emain-ipc.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ export function initIpcHandlers() {
396396
});
397397

398398
electron.ipcMain.on("open-builder", (event, appId?: string) => {
399-
fireAndForget(() => createBuilderWindow(appId || "<new>"));
399+
fireAndForget(() => createBuilderWindow(appId || ""));
400400
});
401401

402402
electron.ipcMain.on("open-new-window", () => fireAndForget(createNewWaveWindow));

emain/emain-menu.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ async function getAppMenu(
9595
if (isDev) {
9696
fileMenu.splice(1, 0, {
9797
label: "New WaveApp Builder Window",
98-
click: () => fireAndForget(() => createBuilderWindow("<new>")),
98+
click: () => fireAndForget(() => createBuilderWindow("")),
9999
});
100100
}
101101
if (numWaveWindows == 0) {

frontend/app/aipanel/aipanel.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ const AIPanelComponentInner = memo(({ className, onClose }: AIPanelProps) => {
232232
};
233233
if (windowType === "builder") {
234234
body.builderid = globalStore.get(atoms.builderId);
235+
body.builderappid = globalStore.get(atoms.builderAppId);
235236
} else {
236237
body.tabid = globalStore.get(atoms.staticTabId);
237238
}

frontend/app/modals/modal.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
.modal-backdrop {
1616
position: fixed;
17-
top: 0;
17+
top: 36px;
1818
left: 0;
1919
right: 0;
2020
bottom: 0;

frontend/app/store/global.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
import { getWebServerEndpoint } from "@/util/endpoints";
1818
import { fetch } from "@/util/fetchutil";
1919
import { setPlatform } from "@/util/platformutil";
20-
import { deepCompareReturnPrev, fireAndForget, getPrefixedSettings, isBlank } from "@/util/util";
20+
import { base64ToString, deepCompareReturnPrev, fireAndForget, getPrefixedSettings, isBlank } from "@/util/util";
2121
import { atom, Atom, PrimitiveAtom, useAtomValue } from "jotai";
2222
import { globalStore } from "./jotaiStore";
2323
import { modalsModel } from "./modalmodel";
@@ -54,6 +54,7 @@ function initGlobalAtoms(initOpts: GlobalInitOptions) {
5454
const windowIdAtom = atom(initOpts.windowId) as PrimitiveAtom<string>;
5555
const clientIdAtom = atom(initOpts.clientId) as PrimitiveAtom<string>;
5656
const builderIdAtom = atom(initOpts.builderId) as PrimitiveAtom<string>;
57+
const builderAppIdAtom = atom<string>(null) as PrimitiveAtom<string>;
5758
const waveWindowTypeAtom = atom((get) => {
5859
const builderId = get(builderIdAtom);
5960
return builderId != null ? "builder" : "tab";
@@ -172,6 +173,7 @@ function initGlobalAtoms(initOpts: GlobalInitOptions) {
172173
// initialized in wave.ts (will not be null inside of application)
173174
clientId: clientIdAtom,
174175
builderId: builderIdAtom,
176+
builderAppId: builderAppIdAtom,
175177
waveWindowType: waveWindowTypeAtom,
176178
uiContext: uiContextAtom,
177179
client: clientAtom,
@@ -547,7 +549,7 @@ async function fetchWaveFile(
547549
if (fileInfo64 == null) {
548550
throw new Error(`missing zone file info for ${zoneId}:${fileName}`);
549551
}
550-
const fileInfo = JSON.parse(atob(fileInfo64));
552+
const fileInfo = JSON.parse(base64ToString(fileInfo64));
551553
const data = await resp.arrayBuffer();
552554
return { data: new Uint8Array(data), fileInfo };
553555
}

frontend/app/store/tabrpcclient.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { WaveAIModel } from "@/app/aipanel/waveai-model";
55
import { getApi } from "@/app/store/global";
66
import { WorkspaceLayoutModel } from "@/app/workspace/workspace-layout-model";
77
import { getLayoutModelForStaticTab } from "@/layout/index";
8-
import { base64ToArray } from "@/util/util";
8+
import { base64ToArrayBuffer } from "@/util/util";
99
import { RpcResponseHelper, WshClient } from "./wshclient";
1010

1111
export class TabClient extends WshClient {
@@ -74,7 +74,7 @@ export class TabClient extends WshClient {
7474

7575
if (data.files && data.files.length > 0) {
7676
for (const fileData of data.files) {
77-
const decodedData = base64ToArray(fileData.data64);
77+
const decodedData = base64ToArrayBuffer(fileData.data64);
7878
const blob = new Blob([decodedData], { type: fileData.type });
7979
const file = new File([blob], fileData.name, { type: fileData.type });
8080
await model.addFile(file);

frontend/app/store/wshclientapi.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ class RpcApiType {
112112
return client.wshRpcCall("createsubblock", data, opts);
113113
}
114114

115+
// command "deleteappfile" [call]
116+
DeleteAppFileCommand(client: WshClient, data: CommandDeleteAppFileData, opts?: RpcOpts): Promise<void> {
117+
return client.wshRpcCall("deleteappfile", data, opts);
118+
}
119+
115120
// command "deleteblock" [call]
116121
DeleteBlockCommand(client: WshClient, data: CommandDeleteBlockData, opts?: RpcOpts): Promise<void> {
117122
return client.wshRpcCall("deleteblock", data, opts);
@@ -297,6 +302,16 @@ class RpcApiType {
297302
return client.wshRpcCall("getwaveairatelimit", null, opts);
298303
}
299304

305+
// command "listallappfiles" [call]
306+
ListAllAppFilesCommand(client: WshClient, data: CommandListAllAppFilesData, opts?: RpcOpts): Promise<CommandListAllAppFilesRtnData> {
307+
return client.wshRpcCall("listallappfiles", data, opts);
308+
}
309+
310+
// command "listalleditableapps" [call]
311+
ListAllEditableAppsCommand(client: WshClient, opts?: RpcOpts): Promise<string[]> {
312+
return client.wshRpcCall("listalleditableapps", null, opts);
313+
}
314+
300315
// command "message" [call]
301316
MessageCommand(client: WshClient, data: CommandMessageData, opts?: RpcOpts): Promise<void> {
302317
return client.wshRpcCall("message", data, opts);
@@ -312,6 +327,11 @@ class RpcApiType {
312327
return client.wshRpcCall("path", data, opts);
313328
}
314329

330+
// command "readappfile" [call]
331+
ReadAppFileCommand(client: WshClient, data: CommandReadAppFileData, opts?: RpcOpts): Promise<CommandReadAppFileRtnData> {
332+
return client.wshRpcCall("readappfile", data, opts);
333+
}
334+
315335
// command "recordtevent" [call]
316336
RecordTEventCommand(client: WshClient, data: TEvent, opts?: RpcOpts): Promise<void> {
317337
return client.wshRpcCall("recordtevent", data, opts);
@@ -387,6 +407,11 @@ class RpcApiType {
387407
return client.wshRpcCall("remotewritefile", data, opts);
388408
}
389409

410+
// command "renameappfile" [call]
411+
RenameAppFileCommand(client: WshClient, data: CommandRenameAppFileData, opts?: RpcOpts): Promise<void> {
412+
return client.wshRpcCall("renameappfile", data, opts);
413+
}
414+
390415
// command "resolveids" [call]
391416
ResolveIdsCommand(client: WshClient, data: CommandResolveIdsData, opts?: RpcOpts): Promise<CommandResolveIdsRtnData> {
392417
return client.wshRpcCall("resolveids", data, opts);
@@ -517,6 +542,11 @@ class RpcApiType {
517542
return client.wshRpcCall("workspacelist", null, opts);
518543
}
519544

545+
// command "writeappfile" [call]
546+
WriteAppFileCommand(client: WshClient, data: CommandWriteAppFileData, opts?: RpcOpts): Promise<void> {
547+
return client.wshRpcCall("writeappfile", data, opts);
548+
}
549+
520550
// command "wshactivity" [call]
521551
WshActivityCommand(client: WshClient, data: {[key: string]: number}, opts?: RpcOpts): Promise<void> {
522552
return client.wshRpcCall("wshactivity", data, opts);

frontend/app/view/term/termwrap.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { TabRpcClient } from "@/app/store/wshrpcutil";
88
import { WOS, atoms, fetchWaveFile, getSettingsKeyAtom, globalStore, openLink } from "@/store/global";
99
import * as services from "@/store/services";
1010
import { PLATFORM, PlatformMacOS } from "@/util/platformutil";
11-
import { base64ToArray, fireAndForget } from "@/util/util";
11+
import { base64ToArray, base64ToString, fireAndForget } from "@/util/util";
1212
import { SearchAddon } from "@xterm/addon-search";
1313
import { SerializeAddon } from "@xterm/addon-serialize";
1414
import { WebLinksAddon } from "@xterm/addon-web-links";
@@ -259,7 +259,7 @@ function handleOsc16162Command(data: string, blockId: string, loaded: boolean, t
259259
globalStore.set(termWrap.lastCommandAtom, rtInfo["shell:lastcmd"]);
260260
} else {
261261
try {
262-
const decodedCmd = atob(cmd.data.cmd64);
262+
const decodedCmd = base64ToString(cmd.data.cmd64);
263263
rtInfo["shell:lastcmd"] = decodedCmd;
264264
globalStore.set(termWrap.lastCommandAtom, decodedCmd);
265265
} catch (e) {
@@ -364,9 +364,7 @@ export class TermWrap {
364364
this.hasResized = false;
365365
this.lastUpdated = Date.now();
366366
this.promptMarkers = [];
367-
this.shellIntegrationStatusAtom = jotai.atom(null) as jotai.PrimitiveAtom<
368-
"ready" | "running-command" | null
369-
>;
367+
this.shellIntegrationStatusAtom = jotai.atom(null) as jotai.PrimitiveAtom<"ready" | "running-command" | null>;
370368
this.lastCommandAtom = jotai.atom(null) as jotai.PrimitiveAtom<string | null>;
371369
this.terminal = new Terminal(options);
372370
this.fitAddon = new FitAddon();
@@ -460,25 +458,25 @@ export class TermWrap {
460458
}
461459
this.mainFileSubject = getFileSubject(this.blockId, TermFileName);
462460
this.mainFileSubject.subscribe(this.handleNewFileSubjectData.bind(this));
463-
461+
464462
try {
465463
const rtInfo = await RpcApi.GetRTInfoCommand(TabRpcClient, {
466464
oref: WOS.makeORef("block", this.blockId),
467465
});
468-
466+
469467
if (rtInfo["shell:integration"]) {
470468
const shellState = rtInfo["shell:state"] as ShellIntegrationStatus;
471469
globalStore.set(this.shellIntegrationStatusAtom, shellState || null);
472470
} else {
473471
globalStore.set(this.shellIntegrationStatusAtom, null);
474472
}
475-
473+
476474
const lastCmd = rtInfo["shell:lastcmd"];
477475
globalStore.set(this.lastCommandAtom, lastCmd || null);
478476
} catch (e) {
479477
console.log("Error loading runtime info:", e);
480478
}
481-
479+
482480
try {
483481
await this.loadInitialTerminalData();
484482
} finally {

0 commit comments

Comments
 (0)