Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frontend/app/block/blockenv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export type BlockEnv = WaveEnvSubset<{
| "window:magnifiedblockblurprimarypx"
| "window:magnifiedblockopacity"
>;
showContextMenu: WaveEnv["showContextMenu"];
atoms: {
modalOpen: WaveEnv["atoms"]["modalOpen"];
controlShiftDelayAtom: WaveEnv["atoms"]["controlShiftDelayAtom"];
Expand Down
13 changes: 7 additions & 6 deletions frontend/app/block/blockframe-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,26 @@ import {
import { ConnectionButton } from "@/app/block/connectionbutton";
import { DurableSessionFlyover } from "@/app/block/durable-session-flyover";
import { getBlockBadgeAtom } from "@/app/store/badge";
import { ContextMenuModel } from "@/app/store/contextmenu";
import { recordTEvent, refocusNode } from "@/app/store/global";
import { globalStore } from "@/app/store/jotaiStore";
import { uxCloseBlock } from "@/app/store/keymodel";
import { TabRpcClient } from "@/app/store/wshrpcutil";
import { useWaveEnv } from "@/app/waveenv/waveenv";
import { BlockEnv } from "./blockenv";
import { IconButton } from "@/element/iconbutton";
import { NodeModel } from "@/layout/index";
import * as util from "@/util/util";
import { cn, makeIconClass } from "@/util/util";
import * as jotai from "jotai";
import * as React from "react";
import { BlockEnv } from "./blockenv";
import { BlockFrameProps } from "./blocktypes";

function handleHeaderContextMenu(
e: React.MouseEvent<HTMLDivElement>,
blockId: string,
viewModel: ViewModel,
nodeModel: NodeModel
nodeModel: NodeModel,
blockEnv: BlockEnv
) {
e.preventDefault();
e.stopPropagation();
Expand Down Expand Up @@ -59,7 +59,7 @@ function handleHeaderContextMenu(
click: () => uxCloseBlock(blockId),
}
);
ContextMenuModel.getInstance().showContextMenu(menu, e);
blockEnv.showContextMenu(menu, e);
}

type HeaderTextElemsProps = {
Expand Down Expand Up @@ -113,6 +113,7 @@ type HeaderEndIconsProps = {
};

const HeaderEndIcons = React.memo(({ viewModel, nodeModel, blockId }: HeaderEndIconsProps) => {
const blockEnv = useWaveEnv<BlockEnv>();
const endIconButtons = util.useAtomValueSafe(viewModel?.endIconButtons);
const magnified = jotai.useAtomValue(nodeModel.isMagnified);
const ephemeral = jotai.useAtomValue(nodeModel.isEphemeral);
Expand All @@ -128,7 +129,7 @@ const HeaderEndIcons = React.memo(({ viewModel, nodeModel, blockId }: HeaderEndI
elemtype: "iconbutton",
icon: "cog",
title: "Settings",
click: (e) => handleHeaderContextMenu(e, blockId, viewModel, nodeModel),
click: (e) => handleHeaderContextMenu(e, blockId, viewModel, nodeModel, blockEnv),
};
endIconsElem.push(<IconButton key="settings" decl={settingsDecl} className="block-frame-settings" />);
if (ephemeral) {
Expand Down Expand Up @@ -211,7 +212,7 @@ const BlockFrame_Header = ({
className={cn("block-frame-default-header", useTermHeader && "!pl-[2px]")}
data-role="block-header"
ref={dragHandleRef}
onContextMenu={(e) => handleHeaderContextMenu(e, nodeModel.blockId, viewModel, nodeModel)}
onContextMenu={(e) => handleHeaderContextMenu(e, nodeModel.blockId, viewModel, nodeModel, waveEnv)}
>
{!useTermHeader && (
<>
Expand Down
16 changes: 16 additions & 0 deletions frontend/preview/mock/mockwaveenv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { previewElectronApi } from "./preview-electron-api";
// is purely FE-based (registered via WPS on the frontend)
// - rpc.GetMetaCommand -- reads .meta from the mock WOS atom for the given oref
// - rpc.SetMetaCommand -- writes .meta to the mock WOS atom (null values delete keys)
// - rpc.SetConfigCommand -- merges settings into fullConfigAtom (null values delete keys)
// - rpc.UpdateTabNameCommand -- updates .name on the Tab WaveObj in the mock WOS
// - rpc.UpdateWorkspaceTabIdsCommand -- updates .tabids on the Workspace WaveObj in the mock WOS
//
Expand Down Expand Up @@ -173,6 +174,7 @@ function makeMockGlobalAtoms(
type MockWosFns = {
getWaveObjectAtom: <T extends WaveObj>(oref: string) => PrimitiveAtom<T>;
mockSetWaveObj: <T extends WaveObj>(oref: string, obj: T) => void;
fullConfigAtom: PrimitiveAtom<FullConfigType>;
};

export function makeMockRpc(overrides: RpcOverrides, wos: MockWosFns): RpcApiType {
Expand Down Expand Up @@ -211,6 +213,19 @@ export function makeMockRpc(overrides: RpcOverrides, wos: MockWosFns): RpcApiTyp
wos.mockSetWaveObj(tabORef, updated);
return null;
});
dispatchMap.set("setconfig", async (_client, data: SettingsType) => {
const current = globalStore.get(wos.fullConfigAtom);
const updatedSettings = { ...(current?.settings ?? {}) };
for (const [key, value] of Object.entries(data)) {
if (value === null) {
delete (updatedSettings as any)[key];
} else {
(updatedSettings as any)[key] = value;
}
}
globalStore.set(wos.fullConfigAtom, { ...current, settings: updatedSettings as SettingsType });
return null;
});
dispatchMap.set("updateworkspacetabids", async (_client, data: { args: [string, string[]] }) => {
const [workspaceId, tabIds] = data.args;
const wsORef = "workspace:" + workspaceId;
Expand Down Expand Up @@ -280,6 +295,7 @@ export function makeMockWaveEnv(mockEnv?: MockEnv): MockWaveEnv {
});
const mockWosFns: MockWosFns = {
getWaveObjectAtom,
fullConfigAtom: atoms.fullConfigAtom,
mockSetWaveObj: <T extends WaveObj>(oref: string, obj: T) => {
if (!waveObjectValueAtomCache.has(oref)) {
waveObjectValueAtomCache.set(oref, atom(null as WaveObj));
Expand Down
Loading