import React, { useEffect, useState } from "react";
import { commands, GameSettings, LobbyState, PingStartCondition, PlayerProfile } from "@/bindings";
import { useTauriEvent } from "@/lib/hooks";
import ProfilePicture, { iconForDecor, ProfileDecor } from "./ProfilePicture";
import { defaultSettings } from "./MenuScreen";
import { ask } from "@tauri-apps/plugin-dialog";
import {
IconArrowBigLeftLinesFilled,
IconCircleCheckFilled,
IconCircleDashedPlus,
IconFlagFilled,
IconInfoCircleFilled,
IconSettingsFilled
} from "@tabler/icons-react";
import LoadingCover from "./LoadingCover";
import GameSettingsModal from "./game-settings/GameSettingsModal";
function ProfileList({
profiles,
decoration,
emptyText
}: {
profiles: [string, PlayerProfile][];
decoration: ProfileDecor;
emptyText: string;
}) {
return (
{profiles.length === 0 &&
{emptyText}}
{profiles.map(([k, p]) => (
))}
);
}
function TeamButton({
onClick,
active,
deco,
text
}: {
onClick: () => void;
active: boolean;
deco: ProfileDecor;
text: string;
}) {
const Icon = iconForDecor(deco);
return (
);
}
const initLobbyState: LobbyState = {
profiles: {},
join_code: "",
teams: {},
self_id: "",
is_host: false,
settings: defaultSettings()
};
export default function LobbyScreen() {
const [lobbyState, setLobbyState] = useState(initLobbyState);
const [loadingCover, setLoadingCover] = useState(true);
const [settingOpen, setSettingsOpen] = useState(false);
useEffect(() => {
let cancel = false;
const clear = setTimeout(() => {
commands.getLobbyState().then((state) => {
if (!cancel) {
setLobbyState(state);
setLoadingCover(false);
}
});
}, 300);
return () => {
cancel = true;
clearTimeout(clear);
};
}, [setLobbyState]);
useTauriEvent("lobbyStateUpdate", () => {
commands.getLobbyState().then((state) => {
setLobbyState(state);
});
});
const profiles = Object.entries(lobbyState.profiles).filter(([_, p]) => p !== undefined) as [
string,
PlayerProfile
][];
const seekers = profiles.filter(([id, _]) => lobbyState.teams[id] ?? false);
const hiders = profiles.filter(([id, _]) => !(lobbyState.teams[id] ?? false));
const isSeeker = lobbyState.teams[lobbyState.self_id] ?? false;
const onLeaveLobby = () => {
// Don't prompt since the lobby is empty (besides us obv)
// <= even though it should never be 0... hopefully....
if (lobbyState.is_host && profiles.length <= 1) {
commands.quitToMenu();
return;
}
const hostMsg = lobbyState.is_host ? " You are the host so this will cancel the lobby" : "";
const msg = `Are you sure you want to leave this lobby?${hostMsg}`;
ask(msg, {
title: "Leave Lobby",
kind: lobbyState.is_host ? "warning" : "info"
}).then((choice) => {
if (choice) {
commands.quitToMenu();
}
});
};
const canStart = lobbyState.is_host && seekers.length !== 0 && hiders.length !== 0;
const onStartGame = () => {
if (canStart) {
setLoadingCover(true);
ask(
"Are you ready to start the game? New players will be unable to join. The hiding timer will begin the moment you press start."
)
.then((choice) => {
if (choice) {
commands.hostStartGame().finally(() => {
setLoadingCover(false);
});
} else {
setLoadingCover(false);
}
})
.catch(() => {
setLoadingCover(false);
});
}
};
const onOpenSettings = () => {
setSettingsOpen(true);
};
const onSettingsSave = (settings: GameSettings) => {
commands.hostUpdateSettings(settings);
setSettingsOpen(false);
};
return (
<>
{settingOpen && (
)}
Lobby
Join: {lobbyState.join_code}
commands.switchTeams(true)}
active={isSeeker}
text="Seekers"
deco="seeker"
/>
{lobbyState.is_host && (
)}
{lobbyState.is_host && (
)}
commands.switchTeams(false)}
active={!isSeeker}
text="Hiders"
deco="hider"
/>
>
);
}