move connection switching to blockheader (#276)

This commit is contained in:
Mike Sawka
2024-08-26 16:19:03 -07:00
committed by GitHub
parent f28bdccb5d
commit c2fe3b18e1
7 changed files with 142 additions and 100 deletions
+2 -1
View File
@@ -148,7 +148,7 @@
font-weight: 400;
color: var(--main-text-color);
border-radius: 2px;
padding-right: 6px;
padding-right: 2px;
&:hover {
background-color: var(--highlight-bg-color);
@@ -162,6 +162,7 @@
.connection-name {
flex: 1 100 auto;
overflow: hidden;
padding-right: 4px;
}
}
+2
View File
@@ -116,6 +116,7 @@ const BlockFull = React.memo(({ nodeModel, viewModel }: FullBlockProps) => {
counterInc("render-BlockFull");
const focusElemRef = React.useRef<HTMLInputElement>(null);
const blockRef = React.useRef<HTMLDivElement>(null);
const contentRef = React.useRef<HTMLDivElement>(null);
const [blockClicked, setBlockClicked] = React.useState(false);
const [blockData] = WOS.useWaveObjectValue<Block>(WOS.makeORef("block", nodeModel.blockId));
const [focusedChild, setFocusedChild] = React.useState(null);
@@ -202,6 +203,7 @@ const BlockFull = React.memo(({ nodeModel, viewModel }: FullBlockProps) => {
width: addlProps?.transform?.width,
height: addlProps?.transform?.height,
}}
ref={contentRef}
>
<ErrorBoundary>
<React.Suspense fallback={<CenteredDiv>Loading...</CenteredDiv>}>{viewElem}</React.Suspense>
+86 -2
View File
@@ -10,11 +10,14 @@ import {
Input,
} from "@/app/block/blockutil";
import { Button } from "@/app/element/button";
import { TypeAheadModal } from "@/app/modals/typeaheadmodal";
import { ContextMenuModel } from "@/app/store/contextmenu";
import { atoms, globalStore, WOS } from "@/app/store/global";
import * as services from "@/app/store/services";
import { WshServer } from "@/app/store/wshserver";
import { MagnifyIcon } from "@/element/magnify";
import { NodeModel } from "@/layout/index";
import * as keyutil from "@/util/keyutil";
import { checkKeyPressed, keydownWrapper } from "@/util/keyutil";
import * as util from "@/util/util";
import clsx from "clsx";
@@ -129,6 +132,7 @@ const BlockFrame_Header = ({ nodeModel, viewModel, preview }: BlockFrameProps) =
const preIconButton = util.useAtomValueSafe(viewModel.preIconButton);
const headerTextUnion = util.useAtomValueSafe(viewModel.viewText);
const magnified = jotai.useAtomValue(nodeModel.isMagnified);
const manageConnection = jotai.useAtomValue(viewModel.manageConnection);
const dragHandleRef = preview ? null : nodeModel.dragHandleRef;
const onContextMenu = React.useCallback(
@@ -163,6 +167,16 @@ const BlockFrame_Header = ({ nodeModel, viewModel, preview }: BlockFrameProps) =
} else if (Array.isArray(headerTextUnion)) {
headerTextElems.push(...renderHeaderElements(headerTextUnion, preview));
}
if (manageConnection) {
const connButtonElem = (
<ConnectionButton
key={nodeModel.blockId}
blockId={nodeModel.blockId}
connection={blockData?.meta?.connection}
/>
);
headerTextElems.unshift(connButtonElem);
}
return (
<div className="block-frame-default-header" ref={dragHandleRef} onContextMenu={onContextMenu}>
@@ -174,6 +188,7 @@ const BlockFrame_Header = ({ nodeModel, viewModel, preview }: BlockFrameProps) =
<div className="block-frame-blockid">[{nodeModel.blockId.substring(0, 8)}]</div>
)}
</div>
<div className="block-frame-textelems-wrapper">{headerTextElems}</div>
<div className="block-frame-end-icons">{endIconsElem}</div>
</div>
@@ -193,8 +208,6 @@ const HeaderTextElem = React.memo(({ elem, preview }: { elem: HeaderElem; previe
{elem.text}
</Button>
);
} else if (elem.elemtype == "connectionbutton") {
return <ConnectionButton decl={elem} />;
} else if (elem.elemtype == "div") {
return (
<div
@@ -294,6 +307,13 @@ const BlockFrame_Default_Component = (props: BlockFrameProps) => {
onKeyDown={keydownWrapper(handleKeyDown)}
>
<BlockMask nodeModel={nodeModel} />
{preview ? null : (
<ChangeConnectionBlockModal
blockId={nodeModel.blockId}
viewModel={viewModel}
blockRef={blockModel?.blockRef}
/>
)}
<div className="block-frame-default-inner" style={innerStyle}>
<BlockFrame_Header {...props} />
{preview ? previewElem : children}
@@ -302,6 +322,70 @@ const BlockFrame_Default_Component = (props: BlockFrameProps) => {
);
};
const ChangeConnectionBlockModal = React.memo(
({
blockId,
viewModel,
blockRef,
}: {
blockId: string;
viewModel: ViewModel;
blockRef: React.RefObject<HTMLDivElement>;
}) => {
const typeAhead = jotai.useAtomValue(atoms.typeAheadModalAtom);
const [connSelected, setConnSelected] = React.useState("");
const changeConnection = React.useCallback(
async (connName: string) => {
await WshServer.SetMetaCommand({
oref: WOS.makeORef("block", blockId),
meta: { connection: connName },
});
await WshServer.ControllerRestartCommand({ blockid: blockId });
},
[blockId]
);
const handleTypeAheadKeyDown = React.useCallback(
(waveEvent: WaveKeyboardEvent): boolean => {
if (keyutil.checkKeyPressed(waveEvent, "Enter")) {
changeConnection(connSelected);
globalStore.set(atoms.typeAheadModalAtom, {
...(typeAhead as TypeAheadModalType),
[blockId]: false,
});
setConnSelected("");
return true;
}
if (keyutil.checkKeyPressed(waveEvent, "Escape")) {
globalStore.set(atoms.typeAheadModalAtom, {
...(typeAhead as TypeAheadModalType),
[blockId]: false,
});
setConnSelected("");
viewModel.giveFocus();
return true;
}
},
[typeAhead, viewModel, blockId, connSelected]
);
if (!typeAhead[blockId]) {
return null;
}
return (
<TypeAheadModal
anchor={blockRef}
suggestions={[]}
onSelect={(selected: string) => {
changeConnection(selected);
}}
onKeyDown={(e) => keyutil.keydownWrapper(handleTypeAheadKeyDown)(e)}
onChange={(current: string) => setConnSelected(current)}
value={connSelected}
label="Switch Connection"
/>
);
}
);
const BlockFrame_Default = React.memo(BlockFrame_Default_Component) as typeof BlockFrame_Default_Component;
const BlockFrame = React.memo((props: BlockFrameProps) => {
+45 -13
View File
@@ -2,8 +2,10 @@
// SPDX-License-Identifier: Apache-2.0
import { useLongClick } from "@/app/hook/useLongClick";
import { atoms, getConnStatusAtom } from "@/app/store/global";
import * as util from "@/util/util";
import clsx from "clsx";
import * as jotai from "jotai";
import * as React from "react";
export const colorRegex = /^((#[0-9a-f]{6,8})|([a-z]+))$/;
@@ -168,30 +170,60 @@ export const IconButton = React.memo(({ decl, className }: { decl: HeaderIconBut
);
});
export const ConnectionButton = React.memo(({ decl }: { decl: ConnectionButton }) => {
export const ConnectionButton = React.memo(({ blockId, connection }: { blockId: string; connection: string }) => {
const [typeAhead, setTypeAhead] = jotai.useAtom(atoms.typeAheadModalAtom);
const buttonRef = React.useRef<HTMLDivElement>(null);
const isLocal = connection == "" || connection == "local";
const connStatusAtom = getConnStatusAtom(connection);
const connStatus = jotai.useAtomValue(connStatusAtom);
const showDisconnectedSlash = !isLocal && !connStatus?.connected;
let connIconElem: React.ReactNode = null;
let color = "#53b4ea";
const clickHandler = function () {
setTypeAhead({
...typeAhead,
[blockId]: true,
});
};
let titleText = null;
if (isLocal) {
color = "var(--grey-text-color)";
titleText = "Connected to Local Machine";
connIconElem = (
<i
className={clsx(util.makeIconClass("laptop", false), "fa-stack-1x")}
style={{ color: color, marginRight: 2 }}
/>
);
} else {
titleText = "Connected to " + connection;
if (!connStatus?.connected) {
color = "var(--grey-text-color)";
titleText = "Disconnected from " + connection;
}
connIconElem = (
<i
className={clsx(util.makeIconClass("arrow-right-arrow-left", false), "fa-stack-1x")}
style={{ color: color, marginRight: 2 }}
/>
);
}
return (
<div ref={buttonRef} className={clsx("connection-button")} onClick={decl.onClick}>
<div ref={buttonRef} className={clsx("connection-button")} onClick={clickHandler} title={titleText}>
<span className="fa-stack connection-icon-box">
{typeof decl.icon === "string" ? (
<i
className={clsx(util.makeIconClass(decl.icon, true), "fa-stack-1x")}
style={{ color: decl.iconColor, marginRight: "2px" }}
/>
) : (
decl.icon
)}
{connIconElem}
<i
className="fa-slash fa-solid fa-stack-1x"
style={{
color: decl.iconColor,
color: color,
marginRight: "2px",
textShadow: "0 1px black, 0 1.5px black",
opacity: decl.connected ? 0 : 1,
opacity: showDisconnectedSlash ? 1 : 0,
}}
/>
</span>
<div className="connection-name">{decl.text}</div>
{isLocal ? null : <div className="connection-name">{connection}</div>}
</div>
);
});