mancala/apps/frontend/src/routes/LobyPage.tsx

104 lines
3.8 KiB
TypeScript
Raw Normal View History

import { CommonMancalaGame } from 'mancala.js';
2022-07-30 14:17:16 +03:00
import * as React from 'react';
import { FunctionComponent, useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import AppHeader from '../components/headerbar/AppHeader';
2022-07-30 14:17:16 +03:00
import PageContainer from '../components/PageContainer';
import { channel_cancel_new_game, channel_on_game_start, channel_on_new_game_rejected } from '@mancala/core';
2022-07-30 14:17:16 +03:00
import { Context } from '../context/context';
import { Theme } from '@mancala/core';
import { useTranslation } from 'react-i18next';
2022-07-30 14:17:16 +03:00
const LobyPage: FunctionComponent<{
context: Context,
userKey?: string,
theme: Theme
}> = ({ context }) => {
2022-07-30 14:17:16 +03:00
let navigate = useNavigate();
const { t } = useTranslation();
// Set when the server refuses a new game because the user has one in progress.
const [activeGameId, setActiveGameId] = useState<string | undefined>(undefined);
const onNewGameRejected = (message: { gameId: string }) => setActiveGameId(message.gameId);
2022-09-02 00:03:17 +03:00
const onGameStart = (message: Object) => {
const newGame: CommonMancalaGame = message as CommonMancalaGame;
navigate(`/game/${newGame.id}`)
}
2024-03-31 17:54:07 +03:00
const onCancelNewGameClick = () => {
if (context.rtmt.connectionState === "connected") {
context.rtmt.sendMessage(channel_cancel_new_game, "");
}
navigate("/")
}
2022-07-30 14:17:16 +03:00
useEffect(() => {
2022-09-02 00:03:17 +03:00
context.rtmt.addMessageListener(channel_on_game_start, onGameStart);
context.rtmt.addMessageListener(channel_on_new_game_rejected, onNewGameRejected);
2022-07-30 14:17:16 +03:00
context.rtmt.sendMessage("new_game", {});
2022-09-02 00:03:17 +03:00
return () => {
context.rtmt.removeMessageListener(channel_on_game_start, onGameStart);
context.rtmt.removeMessageListener(channel_on_new_game_rejected, onNewGameRejected);
2022-09-02 00:03:17 +03:00
}
2022-07-30 14:17:16 +03:00
}, []);
2024-03-31 17:54:07 +03:00
return (
<PageContainer>
<AppHeader context={context} />
<main className="wrap">
<section className="search panel" aria-live="polite">
{!activeGameId && <span className="dot" />}
<h1>{activeGameId ? t("GameInProgress") : t("SearchingOpponent")}</h1>
{!activeGameId && <p>{`${t("PleaseWait")}...`}</p>}
<div className="actions">
{activeGameId && (
<button className="btn pri" onClick={() => navigate(`/game/${activeGameId}`)}>{t("Continue")}</button>
)}
<button className="btn ghost" onClick={onCancelNewGameClick}>{t("Cancel")}</button>
</div>
</section>
</main>
<style jsx>{`
.search {
align-self: center;
width: 100%;
max-width: 460px;
margin-top: 8vh;
padding: 32px;
box-sizing: border-box;
border-radius: 32px;
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
text-align: center;
}
.dot {
width: 14px;
height: 14px;
color: var(--accent);
}
h1 {
margin: 0;
font-size: 28px;
letter-spacing: -.02em;
}
p {
margin: 0;
color: var(--muted);
}
.actions {
display: flex;
gap: 10px;
margin-top: 10px;
}
`}</style>
2022-07-30 14:17:16 +03:00
</PageContainer>
);
}
export default LobyPage;