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