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';
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';
16 const CHAT_CATEGORIES = [
38 const Controls = () => {
39 const [channel, setChannel] = React.useState(null);
40 const [chatText, setChatText] = React.useState('');
41 const [editCommand, setEditCommand] = React.useState('');
42 const [editCommandSettings, setEditCommandSettings] = React.useState({});
43 const [showCommandDialog, setShowCommandDialog] = React.useState(false);
45 const { t } = useTranslation();
47 const chat = React.useCallback(async (text, bot_nick) => {
49 await axios.post(`/api/channels/${channel.id}/chat`, {
53 toastr.success(t('twitchBot.chatSuccess'));
55 toastr.error(t('twitchBot.chatError'));
57 }, [channel, chatText, t]);
59 const randomChat = React.useCallback(async (category) => {
61 await axios.post(`/api/channels/${channel.id}/chat`, {
62 bot_nick: 'horstiebot',
65 toastr.success(t('twitchBot.chatSuccess'));
67 toastr.error(t('twitchBot.chatError'));
69 }, [channel, chatText, t]);
71 const adlibChat = React.useCallback(async () => {
73 await axios.post(`/api/channels/${channel.id}/chat`, {
74 bot_nick: 'horstiebot',
77 toastr.success(t('twitchBot.chatSuccess'));
79 toastr.error(t('twitchBot.chatError'));
81 }, [channel, chatText, t]);
83 const join = React.useCallback(async (bot_nick) => {
85 const rsp = await axios.post(`/api/channels/${channel.id}/join`, { bot_nick });
87 toastr.success(t('twitchBot.joinSuccess'));
89 toastr.error(t('twitchBot.joinError'));
93 const part = React.useCallback(async (bot_nick) => {
95 const rsp = await axios.post(`/api/channels/${channel.id}/part`, { bot_nick });
97 toastr.success(t('twitchBot.partSuccess'));
99 toastr.error(t('twitchBot.partError'));
103 const saveChatSettings = React.useCallback(async (values) => {
105 const rsp = await axios.post(`/api/channels/${channel.id}/chat-settings`, values);
106 setChannel(rsp.data);
107 toastr.success(t('twitchBot.saveSuccess'));
109 toastr.error(t('twitchBot.saveError'));
113 const onAddCommand = React.useCallback(() => {
115 setEditCommandSettings({});
116 setShowCommandDialog(true);
119 const onEditCommand = React.useCallback((name, settings) => {
120 setEditCommand(name);
121 setEditCommandSettings(settings);
122 setShowCommandDialog(true);
125 const onRemoveCommand = React.useCallback(async (name) => {
127 const rsp = await axios.delete(`/api/channels/${channel.id}/commands/${name}`);
128 setChannel(rsp.data);
129 toastr.success(t('twitchBot.saveSuccess'));
131 toastr.error(t('twitchBot.saveError'));
135 const saveCommand = React.useCallback(async (values) => {
137 const rsp = await axios.put(
138 `/api/channels/${channel.id}/commands/${values.name}`,
141 setChannel(rsp.data);
142 setShowCommandDialog(false);
144 setEditCommandSettings({});
145 toastr.success(t('twitchBot.saveSuccess'));
147 toastr.error(t('twitchBot.saveError'));
152 const saveGuessingGame = React.useCallback(async (values) => {
154 const rsp = await axios.put(
155 `/api/channels/${channel.id}/guessing-game/${values.name}`,
158 setChannel(rsp.data);
159 toastr.success(t('twitchBot.saveSuccess'));
161 toastr.error(t('twitchBot.saveError'));
167 <Row className="mb-4">
168 <Form.Group as={Col} md={6}>
169 <Form.Label>{t('twitchBot.channel')}</Form.Label>
175 onChange={({ channel }) => { setChannel(channel); }}
176 value={channel ? channel.id : ''}
180 <Form.Group as={Col} md={3}>
181 <Form.Label>{t('twitchBot.joinApp')}</Form.Label>
185 onChange={({ target: { value } }) => {
187 join('localhorsttv');
189 part('localhorsttv');
196 <Form.Group as={Col} md={3}>
197 <Form.Label>{t('twitchBot.joinChat')}</Form.Label>
201 onChange={({ target: { value } }) => {
216 <Col className="mt-5" md={6}>
217 <h3>{t('twitchBot.chat')}</h3>
219 <Form.Label>{t('twitchBot.chat')}</Form.Label>
222 onChange={({ target: { value } }) => {
227 <div className="button-bar">
230 disabled={!chatText || !channel.join}
232 if (chatText) chat(chatText, 'localhorsttv');
236 {t('twitchBot.sendApp')}
240 disabled={!chatText || !channel.chat}
242 if (chatText) chat(chatText, 'horstiebot');
246 {t('twitchBot.sendChat')}
250 <h3 className="mt-3">{t('twitchBot.randomChat')}</h3>
251 <div className="button-bar">
252 {CHAT_CATEGORIES.map(category =>
255 onClick={() => { randomChat(category); }}
256 variant="outline-secondary"
258 {t(`twitchBot.chatCategories.${category}`)}
262 <div className="mt-3">
264 onClick={() => { adlibChat(); }}
265 title={t('twitchBot.adlibChatDesc')}
266 variant="outline-secondary"
268 {t('twitchBot.adlibChat')}
270 <p className="text-muted">{t('twitchBot.adlibChatNote')}</p>
273 <Col className="mt-5" md={6}>
274 <div className="d-flex justify-content-between">
275 <h3>{t('twitchBot.chatSettings')}</h3>
276 <div className="button-bar">
277 <ChatBotLog id={channel.id} />
280 <ChatSettingsForm channel={channel} onSubmit={saveChatSettings} />
282 <Col className="mt-5" md={12}>
283 <h3>{t('twitchBot.commands')}</h3>
286 onEditCommand={onEditCommand}
287 onRemoveCommand={onRemoveCommand}
292 setShowCommandDialog(false);
294 setEditCommandSettings({});
296 onSubmit={saveCommand}
297 settings={editCommandSettings}
298 show={showCommandDialog}
301 <Button onClick={onAddCommand} variant="primary">
302 {t('twitchBot.addCommand')}
306 <Col className="mt-5" md={12}>
307 <div className="d-flex align-items-end justify-content-between">
308 <h3>{t('twitchBot.guessingGame.settings')}</h3>
309 <div className="button-bar">
310 {channel.access_key ?
312 href={`/guessing-game/monitor/${channel.access_key}`}
314 title={t('button.browserSource')}
315 variant="outline-secondary"
317 <Icon.BROWSER_SOURCE title="" />
323 `/guessing-game/controls/${channel.id}`,
325 'width=640,height=800,titlebar=0,menubar=0,toolbar=0',
328 title={t('twitchBot.guessingGame.popoutControls')}
329 variant="outline-secondary"
331 <Icon.OPEN title="" />
335 <GuessingSettingsForm
337 onSubmit={saveGuessingGame}
338 settings={channel.guessing_settings?.gtbk || {}}
343 <Alert variant="info">
344 {t('twitchBot.selectChannel')}
350 export default Controls;