import { BadgeReceivedEvent, BadgesEvent, RequestBadgesComposer, SetActivatedBadgesComposer } from '@nitrots/nitro-renderer'; import { useEffect, useState } from 'react'; import { useBetween } from 'use-between'; import { GetConfigurationValue, SendMessageComposer, UnseenItemCategory } from '../../api'; import { useMessageEvent } from '../events'; import { useSharedVisibility } from '../useSharedVisibility'; import { useInventoryUnseenTracker } from './useInventoryUnseenTracker'; const useInventoryBadgesState = () => { const [ needsUpdate, setNeedsUpdate ] = useState(true); const [ badgeCodes, setBadgeCodes ] = useState([]); const [ badgeIds, setBadgeIds ] = useState>(new Map()); const [ activeBadgeCodes, setActiveBadgeCodes ] = useState([]); const [ selectedBadgeCode, setSelectedBadgeCode ] = useState(null); const { isVisible = false, activate = null, deactivate = null } = useSharedVisibility(); const { isUnseen = null, resetCategory = null } = useInventoryUnseenTracker(); const maxBadgeCount = GetConfigurationValue('user.badges.max.slots', 5); const isWearingBadge = (badgeCode: string) => (activeBadgeCodes.indexOf(badgeCode) >= 0); const canWearBadges = () => (activeBadgeCodes.length < maxBadgeCount); const toggleBadge = (badgeCode: string) => { setActiveBadgeCodes(prevValue => { const newValue = [ ...prevValue ]; const index = newValue.indexOf(badgeCode); if(index === -1) { if(!canWearBadges()) return prevValue; newValue.push(badgeCode); } else { newValue.splice(index, 1); } const composer = new SetActivatedBadgesComposer(); for(let i = 0; i < maxBadgeCount; i++) composer.addActivatedBadge(newValue[i] ?? ''); SendMessageComposer(composer); return newValue; }); }; const getBadgeId = (badgeCode: string) => { const index = badgeCodes.indexOf(badgeCode); if(index === -1) return 0; return (badgeIds.get(badgeCode) ?? 0); }; useMessageEvent(BadgesEvent, event => { const parser = event.getParser(); const allBadgeCodes = parser.getAllBadgeCodes(); setBadgeIds(() => { const newValue = new Map(); allBadgeCodes.forEach(code => { const badgeId = parser.getBadgeId(code); newValue.set(code, badgeId); }); return newValue; }); setActiveBadgeCodes(parser.getActiveBadgeCodes()); setBadgeCodes(allBadgeCodes); }); useMessageEvent(BadgeReceivedEvent, event => { const parser = event.getParser(); const unseen = isUnseen(UnseenItemCategory.BADGE, parser.badgeId); setBadgeCodes(prevValue => { const newValue = [ ...prevValue ]; if(unseen) newValue.unshift(parser.badgeCode); else newValue.push(parser.badgeCode); return newValue; }); setBadgeIds(prevValue => { const newValue = new Map(prevValue); newValue.set(parser.badgeCode, parser.badgeId); return newValue; }); }); useEffect(() => { if(!badgeCodes || !badgeCodes.length) return; setSelectedBadgeCode(prevValue => { let newValue = prevValue; if(newValue && (badgeCodes.indexOf(newValue) === -1)) newValue = null; if(!newValue) newValue = badgeCodes[0]; return newValue; }); }, [ badgeCodes ]); useEffect(() => { if(!isVisible) return; return () => { resetCategory(UnseenItemCategory.BADGE); }; }, [ isVisible, resetCategory ]); useEffect(() => { if(!isVisible || !needsUpdate) return; SendMessageComposer(new RequestBadgesComposer()); setNeedsUpdate(false); }, [ isVisible, needsUpdate ]); return { badgeCodes, activeBadgeCodes, selectedBadgeCode, setSelectedBadgeCode, isWearingBadge, canWearBadges, toggleBadge, getBadgeId, activate, deactivate }; }; export const useInventoryBadges = () => useBetween(useInventoryBadgesState);