separate cmd+o from switch connection (disconnect typeaaheadatom), and allow width to 95%

This commit is contained in:
sawka 2024-08-26 21:03:12 -07:00
parent a665d372e3
commit c2d2ad9136
3 changed files with 86 additions and 69 deletions

View File

@ -12,7 +12,7 @@ import {
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 { atoms, globalStore, useBlockAtom, WOS } from "@/app/store/global";
import * as services from "@/app/store/services";
import { WshServer } from "@/app/store/wshserver";
import { MagnifyIcon } from "@/element/magnify";
@ -124,7 +124,12 @@ function computeEndIcons(
return endIconsElem;
}
const BlockFrame_Header = ({ nodeModel, viewModel, preview }: BlockFrameProps) => {
const BlockFrame_Header = ({
nodeModel,
viewModel,
preview,
changeConnModalAtom,
}: BlockFrameProps & { changeConnModalAtom: jotai.PrimitiveAtom<boolean> }) => {
const [blockData] = WOS.useWaveObjectValue<Block>(WOS.makeORef("block", nodeModel.blockId));
const viewName = util.useAtomValueSafe(viewModel.viewName) ?? blockViewToName(blockData?.meta?.view);
const settingsConfig = jotai.useAtomValue(atoms.settingsConfigAtom);
@ -173,6 +178,7 @@ const BlockFrame_Header = ({ nodeModel, viewModel, preview }: BlockFrameProps) =
key={nodeModel.blockId}
blockId={nodeModel.blockId}
connection={blockData?.meta?.connection}
changeConnModalAtom={changeConnModalAtom}
/>
);
headerTextElems.unshift(connButtonElem);
@ -270,6 +276,9 @@ const BlockFrame_Default_Component = (props: BlockFrameProps) => {
const isFocused = jotai.useAtomValue(nodeModel.isFocused);
const viewIconUnion = util.useAtomValueSafe(viewModel.viewIcon) ?? blockViewToIcon(blockData?.meta?.view);
const customBg = util.useAtomValueSafe(viewModel.blockBg);
const changeConnModalAtom = useBlockAtom(nodeModel.blockId, "changeConn", () => {
return jotai.atom(false);
}) as jotai.PrimitiveAtom<boolean>;
const viewIconElem = getViewIconElem(viewIconUnion, blockData);
@ -312,10 +321,11 @@ const BlockFrame_Default_Component = (props: BlockFrameProps) => {
blockId={nodeModel.blockId}
viewModel={viewModel}
blockRef={blockModel?.blockRef}
changeConnModalAtom={changeConnModalAtom}
/>
)}
<div className="block-frame-default-inner" style={innerStyle}>
<BlockFrame_Header {...props} />
<BlockFrame_Header {...props} changeConnModalAtom={changeConnModalAtom} />
{preview ? previewElem : children}
</div>
</div>
@ -327,13 +337,15 @@ const ChangeConnectionBlockModal = React.memo(
blockId,
viewModel,
blockRef,
changeConnModalAtom,
}: {
blockId: string;
viewModel: ViewModel;
blockRef: React.RefObject<HTMLDivElement>;
changeConnModalAtom: jotai.PrimitiveAtom<boolean>;
}) => {
const typeAhead = jotai.useAtomValue(atoms.typeAheadModalAtom);
const [connSelected, setConnSelected] = React.useState("");
const changeConnModalOpen = jotai.useAtomValue(changeConnModalAtom);
const changeConnection = React.useCallback(
async (connName: string) => {
await WshServer.SetMetaCommand({
@ -348,26 +360,20 @@ const ChangeConnectionBlockModal = React.memo(
(waveEvent: WaveKeyboardEvent): boolean => {
if (keyutil.checkKeyPressed(waveEvent, "Enter")) {
changeConnection(connSelected);
globalStore.set(atoms.typeAheadModalAtom, {
...(typeAhead as TypeAheadModalType),
[blockId]: false,
});
globalStore.set(changeConnModalAtom, false);
setConnSelected("");
return true;
}
if (keyutil.checkKeyPressed(waveEvent, "Escape")) {
globalStore.set(atoms.typeAheadModalAtom, {
...(typeAhead as TypeAheadModalType),
[blockId]: false,
});
globalStore.set(changeConnModalAtom, false);
setConnSelected("");
viewModel.giveFocus();
return true;
}
},
[typeAhead, viewModel, blockId, connSelected]
[changeConnModalAtom, viewModel, blockId, connSelected]
);
if (!typeAhead[blockId]) {
if (!changeConnModalOpen) {
return null;
}
return (

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import { useLongClick } from "@/app/hook/useLongClick";
import { atoms, getConnStatusAtom } from "@/app/store/global";
import { getConnStatusAtom } from "@/app/store/global";
import * as util from "@/util/util";
import clsx from "clsx";
import * as jotai from "jotai";
@ -170,63 +170,70 @@ export const IconButton = React.memo(({ decl, className }: { decl: HeaderIconBut
);
});
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 = util.isBlank(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) {
export const ConnectionButton = React.memo(
({
blockId,
connection,
changeConnModalAtom,
}: {
blockId: string;
connection: string;
changeConnModalAtom: jotai.PrimitiveAtom<boolean>;
}) => {
const [connModalOpen, setConnModalOpen] = jotai.useAtom(changeConnModalAtom);
const buttonRef = React.useRef<HTMLDivElement>(null);
const isLocal = util.isBlank(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 () {
setConnModalOpen(true);
};
let titleText = null;
if (isLocal) {
color = "var(--grey-text-color)";
titleText = "Disconnected from " + connection;
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 }}
/>
);
}
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={clickHandler} title={titleText}>
<span className="fa-stack connection-icon-box">
{connIconElem}
<i
className="fa-slash fa-solid fa-stack-1x"
style={{
color: color,
marginRight: "2px",
textShadow: "0 1px black, 0 1.5px black",
opacity: showDisconnectedSlash ? 1 : 0,
}}
/>
</span>
{isLocal ? null : <div className="connection-name">{connection}</div>}
</div>
);
}
return (
<div ref={buttonRef} className={clsx("connection-button")} onClick={clickHandler} title={titleText}>
<span className="fa-stack connection-icon-box">
{connIconElem}
<i
className="fa-slash fa-solid fa-stack-1x"
style={{
color: color,
marginRight: "2px",
textShadow: "0 1px black, 0 1.5px black",
opacity: showDisconnectedSlash ? 1 : 0,
}}
/>
</span>
{isLocal ? null : <div className="connection-name">{connection}</div>}
</div>
);
});
);
export const Input = React.memo(
({ decl, className, preview }: { decl: HeaderInput; className: string; preview: boolean }) => {

View File

@ -159,6 +159,10 @@ const TypeAheadModal = ({
onSelect && onSelect(value);
};
let modalWidth = width * 0.6;
if (modalWidth < 300) {
modalWidth = Math.min(300, width * 0.95);
}
const renderModal = () => (
<div className="type-ahead-modal-wrapper" onKeyDown={handleKeyDown}>
{renderBackdrop(onClickBackdrop)}
@ -166,7 +170,7 @@ const TypeAheadModal = ({
ref={modalRef}
className={clsx("type-ahead-modal", className)}
style={{
width: width * 0.6,
width: modalWidth,
maxHeight: modalHeight,
}}
>