Skip to content

Commit

Permalink
add ui for spectators
Browse files Browse the repository at this point in the history
  • Loading branch information
salvoilmiosi committed Sep 7, 2024
1 parent d68efc3 commit 00c697c
Show file tree
Hide file tree
Showing 8 changed files with 24 additions and 9 deletions.
5 changes: 5 additions & 0 deletions src/Components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { DEFAULT_USER_PROPIC } from '../Scenes/Lobby/LobbyUser';
import { ImageSrc } from '../Utils/ImageSerial';
import useCloseOnLoseFocus from '../Utils/UseCloseOnLoseFocus';
import UserMenu, { UserMenuItem } from './UserMenu';
import { getUser } from '../Scenes/Lobby/Lobby';

export interface HeaderProps {
scene: SceneState;
Expand All @@ -30,6 +31,9 @@ function Header({ scene, settings, connection }: HeaderProps) {
const handleLeaveLobby = () => connection.sendMessage({ lobby_leave: {}});
const handleReturnLobby = () => connection.sendMessage({ lobby_return: {}});

const isSpectator = 'lobbyState' in scene && getUser(scene.lobbyState.users, scene.lobbyState.myUserId)?.team === 'game_spectator';
const handleToggleSpectate = () => connection.sendMessage({ user_set_team: isSpectator ? 'game_player' : 'game_spectator' });

const handleDisconnect = () => {
settings.setSessionId(undefined);
connection.disconnect();
Expand Down Expand Up @@ -83,6 +87,7 @@ function Header({ scene, settings, connection }: HeaderProps) {
<UserMenu username={settings.username} setUsername={username => handleEditUser(username, settings.propic)}>
<UserMenuItem onClick={handleToggleSounds}>{getLabel('ui', settings.muteSounds ? 'BUTTON_ENABLE_SOUNDS' : 'BUTTON_DISABLE_SOUNDS')}</UserMenuItem>
{ scene.type === 'game' && isLobbyOwner(scene.lobbyState) && <UserMenuItem onClick={closeMenuAnd(handleReturnLobby)}>{getLabel('ui', 'BUTTON_RETURN_LOBBY')}</UserMenuItem>}
{ scene.type === 'lobby' && <UserMenuItem onClick={handleToggleSpectate}>{getLabel('ui', isSpectator ? 'BUTTON_SPECTATE_OFF' : 'BUTTON_SPECTATE_ON')}</UserMenuItem> }
{ 'lobbyInfo' in scene
? <UserMenuItem onClick={closeMenuAnd(handleLeaveLobby)}>{getLabel('ui', 'BUTTON_LEAVE_LOBBY')}</UserMenuItem>
: <UserMenuItem onClick={closeMenuAnd(handleDisconnect)}>{getLabel('ui', 'BUTTON_DISCONNECT')}</UserMenuItem> }
Expand Down
2 changes: 2 additions & 0 deletions src/Locale/English/Labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ export const LABELS_ENGLISH: LabelRegistry = {
GAME_OPTIONS: "Game Options",
BUTTON_CHAT_SEND: "Send",
BUTTON_START_GAME: "Start Game",
BUTTON_SPECTATE_ON: "Join as spectator",
BUTTON_SPECTATE_OFF: "Join as player",
BUTTON_ENABLE_SOUNDS: "Enable Sounds",
BUTTON_DISABLE_SOUNDS: "Disable Sounds",
BUTTON_RETURN_LOBBY: "Return to Lobby",
Expand Down
2 changes: 2 additions & 0 deletions src/Locale/Italian/Labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ export const LABELS_ITALIAN: LabelRegistry = {
GAME_OPTIONS: "Opzioni di Partita",
BUTTON_CHAT_SEND: "Invia",
BUTTON_START_GAME: "Avvia Partita",
BUTTON_SPECTATE_ON: "Unisciti come spettatore",
BUTTON_SPECTATE_OFF: "Unisciti come giocatore",
BUTTON_ENABLE_SOUNDS: "Abilita Souni",
BUTTON_DISABLE_SOUNDS: "Disabilita Suoni",
BUTTON_RETURN_LOBBY: "Ritorna alla Lobby",
Expand Down
3 changes: 2 additions & 1 deletion src/Model/ClientMessage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { GameAction } from "../Scenes/Game/Model/GameAction";
import { GameOptions } from "../Scenes/Game/Model/GameUpdate";
import { Empty, LobbyId, LobbyInfo, UserId, UserInfo } from "./ServerMessage";
import { Empty, LobbyId, LobbyInfo, LobbyTeam, UserId, UserInfo } from "./ServerMessage";

export interface ClientConnect {
user: UserInfo;
Expand All @@ -22,6 +22,7 @@ export type ClientMessage =
{lobby_leave: Empty } |
{lobby_chat: { message: string }} |
{lobby_return: Empty } |
{user_set_team: LobbyTeam} |
{game_start: Empty } |
{game_rejoin: { user_id: UserId }} |
{game_action: GameAction};
3 changes: 3 additions & 0 deletions src/Model/ServerMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export interface ClientAccepted {

export type LobbyStateEnum = 'waiting' | 'playing' | 'finished';

export type LobbyTeam = 'game_player' | 'game_spectator';

export interface LobbyUpdate {
lobby_id: LobbyId;
name: string;
Expand Down Expand Up @@ -50,6 +52,7 @@ export type LobbyChatFlag = 'is_read';
export interface LobbyAddUser {
user_id: UserId;
user: UserInfo;
team: LobbyTeam;
flags: LobbyChatFlag[];
lifetime: Milliseconds;
}
Expand Down
6 changes: 3 additions & 3 deletions src/Model/UseBangConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ function handleUpdateLobbies({ lobby_id, name, num_players, num_spectators, max_
};
}

function handleLobbyAddUser({ user_id, user: { name, profile_image }, flags, lifetime }: LobbyAddUser): UpdateFunction<LobbyState> {
function handleLobbyAddUser({ user_id, user: { name, profile_image }, team, flags, lifetime }: LobbyAddUser): UpdateFunction<LobbyState> {
return lobbyState => {
let chatMessages = lobbyState.chatMessages;
let users = [...lobbyState.users];
let users = lobbyState.users.slice();

const newUser: UserValue = { id: user_id, name, propic: deserializeImage(profile_image), lifetime };
const newUser: UserValue = { id: user_id, name, propic: deserializeImage(profile_image), team, lifetime };
let index = users.findIndex(user => user.id === user_id);
if (index >= 0) {
users[index] = newUser;
Expand Down
5 changes: 2 additions & 3 deletions src/Scenes/Game/GameUsersView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,9 @@ function GameUserPlayer({ player, user, myUserId }: GameUserProps) {
return <div className="game-player-icons">
{ role && <div className={`player-icon ${role}`}/> }
{ isWinner && <div className="player-icon icon-winner"/> }
{ player ? isPlayerDead(player) && (isPlayerGhost(player)
{ player && isPlayerDead(player) && (isPlayerGhost(player)
? <div className="player-icon icon-ghost"/>
: <div className="player-icon icon-dead"/> )
: <div className="player-icon icon-spectator"/> }
: <div className="player-icon icon-dead"/> ) }
</div>;
}, [player]);

Expand Down
7 changes: 5 additions & 2 deletions src/Scenes/Lobby/LobbyUser.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ReactNode } from "react";
import getLabel from "../../Locale/GetLabel";
import { Milliseconds, UserId } from "../../Model/ServerMessage";
import { LobbyTeam, Milliseconds, UserId } from "../../Model/ServerMessage";
import { ImageSrc } from "../../Utils/ImageSerial";
import "./Style/LobbyUser.css";
import defaultUserPropic from "/media/icon_default_user.png";
Expand All @@ -11,6 +11,7 @@ export interface UserValue {
id: UserId;
name: string;
propic?: ImageSrc;
team: LobbyTeam;
lifetime: Milliseconds;
}

Expand Down Expand Up @@ -45,7 +46,9 @@ export default function LobbyUser({ isSelf, user, align, children }: LobbyUserPr
<img src={getPropic(user)} alt="" />
</div>
<div className={`lobby-username ${isSelf ? 'lobby-username-self' : ''}`}>
{getUsername(user)}{timerWidget}
{getUsername(user)}
{user?.team === 'game_spectator' && <div className="mx-1 align-middle player-icon icon-spectator"/> }
{timerWidget}
</div>
{children}
</div>
Expand Down

0 comments on commit 00c697c

Please sign in to comment.