]> git.localhorst.tv Git - alttp.git/blobdiff - resources/js/pages/GuessingGameControls.js
guessing game controls
[alttp.git] / resources / js / pages / GuessingGameControls.js
diff --git a/resources/js/pages/GuessingGameControls.js b/resources/js/pages/GuessingGameControls.js
new file mode 100644 (file)
index 0000000..1c84689
--- /dev/null
@@ -0,0 +1,157 @@
+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>
+       </>;
+};