nitro-react/src/hooks/inventory/useInventoryPets.ts

114 lines
3.4 KiB
TypeScript
Raw Normal View History

2022-03-30 10:19:09 -04:00
import { PetAddedToInventoryEvent, PetData, PetInventoryEvent, PetRemovedFromInventory, RequestPetsComposer } from '@nitrots/nitro-renderer';
import { useCallback, useEffect, useState } from 'react';
import { useBetween } from 'use-between';
2022-03-30 12:46:48 -04:00
import { useInventoryUnseenTracker } from '.';
2022-03-30 10:19:09 -04:00
import { UseMessageEventHook } from '..';
2022-04-02 21:12:58 -04:00
import { addSinglePetItem, IPetItem, mergePetFragments, processPetFragment, removePetItemById, SendMessageComposer, UnseenItemCategory } from '../../api';
2022-03-30 10:19:09 -04:00
import { useSharedVisibility } from '../useSharedVisibility';
let petMsgFragments: Map<number, PetData>[] = null;
2022-03-30 12:46:48 -04:00
const useInventoryPetsState = () =>
2022-03-30 10:19:09 -04:00
{
const [ needsUpdate, setNeedsUpdate ] = useState(true);
const [ petItems, setPetItems ] = useState<IPetItem[]>([]);
const [ selectedPet, setSelectedPet ] = useState<IPetItem>(null);
2022-04-02 01:33:29 -04:00
const { isVisible = false, activate = null, deactivate = null } = useSharedVisibility();
const { isUnseen = null, resetCategory = null } = useInventoryUnseenTracker();
2022-03-30 10:19:09 -04:00
const onPetInventoryEvent = useCallback((event: PetInventoryEvent) =>
{
const parser = event.getParser();
if(!petMsgFragments) petMsgFragments = new Array(parser.totalFragments);
const fragment = mergePetFragments(parser.fragment, parser.totalFragments, parser.fragmentNumber, petMsgFragments);
if(!fragment) return;
setPetItems(prevValue =>
2022-04-01 16:12:46 -04:00
{
const newValue = [ ...prevValue ];
2022-03-30 10:19:09 -04:00
2022-04-01 16:12:46 -04:00
processPetFragment(newValue, fragment, isUnseen);
2022-03-30 10:19:09 -04:00
2022-04-01 16:12:46 -04:00
return newValue;
});
2022-03-30 10:19:09 -04:00
petMsgFragments = null;
}, [ isUnseen ]);
UseMessageEventHook(PetInventoryEvent, onPetInventoryEvent);
const onPetAddedToInventoryEvent = useCallback((event: PetAddedToInventoryEvent) =>
{
const parser = event.getParser();
setPetItems(prevValue =>
2022-04-01 16:12:46 -04:00
{
const newValue = [ ...prevValue ];
2022-03-30 10:19:09 -04:00
2022-04-02 01:33:29 -04:00
addSinglePetItem(parser.pet, newValue, isUnseen(UnseenItemCategory.PET, parser.pet.id));
2022-03-30 10:19:09 -04:00
2022-04-01 16:12:46 -04:00
return newValue;
});
2022-04-02 01:33:29 -04:00
}, [ isUnseen ]);
2022-03-30 10:19:09 -04:00
UseMessageEventHook(PetAddedToInventoryEvent, onPetAddedToInventoryEvent);
const onPetRemovedFromInventory = useCallback((event: PetRemovedFromInventory) =>
{
const parser = event.getParser();
setPetItems(prevValue =>
2022-04-01 16:12:46 -04:00
{
const newValue = [ ...prevValue ];
2022-03-30 10:19:09 -04:00
2022-04-01 16:12:46 -04:00
removePetItemById(parser.petId, newValue);
2022-03-30 10:19:09 -04:00
2022-04-01 16:12:46 -04:00
return newValue;
});
2022-03-30 10:19:09 -04:00
}, []);
UseMessageEventHook(PetRemovedFromInventory, onPetRemovedFromInventory);
useEffect(() =>
{
if(!petItems || !petItems.length) return;
setSelectedPet(prevValue =>
2022-04-01 16:12:46 -04:00
{
let newValue = prevValue;
2022-03-30 10:19:09 -04:00
2022-04-01 16:12:46 -04:00
if(newValue && (petItems.indexOf(newValue) === -1)) newValue = null;
2022-03-30 10:19:09 -04:00
2022-04-01 16:12:46 -04:00
if(!newValue) newValue = petItems[0];
2022-03-30 10:19:09 -04:00
2022-04-01 16:12:46 -04:00
return newValue;
});
2022-03-30 10:19:09 -04:00
}, [ petItems ]);
2022-04-02 01:33:29 -04:00
useEffect(() =>
{
if(!isVisible) return;
return () =>
{
resetCategory(UnseenItemCategory.PET);
}
}, [ isVisible, resetCategory ]);
2022-03-30 10:19:09 -04:00
useEffect(() =>
{
if(!isVisible || !needsUpdate) return;
SendMessageComposer(new RequestPetsComposer());
setNeedsUpdate(false);
}, [ isVisible, needsUpdate ]);
2022-04-02 01:33:29 -04:00
return { petItems, selectedPet, setSelectedPet, activate, deactivate };
2022-03-30 10:19:09 -04:00
}
2022-04-02 01:33:29 -04:00
export const useInventoryPets = () => useBetween(useInventoryPetsState);