+import axios from 'axios';
+import React from 'react';
+import { Alert, Col, Container, Form, Navbar, Row } from 'react-bootstrap';
+import { Helmet } from 'react-helmet';
+import { useTranslation } from 'react-i18next';
+import toastr from 'toastr';
+
+import User from '../app/User';
+import ChannelSelect from '../components/common/ChannelSelect';
+import GuessingGameControls from '../components/twitch-bot/GuessingGameControls';
+import GuessingGuess from '../components/twitch-bot/GuessingGuess';
+import GuessingWinner from '../components/twitch-bot/GuessingWinner';
+import { patchGuess, patchWinner } from '../helpers/Channel';
+
+export const Component = () => {
+ const [channel, setChannel] = React.useState(null);
+ const [guesses, setGuesses] = React.useState([]);
+ const [winners, setWinners] = React.useState([]);
+
+ const { t } = useTranslation();
+
+ React.useEffect(() => {
+ if (!channel) {
+ setGuesses([]);
+ setWinners([]);
+ return;
+ }
+ if (channel.guessing_type) {
+ axios.get(`/api/channels/${channel.id}/guessing-game/${channel.guessing_type}`)
+ .then(res => {
+ res.data.guesses.forEach(g => {
+ setGuesses(gs => patchGuess(gs, g));
+ });
+ res.data.winners.forEach(w => {
+ setWinners(ws => patchGuess(ws, w));
+ });
+ });
+ }
+ window.Echo.private(`Channel.${channel.id}`)
+ .listen('.GuessingGuessCreated', (e) => {
+ setGuesses(gs => patchGuess(gs, e.model));
+ })
+ .listen('.GuessingWinnerCreated', (e) => {
+ setWinners(ws => patchWinner(ws, e.model));
+ })
+ .listen('.ChannelUpdated', (e) => {
+ setChannel(c => ({ ...c, ...e.model }));
+ });
+ return () => {
+ window.Echo.leave(`Channel.${channel.id}`);
+ };
+ }, [channel && channel.id]);
+
+ React.useEffect(() => {
+ const cutoff = channel && channel.guessing_start;
+ if (cutoff) {
+ setGuesses(gs => gs.filter(g => g.created_at >= cutoff));
+ setWinners(ws => ws.filter(w => w.created_at >= cutoff));
+ }
+ }, [channel && channel.guessing_start]);
+
+ const onCancel = React.useCallback(async () => {
+ try {
+ const rsp = await axios.post(
+ `/api/channels/${channel.id}/guessing-game/gtbk`,
+ { action: 'cancel' },
+ );
+ setChannel(rsp.data);
+ } catch (e) {
+ toastr.error(t('twitchBot.controlError'));
+ }
+ }, [channel]);
+
+ const onSolve = React.useCallback(async (solution) => {
+ try {
+ const rsp = await axios.post(
+ `/api/channels/${channel.id}/guessing-game/gtbk`,
+ { action: 'solve', solution },
+ );
+ setChannel(rsp.data);
+ } catch (e) {
+ toastr.error(t('twitchBot.controlError'));
+ }
+ }, [channel]);
+
+ const onStart = React.useCallback(async () => {
+ try {
+ const rsp = await axios.post(
+ `/api/channels/${channel.id}/guessing-game/gtbk`,
+ { action: 'start' },
+ );
+ setChannel(rsp.data);
+ } catch (e) {
+ toastr.error(t('twitchBot.controlError'));
+ }
+ }, [channel]);
+
+ const onStop = React.useCallback(async () => {
+ try {
+ const rsp = await axios.post(
+ `/api/channels/${channel.id}/guessing-game/gtbk`,
+ { action: 'stop' },
+ );
+ setChannel(rsp.data);
+ } catch (e) {
+ toastr.error(t('twitchBot.controlError'));
+ }
+ }, [channel]);
+
+ return <>
+ <Helmet>
+ <title>Guessing Game Controls</title>
+ </Helmet>
+ <Navbar id="header" bg="dark" variant="dark">
+ <Container fluid>
+ <Form.Control
+ as={ChannelSelect}
+ autoSelect
+ joinable
+ manageable
+ onChange={({ channel }) => { setChannel(channel); }}
+ value={channel ? channel.id : ''}
+ />
+ <User />
+ </Container>
+ </Navbar>
+ <Container fluid>
+ {channel ? <Row>
+ <Col md={12} lg={6}>
+ <GuessingGameControls
+ channel={channel}
+ onCancel={onCancel}
+ onSolve={onSolve}
+ onStart={onStart}
+ onStop={onStop}
+ />
+ </Col>
+ <Col md={6} lg={3}>
+ <h3 className="mt-3">{t('twitchBot.guessingGame.winners')}</h3>
+ {winners.map(winner =>
+ <GuessingWinner key={winner.id} winner={winner} />
+ )}
+ </Col>
+ <Col md={6} lg={3}>
+ <h3 className="mt-3">{t('twitchBot.guessingGame.guesses')}</h3>
+ {guesses.map(guess =>
+ <GuessingGuess guess={guess} key={guess.id} />
+ )}
+ </Col>
+ </Row> :
+ <Alert variant="info">
+ {t('twitchBot.selectChannel')}
+ </Alert>
+ }
+ </Container>
+ </>;
+};