diff --git a/src/events/notification-center/NotificationCenterAlertEvent.ts b/src/events/notification-center/NotificationCenterAlertEvent.ts new file mode 100644 index 00000000..74266659 --- /dev/null +++ b/src/events/notification-center/NotificationCenterAlertEvent.ts @@ -0,0 +1,34 @@ +import { NitroEvent } from 'nitro-renderer'; + +export class NotificationCenterAlertEvent extends NitroEvent +{ + public static HOTEL_ALERT: string = 'NCAE_HOTEL_ALERT'; + + private _message: string[]; + private _clickUrl: string; + private _headerText: string; + + constructor(type: string, message: string[], clickUrl = null, headerText = null) + { + super(type); + + this._message = message; + this._clickUrl = clickUrl; + this._headerText = headerText; + } + + public get message(): string[] + { + return this._message; + } + + public get clickUrl(): string + { + return this._clickUrl; + } + + public get headerText(): string + { + return this._headerText; + } +} diff --git a/src/events/notification-center/index.ts b/src/events/notification-center/index.ts index 2a5b66e3..37a4117b 100644 --- a/src/events/notification-center/index.ts +++ b/src/events/notification-center/index.ts @@ -1,2 +1,3 @@ export * from './NotificationCenterAddNotificationEvent'; +export * from './NotificationCenterAlertEvent'; export * from './NotificationCenterEvent'; diff --git a/src/views/notification-center/NotificationCenterMessageHandler.tsx b/src/views/notification-center/NotificationCenterMessageHandler.tsx index d25038d5..b6a845c2 100644 --- a/src/views/notification-center/NotificationCenterMessageHandler.tsx +++ b/src/views/notification-center/NotificationCenterMessageHandler.tsx @@ -1,14 +1,13 @@ import { HabboBroadcastMessageEvent, HotelWillShutdownEvent, ModeratorMessageEvent, MOTDNotificationEvent, NotificationDialogMessageEvent } from 'nitro-renderer'; import { FC, useCallback } from 'react'; +import { NotificationCenterAlertEvent } from '../../events'; +import { dispatchUiEvent } from '../../hooks/events'; import { CreateMessageHook } from '../../hooks/messages'; import { useNotificationCenterContext } from './context/NotificationCenterContext'; import { INotificationCenterMessageHandlerProps } from './NotificationCenterMessageHandler.types'; import { NotificationCenterActions } from './reducers/NotificationCenterReducer'; -import { BroadcastMessageNotification } from './utils/BroadcastMessageNotification'; import { DialogMessageNotification } from './utils/DialogMessageNotification'; import { HotelWillShutdownNotification } from './utils/HotelWillShutdownNotification'; -import { ModeratorMessageNotification } from './utils/ModeratorMessageNotification'; -import { MOTDNotification } from './utils/MOTDNotification'; export const NotificationCenterMessageHandler: FC = props => { @@ -18,10 +17,31 @@ export const NotificationCenterMessageHandler: FC + { + const parser = event.getParser(); + + dispatchUiEvent(new NotificationCenterAlertEvent(NotificationCenterAlertEvent.HOTEL_ALERT, [ parser.message ], parser.link)); + }, []); + + const onMOTDNotificationEvent = useCallback((event: MOTDNotificationEvent) => + { + const parser = event.getParser(); + + dispatchUiEvent(new NotificationCenterAlertEvent(NotificationCenterAlertEvent.HOTEL_ALERT, parser.messages)); + }, []); + + const onHotelWillShutdownEvent = useCallback((event: HotelWillShutdownEvent) => + { + const parser = event.getParser(); + dispatchNotificationCenterState({ type: NotificationCenterActions.ADD_NOTIFICATION, payload: { - notification: new BroadcastMessageNotification(parser.message) + notification: new HotelWillShutdownNotification(parser.minutes) } }); }, [ dispatchNotificationCenterState ]); @@ -38,47 +58,11 @@ export const NotificationCenterMessageHandler: FC - { - const parser = event.getParser(); - - dispatchNotificationCenterState({ - type: NotificationCenterActions.ADD_NOTIFICATION, - payload: { - notification: new ModeratorMessageNotification(parser.message, parser.link) - } - }); - }, [ dispatchNotificationCenterState ]); - - const onMOTDNotificationEvent = useCallback((event: MOTDNotificationEvent) => - { - const parser = event.getParser(); - - dispatchNotificationCenterState({ - type: NotificationCenterActions.ADD_NOTIFICATION, - payload: { - notification: new MOTDNotification(parser.messages) - } - }); - }, [ dispatchNotificationCenterState ]); - - const onHotelWillShutdownEvent = useCallback((event: HotelWillShutdownEvent) => - { - const parser = event.getParser(); - - dispatchNotificationCenterState({ - type: NotificationCenterActions.ADD_NOTIFICATION, - payload: { - notification: new HotelWillShutdownNotification(parser.minutes) - } - }); - }, [ dispatchNotificationCenterState ]); - CreateMessageHook(HabboBroadcastMessageEvent, onHabboBroadcastMessageEvent); - CreateMessageHook(NotificationDialogMessageEvent, onNotificationDialogMessageEvent); CreateMessageHook(ModeratorMessageEvent, onModeratorMessageEvent); CreateMessageHook(MOTDNotificationEvent, onMOTDNotificationEvent); CreateMessageHook(HotelWillShutdownEvent, onHotelWillShutdownEvent); + CreateMessageHook(NotificationDialogMessageEvent, onNotificationDialogMessageEvent); return null; } diff --git a/src/views/notification-center/NotificationCenterView.scss b/src/views/notification-center/NotificationCenterView.scss index 834846f6..bf7e1d8e 100644 --- a/src/views/notification-center/NotificationCenterView.scss +++ b/src/views/notification-center/NotificationCenterView.scss @@ -1,3 +1,15 @@ +.nitro-alert { + width: 350px; + + .content-area { + min-height: 125px; + height: 125px; + max-height: 430px; + resize: vertical; + overflow: auto; + } +} + .nitro-notification-center-container { position: absolute; top: 0; @@ -13,12 +25,3 @@ pointer-events: all; } } - -.nitro-notification { - width: 350px; - - .content-area { - max-height: 200px; - overflow-y: auto; - } -} diff --git a/src/views/notification-center/NotificationCenterView.tsx b/src/views/notification-center/NotificationCenterView.tsx index de872df3..bbaa5022 100644 --- a/src/views/notification-center/NotificationCenterView.tsx +++ b/src/views/notification-center/NotificationCenterView.tsx @@ -1,116 +1,49 @@ -import { FC, useCallback, useReducer, useState } from 'react'; -import { NotificationCenterAddNotificationEvent, NotificationCenterEvent } from '../../events'; +import { FC, useCallback, useState } from 'react'; +import { NotificationCenterAlertEvent } from '../../events'; import { useUiEvent } from '../../hooks/events'; -import { TransitionAnimation } from '../../layout/transitions/TransitionAnimation'; -import { TransitionAnimationTypes } from '../../layout/transitions/TransitionAnimation.types'; -import { NotificationCenterContextProvider } from './context/NotificationCenterContext'; import { NotificationCenterMessageHandler } from './NotificationCenterMessageHandler'; import { NotificationCenterViewProps } from './NotificationCenterView.types'; -import { initialNotificationCenter, NotificationCenterActions, NotificationCenterReducer } from './reducers/NotificationCenterReducer'; -import { BroadcastMessageNotification } from './utils/BroadcastMessageNotification'; -import { HotelWillShutdownNotification } from './utils/HotelWillShutdownNotification'; -import { ModeratorMessageNotification } from './utils/ModeratorMessageNotification'; -import { MOTDNotification } from './utils/MOTDNotification'; -import { NitroNotification } from './utils/Notification'; -import { BroadcastMessageView } from './views/broadcast-message/BroadcastMessageView'; -import { HotelWillShutdownView } from './views/hotel-will-shutdown/HotelWillShutdownView'; -import { ModeratorMessageView } from './views/moderator-message/ModeratorMessageView'; -import { MOTDView } from './views/motd/MOTDView'; +import { NotificationCenterBroadcastMessageView } from './views/broadcast-message/NotificationCenterBroadcastMessageView'; export const NotificationCenterView: FC = props => { - const [ isVisible, setIsVisible ] = useState(false); + const [ alerts, setAlerts ] = useState([]); - const [ notificationCenterState, dispatchNotificationCenterState ] = useReducer(NotificationCenterReducer, initialNotificationCenter); - const { notifications = null } = notificationCenterState; - - const onNotificationCenterEvent = useCallback((event: NotificationCenterEvent) => + const onNotificationCenterAlertEvent = useCallback((event: NotificationCenterAlertEvent) => { - switch(event.type) - { - case NotificationCenterEvent.SHOW_NOTIFICATION_CENTER: - setIsVisible(true); - return; - case NotificationCenterEvent.HIDE_NOTIFICATION_CENTER: - setIsVisible(false); - return; - case NotificationCenterEvent.TOGGLE_NOTIFICATION_CENTER: - setIsVisible(value => !value); - return; - case NotificationCenterEvent.ADD_NOTIFICATION: { - const castedEvent = (event as NotificationCenterAddNotificationEvent); - - dispatchNotificationCenterState({ - type: NotificationCenterActions.ADD_NOTIFICATION, - payload: { - notification: castedEvent.notification - } - }); - return; - } - } + setAlerts(prevValue => + { + return [ ...prevValue, event ]; + }); }, []); - useUiEvent(NotificationCenterEvent.SHOW_NOTIFICATION_CENTER, onNotificationCenterEvent); - useUiEvent(NotificationCenterEvent.HIDE_NOTIFICATION_CENTER, onNotificationCenterEvent); - useUiEvent(NotificationCenterEvent.TOGGLE_NOTIFICATION_CENTER, onNotificationCenterEvent); - useUiEvent(NotificationCenterEvent.ADD_NOTIFICATION, onNotificationCenterEvent); + useUiEvent(NotificationCenterAlertEvent.HOTEL_ALERT, onNotificationCenterAlertEvent); - const handleButtonClick = useCallback((action: string, value: number) => + const closeAlert = useCallback((alert: NotificationCenterAlertEvent) => { - if(!action) return; - - switch(action) - { - case 'dismiss_notification': - dispatchNotificationCenterState({ - type: NotificationCenterActions.DISMISS_NOTIFICATION, - payload: { - id: value - } - }); - return; - case 'remove_notification': - dispatchNotificationCenterState({ - type: NotificationCenterActions.REMOVE_NOTIFICATION, - payload: { - id: value - } - }); - return; - } - }, [ dispatchNotificationCenterState ]); - - const mapNotifications = useCallback((notifications: NitroNotification[], inTray: boolean) => - { - if(!notifications) return null; - - return notifications.map(notification => + setAlerts(prevValue => { - if(!inTray && notification.dismissed) return null; + const newAlerts = [ ...prevValue ]; + const index = newAlerts.findIndex(value => (alert === value)); - if(notification instanceof BroadcastMessageNotification) - return handleButtonClick(action, notification.id) } /> - if(notification instanceof MOTDNotification) - return handleButtonClick(action, notification.id) } /> - if(notification instanceof ModeratorMessageNotification) - return handleButtonClick(action, notification.id) } /> - if(notification instanceof HotelWillShutdownNotification) - return handleButtonClick(action, notification.id) } /> - else - return null; + if(index >= 0) newAlerts.splice(index, 1); + + return newAlerts; }); - }, [ handleButtonClick ]); + }, []); return ( - + <> - -
- { mapNotifications(notifications, true) } -
-
- { mapNotifications(notifications, false) } -
+ { (alerts.length > 0) && alerts.map((alert, index) => + { + switch(alert.type) + { + case NotificationCenterAlertEvent.HOTEL_ALERT: + default: + return closeAlert(alert) } />; + } + })} + ); } diff --git a/src/views/notification-center/views/alert-base/NotificationCenterAlertBase.tsx b/src/views/notification-center/views/alert-base/NotificationCenterAlertBase.tsx new file mode 100644 index 00000000..58cc5d93 --- /dev/null +++ b/src/views/notification-center/views/alert-base/NotificationCenterAlertBase.tsx @@ -0,0 +1,18 @@ +import { FC } from 'react'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; +import { LocalizeText } from '../../../../utils/LocalizeText'; +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 new file mode 100644 index 00000000..e7c08d27 --- /dev/null +++ b/src/views/notification-center/views/alert-base/NotificationCenterAlertBase.types.ts @@ -0,0 +1,5 @@ +export interface NotificationCenterAlertBaseProps +{ + headerText?: string; + onClose: () => void; +} diff --git a/src/views/notification-center/views/broadcast-message/BroadcastMessageView.tsx b/src/views/notification-center/views/broadcast-message/BroadcastMessageView.tsx deleted file mode 100644 index 5b7cd157..00000000 --- a/src/views/notification-center/views/broadcast-message/BroadcastMessageView.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { FC } from 'react'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; -import { LocalizeText } from '../../../../utils/LocalizeText'; -import { NotificationTrayItemView } from '../tray-item/NotificationTrayItemView'; -import { BroadcastMessageViewProps } from './BroadcastMessageView.types'; - -export const BroadcastMessageView: 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/broadcast-message/BroadcastMessageView.types.ts b/src/views/notification-center/views/broadcast-message/BroadcastMessageView.types.ts deleted file mode 100644 index fcda3f80..00000000 --- a/src/views/notification-center/views/broadcast-message/BroadcastMessageView.types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NotificationViewProps } from '../../NotificationCenterView.types'; -import { BroadcastMessageNotification } from './../../utils/BroadcastMessageNotification'; - -export class BroadcastMessageViewProps extends NotificationViewProps -{ - notification: BroadcastMessageNotification; -} diff --git a/src/views/notification-center/views/broadcast-message/NotificationCenterBroadcastMessageView.tsx b/src/views/notification-center/views/broadcast-message/NotificationCenterBroadcastMessageView.tsx new file mode 100644 index 00000000..e30208f4 --- /dev/null +++ b/src/views/notification-center/views/broadcast-message/NotificationCenterBroadcastMessageView.tsx @@ -0,0 +1,30 @@ +import { FC, useMemo } from 'react'; +import { LocalizeText } from '../../../../utils/LocalizeText'; +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 new file mode 100644 index 00000000..bd89dd38 --- /dev/null +++ b/src/views/notification-center/views/broadcast-message/NotificationCenterBroadcastMessageView.types.ts @@ -0,0 +1,7 @@ +import { NotificationCenterAlertEvent } from '../../../../events'; + +export class NotificationCenterBroadcastMessageViewProps +{ + notification: NotificationCenterAlertEvent; + onClose: () => void; +} diff --git a/src/views/notification-center/views/motd/MOTDView.tsx b/src/views/notification-center/views/motd/MOTDView.tsx deleted file mode 100644 index c63af9ff..00000000 --- a/src/views/notification-center/views/motd/MOTDView.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { FC } from 'react'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; -import { LocalizeText } from '../../../../utils/LocalizeText'; -import { NotificationTrayItemView } from '../tray-item/NotificationTrayItemView'; -import { MOTDViewProps } from './MOTDView.types'; - -export const MOTDView: FC = props => -{ - const { notification = null, inTray = null, onButtonClick = null } = props; - - if(!notification) return null; - - const content = notification.messages.map((message, index) => - { - return
- }); - - if(inTray) - return ( - onButtonClick('remove_notification') } /> - ); - - return ( - - onButtonClick('dismiss_notification') } /> - - { content } - - - ); -}; diff --git a/src/views/notification-center/views/motd/MOTDView.types.ts b/src/views/notification-center/views/motd/MOTDView.types.ts deleted file mode 100644 index 8175abf7..00000000 --- a/src/views/notification-center/views/motd/MOTDView.types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NotificationViewProps } from '../../NotificationCenterView.types'; -import { MOTDNotification } from './../../utils/MOTDNotification'; - -export class MOTDViewProps extends NotificationViewProps -{ - notification: MOTDNotification; -} diff --git a/src/views/notification-center/views/motd/NotificationCenterMotdView.tsx b/src/views/notification-center/views/motd/NotificationCenterMotdView.tsx new file mode 100644 index 00000000..1039f298 --- /dev/null +++ b/src/views/notification-center/views/motd/NotificationCenterMotdView.tsx @@ -0,0 +1,10 @@ +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 new file mode 100644 index 00000000..921e8634 --- /dev/null +++ b/src/views/notification-center/views/motd/NotificationCenterMotdView.types.ts @@ -0,0 +1,7 @@ +import { NotificationCenterAlertEvent } from '../../../../events'; + +export interface NotificationCenterMotdViewProps +{ + notification: NotificationCenterAlertEvent; + onClose: () => void; +}