From 2c4fdc2f238c31607135366cfc1e04a5238837e1 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Fri, 9 Jul 2021 11:55:52 -0400 Subject: [PATCH] Fix HotbarCell display issues and add removal - HotbarCells now display correctly if there are more than 12 of them - Allow empty cells to be removed if there are more than 12 Signed-off-by: Sebastian Malton --- src/common/hotbar-store.ts | 19 ++++++++++++++++ src/renderer/components/+catalog/catalog.tsx | 20 ++++++++++++----- .../components/hotbar/hotbar-cell.tsx | 13 ++++++++++- .../components/hotbar/hotbar-entity-icon.tsx | 17 +++++--------- .../components/hotbar/hotbar-menu.scss | 22 +++++++++++++++++++ .../components/hotbar/hotbar-menu.tsx | 13 ++++++----- 6 files changed, 81 insertions(+), 23 deletions(-) diff --git a/src/common/hotbar-store.ts b/src/common/hotbar-store.ts index 90694e9976..76248d7d15 100644 --- a/src/common/hotbar-store.ts +++ b/src/common/hotbar-store.ts @@ -126,6 +126,25 @@ export class HotbarStore extends BaseStore { ]; } + isInActiveHotbar(entityOrId: string | CatalogEntity): boolean { + const entityId = typeof entityOrId === "string" + ? entityOrId + : entityOrId.getId(); + + return this.getActive().items.findIndex((item) => item?.entity?.uid === entityId) >= 0; + } + + @action + removeHotbarIndexInActive(index: number): void { + const activeHotbar = this.getActive(); + + if (index < 0 || index >= activeHotbar.items.length) { + return void console.error("[HOTBAR-STORE]: tried to removeHotbarIndexInActive: index out of range", { hotbarId: activeHotbar.id, index, itemCount: activeHotbar.items.length }); + } + + activeHotbar.items.splice(index, 1); + } + getActive() { return this.getById(this.activeHotbarId); } diff --git a/src/renderer/components/+catalog/catalog.tsx b/src/renderer/components/+catalog/catalog.tsx index 76339e79a3..97a279d179 100644 --- a/src/renderer/components/+catalog/catalog.tsx +++ b/src/renderer/components/+catalog/catalog.tsx @@ -147,11 +147,24 @@ export class Catalog extends React.Component { return ; } - renderItemMenu = (item: CatalogEntityItem) => { + renderItemMenu = (entityItem: CatalogEntityItem) => { const onOpen = () => { this.contextMenu.menuItems = []; + const hs = HotbarStore.getInstance(); - item.onContextMenuOpen(this.contextMenu); + if (hs.isInActiveHotbar(entityItem.entity)) { + this.contextMenu.menuItems.unshift({ + title: "Unpin from Hotbar", + onClick: () => hs.removeFromHotbar(entityItem.getId()) + }); + } else { + this.contextMenu.menuItems.unshift({ + title: "Pin to Hotbar", + onClick: () => hs.addToHotbar(entityItem.entity) + }); + } + + entityItem.onContextMenuOpen(this.contextMenu); }; return ( @@ -163,9 +176,6 @@ export class Catalog extends React.Component { )) } - this.addToHotbar(item) }> - Pin to Hotbar - ); }; diff --git a/src/renderer/components/hotbar/hotbar-cell.tsx b/src/renderer/components/hotbar/hotbar-cell.tsx index d9a91d3d55..d3619b6f5e 100644 --- a/src/renderer/components/hotbar/hotbar-cell.tsx +++ b/src/renderer/components/hotbar/hotbar-cell.tsx @@ -23,19 +23,29 @@ import "./hotbar-menu.scss"; import React, { HTMLAttributes, ReactNode, useState } from "react"; import { cssNames } from "../../utils"; +import { Icon } from "../icon"; interface Props extends HTMLAttributes { children?: ReactNode; index: number; innerRef?: React.Ref; + + /** + * If present then on :hover an X will be displayed which will call this + * function when clicked + */ + remove?: () => void; } -export function HotbarCell({ innerRef, children, className, ...rest }: Props) { +export function HotbarCell({ innerRef, children, className, remove, ...rest }: Props) { const [animating, setAnimating] = useState(false); const onAnimationEnd = () => { setAnimating(false); }; const onClick = () => { setAnimating(!className.includes("isDraggingOver")); }; + const removeIcon = remove && ( + + ); return (
+ {removeIcon} {children}
); diff --git a/src/renderer/components/hotbar/hotbar-entity-icon.tsx b/src/renderer/components/hotbar/hotbar-entity-icon.tsx index fc6628f3eb..467fe34aaf 100644 --- a/src/renderer/components/hotbar/hotbar-entity-icon.tsx +++ b/src/renderer/components/hotbar/hotbar-entity-icon.tsx @@ -87,10 +87,6 @@ export class HotbarEntityIcon extends React.Component { return catalogEntityRegistry.activeEntity?.metadata?.uid == item.getId(); } - isPersisted(entity: CatalogEntity) { - return HotbarStore.getInstance().getActive().items.find((item) => item?.entity?.uid === entity.metadata.uid) !== undefined; - } - render() { if (!this.contextMenu) { return null; @@ -106,20 +102,19 @@ export class HotbarEntityIcon extends React.Component { disabled: !entity }); - const isPersisted = this.isPersisted(entity); const onOpen = async () => { const menuItems: CatalogEntityContextMenu[] = []; - if (!isPersisted) { - menuItems.unshift({ - title: "Pin to Hotbar", - onClick: () => add(entity, index) - }); - } else { + if (HotbarStore.getInstance().isInActiveHotbar(entity)) { menuItems.unshift({ title: "Unpin from Hotbar", onClick: () => remove(entity.metadata.uid) }); + } else { + menuItems.unshift({ + title: "Pin to Hotbar", + onClick: () => add(entity, index) + }); } this.contextMenu.menuItems = menuItems; diff --git a/src/renderer/components/hotbar/hotbar-menu.scss b/src/renderer/components/hotbar/hotbar-menu.scss index 3b7300507a..69abf3a1ea 100644 --- a/src/renderer/components/hotbar/hotbar-menu.scss +++ b/src/renderer/components/hotbar/hotbar-menu.scss @@ -106,6 +106,28 @@ } } } + + &:hover { + .remove { + display: block; + } + } + + .remove { + position: absolute; + display: none; + left: -2px; + top: -3px; + margin: -6px; + font-size: var(--font-size-small); + background: var(--clusterMenuBackground); + color: var(--textColorAccent); + padding: 0px; + border-radius: 50%; + border: 2px solid var(--clusterMenuBackground); + width: var(--font-size-small); + height: var(--font-size-small); + } } } } diff --git a/src/renderer/components/hotbar/hotbar-menu.tsx b/src/renderer/components/hotbar/hotbar-menu.tsx index 56fa7a25fc..e79d7643e0 100644 --- a/src/renderer/components/hotbar/hotbar-menu.tsx +++ b/src/renderer/components/hotbar/hotbar-menu.tsx @@ -72,15 +72,15 @@ export class HotbarMenu extends React.Component { } removeItem(uid: string) { - const hotbar = HotbarStore.getInstance(); - - hotbar.removeFromHotbar(uid); + HotbarStore.getInstance().removeFromHotbar(uid); } addItem(entity: CatalogEntity, index = -1) { - const hotbar = HotbarStore.getInstance(); + HotbarStore.getInstance().addToHotbar(entity, index); + } - hotbar.addToHotbar(entity, index); + removeHotbarIndex(index: number) { + HotbarStore.getInstance().removeHotbarIndexInActive(index); } getMoveAwayDirection(entityId: string, cellIndex: number) { @@ -118,6 +118,7 @@ export class HotbarMenu extends React.Component { index={index} key={entity ? entity.getId() : `cell${index}`} innerRef={provided.innerRef} + remove={(!item && this.items.length > defaultHotbarCells) ? (() => this.removeHotbarIndex(index)) : undefined } className={cssNames({ isDraggingOver: snapshot.isDraggingOver, isDraggingOwner: snapshot.draggingOverWith == entity?.getId(), @@ -128,7 +129,7 @@ export class HotbarMenu extends React.Component { {(provided, snapshot) => { const style = { - zIndex: defaultHotbarCells - index, + zIndex: this.items.length - index, position: "absolute", ...provided.draggableProps.style, } as React.CSSProperties;