mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-19 05:46:27 +01:00
Update notification-center
This commit is contained in:
parent
48dfdb6ce1
commit
c0293357fb
@ -50,3 +50,11 @@ ul {
|
|||||||
.w-unset {
|
.w-unset {
|
||||||
width: unset;
|
width: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-select {
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-o-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
48
src/events/notification-center/SimpleAlertUIEvent.ts
Normal file
48
src/events/notification-center/SimpleAlertUIEvent.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { NitroEvent } from '@nitrots/nitro-renderer';
|
||||||
|
|
||||||
|
export class SimpleAlertUIEvent extends NitroEvent
|
||||||
|
{
|
||||||
|
public static ALERT: string = 'SAUE_ALERT';
|
||||||
|
|
||||||
|
private _message: 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)
|
||||||
|
{
|
||||||
|
super(SimpleAlertUIEvent.ALERT);
|
||||||
|
|
||||||
|
this._message = message;
|
||||||
|
this._clickUrl = clickUrl;
|
||||||
|
this._clickUrlText = clickUrlText;
|
||||||
|
this._title = title;
|
||||||
|
this._imageUrl = imageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get message(): string
|
||||||
|
{
|
||||||
|
return this._message;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
export * from './NotificationCenterAddNotificationEvent';
|
export * from './NotificationCenterAddNotificationEvent';
|
||||||
export * from './NotificationCenterAlertEvent';
|
export * from './NotificationCenterAlertEvent';
|
||||||
export * from './NotificationCenterEvent';
|
export * from './NotificationCenterEvent';
|
||||||
|
export * from './SimpleAlertUIEvent';
|
||||||
|
@ -26,4 +26,5 @@
|
|||||||
@import './draggable-window/DraggableWindow';
|
@import './draggable-window/DraggableWindow';
|
||||||
@import './loading-spinner/LoadingSpinnerView';
|
@import './loading-spinner/LoadingSpinnerView';
|
||||||
@import './mini-camera/NitroLayoutMiniCameraView';
|
@import './mini-camera/NitroLayoutMiniCameraView';
|
||||||
|
@import './notification-bubble/NotificationBubbleView';
|
||||||
@import './trophy/NitroLayoutTrophyView';
|
@import './trophy/NitroLayoutTrophyView';
|
||||||
|
@ -2,5 +2,6 @@ export * from './card';
|
|||||||
export * from './draggable-window';
|
export * from './draggable-window';
|
||||||
export * from './loading-spinner';
|
export * from './loading-spinner';
|
||||||
export * from './mini-camera';
|
export * from './mini-camera';
|
||||||
|
export * from './notification-bubble';
|
||||||
export * from './transitions';
|
export * from './transitions';
|
||||||
export * from './trophy';
|
export * from './trophy';
|
||||||
|
19
src/layout/notification-bubble/NotificationBubbleView.scss
Normal file
19
src/layout/notification-bubble/NotificationBubbleView.scss
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
.nitro-notification-bubble {
|
||||||
|
pointer-events: all;
|
||||||
|
background-color: $gable-green;
|
||||||
|
border: 2px solid rgba($white, 0.5);
|
||||||
|
font-size: $font-size-sm;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
|
||||||
|
&.club-gift {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.bubble-image {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
overflow: hidden;
|
||||||
|
object-fit: none;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
28
src/layout/notification-bubble/NotificationBubbleView.tsx
Normal file
28
src/layout/notification-bubble/NotificationBubbleView.tsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { FC, useEffect, useState } from 'react';
|
||||||
|
import { NotificationBubbleViewProps } from './NotificationBubbleView.types';
|
||||||
|
|
||||||
|
export const NotificationBubbleView: FC<NotificationBubbleViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { fadesOut = false, close = null, className = '', children = null, ...rest } = props;
|
||||||
|
const [ isFading, setIsFading ] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!fadesOut) return;
|
||||||
|
|
||||||
|
const timeout = setTimeout(() =>
|
||||||
|
{
|
||||||
|
setIsFading(true);
|
||||||
|
|
||||||
|
setTimeout(() => close());
|
||||||
|
}, 8000);
|
||||||
|
|
||||||
|
return () => clearTimeout(timeout);
|
||||||
|
}, [ fadesOut, close ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ ('nitro-notification-bubble p-1 rounded ' + (className || '')) } { ...rest } onClick={ close }>
|
||||||
|
{ children }
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
import { DetailsHTMLAttributes } from 'react';
|
||||||
|
|
||||||
|
export interface NotificationBubbleViewProps extends DetailsHTMLAttributes<HTMLDivElement>
|
||||||
|
{
|
||||||
|
fadesOut?: boolean;
|
||||||
|
close: () => void;
|
||||||
|
}
|
2
src/layout/notification-bubble/index.ts
Normal file
2
src/layout/notification-bubble/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './NotificationBubbleView';
|
||||||
|
export * from './NotificationBubbleView.types';
|
26
src/views/catalog/common/CatalogPageName.ts
Normal file
26
src/views/catalog/common/CatalogPageName.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
export class CatalogPageName
|
||||||
|
{
|
||||||
|
public static DUCKET_INFO: string = 'ducket_info';
|
||||||
|
public static CREDITS: string = 'credits';
|
||||||
|
public static AVATAR_EFFECTS: string = 'avatar_effects';
|
||||||
|
public static HC_MEMBERSHIP: string = 'hc_membership';
|
||||||
|
public static CLUB_GIFTS: string = 'club_gifts';
|
||||||
|
public static LIMITED_SOLD: string = 'limited_sold';
|
||||||
|
public static PET_ACCESSORIES: string = 'pet_accessories';
|
||||||
|
public static TRAX_SONGS: string = 'trax_songs';
|
||||||
|
public static NEW_ADDITIONS: string = 'new_additions';
|
||||||
|
public static QUEST_SHELL: string = 'quest_shell';
|
||||||
|
public static QUEST_SNOWFLAKES: string = 'quest_snowflakes';
|
||||||
|
public static VAL_QUESTS: string = 'val_quests';
|
||||||
|
public static GUILD_CUSTOM_FURNI: string = 'guild_custom_furni';
|
||||||
|
public static GIFT_SHOP: string = 'gift_shop';
|
||||||
|
public static HORSE_STYLES: string = 'horse_styles';
|
||||||
|
public static HORSE_SHOE: string = 'horse_shoe';
|
||||||
|
public static SET_EASTER: string = 'set_easter';
|
||||||
|
public static ECOTRON_TRANSFORM: string = 'ecotron_transform';
|
||||||
|
public static LOYALTY_INFO: string = 'loyalty_info';
|
||||||
|
public static ROOM_BUNDLES: string = 'room_bundles';
|
||||||
|
public static ROOM_BUNDLES_MOBILE: string = 'room_bundles_mobile';
|
||||||
|
public static HABBO_CLUB_DESKTOP: string = 'habbo_club_desktop';
|
||||||
|
public static MOBILE_SUBSCRIPTIONS: string = 'mobile_subscriptions';
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import { AchievementNotificationMessageEvent, HabboBroadcastMessageEvent, HotelWillShutdownEvent, ModeratorMessageEvent, MOTDNotificationEvent, NotificationDialogMessageEvent, RespectReceivedEvent } from '@nitrots/nitro-renderer';
|
import { AchievementNotificationMessageEvent, ActivityPointNotificationMessageEvent, ClubGiftNotificationEvent, HabboBroadcastMessageEvent, HotelClosesAndWillOpenAtEvent, HotelWillShutdownEvent, ModeratorMessageEvent, MOTDNotificationEvent, NotificationDialogMessageEvent, PetAddedToInventoryEvent, RespectReceivedEvent, Vector3d } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC, useCallback } from 'react';
|
||||||
import { GetSessionDataManager, LocalizeBadgeName, LocalizeText } from '../../api';
|
import { GetRoomEngine, GetSessionDataManager, LocalizeBadgeName, LocalizeText } from '../../api';
|
||||||
import { NotificationCenterAlertEvent } from '../../events';
|
import { NotificationCenterAlertEvent } from '../../events';
|
||||||
import { dispatchUiEvent } from '../../hooks/events';
|
import { dispatchUiEvent } from '../../hooks/events';
|
||||||
import { CreateMessageHook } from '../../hooks/messages';
|
import { CreateMessageHook } from '../../hooks/messages';
|
||||||
@ -15,13 +15,53 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
|||||||
{
|
{
|
||||||
const { dispatchNotificationCenterState = null } = useNotificationCenterContext();
|
const { dispatchNotificationCenterState = null } = useNotificationCenterContext();
|
||||||
|
|
||||||
|
const onRespectReceivedEvent = useCallback((event: RespectReceivedEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
if(parser.userId !== GetSessionDataManager().userId) return;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
CreateMessageHook(RespectReceivedEvent, onRespectReceivedEvent);
|
||||||
|
|
||||||
const onHabboBroadcastMessageEvent = useCallback((event: HabboBroadcastMessageEvent) =>
|
const onHabboBroadcastMessageEvent = useCallback((event: HabboBroadcastMessageEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
dispatchUiEvent(new NotificationCenterAlertEvent(NotificationCenterAlertEvent.HOTEL_ALERT, [ parser.message ]));
|
NotificationUtilities.simpleAlert(parser.message.replace(/\\r/g, '\r'));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
CreateMessageHook(HabboBroadcastMessageEvent, onHabboBroadcastMessageEvent);
|
||||||
|
|
||||||
|
const onAchievementNotificationMessageEvent = useCallback((event: AchievementNotificationMessageEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
const text1 = LocalizeText('achievements.levelup.desc');
|
||||||
|
const badgeName = LocalizeBadgeName(parser.data.badgeCode);
|
||||||
|
const badgeImage = GetSessionDataManager().getBadgeUrl(parser.data.badgeCode);
|
||||||
|
const internalLink = 'questengine/achievements/' + parser.data.category;
|
||||||
|
|
||||||
|
NotificationUtilities.showSingleBubble((text1 + ' ' + badgeName), NotificationType.ACHIEVEMENT, badgeImage, internalLink);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
CreateMessageHook(AchievementNotificationMessageEvent, onAchievementNotificationMessageEvent);
|
||||||
|
|
||||||
|
const onClubGiftNotificationEvent = useCallback((event: ClubGiftNotificationEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
NotificationUtilities.showClubGiftNotification(parser.numGifts);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
CreateMessageHook(ClubGiftNotificationEvent, onClubGiftNotificationEvent);
|
||||||
|
|
||||||
const onModeratorMessageEvent = useCallback((event: ModeratorMessageEvent) =>
|
const onModeratorMessageEvent = useCallback((event: ModeratorMessageEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
@ -29,6 +69,43 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
|||||||
dispatchUiEvent(new NotificationCenterAlertEvent(NotificationCenterAlertEvent.HOTEL_ALERT, [ parser.message ], parser.link));
|
dispatchUiEvent(new NotificationCenterAlertEvent(NotificationCenterAlertEvent.HOTEL_ALERT, [ parser.message ], parser.link));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
CreateMessageHook(ModeratorMessageEvent, onModeratorMessageEvent);
|
||||||
|
|
||||||
|
const onActivityPointNotificationMessageEvent = useCallback((event: ActivityPointNotificationMessageEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
// bubble for loyalty
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
CreateMessageHook(ActivityPointNotificationMessageEvent, onActivityPointNotificationMessageEvent);
|
||||||
|
|
||||||
|
const onHotelClosesAndWillOpenAtEvent = useCallback((event: HotelClosesAndWillOpenAtEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
NotificationUtilities.handleHotelClosedMessage(parser.openHour, parser.openMinute, parser.userThrowOutAtClose);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
CreateMessageHook(HotelClosesAndWillOpenAtEvent, onHotelClosesAndWillOpenAtEvent);
|
||||||
|
|
||||||
|
const onPetAddedToInventoryEvent = useCallback((event: PetAddedToInventoryEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
const text = LocalizeText('notifications.text.' + (parser.boughtAsGift ? 'petbought' : 'petreceived'));
|
||||||
|
|
||||||
|
let imageUrl: string = null;
|
||||||
|
|
||||||
|
const imageResult = GetRoomEngine().getRoomObjectPetImage(parser.pet.typeId, parser.pet.paletteId, parseInt(parser.pet.color, 16), new Vector3d(45 * 3), 64, null, true);
|
||||||
|
|
||||||
|
if(imageResult) imageUrl = imageResult.getImage().src;
|
||||||
|
|
||||||
|
NotificationUtilities.showSingleBubble(text, NotificationType.PETLEVEL, imageUrl);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
CreateMessageHook(PetAddedToInventoryEvent, onPetAddedToInventoryEvent);
|
||||||
|
|
||||||
const onMOTDNotificationEvent = useCallback((event: MOTDNotificationEvent) =>
|
const onMOTDNotificationEvent = useCallback((event: MOTDNotificationEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
@ -55,38 +132,9 @@ export const NotificationCenterMessageHandler: FC<INotificationCenterMessageHand
|
|||||||
NotificationUtilities.showNotification(parser.type, parser.parameters);
|
NotificationUtilities.showNotification(parser.type, parser.parameters);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onRespectReceivedEvent = useCallback((event: RespectReceivedEvent) =>
|
|
||||||
{
|
|
||||||
const parser = event.getParser();
|
|
||||||
|
|
||||||
if(parser.userId !== GetSessionDataManager().userId) return;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onAchievementNotificationMessageEvent = useCallback((event: AchievementNotificationMessageEvent) =>
|
|
||||||
{
|
|
||||||
const parser = event.getParser();
|
|
||||||
|
|
||||||
const text1 = LocalizeText('achievements.levelup.desc');
|
|
||||||
const badgeName = LocalizeBadgeName(parser.data.badgeCode);
|
|
||||||
const badgeImage = GetSessionDataManager().getBadgeUrl(parser.data.badgeCode);
|
|
||||||
const internalLink = 'questengine/achievements/' + parser.data.category;
|
|
||||||
|
|
||||||
NotificationUtilities.showSingleBubble((text1 + ' ' + badgeName), NotificationType.ACHIEVEMENT, badgeImage, internalLink);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
CreateMessageHook(HabboBroadcastMessageEvent, onHabboBroadcastMessageEvent);
|
|
||||||
CreateMessageHook(ModeratorMessageEvent, onModeratorMessageEvent);
|
|
||||||
CreateMessageHook(MOTDNotificationEvent, onMOTDNotificationEvent);
|
CreateMessageHook(MOTDNotificationEvent, onMOTDNotificationEvent);
|
||||||
CreateMessageHook(HotelWillShutdownEvent, onHotelWillShutdownEvent);
|
CreateMessageHook(HotelWillShutdownEvent, onHotelWillShutdownEvent);
|
||||||
CreateMessageHook(NotificationDialogMessageEvent, onNotificationDialogMessageEvent);
|
CreateMessageHook(NotificationDialogMessageEvent, onNotificationDialogMessageEvent);
|
||||||
CreateMessageHook(RespectReceivedEvent, onRespectReceivedEvent);
|
|
||||||
CreateMessageHook(AchievementNotificationMessageEvent, onAchievementNotificationMessageEvent);
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -7,18 +7,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nitro-notification-center {
|
|
||||||
|
|
||||||
.notification-bubble {
|
|
||||||
pointer-events: all;
|
|
||||||
padding: 2px;
|
|
||||||
background-color: $gable-green;
|
|
||||||
border: 2px solid rgba($white, 0.5);
|
|
||||||
font-size: $font-size-sm;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nitro-notification-center-container {
|
.nitro-notification-center-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
@ -3,10 +3,11 @@ import { NotificationCenterAlertEvent } 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 { NotificationItem } from './common/NotificationItem';
|
||||||
|
import { NotificationType } from './common/NotificationType';
|
||||||
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 { NotificationCenterBroadcastMessageView } from './views/broadcast-message/NotificationCenterBroadcastMessageView';
|
||||||
import { NotificationBubbleView } from './views/notification-bubble/NotificationBubbleView';
|
import { GetBubbleLayout } from './views/bubble-layouts/GetBubbleLayout';
|
||||||
|
|
||||||
export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
||||||
{
|
{
|
||||||
@ -26,7 +27,7 @@ export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
|||||||
const onNotificationBubbleEvent = useCallback((event: NotificationBubbleEvent) =>
|
const onNotificationBubbleEvent = useCallback((event: NotificationBubbleEvent) =>
|
||||||
{
|
{
|
||||||
console.log(event);
|
console.log(event);
|
||||||
const notificationItem = new NotificationItem(event.message, event.notificationType, null, event.linkUrl);
|
const notificationItem = new NotificationItem(event.message, event.notificationType, event.imageUrl, event.linkUrl);
|
||||||
|
|
||||||
setBubbleAlerts(prevValue => [ notificationItem, ...prevValue ]);
|
setBubbleAlerts(prevValue => [ notificationItem, ...prevValue ]);
|
||||||
}, []);
|
}, []);
|
||||||
@ -65,7 +66,19 @@ export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
|||||||
|
|
||||||
const elements: ReactNode[] = [];
|
const elements: ReactNode[] = [];
|
||||||
|
|
||||||
for(const alert of bubbleAlerts) elements.push(<NotificationBubbleView key={ alert.id } notificationItem={ alert } close={ () => closeBubbleAlert(alert) } />);
|
for(const alert of bubbleAlerts)
|
||||||
|
{
|
||||||
|
const element = GetBubbleLayout(alert, () => closeBubbleAlert(alert));
|
||||||
|
|
||||||
|
if(alert.notificationType === NotificationType.CLUBGIFT)
|
||||||
|
{
|
||||||
|
elements.unshift(element);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
elements.push(element);
|
||||||
|
}
|
||||||
|
|
||||||
return elements;
|
return elements;
|
||||||
}, [ bubbleAlerts, closeBubbleAlert ]);
|
}, [ bubbleAlerts, closeBubbleAlert ]);
|
||||||
|
@ -1,10 +1,25 @@
|
|||||||
import { GetConfiguration, GetNitroInstance, LocalizeText } from '../../../api';
|
import { HabboWebTools } from '@nitrots/nitro-renderer';
|
||||||
|
import { CreateLinkEvent, GetConfiguration, GetNitroInstance, LocalizeText } from '../../../api';
|
||||||
|
import { SimpleAlertUIEvent } 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 { NotificationType } from './NotificationType';
|
import { NotificationType } from './NotificationType';
|
||||||
|
|
||||||
export class NotificationUtilities
|
export class NotificationUtilities
|
||||||
{
|
{
|
||||||
|
private static cleanText(text: string): string
|
||||||
|
{
|
||||||
|
return text.replace(/\\r/g, '\r')
|
||||||
|
}
|
||||||
|
|
||||||
|
private static getTimeZeroPadded(time: number): string
|
||||||
|
{
|
||||||
|
const text = ('0' + time);
|
||||||
|
|
||||||
|
return text.substr((text.length - 2), text.length);
|
||||||
|
}
|
||||||
|
|
||||||
private static getMainNotificationConfig(): { [key: string]: { delivery?: string, display?: string; title?: string; image?: string }}
|
private static getMainNotificationConfig(): { [key: string]: { delivery?: string, display?: string; title?: string; image?: string }}
|
||||||
{
|
{
|
||||||
return GetConfiguration<{ [key: string]: { delivery?: string, display?: string; title?: string; image?: string }}>('notification', {});
|
return GetConfiguration<{ [key: string]: { delivery?: string, display?: string; title?: string; image?: string }}>('notification', {});
|
||||||
@ -63,7 +78,7 @@ export class NotificationUtilities
|
|||||||
const isEventLink = (linkUrl && linkUrl.substr(0, 6) === 'event');
|
const isEventLink = (linkUrl && linkUrl.substr(0, 6) === 'event');
|
||||||
const image = this.getNotificationImageUrl(options, type);
|
const image = this.getNotificationImageUrl(options, type);
|
||||||
|
|
||||||
dispatchUiEvent(new NotificationBubbleEvent(message, NotificationType.INFO, image, (isEventLink ? linkUrl.substr(6) : linkUrl)));
|
dispatchUiEvent(new NotificationBubbleEvent(LocalizeText(message), NotificationType.INFO, LocalizeText(image), (isEventLink ? linkUrl.substr(6) : linkUrl)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -75,4 +90,47 @@ export class NotificationUtilities
|
|||||||
{
|
{
|
||||||
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
|
||||||
|
{
|
||||||
|
if(numGifts <= 0) return;
|
||||||
|
|
||||||
|
dispatchUiEvent(new NotificationBubbleEvent(numGifts.toString(), NotificationType.CLUBGIFT, null, 'catalog/open/' + CatalogPageName.CLUB_GIFTS));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static showModeratorMessage(message: string, url: string = null): void
|
||||||
|
{
|
||||||
|
this.simpleAlert(this.cleanText(message), url, LocalizeText('mod.alert.link'), LocalizeText('mod.alert.title'));
|
||||||
|
}
|
||||||
|
|
||||||
|
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.alert(LocalizeText('opening.hours.title'), text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static openUrl(url: string): void
|
||||||
|
{
|
||||||
|
if(url.startsWith('http'))
|
||||||
|
{
|
||||||
|
HabboWebTools.openWebPage(url);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CreateLinkEvent(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
import { NotificationItem } from '../../common/NotificationItem';
|
||||||
|
import { NotificationType } from '../../common/NotificationType';
|
||||||
|
import { NotificationClubGiftBubbleView } from './club-gift/NotificationClubGiftBubbleView';
|
||||||
|
import { NotificationDefaultBubbleView } from './default/NotificationDefaultBubbleView';
|
||||||
|
|
||||||
|
export const GetBubbleLayout = (item: NotificationItem, close: () => void) =>
|
||||||
|
{
|
||||||
|
if(!item) return null;
|
||||||
|
|
||||||
|
const props = { key: item.id, item, close };
|
||||||
|
|
||||||
|
switch(item.notificationType)
|
||||||
|
{
|
||||||
|
case NotificationType.CLUBGIFT:
|
||||||
|
return <NotificationClubGiftBubbleView { ...props } />
|
||||||
|
default:
|
||||||
|
return <NotificationDefaultBubbleView { ...props } />
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import { NotificationItem } from '../../common/NotificationItem';
|
import { NotificationItem } from '../../common/NotificationItem';
|
||||||
|
|
||||||
export interface NotificationBubbleViewProps
|
export interface NotificationBubbleLayoutViewProps
|
||||||
{
|
{
|
||||||
notificationItem: NotificationItem;
|
item: NotificationItem;
|
||||||
close: () => void;
|
close: () => void;
|
||||||
}
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { LocalizeText } from '../../../../../api';
|
||||||
|
import { NotificationBubbleView } from '../../../../../layout';
|
||||||
|
import { CurrencyIcon } from '../../../../shared/currency-icon/CurrencyIcon';
|
||||||
|
import { NotificationUtilities } from '../../../common/NotificationUtilities';
|
||||||
|
import { NotificationBubbleLayoutViewProps } from '../NotificationBubbleLayoutView.types';
|
||||||
|
|
||||||
|
export const NotificationClubGiftBubbleView: FC<NotificationBubbleLayoutViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { item = null, close = null, ...rest } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NotificationBubbleView className="flex-column club-gift" close={ close } { ...rest }>
|
||||||
|
<div className="d-flex mb-1">
|
||||||
|
<CurrencyIcon type="hc" />
|
||||||
|
<span className="ms-1">{ LocalizeText('notifications.text.club_gift') }</span>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex align-items-center justify-content-end">
|
||||||
|
<span className="fw-bold me-1" onClick={ close }>{ LocalizeText('notifications.button.later') }</span>
|
||||||
|
<button type="button" className="btn btn-primary btn-sm" onClick={ () => NotificationUtilities.openUrl(item.linkUrl) }>{ LocalizeText('notifications.button.show_gift_list') }</button>
|
||||||
|
</div>
|
||||||
|
</NotificationBubbleView>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { NotificationBubbleView } from '../../../../../layout';
|
||||||
|
import { NotificationDefaultBubbleViewProps } from './NotificationDefaultBubbleView.types';
|
||||||
|
|
||||||
|
export const NotificationDefaultBubbleView: FC<NotificationDefaultBubbleViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { item = null, close = null, ...rest } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NotificationBubbleView className="d-flex" fadesOut={ false } close={ close } { ...rest }>
|
||||||
|
{ (item.iconUrl && item.iconUrl.length) && <img className="bubble-image no-select" src={ item.iconUrl } alt="" /> }
|
||||||
|
<span>{ item.message }</span>
|
||||||
|
</NotificationBubbleView>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
import { DetailsHTMLAttributes } from 'react';
|
||||||
|
import { NotificationBubbleLayoutViewProps } from '../NotificationBubbleLayoutView.types';
|
||||||
|
|
||||||
|
export interface NotificationDefaultBubbleViewProps extends NotificationBubbleLayoutViewProps, DetailsHTMLAttributes<HTMLDivElement>
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
import { FC, useMemo } from 'react';
|
|
||||||
import { LocalizeText } from '../../../../api';
|
|
||||||
import { NotificationBubbleViewProps } from './NotificationBubbleView.types';
|
|
||||||
|
|
||||||
export const NotificationBubbleView: FC<NotificationBubbleViewProps> = props =>
|
|
||||||
{
|
|
||||||
const { notificationItem = null, close = null } = props;
|
|
||||||
|
|
||||||
const message = useMemo(() =>
|
|
||||||
{
|
|
||||||
return LocalizeText(notificationItem.message);
|
|
||||||
}, [ notificationItem ]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="notification-bubble">
|
|
||||||
{ message }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user