fix(avatar-info): reactive Ignore/Unignore menu entry via useIsUserIgnored

The Ignore <-> Unignore context-menu entry was driven by
avatarInfo.isIgnored — a boolean captured by AvatarInfoUtilities once,
at the time the avatar was clicked. If the user got ignored / unignored
*while the popup was already open* (e.g. via the friends panel, or
because a server push flipped the state), the menu kept showing the
stale option and clicking it would no-op (or worse, double-ignore).

Switch the menu items to read useIsUserIgnored(avatarInfo.name) — the
reactive hook backed by IgnoredUsersManager.getIgnoredUsersSnapshot()
+ NitroEventType.IGNORED_USERS_UPDATED. Now the menu flips automatically
the moment the ignore list changes, without re-opening.

avatarInfo.isIgnored stays on the data object (other code paths still
consume it) — only the user-facing menu toggle is now reactive.
This commit is contained in:
simoleo89
2026-05-18 21:33:15 +02:00
parent 71a0eee195
commit 36addbe7d4
@@ -3,7 +3,7 @@ import { FC, useEffect, useMemo, useState } from 'react';
import { FaChevronLeft, FaChevronRight } from 'react-icons/fa'; import { FaChevronLeft, FaChevronRight } from 'react-icons/fa';
import { AvatarInfoUser, DispatchUiEvent, GetOwnRoomObject, GetUserProfile, LocalizeText, MessengerFriend, ReportType, RoomWidgetUpdateChatInputContentEvent, SendMessageComposer } from '../../../../../api'; import { AvatarInfoUser, DispatchUiEvent, GetOwnRoomObject, GetUserProfile, LocalizeText, MessengerFriend, ReportType, RoomWidgetUpdateChatInputContentEvent, SendMessageComposer } from '../../../../../api';
import { Flex } from '../../../../../common'; import { Flex } from '../../../../../common';
import { useFriends, useHelp, useRoom, useSessionInfo, useWiredTools } from '../../../../../hooks'; import { useFriends, useHelp, useIsUserIgnored, useRoom, useSessionInfo, useWiredTools } from '../../../../../hooks';
import { ContextMenuHeaderView } from '../../context-menu/ContextMenuHeaderView'; import { ContextMenuHeaderView } from '../../context-menu/ContextMenuHeaderView';
import { ContextMenuListItemView } from '../../context-menu/ContextMenuListItemView'; import { ContextMenuListItemView } from '../../context-menu/ContextMenuListItemView';
import { ContextMenuView } from '../../context-menu/ContextMenuView'; import { ContextMenuView } from '../../context-menu/ContextMenuView';
@@ -31,6 +31,10 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
const { roomSession = null, isHandItemBlocked = false } = useRoom(); const { roomSession = null, isHandItemBlocked = false } = useRoom();
const { userRespectRemaining = 0, respectUser = null } = useSessionInfo(); const { userRespectRemaining = 0, respectUser = null } = useSessionInfo();
const { openInspectionForUser, showInspectButton } = useWiredTools(); 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(() => const isShowGiveRights = useMemo(() =>
{ {
@@ -231,11 +235,11 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
{ LocalizeText('infostand.link.relationship') } { LocalizeText('infostand.link.relationship') }
<FaChevronRight className="right fa-icon" /> <FaChevronRight className="right fa-icon" />
</ContextMenuListItemView> } </ContextMenuListItemView> }
{ !avatarInfo.isIgnored && { !isIgnored &&
<ContextMenuListItemView onClick={ event => processAction('ignore') }> <ContextMenuListItemView onClick={ event => processAction('ignore') }>
{ LocalizeText('infostand.button.ignore') } { LocalizeText('infostand.button.ignore') }
</ContextMenuListItemView> } </ContextMenuListItemView> }
{ avatarInfo.isIgnored && { isIgnored &&
<ContextMenuListItemView onClick={ event => processAction('unignore') }> <ContextMenuListItemView onClick={ event => processAction('unignore') }>
{ LocalizeText('infostand.button.unignore') } { LocalizeText('infostand.button.unignore') }
</ContextMenuListItemView> } </ContextMenuListItemView> }