mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 23:16:21 +00:00
feat(mod-tools): reactive ModToolsUserView (online dot + refresh on sanction)
ModToolsUserView used a one-shot ModeratorUserInfoData snapshot taken at panel-open time. Two consequences: - The online/offline icon (rendered next to userName) was frozen on the value at open. If the target user joined/left while the panel stayed open, the icon kept lying. - After the moderator applied a sanction via ModToolsUserModActionView the user info window stayed open with stale cfhCount / banCount / cautionCount / lastSanctionTime; you had to close and reopen to see the bump. Fix shape mirrors the ModToolsView selected-user dot from yesterday: - Read useRoomUserListSnapshot in the component (outside any useBetween scope — useSyncExternalStore constraint). If the target user is in the current room they're online; fall back to userInfo.online otherwise. Tooltip surfaces which path produced the value. - Subscribe to ModeratorActionResultMessageEvent (parser carries userId + success). On a successful action targeting THIS userId, re-send GetModeratorUserInfoMessageComposer so the table re-fetches.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { CreateLinkEvent, GetModeratorUserInfoMessageComposer, ModeratorUserInfoData, ModeratorUserInfoEvent } from '@nitrots/nitro-renderer';
|
||||
import { CreateLinkEvent, GetModeratorUserInfoMessageComposer, ModeratorActionResultMessageEvent, ModeratorUserInfoData, ModeratorUserInfoEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useMemo, useState } from 'react';
|
||||
import { FriendlyTime, LocalizeText, SendMessageComposer } from '../../../../api';
|
||||
import { Button, Column, DraggableWindowPosition, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common';
|
||||
import { useMessageEvent } from '../../../../hooks';
|
||||
import { useMessageEvent, useRoomUserListSnapshot } from '../../../../hooks';
|
||||
import { ModToolsUserModActionView } from './ModToolsUserModActionView';
|
||||
import { ModToolsUserRoomVisitsView } from './ModToolsUserRoomVisitsView';
|
||||
import { ModToolsUserSendMessageView } from './ModToolsUserSendMessageView';
|
||||
@@ -20,6 +20,15 @@ export const ModToolsUserView: FC<ModToolsUserViewProps> = props =>
|
||||
const [ sendMessageVisible, setSendMessageVisible ] = useState(false);
|
||||
const [ modActionVisible, setModActionVisible ] = useState(false);
|
||||
const [ roomVisitsVisible, setRoomVisitsVisible ] = useState(false);
|
||||
// Reactive presence: if the target user is currently in the room
|
||||
// we're observing, they're online — irrespective of what the
|
||||
// one-shot ModeratorUserInfoData.online said when the panel opened.
|
||||
const roomUserList = useRoomUserListSnapshot();
|
||||
const isPresentInCurrentRoom = useMemo(
|
||||
() => roomUserList.some(user => user && (user.webID === userId)),
|
||||
[ roomUserList, userId ]
|
||||
);
|
||||
const isOnline = isPresentInCurrentRoom || !!(userInfo && userInfo.online);
|
||||
|
||||
const userProperties = useMemo(() =>
|
||||
{
|
||||
@@ -95,6 +104,19 @@ export const ModToolsUserView: FC<ModToolsUserViewProps> = props =>
|
||||
setUserInfo(parser.data);
|
||||
});
|
||||
|
||||
// Refresh counters (cfhCount / banCount / cautionCount /
|
||||
// lastSanctionTime) after the moderator applies a sanction on THIS
|
||||
// user — otherwise the table stays frozen on the values at panel
|
||||
// open. Parser carries userId so we can filter precisely.
|
||||
useMessageEvent<ModeratorActionResultMessageEvent>(ModeratorActionResultMessageEvent, event =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
if(!parser || !parser.success || parser.userId !== userId) return;
|
||||
|
||||
SendMessageComposer(new GetModeratorUserInfoMessageComposer(userId));
|
||||
});
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
SendMessageComposer(new GetModeratorUserInfoMessageComposer(userId));
|
||||
@@ -120,7 +142,7 @@ export const ModToolsUserView: FC<ModToolsUserViewProps> = props =>
|
||||
<td>
|
||||
{ property.value }
|
||||
{ property.showOnline &&
|
||||
<i className={ `icon icon-pf-${ userInfo.online ? 'online' : 'offline' } ms-2` } /> }
|
||||
<i className={ `icon icon-pf-${ isOnline ? 'online' : 'offline' } ms-2` } title={ isPresentInCurrentRoom ? 'In this room' : (userInfo.online ? 'Online' : 'Offline') } /> }
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user