From 34ad458f87b4651dc0329f9c0cb9e9ac069d2f59 Mon Sep 17 00:00:00 2001 From: Bill Date: Fri, 17 Sep 2021 02:39:58 -0400 Subject: [PATCH 1/5] Rename CatalogGiftView --- src/views/catalog/CatalogView.tsx | 4 ++-- src/views/catalog/views/CatalogViews.scss | 2 +- .../gift/{CatalogPageGiftView.scss => CatalogGiftView.scss} | 0 .../gift/{CatalogPageGiftView.tsx => CatalogGiftView.tsx} | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/views/catalog/views/gift/{CatalogPageGiftView.scss => CatalogGiftView.scss} (100%) rename src/views/catalog/views/gift/{CatalogPageGiftView.tsx => CatalogGiftView.tsx} (99%) diff --git a/src/views/catalog/CatalogView.tsx b/src/views/catalog/CatalogView.tsx index d49b167e..d69eb842 100644 --- a/src/views/catalog/CatalogView.tsx +++ b/src/views/catalog/CatalogView.tsx @@ -10,7 +10,7 @@ import { CatalogMode, CatalogViewProps } from './CatalogView.types'; import { BuildCatalogPageTree } from './common/CatalogUtilities'; import { CatalogContextProvider } from './context/CatalogContext'; 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 { CatalogPageView } from './views/page/CatalogPageView'; @@ -214,7 +214,7 @@ export const CatalogView: FC = props => } - + ); } diff --git a/src/views/catalog/views/CatalogViews.scss b/src/views/catalog/views/CatalogViews.scss index d5d8464b..0a5f6295 100644 --- a/src/views/catalog/views/CatalogViews.scss +++ b/src/views/catalog/views/CatalogViews.scss @@ -2,4 +2,4 @@ @import './navigation/CatalogNavigationView'; @import './page/CatalogPageView'; @import './search/CatalogSearchView'; -@import './gift/CatalogPageGiftView'; +@import './gift/CatalogGiftView'; diff --git a/src/views/catalog/views/gift/CatalogPageGiftView.scss b/src/views/catalog/views/gift/CatalogGiftView.scss similarity index 100% rename from src/views/catalog/views/gift/CatalogPageGiftView.scss rename to src/views/catalog/views/gift/CatalogGiftView.scss diff --git a/src/views/catalog/views/gift/CatalogPageGiftView.tsx b/src/views/catalog/views/gift/CatalogGiftView.tsx similarity index 99% rename from src/views/catalog/views/gift/CatalogPageGiftView.tsx rename to src/views/catalog/views/gift/CatalogGiftView.tsx index 1d7a1bf1..d466d5b6 100644 --- a/src/views/catalog/views/gift/CatalogPageGiftView.tsx +++ b/src/views/catalog/views/gift/CatalogGiftView.tsx @@ -10,7 +10,7 @@ import { CurrencyIcon } from '../../../shared/currency-icon/CurrencyIcon'; import { FurniImageView } from '../../../shared/furni-image/FurniImageView'; import { useCatalogContext } from '../../context/CatalogContext'; -export const CatalogPageGiftView: FC<{}> = props => +export const CatalogGiftView: FC<{}> = props => { const { catalogState = null } = useCatalogContext(); const { giftConfiguration = null } = catalogState; From 7ee1a6898780d6e09767a0e87adacf6cffdb4928 Mon Sep 17 00:00:00 2001 From: Bill Date: Fri, 17 Sep 2021 02:40:11 -0400 Subject: [PATCH 2/5] Fix dimmer again --- .../furniture/dimmer/FurnitureDimmerView.tsx | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/views/room/widgets/furniture/dimmer/FurnitureDimmerView.tsx b/src/views/room/widgets/furniture/dimmer/FurnitureDimmerView.tsx index f65f2664..d1f88b64 100644 --- a/src/views/room/widgets/furniture/dimmer/FurnitureDimmerView.tsx +++ b/src/views/room/widgets/furniture/dimmer/FurnitureDimmerView.tsx @@ -55,16 +55,8 @@ export const FurnitureDimmerView: FC<{}> = props => BatchUpdates(() => { - let prevDimmerState = 0; - - setDimmerState(prevValue => - { - setLastDimmerState(prevValue); - - return widgetEvent.state; - }); - - setLastDimmerState(prevDimmerState); + setLastDimmerState(dimmerState); + setDimmerState(widgetEvent.state); setSelectedPresetId(widgetEvent.presetId); setEffectId(widgetEvent.effectId); setSelectedEffectId(widgetEvent.effectId); @@ -73,10 +65,11 @@ export const FurnitureDimmerView: FC<{}> = props => setBrightness(widgetEvent.brightness); setSelectedBrightness(widgetEvent.brightness); }); + return; } } - }, []); + }, [ dimmerState ]); CreateEventDispatcherHook(RoomWidgetUpdateDimmerEvent.PRESETS, eventDispatcher, onNitroEvent); CreateEventDispatcherHook(RoomWidgetUpdateDimmerEvent.HIDE, eventDispatcher, onNitroEvent); @@ -144,6 +137,8 @@ export const FurnitureDimmerView: FC<{}> = props => { if((dimmerState === 0) && (lastDimmerState === 0)) return; + console.log('ye') + widgetHandler.processWidgetMessage(new RoomWidgetDimmerPreviewMessage(selectedColor, selectedBrightness, (selectedEffectId === 2))); }, [ widgetHandler, dimmerState, lastDimmerState, selectedColor, selectedBrightness, selectedEffectId ]); From 4a55aff19cafd0030bdeaa83810ecb9093eb6d3d Mon Sep 17 00:00:00 2001 From: Bill Date: Fri, 17 Sep 2021 02:40:37 -0400 Subject: [PATCH 3/5] Remove console log --- .../page/layout/badge-display/CatalogLayoutBadgeDisplayView.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/views/catalog/views/page/layout/badge-display/CatalogLayoutBadgeDisplayView.tsx b/src/views/catalog/views/page/layout/badge-display/CatalogLayoutBadgeDisplayView.tsx index b36ce01b..4cb90755 100644 --- a/src/views/catalog/views/page/layout/badge-display/CatalogLayoutBadgeDisplayView.tsx +++ b/src/views/catalog/views/page/layout/badge-display/CatalogLayoutBadgeDisplayView.tsx @@ -63,8 +63,6 @@ export const CatalogLayoutBadgeDisplayView: FC Date: Fri, 17 Sep 2021 02:40:54 -0400 Subject: [PATCH 4/5] Fix chat input width resetting --- src/views/room/widgets/chat-input/ChatInputView.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/views/room/widgets/chat-input/ChatInputView.tsx b/src/views/room/widgets/chat-input/ChatInputView.tsx index c1ac2a3b..534dd93c 100644 --- a/src/views/room/widgets/chat-input/ChatInputView.tsx +++ b/src/views/room/widgets/chat-input/ChatInputView.tsx @@ -260,11 +260,18 @@ export const ChatInputView: FC<{}> = props => } }, [ onKeyDownEvent ]); + useEffect(() => + { + if(!inputRef.current) return; + + inputRef.current.parentElement.dataset.value = chatValue; + }, [ chatValue ]); + return ( createPortal(
- { event.target.parentElement.dataset.value = event.target.value; updateChatInput(event.target.value) } } onMouseDown={ event => setInputFocus() } /> + updateChatInput(event.target.value) } onMouseDown={ event => setInputFocus() } />
, document.getElementById('toolbar-chat-input-container')) From 83df995ce3f005cf11a4e956afb81decceb22005 Mon Sep 17 00:00:00 2001 From: Bill Date: Sat, 18 Sep 2021 04:31:08 -0400 Subject: [PATCH 5/5] Update alerts --- src/App.tsx | 1 + ...rtUIEvent.ts => NotificationAlertEvent.ts} | 23 +-- .../NotificationBubbleEvent.ts | 2 +- .../NotificationCenterAddNotificationEvent.ts | 19 --- src/events/notification-center/index.ts | 4 +- src/layout/Layout.scss | 1 + src/layout/index.ts | 1 + .../NotificationAlertView.scss | 8 ++ .../NotificationAlertView.tsx | 17 +++ .../NotificationAlertView.types.ts | 7 + src/layout/notification-alert/index.ts | 2 + src/views/help/HelpMessageHandler.tsx | 27 ++++ src/views/help/HelpView.tsx | 11 ++ src/views/help/common/GetCloseReasonKey.ts | 8 ++ src/views/main/MainView.tsx | 2 + .../NotificationCenterMessageHandler.tsx | 133 ++++++++++++++---- .../NotificationCenterView.scss | 9 -- .../NotificationCenterView.tsx | 60 ++++---- .../common/BroadcastMessageNotification.ts | 4 - .../common/DialogMessageNotification.ts | 24 ---- .../common/HotelWillShutdownNotification.ts | 17 --- .../common/MOTDNotification.ts | 19 --- .../common/ModeratorMessageNotification.ts | 17 --- .../common/Notification.ts | 49 ------- .../common/NotificationAlertItem.ts | 62 ++++++++ .../common/NotificationAlertType.ts | 7 + ...ationItem.ts => NotificationBubbleItem.ts} | 10 +- ...ationType.ts => NotificationBubbleType.ts} | 2 +- .../common/NotificationUtilities.ts | 97 ++++++++----- .../common/ProductImageUtility.ts | 59 ++++++++ .../context/NotificationCenterContext.tsx | 14 -- .../NotificationCenterContext.types.ts | 13 -- .../reducers/NotificationCenterReducer.tsx | 77 ---------- .../NotificationCenterAlertBase.tsx | 19 --- .../NotificationCenterAlertBase.types.ts | 5 - .../views/alert-layouts/GetAlertLayout.tsx | 19 +++ .../NotificationAlertLayoutView.types.ts | 7 + .../default/NotificationDefaultAlertView.tsx | 35 +++++ .../NotificationDefaultAlertView.types.ts | 7 + .../event/NotificationEventAlertView.tsx | 33 +++++ .../event/NotificationEventAlertView.types.ts | 7 + ...NotificationCenterBroadcastMessageView.tsx | 30 ---- ...icationCenterBroadcastMessageView.types.ts | 7 - .../views/bubble-layouts/GetBubbleLayout.tsx | 8 +- .../NotificationBubbleLayoutView.types.ts | 4 +- .../HotelWillShutdownView.tsx | 28 ---- .../HotelWillShutdownView.types.ts | 7 - .../ModeratorMessageView.tsx | 33 ----- .../ModeratorMessageView.types.ts | 7 - .../views/motd/NotificationCenterMotdView.tsx | 10 -- .../motd/NotificationCenterMotdView.types.ts | 7 - .../tray-item/NotificationTrayItemView.tsx | 22 --- .../NotificationTrayItemView.types.ts | 7 - 53 files changed, 555 insertions(+), 553 deletions(-) rename src/events/notification-center/{SimpleAlertUIEvent.ts => NotificationAlertEvent.ts} (52%) delete mode 100644 src/events/notification-center/NotificationCenterAddNotificationEvent.ts create mode 100644 src/layout/notification-alert/NotificationAlertView.scss create mode 100644 src/layout/notification-alert/NotificationAlertView.tsx create mode 100644 src/layout/notification-alert/NotificationAlertView.types.ts create mode 100644 src/layout/notification-alert/index.ts create mode 100644 src/views/help/HelpMessageHandler.tsx create mode 100644 src/views/help/HelpView.tsx create mode 100644 src/views/help/common/GetCloseReasonKey.ts delete mode 100644 src/views/notification-center/common/BroadcastMessageNotification.ts delete mode 100644 src/views/notification-center/common/DialogMessageNotification.ts delete mode 100644 src/views/notification-center/common/HotelWillShutdownNotification.ts delete mode 100644 src/views/notification-center/common/MOTDNotification.ts delete mode 100644 src/views/notification-center/common/ModeratorMessageNotification.ts delete mode 100644 src/views/notification-center/common/Notification.ts create mode 100644 src/views/notification-center/common/NotificationAlertItem.ts create mode 100644 src/views/notification-center/common/NotificationAlertType.ts rename src/views/notification-center/common/{NotificationItem.ts => NotificationBubbleItem.ts} (75%) rename src/views/notification-center/common/{NotificationType.ts => NotificationBubbleType.ts} (95%) create mode 100644 src/views/notification-center/common/ProductImageUtility.ts delete mode 100644 src/views/notification-center/context/NotificationCenterContext.tsx delete mode 100644 src/views/notification-center/context/NotificationCenterContext.types.ts delete mode 100644 src/views/notification-center/reducers/NotificationCenterReducer.tsx delete mode 100644 src/views/notification-center/views/alert-base/NotificationCenterAlertBase.tsx delete mode 100644 src/views/notification-center/views/alert-base/NotificationCenterAlertBase.types.ts create mode 100644 src/views/notification-center/views/alert-layouts/GetAlertLayout.tsx create mode 100644 src/views/notification-center/views/alert-layouts/NotificationAlertLayoutView.types.ts create mode 100644 src/views/notification-center/views/alert-layouts/default/NotificationDefaultAlertView.tsx create mode 100644 src/views/notification-center/views/alert-layouts/default/NotificationDefaultAlertView.types.ts create mode 100644 src/views/notification-center/views/alert-layouts/event/NotificationEventAlertView.tsx create mode 100644 src/views/notification-center/views/alert-layouts/event/NotificationEventAlertView.types.ts delete mode 100644 src/views/notification-center/views/broadcast-message/NotificationCenterBroadcastMessageView.tsx delete mode 100644 src/views/notification-center/views/broadcast-message/NotificationCenterBroadcastMessageView.types.ts delete mode 100644 src/views/notification-center/views/hotel-will-shutdown/HotelWillShutdownView.tsx delete mode 100644 src/views/notification-center/views/hotel-will-shutdown/HotelWillShutdownView.types.ts delete mode 100644 src/views/notification-center/views/moderator-message/ModeratorMessageView.tsx delete mode 100644 src/views/notification-center/views/moderator-message/ModeratorMessageView.types.ts delete mode 100644 src/views/notification-center/views/motd/NotificationCenterMotdView.tsx delete mode 100644 src/views/notification-center/views/motd/NotificationCenterMotdView.types.ts delete mode 100644 src/views/notification-center/views/tray-item/NotificationTrayItemView.tsx delete mode 100644 src/views/notification-center/views/tray-item/NotificationTrayItemView.types.ts diff --git a/src/App.tsx b/src/App.tsx index ae6999e5..439fbc5d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -126,6 +126,7 @@ export const App: FC<{}> = props => return (
+
{ (!isReady || isError) && } diff --git a/src/events/notification-center/SimpleAlertUIEvent.ts b/src/events/notification-center/NotificationAlertEvent.ts similarity index 52% rename from src/events/notification-center/SimpleAlertUIEvent.ts rename to src/events/notification-center/NotificationAlertEvent.ts index d869d0b7..4f64acc9 100644 --- a/src/events/notification-center/SimpleAlertUIEvent.ts +++ b/src/events/notification-center/NotificationAlertEvent.ts @@ -1,29 +1,36 @@ import { NitroEvent } from '@nitrots/nitro-renderer'; -export class SimpleAlertUIEvent extends NitroEvent +export class NotificationAlertEvent extends NitroEvent { - public static ALERT: string = 'SAUE_ALERT'; + public static ALERT: string = 'NAE_ALERT'; - private _message: string; + private _messages: string[]; + private _alertType: string; private _clickUrl: string; private _clickUrlText: string; private _title: string; private _imageUrl: string; - constructor(message: string, clickUrl: string = null, clickUrlText: string = null, title: string = null, imageUrl: string = null) + constructor(messages: string[], alertType: string = null, clickUrl: string = null, clickUrlText: string = null, title: string = null, imageUrl: string = null) { - super(SimpleAlertUIEvent.ALERT); + super(NotificationAlertEvent.ALERT); - this._message = message; + this._messages = messages; + this._alertType = alertType; this._clickUrl = clickUrl; this._clickUrlText = clickUrlText; this._title = title; this._imageUrl = imageUrl; } - public get message(): string + public get messages(): string[] { - return this._message; + return this._messages; + } + + public get alertType(): string + { + return this._alertType; } public get clickUrl(): string diff --git a/src/events/notification-center/NotificationBubbleEvent.ts b/src/events/notification-center/NotificationBubbleEvent.ts index 11a343a2..55383655 100644 --- a/src/events/notification-center/NotificationBubbleEvent.ts +++ b/src/events/notification-center/NotificationBubbleEvent.ts @@ -2,7 +2,7 @@ import { NitroEvent } from '@nitrots/nitro-renderer'; export class NotificationBubbleEvent extends NitroEvent { - public static NEW_BUBBLE: string = 'NNBE_NEW_BUBBLE'; + public static NEW_BUBBLE: string = 'NBE_NEW_BUBBLE'; private _message: string; private _notificationType: string; diff --git a/src/events/notification-center/NotificationCenterAddNotificationEvent.ts b/src/events/notification-center/NotificationCenterAddNotificationEvent.ts deleted file mode 100644 index 200fda47..00000000 --- a/src/events/notification-center/NotificationCenterAddNotificationEvent.ts +++ /dev/null @@ -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; - } -} diff --git a/src/events/notification-center/index.ts b/src/events/notification-center/index.ts index 2951cdfb..cac7d708 100644 --- a/src/events/notification-center/index.ts +++ b/src/events/notification-center/index.ts @@ -1,4 +1,4 @@ -export * from './NotificationCenterAddNotificationEvent'; +export * from './NotificationAlertEvent'; +export * from './NotificationBubbleEvent'; export * from './NotificationCenterAlertEvent'; export * from './NotificationCenterEvent'; -export * from './SimpleAlertUIEvent'; diff --git a/src/layout/Layout.scss b/src/layout/Layout.scss index 3b613a5f..9e435e47 100644 --- a/src/layout/Layout.scss +++ b/src/layout/Layout.scss @@ -27,6 +27,7 @@ @import './loading-habbos/LoadingHabbosView'; @import './loading-spinner/LoadingSpinnerView'; @import './mini-camera/NitroLayoutMiniCameraView'; +@import './notification-alert/NotificationAlertView'; @import './notification-bubble/NotificationBubbleView'; @import './trophy/NitroLayoutTrophyView'; @import './gift-card/NitroLayoutGiftCardView'; diff --git a/src/layout/index.ts b/src/layout/index.ts index f02a74e0..81e87964 100644 --- a/src/layout/index.ts +++ b/src/layout/index.ts @@ -3,6 +3,7 @@ export * from './draggable-window'; export * from './gift-card'; export * from './loading-spinner'; export * from './mini-camera'; +export * from './notification-alert'; export * from './notification-bubble'; export * from './transitions'; export * from './trophy'; diff --git a/src/layout/notification-alert/NotificationAlertView.scss b/src/layout/notification-alert/NotificationAlertView.scss new file mode 100644 index 00000000..d6dbe418 --- /dev/null +++ b/src/layout/notification-alert/NotificationAlertView.scss @@ -0,0 +1,8 @@ +.nitro-alert { + width: 350px; + + .content-area { + min-height: 125px; + max-height: 300px; + } +} diff --git a/src/layout/notification-alert/NotificationAlertView.tsx b/src/layout/notification-alert/NotificationAlertView.tsx new file mode 100644 index 00000000..f5281398 --- /dev/null +++ b/src/layout/notification-alert/NotificationAlertView.tsx @@ -0,0 +1,17 @@ +import { FC } from 'react'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../card'; +import { NotificationAlertViewProps } from './NotificationAlertView.types'; + +export const NotificationAlertView: FC = props => +{ + const { title = '', close = null, className = '', children = null, ...rest } = props; + + return ( + + + + { children } + + + ); +} diff --git a/src/layout/notification-alert/NotificationAlertView.types.ts b/src/layout/notification-alert/NotificationAlertView.types.ts new file mode 100644 index 00000000..9d1817e5 --- /dev/null +++ b/src/layout/notification-alert/NotificationAlertView.types.ts @@ -0,0 +1,7 @@ +import { DetailsHTMLAttributes } from 'react'; + +export interface NotificationAlertViewProps extends DetailsHTMLAttributes +{ + title: string; + close: () => void; +} diff --git a/src/layout/notification-alert/index.ts b/src/layout/notification-alert/index.ts new file mode 100644 index 00000000..91f80b3d --- /dev/null +++ b/src/layout/notification-alert/index.ts @@ -0,0 +1,2 @@ +export * from './NotificationAlertView'; +export * from './NotificationAlertView.types'; diff --git a/src/views/help/HelpMessageHandler.tsx b/src/views/help/HelpMessageHandler.tsx new file mode 100644 index 00000000..f71634b7 --- /dev/null +++ b/src/views/help/HelpMessageHandler.tsx @@ -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[] = null; +let petMsgFragments: Map[] = 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; +} diff --git a/src/views/help/HelpView.tsx b/src/views/help/HelpView.tsx new file mode 100644 index 00000000..4917c713 --- /dev/null +++ b/src/views/help/HelpView.tsx @@ -0,0 +1,11 @@ +import { FC } from 'react'; +import { HelpMessageHandler } from './HelpMessageHandler'; + +export const HelpView: FC<{}> = props => +{ + return ( + <> + + + ); +} diff --git a/src/views/help/common/GetCloseReasonKey.ts b/src/views/help/common/GetCloseReasonKey.ts new file mode 100644 index 00000000..520d14fd --- /dev/null +++ b/src/views/help/common/GetCloseReasonKey.ts @@ -0,0 +1,8 @@ +export const GetCloseReasonKey = (code: number) => +{ + if(code === 1) return 'useless'; + + if(code === 2) return 'abusive'; + + return 'resolved'; +} diff --git a/src/views/main/MainView.tsx b/src/views/main/MainView.tsx index 68269e58..49e28a61 100644 --- a/src/views/main/MainView.tsx +++ b/src/views/main/MainView.tsx @@ -9,6 +9,7 @@ import { CameraWidgetView } from '../camera/CameraWidgetView'; import { CatalogView } from '../catalog/CatalogView'; import { FriendsView } from '../friends/FriendsView'; import { GroupsView } from '../groups/GroupsView'; +import { HelpView } from '../help/HelpView'; import { HotelView } from '../hotel-view/HotelView'; import { InventoryView } from '../inventory/InventoryView'; import { ModToolsView } from '../mod-tools/ModToolsView'; @@ -69,6 +70,7 @@ export const MainView: FC = props => +
); } diff --git a/src/views/notification-center/NotificationCenterMessageHandler.tsx b/src/views/notification-center/NotificationCenterMessageHandler.tsx index de974b13..9afc098d 100644 --- a/src/views/notification-center/NotificationCenterMessageHandler.tsx +++ b/src/views/notification-center/NotificationCenterMessageHandler.tsx @@ -1,20 +1,14 @@ -import { AchievementNotificationMessageEvent, ActivityPointNotificationMessageEvent, ClubGiftNotificationEvent, HabboBroadcastMessageEvent, HotelClosesAndWillOpenAtEvent, HotelWillShutdownEvent, ModeratorMessageEvent, MOTDNotificationEvent, NotificationDialogMessageEvent, PetAddedToInventoryEvent, RespectReceivedEvent, RoomEnterEvent, Vector3d } from '@nitrots/nitro-renderer'; +import { AchievementNotificationMessageEvent, ActivityPointNotificationMessageEvent, ClubGiftNotificationEvent, ClubGiftSelectedEvent, HabboBroadcastMessageEvent, HotelClosedAndOpensEvent, HotelClosesAndWillOpenAtEvent, HotelWillCloseInMinutesEvent, InfoFeedEnableMessageEvent, MaintenanceStatusMessageEvent, ModeratorCautionEvent, ModeratorMessageEvent, MOTDNotificationEvent, NotificationDialogMessageEvent, PetLevelNotificationEvent, PetReceivedMessageEvent, RespectReceivedEvent, RoomEnterEvent, UserBannedMessageEvent, Vector3d } from '@nitrots/nitro-renderer'; import { FC, useCallback } from 'react'; -import { GetRoomEngine, GetSessionDataManager, LocalizeBadgeName, LocalizeText } from '../../api'; -import { NotificationCenterAlertEvent } from '../../events'; -import { dispatchUiEvent } from '../../hooks/events'; +import { GetConfiguration, GetRoomEngine, GetSessionDataManager, LocalizeBadgeName, LocalizeText } from '../../api'; import { CreateMessageHook } from '../../hooks/messages'; -import { HotelWillShutdownNotification } from './common/HotelWillShutdownNotification'; -import { NotificationType } from './common/NotificationType'; +import { NotificationBubbleType } from './common/NotificationBubbleType'; import { NotificationUtilities } from './common/NotificationUtilities'; -import { useNotificationCenterContext } from './context/NotificationCenterContext'; +import { ProductImageUtility } from './common/ProductImageUtility'; import { INotificationCenterMessageHandlerProps } from './NotificationCenterMessageHandler.types'; -import { NotificationCenterActions } from './reducers/NotificationCenterReducer'; export const NotificationCenterMessageHandler: FC = props => { - const { dispatchNotificationCenterState = null } = useNotificationCenterContext(); - const onRespectReceivedEvent = useCallback((event: RespectReceivedEvent) => { const parser = event.getParser(); @@ -24,8 +18,8 @@ export const NotificationCenterMessageHandler: FC('currency.asset.icon.url', '').replace('%type%', parser.type.toString()); + break; + } + + NotificationUtilities.showSingleBubble(LocalizeText('notifications.text.loyalty.received', [ 'amount' ], [ parser.amountChanged.toString() ]), NotificationBubbleType.INFO, imageUrl); }, []); CreateMessageHook(ActivityPointNotificationMessageEvent, onActivityPointNotificationMessageEvent); + const onUserBannedMessageEvent = useCallback((event: UserBannedMessageEvent) => + { + const parser = event.getParser(); + + NotificationUtilities.handleUserBannedMessage(parser.message); + }, []); + + CreateMessageHook(UserBannedMessageEvent, onUserBannedMessageEvent); + const onHotelClosesAndWillOpenAtEvent = useCallback((event: HotelClosesAndWillOpenAtEvent) => { const parser = event.getParser(); @@ -89,7 +103,7 @@ export const NotificationCenterMessageHandler: FC + const onPetReceivedMessageEvent = useCallback((event: PetReceivedMessageEvent) => { const parser = event.getParser(); @@ -101,10 +115,10 @@ export const NotificationCenterMessageHandler: FC { @@ -119,24 +133,67 @@ export const NotificationCenterMessageHandler: FC + const onPetLevelNotificationEvent = useCallback((event: PetLevelNotificationEvent) => { const parser = event.getParser(); - dispatchNotificationCenterState({ - type: NotificationCenterActions.ADD_NOTIFICATION, - payload: { - notification: new HotelWillShutdownNotification(parser.minutes) - } - }); - }, [ dispatchNotificationCenterState ]); + let imageUrl: string = null; - CreateMessageHook(HotelWillShutdownEvent, onHotelWillShutdownEvent); + const imageResult = GetRoomEngine().getRoomObjectPetImage(parser.figureData.typeId, parser.figureData.paletteId, parseInt(parser.figureData.color, 16), new Vector3d(45 * 3), 64, null, true); + + if(imageResult) imageUrl = imageResult.getImage().src; + + NotificationUtilities.showSingleBubble(LocalizeText('notifications.text.petlevel', [ 'pet_name', 'level' ], [ parser.petName, parser.level.toString() ]), NotificationBubbleType.PETLEVEL, imageUrl); + }, []); + + CreateMessageHook(PetLevelNotificationEvent, onPetLevelNotificationEvent); + + const onInfoFeedEnableMessageEvent = useCallback((event: InfoFeedEnableMessageEvent) => + { + const parser = event.getParser(); + + NotificationUtilities.BUBBLES_DISABLED = !(parser.enabled); + }, []); + + CreateMessageHook(InfoFeedEnableMessageEvent, onInfoFeedEnableMessageEvent); + + const onClubGiftSelectedEvent = useCallback((event: ClubGiftSelectedEvent) => + { + const parser = event.getParser(); + + if(!parser.products || !parser.products.length) return; + + const productData = parser.products[0]; + + if(!productData) return; + + NotificationUtilities.showSingleBubble(LocalizeText('notifications.text.club_gift.selected'), NotificationBubbleType.INFO, ProductImageUtility.getProductImageUrl(productData.productType, productData.furniClassId, productData.extraParam)) + }, []); + + CreateMessageHook(ClubGiftSelectedEvent, onClubGiftSelectedEvent); + + const onMaintenanceStatusMessageEvent = useCallback((event: MaintenanceStatusMessageEvent) => + { + const parser = event.getParser(); + + NotificationUtilities.handleHotelMaintenanceMessage(parser.minutesUntilMaintenance, parser.duration); + }, []); + + CreateMessageHook(MaintenanceStatusMessageEvent, onMaintenanceStatusMessageEvent); + + const onModeratorCautionEvent = useCallback((event: ModeratorCautionEvent) => + { + const parser = event.getParser(); + + NotificationUtilities.handleModeratorCaution(parser.message, parser.url); + }, []); + + CreateMessageHook(ModeratorCautionEvent, onModeratorCautionEvent); const onNotificationDialogMessageEvent = useCallback((event: NotificationDialogMessageEvent) => { @@ -147,5 +204,23 @@ export const NotificationCenterMessageHandler: FC + { + 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; } diff --git a/src/views/notification-center/NotificationCenterView.scss b/src/views/notification-center/NotificationCenterView.scss index 78a94d63..671ea3e7 100644 --- a/src/views/notification-center/NotificationCenterView.scss +++ b/src/views/notification-center/NotificationCenterView.scss @@ -1,12 +1,3 @@ -.nitro-alert { - width: 350px; - - .content-area { - min-height: 125px; - max-height: 300px; - } -} - .nitro-notification-center-container { position: absolute; top: 0; diff --git a/src/views/notification-center/NotificationCenterView.tsx b/src/views/notification-center/NotificationCenterView.tsx index ace8d3e4..0367b604 100644 --- a/src/views/notification-center/NotificationCenterView.tsx +++ b/src/views/notification-center/NotificationCenterView.tsx @@ -1,40 +1,42 @@ import { FC, ReactNode, useCallback, useMemo, useState } from 'react'; -import { NotificationCenterAlertEvent } from '../../events'; +import { createPortal } from 'react-dom'; +import { NotificationAlertEvent } from '../../events'; import { NotificationBubbleEvent } from '../../events/notification-center/NotificationBubbleEvent'; import { useUiEvent } from '../../hooks/events'; -import { NotificationItem } from './common/NotificationItem'; -import { NotificationType } from './common/NotificationType'; +import { NotificationAlertItem } from './common/NotificationAlertItem'; +import { NotificationBubbleItem } from './common/NotificationBubbleItem'; +import { NotificationBubbleType } from './common/NotificationBubbleType'; import { NotificationCenterMessageHandler } from './NotificationCenterMessageHandler'; import { NotificationCenterViewProps } from './NotificationCenterView.types'; -import { NotificationCenterBroadcastMessageView } from './views/broadcast-message/NotificationCenterBroadcastMessageView'; +import { GetAlertLayout } from './views/alert-layouts/GetAlertLayout'; import { GetBubbleLayout } from './views/bubble-layouts/GetBubbleLayout'; export const NotificationCenterView: FC = props => { - const [ alerts, setAlerts ] = useState([]); - const [ bubbleAlerts, setBubbleAlerts ] = useState([]); + const [ alerts, setAlerts ] = useState([]); + const [ bubbleAlerts, setBubbleAlerts ] = useState([]); - const onNotificationCenterAlertEvent = useCallback((event: NotificationCenterAlertEvent) => + const onNotificationAlertEvent = useCallback((event: NotificationAlertEvent) => { - setAlerts(prevValue => - { - return [ ...prevValue, event ]; - }); + console.log(event); + const alertItem = new NotificationAlertItem(event.messages, event.alertType, event.clickUrl, event.clickUrlText, event.title, event.imageUrl); + + setAlerts(prevValue => [ alertItem, ...prevValue ]); }, []); - useUiEvent(NotificationCenterAlertEvent.HOTEL_ALERT, onNotificationCenterAlertEvent); + useUiEvent(NotificationAlertEvent.ALERT, onNotificationAlertEvent); const onNotificationBubbleEvent = useCallback((event: NotificationBubbleEvent) => { console.log(event); - const notificationItem = new NotificationItem(event.message, event.notificationType, event.imageUrl, event.linkUrl); + const notificationItem = new NotificationBubbleItem(event.message, event.notificationType, event.imageUrl, event.linkUrl); setBubbleAlerts(prevValue => [ notificationItem, ...prevValue ]); }, []); useUiEvent(NotificationBubbleEvent.NEW_BUBBLE, onNotificationBubbleEvent); - const closeAlert = useCallback((alert: NotificationCenterAlertEvent) => + const closeAlert = useCallback((alert: NotificationAlertItem) => { setAlerts(prevValue => { @@ -47,7 +49,7 @@ export const NotificationCenterView: FC = props => }); }, []); - const closeBubbleAlert = useCallback((item: NotificationItem) => + const closeBubbleAlert = useCallback((item: NotificationBubbleItem) => { setBubbleAlerts(prevValue => { @@ -60,6 +62,22 @@ export const NotificationCenterView: FC = props => }) }, []); + const getAlerts = useMemo(() => + { + if(!alerts || !alerts.length) return null; + + const elements: ReactNode[] = []; + + for(const alert of alerts) + { + const element = GetAlertLayout(alert, () => closeAlert(alert)); + + elements.push(element); + } + + return elements; + }, [ alerts, closeAlert ]); + const getBubbleAlerts = useMemo(() => { if(!bubbleAlerts || !bubbleAlerts.length) return null; @@ -70,7 +88,7 @@ export const NotificationCenterView: FC = props => { const element = GetBubbleLayout(alert, () => closeBubbleAlert(alert)); - if(alert.notificationType === NotificationType.CLUBGIFT) + if(alert.notificationType === NotificationBubbleType.CLUBGIFT) { elements.unshift(element); @@ -89,15 +107,7 @@ export const NotificationCenterView: FC = props =>
{ getBubbleAlerts }
- { (alerts.length > 0) && alerts.map((alert, index) => - { - switch(alert.type) - { - case NotificationCenterAlertEvent.HOTEL_ALERT: - default: - return closeAlert(alert) } />; - } - })} + { createPortal(getAlerts, document.getElementById('nitro-alerts-container')) } ); } diff --git a/src/views/notification-center/common/BroadcastMessageNotification.ts b/src/views/notification-center/common/BroadcastMessageNotification.ts deleted file mode 100644 index ddf0fa0d..00000000 --- a/src/views/notification-center/common/BroadcastMessageNotification.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { NitroNotification } from './Notification'; - -export class BroadcastMessageNotification extends NitroNotification -{} diff --git a/src/views/notification-center/common/DialogMessageNotification.ts b/src/views/notification-center/common/DialogMessageNotification.ts deleted file mode 100644 index a3201658..00000000 --- a/src/views/notification-center/common/DialogMessageNotification.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { NitroNotification } from './Notification'; - -export class DialogMessageNotification extends NitroNotification -{ - private _type: string; - private _parameters: Map; - - constructor(type: string, parameters: Map) - { - super(); - this._type = type; - this._parameters = parameters; - } - - public get type(): string - { - return this._type; - } - - public get parameters(): Map - { - return this._parameters; - } -} diff --git a/src/views/notification-center/common/HotelWillShutdownNotification.ts b/src/views/notification-center/common/HotelWillShutdownNotification.ts deleted file mode 100644 index 9f30c1ae..00000000 --- a/src/views/notification-center/common/HotelWillShutdownNotification.ts +++ /dev/null @@ -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; - } -} diff --git a/src/views/notification-center/common/MOTDNotification.ts b/src/views/notification-center/common/MOTDNotification.ts deleted file mode 100644 index f543507d..00000000 --- a/src/views/notification-center/common/MOTDNotification.ts +++ /dev/null @@ -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, '
')); - } - - public get messages(): string[] - { - return this._messages; - } -} diff --git a/src/views/notification-center/common/ModeratorMessageNotification.ts b/src/views/notification-center/common/ModeratorMessageNotification.ts deleted file mode 100644 index ed324b11..00000000 --- a/src/views/notification-center/common/ModeratorMessageNotification.ts +++ /dev/null @@ -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; - } -} diff --git a/src/views/notification-center/common/Notification.ts b/src/views/notification-center/common/Notification.ts deleted file mode 100644 index 2f170cce..00000000 --- a/src/views/notification-center/common/Notification.ts +++ /dev/null @@ -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, '
'); - } - - 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; - } -} diff --git a/src/views/notification-center/common/NotificationAlertItem.ts b/src/views/notification-center/common/NotificationAlertItem.ts new file mode 100644 index 00000000..b3432276 --- /dev/null +++ b/src/views/notification-center/common/NotificationAlertItem.ts @@ -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; + } +} diff --git a/src/views/notification-center/common/NotificationAlertType.ts b/src/views/notification-center/common/NotificationAlertType.ts new file mode 100644 index 00000000..9a4b192b --- /dev/null +++ b/src/views/notification-center/common/NotificationAlertType.ts @@ -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'; +} diff --git a/src/views/notification-center/common/NotificationItem.ts b/src/views/notification-center/common/NotificationBubbleItem.ts similarity index 75% rename from src/views/notification-center/common/NotificationItem.ts rename to src/views/notification-center/common/NotificationBubbleItem.ts index 9387db74..fe90dab7 100644 --- a/src/views/notification-center/common/NotificationItem.ts +++ b/src/views/notification-center/common/NotificationBubbleItem.ts @@ -1,6 +1,6 @@ -import { NotificationType } from './NotificationType'; +import { NotificationBubbleType } from './NotificationBubbleType'; -export class NotificationItem +export class NotificationBubbleItem { private static ITEM_ID: number = -1; @@ -10,11 +10,11 @@ export class NotificationItem private _iconUrl: string; private _linkUrl: string; - constructor(message: string, notificationType: string = NotificationType.INFO, iconUrl: string = null, linkUrl: string = null) + constructor(message: string, notificationType: string = NotificationBubbleType.INFO, iconUrl: string = null, linkUrl: string = null) { - NotificationItem.ITEM_ID += 1; + NotificationBubbleItem.ITEM_ID += 1; - this._id = NotificationItem.ITEM_ID; + this._id = NotificationBubbleItem.ITEM_ID; this._message = message; this._notificationType = notificationType; this._iconUrl = iconUrl; diff --git a/src/views/notification-center/common/NotificationType.ts b/src/views/notification-center/common/NotificationBubbleType.ts similarity index 95% rename from src/views/notification-center/common/NotificationType.ts rename to src/views/notification-center/common/NotificationBubbleType.ts index dff016d8..cce38f5b 100644 --- a/src/views/notification-center/common/NotificationType.ts +++ b/src/views/notification-center/common/NotificationBubbleType.ts @@ -1,4 +1,4 @@ -export class NotificationType +export class NotificationBubbleType { public static FRIENDOFFLINE: string = 'friendoffline'; public static FRIENDONLINE: string = 'friendonline'; diff --git a/src/views/notification-center/common/NotificationUtilities.ts b/src/views/notification-center/common/NotificationUtilities.ts index a80247b4..c4dd1bd9 100644 --- a/src/views/notification-center/common/NotificationUtilities.ts +++ b/src/views/notification-center/common/NotificationUtilities.ts @@ -1,10 +1,11 @@ import { HabboWebTools, RoomEnterEffect } from '@nitrots/nitro-renderer'; import { CreateLinkEvent, GetConfiguration, GetNitroInstance, LocalizeText } from '../../../api'; -import { SimpleAlertUIEvent } from '../../../events'; +import { NotificationAlertEvent } from '../../../events'; import { NotificationBubbleEvent } from '../../../events/notification-center/NotificationBubbleEvent'; import { dispatchUiEvent } from '../../../hooks'; import { CatalogPageName } from '../../catalog/common/CatalogPageName'; -import { NotificationType } from './NotificationType'; +import { NotificationAlertType } from './NotificationAlertType'; +import { NotificationBubbleType } from './NotificationBubbleType'; export class NotificationUtilities { @@ -12,6 +13,8 @@ export class NotificationUtilities private static MODERATION_DISCLAIMER_DELAY_MS: number = 5000; private static MODERATION_DISCLAIMER_TIMEOUT: ReturnType = null; + public static BUBBLES_DISABLED: boolean = false; + private static cleanText(text: string): string { return text.replace(/\\r/g, '\r') @@ -68,62 +71,92 @@ export class NotificationUtilities const configuration = this.getNotificationConfig(('notification.' + type)); - if(configuration) - { - for(const key in configuration) options.set(key, configuration[key]); - } + if(configuration) for(const key in configuration) options.set(key, configuration[key]); console.log(options); + const title = this.getNotificationPart(options, type, 'title', true); + const message = this.getNotificationPart(options, type, 'message', true).replace(/\\r/g, '\r'); + const linkTitle = this.getNotificationPart(options, type, 'linkTitle', false); + const linkUrl = this.getNotificationPart(options, type, 'linkUrl', false); + const image = this.getNotificationImageUrl(options, type); + if(options.get('display') === 'BUBBLE') { - const message = this.getNotificationPart(options, type, 'message', true); - const linkUrl = this.getNotificationPart(options, type, 'linkUrl', false); - const isEventLink = (linkUrl && linkUrl.substr(0, 6) === 'event'); - const image = this.getNotificationImageUrl(options, type); - - dispatchUiEvent(new NotificationBubbleEvent(LocalizeText(message), NotificationType.INFO, LocalizeText(image), (isEventLink ? linkUrl.substr(6) : linkUrl))); + this.showSingleBubble(LocalizeText(message), NotificationBubbleType.INFO, LocalizeText(image), linkUrl); } else { - + this.simpleAlert(message, NotificationAlertType.EVENT, linkUrl, linkTitle, title, image); } } public static showSingleBubble(message: string, type: string, imageUrl: string = null, internalLink: string = null): void { + if(this.BUBBLES_DISABLED) return; + dispatchUiEvent(new NotificationBubbleEvent(message, type, imageUrl, internalLink)); } - public static simpleAlert(message: string, clickUrl: string = null, clickUrlText: string = null, title: string = null, imageUrl: string = null): void - { - if(!title || !title.length) title = LocalizeText('notifications.broadcast.title'); - - dispatchUiEvent(new SimpleAlertUIEvent(message, clickUrl, clickUrlText, title, imageUrl)); - } - - public static alert(title: string, message: string): void - { - dispatchUiEvent(new SimpleAlertUIEvent(message, null, null, title, null)); - } - public static showClubGiftNotification(numGifts: number): void { if(numGifts <= 0) return; - dispatchUiEvent(new NotificationBubbleEvent(numGifts.toString(), NotificationType.CLUBGIFT, null, 'catalog/open/' + CatalogPageName.CLUB_GIFTS)); + this.showSingleBubble(numGifts.toString(), NotificationBubbleType.CLUBGIFT, null, ('catalog/open/' + CatalogPageName.CLUB_GIFTS)); } - public static showModeratorMessage(message: string, url: string = null): void + public static handleMOTD(messages: string[]): void { - this.simpleAlert(this.cleanText(message), url, LocalizeText('mod.alert.link'), LocalizeText('mod.alert.title')); + messages = messages.map(message => this.cleanText(message)); + + dispatchUiEvent(new NotificationAlertEvent(messages, NotificationAlertType.MOTD, null, null, LocalizeText('notifications.motd.title'))); + } + + public static simpleAlert(message: string, type: string, clickUrl: string = null, clickUrlText: string = null, title: string = null, imageUrl: string = null): void + { + if(!title || !title.length) title = LocalizeText('notifications.broadcast.title'); + + dispatchUiEvent(new NotificationAlertEvent([ this.cleanText(message) ], type, clickUrl, clickUrlText, title, imageUrl)); + } + + public static showModeratorMessage(message: string, url: string = null, showHabboWay: boolean = true): void + { + this.simpleAlert(message, NotificationAlertType.MODERATION, url, LocalizeText('mod.alert.link'), LocalizeText('mod.alert.title')); + } + + public static handleModeratorCaution(message: string, url: string = null): void + { + this.showModeratorMessage(message, url); + } + + public static handleModeratorMessage(message: string, url: string = null): void + { + this.showModeratorMessage(message, url, false); + } + + public static handleUserBannedMessage(message: string): void + { + this.showModeratorMessage(message); } public static handleHotelClosedMessage(open: number, minute: number, thrownOut: boolean): void { - const text: string = LocalizeText(('opening.hours.' + (thrownOut ? 'disconnected' : 'closed')), [ 'h', 'm'], [ this.getTimeZeroPadded(open), this.getTimeZeroPadded(minute) ]);; + this.simpleAlert( LocalizeText(('opening.hours.' + (thrownOut ? 'disconnected' : 'closed')), [ 'h', 'm'], [ this.getTimeZeroPadded(open), this.getTimeZeroPadded(minute) ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title')); + } - this.alert(LocalizeText('opening.hours.title'), text); + public static handleHotelMaintenanceMessage(minutesUntilMaintenance: number, duration: number): void + { + this.simpleAlert(LocalizeText('maintenance.shutdown', [ 'm', 'd' ], [ minutesUntilMaintenance.toString(), duration.toString() ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title')); + } + + public static handleHotelClosingMessage(minutes: number): void + { + this.simpleAlert(LocalizeText('opening.hours.shutdown', [ 'm' ], [ minutes.toString() ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title')); + } + + public static handleLoginFailedHotelClosedMessage(openHour: number, openMinutes: number): void + { + this.simpleAlert(LocalizeText('opening.hours.disconnected', [ 'h', 'm' ], [ openHour.toString(), openMinutes.toString() ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title')); } public static openUrl(url: string): void @@ -134,7 +167,7 @@ export class NotificationUtilities } else { - CreateLinkEvent(url); + CreateLinkEvent(url.substring(6)); } } @@ -153,7 +186,7 @@ export class NotificationUtilities { if(this.MODERATION_DISCLAIMER_SHOWN) return; - this.showSingleBubble(LocalizeText('mod.chatdisclaimer'), NotificationType.INFO); + this.showSingleBubble(LocalizeText('mod.chatdisclaimer'), NotificationBubbleType.INFO); this.MODERATION_DISCLAIMER_SHOWN = true; } diff --git a/src/views/notification-center/common/ProductImageUtility.ts b/src/views/notification-center/common/ProductImageUtility.ts new file mode 100644 index 00000000..9078754c --- /dev/null +++ b/src/views/notification-center/common/ProductImageUtility.ts @@ -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; + } +} diff --git a/src/views/notification-center/context/NotificationCenterContext.tsx b/src/views/notification-center/context/NotificationCenterContext.tsx deleted file mode 100644 index 036cd97b..00000000 --- a/src/views/notification-center/context/NotificationCenterContext.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createContext, FC, useContext } from 'react'; -import { INotificationCenterContext, NotificationCenterContextProps } from './NotificationCenterContext.types'; - -const NotificationCenterContext = createContext({ - notificationCenterState: null, - dispatchNotificationCenterState: null -}); - -export const NotificationCenterContextProvider: FC = props => -{ - return { props.children } -} - -export const useNotificationCenterContext = () => useContext(NotificationCenterContext); diff --git a/src/views/notification-center/context/NotificationCenterContext.types.ts b/src/views/notification-center/context/NotificationCenterContext.types.ts deleted file mode 100644 index 8e5358f4..00000000 --- a/src/views/notification-center/context/NotificationCenterContext.types.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Dispatch, ProviderProps } from 'react'; -import { INotificationCenterAction, INotificationCenterState } from '../reducers/NotificationCenterReducer'; - -export interface INotificationCenterContext -{ - notificationCenterState: INotificationCenterState; - dispatchNotificationCenterState: Dispatch; -} - -export interface NotificationCenterContextProps extends ProviderProps -{ - -} diff --git a/src/views/notification-center/reducers/NotificationCenterReducer.tsx b/src/views/notification-center/reducers/NotificationCenterReducer.tsx deleted file mode 100644 index 8d861033..00000000 --- a/src/views/notification-center/reducers/NotificationCenterReducer.tsx +++ /dev/null @@ -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 = (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; - } -} diff --git a/src/views/notification-center/views/alert-base/NotificationCenterAlertBase.tsx b/src/views/notification-center/views/alert-base/NotificationCenterAlertBase.tsx deleted file mode 100644 index e071e39b..00000000 --- a/src/views/notification-center/views/alert-base/NotificationCenterAlertBase.tsx +++ /dev/null @@ -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 = props => -{ - const { headerText = LocalizeText('mod.alert.title'), onClose = null, children = null } = props; - - return ( - - - - { children } - - - ); -} diff --git a/src/views/notification-center/views/alert-base/NotificationCenterAlertBase.types.ts b/src/views/notification-center/views/alert-base/NotificationCenterAlertBase.types.ts deleted file mode 100644 index e7c08d27..00000000 --- a/src/views/notification-center/views/alert-base/NotificationCenterAlertBase.types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface NotificationCenterAlertBaseProps -{ - headerText?: string; - onClose: () => void; -} diff --git a/src/views/notification-center/views/alert-layouts/GetAlertLayout.tsx b/src/views/notification-center/views/alert-layouts/GetAlertLayout.tsx new file mode 100644 index 00000000..fb774c6e --- /dev/null +++ b/src/views/notification-center/views/alert-layouts/GetAlertLayout.tsx @@ -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 + default: + return + } +} diff --git a/src/views/notification-center/views/alert-layouts/NotificationAlertLayoutView.types.ts b/src/views/notification-center/views/alert-layouts/NotificationAlertLayoutView.types.ts new file mode 100644 index 00000000..57c77873 --- /dev/null +++ b/src/views/notification-center/views/alert-layouts/NotificationAlertLayoutView.types.ts @@ -0,0 +1,7 @@ +import { NotificationAlertItem } from '../../common/NotificationAlertItem'; + +export interface NotificationAlertLayoutViewProps +{ + item: NotificationAlertItem; + close: () => void; +} diff --git a/src/views/notification-center/views/alert-layouts/default/NotificationDefaultAlertView.tsx b/src/views/notification-center/views/alert-layouts/default/NotificationDefaultAlertView.tsx new file mode 100644 index 00000000..5b567410 --- /dev/null +++ b/src/views/notification-center/views/alert-layouts/default/NotificationDefaultAlertView.tsx @@ -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 = props => +{ + const { item = null, close = null, ...rest } = props; + + const visitUrl = useCallback(() => + { + NotificationUtilities.openUrl(item.clickUrl); + + close(); + }, [ item, close ]); + + return ( + + { (item.messages.length > 0) && item.messages.map((message, index) => + { + const htmlText = message.replace(/\r\n|\r|\n/g, '
'); + + return ( +
+ ); + }) } +
+ +
+ { item.clickUrl && item.clickUrl.length && + } + + ); +} diff --git a/src/views/notification-center/views/alert-layouts/default/NotificationDefaultAlertView.types.ts b/src/views/notification-center/views/alert-layouts/default/NotificationDefaultAlertView.types.ts new file mode 100644 index 00000000..287d8ca3 --- /dev/null +++ b/src/views/notification-center/views/alert-layouts/default/NotificationDefaultAlertView.types.ts @@ -0,0 +1,7 @@ +import { DetailsHTMLAttributes } from 'react'; +import { NotificationAlertLayoutViewProps } from '../NotificationAlertLayoutView.types'; + +export interface NotificationDefaultAlertViewProps extends NotificationAlertLayoutViewProps, DetailsHTMLAttributes +{ + +} diff --git a/src/views/notification-center/views/alert-layouts/event/NotificationEventAlertView.tsx b/src/views/notification-center/views/alert-layouts/event/NotificationEventAlertView.tsx new file mode 100644 index 00000000..8910e22e --- /dev/null +++ b/src/views/notification-center/views/alert-layouts/event/NotificationEventAlertView.tsx @@ -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 = props => +{ + const { item = null, close = null, ...rest } = props; + + const visitUrl = useCallback(() => + { + NotificationUtilities.openUrl(item.clickUrl); + + close(); + }, [ item, close ]); + + return ( + + { (item.messages.length > 0) && item.messages.map((message, index) => + { + const htmlText = message.replace(/\r\n|\r|\n/g, '
'); + + return ( +
+ ); + }) } +
+ +
+ + ); +} diff --git a/src/views/notification-center/views/alert-layouts/event/NotificationEventAlertView.types.ts b/src/views/notification-center/views/alert-layouts/event/NotificationEventAlertView.types.ts new file mode 100644 index 00000000..1d8b2906 --- /dev/null +++ b/src/views/notification-center/views/alert-layouts/event/NotificationEventAlertView.types.ts @@ -0,0 +1,7 @@ +import { DetailsHTMLAttributes } from 'react'; +import { NotificationAlertLayoutViewProps } from '../NotificationAlertLayoutView.types'; + +export interface NotificationEventAlertViewProps extends NotificationAlertLayoutViewProps, DetailsHTMLAttributes +{ + +} diff --git a/src/views/notification-center/views/broadcast-message/NotificationCenterBroadcastMessageView.tsx b/src/views/notification-center/views/broadcast-message/NotificationCenterBroadcastMessageView.tsx deleted file mode 100644 index 04908525..00000000 --- a/src/views/notification-center/views/broadcast-message/NotificationCenterBroadcastMessageView.tsx +++ /dev/null @@ -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 = props => -{ - const { notification = null, onClose = null } = props; - - const message = useMemo(() => - { - let finalMessage = ''; - - notification.message.forEach(message => - { - finalMessage += message.replace(/\r\n|\r|\n/g, '
'); - }); - - return finalMessage; - }, [ notification ]); - - return ( - -
-
- -
- - ); -}; diff --git a/src/views/notification-center/views/broadcast-message/NotificationCenterBroadcastMessageView.types.ts b/src/views/notification-center/views/broadcast-message/NotificationCenterBroadcastMessageView.types.ts deleted file mode 100644 index bd89dd38..00000000 --- a/src/views/notification-center/views/broadcast-message/NotificationCenterBroadcastMessageView.types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NotificationCenterAlertEvent } from '../../../../events'; - -export class NotificationCenterBroadcastMessageViewProps -{ - notification: NotificationCenterAlertEvent; - onClose: () => void; -} diff --git a/src/views/notification-center/views/bubble-layouts/GetBubbleLayout.tsx b/src/views/notification-center/views/bubble-layouts/GetBubbleLayout.tsx index 08492b92..4426df56 100644 --- a/src/views/notification-center/views/bubble-layouts/GetBubbleLayout.tsx +++ b/src/views/notification-center/views/bubble-layouts/GetBubbleLayout.tsx @@ -1,9 +1,9 @@ -import { NotificationItem } from '../../common/NotificationItem'; -import { NotificationType } from '../../common/NotificationType'; +import { NotificationBubbleItem } from '../../common/NotificationBubbleItem'; +import { NotificationBubbleType } from '../../common/NotificationBubbleType'; import { NotificationClubGiftBubbleView } from './club-gift/NotificationClubGiftBubbleView'; import { NotificationDefaultBubbleView } from './default/NotificationDefaultBubbleView'; -export const GetBubbleLayout = (item: NotificationItem, close: () => void) => +export const GetBubbleLayout = (item: NotificationBubbleItem, close: () => void) => { if(!item) return null; @@ -11,7 +11,7 @@ export const GetBubbleLayout = (item: NotificationItem, close: () => void) => switch(item.notificationType) { - case NotificationType.CLUBGIFT: + case NotificationBubbleType.CLUBGIFT: return default: return diff --git a/src/views/notification-center/views/bubble-layouts/NotificationBubbleLayoutView.types.ts b/src/views/notification-center/views/bubble-layouts/NotificationBubbleLayoutView.types.ts index ca1fd341..5f9c81d6 100644 --- a/src/views/notification-center/views/bubble-layouts/NotificationBubbleLayoutView.types.ts +++ b/src/views/notification-center/views/bubble-layouts/NotificationBubbleLayoutView.types.ts @@ -1,7 +1,7 @@ -import { NotificationItem } from '../../common/NotificationItem'; +import { NotificationBubbleItem } from '../../common/NotificationBubbleItem'; export interface NotificationBubbleLayoutViewProps { - item: NotificationItem; + item: NotificationBubbleItem; close: () => void; } diff --git a/src/views/notification-center/views/hotel-will-shutdown/HotelWillShutdownView.tsx b/src/views/notification-center/views/hotel-will-shutdown/HotelWillShutdownView.tsx deleted file mode 100644 index 650de0e4..00000000 --- a/src/views/notification-center/views/hotel-will-shutdown/HotelWillShutdownView.tsx +++ /dev/null @@ -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 = 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 ( - onButtonClick('remove_notification') } /> - ); - - return ( - - onButtonClick('dismiss_notification') } /> - - { content } - - - ); -}; diff --git a/src/views/notification-center/views/hotel-will-shutdown/HotelWillShutdownView.types.ts b/src/views/notification-center/views/hotel-will-shutdown/HotelWillShutdownView.types.ts deleted file mode 100644 index 89915153..00000000 --- a/src/views/notification-center/views/hotel-will-shutdown/HotelWillShutdownView.types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { HotelWillShutdownNotification } from '../../common/HotelWillShutdownNotification'; -import { NotificationViewProps } from '../../NotificationCenterView.types'; - -export class HotelWillShutdownViewProps extends NotificationViewProps -{ - notification: HotelWillShutdownNotification; -} diff --git a/src/views/notification-center/views/moderator-message/ModeratorMessageView.tsx b/src/views/notification-center/views/moderator-message/ModeratorMessageView.tsx deleted file mode 100644 index 341d31ea..00000000 --- a/src/views/notification-center/views/moderator-message/ModeratorMessageView.tsx +++ /dev/null @@ -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 = props => -{ - const { notification = null, inTray = null, onButtonClick = null } = props; - - if(!notification) return null; - - const content = <> -
- - ; - - if(inTray) - return ( - onButtonClick('remove_notification') } /> - ); - - return ( - - onButtonClick('dismiss_notification') } /> - - { content } - - - ); -}; diff --git a/src/views/notification-center/views/moderator-message/ModeratorMessageView.types.ts b/src/views/notification-center/views/moderator-message/ModeratorMessageView.types.ts deleted file mode 100644 index 2e7c63de..00000000 --- a/src/views/notification-center/views/moderator-message/ModeratorMessageView.types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ModeratorMessageNotification } from '../../common/ModeratorMessageNotification'; -import { NotificationViewProps } from '../../NotificationCenterView.types'; - -export class ModeratorMessageViewProps extends NotificationViewProps -{ - notification: ModeratorMessageNotification; -} diff --git a/src/views/notification-center/views/motd/NotificationCenterMotdView.tsx b/src/views/notification-center/views/motd/NotificationCenterMotdView.tsx deleted file mode 100644 index 1039f298..00000000 --- a/src/views/notification-center/views/motd/NotificationCenterMotdView.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { FC } from 'react'; -import { NotificationCenterBroadcastMessageView } from '../broadcast-message/NotificationCenterBroadcastMessageView'; -import { NotificationCenterMotdViewProps } from './NotificationCenterMotdView.types'; - -export const NotificationCenterMotdView: FC = props => -{ - const { notification = null, onClose = null } = props; - - return ; -} diff --git a/src/views/notification-center/views/motd/NotificationCenterMotdView.types.ts b/src/views/notification-center/views/motd/NotificationCenterMotdView.types.ts deleted file mode 100644 index 921e8634..00000000 --- a/src/views/notification-center/views/motd/NotificationCenterMotdView.types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NotificationCenterAlertEvent } from '../../../../events'; - -export interface NotificationCenterMotdViewProps -{ - notification: NotificationCenterAlertEvent; - onClose: () => void; -} diff --git a/src/views/notification-center/views/tray-item/NotificationTrayItemView.tsx b/src/views/notification-center/views/tray-item/NotificationTrayItemView.tsx deleted file mode 100644 index cc836c6a..00000000 --- a/src/views/notification-center/views/tray-item/NotificationTrayItemView.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { FC } from 'react'; -import { NotificationTrayItemViewProps } from './NotificationTrayItemView.types'; - -export const NotificationTrayItemView: FC = props => -{ - const { title = null, content = null, timestamp = null, onCloseClick = null } = props; - - return ( -
-
-
{ title }
- -
-
- { content } -
-
- { timestamp } -
-
- ); -}; diff --git a/src/views/notification-center/views/tray-item/NotificationTrayItemView.types.ts b/src/views/notification-center/views/tray-item/NotificationTrayItemView.types.ts deleted file mode 100644 index c84e1793..00000000 --- a/src/views/notification-center/views/tray-item/NotificationTrayItemView.types.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class NotificationTrayItemViewProps -{ - title: string; - content: any; - timestamp: number; - onCloseClick: () => void; -}