mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-20 15:36:18 +00:00
Split useFriendRequestWidget into state + actions (flat hooks layout)
Stesso pattern di doorbell / poll / furni-chooser / user-chooser:
flat split sotto src/hooks/rooms/widgets/, no co-location dentro
src/components/.
Split
- src/hooks/rooms/widgets/useFriendRequestState.ts (new):
activeRequests state + displayedRequests derived (filter su
dismissedRequestIds) + due bridge events (user added/removed) +
un useEffect che riallinea activeRequests quando cambia il set
di requests dal friends-store. Esporta anche il tipo
ActiveFriendRequest per consumi futuri.
Plus: ?. su roomSession e userDataManager per evitare il bug
pattern "session è null in transition" (vedi PetTrainingPanel,
precedentemente fixato).
- src/hooks/rooms/widgets/useFriendRequestActions.ts (new):
hideFriendRequest. Thin adapter sul friends-store
(setDismissedRequestIds), nessuna subscription.
- src/hooks/rooms/widgets/useFriendRequestWidget.ts: deprecated
shim che compone i due e preserva
{ displayedRequests, hideFriendRequest } per il consumer
FriendRequestWidgetView.
Verifica
- yarn eslint sui 4 file toccati: 1 errore pre-esistente
(set-state-in-effect sul useEffect che ri-derive activeRequests
da requests — già nel file originale, baseline invariata).
- yarn test: 49/49 passing.
- yarn tsc: clean.
Sequence widget split adesso a 5 (doorbell, poll, furni-chooser,
user-chooser, friend-request). Rimangono: usePetPackageWidget,
useWordQuizWidget, useChatInputWidget, useChatWidget,
useAvatarInfoWidget, useFilterWordsWidget.
This commit is contained in:
@@ -7,6 +7,8 @@ export * from './useDoorbellActions';
|
|||||||
export * from './useDoorbellState';
|
export * from './useDoorbellState';
|
||||||
export * from './useDoorbellWidget';
|
export * from './useDoorbellWidget';
|
||||||
export * from './useFilterWordsWidget';
|
export * from './useFilterWordsWidget';
|
||||||
|
export * from './useFriendRequestActions';
|
||||||
|
export * from './useFriendRequestState';
|
||||||
export * from './useFriendRequestWidget';
|
export * from './useFriendRequestWidget';
|
||||||
export * from './useFurniChooserActions';
|
export * from './useFurniChooserActions';
|
||||||
export * from './useFurniChooserState';
|
export * from './useFurniChooserState';
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { useFriends } from '../../friends';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imperative actions for the friend-request widget. Stateless — split
|
||||||
|
* from useFriendRequestState so a component that only needs to dismiss
|
||||||
|
* a request doesn't subscribe to the user-added/removed lifecycle.
|
||||||
|
*
|
||||||
|
* The actual dismissal flag lives in the shared friends store
|
||||||
|
* (via `setDismissedRequestIds`), so this hook is a thin adapter.
|
||||||
|
*/
|
||||||
|
export const useFriendRequestActions = () =>
|
||||||
|
{
|
||||||
|
const { setDismissedRequestIds = null } = useFriends();
|
||||||
|
|
||||||
|
return {
|
||||||
|
hideFriendRequest: (userId: number): void =>
|
||||||
|
{
|
||||||
|
if(!setDismissedRequestIds) return;
|
||||||
|
|
||||||
|
setDismissedRequestIds(prevValue =>
|
||||||
|
{
|
||||||
|
if(prevValue.indexOf(userId) >= 0) return prevValue;
|
||||||
|
|
||||||
|
return [ ...prevValue, userId ];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
import { RoomObjectCategory, RoomObjectUserType } from '@nitrots/nitro-renderer';
|
||||||
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
|
import { GetRoomSession, MessengerRequest } from '../../../api';
|
||||||
|
import { useFriends } from '../../friends';
|
||||||
|
import { useUserAddedEvent, useUserRemovedEvent } from '../engine';
|
||||||
|
|
||||||
|
export interface ActiveFriendRequest
|
||||||
|
{
|
||||||
|
roomIndex: number;
|
||||||
|
request: MessengerRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State + event subscriptions for the friend-request room widget.
|
||||||
|
* Pure imperative action (hideFriendRequest) lives in
|
||||||
|
* useFriendRequestActions.
|
||||||
|
*/
|
||||||
|
export const useFriendRequestState = () =>
|
||||||
|
{
|
||||||
|
const [ activeRequests, setActiveRequests ] = useState<ActiveFriendRequest[]>([]);
|
||||||
|
const { requests = [], dismissedRequestIds = [] } = useFriends();
|
||||||
|
|
||||||
|
const displayedRequests = useMemo(
|
||||||
|
() => activeRequests.filter(entry => (dismissedRequestIds.indexOf(entry.request.requesterUserId) === -1)),
|
||||||
|
[ activeRequests, dismissedRequestIds ]
|
||||||
|
);
|
||||||
|
|
||||||
|
useUserAddedEvent(true, event =>
|
||||||
|
{
|
||||||
|
if(event.category !== RoomObjectCategory.UNIT) return;
|
||||||
|
|
||||||
|
const userData = GetRoomSession()?.userDataManager?.getUserDataByIndex(event.id);
|
||||||
|
|
||||||
|
if(!userData || (userData.type !== RoomObjectUserType.getTypeNumber(RoomObjectUserType.USER))) return;
|
||||||
|
|
||||||
|
const request = requests.find(r => (r.requesterUserId === userData.webID));
|
||||||
|
|
||||||
|
if(!request) return;
|
||||||
|
|
||||||
|
setActiveRequests(prev =>
|
||||||
|
{
|
||||||
|
if(prev.find(entry => (entry.request.requesterUserId === userData.webID))) return prev;
|
||||||
|
|
||||||
|
return [ ...prev, { roomIndex: userData.roomIndex, request } ];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
useUserRemovedEvent(true, event =>
|
||||||
|
{
|
||||||
|
if(event.category !== RoomObjectCategory.UNIT) return;
|
||||||
|
|
||||||
|
setActiveRequests(prev =>
|
||||||
|
{
|
||||||
|
const index = prev.findIndex(entry => (entry.roomIndex === event.id));
|
||||||
|
|
||||||
|
if(index === -1) return prev;
|
||||||
|
|
||||||
|
const next = [ ...prev ];
|
||||||
|
next.splice(index, 1);
|
||||||
|
return next;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
const session = GetRoomSession();
|
||||||
|
|
||||||
|
if(!session) return;
|
||||||
|
|
||||||
|
const next: ActiveFriendRequest[] = [];
|
||||||
|
|
||||||
|
for(const request of requests)
|
||||||
|
{
|
||||||
|
const userData = session.userDataManager?.getUserData(request.requesterUserId);
|
||||||
|
|
||||||
|
if(!userData) continue;
|
||||||
|
|
||||||
|
next.push({ roomIndex: userData.roomIndex, request });
|
||||||
|
}
|
||||||
|
|
||||||
|
setActiveRequests(next);
|
||||||
|
}, [ requests ]);
|
||||||
|
|
||||||
|
return { displayedRequests };
|
||||||
|
};
|
||||||
@@ -1,81 +1,15 @@
|
|||||||
import { RoomObjectCategory, RoomObjectUserType } from '@nitrots/nitro-renderer';
|
import { useFriendRequestActions } from './useFriendRequestActions';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useFriendRequestState } from './useFriendRequestState';
|
||||||
import { GetRoomSession, MessengerRequest } from '../../../api';
|
|
||||||
import { useFriends } from '../../friends';
|
|
||||||
import { useUserAddedEvent, useUserRemovedEvent } from '../engine';
|
|
||||||
|
|
||||||
const useFriendRequestWidgetState = () =>
|
/**
|
||||||
|
* @deprecated Use `useFriendRequestState` and `useFriendRequestActions`
|
||||||
|
* directly. This shim preserves the
|
||||||
|
* `{ displayedRequests, hideFriendRequest }` shape for existing consumers.
|
||||||
|
*/
|
||||||
|
export const useFriendRequestWidget = () =>
|
||||||
{
|
{
|
||||||
const [ activeRequests, setActiveRequests ] = useState<{ roomIndex: number, request: MessengerRequest }[]>([]);
|
const { displayedRequests } = useFriendRequestState();
|
||||||
const { requests = [], dismissedRequestIds = [], setDismissedRequestIds = null } = useFriends();
|
const { hideFriendRequest } = useFriendRequestActions();
|
||||||
|
|
||||||
const displayedRequests = useMemo(() => activeRequests.filter(request => (dismissedRequestIds.indexOf(request.request.requesterUserId) === -1)), [ activeRequests, dismissedRequestIds ]);
|
|
||||||
|
|
||||||
const hideFriendRequest = (userId: number) =>
|
|
||||||
{
|
|
||||||
setDismissedRequestIds(prevValue =>
|
|
||||||
{
|
|
||||||
if(prevValue.indexOf(userId) >= 0) return prevValue;
|
|
||||||
|
|
||||||
const newValue = [ ...prevValue ];
|
|
||||||
|
|
||||||
newValue.push(userId);
|
|
||||||
|
|
||||||
return newValue;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
useUserAddedEvent(true, event =>
|
|
||||||
{
|
|
||||||
if(event.category !== RoomObjectCategory.UNIT) return;
|
|
||||||
|
|
||||||
const userData = GetRoomSession().userDataManager.getUserDataByIndex(event.id);
|
|
||||||
|
|
||||||
if(!userData || (userData.type !== RoomObjectUserType.getTypeNumber(RoomObjectUserType.USER))) return;
|
|
||||||
|
|
||||||
const request = requests.find(request => (request.requesterUserId === userData.webID));
|
|
||||||
|
|
||||||
if(!request || activeRequests.find(request => (request.request.requesterUserId === userData.webID))) return;
|
|
||||||
|
|
||||||
const newValue = [ ...activeRequests ];
|
|
||||||
|
|
||||||
newValue.push({ roomIndex: userData.roomIndex, request });
|
|
||||||
|
|
||||||
setActiveRequests(newValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
useUserRemovedEvent(true, event =>
|
|
||||||
{
|
|
||||||
if(event.category !== RoomObjectCategory.UNIT) return;
|
|
||||||
|
|
||||||
const index = activeRequests.findIndex(request => (request.roomIndex === event.id));
|
|
||||||
|
|
||||||
if(index === -1) return;
|
|
||||||
|
|
||||||
const newValue = [ ...activeRequests ];
|
|
||||||
|
|
||||||
newValue.splice(index, 1);
|
|
||||||
|
|
||||||
setActiveRequests(newValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
const newDisplayedRequests: { roomIndex: number, request: MessengerRequest }[] = [];
|
|
||||||
|
|
||||||
for(const request of requests)
|
|
||||||
{
|
|
||||||
const userData = GetRoomSession().userDataManager.getUserData(request.requesterUserId);
|
|
||||||
|
|
||||||
if(!userData) continue;
|
|
||||||
|
|
||||||
newDisplayedRequests.push({ roomIndex: userData.roomIndex, request });
|
|
||||||
}
|
|
||||||
|
|
||||||
setActiveRequests(newDisplayedRequests);
|
|
||||||
}, [ requests ]);
|
|
||||||
|
|
||||||
return { displayedRequests, hideFriendRequest };
|
return { displayedRequests, hideFriendRequest };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useFriendRequestWidget = useFriendRequestWidgetState;
|
|
||||||
|
|||||||
Reference in New Issue
Block a user