Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | import { useMemo } from 'react' import type { RosterWarning } from '@/components/nav/GameContextNav' import { useGameMode } from '@/contexts/GameModeContext' import { useDeactivatePlayer, useKickUser } from '@/hooks/useRoomData' import { useUserId } from '@/hooks/useUserId' import { useRithmomachia } from '../Provider' export function useRosterWarning(phase: 'setup' | 'playing'): RosterWarning | undefined { const { rosterStatus, whitePlayerId, blackPlayerId } = useRithmomachia() const { players: playerMap, activePlayers: activePlayerIds, addPlayer, setActive, roomData, } = useGameMode() const { data: viewerId } = useUserId() const { mutate: kickUser } = useKickUser() const { mutate: deactivatePlayer } = useDeactivatePlayer() return useMemo(() => { // Don't show notice for 'ok' or 'noLocalControl' (observers are allowed) if (rosterStatus.status === 'ok' || rosterStatus.status === 'noLocalControl') { return undefined } const playersArray = Array.from(playerMap.values()).sort((a, b) => { const aTime = typeof a.createdAt === 'number' ? a.createdAt : a.createdAt instanceof Date ? a.createdAt.getTime() : 0 const bTime = typeof b.createdAt === 'number' ? b.createdAt : b.createdAt instanceof Date ? b.createdAt.getTime() : 0 return aTime - bTime }) const isHost = roomData && viewerId ? roomData.members?.find((m) => m.userId === viewerId)?.isCreator === true : false const removableLocalPlayers = playersArray.filter( (player) => player.isLocal !== false && activePlayerIds.has(player.id) && player.id !== whitePlayerId && player.id !== blackPlayerId ) const kickablePlayers = isHost && roomData ? playersArray.filter( (player) => player.isLocal === false && activePlayerIds.has(player.id) && player.id !== whitePlayerId && player.id !== blackPlayerId ) : [] const inactiveLocalPlayer = playersArray.find( (player) => player.isLocal !== false && !activePlayerIds.has(player.id) ) const handleKick = (player: any) => { if (!roomData) return for (const [userId, players] of Object.entries(roomData.memberPlayers ?? {})) { if (players.some((p) => p.id === player.id)) { kickUser({ roomId: roomData.id!, userId }) break } } } if (rosterStatus.status === 'tooFew') { // During setup, don't show nav banner - SetupPlayerRequirement panel handles this if (phase === 'setup') { return undefined } // During playing phase, show nav warning banner const actions = [] if (inactiveLocalPlayer) { actions.push({ label: `Activate ${inactiveLocalPlayer.name}`, onClick: () => setActive(inactiveLocalPlayer.id, true), }) } else { actions.push({ label: 'Create local player', onClick: () => addPlayer({ isActive: true }), }) } return { heading: 'Need two active players', description: 'Gameplay is paused until two players are active.', actions, } } return undefined }, [ rosterStatus.status, phase, playerMap, activePlayerIds, whitePlayerId, blackPlayerId, roomData, viewerId, addPlayer, setActive, kickUser, deactivatePlayer, ]) } |