import { ActivityPointNotificationMessageEvent, FriendlyTime, HabboClubLevelEnum, UserCreditsEvent, UserCurrencyComposer, UserCurrencyEvent, UserSubscriptionComposer, UserSubscriptionEvent, UserSubscriptionParser } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { CreateLinkEvent, CREDITS, DUCKETS, GetConfiguration, LocalizeText, PlaySound, SendMessageComposer } from '../../api'; import { Column, Flex, Grid, Text } from '../../common'; import { HcCenterEvent, UserSettingsUIEvent } from '../../events'; import { DispatchUiEvent, UseMessageEventHook } from '../../hooks'; import { CurrencyIcon } from '../../views/shared/currency-icon/CurrencyIcon'; import { IPurse } from './common/IPurse'; import { Purse } from './common/Purse'; import { PurseContextProvider } from './PurseContext'; import { CurrencyView } from './views/CurrencyView'; import { SeasonalView } from './views/SeasonalView'; export let GLOBAL_PURSE: IPurse = null; export const PurseView: FC<{}> = props => { const [ purse, setPurse ] = useState(new Purse()); const displayedCurrencies = useMemo(() => GetConfiguration('system.currency.types', []), []); const currencyDisplayNumberShort = useMemo(() => GetConfiguration('currency.display.number.short', false), []); const getClubText = useMemo(() => { if(!purse) return null; const totalDays = ((purse.clubPeriods * 31) + purse.clubDays); const minutesUntilExpiration = purse.minutesUntilExpiration; if(purse.clubLevel === HabboClubLevelEnum.NO_CLUB) return LocalizeText('purse.clubdays.zero.amount.text'); else if((minutesUntilExpiration > -1) && (minutesUntilExpiration < (60 * 24))) return FriendlyTime.shortFormat(minutesUntilExpiration * 60); else return FriendlyTime.shortFormat(totalDays * 86400); }, [ purse ]); const getCurrencyElements = useCallback((offset: number, limit: number = -1, seasonal: boolean = false) => { if(!purse || !purse.activityPoints || !purse.activityPoints.size) return null; const types = Array.from(purse.activityPoints.keys()).filter(type => (displayedCurrencies.indexOf(type) >= 0)); let count = 0; while(count < offset) { types.shift(); count++; } count = 0; const elements: JSX.Element[] = []; for(const type of types) { if((limit > -1) && (count === limit)) break; if(seasonal) elements.push(); else elements.push(); count++; } return elements; }, [ purse, displayedCurrencies, currencyDisplayNumberShort ]); const onUserCreditsEvent = useCallback((event: UserCreditsEvent) => { const parser = event.getParser(); setPurse(prevValue => { const newValue = { ...prevValue }; newValue.credits = parseFloat(parser.credits); if(prevValue.credits !== newValue.credits) PlaySound(CREDITS); return newValue; }); }, []); UseMessageEventHook(UserCreditsEvent, onUserCreditsEvent); const onUserCurrencyEvent = useCallback((event: UserCurrencyEvent) => { const parser = event.getParser(); setPurse(prevValue => { const newValue = { ...prevValue }; newValue.activityPoints = parser.currencies; return newValue; }); }, []); UseMessageEventHook(UserCurrencyEvent, onUserCurrencyEvent); const onActivityPointNotificationMessageEvent = useCallback((event: ActivityPointNotificationMessageEvent) => { const parser = event.getParser(); setPurse(prevValue => { const newValue = { ...prevValue }; newValue.activityPoints = new Map(newValue.activityPoints); newValue.activityPoints.set(parser.type, parser.amount); if(parser.type === 0) PlaySound(DUCKETS) return newValue; }); }, []); UseMessageEventHook(ActivityPointNotificationMessageEvent, onActivityPointNotificationMessageEvent); const onUserSubscriptionEvent = useCallback((event: UserSubscriptionEvent) => { const parser = event.getParser(); const productName = parser.productName; if((productName !== 'club_habbo') && (productName !== 'habbo_club')) return; setPurse(prevValue => { const newValue = { ...prevValue }; newValue.clubDays = Math.max(0, parser.daysToPeriodEnd); newValue.clubPeriods = Math.max(0, parser.periodsSubscribedAhead); newValue.isVip = parser.isVip; newValue.pastClubDays = parser.pastClubDays; newValue.pastVipDays = parser.pastVipDays; newValue.isExpiring = ((parser.responseType === UserSubscriptionParser.RESPONSE_TYPE_DISCOUNT_AVAILABLE) ? true : false); newValue.minutesUntilExpiration = parser.minutesUntilExpiration; newValue.minutesSinceLastModified = parser.minutesSinceLastModified; return newValue; }); }, []); UseMessageEventHook(UserSubscriptionEvent, onUserSubscriptionEvent); useEffect(() => { GLOBAL_PURSE = purse; }, [ purse ]); useEffect(() => { SendMessageComposer(new UserSubscriptionComposer('habbo_club')); const interval = setInterval(() => SendMessageComposer(new UserSubscriptionComposer('habbo_club')), 50000); return () => clearInterval(interval); }, [ purse ]); useEffect(() => { SendMessageComposer(new UserCurrencyComposer()); }, []); if(!purse) return null; return ( { getCurrencyElements(0, 2) } DispatchUiEvent(new HcCenterEvent(HcCenterEvent.TOGGLE_HC_CENTER)) }> { getClubText } CreateLinkEvent('help/show') }> DispatchUiEvent(new UserSettingsUIEvent(UserSettingsUIEvent.TOGGLE_USER_SETTINGS)) } > { getCurrencyElements(2, -1, true) } ); }