From 20837ea2f0951d50394eca04afac2608963ad434 Mon Sep 17 00:00:00 2001 From: cha0s Date: Tue, 15 Oct 2019 04:28:42 -0500 Subject: [PATCH] refactor: much better item UI handling --- client/ui/hooks/use-inventory-slice.js | 22 +++++++++++++ client/ui/menu/hotbar.js | 44 +++++++------------------- client/ui/menu/index.js | 6 ++-- client/ui/menu/inventory.js | 21 ++++++------ client/ui/menu/item-slot.js | 8 +++-- 5 files changed, 54 insertions(+), 47 deletions(-) create mode 100644 client/ui/hooks/use-inventory-slice.js diff --git a/client/ui/hooks/use-inventory-slice.js b/client/ui/hooks/use-inventory-slice.js new file mode 100644 index 0000000..390e1b3 --- /dev/null +++ b/client/ui/hooks/use-inventory-slice.js @@ -0,0 +1,22 @@ +// 3rd party. +import * as I from 'immutable'; +import React, {useState} from 'react'; +// 1st party. +import {useEvent} from './use-event'; + +export function useInventorySlice(selfEntity, start, end) { + const [items, setItems] = useState(I.List()); + useEvent(selfEntity, 'inventoryChanged', () => { + setItems(items.withMutations((items) => { + for (let i = start; i < end; ++i) { + const item = selfEntity.itemInSlot(i); + items.set(i, item ? item : undefined); + } + })); + }); + const slice = []; + for (let i = start; i < end; ++i) { + slice.push(items.get(i)); + } + return slice; +} diff --git a/client/ui/menu/hotbar.js b/client/ui/menu/hotbar.js index 4b8ce60..65c594f 100644 --- a/client/ui/menu/hotbar.js +++ b/client/ui/menu/hotbar.js @@ -1,51 +1,32 @@ // 3rd party. import classnames from 'classnames'; -import * as I from 'immutable'; -import React, {useEffect, useState} from 'react'; +import React from 'react'; // 2nd party. import {compose} from '@avocado/core'; import contempo from 'contempo'; // 1st party. -import {useEvent} from '../hooks/use-event'; import {usePropertyChange} from '../hooks/use-property-change'; +import {useInventorySlice} from '../hooks/use-inventory-slice'; + import ItemSlot from './item-slot'; const decorate = compose( contempo(require('./hotbar.raw.scss').default), ); -const HotbarComponent = ({app}) => { - const selfEntity = usePropertyChange(app, 'selfEntity'); - const activeSlotIndex = usePropertyChange(selfEntity, 'activeSlotIndex'); - const [items, setItems] = useState(I.List()); - useEvent(selfEntity, 'inventoryChanged', () => { - setItems(items.withMutations((items) => { - for (let i = 0; i < 10; ++i) { - const item = selfEntity.itemInSlot(i); - if (!item) { - continue; - } - if (!items.has(i)) { - items.set(i, I.Map()); - } - items.set(i, items.get(i).withMutations((listItem) => { - listItem.set('backgroundImage', item.imageForSlot()); - listItem.set('qty', item.qty); - })); - } - })); - }); +const HotbarComponent = ({selfEntity}) => { const hotkeyForSlot = (index) => { return (index + 1) % 10; } - const slots = []; - for (let i = 0; i < 10; ++i) { - const slot = { + return { if (selfEntity) { selfEntity.activeSlotIndex = i; @@ -57,13 +38,12 @@ const HotbarComponent = ({app}) => { >
{hotkeyForSlot(i)}
; - slots.push(slot); - } + }); return
- {slots} + {itemSlots}
; } diff --git a/client/ui/menu/index.js b/client/ui/menu/index.js index 845f1d8..0280b5d 100644 --- a/client/ui/menu/index.js +++ b/client/ui/menu/index.js @@ -6,6 +6,7 @@ import {compose} from '@avocado/core'; import contempo from 'contempo'; // 1st party. import {useEvent} from '../hooks/use-event'; +import {usePropertyChange} from '../hooks/use-property-change'; import QuickStatus from './quick-status'; import Hotbar from './hotbar'; import Inventory from './inventory'; @@ -17,6 +18,7 @@ const decorate = compose( const MenuComponent = ({app}) => { const [opened, setOpened] = useState(false); + const selfEntity = usePropertyChange(app, 'selfEntity'); useEvent(app, 'isMenuOpenedChanged', (_, isOpened) => { setOpened(isOpened); }); @@ -25,10 +27,10 @@ const MenuComponent = ({app}) => { 'menu-inner', opened ? 'open' : '', )}> - + - + ; } diff --git a/client/ui/menu/inventory.js b/client/ui/menu/inventory.js index a86875f..82d831b 100644 --- a/client/ui/menu/inventory.js +++ b/client/ui/menu/inventory.js @@ -1,24 +1,25 @@ // 3rd party. -import React, {useEffect, useState} from 'react'; +import React from 'react'; // 2nd party. import {compose} from '@avocado/core'; import contempo from 'contempo'; // 1st party. +import {useInventorySlice} from '../hooks/use-inventory-slice'; import ItemSlot from './item-slot'; const decorate = compose( contempo(require('./inventory.raw.scss').default), ); -const InventoryComponent = () => { - const bagSlots = []; - for (let i = 0; i < 40; ++i) { - bagSlots.push(); - } - const equipmentSlots = []; - for (let i = 0; i < 4; ++i) { - equipmentSlots.push(); - } +const InventoryComponent = ({selfEntity}) => { + const bagSlice = useInventorySlice(selfEntity, 10, 50); + const bagSlots = bagSlice.map((item, i) => { + return ; + }); + const equipmentSlice = useInventorySlice(selfEntity, 50, 54); + const equipmentSlots = equipmentSlice.map((item, i) => { + return ; + }); return
{bagSlots}
diff --git a/client/ui/menu/item-slot.js b/client/ui/menu/item-slot.js index 5176e3b..247876f 100644 --- a/client/ui/menu/item-slot.js +++ b/client/ui/menu/item-slot.js @@ -4,6 +4,8 @@ import React, {useEffect, useState} from 'react'; // 2nd party. import {compose} from '@avocado/core'; import contempo from 'contempo'; +// 1st party. +import {useEvent} from '../hooks/use-event'; const decorate = compose( contempo(require('./item-slot.raw.scss').default), @@ -11,15 +13,15 @@ const decorate = compose( const ItemSlotComponent = (props) => { const {children, className, item, ...rest} = props; + const [qty, setQty] = useState(undefined); + useEvent(item, 'qtyChanged', (_, qty) => setQty(item.qty)); let backgroundImageUri; - let qty; let qtyClass; if (item) { - const backgroundImage = item.get('backgroundImage'); + const backgroundImage = item.imageForSlot(); if (backgroundImage) { backgroundImageUri = backgroundImage.uri; } - qty = item.get('qty'); if (qty > 9999) { qtyClass = 'e4'; }