2026-10-16 09:35:39 +03:00
|
|
|
import { CommonMancalaGame } from 'mancala.js';
|
2022-07-30 14:17:16 +03:00
|
|
|
import * as React from 'react';
|
2026-10-16 00:27:06 +03:00
|
|
|
import { FunctionComponent, useEffect, useState } from 'react';
|
2026-10-16 09:35:39 +03:00
|
|
|
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';
|
2026-10-16 00:27:06 +03:00
|
|
|
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';
|
2024-06-17 23:50:13 +03:00
|
|
|
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
|
2026-10-16 09:35:39 +03:00
|
|
|
}> = ({ context }) => {
|
2022-07-30 14:17:16 +03:00
|
|
|
|
|
|
|
|
let navigate = useNavigate();
|
|
|
|
|
|
2024-06-17 23:50:13 +03:00
|
|
|
const { t } = useTranslation();
|
|
|
|
|
|
2026-10-16 00:27:06 +03:00
|
|
|
// 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);
|
2026-10-16 00:27:06 +03:00
|
|
|
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);
|
2026-10-16 00:27:06 +03:00
|
|
|
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
|
|
|
|
2026-10-16 09:35:39 +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>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-16 09:35:39 +03:00
|
|
|
export default LobyPage;
|