feat: Add user statuses and cards

This commit is contained in:
2026-04-16 22:52:45 +02:00
parent b4ac0cdc92
commit 2927a86fbb
57 changed files with 1964 additions and 185 deletions

View File

@@ -4,7 +4,11 @@ import {
EntityAdapter,
createEntityAdapter
} from '@ngrx/entity';
import { User, BanEntry } from '../../shared-kernel';
import {
User,
BanEntry,
UserStatus
} from '../../shared-kernel';
import { UsersActions } from './users.actions';
function normalizePresenceServerIds(serverIds: readonly string[] | undefined): string[] | undefined {
@@ -112,6 +116,8 @@ export interface UsersState extends EntityState<User> {
loading: boolean;
error: string | null;
bans: BanEntry[];
/** Manual status set by user (e.g. DND). `null` = automatic. */
manualStatus: UserStatus | null;
}
export const usersAdapter: EntityAdapter<User> = createEntityAdapter<User>({
@@ -124,7 +130,8 @@ export const initialState: UsersState = usersAdapter.getInitialState({
hostId: null,
loading: false,
error: null,
bans: []
bans: [],
manualStatus: null
});
export const usersReducer = createReducer(
@@ -413,5 +420,34 @@ export const usersReducer = createReducer(
hostId: userId
}
);
}),
on(UsersActions.setManualStatus, (state, { status }) => {
const manualStatus = status;
const effectiveStatus = manualStatus ?? 'online';
if (!state.currentUserId)
return { ...state, manualStatus };
return usersAdapter.updateOne(
{
id: state.currentUserId,
changes: { status: effectiveStatus }
},
{ ...state, manualStatus }
);
}),
on(UsersActions.updateRemoteUserStatus, (state, { userId, status }) => {
const existingUser = state.entities[userId];
if (!existingUser)
return state;
return usersAdapter.updateOne(
{
id: userId,
changes: { status }
},
state
);
})
);