mancala/apps/frontend/src/components/home/LiveGamesSection.tsx
Halit Aksoy 9619825605 feat(frontend): lay out the home page in the new design
The game in progress comes first with a large mini board; live,
popular and recent games are grids of cards with the score, a mini
board and a status pill. Live and popular games are shown together;
live games are hidden while nothing is being played.
2026-10-16 10:21:46 +03:00

52 lines
2.1 KiB
TypeScript

import * as React from "react";
import { FunctionComponent, useEffect, useState } from "react";
import {
channel_on_live_games,
channel_subscribe_live_games,
channel_unsubscribe_live_games,
LiveGameSummary,
} from "@mancala/core";
import { useTranslation } from "react-i18next";
import { Context } from "../../context/context";
import GameCard from "./GameCard";
import HomeSection from "./HomeSection";
// Live games, updated as they are played; hidden while nothing is being played.
const LiveGamesSection: FunctionComponent<{ context: Context }> = ({ context }) => {
const { t } = useTranslation();
const [games, setGames] = useState<LiveGameSummary[]>([]);
useEffect(() => {
const onLiveGames = (message: { games: LiveGameSummary[] }) => setGames(message.games);
// Subscribe whenever the connection is (re)established; the server forgets subscriptions of offline users.
const subscribe = () => context.rtmt.sendMessage(channel_subscribe_live_games, {});
context.rtmt.addMessageListener(channel_on_live_games, onLiveGames);
context.rtmt.on("open", subscribe);
if (context.rtmt.connectionState === "connected") subscribe();
return () => {
context.rtmt.off("open", subscribe);
context.rtmt.removeMessageListener(channel_on_live_games, onLiveGames);
if (context.rtmt.connectionState === "connected") context.rtmt.sendMessage(channel_unsubscribe_live_games, {});
};
}, []);
if (games.length === 0) return <></>;
return (
<HomeSection title={t("LiveGames")} subtitle={t("BeingPlayedNow")}>
{games.map((game) => (
<GameCard
key={game.id}
id={game.id}
player1={game.player1}
player2={game.player2}
board={game.board}
status={t("Live")}
statusKind="live"
details={`${t("Watching", { count: game.spectatorCount })} · ${t("MoveNumber", { number: game.moveCount })}`} />
))}
</HomeSection>
);
};
export default LiveGamesSection;