mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-23 06:40:50 +01:00
Update inventory to use useReducer
This commit is contained in:
parent
629205d096
commit
fece78897f
@ -1,50 +1,28 @@
|
|||||||
import { FurnitureListAddOrUpdateEvent, FurnitureListEvent, FurnitureListInvalidateEvent, FurnitureListItemParser, FurnitureListRemovedEvent, FurniturePostItPlacedEvent } from 'nitro-renderer';
|
import { FurnitureListAddOrUpdateEvent, FurnitureListEvent, FurnitureListInvalidateEvent, FurnitureListItemParser, FurnitureListRemovedEvent, FurniturePostItPlacedEvent } from 'nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC, useCallback } from 'react';
|
||||||
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
||||||
|
import { useInventoryContext } from './context/InventoryContext';
|
||||||
import { InventoryMessageHandlerProps } from './InventoryMessageHandler.types';
|
import { InventoryMessageHandlerProps } from './InventoryMessageHandler.types';
|
||||||
import { FurnitureItem } from './utils/FurnitureItem';
|
import { InventoryFurnitureActions } from './reducers/InventoryFurnitureReducer';
|
||||||
import { addFurnitureItem, getGroupItemForFurnitureId, mergeFragments, processFragment, removeItemById } from './utils/FurnitureUtilities';
|
import { mergeFragments } from './utils/FurnitureUtilities';
|
||||||
|
|
||||||
let furniMsgFragments: Map<number, FurnitureListItemParser>[] = null;
|
let furniMsgFragments: Map<number, FurnitureListItemParser>[] = null;
|
||||||
|
|
||||||
export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =>
|
export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =>
|
||||||
{
|
{
|
||||||
const { setNeedsFurniUpdate = null, setGroupItems = null } = props;
|
const { dispatchFurnitureState = null } = useInventoryContext();
|
||||||
|
|
||||||
const onFurnitureListAddOrUpdateEvent = useCallback((event: FurnitureListAddOrUpdateEvent) =>
|
const onFurnitureListAddOrUpdateEvent = useCallback((event: FurnitureListAddOrUpdateEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
setGroupItems(prevValue =>
|
dispatchFurnitureState({
|
||||||
{
|
type: InventoryFurnitureActions.ADD_OR_UPDATE_FURNITURE,
|
||||||
const newSet = [ ...prevValue ];
|
payload: {
|
||||||
|
parsers: parser.items
|
||||||
for(const item of parser.items)
|
}
|
||||||
{
|
});
|
||||||
const groupItem = getGroupItemForFurnitureId(newSet, item.itemId);
|
}, [ dispatchFurnitureState ]);
|
||||||
|
|
||||||
if(groupItem)
|
|
||||||
{
|
|
||||||
const furniture = groupItem.getItemById(item.itemId);
|
|
||||||
|
|
||||||
if(furniture)
|
|
||||||
{
|
|
||||||
furniture.update(item);
|
|
||||||
|
|
||||||
groupItem.hasUnseenItems = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const furniture = new FurnitureItem(item);
|
|
||||||
|
|
||||||
addFurnitureItem(newSet, furniture, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return newSet;
|
|
||||||
});
|
|
||||||
}, [ setGroupItems ]);
|
|
||||||
|
|
||||||
const onFurnitureListEvent = useCallback((event: FurnitureListEvent) =>
|
const onFurnitureListEvent = useCallback((event: FurnitureListEvent) =>
|
||||||
{
|
{
|
||||||
@ -52,41 +30,37 @@ export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =
|
|||||||
|
|
||||||
if(!furniMsgFragments) furniMsgFragments = new Array(parser.totalFragments);
|
if(!furniMsgFragments) furniMsgFragments = new Array(parser.totalFragments);
|
||||||
|
|
||||||
const merged = mergeFragments(parser.fragment, parser.totalFragments, parser.fragmentNumber, furniMsgFragments);
|
const fragment = mergeFragments(parser.fragment, parser.totalFragments, parser.fragmentNumber, furniMsgFragments);
|
||||||
|
|
||||||
if(!merged) return;
|
if(!fragment) return;
|
||||||
|
|
||||||
setGroupItems(prevValue =>
|
dispatchFurnitureState({
|
||||||
{
|
type: InventoryFurnitureActions.PROCESS_FRAGMENT,
|
||||||
return processFragment(prevValue, merged);
|
payload: { fragment }
|
||||||
});
|
});
|
||||||
}, [ setGroupItems ]);
|
}, [ dispatchFurnitureState ]);
|
||||||
|
|
||||||
const onFurnitureListInvalidateEvent = useCallback((event: FurnitureListInvalidateEvent) =>
|
const onFurnitureListInvalidateEvent = useCallback((event: FurnitureListInvalidateEvent) =>
|
||||||
{
|
{
|
||||||
setNeedsFurniUpdate(true);
|
dispatchFurnitureState({
|
||||||
}, [ setNeedsFurniUpdate ]);
|
type: InventoryFurnitureActions.SET_NEEDS_UPDATE,
|
||||||
|
payload: {
|
||||||
|
flag: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [ dispatchFurnitureState ]);
|
||||||
|
|
||||||
const onFurnitureListRemovedEvent = useCallback((event: FurnitureListRemovedEvent) =>
|
const onFurnitureListRemovedEvent = useCallback((event: FurnitureListRemovedEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
setGroupItems(prevValue =>
|
dispatchFurnitureState({
|
||||||
{
|
type: InventoryFurnitureActions.REMOVE_FURNITURE,
|
||||||
const newSet = [ ...prevValue ];
|
payload: {
|
||||||
|
itemId: parser.itemId
|
||||||
const groupItem = removeItemById(parser.itemId, newSet);
|
}
|
||||||
|
});
|
||||||
if(groupItem)
|
}, [ dispatchFurnitureState ]);
|
||||||
{
|
|
||||||
// set all seen
|
|
||||||
|
|
||||||
return newSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
return prevValue;
|
|
||||||
});
|
|
||||||
}, [ setGroupItems ]);
|
|
||||||
|
|
||||||
const onFurniturePostItPlacedEvent = useCallback((event: FurniturePostItPlacedEvent) =>
|
const onFurniturePostItPlacedEvent = useCallback((event: FurniturePostItPlacedEvent) =>
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
import { Dispatch, SetStateAction } from 'react';
|
|
||||||
import { GroupItem } from './utils/GroupItem';
|
|
||||||
|
|
||||||
export interface InventoryMessageHandlerProps
|
export interface InventoryMessageHandlerProps
|
||||||
{
|
{
|
||||||
setNeedsFurniUpdate: Dispatch<SetStateAction<boolean>>;
|
|
||||||
setGroupItems: Dispatch<SetStateAction<GroupItem[]>>;
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
.nitro-inventory {
|
.nitro-inventory {
|
||||||
width: 475px;
|
width: 475px;
|
||||||
height: 300px;
|
// height: 300px;
|
||||||
max-height: 300px;
|
// max-height: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@import './views/InventoryViews';
|
@import './views/InventoryViews';
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { IRoomSession, RoomPreviewer, RoomSessionEvent } from 'nitro-renderer';
|
import { IRoomSession, RoomEngineObjectEvent, RoomEngineObjectPlacedEvent, RoomPreviewer, RoomSessionEvent } from 'nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
import { FC, useCallback, useEffect, useReducer, useState } from 'react';
|
||||||
import { GetRoomEngine } from '../../api';
|
import { GetRoomEngine } from '../../api';
|
||||||
import { InventoryEvent } from '../../events';
|
import { InventoryEvent } from '../../events';
|
||||||
import { DraggableWindow } from '../../hooks/draggable-window/DraggableWindow';
|
import { DraggableWindow } from '../../hooks/draggable-window/DraggableWindow';
|
||||||
|
import { useRoomEngineEvent } from '../../hooks/events/nitro/room/room-engine-event';
|
||||||
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
|
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
|
||||||
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
||||||
import { LocalizeText } from '../../utils/LocalizeText';
|
import { LocalizeText } from '../../utils/LocalizeText';
|
||||||
|
import { InventoryContextProvider } from './context/InventoryContext';
|
||||||
import { InventoryMessageHandler } from './InventoryMessageHandler';
|
import { InventoryMessageHandler } from './InventoryMessageHandler';
|
||||||
import { InventoryTabs, InventoryViewProps } from './InventoryView.types';
|
import { InventoryTabs, InventoryViewProps } from './InventoryView.types';
|
||||||
import { GroupItem } from './utils/GroupItem';
|
import { initialInventoryFurniture, inventoryFurnitureReducer } from './reducers/InventoryFurnitureReducer';
|
||||||
|
import { isObjectMoverRequested, setObjectMoverRequested } from './utils/FurnitureUtilities';
|
||||||
import { InventoryFurnitureView } from './views/furniture/InventoryFurnitureView';
|
import { InventoryFurnitureView } from './views/furniture/InventoryFurnitureView';
|
||||||
|
|
||||||
export const InventoryView: FC<InventoryViewProps> = props =>
|
export const InventoryView: FC<InventoryViewProps> = props =>
|
||||||
@ -18,12 +21,9 @@ export const InventoryView: FC<InventoryViewProps> = props =>
|
|||||||
|
|
||||||
const [ isVisible, setIsVisible ] = useState(false);
|
const [ isVisible, setIsVisible ] = useState(false);
|
||||||
const [ currentTab, setCurrentTab ] = useState<string>(tabs[0]);
|
const [ currentTab, setCurrentTab ] = useState<string>(tabs[0]);
|
||||||
|
|
||||||
const [ roomSession, setRoomSession ] = useState<IRoomSession>(null);
|
const [ roomSession, setRoomSession ] = useState<IRoomSession>(null);
|
||||||
const [ needsFurniUpdate, setNeedsFurniUpdate ] = useState(true);
|
|
||||||
const [ groupItem, setGroupItem ] = useState<GroupItem>(null);
|
|
||||||
const [ groupItems, setGroupItems ] = useState<GroupItem[]>([]);
|
|
||||||
const [ roomPreviewer, setRoomPreviewer ] = useState<RoomPreviewer>(null);
|
const [ roomPreviewer, setRoomPreviewer ] = useState<RoomPreviewer>(null);
|
||||||
|
const [ furnitureState, dispatchFurnitureState ] = useReducer(inventoryFurnitureReducer, initialInventoryFurniture);
|
||||||
|
|
||||||
const onInventoryEvent = useCallback((event: InventoryEvent) =>
|
const onInventoryEvent = useCallback((event: InventoryEvent) =>
|
||||||
{
|
{
|
||||||
@ -45,6 +45,17 @@ export const InventoryView: FC<InventoryViewProps> = props =>
|
|||||||
useUiEvent(InventoryEvent.HIDE_INVENTORY, onInventoryEvent);
|
useUiEvent(InventoryEvent.HIDE_INVENTORY, onInventoryEvent);
|
||||||
useUiEvent(InventoryEvent.TOGGLE_INVENTORY, onInventoryEvent);
|
useUiEvent(InventoryEvent.TOGGLE_INVENTORY, onInventoryEvent);
|
||||||
|
|
||||||
|
const onRoomEngineObjectPlacedEvent = useCallback((event: RoomEngineObjectPlacedEvent) =>
|
||||||
|
{
|
||||||
|
if(!isObjectMoverRequested()) return;
|
||||||
|
|
||||||
|
setObjectMoverRequested(false);
|
||||||
|
|
||||||
|
if(!event._Str_4057) setIsVisible(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useRoomEngineEvent(RoomEngineObjectEvent.PLACED, onRoomEngineObjectPlacedEvent);
|
||||||
|
|
||||||
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
|
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
|
||||||
{
|
{
|
||||||
switch(event.type)
|
switch(event.type)
|
||||||
@ -83,10 +94,8 @@ export const InventoryView: FC<InventoryViewProps> = props =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<InventoryContextProvider value={ { furnitureState, dispatchFurnitureState } }>
|
||||||
<InventoryMessageHandler
|
<InventoryMessageHandler />
|
||||||
setNeedsFurniUpdate={ setNeedsFurniUpdate }
|
|
||||||
setGroupItems={ setGroupItems } />
|
|
||||||
{ isVisible && <DraggableWindow handle=".drag-handler">
|
{ isVisible && <DraggableWindow handle=".drag-handler">
|
||||||
<div className="nitro-inventory d-flex flex-column">
|
<div className="nitro-inventory d-flex flex-column">
|
||||||
<div className="drag-handler d-flex align-items-center bg-primary border border-bottom-0 rounded-top px-3 py-1">
|
<div className="drag-handler d-flex align-items-center bg-primary border border-bottom-0 rounded-top px-3 py-1">
|
||||||
@ -107,16 +116,11 @@ export const InventoryView: FC<InventoryViewProps> = props =>
|
|||||||
</ul>
|
</ul>
|
||||||
<div className="bg-light rounded-bottom border border-top-0 px-3 py-2 h-100 shadow overflow-hidden">
|
<div className="bg-light rounded-bottom border border-top-0 px-3 py-2 h-100 shadow overflow-hidden">
|
||||||
{ (currentTab === InventoryTabs.FURNITURE ) && <InventoryFurnitureView
|
{ (currentTab === InventoryTabs.FURNITURE ) && <InventoryFurnitureView
|
||||||
needsFurniUpdate={ needsFurniUpdate }
|
|
||||||
setNeedsFurniUpdate={ setNeedsFurniUpdate }
|
|
||||||
groupItem={ groupItem }
|
|
||||||
setGroupItem={ setGroupItem }
|
|
||||||
groupItems={ groupItems }
|
|
||||||
roomSession={ roomSession }
|
roomSession={ roomSession }
|
||||||
roomPreviewer={ roomPreviewer } /> }
|
roomPreviewer={ roomPreviewer } /> }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</DraggableWindow> }
|
</DraggableWindow> }
|
||||||
</>
|
</InventoryContextProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@ import { createContext, FC, useContext } from 'react';
|
|||||||
import { IInventoryContext, InventoryContextProps } from './InventoryContext.types';
|
import { IInventoryContext, InventoryContextProps } from './InventoryContext.types';
|
||||||
|
|
||||||
const InventoryContext = createContext<IInventoryContext>({
|
const InventoryContext = createContext<IInventoryContext>({
|
||||||
currentTab: null,
|
furnitureState: null,
|
||||||
setCurrentTab: null,
|
dispatchFurnitureState: null
|
||||||
});
|
});
|
||||||
|
|
||||||
export const InventoryContextProvider: FC<InventoryContextProps> = props =>
|
export const InventoryContextProvider: FC<InventoryContextProps> = props =>
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { ProviderProps } from 'react';
|
import { Dispatch, ProviderProps } from 'react';
|
||||||
|
import { IInventoryFurnitureAction, IInventoryFurnitureState } from '../reducers/InventoryFurnitureReducer';
|
||||||
|
|
||||||
export interface IInventoryContext
|
export interface IInventoryContext
|
||||||
{
|
{
|
||||||
currentTab: string;
|
furnitureState: IInventoryFurnitureState;
|
||||||
setCurrentTab: (tab: string) => void;
|
dispatchFurnitureState: Dispatch<IInventoryFurnitureAction>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InventoryContextProps extends ProviderProps<IInventoryContext>
|
export interface InventoryContextProps extends ProviderProps<IInventoryContext>
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
import { createContext, FC, useContext } from 'react';
|
|
||||||
import { IInventoryFurnitureContext, InventoryFurnitureContextProps } from './InventoryFurnitureContext.types';
|
|
||||||
|
|
||||||
const InventoryFurnitureContext = createContext<IInventoryFurnitureContext>({
|
|
||||||
setNeedsUpdate: null,
|
|
||||||
setGroupItems: null
|
|
||||||
});
|
|
||||||
|
|
||||||
export const InventoryFurnitureContextProvider: FC<InventoryFurnitureContextProps> = props =>
|
|
||||||
{
|
|
||||||
return <InventoryFurnitureContext.Provider value={ props.value }>{ props.children }</InventoryFurnitureContext.Provider>
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useInventoryFurnitureContext = () => useContext(InventoryFurnitureContext);
|
|
@ -1,13 +0,0 @@
|
|||||||
import { Dispatch, ProviderProps, SetStateAction } from 'react';
|
|
||||||
import { GroupItem } from '../../utils/GroupItem';
|
|
||||||
|
|
||||||
export interface IInventoryFurnitureContext
|
|
||||||
{
|
|
||||||
setNeedsUpdate: Dispatch<SetStateAction<boolean>>;
|
|
||||||
setGroupItems: Dispatch<SetStateAction<GroupItem[]>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface InventoryFurnitureContextProps extends ProviderProps<IInventoryFurnitureContext>
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
137
src/views/inventory/reducers/InventoryFurnitureReducer.tsx
Normal file
137
src/views/inventory/reducers/InventoryFurnitureReducer.tsx
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
import { FurnitureListItemParser } from 'nitro-renderer';
|
||||||
|
import { Reducer } from 'react';
|
||||||
|
import { FurnitureItem } from '../utils/FurnitureItem';
|
||||||
|
import { addFurnitureItem, processFragment, removeItemById } from '../utils/FurnitureUtilities';
|
||||||
|
import { GroupItem } from '../utils/GroupItem';
|
||||||
|
|
||||||
|
export interface IInventoryFurnitureState
|
||||||
|
{
|
||||||
|
needsFurniUpdate: boolean;
|
||||||
|
groupItem: GroupItem;
|
||||||
|
groupItems: GroupItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IInventoryFurnitureAction
|
||||||
|
{
|
||||||
|
type: string;
|
||||||
|
payload: {
|
||||||
|
flag?: boolean;
|
||||||
|
groupItem?: GroupItem;
|
||||||
|
parsers?: FurnitureListItemParser[];
|
||||||
|
itemId?: number;
|
||||||
|
fragment?: Map<number, FurnitureListItemParser>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class InventoryFurnitureActions
|
||||||
|
{
|
||||||
|
public static SET_NEEDS_UPDATE: string = 'IFA_SET_NEEDS_UPDATE';
|
||||||
|
public static SET_GROUP_ITEM: string = 'IFA_SET_GROUP_ITEM';
|
||||||
|
public static ADD_OR_UPDATE_FURNITURE: string = 'IFA_ADD_OR_UPDATE_FURNITURE';
|
||||||
|
public static REMOVE_FURNITURE: string = 'IFA_REMOVE_FURNITURE';
|
||||||
|
public static PROCESS_FRAGMENT: string = 'IFA_PROCESS_FRAGMENT';
|
||||||
|
}
|
||||||
|
|
||||||
|
export const initialInventoryFurniture: IInventoryFurnitureState = {
|
||||||
|
needsFurniUpdate: true,
|
||||||
|
groupItem: null,
|
||||||
|
groupItems: []
|
||||||
|
}
|
||||||
|
|
||||||
|
export const inventoryFurnitureReducer: Reducer<IInventoryFurnitureState, IInventoryFurnitureAction> = (state, action) =>
|
||||||
|
{
|
||||||
|
switch(action.type)
|
||||||
|
{
|
||||||
|
case InventoryFurnitureActions.SET_NEEDS_UPDATE:
|
||||||
|
return { ...state, needsFurniUpdate: (action.payload.flag || false) };
|
||||||
|
case InventoryFurnitureActions.SET_GROUP_ITEM: {
|
||||||
|
let groupItem = (action.payload.groupItem || state.groupItem || null);
|
||||||
|
|
||||||
|
let index = 0;
|
||||||
|
|
||||||
|
if(groupItem)
|
||||||
|
{
|
||||||
|
const foundIndex = state.groupItems.indexOf(groupItem);
|
||||||
|
|
||||||
|
if(foundIndex > -1) index = foundIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
groupItem = (state.groupItems[index] || null);
|
||||||
|
|
||||||
|
return { ...state, groupItem };
|
||||||
|
}
|
||||||
|
case InventoryFurnitureActions.ADD_OR_UPDATE_FURNITURE: {
|
||||||
|
const groupItems = [ ...state.groupItems ];
|
||||||
|
|
||||||
|
for(const item of action.payload.parsers)
|
||||||
|
{
|
||||||
|
let i = 0;
|
||||||
|
let groupItem: GroupItem = null;
|
||||||
|
|
||||||
|
while(i < groupItems.length)
|
||||||
|
{
|
||||||
|
const group = groupItems[i];
|
||||||
|
|
||||||
|
let j = 0;
|
||||||
|
|
||||||
|
while(j < group.items.length)
|
||||||
|
{
|
||||||
|
const furniture = group.items[j];
|
||||||
|
|
||||||
|
if(furniture.id === item.itemId)
|
||||||
|
{
|
||||||
|
furniture.update(item);
|
||||||
|
|
||||||
|
const newFurniture = [ ...group.items ];
|
||||||
|
|
||||||
|
newFurniture[j] = furniture;
|
||||||
|
|
||||||
|
group.items = newFurniture;
|
||||||
|
|
||||||
|
groupItem = group;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
|
||||||
|
if(groupItem) break;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(groupItem)
|
||||||
|
{
|
||||||
|
groupItem.hasUnseenItems = true;
|
||||||
|
|
||||||
|
groupItems[i] = Object.create(groupItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const furniture = new FurnitureItem(item);
|
||||||
|
|
||||||
|
addFurnitureItem(groupItems, furniture, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ...state, groupItems };
|
||||||
|
}
|
||||||
|
case InventoryFurnitureActions.REMOVE_FURNITURE: {
|
||||||
|
const groupItems = [ ...state.groupItems ];
|
||||||
|
|
||||||
|
removeItemById(action.payload.itemId, groupItems);
|
||||||
|
|
||||||
|
return { ...state, groupItems };
|
||||||
|
}
|
||||||
|
case InventoryFurnitureActions.PROCESS_FRAGMENT: {
|
||||||
|
const groupItems = [ ...state.groupItems ];
|
||||||
|
|
||||||
|
processFragment(groupItems, (action.payload.fragment || null));
|
||||||
|
|
||||||
|
return { ...state, groupItems };
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
@ -155,9 +155,7 @@ export function processFragment(set: GroupItem[], fragment: Map<number, Furnitur
|
|||||||
|
|
||||||
const emptyExistingSet = (existingIds.length === 0);
|
const emptyExistingSet = (existingIds.length === 0);
|
||||||
|
|
||||||
const newSet = [ ...set ];
|
for(const id of removedIds) removeItemById(id, set);
|
||||||
|
|
||||||
for(const id of removedIds) removeItemById(id, newSet);
|
|
||||||
|
|
||||||
for(const id of addedIds)
|
for(const id of addedIds)
|
||||||
{
|
{
|
||||||
@ -167,10 +165,10 @@ export function processFragment(set: GroupItem[], fragment: Map<number, Furnitur
|
|||||||
|
|
||||||
const item = new FurnitureItem(parser);
|
const item = new FurnitureItem(parser);
|
||||||
|
|
||||||
addFurnitureItem(newSet, item, true);
|
addFurnitureItem(set, item, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newSet;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeItemById(id: number, set: GroupItem[]): GroupItem
|
export function removeItemById(id: number, set: GroupItem[]): GroupItem
|
||||||
|
@ -420,4 +420,9 @@ export class GroupItem
|
|||||||
{
|
{
|
||||||
return this._items;
|
return this._items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public set items(items: FurnitureItem[])
|
||||||
|
{
|
||||||
|
this._items = items;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
.item-container {
|
|
||||||
height: 216px;
|
|
||||||
max-height: 216px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
@import './item/InventoryFurnitureItemView';
|
@import './item/InventoryFurnitureItemView';
|
||||||
|
@import './results/InventoryFurnitureResultsView';
|
||||||
|
@import './search/InventoryFurnitureSearchView';
|
||||||
|
@ -4,45 +4,45 @@ import { GetRoomEngine } from '../../../../api';
|
|||||||
import { SendMessageHook } from '../../../../hooks/messages/message-event';
|
import { SendMessageHook } from '../../../../hooks/messages/message-event';
|
||||||
import { LocalizeText } from '../../../../utils/LocalizeText';
|
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||||
import { RoomPreviewerView } from '../../../room-previewer/RoomPreviewerView';
|
import { RoomPreviewerView } from '../../../room-previewer/RoomPreviewerView';
|
||||||
|
import { useInventoryContext } from '../../context/InventoryContext';
|
||||||
|
import { InventoryFurnitureActions } from '../../reducers/InventoryFurnitureReducer';
|
||||||
import { FurniCategory } from '../../utils/FurniCategory';
|
import { FurniCategory } from '../../utils/FurniCategory';
|
||||||
import { attemptItemPlacement } from '../../utils/FurnitureUtilities';
|
import { attemptItemPlacement } from '../../utils/FurnitureUtilities';
|
||||||
import { InventoryFurnitureViewProps } from './InventoryFurnitureView.types';
|
import { InventoryFurnitureViewProps } from './InventoryFurnitureView.types';
|
||||||
import { InventoryFurnitureItemView } from './item/InventoryFurnitureItemView';
|
import { InventoryFurnitureResultsView } from './results/InventoryFurnitureResultsView';
|
||||||
|
import { InventoryFurnitureSearchView } from './search/InventoryFurnitureSearchView';
|
||||||
|
|
||||||
export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { needsFurniUpdate = false, setNeedsFurniUpdate = null, groupItem = null, setGroupItem = null, groupItems = null, roomSession = null, roomPreviewer = null } = props;
|
const { roomSession = null, roomPreviewer = null } = props;
|
||||||
|
|
||||||
console.log(props);
|
const { furnitureState = null, dispatchFurnitureState = null } = useInventoryContext();
|
||||||
|
const { needsFurniUpdate = false, groupItem = null, groupItems = [] } = furnitureState;
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if(needsFurniUpdate)
|
if(needsFurniUpdate)
|
||||||
{
|
{
|
||||||
setNeedsFurniUpdate(false);
|
dispatchFurnitureState({
|
||||||
|
type: InventoryFurnitureActions.SET_NEEDS_UPDATE,
|
||||||
|
payload: {
|
||||||
|
flag: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
SendMessageHook(new FurnitureListComposer());
|
SendMessageHook(new FurnitureListComposer());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
setGroupItem(prevValue =>
|
dispatchFurnitureState({
|
||||||
{
|
type: InventoryFurnitureActions.SET_GROUP_ITEM,
|
||||||
if(!groupItems || !groupItems.length) return null;
|
payload: {
|
||||||
|
groupItem: null
|
||||||
let index = 0;
|
}
|
||||||
|
});
|
||||||
if(prevValue)
|
|
||||||
{
|
|
||||||
const foundIndex = groupItems.indexOf(prevValue);
|
|
||||||
|
|
||||||
if(foundIndex > -1) index = foundIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
return groupItems[index];
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}, [ needsFurniUpdate, setNeedsFurniUpdate, groupItems, setGroupItem ]);
|
}, [ needsFurniUpdate, groupItems, dispatchFurnitureState ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
@ -97,18 +97,13 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
|||||||
return (
|
return (
|
||||||
<div className="row h-100">
|
<div className="row h-100">
|
||||||
<div className="col col-7">
|
<div className="col col-7">
|
||||||
<div className="row row-cols-5 g-0 item-container">
|
<InventoryFurnitureSearchView />
|
||||||
{ groupItems && groupItems.length && groupItems.map((item, index) =>
|
<InventoryFurnitureResultsView groupItems={ groupItems } />
|
||||||
{
|
|
||||||
return <InventoryFurnitureItemView key={ index } groupItem={ item } isActive={ groupItem === item } setGroupItem={ setGroupItem } />
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex flex-column col col-5 justify-space-between">
|
<div className="d-flex flex-column col col-5 justify-space-between">
|
||||||
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 130 } />
|
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } />
|
||||||
{ groupItem && <div className="flex-grow-1 py-2">
|
{ groupItem && <div className="d-flex flex-column flex-grow-1">
|
||||||
<p className="fs-6 text-black">{ groupItem.name }</p>
|
<p className="flex-grow-1 fs-6 text-black my-2">{ groupItem.name }</p>
|
||||||
{ !!roomSession && <button type="button" className="btn btn-success" onClick={ event => attemptItemPlacement(groupItem) }>{ LocalizeText('inventory.furni.placetoroom') }</button> }
|
{ !!roomSession && <button type="button" className="btn btn-success" onClick={ event => attemptItemPlacement(groupItem) }>{ LocalizeText('inventory.furni.placetoroom') }</button> }
|
||||||
</div> }
|
</div> }
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,14 +1,7 @@
|
|||||||
import { IRoomSession, RoomPreviewer } from 'nitro-renderer';
|
import { IRoomSession, RoomPreviewer } from 'nitro-renderer';
|
||||||
import { Dispatch, SetStateAction } from 'react';
|
|
||||||
import { GroupItem } from '../../utils/GroupItem';
|
|
||||||
|
|
||||||
export interface InventoryFurnitureViewProps
|
export interface InventoryFurnitureViewProps
|
||||||
{
|
{
|
||||||
needsFurniUpdate: boolean;
|
|
||||||
setNeedsFurniUpdate: Dispatch<SetStateAction<boolean>>;
|
|
||||||
groupItem: GroupItem;
|
|
||||||
setGroupItem: Dispatch<SetStateAction<GroupItem>>;
|
|
||||||
groupItems: GroupItem[];
|
|
||||||
roomSession: IRoomSession;
|
roomSession: IRoomSession;
|
||||||
roomPreviewer: RoomPreviewer;
|
roomPreviewer: RoomPreviewer;
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,25 @@
|
|||||||
.inventory-furniture-item {
|
.inventory-furniture-item-container {
|
||||||
background-position: center;
|
height: 48px;
|
||||||
background-repeat: no-repeat;
|
max-height: 48px;
|
||||||
height: 50px;
|
|
||||||
max-height: 50px;
|
|
||||||
border-color: $muted !important;
|
|
||||||
background-color: #CDD3D9;
|
|
||||||
|
|
||||||
&.active {
|
.inventory-furniture-item {
|
||||||
border-color: $white !important;
|
width: 100%;
|
||||||
background-color: #ECECEC;
|
height: 100%;
|
||||||
}
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
.badge {
|
border-color: $muted !important;
|
||||||
top: 3px;
|
background-color: #CDD3D9;
|
||||||
right: 3px;
|
overflow: hidden;
|
||||||
font-size: 10px;
|
|
||||||
|
&.active {
|
||||||
|
border-color: $white !important;
|
||||||
|
background-color: #ECECEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
top: 2px;
|
||||||
|
right: 2px;
|
||||||
|
font-size: 8px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,48 @@
|
|||||||
import { FC } from 'react';
|
import { MouseEventType } from 'nitro-renderer';
|
||||||
|
import { FC, MouseEvent, useCallback, useState } from 'react';
|
||||||
|
import { useInventoryContext } from '../../../context/InventoryContext';
|
||||||
|
import { InventoryFurnitureActions } from '../../../reducers/InventoryFurnitureReducer';
|
||||||
|
import { attemptItemPlacement } from '../../../utils/FurnitureUtilities';
|
||||||
import { InventoryFurnitureItemViewProps } from './InventoryFurnitureItemView.types';
|
import { InventoryFurnitureItemViewProps } from './InventoryFurnitureItemView.types';
|
||||||
|
|
||||||
export const InventoryFurnitureItemView: FC<InventoryFurnitureItemViewProps> = props =>
|
export const InventoryFurnitureItemView: FC<InventoryFurnitureItemViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { groupItem = null, isActive = false, setGroupItem = null } = props;
|
const { groupItem } = props;
|
||||||
|
const { furnitureState, dispatchFurnitureState } = useInventoryContext();
|
||||||
|
const [ isMouseDown, setMouseDown ] = useState(false);
|
||||||
|
const isActive = (furnitureState.groupItem === groupItem);
|
||||||
|
|
||||||
|
const onMouseEvent = useCallback((event: MouseEvent) =>
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
case MouseEventType.MOUSE_DOWN:
|
||||||
|
dispatchFurnitureState({
|
||||||
|
type: InventoryFurnitureActions.SET_GROUP_ITEM,
|
||||||
|
payload: {
|
||||||
|
groupItem
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setMouseDown(true);
|
||||||
|
return;
|
||||||
|
case MouseEventType.MOUSE_UP:
|
||||||
|
setMouseDown(false);
|
||||||
|
return;
|
||||||
|
case MouseEventType.ROLL_OUT:
|
||||||
|
if(!isMouseDown || !isActive) return;
|
||||||
|
|
||||||
|
attemptItemPlacement(groupItem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}, [ isActive, isMouseDown, groupItem, dispatchFurnitureState ]);
|
||||||
|
|
||||||
const imageUrl = `url(${ groupItem.iconUrl })`;
|
const imageUrl = `url(${ groupItem.iconUrl })`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="col pe-1 pb-1">
|
<div className="col pe-1 pb-1 inventory-furniture-item-container">
|
||||||
<div className={ 'position-relative border border-2 rounded inventory-furniture-item cursor-pointer ' + (isActive && 'active') } style={ { backgroundImage: imageUrl }} onClick={ event => setGroupItem(groupItem) }>
|
<div className={ 'position-relative border border-2 rounded inventory-furniture-item cursor-pointer ' + (isActive && 'active') } style={ { backgroundImage: imageUrl }} onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent }>
|
||||||
<span className="position-absolute badge border bg-secondary p-1">{ groupItem.getUnlockedCount() }</span>
|
<span className="position-absolute badge border bg-danger px-1 rounded-circle">{ groupItem.getUnlockedCount() }</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
import { Dispatch, SetStateAction } from 'react';
|
|
||||||
import { GroupItem } from '../../../utils/GroupItem';
|
import { GroupItem } from '../../../utils/GroupItem';
|
||||||
|
|
||||||
export interface InventoryFurnitureItemViewProps
|
export interface InventoryFurnitureItemViewProps
|
||||||
{
|
{
|
||||||
groupItem: GroupItem;
|
groupItem: GroupItem;
|
||||||
isActive: boolean;
|
|
||||||
setGroupItem: Dispatch<SetStateAction<GroupItem>>;
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
.item-container {
|
||||||
|
height: 208px;
|
||||||
|
max-height: 208px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { InventoryFurnitureItemView } from '../item/InventoryFurnitureItemView';
|
||||||
|
import { InventoryFurnitureResultsViewProps } from './InventoryFurnitureResultsView.types';
|
||||||
|
|
||||||
|
export const InventoryFurnitureResultsView: FC<InventoryFurnitureResultsViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { groupItems = [] } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="row row-cols-5 g-0 item-container">
|
||||||
|
{ groupItems && groupItems.length && groupItems.map((item, index) =>
|
||||||
|
{
|
||||||
|
return <InventoryFurnitureItemView key={ index } groupItem={ item } />
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
import { GroupItem } from '../../../utils/GroupItem';
|
||||||
|
|
||||||
|
export interface InventoryFurnitureResultsViewProps
|
||||||
|
{
|
||||||
|
groupItems: GroupItem[];
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
import { ChangeEvent, FC, FormEvent, useEffect, useState } from 'react';
|
||||||
|
import { InventoryFurnitureSearchViewProps } from './InventoryFurnitureSearchView.types';
|
||||||
|
|
||||||
|
export const InventoryFurnitureSearchView: FC<InventoryFurnitureSearchViewProps> = props =>
|
||||||
|
{
|
||||||
|
const [ searchValue, setSearchValue ] = useState('');
|
||||||
|
|
||||||
|
function onChange(event: ChangeEvent<HTMLInputElement>): void
|
||||||
|
{
|
||||||
|
setSearchValue(event.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSubmit(event: FormEvent<HTMLFormElement>): void
|
||||||
|
{
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
|
||||||
|
}, [ searchValue ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form className="d-flex mb-1" onSubmit={ handleSubmit }>
|
||||||
|
<div className="d-flex flex-grow-1 me-1">
|
||||||
|
<input type="text" className="form-control form-control-sm" placeholder="search" />
|
||||||
|
</div>
|
||||||
|
<div className="d-flex">
|
||||||
|
<button type="submit" className="btn btn-primary btn-sm"><i className="fas fa-search"></i></button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
export interface InventoryFurnitureSearchViewProps
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user