mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 23:16:21 +00:00
refactor(useChatWidget,useAvatarInfoWidget): reactive ownUserId + typed avatar-click-control
Two small modernization wins on the previously skip-motivated god-hooks. Neither hook lends itself to the data/actions split, but both had concrete imperative-style residue worth tidying: == useChatWidget Replace `const ownUserId = GetSessionDataManager()?.userId || -1;` with `useUserDataSnapshot().userId`. The previous read happened at hook mount and stayed pinned to whatever userId the manager held at that point — a session change (re-login without page reload) would silently corrupt the outgoing-translation owner check below. With the snapshot hook, the value updates reactively via SESSION_DATA_UPDATED and the useNitroEvent re-registration picks up the fresh ownUserId for every incoming chat event. == useAvatarInfoWidget Two tidy points: - CLICK_USER_DEBOUNCE_MS (the 120ms window during which a directional click suppresses the context menu) lifted from inside the hook body to a module-level const. It's never going to change at runtime and doesn't depend on hook state — keeping it inside meant it was redeclared on every render. - The `(globalThis as any).__nitroAvatarClickControl` read replaced by a typed `getAvatarClickControl()` helper backed by a proper `NitroAvatarClickControl` interface. Same runtime behaviour; type channel no longer goes through `any`, and the symbol is documented in one place above the hook. Public APIs of both hooks unchanged. Suite: 207/207.
This commit is contained in:
@@ -8,9 +8,21 @@ import { useObjectDeselectedEvent, useObjectRollOutEvent, useObjectRollOverEvent
|
|||||||
import { useRoom } from '../useRoom';
|
import { useRoom } from '../useRoom';
|
||||||
import { applyFavouriteGroupUpdate, applyUserBadgesUpdate, applyUserFigureUpdate } from './avatarInfo.reducers';
|
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 useAvatarInfoWidgetState = () =>
|
||||||
{
|
{
|
||||||
const CLICK_USER_DEBOUNCE_MS = 120;
|
|
||||||
const [ avatarInfo, setAvatarInfo ] = useState<IAvatarInfo>(null);
|
const [ avatarInfo, setAvatarInfo ] = useState<IAvatarInfo>(null);
|
||||||
const [ activeNameBubble, setActiveNameBubble ] = useState<AvatarInfoName>(null);
|
const [ activeNameBubble, setActiveNameBubble ] = useState<AvatarInfoName>(null);
|
||||||
const [ nameBubbles, setNameBubbles ] = useState<AvatarInfoName[]>([]);
|
const [ nameBubbles, setNameBubbles ] = useState<AvatarInfoName[]>([]);
|
||||||
@@ -33,7 +45,7 @@ const useAvatarInfoWidgetState = () =>
|
|||||||
|
|
||||||
const isAvatarMenuBlocked = () =>
|
const isAvatarMenuBlocked = () =>
|
||||||
{
|
{
|
||||||
const control = (globalThis as any).__nitroAvatarClickControl;
|
const control = getAvatarClickControl();
|
||||||
|
|
||||||
return !!control && (control.suppressMenuUntil > Date.now());
|
return !!control && (control.suppressMenuUntil > Date.now());
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { ChatBubbleMessage, ChatBubbleUtilities, ChatEntryType, ChatHistoryCurrentDate, GetConfigurationValue, GetRoomObjectScreenLocation, IRoomChatSettings, LocalizeText, PlaySound, RoomChatFormatter } from '../../../api';
|
import { ChatBubbleMessage, ChatBubbleUtilities, ChatEntryType, ChatHistoryCurrentDate, GetConfigurationValue, GetRoomObjectScreenLocation, IRoomChatSettings, LocalizeText, PlaySound, RoomChatFormatter } from '../../../api';
|
||||||
import { useMessageEvent, useNitroEvent } from '../../events';
|
import { useMessageEvent, useNitroEvent } from '../../events';
|
||||||
|
import { useUserDataSnapshot } from '../../session/useSessionSnapshots';
|
||||||
import { useTranslation } from '../../translation';
|
import { useTranslation } from '../../translation';
|
||||||
import { useRoom } from '../useRoom';
|
import { useRoom } from '../useRoom';
|
||||||
import { useChatHistory } from './../../chat-history';
|
import { useChatHistory } from './../../chat-history';
|
||||||
@@ -22,7 +23,11 @@ const useChatWidgetState = () =>
|
|||||||
const { addChatEntry, updateChatEntry } = useChatHistory();
|
const { addChatEntry, updateChatEntry } = useChatHistory();
|
||||||
const { settings, translateIncoming, consumeOutgoingTranslation } = useTranslation();
|
const { settings, translateIncoming, consumeOutgoingTranslation } = useTranslation();
|
||||||
const isDisposed = useRef(false);
|
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) =>
|
const applyTranslationToBubble = useCallback((chatMessage: ChatBubbleMessage, originalText: string, translatedText: string, detectedLanguage: string, targetLanguage: string) =>
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user