]> git.localhorst.tv Git - alttp.git/blob - resources/js/pages/GuessingGameControls.js
save tracker config
[alttp.git] / resources / js / pages / GuessingGameControls.js
1 import axios from 'axios';
2 import React from 'react';
3 import { Alert, Col, Container, Form, Navbar, Row } from 'react-bootstrap';
4 import { Helmet } from 'react-helmet';
5 import { useTranslation } from 'react-i18next';
6 import { useParams } from 'react-router-dom';
7 import toastr from 'toastr';
8
9 import User from '../app/User';
10 import ChannelSelect from '../components/common/ChannelSelect';
11 import GuessingGameControls from '../components/twitch-bot/GuessingGameControls';
12 import GuessingGuess from '../components/twitch-bot/GuessingGuess';
13 import GuessingWinner from '../components/twitch-bot/GuessingWinner';
14 import { patchGuess, patchWinner } from '../helpers/Channel';
15
16 export const Component = () => {
17         const [channel, setChannel] = React.useState(null);
18         const [guesses, setGuesses] = React.useState([]);
19         const [winners, setWinners] = React.useState([]);
20
21         const { channelId } = useParams();
22         const { t } = useTranslation();
23
24         React.useEffect(() => {
25                 if (!channelId) return;
26                 const fetchChannel = async () => {
27                         const response = await axios.get(`/api/channels`, {
28                                 params: {
29                                         id: [channelId],
30                                         manageable: 1,
31                                 },
32                         });
33                         if (response.data.length) {
34                                 setChannel(response.data[0]);
35                         }
36                 };
37                 fetchChannel();
38         }, [channelId]);
39
40         React.useEffect(() => {
41                 if (!channel) {
42                         setGuesses([]);
43                         setWinners([]);
44                         return;
45                 }
46                 if (channel.guessing_type) {
47                         axios.get(`/api/channels/${channel.id}/guessing-game/${channel.guessing_type}`)
48                                 .then(res => {
49                                         res.data.guesses.forEach(g => {
50                                                 setGuesses(gs => patchGuess(gs, g));
51                                         });
52                                         res.data.winners.forEach(w => {
53                                                 setWinners(ws => patchGuess(ws, w));
54                                         });
55                                 });
56                 }
57                 window.Echo.private(`Channel.${channel.id}`)
58                         .listen('.GuessingGuessCreated', (e) => {
59                                 setGuesses(gs => patchGuess(gs, e.model));
60                         })
61                         .listen('.GuessingWinnerCreated', (e) => {
62                                 setWinners(ws => patchWinner(ws, e.model));
63                         })
64                         .listen('.ChannelUpdated', (e) => {
65                                 setChannel(c => ({ ...c, ...e.model }));
66                         });
67                 return () => {
68                         window.Echo.leave(`Channel.${channel.id}`);
69                 };
70         }, [channel && channel.id]);
71
72         React.useEffect(() => {
73                 const cutoff = channel && channel.guessing_start;
74                 if (cutoff) {
75                         setGuesses(gs => gs.filter(g => g.created_at >= cutoff));
76                         setWinners(ws => ws.filter(w => w.created_at >= cutoff));
77                 }
78         }, [channel && channel.guessing_start]);
79
80         const onCancel = React.useCallback(async () => {
81                 try {
82                         const rsp = await axios.post(
83                                 `/api/channels/${channel.id}/guessing-game/gtbk`,
84                                 { action: 'cancel' },
85                         );
86                         setChannel(rsp.data);
87                 } catch (e) {
88                         toastr.error(t('twitchBot.controlError'));
89                 }
90         }, [channel]);
91
92         const onSolve = React.useCallback(async (solution) => {
93                 try {
94                         const rsp = await axios.post(
95                                 `/api/channels/${channel.id}/guessing-game/gtbk`,
96                                 { action: 'solve', solution },
97                         );
98                         setChannel(rsp.data);
99                 } catch (e) {
100                         toastr.error(t('twitchBot.controlError'));
101                 }
102         }, [channel]);
103
104         const onStart = React.useCallback(async () => {
105                 try {
106                         const rsp = await axios.post(
107                                 `/api/channels/${channel.id}/guessing-game/gtbk`,
108                                 { action: 'start' },
109                         );
110                         setChannel(rsp.data);
111                 } catch (e) {
112                         toastr.error(t('twitchBot.controlError'));
113                 }
114         }, [channel]);
115
116         const onStop = React.useCallback(async () => {
117                 try {
118                         const rsp = await axios.post(
119                                 `/api/channels/${channel.id}/guessing-game/gtbk`,
120                                 { action: 'stop' },
121                         );
122                         setChannel(rsp.data);
123                 } catch (e) {
124                         toastr.error(t('twitchBot.controlError'));
125                 }
126         }, [channel]);
127
128         return <>
129                 <Helmet>
130                         <title>Guessing Game Controls</title>
131                 </Helmet>
132                 <Navbar id="header" bg="dark" variant="dark">
133                         <Container fluid>
134                                 <Form.Control
135                                         as={ChannelSelect}
136                                         autoSelect
137                                         joinable
138                                         manageable
139                                         onChange={({ channel }) => { setChannel(channel); }}
140                                         readOnly={!!(channelId && channel)}
141                                         value={channel ? channel.id : channelId}
142                                 />
143                                 <User />
144                         </Container>
145                 </Navbar>
146                 <Container fluid>
147                 {channel ? <Row>
148                         <Col md={12} lg={6}>
149                                 <GuessingGameControls
150                                         channel={channel}
151                                         onCancel={onCancel}
152                                         onSolve={onSolve}
153                                         onStart={onStart}
154                                         onStop={onStop}
155                                 />
156                         </Col>
157                         <Col md={6} lg={3}>
158                                 <h3 className="mt-3">{t('twitchBot.guessingGame.winners')}</h3>
159                                 {winners.map(winner =>
160                                         <GuessingWinner key={winner.id} winner={winner} />
161                                 )}
162                         </Col>
163                         <Col md={6} lg={3}>
164                                 <h3 className="mt-3">{t('twitchBot.guessingGame.guesses')}</h3>
165                                 {guesses.map(guess =>
166                                         <GuessingGuess guess={guess} key={guess.id} />
167                                 )}
168                         </Col>
169                 </Row> :
170                         <Alert variant="info">
171                                 {t('twitchBot.selectChannel')}
172                         </Alert>
173                 }
174                 </Container>
175         </>;
176 };