From a3958b6a64b03cbbe3895a460770af5c1e222149 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 30 Apr 2021 15:09:32 +0300 Subject: [PATCH] Adding drag-n-drop behavior Signed-off-by: Alex Andreev --- src/common/hotbar-store.ts | 14 +++ .../components/hotbar/hotbar-menu.tsx | 86 +++++++++++++------ .../components/hotbar/hotbar-selector.tsx | 3 +- 3 files changed, 73 insertions(+), 30 deletions(-) diff --git a/src/common/hotbar-store.ts b/src/common/hotbar-store.ts index fa0116937b..ce651dc66b 100644 --- a/src/common/hotbar-store.ts +++ b/src/common/hotbar-store.ts @@ -158,6 +158,20 @@ export class HotbarStore extends BaseStore { hotbar.items[index] = null; } + swapItems(from: number, to: number): void { + const { items } = this.getActive(); + + if (from < 0 || to < 0 || from >= items.length || to >= items.length || isNaN(from) || isNaN(to)) { + throw new Error("Invalid 'from' or 'to' arguments"); + } + + if (from != to) { + const source = items.splice(from, 1); + + items.splice(to, 0, source[0]); + } + } + switchToPrevious() { const hotbarStore = HotbarStore.getInstance(); let index = hotbarStore.activeHotbarIndex - 1; diff --git a/src/renderer/components/hotbar/hotbar-menu.tsx b/src/renderer/components/hotbar/hotbar-menu.tsx index 0458e0f1ff..fdbe4f70d4 100644 --- a/src/renderer/components/hotbar/hotbar-menu.tsx +++ b/src/renderer/components/hotbar/hotbar-menu.tsx @@ -6,9 +6,9 @@ import { observer } from "mobx-react"; import { HotbarIcon } from "./hotbar-icon"; import { cssNames, IClassName } from "../../utils"; import { catalogEntityRegistry } from "../../api/catalog-entity-registry"; -import { HotbarItem, HotbarStore } from "../../../common/hotbar-store"; +import { defaultHotbarCells, HotbarItem, HotbarStore } from "../../../common/hotbar-store"; import { CatalogEntity, catalogEntityRunContext } from "../../api/catalog-entity"; -import { DragDropContext, Draggable, DraggableProvided, Droppable, DroppableProvided, DropResult } from "react-beautiful-dnd"; +import { DragDropContext, Draggable, Droppable, DropResult } from "react-beautiful-dnd"; import { HotbarSelector } from "./hotbar-selector"; interface Props { @@ -35,8 +35,17 @@ export class HotbarMenu extends React.Component { return item ? catalogEntityRegistry.items.find((entity) => entity.metadata.uid === item.entity.uid) : null; } - onDragEnd() { - console.log("drag end") + onDragEnd(result: DropResult) { + const { source, destination } = result; + + if (!destination) { // Dropped outside of the list + return; + } + + const from = parseInt(source.droppableId); + const to = parseInt(destination.droppableId); + + HotbarStore.getInstance().swapItems(from, to); } renderGrid() { @@ -44,33 +53,46 @@ export class HotbarMenu extends React.Component { const entity = this.getEntity(item); return ( - + {(provided, snapshot) => ( {entity && ( - - {(provided, snapshot) => ( -
- entity.onRun(catalogEntityRunContext)} - /> -
- )} + + {(provided, snapshot) => { + const style = { + zIndex: defaultHotbarCells - index, + position: "absolute", + ...provided.draggableProps.style, + } as React.CSSProperties; + + return ( +
+ entity.onRun(catalogEntityRunContext)} + className={cssNames({ isDragging: snapshot.isDragging })} + /> +
+ ); + }}
)} + {provided.placeholder}
)}
@@ -99,21 +121,29 @@ export class HotbarMenu extends React.Component { interface HotbarCellProps extends HTMLAttributes { children?: ReactNode; index: number; - ref?: any; + innerRef?: React.LegacyRef; } -function HotbarCell(props: HotbarCellProps) { +function HotbarCell({ innerRef, children, className, ...rest }: HotbarCellProps) { const [animating, setAnimating] = useState(false); const onAnimationEnd = () => { setAnimating(false); }; - const onClick = () => { setAnimating(true); }; + const onClick = () => { + if (className.includes("isDraggingOver")) { + return; + } + + setAnimating(true); + }; return (
- {props.children} + {children}
); } diff --git a/src/renderer/components/hotbar/hotbar-selector.tsx b/src/renderer/components/hotbar/hotbar-selector.tsx index 9ae7f1d64d..15a38ef14c 100644 --- a/src/renderer/components/hotbar/hotbar-selector.tsx +++ b/src/renderer/components/hotbar/hotbar-selector.tsx @@ -11,9 +11,8 @@ interface Props { hotbar: Hotbar; } -const store = HotbarStore.getInstance(); - export function HotbarSelector({ hotbar }: Props) { + const store = HotbarStore.getInstance(); const activeIndexDisplay = store.activeHotbarIndex + 1; return (