fix(navigator): restore useNotification() inside useNavigatorStore

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.
This commit is contained in:
simoleo89
2026-05-27 18:50:40 +02:00
parent 8ab0021af6
commit 3c10ccdaee
2 changed files with 44 additions and 8 deletions
+2 -8
View File
@@ -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<NavigatorCategoryDataParser[]>(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) =>
{
+42
View File
@@ -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 {}