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