diff --git a/src/hooks/rooms/widgets/useAvatarInfoWidget.ts b/src/hooks/rooms/widgets/useAvatarInfoWidget.ts index 0c5196b..189f34a 100644 --- a/src/hooks/rooms/widgets/useAvatarInfoWidget.ts +++ b/src/hooks/rooms/widgets/useAvatarInfoWidget.ts @@ -8,9 +8,21 @@ import { useObjectDeselectedEvent, useObjectRollOutEvent, useObjectRollOverEvent import { useRoom } from '../useRoom'; import { applyFavouriteGroupUpdate, applyUserBadgesUpdate, applyUserFigureUpdate } from './avatarInfo.reducers'; +// Time window after a directional / move-state user click during +// which the context menu must NOT open. Set on `globalThis.__nitroAvatarClickControl` +// by the click-routing code in the room engine. +const CLICK_USER_DEBOUNCE_MS = 120; + +interface NitroAvatarClickControl +{ + suppressMenuUntil: number; +} + +const getAvatarClickControl = (): NitroAvatarClickControl | null => + (globalThis as unknown as { __nitroAvatarClickControl?: NitroAvatarClickControl }).__nitroAvatarClickControl ?? null; + const useAvatarInfoWidgetState = () => { - const CLICK_USER_DEBOUNCE_MS = 120; const [ avatarInfo, setAvatarInfo ] = useState(null); const [ activeNameBubble, setActiveNameBubble ] = useState(null); const [ nameBubbles, setNameBubbles ] = useState([]); @@ -33,7 +45,7 @@ const useAvatarInfoWidgetState = () => const isAvatarMenuBlocked = () => { - const control = (globalThis as any).__nitroAvatarClickControl; + const control = getAvatarClickControl(); return !!control && (control.suppressMenuUntil > Date.now()); }; diff --git a/src/hooks/rooms/widgets/useChatWidget.ts b/src/hooks/rooms/widgets/useChatWidget.ts index f278659..f81ffd2 100644 --- a/src/hooks/rooms/widgets/useChatWidget.ts +++ b/src/hooks/rooms/widgets/useChatWidget.ts @@ -1,7 +1,8 @@ -import { GetGuestRoomResultEvent, GetRoomEngine, GetSessionDataManager, PetFigureData, RoomChatSettings, RoomChatSettingsEvent, RoomDragEvent, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomSessionChatEvent, RoomUserData, SystemChatStyleEnum } from '@nitrots/nitro-renderer'; +import { GetGuestRoomResultEvent, GetRoomEngine, PetFigureData, RoomChatSettings, RoomChatSettingsEvent, RoomDragEvent, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomSessionChatEvent, RoomUserData, SystemChatStyleEnum } from '@nitrots/nitro-renderer'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { ChatBubbleMessage, ChatBubbleUtilities, ChatEntryType, ChatHistoryCurrentDate, GetConfigurationValue, GetRoomObjectScreenLocation, IRoomChatSettings, LocalizeText, PlaySound, RoomChatFormatter } from '../../../api'; import { useMessageEvent, useNitroEvent } from '../../events'; +import { useUserDataSnapshot } from '../../session/useSessionSnapshots'; import { useTranslation } from '../../translation'; import { useRoom } from '../useRoom'; import { useChatHistory } from './../../chat-history'; @@ -22,7 +23,11 @@ const useChatWidgetState = () => const { addChatEntry, updateChatEntry } = useChatHistory(); const { settings, translateIncoming, consumeOutgoingTranslation } = useTranslation(); const isDisposed = useRef(false); - const ownUserId = (GetSessionDataManager()?.userId || -1); + // Reactive: a session change (re-login without reload) immediately + // updates the outgoing-translation owner check below. Old code read + // GetSessionDataManager()?.userId at hook mount and would have stayed + // stuck on the previous session's id. + const ownUserId = (useUserDataSnapshot().userId || -1); const applyTranslationToBubble = useCallback((chatMessage: ChatBubbleMessage, originalText: string, translatedText: string, detectedLanguage: string, targetLanguage: string) => {