Add flag for specifying a new node as magnified on insert (#253)

This commit is contained in:
Evan Simkowitz 2024-08-20 20:14:14 -07:00 committed by GitHub
parent bd4bf93d4a
commit 23261a7a98
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 62 additions and 34 deletions

View File

@ -14,6 +14,8 @@ import (
"github.com/wavetermdev/thenextwave/pkg/wshrpc/wshclient"
)
var editMagnified bool
var editCmd = &cobra.Command{
Use: "edit",
Short: "edit a file",
@ -23,6 +25,7 @@ var editCmd = &cobra.Command{
}
func init() {
editCmd.Flags().BoolVarP(&editMagnified, "magnified", "m", false, "open view in magnified mode")
rootCmd.AddCommand(editCmd)
}
@ -35,6 +38,7 @@ func editRun(cmd *cobra.Command, args []string) {
waveobj.MetaKey_File: fileArg,
},
},
Magnified: editMagnified,
}
if RpcContext.Conn != "" {
wshCmd.BlockDef.Meta[waveobj.MetaKey_Connection] = RpcContext.Conn

View File

@ -14,6 +14,8 @@ import (
"github.com/wavetermdev/thenextwave/pkg/wshrpc/wshclient"
)
var termMagnified bool
var termCmd = &cobra.Command{
Use: "term",
Short: "open a terminal in directory",
@ -23,6 +25,7 @@ var termCmd = &cobra.Command{
}
func init() {
termCmd.Flags().BoolVarP(&termMagnified, "magnified", "m", false, "open view in magnified mode")
rootCmd.AddCommand(termCmd)
}
@ -53,6 +56,7 @@ func termRun(cmd *cobra.Command, args []string) {
waveobj.MetaKey_Controller: "shell",
},
},
Magnified: termMagnified,
}
if RpcContext.Conn != "" {
createBlockData.BlockDef.Meta[waveobj.MetaKey_Connection] = RpcContext.Conn

View File

@ -15,6 +15,7 @@ import (
)
var viewNewBlock bool
var viewMagnified bool
var viewCmd = &cobra.Command{
Use: "view",
@ -26,6 +27,7 @@ var viewCmd = &cobra.Command{
func init() {
viewCmd.Flags().BoolVarP(&viewNewBlock, "newblock", "n", false, "open view in a new block")
viewCmd.Flags().BoolVarP(&viewMagnified, "magnified", "m", false, "open view in magnified mode")
rootCmd.AddCommand(viewCmd)
}
@ -41,6 +43,7 @@ func viewRun(cmd *cobra.Command, args []string) {
waveobj.MetaKey_Url: fileArg,
},
},
Magnified: viewMagnified,
}
} else {
absFile, err := filepath.Abs(fileArg)
@ -64,6 +67,7 @@ func viewRun(cmd *cobra.Command, args []string) {
waveobj.MetaKey_File: absFile,
},
},
Magnified: viewMagnified,
}
if conn != "" {
wshCmd.BlockDef.Meta[waveobj.MetaKey_Connection] = conn

View File

@ -277,6 +277,7 @@ function handleWSEventMessage(msg: WSEventType) {
node: newLayoutNode(undefined, undefined, undefined, {
blockId: layoutAction.blockid,
}),
magnified: layoutAction.magnified,
};
layoutModel.treeReducer(insertNodeAction);
break;
@ -304,6 +305,7 @@ function handleWSEventMessage(msg: WSEventType) {
blockId: layoutAction.blockid,
}),
indexArr: layoutAction.indexarr,
magnified: layoutAction.magnified,
};
layoutModel.treeReducer(insertAction);
break;

View File

@ -175,7 +175,6 @@ const DisplayNode = ({ layoutModel, layoutNode, contents }: DisplayNodeProps) =>
const addlProps = useLayoutNode(layoutModel, layoutNode);
const activeDrag = useAtomValue(layoutModel.activeDrag);
const globalReady = useAtomValue(layoutModel.ready);
const layoutGeneration = useAtomValue(layoutModel.generationAtom);
const devicePixelRatio = useDevicePixelRatio();
@ -183,12 +182,12 @@ const DisplayNode = ({ layoutModel, layoutNode, contents }: DisplayNodeProps) =>
() => ({
type: dragItemType,
item: () => layoutNode,
canDrag: () => !layoutModel?.treeState?.magnifiedNodeId,
canDrag: () => !addlProps?.isMagnifiedNode,
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
}),
[layoutNode, layoutGeneration]
[layoutNode, addlProps]
);
const [previewElementGeneration, setPreviewElementGeneration] = useState(0);
@ -249,7 +248,7 @@ const DisplayNode = ({ layoutModel, layoutNode, contents }: DisplayNodeProps) =>
{contents.renderContent(
layoutNode.data,
globalReady,
layoutNode.id === layoutModel.treeState.magnifiedNodeId,
addlProps?.isMagnifiedNode ?? false,
activeDrag,
() => layoutModel.magnifyNodeToggle(layoutNode),
() => layoutModel.closeNode(layoutNode),
@ -258,13 +257,13 @@ const DisplayNode = ({ layoutModel, layoutNode, contents }: DisplayNodeProps) =>
</div>
)
);
}, [layoutNode, globalReady, layoutGeneration, activeDrag, addlProps]);
}, [layoutNode, globalReady, activeDrag, addlProps]);
return (
<div
className={clsx("tile-node", {
dragging: isDragging,
magnified: layoutModel.treeState.magnifiedNodeId === layoutNode.id,
magnified: addlProps?.isMagnifiedNode,
"last-magnified": addlProps?.isLastMagnifiedNode,
})}
ref={tileNodeRef}

View File

@ -130,6 +130,10 @@ export class LayoutModel {
*/
overlayTransform: Atom<CSSProperties>;
/**
* The currently magnified node.
*/
magnifiedNodeId: string;
/**
* The last node to be magnified, other than the current magnified node, if set. This node should sit at a higher z-index than the others so that it floats above the other nodes as it returns to its original position.
*/
@ -314,6 +318,10 @@ export class LayoutModel {
}
if (stateChanged) {
console.log("state changed", this.treeState);
if (this.magnifiedNodeId !== this.treeState.magnifiedNodeId) {
this.lastMagnifiedNodeId = this.magnifiedNodeId;
this.magnifiedNodeId = this.treeState.magnifiedNodeId;
}
this.updateTree();
this.treeState.generation++;
this.setter(this.treeStateAtom, this.treeState);
@ -393,7 +401,7 @@ export class LayoutModel {
leafs.push(node);
const addlProps = additionalPropsMap[node.id];
if (addlProps) {
if (this.treeState.magnifiedNodeId === node.id) {
if (this.magnifiedNodeId === node.id) {
const boundingRect = getBoundingRect();
const transform = setTransform(
{
@ -405,6 +413,7 @@ export class LayoutModel {
true
);
addlProps.transform = transform;
addlProps.isMagnifiedNode = true;
}
addlProps.isLastMagnifiedNode = this.lastMagnifiedNodeId === node.id;
}
@ -578,12 +587,6 @@ export class LayoutModel {
nodeId: node.id,
};
// If the node is already magnified, then it is being un-magnified and should be set as the last-magnified node to ensure it has a higher z-index as it transitions back to its original position.
if (this.treeState.magnifiedNodeId === node.id) {
console.log("new last-magnified-node", node.id);
this.lastMagnifiedNodeId = node.id;
}
this.treeReducer(action);
}

View File

@ -43,6 +43,8 @@ export function useLayoutModel(tabAtom: Atom<Tab>): LayoutModel {
}
export function useTileLayout(tabAtom: Atom<Tab>, tileContent: TileLayoutContents): LayoutModel {
// Use tab data to ensure we can reload if the tab is disposed and remade (such as during Hot Module Reloading)
useAtomValue(tabAtom);
const layoutModel = useLayoutModel(tabAtom);
useResizeObserver(layoutModel?.displayContainerRef, layoutModel?.onContainerResize);
useEffect(() => layoutModel.registerTileLayout(tileContent), [tileContent]);

View File

@ -5,7 +5,6 @@ import { lazy } from "@/util/util";
import {
addChildAt,
addIntermediateNode,
balanceNode,
findInsertLocationFromIndexArr,
findNextInsertLocation,
findNode,
@ -256,8 +255,6 @@ export function moveNode(layoutState: LayoutTreeState, action: LayoutTreeMoveNod
if (oldParent) {
removeChild(oldParent, node, startingIndex);
}
layoutState.rootNode = balanceNode(layoutState.rootNode);
}
export function insertNode(layoutState: LayoutTreeState, action: LayoutTreeInsertNodeAction) {
@ -266,12 +263,14 @@ export function insertNode(layoutState: LayoutTreeState, action: LayoutTreeInser
return;
}
if (!layoutState.rootNode) {
layoutState.rootNode = balanceNode(action.node);
layoutState.rootNode = action.node;
return;
}
const insertLoc = findNextInsertLocation(layoutState.rootNode, 5);
addChildAt(insertLoc.node, insertLoc.index, action.node);
layoutState.rootNode = balanceNode(layoutState.rootNode);
if (action.magnified) {
layoutState.magnifiedNodeId = action.node.id;
}
}
export function insertNodeAtIndex(layoutState: LayoutTreeState, action: LayoutTreeInsertNodeAtIndexAction) {
@ -280,7 +279,7 @@ export function insertNodeAtIndex(layoutState: LayoutTreeState, action: LayoutTr
return;
}
if (!layoutState.rootNode) {
layoutState.rootNode = balanceNode(action.node);
layoutState.rootNode = action.node;
return;
}
const insertLoc = findInsertLocationFromIndexArr(layoutState.rootNode, action.indexArr);
@ -289,7 +288,9 @@ export function insertNodeAtIndex(layoutState: LayoutTreeState, action: LayoutTr
return;
}
addChildAt(insertLoc.node, insertLoc.index + 1, action.node);
layoutState.rootNode = balanceNode(layoutState.rootNode);
if (action.magnified) {
layoutState.magnifiedNodeId = action.node.id;
}
}
export function swapNode(layoutState: LayoutTreeState, action: LayoutTreeSwapNodeAction) {
@ -323,8 +324,6 @@ export function swapNode(layoutState: LayoutTreeState, action: LayoutTreeSwapNod
parentNode1.children[parentNode1Index] = node2;
parentNode2.children[parentNode2Index] = node1;
layoutState.rootNode = balanceNode(layoutState.rootNode);
}
export function deleteNode(layoutState: LayoutTreeState, action: LayoutTreeDeleteNodeAction) {
@ -349,7 +348,6 @@ export function deleteNode(layoutState: LayoutTreeState, action: LayoutTreeDelet
} else {
console.error("unable to delete node, not found in tree");
}
layoutState.rootNode = balanceNode(layoutState.rootNode);
}
export function resizeNode(layoutState: LayoutTreeState, action: LayoutTreeResizeNodeAction) {

View File

@ -93,24 +93,30 @@ export interface LayoutTreeSwapNodeAction extends LayoutTreeAction {
node2Id: string;
}
interface InsertNodeOperation {
/**
* The node to insert.
*/
node: LayoutNode;
/**
* Whether the inserted node should be magnified.
*/
magnified?: boolean;
}
/**
* Action for inserting a new node to the layout tree.
*
*/
export interface LayoutTreeInsertNodeAction extends LayoutTreeAction {
export interface LayoutTreeInsertNodeAction extends LayoutTreeAction, InsertNodeOperation {
type: LayoutTreeActionType.InsertNode;
node: LayoutNode;
}
/**
* Action for inserting a node into the layout tree at the specified index.
*/
export interface LayoutTreeInsertNodeAtIndexAction extends LayoutTreeAction {
export interface LayoutTreeInsertNodeAtIndexAction extends LayoutTreeAction, InsertNodeOperation {
type: LayoutTreeActionType.InsertNodeAtIndex;
/**
* The node to insert.
*/
node: LayoutNode;
/**
* The array of indices to traverse when inserting the node.
* The last index is the index within the parent node where the node should be inserted.
@ -274,5 +280,6 @@ export interface LayoutNodeAdditionalProps {
rect?: Dimensions;
pixelToSizeRatio?: number;
resizeHandles?: ResizeHandleProps[];
isMagnifiedNode?: boolean;
isLastMagnifiedNode?: boolean;
}

View File

@ -95,7 +95,8 @@ declare global {
type CommandCreateBlockData = {
tabid: string;
blockdef: BlockDef;
rtopts: RuntimeOpts;
rtopts?: RuntimeOpts;
magnified?: boolean;
};
// wshrpc.CommandDeleteBlockData
@ -522,6 +523,7 @@ declare global {
blockid: string;
nodesize?: number;
indexarr?: number[];
magnified?: boolean;
};
// webcmd.WSRpcCommand

View File

@ -62,6 +62,7 @@ type WSLayoutActionData struct {
BlockId string `json:"blockid"`
NodeSize uint `json:"nodesize,omitempty"`
IndexArr []int `json:"indexarr,omitempty"`
Magnified bool `json:"magnified,omitempty"`
}
var globalLock = &sync.Mutex{}

View File

@ -185,9 +185,10 @@ type CommandResolveIdsRtnData struct {
}
type CommandCreateBlockData struct {
TabId string `json:"tabid" wshcontext:"TabId"`
BlockDef *waveobj.BlockDef `json:"blockdef"`
RtOpts *waveobj.RuntimeOpts `json:"rtopts"`
TabId string `json:"tabid" wshcontext:"TabId"`
BlockDef *waveobj.BlockDef `json:"blockdef"`
RtOpts *waveobj.RuntimeOpts `json:"rtopts,omitempty"`
Magnified bool `json:"magnified,omitempty"`
}
type CommandBlockSetViewData struct {

View File

@ -293,6 +293,7 @@ func (ws *WshServer) CreateBlockCommand(ctx context.Context, data wshrpc.Command
ActionType: "insert",
TabId: tabId,
BlockId: blockData.OID,
Magnified: data.Magnified,
},
})
return &waveobj.ORef{OType: waveobj.OType_Block, OID: blockData.OID}, nil