nitro-react/src/views/hc-center/HcCenterView.tsx

290 lines
13 KiB
TypeScript
Raw Normal View History

2022-03-03 19:16:51 +01:00
import { BadgesEvent, ClubGiftInfoEvent, FigureUpdateEvent, FriendlyTime, GetClubGiftInfo, ILinkEventTracker, RequestBadgesComposer, ScrGetKickbackInfoMessageComposer, ScrKickbackData, ScrSendKickbackInfoMessageEvent, UserInfoEvent, UserSubscriptionEvent } from '@nitrots/nitro-renderer';
2021-12-05 14:14:43 +01:00
import { FC, useCallback, useEffect, useState } from 'react';
import { OverlayTrigger, Popover } from 'react-bootstrap';
2022-03-03 10:11:31 +01:00
import { AddEventLinkTracker, CreateLinkEvent, GetConfiguration, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
2022-03-12 06:23:57 +01:00
import { Base, Button, Column, Flex, LayoutAvatarImageView, LayoutBadgeImageView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common';
2022-03-03 10:11:31 +01:00
import { HcCenterEvent } from '../../events';
import { UseMessageEventHook, UseUiEvent } from '../../hooks';
2021-12-05 14:14:43 +01:00
import { BadgeResolver } from './util/BadgeResolver';
import { ClubStatus } from './util/ClubStatus';
export const HcCenterView: FC<{}> = props =>
{
2022-03-12 06:23:57 +01:00
const [ isVisible, setIsVisible ] = useState(false);
const [ userFigure, setUserFigure ] = useState<string>(null);
const [ kickbackData, setKickbackData ] = useState<ScrKickbackData>(null);
const [ clubDays, setClubDays ] = useState(0);
const [ pastClubDays, setPastClubDays ] = useState(0);
const [ clubPeriods, setPastClubPeriods ] = useState(0);
const [ minsTillExpire, setMinsTillExpire ] = useState(0);
const [ clubStatus, setClubStatus ] = useState(ClubStatus.NONE);
const [ unclaimedGifts, setUnclaimedGifts ] = useState(0);
const [ badgeCode, setBadgeCode ] = useState(BadgeResolver.default_badge);
const getClubText = () =>
2022-01-06 04:07:01 +01:00
{
2022-03-12 06:23:57 +01:00
const totalDays = ((clubPeriods * 31) + clubDays);
const minutesUntilExpiration = minsTillExpire;
2022-01-06 04:07:01 +01:00
2022-03-12 06:23:57 +01:00
if(clubStatus !== ClubStatus.ACTIVE)
2022-01-06 04:07:01 +01:00
{
2022-03-12 06:23:57 +01:00
return LocalizeText('purse.clubdays.zero.amount.text');
}
if((minutesUntilExpiration > -1) && (minutesUntilExpiration < (60 * 24)))
{
return FriendlyTime.shortFormat(minutesUntilExpiration * 60);
}
return FriendlyTime.shortFormat(totalDays * 86400);
}
2022-01-06 04:07:01 +01:00
2022-03-12 06:23:57 +01:00
const getInfoText = () =>
2022-01-06 04:07:01 +01:00
{
2022-03-12 06:23:57 +01:00
switch(clubStatus)
{
case ClubStatus.ACTIVE:
return LocalizeText(`hccenter.status.${ clubStatus }.info`, [ 'timeleft', 'joindate', 'streakduration' ], [ getClubText(), kickbackData.firstSubscriptionDate, FriendlyTime.shortFormat(kickbackData.currentHcStreak * 86400) ]);
case ClubStatus.EXPIRED:
return LocalizeText(`hccenter.status.${ clubStatus }.info`, [ 'joindate' ], [ kickbackData.firstSubscriptionDate ]);
default:
return LocalizeText(`hccenter.status.${ clubStatus }.info`);
}
}
2022-01-06 04:07:01 +01:00
2022-03-12 06:23:57 +01:00
const getHcPaydayTime = () =>
{
if(kickbackData.timeUntilPayday < 60) return LocalizeText('hccenter.special.time.soon');
return FriendlyTime.shortFormat(kickbackData.timeUntilPayday * 60);
}
2022-01-06 04:07:01 +01:00
2022-03-12 06:23:57 +01:00
const getHcPaydayAmount = () =>
{
return LocalizeText('hccenter.special.sum', [ 'credits' ], [ (kickbackData.creditRewardForStreakBonus + kickbackData.creditRewardForMonthlySpent).toString() ]);
}
2022-01-06 04:07:01 +01:00
2021-12-05 14:14:43 +01:00
const onUserInfoEvent = useCallback((event: UserInfoEvent) =>
{
const parser = event.getParser();
2022-03-12 06:23:57 +01:00
2021-12-05 14:14:43 +01:00
setUserFigure(parser.userInfo.figure);
}, []);
2022-03-12 06:23:57 +01:00
UseMessageEventHook(UserInfoEvent, onUserInfoEvent);
2021-12-05 14:14:43 +01:00
const onUserFigureEvent = useCallback((event: FigureUpdateEvent) =>
{
const parser = event.getParser();
2022-03-12 06:23:57 +01:00
2021-12-05 14:14:43 +01:00
setUserFigure(parser.figure);
}, []);
2022-03-03 10:11:31 +01:00
UseMessageEventHook(FigureUpdateEvent, onUserFigureEvent);
2021-12-05 14:14:43 +01:00
const onHcCenterEvent = useCallback((event: HcCenterEvent) =>
{
switch(event.type)
{
case HcCenterEvent.TOGGLE_HC_CENTER:
setIsVisible(!isVisible);
break;
}
}, [isVisible]);
2022-03-03 10:11:31 +01:00
UseUiEvent(HcCenterEvent.TOGGLE_HC_CENTER, onHcCenterEvent);
2021-12-05 14:14:43 +01:00
const onClubGiftInfoEvent = useCallback((event: ClubGiftInfoEvent) =>
{
const parser = event.getParser();
setUnclaimedGifts(parser.giftsAvailable);
}, []);
2022-03-12 06:23:57 +01:00
UseMessageEventHook(ClubGiftInfoEvent, onClubGiftInfoEvent);
2021-12-05 14:14:43 +01:00
const onScrSendKickbackInfo = useCallback((event: ScrSendKickbackInfoMessageEvent) =>
{
const parser = event.getParser();
2022-03-12 06:23:57 +01:00
setKickbackData(parser.data);
2021-12-05 14:14:43 +01:00
}, []);
2022-03-12 06:23:57 +01:00
UseMessageEventHook(ScrSendKickbackInfoMessageEvent, onScrSendKickbackInfo);
2021-12-05 14:14:43 +01:00
const onBadges = useCallback((event: BadgesEvent) =>
{
const parser = event.getParser();
setBadgeCode(BadgeResolver.getClubBadge(parser.getAllBadgeCodes()));
2022-03-12 06:23:57 +01:00
}, []);
2021-12-05 14:14:43 +01:00
2022-03-03 10:11:31 +01:00
UseMessageEventHook(BadgesEvent, onBadges);
2021-12-05 14:14:43 +01:00
const onUserSubscriptionEvent = useCallback((event: UserSubscriptionEvent) =>
{
const parser = event.getParser();
const productName = parser.productName;
if((productName !== 'club_habbo') && (productName !== 'habbo_club')) return;
setClubDays(Math.max(0, parser.daysToPeriodEnd));
setPastClubPeriods(Math.max(0, parser.periodsSubscribedAhead));
setPastClubDays(Math.max(0, parser.pastClubDays));
setMinsTillExpire(Math.max(0, parser.minutesUntilExpiration));
}, []);
2022-03-12 06:23:57 +01:00
UseMessageEventHook(UserSubscriptionEvent, onUserSubscriptionEvent);
const linkReceived = useCallback((url: string) =>
2021-12-05 14:14:43 +01:00
{
2022-03-12 06:23:57 +01:00
const parts = url.split('/');
2021-12-05 14:14:43 +01:00
2022-03-12 06:23:57 +01:00
if(parts.length < 2) return;
2021-12-05 14:14:43 +01:00
2022-03-12 06:23:57 +01:00
switch(parts[1])
{
case 'open':
if(parts.length > 2)
{
switch(parts[2])
{
case 'hccenter':
setIsVisible(true);
break;
}
}
return;
}
}, []);
2021-12-05 14:14:43 +01:00
2022-03-12 06:23:57 +01:00
useEffect(() =>
2021-12-05 14:14:43 +01:00
{
2022-03-12 06:23:57 +01:00
const linkTracker: ILinkEventTracker = {
linkReceived,
eventUrlPrefix: 'habboUI/'
};
2021-12-05 14:14:43 +01:00
2022-03-12 06:23:57 +01:00
AddEventLinkTracker(linkTracker);
2021-12-05 14:14:43 +01:00
2022-03-12 06:23:57 +01:00
return () => RemoveLinkEventTracker(linkTracker);
}, [ linkReceived]);
useEffect(() =>
2021-12-05 14:14:43 +01:00
{
2022-03-12 06:23:57 +01:00
if(clubDays > 0)
2021-12-05 14:14:43 +01:00
{
2022-03-12 06:23:57 +01:00
setClubStatus(ClubStatus.ACTIVE);
return;
2021-12-05 14:14:43 +01:00
}
2022-03-12 06:23:57 +01:00
if(pastClubDays > 0)
{
setClubStatus(ClubStatus.EXPIRED);
return;
}
}, [ clubDays, pastClubDays ]);
2021-12-05 14:14:43 +01:00
2022-03-12 06:23:57 +01:00
useEffect(() =>
2021-12-05 14:14:43 +01:00
{
2022-03-12 06:23:57 +01:00
SendMessageComposer(new GetClubGiftInfo());
SendMessageComposer(new ScrGetKickbackInfoMessageComposer());
SendMessageComposer(new RequestBadgesComposer());
}, []);
2021-12-05 14:14:43 +01:00
if(!isVisible) return null;
const popover = (
<Popover id="popover-basic">
<Popover.Body className="text-black py-2 px-3">
<h5>{LocalizeText('hccenter.breakdown.title')}</h5>
<div>{LocalizeText('hccenter.breakdown.creditsspent', ['credits'], [kickbackData.totalCreditsSpent.toString()])}</div>
<div>{LocalizeText('hccenter.breakdown.paydayfactor.percent', ['percent'], [(kickbackData.kickbackPercentage * 100).toString()])}</div>
<div>{LocalizeText('hccenter.breakdown.streakbonus', ['credits'], [kickbackData.creditRewardForStreakBonus.toString()])}</div>
<hr className="w-100 text-black my-1" />
<div>{LocalizeText('hccenter.breakdown.total', ['credits', 'actual'], [getHcPaydayAmount(),
((((kickbackData.kickbackPercentage * kickbackData.totalCreditsSpent) + kickbackData.creditRewardForStreakBonus) * 100) / 100).toString()])}</div>
<div className="btn btn-link text-primary p-0" onClick={() => { CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['payday.habbopage']) }}>{
LocalizeText('hccenter.special.infolink')}
</div>
</Popover.Body>
</Popover>
);
return (
2022-03-04 07:29:14 +01:00
<NitroCardView theme="primary-slim" className="nitro-hc-center">
2022-03-12 06:23:57 +01:00
<NitroCardHeaderView headerText={ LocalizeText('generic.hccenter') } onCloseClick={ () => setIsVisible(false) } />
<Flex position="relative" className="bg-muted p-2">
<Column gap={ 1 }>
<div className="hc-logo" />
<Flex>
<Button variant="success" onClick={ event => { CreateLinkEvent('catalog/open/' + GetConfiguration('hc.center')['catalog.buy']) } }>
{ LocalizeText((clubStatus === ClubStatus.ACTIVE) ? 'hccenter.btn.extend' : 'hccenter.btn.buy') }
</Button>
</Flex>
</Column>
<Base position="absolute" className="end-0 p-4 top-0 habbo-avatar">
<LayoutAvatarImageView figure={ userFigure } direction={ 4 } scale={ 2 } />
</Base>
</Flex>
2021-12-05 14:14:43 +01:00
<NitroCardContentView>
2022-03-12 06:23:57 +01:00
<Flex gap={ 2 }>
2022-03-03 19:16:51 +01:00
<LayoutBadgeImageView badgeCode={badgeCode} className="align-self-center flex-shrink-0 me-1" />
2022-03-12 06:23:57 +01:00
<Column size={ 5 } className="streak-info" gap={ 0 }>
<Text>{ LocalizeText('hccenter.status.' + clubStatus) }</Text>
<Text dangerouslySetInnerHTML={{ __html: getInfoText() }} />
</Column>
</Flex>
{ GetConfiguration('hc.center')['payday.info'] &&
<Flex alignItems="center">
<Column className="rounded-start bg-primary p-2 payday-special mb-1">
2021-12-05 14:14:43 +01:00
<h4 className="mb-1">{LocalizeText('hccenter.special.title')}</h4>
<div>{LocalizeText('hccenter.special.info')}</div>
<div className="btn btn-link text-white p-0 mt-auto align-self-baseline" onClick={() => { CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['payday.habbopage']) }}>{LocalizeText('hccenter.special.infolink')}</div>
2022-03-12 06:23:57 +01:00
</Column>
2021-12-05 14:14:43 +01:00
<div className="payday flex-shrink-0 p-2">
<h5 className="mb-2 ms-2">{LocalizeText('hccenter.special.time.title')}</h5>
<div className="d-flex flex-row mb-2">
<div className="clock me-2" />
<h6 className="mb-0 align-self-center">{getHcPaydayTime()}</h6>
</div>
{clubStatus === ClubStatus.ACTIVE &&
<div className="pe-3">
<h5 className="ms-2 mb-1 bolder">{LocalizeText('hccenter.special.amount.title')}</h5>
<div className="d-flex flex-column">
<div className="w-100 text-center ms-4n">{getHcPaydayAmount()}</div>
<OverlayTrigger trigger="hover" placement="left" overlay={popover}>
<div className="btn btn-link align-self-end text-primary">
{LocalizeText('hccenter.breakdown.infolink')}
</div>
</OverlayTrigger>
</div>
</div>
}
</div>
2022-03-12 06:23:57 +01:00
</Flex>
2021-12-05 14:14:43 +01:00
}
{GetConfiguration('hc.center')['gift.info'] &&
<div className="rounded bg-success p-2 d-flex flex-row mb-0">
<div>
<h4 className="mb-1">{LocalizeText('hccenter.gift.title')}</h4>
<div dangerouslySetInnerHTML={{ __html: unclaimedGifts > 0 ? LocalizeText('hccenter.unclaimedgifts', ['unclaimedgifts'], [unclaimedGifts.toString()]) : LocalizeText('hccenter.gift.info') }}></div>
</div>
<button className="btn btn-primary btn-lg align-self-center ms-auto" onClick={() => { CreateLinkEvent('catalog/open/' + GetConfiguration('hc.center')['catalog.gifts']) }}>{LocalizeText(clubStatus === ClubStatus.ACTIVE ? 'hccenter.btn.gifts.redeem' : 'hccenter.btn.gifts.view')}</button>
</div>
}
{GetConfiguration('hc.center')['benefits.info'] &&
<div className="benefits text-black py-2">
<h5 className="mb-1 text-primary">{LocalizeText('hccenter.general.title')}</h5>
<div className="mb-2" dangerouslySetInnerHTML={{ __html: LocalizeText('hccenter.general.info') }} />
<button className="btn btn-link p-0 text-primary" onClick={() => { CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['benefits.habbopage']) }}>{LocalizeText('hccenter.general.infolink')}</button>
</div>
}
</NitroCardContentView>
</NitroCardView>
);
}