mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
97 lines
3.6 KiB
TypeScript
97 lines
3.6 KiB
TypeScript
import { createSelector } from '@reduxjs/toolkit';
|
|
import { App, Data } from '@app/types';
|
|
import { SortUtil } from '../common';
|
|
import { ServerState } from './server.interfaces';
|
|
|
|
interface State {
|
|
server: ServerState
|
|
}
|
|
|
|
const EMPTY_USERS: Data.ServerInfo_User[] = [];
|
|
const EMPTY_REPLAYS: Data.ServerInfo_ReplayMatch[] = [];
|
|
|
|
export const Selectors = {
|
|
getInitialized: ({ server }: State) => server.initialized,
|
|
getMessage: ({ server }: State) => server.info.message,
|
|
getName: ({ server }: State) => server.info.name,
|
|
getVersion: ({ server }: State) => server.info.version,
|
|
getDescription: ({ server }: State) => server.status.description,
|
|
getState: ({ server }: State) => server.status.state,
|
|
getConnectionAttemptMade: ({ server }: State) => server.status.connectionAttemptMade,
|
|
getUser: ({ server }: State) => server.user,
|
|
|
|
/** True when the server status has reached LOGGED_IN. */
|
|
getIsConnected: createSelector(
|
|
[({ server }: State) => server.status.state],
|
|
(state): boolean => state === App.StatusEnum.LOGGED_IN
|
|
),
|
|
|
|
/** True when the currently logged-in user has the IsModerator level flag. */
|
|
getIsUserModerator: createSelector(
|
|
[({ server }: State) => server.user],
|
|
(user): boolean => {
|
|
if (!user) {
|
|
return false;
|
|
}
|
|
const mask = Data.ServerInfo_User_UserLevelFlag.IsModerator;
|
|
return (user.userLevel & mask) === mask;
|
|
}
|
|
),
|
|
getLogs: ({ server }: State) => server.logs,
|
|
getBackendDecks: ({ server }: State) => server.backendDecks,
|
|
getRegistrationError: ({ server }: State) => server.registrationError,
|
|
getSortUsersBy: ({ server }: State) => server.sortUsersBy,
|
|
|
|
/** Raw keyed maps — use the sorted-view selectors below for display. */
|
|
getUsers: ({ server }: State) => server.users,
|
|
getBuddyList: ({ server }: State) => server.buddyList,
|
|
getIgnoreList: ({ server }: State) => server.ignoreList,
|
|
getReplays: ({ server }: State) => server.replays,
|
|
|
|
/**
|
|
* Sorted array views of the keyed maps. Memoized via `createSelector` so
|
|
* the array reference is stable until the underlying map or sort config
|
|
* actually changes — consumers using these in `useAppSelector` won't
|
|
* re-render unnecessarily.
|
|
*/
|
|
getSortedUsers: createSelector(
|
|
[(state: State) => state.server.users, (state: State) => state.server.sortUsersBy],
|
|
(users, sortBy): Data.ServerInfo_User[] => {
|
|
if (!users || Object.keys(users).length === 0) {
|
|
return EMPTY_USERS;
|
|
}
|
|
return SortUtil.sortedUsersByField(Object.values(users), sortBy);
|
|
}
|
|
),
|
|
|
|
getSortedBuddyList: createSelector(
|
|
[(state: State) => state.server.buddyList, (state: State) => state.server.sortUsersBy],
|
|
(buddyList, sortBy): Data.ServerInfo_User[] => {
|
|
if (!buddyList || Object.keys(buddyList).length === 0) {
|
|
return EMPTY_USERS;
|
|
}
|
|
return SortUtil.sortedUsersByField(Object.values(buddyList), sortBy);
|
|
}
|
|
),
|
|
|
|
getSortedIgnoreList: createSelector(
|
|
[(state: State) => state.server.ignoreList, (state: State) => state.server.sortUsersBy],
|
|
(ignoreList, sortBy): Data.ServerInfo_User[] => {
|
|
if (!ignoreList || Object.keys(ignoreList).length === 0) {
|
|
return EMPTY_USERS;
|
|
}
|
|
return SortUtil.sortedUsersByField(Object.values(ignoreList), sortBy);
|
|
}
|
|
),
|
|
|
|
/** Replay list as an array, ordered by gameId ascending for stable display. */
|
|
getReplaysList: createSelector(
|
|
[(state: State) => state.server.replays],
|
|
(replays): Data.ServerInfo_ReplayMatch[] => {
|
|
if (!replays || Object.keys(replays).length === 0) {
|
|
return EMPTY_REPLAYS;
|
|
}
|
|
return Object.values(replays).sort((a, b) => a.gameId - b.gameId);
|
|
}
|
|
),
|
|
}
|