Files
Nitro_Render_V3/packages/session/src/IgnoredUsersManager.ts
T
simoleo89 a599e0cf89 feat(session): snapshot getters for IgnoredUsersManager + GroupInformationManager
Extends the v2.1.0 React-friendly snapshot pattern (originally on
SessionDataManager / RoomSessionManager) to two more session-state
holders the React client reads frequently:

- IgnoredUsersManager.getIgnoredUsersSnapshot(): ReadonlyArray<string>
- GroupInformationManager.getGroupBadgesSnapshot(): ReadonlyMap<number, string>

Both follow the same shape: lazy-frozen snapshot, cached until the
underlying state mutates, then invalidated and a dispatched event lets
the React client rebuild via useSyncExternalStore.

Two new NitroEventType members carry the invalidation signal:
- IGNORED_USERS_UPDATED — dispatched by IgnoredUsersManager whenever
  the list changes (initial load, add, remove, queue-truncate case 2).
- GROUP_BADGES_UPDATED — dispatched by GroupInformationManager only
  when the incoming HabboGroupBadges payload contains at least one
  new or changed mapping (no-op refresh stays quiet).

This lets the user-info popup, profile page, friend/guild filtering,
and any other consumer share a single read through useSyncExternalStore
instead of each subscribing to the underlying message events
independently.

API additions are interface-respecting and backwards-compatible — the
existing `isIgnored(name)` / `getGroupBadge(groupId)` accessors stay
untouched.
2026-05-18 20:50:24 +02:00

115 lines
3.3 KiB
TypeScript

import { IIgnoredUsersManager } from '@nitrots/api';
import { GetCommunication, GetIgnoredUsersComposer, IgnoreResultEvent, IgnoreUserComposer, IgnoreUserIdComposer, IgnoredUsersEvent, UnignoreUserComposer } from '@nitrots/communication';
import { GetEventDispatcher, NitroEvent, NitroEventType } from '@nitrots/events';
export class IgnoredUsersManager implements IIgnoredUsersManager
{
private _ignoredUsers: string[] = [];
private _ignoredUsersSnapshot: ReadonlyArray<string> | null = null;
private invalidateIgnoredUsersSnapshot(): void
{
this._ignoredUsersSnapshot = null;
GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.IGNORED_USERS_UPDATED));
}
public getIgnoredUsersSnapshot(): ReadonlyArray<string>
{
if(this._ignoredUsersSnapshot) return this._ignoredUsersSnapshot;
this._ignoredUsersSnapshot = Object.freeze<string[]>([ ...this._ignoredUsers ]) as ReadonlyArray<string>;
return this._ignoredUsersSnapshot;
}
public init(): void
{
GetCommunication().registerMessageEvent(new IgnoredUsersEvent(this.onIgnoredUsersEvent.bind(this)));
GetCommunication().registerMessageEvent(new IgnoreResultEvent(this.onIgnoreResultEvent.bind(this)));
}
public requestIgnoredUsers(username: string): void
{
GetCommunication().connection.send(new GetIgnoredUsersComposer(username));
}
private onIgnoredUsersEvent(event: IgnoredUsersEvent): void
{
if(!event) return;
const parser = event.getParser();
if(!parser) return;
this._ignoredUsers = parser.ignoredUsers;
this.invalidateIgnoredUsersSnapshot();
}
private onIgnoreResultEvent(event: IgnoreResultEvent): void
{
if(!event) return;
const parser = event.getParser();
if(!parser) return;
const name = parser.name;
switch(parser.result)
{
case 0:
return;
case 1:
this.addUserToIgnoreList(name);
return;
case 2:
this.addUserToIgnoreList(name);
this._ignoredUsers.shift();
this.invalidateIgnoredUsersSnapshot();
return;
case 3:
this.removeUserFromIgnoreList(name);
return;
}
}
private addUserToIgnoreList(name: string): void
{
if(this._ignoredUsers.indexOf(name) >= 0) return;
this._ignoredUsers.push(name);
this.invalidateIgnoredUsersSnapshot();
}
private removeUserFromIgnoreList(name: string): void
{
const index = this._ignoredUsers.indexOf(name);
if(index < 0) return;
this._ignoredUsers.splice(index, 1);
this.invalidateIgnoredUsersSnapshot();
}
public ignoreUserId(id: number): void
{
GetCommunication().connection.send(new IgnoreUserIdComposer(id));
}
public ignoreUser(name: string): void
{
GetCommunication().connection.send(new IgnoreUserComposer(name));
}
public unignoreUser(name: string): void
{
GetCommunication().connection.send(new UnignoreUserComposer(name));
}
public isIgnored(name: string): boolean
{
return (this._ignoredUsers.indexOf(name) >= 0);
}
}