mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-27 08:00:51 +01:00
Merge remote-tracking branch 'origin/dev' into feature/messenger
This commit is contained in:
commit
cc33ba3e36
@ -126,6 +126,7 @@ export const App: FC<{}> = props =>
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="nitro-app">
|
<div className="nitro-app">
|
||||||
|
<div id="nitro-alerts-container" />
|
||||||
{ (!isReady || isError) && <LoadingView isError={ isError } message={ message } /> }
|
{ (!isReady || isError) && <LoadingView isError={ isError } message={ message } /> }
|
||||||
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ (isReady && !isError) } timeout={ 300 }>
|
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ (isReady && !isError) } timeout={ 300 }>
|
||||||
<MainView />
|
<MainView />
|
||||||
|
@ -1,29 +1,36 @@
|
|||||||
import { NitroEvent } from '@nitrots/nitro-renderer';
|
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 _clickUrl: string;
|
||||||
private _clickUrlText: string;
|
private _clickUrlText: string;
|
||||||
private _title: string;
|
private _title: string;
|
||||||
private _imageUrl: 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._clickUrl = clickUrl;
|
||||||
this._clickUrlText = clickUrlText;
|
this._clickUrlText = clickUrlText;
|
||||||
this._title = title;
|
this._title = title;
|
||||||
this._imageUrl = imageUrl;
|
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
|
public get clickUrl(): string
|
@ -2,7 +2,7 @@ import { NitroEvent } from '@nitrots/nitro-renderer';
|
|||||||
|
|
||||||
export class NotificationBubbleEvent extends NitroEvent
|
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 _message: string;
|
||||||
private _notificationType: 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 './NotificationCenterAlertEvent';
|
||||||
export * from './NotificationCenterEvent';
|
export * from './NotificationCenterEvent';
|
||||||
export * from './SimpleAlertUIEvent';
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
@import './loading-habbos/LoadingHabbosView';
|
@import './loading-habbos/LoadingHabbosView';
|
||||||
@import './loading-spinner/LoadingSpinnerView';
|
@import './loading-spinner/LoadingSpinnerView';
|
||||||
@import './mini-camera/NitroLayoutMiniCameraView';
|
@import './mini-camera/NitroLayoutMiniCameraView';
|
||||||
|
@import './notification-alert/NotificationAlertView';
|
||||||
@import './notification-bubble/NotificationBubbleView';
|
@import './notification-bubble/NotificationBubbleView';
|
||||||
@import './trophy/NitroLayoutTrophyView';
|
@import './trophy/NitroLayoutTrophyView';
|
||||||
@import './gift-card/NitroLayoutGiftCardView';
|
@import './gift-card/NitroLayoutGiftCardView';
|
||||||
|
@ -3,6 +3,7 @@ export * from './draggable-window';
|
|||||||
export * from './gift-card';
|
export * from './gift-card';
|
||||||
export * from './loading-spinner';
|
export * from './loading-spinner';
|
||||||
export * from './mini-camera';
|
export * from './mini-camera';
|
||||||
|
export * from './notification-alert';
|
||||||
export * from './notification-bubble';
|
export * from './notification-bubble';
|
||||||
export * from './transitions';
|
export * from './transitions';
|
||||||
export * from './trophy';
|
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';
|
@ -10,7 +10,7 @@ import { CatalogMode, CatalogViewProps } from './CatalogView.types';
|
|||||||
import { BuildCatalogPageTree } from './common/CatalogUtilities';
|
import { BuildCatalogPageTree } from './common/CatalogUtilities';
|
||||||
import { CatalogContextProvider } from './context/CatalogContext';
|
import { CatalogContextProvider } from './context/CatalogContext';
|
||||||
import { CatalogReducer, initialCatalog } from './reducers/CatalogReducer';
|
import { CatalogReducer, initialCatalog } from './reducers/CatalogReducer';
|
||||||
import { CatalogPageGiftView } from './views/gift/CatalogPageGiftView';
|
import { CatalogGiftView } from './views/gift/CatalogGiftView';
|
||||||
import { ACTIVE_PAGES, CatalogNavigationView } from './views/navigation/CatalogNavigationView';
|
import { ACTIVE_PAGES, CatalogNavigationView } from './views/navigation/CatalogNavigationView';
|
||||||
import { CatalogPageView } from './views/page/CatalogPageView';
|
import { CatalogPageView } from './views/page/CatalogPageView';
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ export const CatalogView: FC<CatalogViewProps> = props =>
|
|||||||
</div>
|
</div>
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView> }
|
</NitroCardView> }
|
||||||
<CatalogPageGiftView />
|
<CatalogGiftView />
|
||||||
</CatalogContextProvider>
|
</CatalogContextProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
@import './navigation/CatalogNavigationView';
|
@import './navigation/CatalogNavigationView';
|
||||||
@import './page/CatalogPageView';
|
@import './page/CatalogPageView';
|
||||||
@import './search/CatalogSearchView';
|
@import './search/CatalogSearchView';
|
||||||
@import './gift/CatalogPageGiftView';
|
@import './gift/CatalogGiftView';
|
||||||
|
@ -10,7 +10,7 @@ import { CurrencyIcon } from '../../../shared/currency-icon/CurrencyIcon';
|
|||||||
import { FurniImageView } from '../../../shared/furni-image/FurniImageView';
|
import { FurniImageView } from '../../../shared/furni-image/FurniImageView';
|
||||||
import { useCatalogContext } from '../../context/CatalogContext';
|
import { useCatalogContext } from '../../context/CatalogContext';
|
||||||
|
|
||||||
export const CatalogPageGiftView: FC<{}> = props =>
|
export const CatalogGiftView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const { catalogState = null } = useCatalogContext();
|
const { catalogState = null } = useCatalogContext();
|
||||||
const { giftConfiguration = null } = catalogState;
|
const { giftConfiguration = null } = catalogState;
|
@ -63,8 +63,6 @@ export const CatalogLayoutBadgeDisplayView: FC<CatalogLayoutBadgeDisplayViewProp
|
|||||||
const stringDataType = new StringDataType();
|
const stringDataType = new StringDataType();
|
||||||
stringDataType.setValue(productData);
|
stringDataType.setValue(productData);
|
||||||
|
|
||||||
console.log(stringDataType);
|
|
||||||
|
|
||||||
dispatchUiEvent(new SetRoomPreviewerStuffDataEvent(activeOffer, stringDataType));
|
dispatchUiEvent(new SetRoomPreviewerStuffDataEvent(activeOffer, stringDataType));
|
||||||
}, [ currentBadge, activeOffer, roomPreviewer ]);
|
}, [ currentBadge, activeOffer, roomPreviewer ]);
|
||||||
|
|
||||||
|
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 { CatalogView } from '../catalog/CatalogView';
|
||||||
import { FriendsView } from '../friends/FriendsView';
|
import { FriendsView } from '../friends/FriendsView';
|
||||||
import { GroupsView } from '../groups/GroupsView';
|
import { GroupsView } from '../groups/GroupsView';
|
||||||
|
import { HelpView } from '../help/HelpView';
|
||||||
import { HotelView } from '../hotel-view/HotelView';
|
import { HotelView } from '../hotel-view/HotelView';
|
||||||
import { InventoryView } from '../inventory/InventoryView';
|
import { InventoryView } from '../inventory/InventoryView';
|
||||||
import { ModToolsView } from '../mod-tools/ModToolsView';
|
import { ModToolsView } from '../mod-tools/ModToolsView';
|
||||||
@ -69,6 +70,7 @@ export const MainView: FC<MainViewProps> = props =>
|
|||||||
<UserProfileView />
|
<UserProfileView />
|
||||||
<GroupsView />
|
<GroupsView />
|
||||||
<CameraWidgetView />
|
<CameraWidgetView />
|
||||||
|
<HelpView />
|
||||||
</div>
|
</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 { FC, useCallback } from 'react';
|
||||||
import { GetRoomEngine, GetSessionDataManager, LocalizeBadgeName, LocalizeText } from '../../api';
|
import { GetConfiguration, GetRoomEngine, GetSessionDataManager, LocalizeBadgeName, LocalizeText } from '../../api';
|
||||||
import { NotificationCenterAlertEvent } from '../../events';
|
|
||||||
import { dispatchUiEvent } from '../../hooks/events';
|
|
||||||
import { CreateMessageHook } from '../../hooks/messages';
|
import { CreateMessageHook } from '../../hooks/messages';
|
||||||
import { HotelWillShutdownNotification } from './common/HotelWillShutdownNotification';
|
import { NotificationBubbleType } from './common/NotificationBubbleType';
|
||||||
import { NotificationType } from './common/NotificationType';
|
|
||||||
import { NotificationUtilities } from './common/NotificationUtilities';
|
import { NotificationUtilities } from './common/NotificationUtilities';
|
||||||
import { useNotificationCenterContext } from './context/NotificationCenterContext';
|
import { ProductImageUtility } from './common/ProductImageUtility';
|
||||||
import { INotificationCenterMessageHandlerProps } from './NotificationCenterMessageHandler.types';
|
import { INotificationCenterMessageHandlerProps } from './NotificationCenterMessageHandler.types';
|
||||||
import { NotificationCenterActions } from './reducers/NotificationCenterReducer';
|
|
||||||
|
|
||||||
export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHandlerProps> = props =>
|
export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHandlerProps> = props =>
|
||||||
{
|
{
|
||||||
const { dispatchNotificationCenterState = null } = useNotificationCenterContext();
|
|
||||||
|
|
||||||
const onRespectReceivedEvent = useCallback((event: RespectReceivedEvent) =>
|
const onRespectReceivedEvent = useCallback((event: RespectReceivedEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
@ -24,8 +18,8 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
|||||||
const text1 = LocalizeText('notifications.text.respect.1');
|
const text1 = LocalizeText('notifications.text.respect.1');
|
||||||
const text2 = LocalizeText('notifications.text.respect.2', [ 'count' ], [ parser.respectsReceived.toString() ]);
|
const text2 = LocalizeText('notifications.text.respect.2', [ 'count' ], [ parser.respectsReceived.toString() ]);
|
||||||
|
|
||||||
NotificationUtilities.showSingleBubble(text1, NotificationType.RESPECT);
|
NotificationUtilities.showSingleBubble(text1, NotificationBubbleType.RESPECT);
|
||||||
NotificationUtilities.showSingleBubble(text2, NotificationType.RESPECT);
|
NotificationUtilities.showSingleBubble(text2, NotificationBubbleType.RESPECT);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
CreateMessageHook(RespectReceivedEvent, onRespectReceivedEvent);
|
CreateMessageHook(RespectReceivedEvent, onRespectReceivedEvent);
|
||||||
@ -34,7 +28,7 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
|||||||
{
|
{
|
||||||
const parser = event.getParser();
|
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);
|
CreateMessageHook(HabboBroadcastMessageEvent, onHabboBroadcastMessageEvent);
|
||||||
@ -48,7 +42,7 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
|||||||
const badgeImage = GetSessionDataManager().getBadgeUrl(parser.data.badgeCode);
|
const badgeImage = GetSessionDataManager().getBadgeUrl(parser.data.badgeCode);
|
||||||
const internalLink = 'questengine/achievements/' + parser.data.category;
|
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);
|
CreateMessageHook(AchievementNotificationMessageEvent, onAchievementNotificationMessageEvent);
|
||||||
@ -66,7 +60,7 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
|||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
dispatchUiEvent(new NotificationCenterAlertEvent(NotificationCenterAlertEvent.HOTEL_ALERT, [ parser.message ], parser.link));
|
NotificationUtilities.handleModeratorMessage(parser.message, parser.link);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
CreateMessageHook(ModeratorMessageEvent, onModeratorMessageEvent);
|
CreateMessageHook(ModeratorMessageEvent, onModeratorMessageEvent);
|
||||||
@ -75,11 +69,31 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
|||||||
{
|
{
|
||||||
const parser = event.getParser();
|
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);
|
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 onHotelClosesAndWillOpenAtEvent = useCallback((event: HotelClosesAndWillOpenAtEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
@ -89,7 +103,7 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
|||||||
|
|
||||||
CreateMessageHook(HotelClosesAndWillOpenAtEvent, onHotelClosesAndWillOpenAtEvent);
|
CreateMessageHook(HotelClosesAndWillOpenAtEvent, onHotelClosesAndWillOpenAtEvent);
|
||||||
|
|
||||||
const onPetAddedToInventoryEvent = useCallback((event: PetAddedToInventoryEvent) =>
|
const onPetReceivedMessageEvent = useCallback((event: PetReceivedMessageEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
@ -101,10 +115,10 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
|||||||
|
|
||||||
if(imageResult) imageUrl = imageResult.getImage().src;
|
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) =>
|
const onRoomEnterEvent = useCallback((event: RoomEnterEvent) =>
|
||||||
{
|
{
|
||||||
@ -119,24 +133,67 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
|||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
dispatchUiEvent(new NotificationCenterAlertEvent(NotificationCenterAlertEvent.HOTEL_ALERT, parser.messages));
|
NotificationUtilities.handleMOTD(parser.messages);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
CreateMessageHook(MOTDNotificationEvent, onMOTDNotificationEvent);
|
CreateMessageHook(MOTDNotificationEvent, onMOTDNotificationEvent);
|
||||||
|
|
||||||
const onHotelWillShutdownEvent = useCallback((event: HotelWillShutdownEvent) =>
|
const onPetLevelNotificationEvent = useCallback((event: PetLevelNotificationEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
dispatchNotificationCenterState({
|
let imageUrl: string = null;
|
||||||
type: NotificationCenterActions.ADD_NOTIFICATION,
|
|
||||||
payload: {
|
|
||||||
notification: new HotelWillShutdownNotification(parser.minutes)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, [ dispatchNotificationCenterState ]);
|
|
||||||
|
|
||||||
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) =>
|
const onNotificationDialogMessageEvent = useCallback((event: NotificationDialogMessageEvent) =>
|
||||||
{
|
{
|
||||||
@ -147,5 +204,23 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
|||||||
|
|
||||||
CreateMessageHook(NotificationDialogMessageEvent, onNotificationDialogMessageEvent);
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,3 @@
|
|||||||
.nitro-alert {
|
|
||||||
width: 350px;
|
|
||||||
|
|
||||||
.content-area {
|
|
||||||
min-height: 125px;
|
|
||||||
max-height: 300px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nitro-notification-center-container {
|
.nitro-notification-center-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
@ -1,40 +1,42 @@
|
|||||||
import { FC, ReactNode, useCallback, useMemo, useState } from 'react';
|
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 { NotificationBubbleEvent } from '../../events/notification-center/NotificationBubbleEvent';
|
||||||
import { useUiEvent } from '../../hooks/events';
|
import { useUiEvent } from '../../hooks/events';
|
||||||
import { NotificationItem } from './common/NotificationItem';
|
import { NotificationAlertItem } from './common/NotificationAlertItem';
|
||||||
import { NotificationType } from './common/NotificationType';
|
import { NotificationBubbleItem } from './common/NotificationBubbleItem';
|
||||||
|
import { NotificationBubbleType } from './common/NotificationBubbleType';
|
||||||
import { NotificationCenterMessageHandler } from './NotificationCenterMessageHandler';
|
import { NotificationCenterMessageHandler } from './NotificationCenterMessageHandler';
|
||||||
import { NotificationCenterViewProps } from './NotificationCenterView.types';
|
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';
|
import { GetBubbleLayout } from './views/bubble-layouts/GetBubbleLayout';
|
||||||
|
|
||||||
export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
||||||
{
|
{
|
||||||
const [ alerts, setAlerts ] = useState<NotificationCenterAlertEvent[]>([]);
|
const [ alerts, setAlerts ] = useState<NotificationAlertItem[]>([]);
|
||||||
const [ bubbleAlerts, setBubbleAlerts ] = useState<NotificationItem[]>([]);
|
const [ bubbleAlerts, setBubbleAlerts ] = useState<NotificationBubbleItem[]>([]);
|
||||||
|
|
||||||
const onNotificationCenterAlertEvent = useCallback((event: NotificationCenterAlertEvent) =>
|
const onNotificationAlertEvent = useCallback((event: NotificationAlertEvent) =>
|
||||||
{
|
{
|
||||||
setAlerts(prevValue =>
|
console.log(event);
|
||||||
{
|
const alertItem = new NotificationAlertItem(event.messages, event.alertType, event.clickUrl, event.clickUrlText, event.title, event.imageUrl);
|
||||||
return [ ...prevValue, event ];
|
|
||||||
});
|
setAlerts(prevValue => [ alertItem, ...prevValue ]);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useUiEvent(NotificationCenterAlertEvent.HOTEL_ALERT, onNotificationCenterAlertEvent);
|
useUiEvent(NotificationAlertEvent.ALERT, onNotificationAlertEvent);
|
||||||
|
|
||||||
const onNotificationBubbleEvent = useCallback((event: NotificationBubbleEvent) =>
|
const onNotificationBubbleEvent = useCallback((event: NotificationBubbleEvent) =>
|
||||||
{
|
{
|
||||||
console.log(event);
|
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 ]);
|
setBubbleAlerts(prevValue => [ notificationItem, ...prevValue ]);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useUiEvent(NotificationBubbleEvent.NEW_BUBBLE, onNotificationBubbleEvent);
|
useUiEvent(NotificationBubbleEvent.NEW_BUBBLE, onNotificationBubbleEvent);
|
||||||
|
|
||||||
const closeAlert = useCallback((alert: NotificationCenterAlertEvent) =>
|
const closeAlert = useCallback((alert: NotificationAlertItem) =>
|
||||||
{
|
{
|
||||||
setAlerts(prevValue =>
|
setAlerts(prevValue =>
|
||||||
{
|
{
|
||||||
@ -47,7 +49,7 @@ export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
|||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const closeBubbleAlert = useCallback((item: NotificationItem) =>
|
const closeBubbleAlert = useCallback((item: NotificationBubbleItem) =>
|
||||||
{
|
{
|
||||||
setBubbleAlerts(prevValue =>
|
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(() =>
|
const getBubbleAlerts = useMemo(() =>
|
||||||
{
|
{
|
||||||
if(!bubbleAlerts || !bubbleAlerts.length) return null;
|
if(!bubbleAlerts || !bubbleAlerts.length) return null;
|
||||||
@ -70,7 +88,7 @@ export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
|||||||
{
|
{
|
||||||
const element = GetBubbleLayout(alert, () => closeBubbleAlert(alert));
|
const element = GetBubbleLayout(alert, () => closeBubbleAlert(alert));
|
||||||
|
|
||||||
if(alert.notificationType === NotificationType.CLUBGIFT)
|
if(alert.notificationType === NotificationBubbleType.CLUBGIFT)
|
||||||
{
|
{
|
||||||
elements.unshift(element);
|
elements.unshift(element);
|
||||||
|
|
||||||
@ -89,15 +107,7 @@ export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
|||||||
<div className="nitro-notification-center">
|
<div className="nitro-notification-center">
|
||||||
{ getBubbleAlerts }
|
{ getBubbleAlerts }
|
||||||
</div>
|
</div>
|
||||||
{ (alerts.length > 0) && alerts.map((alert, index) =>
|
{ createPortal(getAlerts, document.getElementById('nitro-alerts-container')) }
|
||||||
{
|
|
||||||
switch(alert.type)
|
|
||||||
{
|
|
||||||
case NotificationCenterAlertEvent.HOTEL_ALERT:
|
|
||||||
default:
|
|
||||||
return <NotificationCenterBroadcastMessageView key={ index } notification={ alert } onClose={ () => closeAlert(alert) } />;
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
private static ITEM_ID: number = -1;
|
||||||
|
|
||||||
@ -10,11 +10,11 @@ export class NotificationItem
|
|||||||
private _iconUrl: string;
|
private _iconUrl: string;
|
||||||
private _linkUrl: 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._message = message;
|
||||||
this._notificationType = notificationType;
|
this._notificationType = notificationType;
|
||||||
this._iconUrl = iconUrl;
|
this._iconUrl = iconUrl;
|
@ -1,4 +1,4 @@
|
|||||||
export class NotificationType
|
export class NotificationBubbleType
|
||||||
{
|
{
|
||||||
public static FRIENDOFFLINE: string = 'friendoffline';
|
public static FRIENDOFFLINE: string = 'friendoffline';
|
||||||
public static FRIENDONLINE: string = 'friendonline';
|
public static FRIENDONLINE: string = 'friendonline';
|
@ -1,10 +1,11 @@
|
|||||||
import { HabboWebTools, RoomEnterEffect } from '@nitrots/nitro-renderer';
|
import { HabboWebTools, RoomEnterEffect } from '@nitrots/nitro-renderer';
|
||||||
import { CreateLinkEvent, GetConfiguration, GetNitroInstance, LocalizeText } from '../../../api';
|
import { CreateLinkEvent, GetConfiguration, GetNitroInstance, LocalizeText } from '../../../api';
|
||||||
import { SimpleAlertUIEvent } from '../../../events';
|
import { NotificationAlertEvent } from '../../../events';
|
||||||
import { NotificationBubbleEvent } from '../../../events/notification-center/NotificationBubbleEvent';
|
import { NotificationBubbleEvent } from '../../../events/notification-center/NotificationBubbleEvent';
|
||||||
import { dispatchUiEvent } from '../../../hooks';
|
import { dispatchUiEvent } from '../../../hooks';
|
||||||
import { CatalogPageName } from '../../catalog/common/CatalogPageName';
|
import { CatalogPageName } from '../../catalog/common/CatalogPageName';
|
||||||
import { NotificationType } from './NotificationType';
|
import { NotificationAlertType } from './NotificationAlertType';
|
||||||
|
import { NotificationBubbleType } from './NotificationBubbleType';
|
||||||
|
|
||||||
export class NotificationUtilities
|
export class NotificationUtilities
|
||||||
{
|
{
|
||||||
@ -12,6 +13,8 @@ export class NotificationUtilities
|
|||||||
private static MODERATION_DISCLAIMER_DELAY_MS: number = 5000;
|
private static MODERATION_DISCLAIMER_DELAY_MS: number = 5000;
|
||||||
private static MODERATION_DISCLAIMER_TIMEOUT: ReturnType<typeof setTimeout> = null;
|
private static MODERATION_DISCLAIMER_TIMEOUT: ReturnType<typeof setTimeout> = null;
|
||||||
|
|
||||||
|
public static BUBBLES_DISABLED: boolean = false;
|
||||||
|
|
||||||
private static cleanText(text: string): string
|
private static cleanText(text: string): string
|
||||||
{
|
{
|
||||||
return text.replace(/\\r/g, '\r')
|
return text.replace(/\\r/g, '\r')
|
||||||
@ -68,62 +71,92 @@ export class NotificationUtilities
|
|||||||
|
|
||||||
const configuration = this.getNotificationConfig(('notification.' + type));
|
const configuration = this.getNotificationConfig(('notification.' + type));
|
||||||
|
|
||||||
if(configuration)
|
if(configuration) for(const key in configuration) options.set(key, configuration[key]);
|
||||||
{
|
|
||||||
for(const key in configuration) options.set(key, configuration[key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(options);
|
console.log(options);
|
||||||
|
|
||||||
if(options.get('display') === 'BUBBLE')
|
const title = this.getNotificationPart(options, type, 'title', true);
|
||||||
{
|
const message = this.getNotificationPart(options, type, 'message', true).replace(/\\r/g, '\r');
|
||||||
const message = this.getNotificationPart(options, type, 'message', true);
|
const linkTitle = this.getNotificationPart(options, type, 'linkTitle', false);
|
||||||
const linkUrl = this.getNotificationPart(options, type, 'linkUrl', false);
|
const linkUrl = this.getNotificationPart(options, type, 'linkUrl', false);
|
||||||
const isEventLink = (linkUrl && linkUrl.substr(0, 6) === 'event');
|
|
||||||
const image = this.getNotificationImageUrl(options, type);
|
const image = this.getNotificationImageUrl(options, type);
|
||||||
|
|
||||||
dispatchUiEvent(new NotificationBubbleEvent(LocalizeText(message), NotificationType.INFO, LocalizeText(image), (isEventLink ? linkUrl.substr(6) : linkUrl)));
|
if(options.get('display') === 'BUBBLE')
|
||||||
|
{
|
||||||
|
this.showSingleBubble(LocalizeText(message), NotificationBubbleType.INFO, LocalizeText(image), linkUrl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
this.simpleAlert(message, NotificationAlertType.EVENT, linkUrl, linkTitle, title, image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static showSingleBubble(message: string, type: string, imageUrl: string = null, internalLink: string = null): void
|
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));
|
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
|
public static showClubGiftNotification(numGifts: number): void
|
||||||
{
|
{
|
||||||
if(numGifts <= 0) return;
|
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
|
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
|
public static openUrl(url: string): void
|
||||||
@ -134,7 +167,7 @@ export class NotificationUtilities
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CreateLinkEvent(url);
|
CreateLinkEvent(url.substring(6));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +186,7 @@ export class NotificationUtilities
|
|||||||
{
|
{
|
||||||
if(this.MODERATION_DISCLAIMER_SHOWN) return;
|
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;
|
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 { NotificationBubbleItem } from '../../common/NotificationBubbleItem';
|
||||||
import { NotificationType } from '../../common/NotificationType';
|
import { NotificationBubbleType } from '../../common/NotificationBubbleType';
|
||||||
import { NotificationClubGiftBubbleView } from './club-gift/NotificationClubGiftBubbleView';
|
import { NotificationClubGiftBubbleView } from './club-gift/NotificationClubGiftBubbleView';
|
||||||
import { NotificationDefaultBubbleView } from './default/NotificationDefaultBubbleView';
|
import { NotificationDefaultBubbleView } from './default/NotificationDefaultBubbleView';
|
||||||
|
|
||||||
export const GetBubbleLayout = (item: NotificationItem, close: () => void) =>
|
export const GetBubbleLayout = (item: NotificationBubbleItem, close: () => void) =>
|
||||||
{
|
{
|
||||||
if(!item) return null;
|
if(!item) return null;
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ export const GetBubbleLayout = (item: NotificationItem, close: () => void) =>
|
|||||||
|
|
||||||
switch(item.notificationType)
|
switch(item.notificationType)
|
||||||
{
|
{
|
||||||
case NotificationType.CLUBGIFT:
|
case NotificationBubbleType.CLUBGIFT:
|
||||||
return <NotificationClubGiftBubbleView { ...props } />
|
return <NotificationClubGiftBubbleView { ...props } />
|
||||||
default:
|
default:
|
||||||
return <NotificationDefaultBubbleView { ...props } />
|
return <NotificationDefaultBubbleView { ...props } />
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { NotificationItem } from '../../common/NotificationItem';
|
import { NotificationBubbleItem } from '../../common/NotificationBubbleItem';
|
||||||
|
|
||||||
export interface NotificationBubbleLayoutViewProps
|
export interface NotificationBubbleLayoutViewProps
|
||||||
{
|
{
|
||||||
item: NotificationItem;
|
item: NotificationBubbleItem;
|
||||||
close: () => void;
|
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;
|
|
||||||
}
|
|
@ -260,11 +260,18 @@ export const ChatInputView: FC<{}> = props =>
|
|||||||
}
|
}
|
||||||
}, [ onKeyDownEvent ]);
|
}, [ onKeyDownEvent ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!inputRef.current) return;
|
||||||
|
|
||||||
|
inputRef.current.parentElement.dataset.value = chatValue;
|
||||||
|
}, [ chatValue ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
createPortal(
|
createPortal(
|
||||||
<div className="nitro-chat-input-container">
|
<div className="nitro-chat-input-container">
|
||||||
<div className="input-sizer">
|
<div className="input-sizer">
|
||||||
<input ref={ inputRef } type="text" className="chat-input" placeholder={ LocalizeText('widgets.chatinput.default') } value={ chatValue } maxLength={ maxChatLength } onChange={ event => { event.target.parentElement.dataset.value = event.target.value; updateChatInput(event.target.value) } } onMouseDown={ event => setInputFocus() } />
|
<input ref={ inputRef } type="text" className="chat-input" placeholder={ LocalizeText('widgets.chatinput.default') } value={ chatValue } maxLength={ maxChatLength } onChange={ event => updateChatInput(event.target.value) } onMouseDown={ event => setInputFocus() } />
|
||||||
</div>
|
</div>
|
||||||
<ChatInputStyleSelectorView onStyleSelected={ onStyleSelected } />
|
<ChatInputStyleSelectorView onStyleSelected={ onStyleSelected } />
|
||||||
</div>, document.getElementById('toolbar-chat-input-container'))
|
</div>, document.getElementById('toolbar-chat-input-container'))
|
||||||
|
@ -55,16 +55,8 @@ export const FurnitureDimmerView: FC<{}> = props =>
|
|||||||
|
|
||||||
BatchUpdates(() =>
|
BatchUpdates(() =>
|
||||||
{
|
{
|
||||||
let prevDimmerState = 0;
|
setLastDimmerState(dimmerState);
|
||||||
|
setDimmerState(widgetEvent.state);
|
||||||
setDimmerState(prevValue =>
|
|
||||||
{
|
|
||||||
setLastDimmerState(prevValue);
|
|
||||||
|
|
||||||
return widgetEvent.state;
|
|
||||||
});
|
|
||||||
|
|
||||||
setLastDimmerState(prevDimmerState);
|
|
||||||
setSelectedPresetId(widgetEvent.presetId);
|
setSelectedPresetId(widgetEvent.presetId);
|
||||||
setEffectId(widgetEvent.effectId);
|
setEffectId(widgetEvent.effectId);
|
||||||
setSelectedEffectId(widgetEvent.effectId);
|
setSelectedEffectId(widgetEvent.effectId);
|
||||||
@ -73,10 +65,11 @@ export const FurnitureDimmerView: FC<{}> = props =>
|
|||||||
setBrightness(widgetEvent.brightness);
|
setBrightness(widgetEvent.brightness);
|
||||||
setSelectedBrightness(widgetEvent.brightness);
|
setSelectedBrightness(widgetEvent.brightness);
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, []);
|
}, [ dimmerState ]);
|
||||||
|
|
||||||
CreateEventDispatcherHook(RoomWidgetUpdateDimmerEvent.PRESETS, eventDispatcher, onNitroEvent);
|
CreateEventDispatcherHook(RoomWidgetUpdateDimmerEvent.PRESETS, eventDispatcher, onNitroEvent);
|
||||||
CreateEventDispatcherHook(RoomWidgetUpdateDimmerEvent.HIDE, eventDispatcher, onNitroEvent);
|
CreateEventDispatcherHook(RoomWidgetUpdateDimmerEvent.HIDE, eventDispatcher, onNitroEvent);
|
||||||
@ -144,6 +137,8 @@ export const FurnitureDimmerView: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
if((dimmerState === 0) && (lastDimmerState === 0)) return;
|
if((dimmerState === 0) && (lastDimmerState === 0)) return;
|
||||||
|
|
||||||
|
console.log('ye')
|
||||||
|
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetDimmerPreviewMessage(selectedColor, selectedBrightness, (selectedEffectId === 2)));
|
widgetHandler.processWidgetMessage(new RoomWidgetDimmerPreviewMessage(selectedColor, selectedBrightness, (selectedEffectId === 2)));
|
||||||
}, [ widgetHandler, dimmerState, lastDimmerState, selectedColor, selectedBrightness, selectedEffectId ]);
|
}, [ widgetHandler, dimmerState, lastDimmerState, selectedColor, selectedBrightness, selectedEffectId ]);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user