mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-23 06:40:50 +01:00
Update alerts
This commit is contained in:
parent
94f0d142c7
commit
83df995ce3
@ -126,6 +126,7 @@ export const App: FC<{}> = props =>
|
||||
|
||||
return (
|
||||
<div className="nitro-app">
|
||||
<div id="nitro-alerts-container" />
|
||||
{ (!isReady || isError) && <LoadingView isError={ isError } message={ message } /> }
|
||||
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ (isReady && !isError) } timeout={ 300 }>
|
||||
<MainView />
|
||||
|
@ -1,29 +1,36 @@
|
||||
import { NitroEvent } from '@nitrots/nitro-renderer';
|
||||
|
||||
export class SimpleAlertUIEvent extends NitroEvent
|
||||
export class NotificationAlertEvent extends NitroEvent
|
||||
{
|
||||
public static ALERT: string = 'SAUE_ALERT';
|
||||
public static ALERT: string = 'NAE_ALERT';
|
||||
|
||||
private _message: string;
|
||||
private _messages: string[];
|
||||
private _alertType: string;
|
||||
private _clickUrl: string;
|
||||
private _clickUrlText: string;
|
||||
private _title: string;
|
||||
private _imageUrl: string;
|
||||
|
||||
constructor(message: string, clickUrl: string = null, clickUrlText: string = null, title: string = null, imageUrl: string = null)
|
||||
constructor(messages: string[], alertType: string = null, clickUrl: string = null, clickUrlText: string = null, title: string = null, imageUrl: string = null)
|
||||
{
|
||||
super(SimpleAlertUIEvent.ALERT);
|
||||
super(NotificationAlertEvent.ALERT);
|
||||
|
||||
this._message = message;
|
||||
this._messages = messages;
|
||||
this._alertType = alertType;
|
||||
this._clickUrl = clickUrl;
|
||||
this._clickUrlText = clickUrlText;
|
||||
this._title = title;
|
||||
this._imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public get message(): string
|
||||
public get messages(): string[]
|
||||
{
|
||||
return this._message;
|
||||
return this._messages;
|
||||
}
|
||||
|
||||
public get alertType(): string
|
||||
{
|
||||
return this._alertType;
|
||||
}
|
||||
|
||||
public get clickUrl(): string
|
@ -2,7 +2,7 @@ import { NitroEvent } from '@nitrots/nitro-renderer';
|
||||
|
||||
export class NotificationBubbleEvent extends NitroEvent
|
||||
{
|
||||
public static NEW_BUBBLE: string = 'NNBE_NEW_BUBBLE';
|
||||
public static NEW_BUBBLE: string = 'NBE_NEW_BUBBLE';
|
||||
|
||||
private _message: string;
|
||||
private _notificationType: string;
|
||||
|
@ -1,19 +0,0 @@
|
||||
import { NitroNotification } from '../../views/notification-center/common/Notification';
|
||||
import { NotificationCenterEvent } from './NotificationCenterEvent';
|
||||
|
||||
export class NotificationCenterAddNotificationEvent extends NotificationCenterEvent
|
||||
{
|
||||
private _notification: NitroNotification;
|
||||
|
||||
constructor(notification: NitroNotification)
|
||||
{
|
||||
super(NotificationCenterEvent.ADD_NOTIFICATION);
|
||||
|
||||
this._notification = notification;
|
||||
}
|
||||
|
||||
public get notification(): NitroNotification
|
||||
{
|
||||
return this._notification;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
export * from './NotificationCenterAddNotificationEvent';
|
||||
export * from './NotificationAlertEvent';
|
||||
export * from './NotificationBubbleEvent';
|
||||
export * from './NotificationCenterAlertEvent';
|
||||
export * from './NotificationCenterEvent';
|
||||
export * from './SimpleAlertUIEvent';
|
||||
|
@ -27,6 +27,7 @@
|
||||
@import './loading-habbos/LoadingHabbosView';
|
||||
@import './loading-spinner/LoadingSpinnerView';
|
||||
@import './mini-camera/NitroLayoutMiniCameraView';
|
||||
@import './notification-alert/NotificationAlertView';
|
||||
@import './notification-bubble/NotificationBubbleView';
|
||||
@import './trophy/NitroLayoutTrophyView';
|
||||
@import './gift-card/NitroLayoutGiftCardView';
|
||||
|
@ -3,6 +3,7 @@ export * from './draggable-window';
|
||||
export * from './gift-card';
|
||||
export * from './loading-spinner';
|
||||
export * from './mini-camera';
|
||||
export * from './notification-alert';
|
||||
export * from './notification-bubble';
|
||||
export * from './transitions';
|
||||
export * from './trophy';
|
||||
|
8
src/layout/notification-alert/NotificationAlertView.scss
Normal file
8
src/layout/notification-alert/NotificationAlertView.scss
Normal file
@ -0,0 +1,8 @@
|
||||
.nitro-alert {
|
||||
width: 350px;
|
||||
|
||||
.content-area {
|
||||
min-height: 125px;
|
||||
max-height: 300px;
|
||||
}
|
||||
}
|
17
src/layout/notification-alert/NotificationAlertView.tsx
Normal file
17
src/layout/notification-alert/NotificationAlertView.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import { FC } from 'react';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../card';
|
||||
import { NotificationAlertViewProps } from './NotificationAlertView.types';
|
||||
|
||||
export const NotificationAlertView: FC<NotificationAlertViewProps> = props =>
|
||||
{
|
||||
const { title = '', close = null, className = '', children = null, ...rest } = props;
|
||||
|
||||
return (
|
||||
<NitroCardView className={ 'nitro-alert ' + className } simple={ true } { ...rest }>
|
||||
<NitroCardHeaderView headerText={ title } onCloseClick={ close } />
|
||||
<NitroCardContentView className="d-flex flex-column justify-content-between text-black">
|
||||
{ children }
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
import { DetailsHTMLAttributes } from 'react';
|
||||
|
||||
export interface NotificationAlertViewProps extends DetailsHTMLAttributes<HTMLDivElement>
|
||||
{
|
||||
title: string;
|
||||
close: () => void;
|
||||
}
|
2
src/layout/notification-alert/index.ts
Normal file
2
src/layout/notification-alert/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './NotificationAlertView';
|
||||
export * from './NotificationAlertView.types';
|
27
src/views/help/HelpMessageHandler.tsx
Normal file
27
src/views/help/HelpMessageHandler.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import { CallForHelpResultMessageEvent, FurnitureListItemParser, PetData } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { LocalizeText } from '../../api';
|
||||
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
||||
import { NotificationAlertType } from '../notification-center/common/NotificationAlertType';
|
||||
import { NotificationUtilities } from '../notification-center/common/NotificationUtilities';
|
||||
import { GetCloseReasonKey } from './common/GetCloseReasonKey';
|
||||
let furniMsgFragments: Map<number, FurnitureListItemParser>[] = null;
|
||||
let petMsgFragments: Map<number, PetData>[] = null;
|
||||
|
||||
export const HelpMessageHandler: FC<{}> = props =>
|
||||
{
|
||||
const onCallForHelpResultMessageEvent = useCallback((event: CallForHelpResultMessageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
let message = parser.messageText;
|
||||
|
||||
if(!message || !message.length) message = LocalizeText('help.cfh.closed.' + GetCloseReasonKey(parser.resultType))
|
||||
|
||||
NotificationUtilities.simpleAlert(message, NotificationAlertType.MODERATION, null, null, LocalizeText('mod.alert.title'));
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(CallForHelpResultMessageEvent, onCallForHelpResultMessageEvent);
|
||||
|
||||
return null;
|
||||
}
|
11
src/views/help/HelpView.tsx
Normal file
11
src/views/help/HelpView.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import { FC } from 'react';
|
||||
import { HelpMessageHandler } from './HelpMessageHandler';
|
||||
|
||||
export const HelpView: FC<{}> = props =>
|
||||
{
|
||||
return (
|
||||
<>
|
||||
<HelpMessageHandler />
|
||||
</>
|
||||
);
|
||||
}
|
8
src/views/help/common/GetCloseReasonKey.ts
Normal file
8
src/views/help/common/GetCloseReasonKey.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export const GetCloseReasonKey = (code: number) =>
|
||||
{
|
||||
if(code === 1) return 'useless';
|
||||
|
||||
if(code === 2) return 'abusive';
|
||||
|
||||
return 'resolved';
|
||||
}
|
@ -9,6 +9,7 @@ import { CameraWidgetView } from '../camera/CameraWidgetView';
|
||||
import { CatalogView } from '../catalog/CatalogView';
|
||||
import { FriendsView } from '../friends/FriendsView';
|
||||
import { GroupsView } from '../groups/GroupsView';
|
||||
import { HelpView } from '../help/HelpView';
|
||||
import { HotelView } from '../hotel-view/HotelView';
|
||||
import { InventoryView } from '../inventory/InventoryView';
|
||||
import { ModToolsView } from '../mod-tools/ModToolsView';
|
||||
@ -69,6 +70,7 @@ export const MainView: FC<MainViewProps> = props =>
|
||||
<UserProfileView />
|
||||
<GroupsView />
|
||||
<CameraWidgetView />
|
||||
<HelpView />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,20 +1,14 @@
|
||||
import { AchievementNotificationMessageEvent, ActivityPointNotificationMessageEvent, ClubGiftNotificationEvent, HabboBroadcastMessageEvent, HotelClosesAndWillOpenAtEvent, HotelWillShutdownEvent, ModeratorMessageEvent, MOTDNotificationEvent, NotificationDialogMessageEvent, PetAddedToInventoryEvent, RespectReceivedEvent, RoomEnterEvent, Vector3d } from '@nitrots/nitro-renderer';
|
||||
import { AchievementNotificationMessageEvent, ActivityPointNotificationMessageEvent, ClubGiftNotificationEvent, ClubGiftSelectedEvent, HabboBroadcastMessageEvent, HotelClosedAndOpensEvent, HotelClosesAndWillOpenAtEvent, HotelWillCloseInMinutesEvent, InfoFeedEnableMessageEvent, MaintenanceStatusMessageEvent, ModeratorCautionEvent, ModeratorMessageEvent, MOTDNotificationEvent, NotificationDialogMessageEvent, PetLevelNotificationEvent, PetReceivedMessageEvent, RespectReceivedEvent, RoomEnterEvent, UserBannedMessageEvent, Vector3d } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { GetRoomEngine, GetSessionDataManager, LocalizeBadgeName, LocalizeText } from '../../api';
|
||||
import { NotificationCenterAlertEvent } from '../../events';
|
||||
import { dispatchUiEvent } from '../../hooks/events';
|
||||
import { GetConfiguration, GetRoomEngine, GetSessionDataManager, LocalizeBadgeName, LocalizeText } from '../../api';
|
||||
import { CreateMessageHook } from '../../hooks/messages';
|
||||
import { HotelWillShutdownNotification } from './common/HotelWillShutdownNotification';
|
||||
import { NotificationType } from './common/NotificationType';
|
||||
import { NotificationBubbleType } from './common/NotificationBubbleType';
|
||||
import { NotificationUtilities } from './common/NotificationUtilities';
|
||||
import { useNotificationCenterContext } from './context/NotificationCenterContext';
|
||||
import { ProductImageUtility } from './common/ProductImageUtility';
|
||||
import { INotificationCenterMessageHandlerProps } from './NotificationCenterMessageHandler.types';
|
||||
import { NotificationCenterActions } from './reducers/NotificationCenterReducer';
|
||||
|
||||
export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHandlerProps> = props =>
|
||||
{
|
||||
const { dispatchNotificationCenterState = null } = useNotificationCenterContext();
|
||||
|
||||
const onRespectReceivedEvent = useCallback((event: RespectReceivedEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
@ -24,8 +18,8 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
||||
const text1 = LocalizeText('notifications.text.respect.1');
|
||||
const text2 = LocalizeText('notifications.text.respect.2', [ 'count' ], [ parser.respectsReceived.toString() ]);
|
||||
|
||||
NotificationUtilities.showSingleBubble(text1, NotificationType.RESPECT);
|
||||
NotificationUtilities.showSingleBubble(text2, NotificationType.RESPECT);
|
||||
NotificationUtilities.showSingleBubble(text1, NotificationBubbleType.RESPECT);
|
||||
NotificationUtilities.showSingleBubble(text2, NotificationBubbleType.RESPECT);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(RespectReceivedEvent, onRespectReceivedEvent);
|
||||
@ -34,7 +28,7 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
NotificationUtilities.simpleAlert(parser.message.replace(/\\r/g, '\r'));
|
||||
NotificationUtilities.simpleAlert(parser.message.replace(/\\r/g, '\r'), null, null, LocalizeText('notifications.broadcast.title'));
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(HabboBroadcastMessageEvent, onHabboBroadcastMessageEvent);
|
||||
@ -48,7 +42,7 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
||||
const badgeImage = GetSessionDataManager().getBadgeUrl(parser.data.badgeCode);
|
||||
const internalLink = 'questengine/achievements/' + parser.data.category;
|
||||
|
||||
NotificationUtilities.showSingleBubble((text1 + ' ' + badgeName), NotificationType.ACHIEVEMENT, badgeImage, internalLink);
|
||||
NotificationUtilities.showSingleBubble((text1 + ' ' + badgeName), NotificationBubbleType.ACHIEVEMENT, badgeImage, internalLink);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(AchievementNotificationMessageEvent, onAchievementNotificationMessageEvent);
|
||||
@ -66,7 +60,7 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
dispatchUiEvent(new NotificationCenterAlertEvent(NotificationCenterAlertEvent.HOTEL_ALERT, [ parser.message ], parser.link));
|
||||
NotificationUtilities.handleModeratorMessage(parser.message, parser.link);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(ModeratorMessageEvent, onModeratorMessageEvent);
|
||||
@ -75,11 +69,31 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
// bubble for loyalty
|
||||
if(parser.amountChanged <= 0) return;
|
||||
|
||||
let imageUrl: string = null;
|
||||
|
||||
switch(parser.type)
|
||||
{
|
||||
case 5:
|
||||
imageUrl = GetConfiguration<string>('currency.asset.icon.url', '').replace('%type%', parser.type.toString());
|
||||
break;
|
||||
}
|
||||
|
||||
NotificationUtilities.showSingleBubble(LocalizeText('notifications.text.loyalty.received', [ 'amount' ], [ parser.amountChanged.toString() ]), NotificationBubbleType.INFO, imageUrl);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(ActivityPointNotificationMessageEvent, onActivityPointNotificationMessageEvent);
|
||||
|
||||
const onUserBannedMessageEvent = useCallback((event: UserBannedMessageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
NotificationUtilities.handleUserBannedMessage(parser.message);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(UserBannedMessageEvent, onUserBannedMessageEvent);
|
||||
|
||||
const onHotelClosesAndWillOpenAtEvent = useCallback((event: HotelClosesAndWillOpenAtEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
@ -89,7 +103,7 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
||||
|
||||
CreateMessageHook(HotelClosesAndWillOpenAtEvent, onHotelClosesAndWillOpenAtEvent);
|
||||
|
||||
const onPetAddedToInventoryEvent = useCallback((event: PetAddedToInventoryEvent) =>
|
||||
const onPetReceivedMessageEvent = useCallback((event: PetReceivedMessageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
@ -101,10 +115,10 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
||||
|
||||
if(imageResult) imageUrl = imageResult.getImage().src;
|
||||
|
||||
NotificationUtilities.showSingleBubble(text, NotificationType.PETLEVEL, imageUrl);
|
||||
NotificationUtilities.showSingleBubble(text, NotificationBubbleType.PETLEVEL, imageUrl);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(PetAddedToInventoryEvent, onPetAddedToInventoryEvent);
|
||||
CreateMessageHook(PetReceivedMessageEvent, onPetReceivedMessageEvent);
|
||||
|
||||
const onRoomEnterEvent = useCallback((event: RoomEnterEvent) =>
|
||||
{
|
||||
@ -119,24 +133,67 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
dispatchUiEvent(new NotificationCenterAlertEvent(NotificationCenterAlertEvent.HOTEL_ALERT, parser.messages));
|
||||
NotificationUtilities.handleMOTD(parser.messages);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(MOTDNotificationEvent, onMOTDNotificationEvent);
|
||||
|
||||
const onHotelWillShutdownEvent = useCallback((event: HotelWillShutdownEvent) =>
|
||||
const onPetLevelNotificationEvent = useCallback((event: PetLevelNotificationEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
dispatchNotificationCenterState({
|
||||
type: NotificationCenterActions.ADD_NOTIFICATION,
|
||||
payload: {
|
||||
notification: new HotelWillShutdownNotification(parser.minutes)
|
||||
}
|
||||
});
|
||||
}, [ dispatchNotificationCenterState ]);
|
||||
let imageUrl: string = null;
|
||||
|
||||
CreateMessageHook(HotelWillShutdownEvent, onHotelWillShutdownEvent);
|
||||
const imageResult = GetRoomEngine().getRoomObjectPetImage(parser.figureData.typeId, parser.figureData.paletteId, parseInt(parser.figureData.color, 16), new Vector3d(45 * 3), 64, null, true);
|
||||
|
||||
if(imageResult) imageUrl = imageResult.getImage().src;
|
||||
|
||||
NotificationUtilities.showSingleBubble(LocalizeText('notifications.text.petlevel', [ 'pet_name', 'level' ], [ parser.petName, parser.level.toString() ]), NotificationBubbleType.PETLEVEL, imageUrl);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(PetLevelNotificationEvent, onPetLevelNotificationEvent);
|
||||
|
||||
const onInfoFeedEnableMessageEvent = useCallback((event: InfoFeedEnableMessageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
NotificationUtilities.BUBBLES_DISABLED = !(parser.enabled);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(InfoFeedEnableMessageEvent, onInfoFeedEnableMessageEvent);
|
||||
|
||||
const onClubGiftSelectedEvent = useCallback((event: ClubGiftSelectedEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
if(!parser.products || !parser.products.length) return;
|
||||
|
||||
const productData = parser.products[0];
|
||||
|
||||
if(!productData) return;
|
||||
|
||||
NotificationUtilities.showSingleBubble(LocalizeText('notifications.text.club_gift.selected'), NotificationBubbleType.INFO, ProductImageUtility.getProductImageUrl(productData.productType, productData.furniClassId, productData.extraParam))
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(ClubGiftSelectedEvent, onClubGiftSelectedEvent);
|
||||
|
||||
const onMaintenanceStatusMessageEvent = useCallback((event: MaintenanceStatusMessageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
NotificationUtilities.handleHotelMaintenanceMessage(parser.minutesUntilMaintenance, parser.duration);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(MaintenanceStatusMessageEvent, onMaintenanceStatusMessageEvent);
|
||||
|
||||
const onModeratorCautionEvent = useCallback((event: ModeratorCautionEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
NotificationUtilities.handleModeratorCaution(parser.message, parser.url);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(ModeratorCautionEvent, onModeratorCautionEvent);
|
||||
|
||||
const onNotificationDialogMessageEvent = useCallback((event: NotificationDialogMessageEvent) =>
|
||||
{
|
||||
@ -147,5 +204,23 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
||||
|
||||
CreateMessageHook(NotificationDialogMessageEvent, onNotificationDialogMessageEvent);
|
||||
|
||||
const onHotelWillCloseInMinutesEvent = useCallback((event: HotelWillCloseInMinutesEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
NotificationUtilities.handleHotelClosingMessage(parser.openMinute);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(HotelWillCloseInMinutesEvent, onHotelWillCloseInMinutesEvent);
|
||||
|
||||
const onHotelClosedAndOpensEvent = useCallback((event: HotelClosedAndOpensEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
NotificationUtilities.handleLoginFailedHotelClosedMessage(parser.openHour, parser.openMinute);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(HotelClosedAndOpensEvent, onHotelClosedAndOpensEvent);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -1,12 +1,3 @@
|
||||
.nitro-alert {
|
||||
width: 350px;
|
||||
|
||||
.content-area {
|
||||
min-height: 125px;
|
||||
max-height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
.nitro-notification-center-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
@ -1,40 +1,42 @@
|
||||
import { FC, ReactNode, useCallback, useMemo, useState } from 'react';
|
||||
import { NotificationCenterAlertEvent } from '../../events';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { NotificationAlertEvent } from '../../events';
|
||||
import { NotificationBubbleEvent } from '../../events/notification-center/NotificationBubbleEvent';
|
||||
import { useUiEvent } from '../../hooks/events';
|
||||
import { NotificationItem } from './common/NotificationItem';
|
||||
import { NotificationType } from './common/NotificationType';
|
||||
import { NotificationAlertItem } from './common/NotificationAlertItem';
|
||||
import { NotificationBubbleItem } from './common/NotificationBubbleItem';
|
||||
import { NotificationBubbleType } from './common/NotificationBubbleType';
|
||||
import { NotificationCenterMessageHandler } from './NotificationCenterMessageHandler';
|
||||
import { NotificationCenterViewProps } from './NotificationCenterView.types';
|
||||
import { NotificationCenterBroadcastMessageView } from './views/broadcast-message/NotificationCenterBroadcastMessageView';
|
||||
import { GetAlertLayout } from './views/alert-layouts/GetAlertLayout';
|
||||
import { GetBubbleLayout } from './views/bubble-layouts/GetBubbleLayout';
|
||||
|
||||
export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
||||
{
|
||||
const [ alerts, setAlerts ] = useState<NotificationCenterAlertEvent[]>([]);
|
||||
const [ bubbleAlerts, setBubbleAlerts ] = useState<NotificationItem[]>([]);
|
||||
const [ alerts, setAlerts ] = useState<NotificationAlertItem[]>([]);
|
||||
const [ bubbleAlerts, setBubbleAlerts ] = useState<NotificationBubbleItem[]>([]);
|
||||
|
||||
const onNotificationCenterAlertEvent = useCallback((event: NotificationCenterAlertEvent) =>
|
||||
const onNotificationAlertEvent = useCallback((event: NotificationAlertEvent) =>
|
||||
{
|
||||
setAlerts(prevValue =>
|
||||
{
|
||||
return [ ...prevValue, event ];
|
||||
});
|
||||
console.log(event);
|
||||
const alertItem = new NotificationAlertItem(event.messages, event.alertType, event.clickUrl, event.clickUrlText, event.title, event.imageUrl);
|
||||
|
||||
setAlerts(prevValue => [ alertItem, ...prevValue ]);
|
||||
}, []);
|
||||
|
||||
useUiEvent(NotificationCenterAlertEvent.HOTEL_ALERT, onNotificationCenterAlertEvent);
|
||||
useUiEvent(NotificationAlertEvent.ALERT, onNotificationAlertEvent);
|
||||
|
||||
const onNotificationBubbleEvent = useCallback((event: NotificationBubbleEvent) =>
|
||||
{
|
||||
console.log(event);
|
||||
const notificationItem = new NotificationItem(event.message, event.notificationType, event.imageUrl, event.linkUrl);
|
||||
const notificationItem = new NotificationBubbleItem(event.message, event.notificationType, event.imageUrl, event.linkUrl);
|
||||
|
||||
setBubbleAlerts(prevValue => [ notificationItem, ...prevValue ]);
|
||||
}, []);
|
||||
|
||||
useUiEvent(NotificationBubbleEvent.NEW_BUBBLE, onNotificationBubbleEvent);
|
||||
|
||||
const closeAlert = useCallback((alert: NotificationCenterAlertEvent) =>
|
||||
const closeAlert = useCallback((alert: NotificationAlertItem) =>
|
||||
{
|
||||
setAlerts(prevValue =>
|
||||
{
|
||||
@ -47,7 +49,7 @@ export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
||||
});
|
||||
}, []);
|
||||
|
||||
const closeBubbleAlert = useCallback((item: NotificationItem) =>
|
||||
const closeBubbleAlert = useCallback((item: NotificationBubbleItem) =>
|
||||
{
|
||||
setBubbleAlerts(prevValue =>
|
||||
{
|
||||
@ -60,6 +62,22 @@ export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
||||
})
|
||||
}, []);
|
||||
|
||||
const getAlerts = useMemo(() =>
|
||||
{
|
||||
if(!alerts || !alerts.length) return null;
|
||||
|
||||
const elements: ReactNode[] = [];
|
||||
|
||||
for(const alert of alerts)
|
||||
{
|
||||
const element = GetAlertLayout(alert, () => closeAlert(alert));
|
||||
|
||||
elements.push(element);
|
||||
}
|
||||
|
||||
return elements;
|
||||
}, [ alerts, closeAlert ]);
|
||||
|
||||
const getBubbleAlerts = useMemo(() =>
|
||||
{
|
||||
if(!bubbleAlerts || !bubbleAlerts.length) return null;
|
||||
@ -70,7 +88,7 @@ export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
||||
{
|
||||
const element = GetBubbleLayout(alert, () => closeBubbleAlert(alert));
|
||||
|
||||
if(alert.notificationType === NotificationType.CLUBGIFT)
|
||||
if(alert.notificationType === NotificationBubbleType.CLUBGIFT)
|
||||
{
|
||||
elements.unshift(element);
|
||||
|
||||
@ -89,15 +107,7 @@ export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
||||
<div className="nitro-notification-center">
|
||||
{ getBubbleAlerts }
|
||||
</div>
|
||||
{ (alerts.length > 0) && alerts.map((alert, index) =>
|
||||
{
|
||||
switch(alert.type)
|
||||
{
|
||||
case NotificationCenterAlertEvent.HOTEL_ALERT:
|
||||
default:
|
||||
return <NotificationCenterBroadcastMessageView key={ index } notification={ alert } onClose={ () => closeAlert(alert) } />;
|
||||
}
|
||||
})}
|
||||
{ createPortal(getAlerts, document.getElementById('nitro-alerts-container')) }
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
import { NitroNotification } from './Notification';
|
||||
|
||||
export class BroadcastMessageNotification extends NitroNotification
|
||||
{}
|
@ -1,24 +0,0 @@
|
||||
import { NitroNotification } from './Notification';
|
||||
|
||||
export class DialogMessageNotification extends NitroNotification
|
||||
{
|
||||
private _type: string;
|
||||
private _parameters: Map<string, string>;
|
||||
|
||||
constructor(type: string, parameters: Map<string, string>)
|
||||
{
|
||||
super();
|
||||
this._type = type;
|
||||
this._parameters = parameters;
|
||||
}
|
||||
|
||||
public get type(): string
|
||||
{
|
||||
return this._type;
|
||||
}
|
||||
|
||||
public get parameters(): Map<string, string>
|
||||
{
|
||||
return this._parameters;
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import { NitroNotification } from './Notification';
|
||||
|
||||
export class HotelWillShutdownNotification extends NitroNotification
|
||||
{
|
||||
private _minutes: number;
|
||||
|
||||
constructor(minutes: number)
|
||||
{
|
||||
super();
|
||||
this._minutes = minutes;
|
||||
}
|
||||
|
||||
public get minutes(): number
|
||||
{
|
||||
return this._minutes;
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import { NitroNotification } from './Notification';
|
||||
|
||||
export class MOTDNotification extends NitroNotification
|
||||
{
|
||||
private _messages: string[];
|
||||
|
||||
constructor(messages: string[])
|
||||
{
|
||||
super();
|
||||
this._messages = [];
|
||||
|
||||
for(const message of messages) this._messages.push(message.replace(/\r\n|\r|\n/g, '<br />'));
|
||||
}
|
||||
|
||||
public get messages(): string[]
|
||||
{
|
||||
return this._messages;
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import { NitroNotification } from './Notification';
|
||||
|
||||
export class ModeratorMessageNotification extends NitroNotification
|
||||
{
|
||||
private _link: string;
|
||||
|
||||
constructor(message: string, link: string)
|
||||
{
|
||||
super(message);
|
||||
this._link = link;
|
||||
}
|
||||
|
||||
public get link(): string
|
||||
{
|
||||
return this._link;
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
export class NitroNotification
|
||||
{
|
||||
public static CURRENT_ID: number = 0;
|
||||
|
||||
private _id: number;
|
||||
private _title: string;
|
||||
private _message: string;
|
||||
private _dismissed: boolean = false;
|
||||
private _timestamp: number;
|
||||
|
||||
constructor(message: string = null, title: string = null)
|
||||
{
|
||||
this._id = ++NitroNotification.CURRENT_ID;
|
||||
this._title = title;
|
||||
this._timestamp = Date.now();
|
||||
|
||||
if(message) this._message = message.replace(/\r\n|\r|\n/g, '<br />');
|
||||
}
|
||||
|
||||
public dismiss(): void
|
||||
{
|
||||
this._dismissed = true;
|
||||
}
|
||||
|
||||
public get id(): number
|
||||
{
|
||||
return this._id;
|
||||
}
|
||||
|
||||
public get title(): string
|
||||
{
|
||||
return this._title;
|
||||
}
|
||||
|
||||
public get message(): string
|
||||
{
|
||||
return this._message;
|
||||
}
|
||||
|
||||
public get dismissed(): boolean
|
||||
{
|
||||
return this._dismissed;
|
||||
}
|
||||
|
||||
public get timestamp(): number
|
||||
{
|
||||
return this._timestamp;
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
import { NotificationBubbleType } from './NotificationBubbleType';
|
||||
|
||||
export class NotificationAlertItem
|
||||
{
|
||||
private static ITEM_ID: number = -1;
|
||||
|
||||
private _id: number;
|
||||
private _messages: string[];
|
||||
private _alertType: string;
|
||||
private _clickUrl: string;
|
||||
private _clickUrlText: string;
|
||||
private _title: string;
|
||||
private _imageUrl: string;
|
||||
|
||||
constructor(messages: string[], alertType: string = NotificationBubbleType.INFO, clickUrl: string = null, clickUrlText: string = null, title: string = null, imageUrl: string = null)
|
||||
{
|
||||
NotificationAlertItem.ITEM_ID += 1;
|
||||
|
||||
this._id = NotificationAlertItem.ITEM_ID;
|
||||
this._messages = messages;
|
||||
this._alertType = alertType;
|
||||
this._clickUrl = clickUrl;
|
||||
this._clickUrlText = clickUrlText;
|
||||
this._title = title;
|
||||
this._imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public get id(): number
|
||||
{
|
||||
return this._id;
|
||||
}
|
||||
|
||||
public get messages(): string[]
|
||||
{
|
||||
return this._messages;
|
||||
}
|
||||
|
||||
public get alertType(): string
|
||||
{
|
||||
return this._alertType;
|
||||
}
|
||||
|
||||
public get clickUrl(): string
|
||||
{
|
||||
return this._clickUrl;
|
||||
}
|
||||
|
||||
public get clickUrlText(): string
|
||||
{
|
||||
return this._clickUrlText;
|
||||
}
|
||||
|
||||
public get title(): string
|
||||
{
|
||||
return this._title;
|
||||
}
|
||||
|
||||
public get imageUrl(): string
|
||||
{
|
||||
return this._imageUrl;
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
export class NotificationAlertType
|
||||
{
|
||||
public static DEFAULT: string = 'default';
|
||||
public static MOTD: string = 'motd';
|
||||
public static MODERATION: string = 'moderation';
|
||||
public static EVENT: string = 'event';
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { NotificationType } from './NotificationType';
|
||||
import { NotificationBubbleType } from './NotificationBubbleType';
|
||||
|
||||
export class NotificationItem
|
||||
export class NotificationBubbleItem
|
||||
{
|
||||
private static ITEM_ID: number = -1;
|
||||
|
||||
@ -10,11 +10,11 @@ export class NotificationItem
|
||||
private _iconUrl: string;
|
||||
private _linkUrl: string;
|
||||
|
||||
constructor(message: string, notificationType: string = NotificationType.INFO, iconUrl: string = null, linkUrl: string = null)
|
||||
constructor(message: string, notificationType: string = NotificationBubbleType.INFO, iconUrl: string = null, linkUrl: string = null)
|
||||
{
|
||||
NotificationItem.ITEM_ID += 1;
|
||||
NotificationBubbleItem.ITEM_ID += 1;
|
||||
|
||||
this._id = NotificationItem.ITEM_ID;
|
||||
this._id = NotificationBubbleItem.ITEM_ID;
|
||||
this._message = message;
|
||||
this._notificationType = notificationType;
|
||||
this._iconUrl = iconUrl;
|
@ -1,4 +1,4 @@
|
||||
export class NotificationType
|
||||
export class NotificationBubbleType
|
||||
{
|
||||
public static FRIENDOFFLINE: string = 'friendoffline';
|
||||
public static FRIENDONLINE: string = 'friendonline';
|
@ -1,10 +1,11 @@
|
||||
import { HabboWebTools, RoomEnterEffect } from '@nitrots/nitro-renderer';
|
||||
import { CreateLinkEvent, GetConfiguration, GetNitroInstance, LocalizeText } from '../../../api';
|
||||
import { SimpleAlertUIEvent } from '../../../events';
|
||||
import { NotificationAlertEvent } from '../../../events';
|
||||
import { NotificationBubbleEvent } from '../../../events/notification-center/NotificationBubbleEvent';
|
||||
import { dispatchUiEvent } from '../../../hooks';
|
||||
import { CatalogPageName } from '../../catalog/common/CatalogPageName';
|
||||
import { NotificationType } from './NotificationType';
|
||||
import { NotificationAlertType } from './NotificationAlertType';
|
||||
import { NotificationBubbleType } from './NotificationBubbleType';
|
||||
|
||||
export class NotificationUtilities
|
||||
{
|
||||
@ -12,6 +13,8 @@ export class NotificationUtilities
|
||||
private static MODERATION_DISCLAIMER_DELAY_MS: number = 5000;
|
||||
private static MODERATION_DISCLAIMER_TIMEOUT: ReturnType<typeof setTimeout> = null;
|
||||
|
||||
public static BUBBLES_DISABLED: boolean = false;
|
||||
|
||||
private static cleanText(text: string): string
|
||||
{
|
||||
return text.replace(/\\r/g, '\r')
|
||||
@ -68,62 +71,92 @@ export class NotificationUtilities
|
||||
|
||||
const configuration = this.getNotificationConfig(('notification.' + type));
|
||||
|
||||
if(configuration)
|
||||
{
|
||||
for(const key in configuration) options.set(key, configuration[key]);
|
||||
}
|
||||
if(configuration) for(const key in configuration) options.set(key, configuration[key]);
|
||||
|
||||
console.log(options);
|
||||
|
||||
const title = this.getNotificationPart(options, type, 'title', true);
|
||||
const message = this.getNotificationPart(options, type, 'message', true).replace(/\\r/g, '\r');
|
||||
const linkTitle = this.getNotificationPart(options, type, 'linkTitle', false);
|
||||
const linkUrl = this.getNotificationPart(options, type, 'linkUrl', false);
|
||||
const image = this.getNotificationImageUrl(options, type);
|
||||
|
||||
if(options.get('display') === 'BUBBLE')
|
||||
{
|
||||
const message = this.getNotificationPart(options, type, 'message', true);
|
||||
const linkUrl = this.getNotificationPart(options, type, 'linkUrl', false);
|
||||
const isEventLink = (linkUrl && linkUrl.substr(0, 6) === 'event');
|
||||
const image = this.getNotificationImageUrl(options, type);
|
||||
|
||||
dispatchUiEvent(new NotificationBubbleEvent(LocalizeText(message), NotificationType.INFO, LocalizeText(image), (isEventLink ? linkUrl.substr(6) : linkUrl)));
|
||||
this.showSingleBubble(LocalizeText(message), NotificationBubbleType.INFO, LocalizeText(image), linkUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
this.simpleAlert(message, NotificationAlertType.EVENT, linkUrl, linkTitle, title, image);
|
||||
}
|
||||
}
|
||||
|
||||
public static showSingleBubble(message: string, type: string, imageUrl: string = null, internalLink: string = null): void
|
||||
{
|
||||
if(this.BUBBLES_DISABLED) return;
|
||||
|
||||
dispatchUiEvent(new NotificationBubbleEvent(message, type, imageUrl, internalLink));
|
||||
}
|
||||
|
||||
public static simpleAlert(message: string, clickUrl: string = null, clickUrlText: string = null, title: string = null, imageUrl: string = null): void
|
||||
{
|
||||
if(!title || !title.length) title = LocalizeText('notifications.broadcast.title');
|
||||
|
||||
dispatchUiEvent(new SimpleAlertUIEvent(message, clickUrl, clickUrlText, title, imageUrl));
|
||||
}
|
||||
|
||||
public static alert(title: string, message: string): void
|
||||
{
|
||||
dispatchUiEvent(new SimpleAlertUIEvent(message, null, null, title, null));
|
||||
}
|
||||
|
||||
public static showClubGiftNotification(numGifts: number): void
|
||||
{
|
||||
if(numGifts <= 0) return;
|
||||
|
||||
dispatchUiEvent(new NotificationBubbleEvent(numGifts.toString(), NotificationType.CLUBGIFT, null, 'catalog/open/' + CatalogPageName.CLUB_GIFTS));
|
||||
this.showSingleBubble(numGifts.toString(), NotificationBubbleType.CLUBGIFT, null, ('catalog/open/' + CatalogPageName.CLUB_GIFTS));
|
||||
}
|
||||
|
||||
public static showModeratorMessage(message: string, url: string = null): void
|
||||
public static handleMOTD(messages: string[]): void
|
||||
{
|
||||
this.simpleAlert(this.cleanText(message), url, LocalizeText('mod.alert.link'), LocalizeText('mod.alert.title'));
|
||||
messages = messages.map(message => this.cleanText(message));
|
||||
|
||||
dispatchUiEvent(new NotificationAlertEvent(messages, NotificationAlertType.MOTD, null, null, LocalizeText('notifications.motd.title')));
|
||||
}
|
||||
|
||||
public static simpleAlert(message: string, type: string, clickUrl: string = null, clickUrlText: string = null, title: string = null, imageUrl: string = null): void
|
||||
{
|
||||
if(!title || !title.length) title = LocalizeText('notifications.broadcast.title');
|
||||
|
||||
dispatchUiEvent(new NotificationAlertEvent([ this.cleanText(message) ], type, clickUrl, clickUrlText, title, imageUrl));
|
||||
}
|
||||
|
||||
public static showModeratorMessage(message: string, url: string = null, showHabboWay: boolean = true): void
|
||||
{
|
||||
this.simpleAlert(message, NotificationAlertType.MODERATION, url, LocalizeText('mod.alert.link'), LocalizeText('mod.alert.title'));
|
||||
}
|
||||
|
||||
public static handleModeratorCaution(message: string, url: string = null): void
|
||||
{
|
||||
this.showModeratorMessage(message, url);
|
||||
}
|
||||
|
||||
public static handleModeratorMessage(message: string, url: string = null): void
|
||||
{
|
||||
this.showModeratorMessage(message, url, false);
|
||||
}
|
||||
|
||||
public static handleUserBannedMessage(message: string): void
|
||||
{
|
||||
this.showModeratorMessage(message);
|
||||
}
|
||||
|
||||
public static handleHotelClosedMessage(open: number, minute: number, thrownOut: boolean): void
|
||||
{
|
||||
const text: string = LocalizeText(('opening.hours.' + (thrownOut ? 'disconnected' : 'closed')), [ 'h', 'm'], [ this.getTimeZeroPadded(open), this.getTimeZeroPadded(minute) ]);;
|
||||
this.simpleAlert( LocalizeText(('opening.hours.' + (thrownOut ? 'disconnected' : 'closed')), [ 'h', 'm'], [ this.getTimeZeroPadded(open), this.getTimeZeroPadded(minute) ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title'));
|
||||
}
|
||||
|
||||
this.alert(LocalizeText('opening.hours.title'), text);
|
||||
public static handleHotelMaintenanceMessage(minutesUntilMaintenance: number, duration: number): void
|
||||
{
|
||||
this.simpleAlert(LocalizeText('maintenance.shutdown', [ 'm', 'd' ], [ minutesUntilMaintenance.toString(), duration.toString() ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title'));
|
||||
}
|
||||
|
||||
public static handleHotelClosingMessage(minutes: number): void
|
||||
{
|
||||
this.simpleAlert(LocalizeText('opening.hours.shutdown', [ 'm' ], [ minutes.toString() ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title'));
|
||||
}
|
||||
|
||||
public static handleLoginFailedHotelClosedMessage(openHour: number, openMinutes: number): void
|
||||
{
|
||||
this.simpleAlert(LocalizeText('opening.hours.disconnected', [ 'h', 'm' ], [ openHour.toString(), openMinutes.toString() ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title'));
|
||||
}
|
||||
|
||||
public static openUrl(url: string): void
|
||||
@ -134,7 +167,7 @@ export class NotificationUtilities
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateLinkEvent(url);
|
||||
CreateLinkEvent(url.substring(6));
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +186,7 @@ export class NotificationUtilities
|
||||
{
|
||||
if(this.MODERATION_DISCLAIMER_SHOWN) return;
|
||||
|
||||
this.showSingleBubble(LocalizeText('mod.chatdisclaimer'), NotificationType.INFO);
|
||||
this.showSingleBubble(LocalizeText('mod.chatdisclaimer'), NotificationBubbleType.INFO);
|
||||
|
||||
this.MODERATION_DISCLAIMER_SHOWN = true;
|
||||
}
|
||||
|
59
src/views/notification-center/common/ProductImageUtility.ts
Normal file
59
src/views/notification-center/common/ProductImageUtility.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import { CatalogPageMessageProductData } from '@nitrots/nitro-renderer';
|
||||
import { GetRoomEngine } from '../../../api';
|
||||
import { FurniCategory } from '../../catalog/common/FurniCategory';
|
||||
|
||||
export class ProductImageUtility
|
||||
{
|
||||
public static getProductImageUrl(productType: string, furniClassId: number, extraParam: string): string
|
||||
{
|
||||
let imageUrl: string = null;
|
||||
|
||||
switch(productType)
|
||||
{
|
||||
case CatalogPageMessageProductData.S:
|
||||
imageUrl = GetRoomEngine().getFurnitureFloorIconUrl(furniClassId);
|
||||
break;
|
||||
case CatalogPageMessageProductData.I:
|
||||
const productCategory = this.getProductCategory(CatalogPageMessageProductData.I, furniClassId);
|
||||
|
||||
if(productCategory === 1)
|
||||
{
|
||||
imageUrl = GetRoomEngine().getFurnitureWallIconUrl(furniClassId, extraParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(productCategory)
|
||||
{
|
||||
case FurniCategory.WALL_PAPER:
|
||||
break;
|
||||
case FurniCategory.LANDSCAPE:
|
||||
break;
|
||||
case FurniCategory.FLOOR:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CatalogPageMessageProductData.E:
|
||||
// fx_icon_furniClassId_png
|
||||
break;
|
||||
}
|
||||
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
private static getProductCategory(productType: string, furniClassId: number): number
|
||||
{
|
||||
if(productType === CatalogPageMessageProductData.S) return 1;
|
||||
|
||||
if(productType === CatalogPageMessageProductData.I)
|
||||
{
|
||||
if(furniClassId === 3001) return FurniCategory.WALL_PAPER;
|
||||
|
||||
if(furniClassId === 3002) return FurniCategory.FLOOR;
|
||||
|
||||
if(furniClassId === 4057) return FurniCategory.LANDSCAPE;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
import { createContext, FC, useContext } from 'react';
|
||||
import { INotificationCenterContext, NotificationCenterContextProps } from './NotificationCenterContext.types';
|
||||
|
||||
const NotificationCenterContext = createContext<INotificationCenterContext>({
|
||||
notificationCenterState: null,
|
||||
dispatchNotificationCenterState: null
|
||||
});
|
||||
|
||||
export const NotificationCenterContextProvider: FC<NotificationCenterContextProps> = props =>
|
||||
{
|
||||
return <NotificationCenterContext.Provider value={ props.value }>{ props.children }</NotificationCenterContext.Provider>
|
||||
}
|
||||
|
||||
export const useNotificationCenterContext = () => useContext(NotificationCenterContext);
|
@ -1,13 +0,0 @@
|
||||
import { Dispatch, ProviderProps } from 'react';
|
||||
import { INotificationCenterAction, INotificationCenterState } from '../reducers/NotificationCenterReducer';
|
||||
|
||||
export interface INotificationCenterContext
|
||||
{
|
||||
notificationCenterState: INotificationCenterState;
|
||||
dispatchNotificationCenterState: Dispatch<INotificationCenterAction>;
|
||||
}
|
||||
|
||||
export interface NotificationCenterContextProps extends ProviderProps<INotificationCenterContext>
|
||||
{
|
||||
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
import { Reducer } from 'react';
|
||||
import { NitroNotification } from '../common/Notification';
|
||||
|
||||
export interface INotificationCenterState
|
||||
{
|
||||
notifications: NitroNotification[];
|
||||
}
|
||||
|
||||
export interface INotificationCenterAction
|
||||
{
|
||||
type: string;
|
||||
payload: {
|
||||
id?: number;
|
||||
notification?: NitroNotification;
|
||||
};
|
||||
}
|
||||
|
||||
export class NotificationCenterActions
|
||||
{
|
||||
public static ADD_NOTIFICATION: string = 'NCA_ADD_NOTIFICATION';
|
||||
public static REMOVE_NOTIFICATION: string = 'NCA_REMOVE_NOTIFICATION';
|
||||
public static DISMISS_NOTIFICATION: string = 'NCA_DISMISS_NOTIFICATION';
|
||||
}
|
||||
|
||||
export const initialNotificationCenter: INotificationCenterState = {
|
||||
notifications: []
|
||||
}
|
||||
|
||||
export const NotificationCenterReducer: Reducer<INotificationCenterState, INotificationCenterAction> = (state, action) =>
|
||||
{
|
||||
switch(action.type)
|
||||
{
|
||||
case NotificationCenterActions.ADD_NOTIFICATION: {
|
||||
const notification = (action.payload.notification || null);
|
||||
|
||||
if(!notification) return state;
|
||||
|
||||
const notifications = [ ...state.notifications, notification ];
|
||||
|
||||
return { ...state, notifications };
|
||||
}
|
||||
case NotificationCenterActions.REMOVE_NOTIFICATION: {
|
||||
const id = (action.payload.id || null);
|
||||
|
||||
if(!id) return state;
|
||||
|
||||
if(!state.notifications) return state;
|
||||
|
||||
const notifications = Array.from(state.notifications);
|
||||
const notificationIndex = notifications.findIndex(notification => notification.id === id);
|
||||
|
||||
if(notificationIndex === -1) return state;
|
||||
|
||||
notifications.splice(notificationIndex, 1);
|
||||
|
||||
return { ...state, notifications };
|
||||
}
|
||||
case NotificationCenterActions.DISMISS_NOTIFICATION: {
|
||||
const id = (action.payload.id || null);
|
||||
|
||||
if(!id) return state;
|
||||
|
||||
if(!state.notifications) return state;
|
||||
|
||||
const notifications = Array.from(state.notifications);
|
||||
const notificationIndex = notifications.findIndex(notification => notification.id === id);
|
||||
|
||||
if(notificationIndex === -1) return state;
|
||||
|
||||
notifications[notificationIndex].dismiss();
|
||||
|
||||
return { ...state, notifications };
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import { FC } from 'react';
|
||||
import { LocalizeText } from '../../../../api';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||
import { NotificationCenterAlertBaseProps } from './NotificationCenterAlertBase.types';
|
||||
|
||||
|
||||
export const NotificationCenterAlertBase: FC<NotificationCenterAlertBaseProps> = props =>
|
||||
{
|
||||
const { headerText = LocalizeText('mod.alert.title'), onClose = null, children = null } = props;
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-alert" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ headerText } onCloseClick={ onClose } />
|
||||
<NitroCardContentView className="d-flex flex-column justify-content-between text-black">
|
||||
{ children }
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
export interface NotificationCenterAlertBaseProps
|
||||
{
|
||||
headerText?: string;
|
||||
onClose: () => void;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
import { NotificationAlertItem } from '../../common/NotificationAlertItem';
|
||||
import { NotificationAlertType } from '../../common/NotificationAlertType';
|
||||
import { NotificationDefaultAlertView } from './default/NotificationDefaultAlertView';
|
||||
import { NotificationEventAlertView } from './event/NotificationEventAlertView';
|
||||
|
||||
export const GetAlertLayout = (item: NotificationAlertItem, close: () => void) =>
|
||||
{
|
||||
if(!item) return null;
|
||||
|
||||
const props = { key: item.id, item, close };
|
||||
|
||||
switch(item.alertType)
|
||||
{
|
||||
case NotificationAlertType.EVENT:
|
||||
return <NotificationEventAlertView { ...props } />
|
||||
default:
|
||||
return <NotificationDefaultAlertView { ...props } />
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
import { NotificationAlertItem } from '../../common/NotificationAlertItem';
|
||||
|
||||
export interface NotificationAlertLayoutViewProps
|
||||
{
|
||||
item: NotificationAlertItem;
|
||||
close: () => void;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
import { FC, useCallback } from 'react';
|
||||
import { LocalizeText } from '../../../../../api';
|
||||
import { NotificationAlertView } from '../../../../../layout';
|
||||
import { NotificationUtilities } from '../../../common/NotificationUtilities';
|
||||
import { NotificationDefaultAlertViewProps } from './NotificationDefaultAlertView.types';
|
||||
|
||||
export const NotificationDefaultAlertView: FC<NotificationDefaultAlertViewProps> = props =>
|
||||
{
|
||||
const { item = null, close = null, ...rest } = props;
|
||||
|
||||
const visitUrl = useCallback(() =>
|
||||
{
|
||||
NotificationUtilities.openUrl(item.clickUrl);
|
||||
|
||||
close();
|
||||
}, [ item, close ]);
|
||||
|
||||
return (
|
||||
<NotificationAlertView title={ item.title } close={ close } { ...rest }>
|
||||
{ (item.messages.length > 0) && item.messages.map((message, index) =>
|
||||
{
|
||||
const htmlText = message.replace(/\r\n|\r|\n/g, '<br />');
|
||||
|
||||
return (
|
||||
<div key={ index } dangerouslySetInnerHTML={ { __html: htmlText } } />
|
||||
);
|
||||
}) }
|
||||
<div className="d-flex justify-content-center align-items-center mt-1">
|
||||
<button type="button" className="btn btn-primary" onClick={ close }>{ LocalizeText('generic.close') }</button>
|
||||
</div>
|
||||
{ item.clickUrl && item.clickUrl.length &&
|
||||
<button type="button" className="btn btn-link" onClick={ visitUrl }>{ LocalizeText(item.clickUrlText) }</button> }
|
||||
</NotificationAlertView>
|
||||
);
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
import { DetailsHTMLAttributes } from 'react';
|
||||
import { NotificationAlertLayoutViewProps } from '../NotificationAlertLayoutView.types';
|
||||
|
||||
export interface NotificationDefaultAlertViewProps extends NotificationAlertLayoutViewProps, DetailsHTMLAttributes<HTMLDivElement>
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
import { FC, useCallback } from 'react';
|
||||
import { LocalizeText } from '../../../../../api';
|
||||
import { NotificationAlertView } from '../../../../../layout';
|
||||
import { NotificationUtilities } from '../../../common/NotificationUtilities';
|
||||
import { NotificationEventAlertViewProps } from './NotificationEventAlertView.types';
|
||||
|
||||
export const NotificationEventAlertView: FC<NotificationEventAlertViewProps> = props =>
|
||||
{
|
||||
const { item = null, close = null, ...rest } = props;
|
||||
|
||||
const visitUrl = useCallback(() =>
|
||||
{
|
||||
NotificationUtilities.openUrl(item.clickUrl);
|
||||
|
||||
close();
|
||||
}, [ item, close ]);
|
||||
|
||||
return (
|
||||
<NotificationAlertView title={ item.title } close={ close } { ...rest }>
|
||||
{ (item.messages.length > 0) && item.messages.map((message, index) =>
|
||||
{
|
||||
const htmlText = message.replace(/\r\n|\r|\n/g, '<br />');
|
||||
|
||||
return (
|
||||
<div key={ index } dangerouslySetInnerHTML={ { __html: htmlText } } />
|
||||
);
|
||||
}) }
|
||||
<div className="d-flex justify-content-center align-items-center mt-1">
|
||||
<button type="button" className="btn btn-primary" onClick={ visitUrl }>{ LocalizeText(item.clickUrlText) }</button>
|
||||
</div>
|
||||
</NotificationAlertView>
|
||||
);
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
import { DetailsHTMLAttributes } from 'react';
|
||||
import { NotificationAlertLayoutViewProps } from '../NotificationAlertLayoutView.types';
|
||||
|
||||
export interface NotificationEventAlertViewProps extends NotificationAlertLayoutViewProps, DetailsHTMLAttributes<HTMLDivElement>
|
||||
{
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
import { FC, useMemo } from 'react';
|
||||
import { LocalizeText } from '../../../../api';
|
||||
import { NotificationCenterAlertBase } from '../alert-base/NotificationCenterAlertBase';
|
||||
import { NotificationCenterBroadcastMessageViewProps } from './NotificationCenterBroadcastMessageView.types';
|
||||
|
||||
export const NotificationCenterBroadcastMessageView: FC<NotificationCenterBroadcastMessageViewProps> = props =>
|
||||
{
|
||||
const { notification = null, onClose = null } = props;
|
||||
|
||||
const message = useMemo(() =>
|
||||
{
|
||||
let finalMessage = '';
|
||||
|
||||
notification.message.forEach(message =>
|
||||
{
|
||||
finalMessage += message.replace(/\r\n|\r|\n/g, '<br />');
|
||||
});
|
||||
|
||||
return finalMessage;
|
||||
}, [ notification ]);
|
||||
|
||||
return (
|
||||
<NotificationCenterAlertBase onClose={ onClose }>
|
||||
<div dangerouslySetInnerHTML={ { __html: message } } />
|
||||
<div className="d-flex justify-content-center align-items-center">
|
||||
<button type="button" className="btn btn-primary" onClick={ onClose }>{ LocalizeText('generic.close') }</button>
|
||||
</div>
|
||||
</NotificationCenterAlertBase>
|
||||
);
|
||||
};
|
@ -1,7 +0,0 @@
|
||||
import { NotificationCenterAlertEvent } from '../../../../events';
|
||||
|
||||
export class NotificationCenterBroadcastMessageViewProps
|
||||
{
|
||||
notification: NotificationCenterAlertEvent;
|
||||
onClose: () => void;
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
import { NotificationItem } from '../../common/NotificationItem';
|
||||
import { NotificationType } from '../../common/NotificationType';
|
||||
import { NotificationBubbleItem } from '../../common/NotificationBubbleItem';
|
||||
import { NotificationBubbleType } from '../../common/NotificationBubbleType';
|
||||
import { NotificationClubGiftBubbleView } from './club-gift/NotificationClubGiftBubbleView';
|
||||
import { NotificationDefaultBubbleView } from './default/NotificationDefaultBubbleView';
|
||||
|
||||
export const GetBubbleLayout = (item: NotificationItem, close: () => void) =>
|
||||
export const GetBubbleLayout = (item: NotificationBubbleItem, close: () => void) =>
|
||||
{
|
||||
if(!item) return null;
|
||||
|
||||
@ -11,7 +11,7 @@ export const GetBubbleLayout = (item: NotificationItem, close: () => void) =>
|
||||
|
||||
switch(item.notificationType)
|
||||
{
|
||||
case NotificationType.CLUBGIFT:
|
||||
case NotificationBubbleType.CLUBGIFT:
|
||||
return <NotificationClubGiftBubbleView { ...props } />
|
||||
default:
|
||||
return <NotificationDefaultBubbleView { ...props } />
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { NotificationItem } from '../../common/NotificationItem';
|
||||
import { NotificationBubbleItem } from '../../common/NotificationBubbleItem';
|
||||
|
||||
export interface NotificationBubbleLayoutViewProps
|
||||
{
|
||||
item: NotificationItem;
|
||||
item: NotificationBubbleItem;
|
||||
close: () => void;
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
import { FC } from 'react';
|
||||
import { LocalizeText } from '../../../../api';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||
import { NotificationTrayItemView } from '../tray-item/NotificationTrayItemView';
|
||||
import { HotelWillShutdownViewProps } from './HotelWillShutdownView.types';
|
||||
|
||||
export const HotelWillShutdownView: FC<HotelWillShutdownViewProps> = props =>
|
||||
{
|
||||
const { notification = null, inTray = null, onButtonClick = null } = props;
|
||||
|
||||
if(!notification) return null;
|
||||
|
||||
const content = <>{ LocalizeText('opening.hours.shutdown', ['m'], [notification.minutes.toString()]) }</>;
|
||||
|
||||
if(inTray)
|
||||
return (
|
||||
<NotificationTrayItemView title={ LocalizeText('mod.alert.title') } content={ content } timestamp={ notification.timestamp } onCloseClick={ () => onButtonClick('remove_notification') } />
|
||||
);
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-notification" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('mod.alert.title') } onCloseClick={ () => onButtonClick('dismiss_notification') } />
|
||||
<NitroCardContentView className="text-black">
|
||||
{ content }
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
};
|
@ -1,7 +0,0 @@
|
||||
import { HotelWillShutdownNotification } from '../../common/HotelWillShutdownNotification';
|
||||
import { NotificationViewProps } from '../../NotificationCenterView.types';
|
||||
|
||||
export class HotelWillShutdownViewProps extends NotificationViewProps
|
||||
{
|
||||
notification: HotelWillShutdownNotification;
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
import { FC } from 'react';
|
||||
import { LocalizeText } from '../../../../api';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||
import { NotificationTrayItemView } from '../tray-item/NotificationTrayItemView';
|
||||
import { ModeratorMessageViewProps } from './ModeratorMessageView.types';
|
||||
|
||||
export const ModeratorMessageView: FC<ModeratorMessageViewProps> = props =>
|
||||
{
|
||||
const { notification = null, inTray = null, onButtonClick = null } = props;
|
||||
|
||||
if(!notification) return null;
|
||||
|
||||
const content = <>
|
||||
<div dangerouslySetInnerHTML={ { __html: notification.message } } />
|
||||
<div className="fw-bold text-center">
|
||||
<a href={ notification.link } rel="noreferrer" target="_blank" onClick={ () => onButtonClick('dismiss_notification') }>{ LocalizeText('mod.alert.link') }</a>
|
||||
</div>
|
||||
</>;
|
||||
|
||||
if(inTray)
|
||||
return (
|
||||
<NotificationTrayItemView title={ LocalizeText('mod.alert.title') } content={ content } timestamp={ notification.timestamp } onCloseClick={ () => onButtonClick('remove_notification') } />
|
||||
);
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-notification" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('mod.alert.title') } onCloseClick={ () => onButtonClick('dismiss_notification') } />
|
||||
<NitroCardContentView className="text-black">
|
||||
{ content }
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
};
|
@ -1,7 +0,0 @@
|
||||
import { ModeratorMessageNotification } from '../../common/ModeratorMessageNotification';
|
||||
import { NotificationViewProps } from '../../NotificationCenterView.types';
|
||||
|
||||
export class ModeratorMessageViewProps extends NotificationViewProps
|
||||
{
|
||||
notification: ModeratorMessageNotification;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
import { FC } from 'react';
|
||||
import { NotificationCenterBroadcastMessageView } from '../broadcast-message/NotificationCenterBroadcastMessageView';
|
||||
import { NotificationCenterMotdViewProps } from './NotificationCenterMotdView.types';
|
||||
|
||||
export const NotificationCenterMotdView: FC<NotificationCenterMotdViewProps> = props =>
|
||||
{
|
||||
const { notification = null, onClose = null } = props;
|
||||
|
||||
return <NotificationCenterBroadcastMessageView notification={ notification } onClose={ onClose } />;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { NotificationCenterAlertEvent } from '../../../../events';
|
||||
|
||||
export interface NotificationCenterMotdViewProps
|
||||
{
|
||||
notification: NotificationCenterAlertEvent;
|
||||
onClose: () => void;
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
import { FC } from 'react';
|
||||
import { NotificationTrayItemViewProps } from './NotificationTrayItemView.types';
|
||||
|
||||
export const NotificationTrayItemView: FC<NotificationTrayItemViewProps> = props =>
|
||||
{
|
||||
const { title = null, content = null, timestamp = null, onCloseClick = null } = props;
|
||||
|
||||
return (
|
||||
<div className="rounded bg-muted mb-2 text-black">
|
||||
<div className="py-1 px-2 fw-bold d-flex justify-content-between align-items-center">
|
||||
<div className="me-2">{ title }</div>
|
||||
<i className="fas fa-times cursor-pointer" onClick={ onCloseClick }></i>
|
||||
</div>
|
||||
<div className="py-1 px-2">
|
||||
{ content }
|
||||
</div>
|
||||
<div className="py-1 px-2">
|
||||
<i className="far fa-clock"></i> { timestamp }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,7 +0,0 @@
|
||||
export class NotificationTrayItemViewProps
|
||||
{
|
||||
title: string;
|
||||
content: any;
|
||||
timestamp: number;
|
||||
onCloseClick: () => void;
|
||||
}
|
Loading…
Reference in New Issue
Block a user