mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-26 23:50:52 +01:00
Purse updates
This commit is contained in:
parent
d229e63135
commit
9d1590c74c
@ -1,69 +1,59 @@
|
|||||||
import { UserCreditsEvent, UserCurrencyEvent, UserCurrencyUpdateEvent, UserSubscriptionEvent } from 'nitro-renderer';
|
import { UserCreditsEvent, UserCurrencyEvent, UserCurrencyUpdateEvent, UserSubscriptionEvent, UserSubscriptionParser } 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 { Currency } from './common/Currency';
|
|
||||||
import { usePurseContext } from './context/PurseContext';
|
import { usePurseContext } from './context/PurseContext';
|
||||||
import { PurseMessageHandlerProps } from './PurseMessageHandler.types';
|
import { PurseMessageHandlerProps } from './PurseMessageHandler.types';
|
||||||
import { PurseActions } from './reducers/PurseReducer';
|
|
||||||
|
|
||||||
export const PurseMessageHandler: FC<PurseMessageHandlerProps> = props =>
|
export const PurseMessageHandler: FC<PurseMessageHandlerProps> = props =>
|
||||||
{
|
{
|
||||||
const { dispatchPurseState = null } = usePurseContext();
|
const { purse = null } = usePurseContext();
|
||||||
|
|
||||||
const onUserCreditsEvent = useCallback((event: UserCreditsEvent) =>
|
const onUserCreditsEvent = useCallback((event: UserCreditsEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
dispatchPurseState({
|
purse.credits = parseFloat(parser.credits);
|
||||||
type: PurseActions.SET_CURRENCY,
|
|
||||||
payload: {
|
purse.notify();
|
||||||
currency: { type: -1, amount: parseFloat(parser.credits) }
|
}, [ purse ]);
|
||||||
}
|
|
||||||
});
|
|
||||||
}, [ dispatchPurseState ]);
|
|
||||||
|
|
||||||
const onUserCurrencyEvent = useCallback((event: UserCurrencyEvent) =>
|
const onUserCurrencyEvent = useCallback((event: UserCurrencyEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
const currencies: Currency[] = [];
|
purse.activityPoints = parser.currencies;
|
||||||
|
|
||||||
for(const [ key, value ] of parser.currencies.entries()) currencies.push({ type: key, amount: value });
|
purse.notify();
|
||||||
|
}, [ purse ]);
|
||||||
dispatchPurseState({
|
|
||||||
type: PurseActions.SET_CURRENCIES,
|
|
||||||
payload: { currencies }
|
|
||||||
});
|
|
||||||
}, [ dispatchPurseState ]);
|
|
||||||
|
|
||||||
const onUserCurrencyUpdateEvent = useCallback((event: UserCurrencyUpdateEvent) =>
|
const onUserCurrencyUpdateEvent = useCallback((event: UserCurrencyUpdateEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
dispatchPurseState({
|
purse.activityPoints.set(parser.type, parser.amount);
|
||||||
type: PurseActions.SET_CURRENCY,
|
|
||||||
payload: {
|
purse.notify();
|
||||||
currency: { type: parser.type, amount: parser.amount }
|
}, [ purse ]);
|
||||||
}
|
|
||||||
});
|
|
||||||
}, [ dispatchPurseState ]);
|
|
||||||
|
|
||||||
const onUserSubscriptionEvent = useCallback((event: UserSubscriptionEvent) =>
|
const onUserSubscriptionEvent = useCallback((event: UserSubscriptionEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
switch(parser.name)
|
const productName = parser.productName;
|
||||||
{
|
|
||||||
case 'habbo_club':
|
if((productName !== 'club_habbo') && (productName !== 'habbo_club')) return;
|
||||||
dispatchPurseState({
|
|
||||||
type: PurseActions.SET_CLUB_SUBSCRIPTION,
|
purse.clubDays = Math.max(0, parser.daysToPeriodEnd);
|
||||||
payload: {
|
purse.clubPeriods = Math.max(0, parser.periodsSubscribedAhead);
|
||||||
clubSubscription: parser
|
purse.isVip = parser.isVip;
|
||||||
}
|
purse.pastClubDays = parser.pastClubDays;
|
||||||
});
|
purse.pastVipDays = parser.pastVipDays;
|
||||||
return;
|
purse.isExpiring = ((parser.responseType === UserSubscriptionParser.RESPONSE_TYPE_DISCOUNT_AVAILABLE) ? true : false);
|
||||||
}
|
purse.minutesUntilExpiration = parser.minutesUntilExpiration;
|
||||||
}, [ dispatchPurseState ]);
|
purse.minutesSinceLastModified = parser.minutesSinceLastModified;
|
||||||
|
|
||||||
|
purse.notify();
|
||||||
|
}, [ purse ]);
|
||||||
|
|
||||||
CreateMessageHook(UserCreditsEvent, onUserCreditsEvent);
|
CreateMessageHook(UserCreditsEvent, onUserCreditsEvent);
|
||||||
CreateMessageHook(UserCurrencyEvent, onUserCurrencyEvent);
|
CreateMessageHook(UserCurrencyEvent, onUserCurrencyEvent);
|
||||||
|
@ -2,9 +2,8 @@
|
|||||||
padding: 2px;
|
padding: 2px;
|
||||||
background-color: #1c323f;
|
background-color: #1c323f;
|
||||||
border: 2px solid rgba($white, 0.5);
|
border: 2px solid rgba($white, 0.5);
|
||||||
border-top:0;
|
border-top: 0;
|
||||||
font-size: $font-size-sm;
|
font-size: $font-size-sm;
|
||||||
z-index: $context-menu-zindex;
|
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
margin-bottom:5px;
|
margin-bottom:5px;
|
||||||
|
|
||||||
@ -35,5 +34,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@import './currency/CurrencyView';
|
@import './views';
|
||||||
@import './seasonal/SeasonalView';
|
|
||||||
|
@ -1,62 +1,130 @@
|
|||||||
import { UserCurrencyComposer } from 'nitro-renderer';
|
import { FriendlyTime, HabboClubLevelEnum, UserCurrencyComposer, UserSubscriptionComposer } from 'nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useMemo, useReducer } from 'react';
|
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { GetConfiguration } from '../../api';
|
import { GetConfiguration } from '../../api';
|
||||||
import { NotificationCenterEvent } from '../../events';
|
|
||||||
import { dispatchUiEvent } from '../../hooks/events';
|
|
||||||
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 { CurrencyIcon } from '../shared/currency-icon/CurrencyIcon';
|
import { CurrencyIcon } from '../shared/currency-icon/CurrencyIcon';
|
||||||
import { SetLastCurrencies } from './common/CurrencyHelper';
|
import { IPurse } from './common/IPurse';
|
||||||
|
import { Purse } from './common/Purse';
|
||||||
import { PurseContextProvider } from './context/PurseContext';
|
import { PurseContextProvider } from './context/PurseContext';
|
||||||
import { CurrencyView } from './currency/CurrencyView';
|
|
||||||
import { PurseMessageHandler } from './PurseMessageHandler';
|
import { PurseMessageHandler } from './PurseMessageHandler';
|
||||||
import { PurseViewProps } from './PurseView.types';
|
import { CurrencyView } from './views/currency/CurrencyView';
|
||||||
import { initialPurse, PurseReducer } from './reducers/PurseReducer';
|
import { SeasonalView } from './views/seasonal/SeasonalView';
|
||||||
import { SeasonalView } from './seasonal/SeasonalView';
|
|
||||||
|
|
||||||
export const PurseView: FC<PurseViewProps> = props =>
|
export let GLOBAL_PURSE: IPurse = null;
|
||||||
|
|
||||||
|
export const PurseView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [ purseState, dispatchPurseState ] = useReducer(PurseReducer, initialPurse);
|
const [ purse, setPurse ] = useState<IPurse>(new Purse());
|
||||||
const { currencies = [] } = purseState;
|
const [ updateId, setUpdateId ] = useState(-1);
|
||||||
|
|
||||||
const displayedCurrencies = useMemo(() =>
|
const displayedCurrencies = useMemo(() =>
|
||||||
{
|
{
|
||||||
return GetConfiguration<number[]>('system.currency.types', []);
|
return GetConfiguration<number[]>('system.currency.types', []);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const getCurrencyElements = useCallback((offset: number, limit: number = -1, seasonal: boolean = false) =>
|
||||||
|
{
|
||||||
|
if(!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(<SeasonalView key={ type } type={ type } amount={ purse.activityPoints.get(type) } />);
|
||||||
|
else elements.push(<CurrencyView key={ type } type={ type } amount={ purse.activityPoints.get(type) } />);
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return elements;
|
||||||
|
}, [ purse, displayedCurrencies ]);
|
||||||
|
|
||||||
|
const getClubText = useCallback(() =>
|
||||||
|
{
|
||||||
|
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 ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
SendMessageHook(new UserCurrencyComposer());
|
const purse = new Purse();
|
||||||
|
|
||||||
|
GLOBAL_PURSE = purse;
|
||||||
|
|
||||||
|
purse.notifier = () => setUpdateId(prevValue => (prevValue + 1));
|
||||||
|
|
||||||
|
setPurse(purse);
|
||||||
|
|
||||||
|
return () => (purse.notifier = null);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
SetLastCurrencies(currencies);
|
useEffect(() =>
|
||||||
|
|
||||||
const toggleNotificationCenter = useCallback(() =>
|
|
||||||
{
|
{
|
||||||
dispatchUiEvent(new NotificationCenterEvent(NotificationCenterEvent.TOGGLE_NOTIFICATION_CENTER));
|
if(!purse) return;
|
||||||
}, []);
|
|
||||||
|
SendMessageHook(new UserCurrencyComposer());
|
||||||
|
}, [ purse ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
SendMessageHook(new UserSubscriptionComposer('habbo_club'));
|
||||||
|
|
||||||
|
const interval = setInterval(() =>
|
||||||
|
{
|
||||||
|
SendMessageHook(new UserSubscriptionComposer('habbo_club'));
|
||||||
|
}, 50000);
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [ purse ]);
|
||||||
|
|
||||||
|
if(!purse) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PurseContextProvider value={ { purseState, dispatchPurseState }}>
|
<PurseContextProvider value={ { purse } }>
|
||||||
<PurseMessageHandler />
|
<PurseMessageHandler />
|
||||||
<div className="nitro-purse rounded-bottom d-flex flex-row justify-content-between">
|
<div className="nitro-purse rounded-bottom d-flex flex-row justify-content-between">
|
||||||
<div className="row mx-0 w-100">
|
<div className="row mx-0 w-100">
|
||||||
<div className="col-6 px-0">
|
<div className="col-6 px-0">
|
||||||
<div className="d-flex flex-column nitro-currencies">
|
<div className="d-flex flex-column nitro-currencies">
|
||||||
{ currencies && currencies.map((currency, index) =>
|
<CurrencyView type={ -1 } amount={ purse.credits } />
|
||||||
{
|
{ getCurrencyElements(0, 2) }
|
||||||
if (displayedCurrencies.indexOf(currency.type) === -1) return null;
|
|
||||||
|
|
||||||
if (currency.type === -1 || currency.type === 0 || currency.type === 5) return <CurrencyView key={index} currency={currency} />;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-4 px-0">
|
<div className="col-4 px-0">
|
||||||
<div className="nitro-purse-hc p-1 d-flex flex-column justify-content-center align-items-center h-100">
|
<div className="nitro-purse-hc p-1 d-flex flex-column justify-content-center align-items-center h-100">
|
||||||
<CurrencyIcon className="flex-shrink-0" type="hc" />
|
<CurrencyIcon className="flex-shrink-0" type="hc" />
|
||||||
<span>{LocalizeText('purse.clubdays.zero.amount.text')}</span>
|
<span>{ getClubText() }</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-2 px-0">
|
<div className="col-2 px-0">
|
||||||
@ -70,14 +138,7 @@ export const PurseView: FC<PurseViewProps> = props =>
|
|||||||
<i className="fas fa-bars" />
|
<i className="fas fa-bars" />
|
||||||
</div>*/}
|
</div>*/}
|
||||||
</div>
|
</div>
|
||||||
{ currencies && currencies.map((currency, index) =>
|
{ getCurrencyElements(2, -1, true) }
|
||||||
{
|
|
||||||
if (displayedCurrencies.indexOf(currency.type) === -1) return null;
|
|
||||||
|
|
||||||
if (currency.type === -1 || currency.type === 0 || currency.type === 5) return null;
|
|
||||||
|
|
||||||
return <SeasonalView key={index} currency={ currency } />;
|
|
||||||
})}
|
|
||||||
</PurseContextProvider>
|
</PurseContextProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
export interface PurseViewProps
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
@ -1,19 +1,16 @@
|
|||||||
import { Currency } from './Currency';
|
import { GLOBAL_PURSE } from '../PurseView';
|
||||||
|
|
||||||
let lastCurrencies: Currency[] = [];
|
|
||||||
|
|
||||||
export function SetLastCurrencies(currencies: Currency[]): void
|
|
||||||
{
|
|
||||||
lastCurrencies = currencies;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function GetCurrencyAmount(type: number): number
|
export function GetCurrencyAmount(type: number): number
|
||||||
{
|
{
|
||||||
for(const currency of lastCurrencies)
|
const purse = GLOBAL_PURSE;
|
||||||
{
|
|
||||||
if(currency.type !== type) continue;
|
|
||||||
|
|
||||||
return currency.amount;
|
if(type === -1) return purse.credits;
|
||||||
|
|
||||||
|
for(const [ key, value ] of purse.activityPoints.entries())
|
||||||
|
{
|
||||||
|
if(key !== type) continue;
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
17
src/views/purse/common/IPurse.ts
Normal file
17
src/views/purse/common/IPurse.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
export interface IPurse
|
||||||
|
{
|
||||||
|
credits: number;
|
||||||
|
activityPoints: Map<number, number>;
|
||||||
|
clubDays: number;
|
||||||
|
clubPeriods: number;
|
||||||
|
_Str_13571: boolean;
|
||||||
|
isVip: boolean;
|
||||||
|
pastClubDays: number;
|
||||||
|
pastVipDays: number;
|
||||||
|
isExpiring: boolean;
|
||||||
|
minutesUntilExpiration: number;
|
||||||
|
minutesSinceLastModified: number;
|
||||||
|
clubLevel: number;
|
||||||
|
notifier: () => void
|
||||||
|
notify(): void;
|
||||||
|
}
|
163
src/views/purse/common/Purse.ts
Normal file
163
src/views/purse/common/Purse.ts
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
import { HabboClubLevelEnum } from 'nitro-renderer';
|
||||||
|
import { GetNitroInstance } from '../../../api';
|
||||||
|
import { IPurse } from './IPurse';
|
||||||
|
|
||||||
|
export class Purse implements IPurse
|
||||||
|
{
|
||||||
|
private _credits: number = 0;
|
||||||
|
private _activityPoints: Map<number, number> = new Map();
|
||||||
|
private _clubDays: number = 0;
|
||||||
|
private _clubPeriods: number = 0;
|
||||||
|
private _isVIP: boolean = false;
|
||||||
|
private _pastClubDays: number = 0;
|
||||||
|
private _pastVipDays: number = 0;
|
||||||
|
private _isExpiring: boolean = false;
|
||||||
|
private _minutesUntilExpiration: number = 0;
|
||||||
|
private _minutesSinceLastModified: number;
|
||||||
|
private _lastUpdated: number;
|
||||||
|
private _notifier: () => void;
|
||||||
|
|
||||||
|
public get credits(): number
|
||||||
|
{
|
||||||
|
return this._credits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set credits(credits: number)
|
||||||
|
{
|
||||||
|
this._lastUpdated = GetNitroInstance().time;
|
||||||
|
this._credits = credits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get activityPoints(): Map<number, number>
|
||||||
|
{
|
||||||
|
return this._activityPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set activityPoints(k: Map<number, number>)
|
||||||
|
{
|
||||||
|
this._lastUpdated = GetNitroInstance().time;
|
||||||
|
this._activityPoints = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get clubDays(): number
|
||||||
|
{
|
||||||
|
return this._clubDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set clubDays(k: number)
|
||||||
|
{
|
||||||
|
this._lastUpdated = GetNitroInstance().time;
|
||||||
|
this._clubDays = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get clubPeriods(): number
|
||||||
|
{
|
||||||
|
return this._clubPeriods;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set clubPeriods(k: number)
|
||||||
|
{
|
||||||
|
this._lastUpdated = GetNitroInstance().time;
|
||||||
|
this._clubPeriods = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get _Str_13571(): boolean
|
||||||
|
{
|
||||||
|
return (this._clubDays > 0) || (this._clubPeriods > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isVip(): boolean
|
||||||
|
{
|
||||||
|
return this._isVIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set isVip(k: boolean)
|
||||||
|
{
|
||||||
|
this._isVIP = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get pastClubDays(): number
|
||||||
|
{
|
||||||
|
return this._pastClubDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set pastClubDays(k: number)
|
||||||
|
{
|
||||||
|
this._lastUpdated = GetNitroInstance().time;
|
||||||
|
this._pastClubDays = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get pastVipDays(): number
|
||||||
|
{
|
||||||
|
return this._pastVipDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set pastVipDays(k: number)
|
||||||
|
{
|
||||||
|
this._lastUpdated = GetNitroInstance().time;
|
||||||
|
this._pastVipDays = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isExpiring(): boolean
|
||||||
|
{
|
||||||
|
return this._isExpiring;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set isExpiring(k: boolean)
|
||||||
|
{
|
||||||
|
this._isExpiring = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get minutesUntilExpiration(): number
|
||||||
|
{
|
||||||
|
var k: number = ((GetNitroInstance().time - this._lastUpdated) / (1000 * 60));
|
||||||
|
var _local_2: number = (this._minutesUntilExpiration - k);
|
||||||
|
return (_local_2 > 0) ? _local_2 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set minutesUntilExpiration(k: number)
|
||||||
|
{
|
||||||
|
this._lastUpdated = GetNitroInstance().time;
|
||||||
|
this._minutesUntilExpiration = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get minutesSinceLastModified(): number
|
||||||
|
{
|
||||||
|
return this._minutesSinceLastModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set minutesSinceLastModified(k: number)
|
||||||
|
{
|
||||||
|
this._lastUpdated = GetNitroInstance().time;
|
||||||
|
this._minutesSinceLastModified = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get lastUpdated(): number
|
||||||
|
{
|
||||||
|
return this._lastUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get notifier(): () => void
|
||||||
|
{
|
||||||
|
return this._notifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set notifier(notifier: () => void)
|
||||||
|
{
|
||||||
|
this._notifier = notifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get clubLevel(): number
|
||||||
|
{
|
||||||
|
if(((this.clubDays === 0) && (this.clubPeriods === 0))) return HabboClubLevelEnum.NO_CLUB;
|
||||||
|
|
||||||
|
if (this.isVip) return HabboClubLevelEnum.VIP;
|
||||||
|
|
||||||
|
return HabboClubLevelEnum.CLUB;
|
||||||
|
}
|
||||||
|
|
||||||
|
public notify(): void
|
||||||
|
{
|
||||||
|
if(this._notifier) this._notifier();
|
||||||
|
}
|
||||||
|
}
|
@ -2,8 +2,7 @@ import { createContext, FC, useContext } from 'react';
|
|||||||
import { IPurseContext, PurseContextProps } from './PurseContext.types';
|
import { IPurseContext, PurseContextProps } from './PurseContext.types';
|
||||||
|
|
||||||
const PurseContext = createContext<IPurseContext>({
|
const PurseContext = createContext<IPurseContext>({
|
||||||
purseState: null,
|
purse: null
|
||||||
dispatchPurseState: null
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const PurseContextProvider: FC<PurseContextProps> = props =>
|
export const PurseContextProvider: FC<PurseContextProps> = props =>
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import { Dispatch, ProviderProps } from 'react';
|
import { ProviderProps } from 'react';
|
||||||
import { IPurseAction, IPurseState } from '../reducers/PurseReducer';
|
import { IPurse } from '../common/IPurse';
|
||||||
|
|
||||||
export interface IPurseContext
|
export interface IPurseContext
|
||||||
{
|
{
|
||||||
purseState: IPurseState;
|
purse: IPurse;
|
||||||
dispatchPurseState: Dispatch<IPurseAction>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PurseContextProps extends ProviderProps<IPurseContext>
|
export interface PurseContextProps extends ProviderProps<IPurseContext>
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
import { Currency } from '../common/Currency';
|
|
||||||
|
|
||||||
export interface CurrencyViewProps
|
|
||||||
{
|
|
||||||
currency: Currency;
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
import { UserSubscriptionParser } from 'nitro-renderer';
|
|
||||||
import { Reducer } from 'react';
|
|
||||||
import { Currency } from '../common/Currency';
|
|
||||||
|
|
||||||
export interface IPurseState
|
|
||||||
{
|
|
||||||
currencies: Currency[];
|
|
||||||
clubSubscription: UserSubscriptionParser;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IPurseAction
|
|
||||||
{
|
|
||||||
type: string;
|
|
||||||
payload: {
|
|
||||||
currency?: Currency;
|
|
||||||
currencies?: Currency[];
|
|
||||||
clubSubscription?: UserSubscriptionParser;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PurseActions
|
|
||||||
{
|
|
||||||
public static SET_CURRENCY: string = 'PA_SET_CURRENCY';
|
|
||||||
public static SET_CURRENCIES: string = 'PA_SET_CURRENCIES';
|
|
||||||
public static SET_CLUB_SUBSCRIPTION: string = 'PA_SET_CLUB_SUBSCRIPTION';
|
|
||||||
}
|
|
||||||
|
|
||||||
export const initialPurse: IPurseState = {
|
|
||||||
currencies: [],
|
|
||||||
clubSubscription: null
|
|
||||||
}
|
|
||||||
|
|
||||||
export const PurseReducer: Reducer<IPurseState, IPurseAction> = (state, action) =>
|
|
||||||
{
|
|
||||||
switch(action.type)
|
|
||||||
{
|
|
||||||
case PurseActions.SET_CURRENCY: {
|
|
||||||
const updated = action.payload.currency;
|
|
||||||
|
|
||||||
let didSet = false;
|
|
||||||
|
|
||||||
const currencies = state.currencies.map(existing =>
|
|
||||||
{
|
|
||||||
if(existing.type !== updated.type) return existing;
|
|
||||||
|
|
||||||
didSet = true;
|
|
||||||
|
|
||||||
return { ...updated };
|
|
||||||
});
|
|
||||||
|
|
||||||
if(!didSet) currencies.push({ ...updated });
|
|
||||||
|
|
||||||
return { ...state, currencies };
|
|
||||||
}
|
|
||||||
case PurseActions.SET_CURRENCIES: {
|
|
||||||
const updated = action.payload.currencies;
|
|
||||||
|
|
||||||
const currencies = state.currencies.filter(existing =>
|
|
||||||
{
|
|
||||||
if(existing.type !== -1) return null;
|
|
||||||
|
|
||||||
return existing;
|
|
||||||
});
|
|
||||||
|
|
||||||
if(updated && updated.length) currencies.push(...updated);
|
|
||||||
|
|
||||||
return { ...state, currencies };
|
|
||||||
}
|
|
||||||
case PurseActions.SET_CLUB_SUBSCRIPTION: {
|
|
||||||
const clubSubscription = action.payload.clubSubscription;
|
|
||||||
|
|
||||||
return { ...state, clubSubscription };
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
import { Currency } from '../common/Currency';
|
|
||||||
|
|
||||||
export interface SeasonalViewProps
|
|
||||||
{
|
|
||||||
currency: Currency;
|
|
||||||
}
|
|
@ -1,24 +1,24 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { OverlayTrigger, Tooltip } from 'react-bootstrap';
|
import { OverlayTrigger, Tooltip } from 'react-bootstrap';
|
||||||
import { LocalizeShortNumber } from '../../../utils/LocalizeShortNumber';
|
import { LocalizeShortNumber } from '../../../../utils/LocalizeShortNumber';
|
||||||
import { CurrencyIcon } from '../../shared/currency-icon/CurrencyIcon';
|
import { CurrencyIcon } from '../../../shared/currency-icon/CurrencyIcon';
|
||||||
import { CurrencyViewProps } from './CurrencyView.types';
|
import { CurrencyViewProps } from './CurrencyView.types';
|
||||||
|
|
||||||
export const CurrencyView: FC<CurrencyViewProps> = props =>
|
export const CurrencyView: FC<CurrencyViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { currency = null } = props;
|
const { type = -1, amount = -1 } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OverlayTrigger
|
<OverlayTrigger
|
||||||
placement="left"
|
placement="left"
|
||||||
overlay={
|
overlay={
|
||||||
<Tooltip id={`tooltip-${currency.type}`}>
|
<Tooltip id={`tooltip-${ type }`}>
|
||||||
{ currency.amount }
|
{ amount }
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
}>
|
}>
|
||||||
<div className="nitro-currency d-flex justify-content-end nitro-purse-button">
|
<div className="nitro-currency d-flex justify-content-end nitro-purse-button">
|
||||||
<div className="px-1 text-end text-truncate nitro-currency-text align-self-center">{LocalizeShortNumber(currency.amount)}</div>
|
<div className="px-1 text-end text-truncate nitro-currency-text align-self-center">{LocalizeShortNumber(amount)}</div>
|
||||||
<CurrencyIcon className="flex-shrink-0" type={ currency.type } />
|
<CurrencyIcon className="flex-shrink-0" type={ type } />
|
||||||
</div>
|
</div>
|
||||||
</OverlayTrigger>
|
</OverlayTrigger>
|
||||||
);
|
);
|
@ -1,4 +1,4 @@
|
|||||||
export interface Currency
|
export interface CurrencyViewProps
|
||||||
{
|
{
|
||||||
type: number;
|
type: number;
|
||||||
amount: number;
|
amount: number;
|
2
src/views/purse/views/index.scss
Normal file
2
src/views/purse/views/index.scss
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@import './currency/CurrencyView';
|
||||||
|
@import './seasonal/SeasonalView';
|
@ -1,21 +1,21 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { LocalizeShortNumber } from '../../../utils/LocalizeShortNumber';
|
import { LocalizeShortNumber } from '../../../../utils/LocalizeShortNumber';
|
||||||
import { LocalizeText } from '../../../utils/LocalizeText';
|
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||||
import { CurrencyIcon } from '../../shared/currency-icon/CurrencyIcon';
|
import { CurrencyIcon } from '../../../shared/currency-icon/CurrencyIcon';
|
||||||
import { SeasonalViewProps } from './SeasonalView.types';
|
import { SeasonalViewProps } from './SeasonalView.types';
|
||||||
|
|
||||||
export const SeasonalView: FC<SeasonalViewProps> = props =>
|
export const SeasonalView: FC<SeasonalViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { currency = null } = props;
|
const { type = -1, amount = -1 } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="nitro-seasonal-currency rounded d-flex justify-content-end">
|
<div className="nitro-seasonal-currency rounded d-flex justify-content-end">
|
||||||
<div className="nitro-currency-text w-100 px-1 d-flex justify-content-between">
|
<div className="nitro-currency-text w-100 px-1 d-flex justify-content-between">
|
||||||
<span>{ LocalizeText(`purse.seasonal.currency.${currency.type}`) }</span>
|
<span>{ LocalizeText(`purse.seasonal.currency.${ type }`) }</span>
|
||||||
<span>{ LocalizeShortNumber(currency.amount) }</span>
|
<span>{ LocalizeShortNumber(amount) }</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="nitro-seasonal-icon">
|
<div className="nitro-seasonal-icon">
|
||||||
<CurrencyIcon type={ currency.type } />
|
<CurrencyIcon type={ type } />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
6
src/views/purse/views/seasonal/SeasonalView.types.ts
Normal file
6
src/views/purse/views/seasonal/SeasonalView.types.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
export interface SeasonalViewProps
|
||||||
|
{
|
||||||
|
type: number;
|
||||||
|
amount: number;
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
.nitro-right-side {
|
.nitro-right-side {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
right: 5px;
|
right: 10px;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
z-index: $rightside-zindex;
|
z-index: $rightside-zindex;
|
||||||
|
Loading…
Reference in New Issue
Block a user