From 3c10ccdaee49fa32b33bf66b5c2e376b0f660382 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Wed, 27 May 2026 18:50:40 +0200 Subject: [PATCH] fix(navigator): restore useNotification() inside useNavigatorStore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 8ab0021a introduced an unjustified deviation: it removed the useNotification() call from inside useNavigatorStore and replaced it with a module-level _simpleAlert ref + _injectSimpleAlert() exported function, on the theory that nested useBetween calls corrupt use-between's state. That diagnosis is wrong. Production proof: - useCatalog.ts:56 calls useNotification() inside useCatalogStore - useWiredToolsStore.ts:131 calls useNotification() inside its store - The original useNavigator.ts:32 calls useNotification() inside its state closure All three have been in production for ages without issue. Nested useBetween calls work fine. The smoke-test failure that prompted the workaround was a mock issue, not a real bug. Reverting to the standard pattern — useNotification() direct inside the useBetween store closure. Production alerts work again immediately without requiring an explicit injection call from consumers. Mock additions (src/nitro-renderer.mock.ts): - Added 23 notification MessageEvent subclasses (AchievementNotification- MessageEvent, ActivityPoint..., BadgeReceived, ClubGiftNotification, ClubGiftSelected, ConnectionError, HabboBroadcast, HotelClosedAndOpens, HotelClosesAndWillOpenAt, HotelWillCloseInMinutes, InfoFeedEnable, MaintenanceStatus, ModeratorCaution, ModeratorMessage, MOTD, NotificationDialog, PetLevel, PetReceived, RespectReceived, RoomEnter, SimpleAlert, UserBanned, WiredRewardResult) so useNotificationStore can register its listeners without throwing. - Added RoomEnterEffect stub (isRunning: false, totalRunningTime: 0). - Added WiredRewardResultMessageEvent static constants. --- src/hooks/navigator/useNavigatorStore.ts | 10 ++---- src/nitro-renderer.mock.ts | 42 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/hooks/navigator/useNavigatorStore.ts b/src/hooks/navigator/useNavigatorStore.ts index d577413..e3165d9 100644 --- a/src/hooks/navigator/useNavigatorStore.ts +++ b/src/hooks/navigator/useNavigatorStore.ts @@ -17,15 +17,9 @@ import { CreateRoomSession, GetConfigurationValue, INavigatorData, LocalizeText, NotificationAlertType, SendMessageComposer, TryVisitRoom, VisitDesktop } from '../../api'; import { useMessageEvent, useNitroEvent } from '../events'; +import { useNotification } from '../notification'; import { useNavigatorUiStore } from './navigatorUiStore'; -// Module-level reference to simpleAlert, injected by useNavigatorActions -// (which runs in a real React dispatcher context, outside useBetween). -// Avoids nested useBetween calls that corrupt use-between's module-level state. -type SimpleAlertFn = (message: string, type?: string, clickUrl?: string, clickUrlText?: string, title?: string, imageUrl?: string) => void; -let _simpleAlert: SimpleAlertFn | null = null; -export const _injectSimpleAlert = (fn: SimpleAlertFn | null) => { _simpleAlert = fn; }; - export const useNavigatorStore = () => { const [ categories, setCategories ] = useState(null); @@ -58,7 +52,7 @@ export const useNavigatorStore = () => const searchResultRef = useRef(searchResult); searchResultRef.current = searchResult; - const simpleAlert = _simpleAlert; + const { simpleAlert = null } = useNotification(); const sendSearch = useCallback((searchValue: string, contextCode: string) => { diff --git a/src/nitro-renderer.mock.ts b/src/nitro-renderer.mock.ts index 54bf1e6..28abd00 100644 --- a/src/nitro-renderer.mock.ts +++ b/src/nitro-renderer.mock.ts @@ -274,6 +274,48 @@ export class UserFlatCatsEvent extends MessageEvent {} export class UserInfoEvent extends MessageEvent {} export class UserPermissionsEvent extends MessageEvent {} +// --------------------------------------------------------------------------- +// Notification event classes — MessageEvent subclasses needed by +// useNotificationStore (called via useNotification() inside useNavigatorStore). +// The real renderer classes take a `callBack` constructor arg; the pattern +// here is the same as the Navigator event stubs above. +// --------------------------------------------------------------------------- + +export class AchievementNotificationMessageEvent extends MessageEvent {} +export class ActivityPointNotificationMessageEvent extends MessageEvent {} +export class BadgeReceivedEvent extends MessageEvent {} +export class ClubGiftNotificationEvent extends MessageEvent {} +export class ClubGiftSelectedEvent extends MessageEvent {} +export class ConnectionErrorEvent extends MessageEvent {} +export class HabboBroadcastMessageEvent extends MessageEvent {} +export class HotelClosedAndOpensEvent extends MessageEvent {} +export class HotelClosesAndWillOpenAtEvent extends MessageEvent {} +export class HotelWillCloseInMinutesEvent extends MessageEvent {} +export class InfoFeedEnableMessageEvent extends MessageEvent {} +export class MaintenanceStatusMessageEvent extends MessageEvent {} +export class ModeratorCautionEvent extends MessageEvent {} +export class ModeratorMessageEvent extends MessageEvent {} +export class MOTDNotificationEvent extends MessageEvent {} +export class NotificationDialogMessageEvent extends MessageEvent {} +export class PetLevelNotificationEvent extends MessageEvent {} +export class PetReceivedMessageEvent extends MessageEvent {} +export class RespectReceivedEvent extends MessageEvent {} +export class RoomEnterEvent extends MessageEvent {} +export class SimpleAlertMessageEvent extends MessageEvent {} +export class UserBannedMessageEvent extends MessageEvent {} +export class WiredRewardResultMessageEvent extends MessageEvent +{ + static readonly PRODUCT_DONATED_CODE = 7; + static readonly BADGE_DONATED_CODE = 8; +} + +// RoomEnterEffect — used by useNotificationStore to check if the room-enter +// animation is still running before showing the mod disclaimer bubble. +export const RoomEnterEffect = { + isRunning: () => false, + totalRunningTime: 0 +}; + export class RoomEngineObjectEvent extends StubClass {} export class CreateLinkEvent extends StubClass {} export class EventDispatcher extends StubClass {}