diff --git a/src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetAvatarView.tsx b/src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetAvatarView.tsx index f5e362e..582b9a1 100644 --- a/src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetAvatarView.tsx +++ b/src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetAvatarView.tsx @@ -3,7 +3,7 @@ import { FC, useEffect, useMemo, useState } from 'react'; import { FaChevronLeft, FaChevronRight } from 'react-icons/fa'; import { AvatarInfoUser, DispatchUiEvent, GetOwnRoomObject, GetUserProfile, LocalizeText, MessengerFriend, ReportType, RoomWidgetUpdateChatInputContentEvent, SendMessageComposer } from '../../../../../api'; import { Flex } from '../../../../../common'; -import { useFriends, useHelp, useIsUserIgnored, useRoom, useSessionInfo, useWiredTools } from '../../../../../hooks'; +import { useFriends, useHelp, useRoom, useSessionInfo, useWiredTools } from '../../../../../hooks'; import { ContextMenuHeaderView } from '../../context-menu/ContextMenuHeaderView'; import { ContextMenuListItemView } from '../../context-menu/ContextMenuListItemView'; import { ContextMenuView } from '../../context-menu/ContextMenuView'; @@ -31,10 +31,6 @@ export const AvatarInfoWidgetAvatarView: FC = p const { roomSession = null, isHandItemBlocked = false } = useRoom(); const { userRespectRemaining = 0, respectUser = null } = useSessionInfo(); const { openInspectionForUser, showInspectButton } = useWiredTools(); - // Reactive: the menu auto-flips Ignore <-> Unignore if the state - // changes while the popup is open, instead of being frozen to the - // snapshot AvatarInfoUtilities took at click time. - const isIgnored = useIsUserIgnored(avatarInfo.name); const isShowGiveRights = useMemo(() => { @@ -235,11 +231,11 @@ export const AvatarInfoWidgetAvatarView: FC = p { LocalizeText('infostand.link.relationship') } } - { !isIgnored && + { !avatarInfo.isIgnored && processAction('ignore') }> { LocalizeText('infostand.button.ignore') } } - { isIgnored && + { avatarInfo.isIgnored && processAction('unignore') }> { LocalizeText('infostand.button.unignore') } } diff --git a/src/hooks/rooms/widgets/useChatWidget.ts b/src/hooks/rooms/widgets/useChatWidget.ts index f81ffd2..f278659 100644 --- a/src/hooks/rooms/widgets/useChatWidget.ts +++ b/src/hooks/rooms/widgets/useChatWidget.ts @@ -1,8 +1,7 @@ -import { GetGuestRoomResultEvent, GetRoomEngine, PetFigureData, RoomChatSettings, RoomChatSettingsEvent, RoomDragEvent, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomSessionChatEvent, RoomUserData, SystemChatStyleEnum } from '@nitrots/nitro-renderer'; +import { GetGuestRoomResultEvent, GetRoomEngine, GetSessionDataManager, 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'; @@ -23,11 +22,7 @@ const useChatWidgetState = () => const { addChatEntry, updateChatEntry } = useChatHistory(); const { settings, translateIncoming, consumeOutgoingTranslation } = useTranslation(); const isDisposed = useRef(false); - // 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 ownUserId = (GetSessionDataManager()?.userId || -1); const applyTranslationToBubble = useCallback((chatMessage: ChatBubbleMessage, originalText: string, translatedText: string, detectedLanguage: string, targetLanguage: string) => { diff --git a/src/hooks/session/useSessionInfo.ts b/src/hooks/session/useSessionInfo.ts index bb2cd11..9959698 100644 --- a/src/hooks/session/useSessionInfo.ts +++ b/src/hooks/session/useSessionInfo.ts @@ -1,21 +1,16 @@ -import { GetSessionDataManager, RoomUnitChatStyleComposer, UserSettingsEvent } from '@nitrots/nitro-renderer'; +import { FigureUpdateEvent, GetSessionDataManager, RoomUnitChatStyleComposer, UserInfoDataParser, UserInfoEvent, UserSettingsEvent } from '@nitrots/nitro-renderer'; import { useState } from 'react'; import { useBetween } from 'use-between'; import { SendMessageComposer } from '../../api'; import { useMessageEvent } from '../events'; -import { useUserDataSnapshot } from './useSessionSnapshots'; const useSessionInfoState = () => { - // figure / respectsLeft / respectsPetLeft come from the renderer's - // referentially-stable IUserDataSnapshot. The snapshot is invalidated - // (and re-derived on next read) inside SessionDataManager whenever - // the underlying state changes: UserInfoEvent + FigureUpdateEvent + - // giveRespect/givePetRespect all call invalidateUserDataSnapshot(). - // So we no longer need to mirror those fields into local useState. - const userData = useUserDataSnapshot(); - + const [ userInfo, setUserInfo ] = useState(null); + const [ userFigure, setUserFigure ] = useState(null); const [ chatStyleId, setChatStyleId ] = useState(0); + const [ userRespectRemaining, setUserRespectRemaining ] = useState(0); + const [ petRespectRemaining, setPetRespectRemaining ] = useState(0); const updateChatStyleId = (styleId: number) => { @@ -24,8 +19,36 @@ const useSessionInfoState = () => SendMessageComposer(new RoomUnitChatStyleComposer(styleId)); }; - const respectUser = (userId: number) => GetSessionDataManager().giveRespect(userId); - const respectPet = (petId: number) => GetSessionDataManager().givePetRespect(petId); + const respectUser = (userId: number) => + { + GetSessionDataManager().giveRespect(userId); + + setUserRespectRemaining(GetSessionDataManager().respectsLeft); + }; + + const respectPet = (petId: number) => + { + GetSessionDataManager().givePetRespect(petId); + + setPetRespectRemaining(GetSessionDataManager().respectsPetLeft); + }; + + useMessageEvent(UserInfoEvent, event => + { + const parser = event.getParser(); + + setUserInfo(parser.userInfo); + setUserFigure(parser.userInfo.figure); + setUserRespectRemaining(parser.userInfo.respectsRemaining); + setPetRespectRemaining(parser.userInfo.respectsPetRemaining); + }); + + useMessageEvent(FigureUpdateEvent, event => + { + const parser = event.getParser(); + + setUserFigure(parser.figure); + }); useMessageEvent(UserSettingsEvent, event => { @@ -34,15 +57,7 @@ const useSessionInfoState = () => setChatStyleId(parser.chatType); }); - return { - userFigure: userData.figure, - chatStyleId, - userRespectRemaining: userData.respectsLeft, - petRespectRemaining: userData.respectsPetLeft, - respectUser, - respectPet, - updateChatStyleId - }; + return { userInfo, userFigure, chatStyleId, userRespectRemaining, petRespectRemaining, respectUser, respectPet, updateChatStyleId }; }; export const useSessionInfo = () => useBetween(useSessionInfoState);