]> git.localhorst.tv Git - alttp.git/blob - resources/js/components/twitch-bot/Controls.js
more classification
[alttp.git] / resources / js / components / twitch-bot / Controls.js
1 import axios from 'axios';
2 import React from 'react';
3 import { Alert, Button, Col, Form, Row } from 'react-bootstrap';
4 import { useTranslation } from 'react-i18next';
5 import toastr from 'toastr';
6
7 import ChatSettingsForm from './ChatSettingsForm';
8 import CommandDialog from './CommandDialog';
9 import Commands from './Commands';
10 import GuessingSettingsForm from './GuessingSettingsForm';
11 import ChatBotLog from '../chat-bot-logs/ChatBotLog';
12 import ChannelSelect from '../common/ChannelSelect';
13 import Icon from '../common/Icon';
14 import ToggleSwitch from '../common/ToggleSwitch';
15
16 const CHAT_CATEGORIES = [
17         'unclassified',
18         'hi',
19         'gl',
20         'gg',
21         'love',
22         'lol',
23         'wtf',
24         'pog',
25         'hype',
26         'o7',
27         'question',
28         'thx',
29 ];
30
31 const Controls = () => {
32         const [channel, setChannel] = React.useState(null);
33         const [chatText, setChatText] = React.useState('');
34         const [editCommand, setEditCommand] = React.useState('');
35         const [editCommandSettings, setEditCommandSettings] = React.useState({});
36         const [showCommandDialog, setShowCommandDialog] = React.useState(false);
37
38         const { t } = useTranslation();
39
40         const chat = React.useCallback(async (text, bot_nick) => {
41                 try {
42                         await axios.post(`/api/channels/${channel.id}/chat`, {
43                                 text,
44                                 bot_nick,
45                         });
46                         toastr.success(t('twitchBot.chatSuccess'));
47                 } catch (e) {
48                         toastr.error(t('twitchBot.chatError'));
49                 }
50         }, [channel, chatText, t]);
51
52         const randomChat = React.useCallback(async (category) => {
53                 try {
54                         await axios.post(`/api/channels/${channel.id}/chat`, {
55                                 bot_nick: 'horstiebot',
56                                 category,
57                         });
58                         toastr.success(t('twitchBot.chatSuccess'));
59                 } catch (e) {
60                         toastr.error(t('twitchBot.chatError'));
61                 }
62         }, [channel, chatText, t]);
63
64         const join = React.useCallback(async (bot_nick) => {
65                 try {
66                         const rsp = await axios.post(`/api/channels/${channel.id}/join`, { bot_nick });
67                         setChannel(rsp.data);
68                         toastr.success(t('twitchBot.joinSuccess'));
69                 } catch (e) {
70                         toastr.error(t('twitchBot.joinError'));
71                 }
72         }, [channel, t]);
73
74         const part = React.useCallback(async (bot_nick) => {
75                 try {
76                         const rsp = await axios.post(`/api/channels/${channel.id}/part`, { bot_nick });
77                         setChannel(rsp.data);
78                         toastr.success(t('twitchBot.partSuccess'));
79                 } catch (e) {
80                         toastr.error(t('twitchBot.partError'));
81                 }
82         }, [channel, t]);
83
84         const saveChatSettings = React.useCallback(async (values) => {
85                 try {
86                         const rsp = await axios.post(`/api/channels/${channel.id}/chat-settings`, values);
87                         setChannel(rsp.data);
88                         toastr.success(t('twitchBot.saveSuccess'));
89                 } catch (e) {
90                         toastr.error(t('twitchBot.saveError'));
91                 }
92         }, [channel, t]);
93
94         const onAddCommand = React.useCallback(() => {
95                 setEditCommand('');
96                 setEditCommandSettings({});
97                 setShowCommandDialog(true);
98         }, [channel]);
99
100         const onEditCommand = React.useCallback((name, settings) => {
101                 setEditCommand(name);
102                 setEditCommandSettings(settings);
103                 setShowCommandDialog(true);
104         }, [channel]);
105
106         const onRemoveCommand = React.useCallback(async (name) => {
107                 try {
108                         const rsp = await axios.delete(`/api/channels/${channel.id}/commands/${name}`);
109                         setChannel(rsp.data);
110                         toastr.success(t('twitchBot.saveSuccess'));
111                 } catch (e) {
112                         toastr.error(t('twitchBot.saveError'));
113                 }
114         }, [channel]);
115
116         const saveCommand = React.useCallback(async (values) => {
117                 try {
118                         const rsp = await axios.put(
119                                 `/api/channels/${channel.id}/commands/${values.name}`,
120                                 values,
121                         );
122                         setChannel(rsp.data);
123                         setShowCommandDialog(false);
124                         setEditCommand('');
125                         setEditCommandSettings({});
126                         toastr.success(t('twitchBot.saveSuccess'));
127                 } catch (e) {
128                         toastr.error(t('twitchBot.saveError'));
129                         throw e;
130                 }
131         }, [channel]);
132
133         const saveGuessingGame = React.useCallback(async (values) => {
134                 try {
135                         const rsp = await axios.put(
136                                 `/api/channels/${channel.id}/guessing-game/${values.name}`,
137                                 values,
138                         );
139                         setChannel(rsp.data);
140                         toastr.success(t('twitchBot.saveSuccess'));
141                 } catch (e) {
142                         toastr.error(t('twitchBot.saveError'));
143                         throw e;
144                 }
145         }, [channel]);
146
147         return <>
148                 <Row className="mb-4">
149                         <Form.Group as={Col} md={6}>
150                                 <Form.Label>{t('twitchBot.channel')}</Form.Label>
151                                 <Form.Control
152                                         as={ChannelSelect}
153                                         autoSelect
154                                         joinable
155                                         manageable
156                                         onChange={({ channel }) => { setChannel(channel); }}
157                                         value={channel ? channel.id : ''}
158                                 />
159                         </Form.Group>
160                         {channel ? <>
161                                 <Form.Group as={Col} md={3}>
162                                         <Form.Label>{t('twitchBot.joinApp')}</Form.Label>
163                                         <div>
164                                                 <Form.Control
165                                                         as={ToggleSwitch}
166                                                         onChange={({ target: { value } }) => {
167                                                                 if (value) {
168                                                                         join('localhorsttv');
169                                                                 } else {
170                                                                         part('localhorsttv');
171                                                                 }
172                                                         }}
173                                                         value={channel.join}
174                                                 />
175                                         </div>
176                                 </Form.Group>
177                                 <Form.Group as={Col} md={3}>
178                                         <Form.Label>{t('twitchBot.joinChat')}</Form.Label>
179                                         <div>
180                                                 <Form.Control
181                                                         as={ToggleSwitch}
182                                                         onChange={({ target: { value } }) => {
183                                                                 if (value) {
184                                                                         join('horstiebot');
185                                                                 } else {
186                                                                         part('horstiebot');
187                                                                 }
188                                                         }}
189                                                         value={channel.chat}
190                                                 />
191                                         </div>
192                                 </Form.Group>
193                         </> : null}
194                 </Row>
195                 {channel ?
196                         <Row>
197                                 <Col className="mt-5" md={6}>
198                                         <h3>{t('twitchBot.chat')}</h3>
199                                         <Form.Group>
200                                                 <Form.Label>{t('twitchBot.chat')}</Form.Label>
201                                                 <Form.Control
202                                                         as="textarea"
203                                                         onChange={({ target: { value } }) => {
204                                                                 setChatText(value);
205                                                         }}
206                                                         value={chatText}
207                                                 />
208                                                 <div className="button-bar">
209                                                         <Button
210                                                                 className="mt-2"
211                                                                 disabled={!chatText || !channel.join}
212                                                                 onClick={() => {
213                                                                         if (chatText) chat(chatText, 'localhorsttv');
214                                                                 }}
215                                                                 variant="twitch"
216                                                         >
217                                                                 {t('twitchBot.sendApp')}
218                                                         </Button>
219                                                         <Button
220                                                                 className="mt-2"
221                                                                 disabled={!chatText || !channel.chat}
222                                                                 onClick={() => {
223                                                                         if (chatText) chat(chatText, 'horstiebot');
224                                                                 }}
225                                                                 variant="twitch"
226                                                         >
227                                                                 {t('twitchBot.sendChat')}
228                                                         </Button>
229                                                 </div>
230                                         </Form.Group>
231                                         <h3 className="mt-3">{t('twitchBot.randomChat')}</h3>
232                                         <div className="button-bar">
233                                                 {CHAT_CATEGORIES.map(category =>
234                                                         <Button
235                                                                 key={category}
236                                                                 onClick={() => { randomChat(category); }}
237                                                                 variant="outline-secondary"
238                                                         >
239                                                                 {t(`twitchBot.chatCategories.${category}`)}
240                                                         </Button>
241                                                 )}
242                                         </div>
243                                 </Col>
244                                 <Col className="mt-5" md={6}>
245                                         <div className="d-flex justify-content-between">
246                                                 <h3>{t('twitchBot.chatSettings')}</h3>
247                                                 <div className="button-bar">
248                                                         <ChatBotLog id={channel.id} />
249                                                 </div>
250                                         </div>
251                                         <ChatSettingsForm channel={channel} onSubmit={saveChatSettings} />
252                                 </Col>
253                                 <Col className="mt-5" md={12}>
254                                         <h3>{t('twitchBot.commands')}</h3>
255                                         <Commands
256                                                 channel={channel}
257                                                 onEditCommand={onEditCommand}
258                                                 onRemoveCommand={onRemoveCommand}
259                                         />
260                                         <CommandDialog
261                                                 name={editCommand}
262                                                 onHide={() => {
263                                                         setShowCommandDialog(false);
264                                                         setEditCommand('');
265                                                         setEditCommandSettings({});
266                                                 }}
267                                                 onSubmit={saveCommand}
268                                                 settings={editCommandSettings}
269                                                 show={showCommandDialog}
270                                         />
271                                         <div>
272                                                 <Button onClick={onAddCommand} variant="primary">
273                                                         {t('twitchBot.addCommand')}
274                                                 </Button>
275                                         </div>
276                                 </Col>
277                                 <Col className="mt-5" md={12}>
278                                         <div className="d-flex align-items-end justify-content-between">
279                                                 <h3>{t('twitchBot.guessingGame.settings')}</h3>
280                                                 <div className="button-bar">
281                                                         {channel.access_key ?
282                                                                 <Button
283                                                                         href={`/guessing-game/monitor/${channel.access_key}`}
284                                                                         target="_blank"
285                                                                         title={t('button.browserSource')}
286                                                                         variant="outline-secondary"
287                                                                 >
288                                                                         <Icon.BROWSER_SOURCE title="" />
289                                                                 </Button>
290                                                         : null}
291                                                         <Button
292                                                                 onClick={() => {
293                                                                         window.open(
294                                                                                 `/guessing-game/controls/${channel.id}`,
295                                                                                 '',
296                                                                                 'width=640,height=800,titlebar=0,menubar=0,toolbar=0',
297                                                                         );
298                                                                 }}
299                                                                 title={t('twitchBot.guessingGame.popoutControls')}
300                                                                 variant="outline-secondary"
301                                                         >
302                                                                 <Icon.OPEN title="" />
303                                                         </Button>
304                                                 </div>
305                                         </div>
306                                         <GuessingSettingsForm
307                                                 name="gtbk"
308                                                 onSubmit={saveGuessingGame}
309                                                 settings={channel.guessing_settings?.gtbk || {}}
310                                         />
311                                 </Col>
312                         </Row>
313                 :
314                         <Alert variant="info">
315                                 {t('twitchBot.selectChannel')}
316                         </Alert>
317                 }
318         </>;
319 };
320
321 export default Controls;