From 31d44b950e52a19841caa2b0e69850a70741241e Mon Sep 17 00:00:00 2001 From: Ash Keel Date: Tue, 12 Mar 2024 23:39:18 +0100 Subject: [PATCH] feat: migration and more chat stuff --- README.md | 4 +- app.go | 8 + frontend/src/locale/en/translation.json | 24 ++- frontend/src/locale/it/translation.json | 9 +- frontend/src/store/api/reducer.ts | 44 +++--- frontend/src/store/api/types.ts | 29 ++-- frontend/src/ui/App.tsx | 26 ++-- frontend/src/ui/pages/ChatAlerts.tsx | 22 +-- .../{BotCommands.tsx => ChatCommands.tsx} | 18 +-- .../pages/{BotTimers.tsx => ChatTimers.tsx} | 18 +-- frontend/src/ui/pages/Onboarding.tsx | 2 +- frontend/src/ui/pages/TwitchSettings.tsx | 145 ++---------------- go.mod | 2 +- go.sum | 4 +- migrations/common.go | 23 +++ migrations/migration.go | 72 +++++++++ migrations/v3_v4.go | 80 ++++++++++ twitch/alerts/module.go | 5 +- twitch/chat/config.go | 3 - twitch/chat/data.go | 2 - twitch/chat/module.go | 36 ++--- twitch/client/client.go | 82 ++++++---- twitch/config.go | 3 - twitch/doc/doc.go | 10 -- twitch/eventsub/client.go | 1 - twitch/scopes.go | 1 + twitch/timers/module.go | 5 +- 27 files changed, 368 insertions(+), 310 deletions(-) rename frontend/src/ui/pages/{BotCommands.tsx => ChatCommands.tsx} (96%) rename frontend/src/ui/pages/{BotTimers.tsx => ChatTimers.tsx} (96%) create mode 100644 migrations/common.go create mode 100644 migrations/migration.go create mode 100644 migrations/v3_v4.go diff --git a/README.md b/README.md index 32ccd30..1c4b370 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ You can also build the project yourself, refer to the Building section below. Strimertül is a single executable app that provides the following: - HTTP server for serving static assets and a websocket API -- Twitch bot for handling chat messages and providing custom commands +- Twitch EventSub handlers for chat functionalities such as custom commands and alerts - Polling-based loyalty system for rewards and community goals At strimertül's core is [Kilovolt](https://git.sr.ht/~ashkeel/kilovolt), a pub/sub key-value store accessible via websocket. You can access every functionality of strimertul through the Kilovolt API. Check [this repository](https://github.com/strimertul/kilovolt-clients) for a list of officially supported kilovolt clients (or submit your own). You should be able to easily build a client yourself by just creating a websocket connection and using the [Kilovolt protocol](https://github.com/strimertul/kilovolt/blob/main/PROTOCOL.md). @@ -54,6 +54,4 @@ To build a redistributable, production mode package, use `wails build`. ## License -Kilovolt's code is based on Gorilla Websocket's server example, licensed under [BSD-2-Clause](https://github.com/gorilla/websocket/blob/master/LICENSE) - The entire project is licensed under [AGPL-3.0-only](LICENSE) (see `LICENSE`). diff --git a/app.go b/app.go index d6949c8..073d9fc 100644 --- a/app.go +++ b/app.go @@ -12,6 +12,8 @@ import ( "runtime/debug" "strconv" + "git.sr.ht/~ashkeel/strimertul/migrations" + "git.sr.ht/~ashkeel/strimertul/twitch/client" "github.com/wailsapp/wails/v2/pkg/options" @@ -88,6 +90,12 @@ func (a *App) startup(ctx context.Context) { return } + // Check for migrations + if err := migrations.Run(a.driver, a.db, logger); err != nil { + a.showFatalError(err, "Failed to migrate database to latest version") + return + } + // Initialize components if err := a.initializeComponents(); err != nil { a.showFatalError(err, "Failed to initialize required component") diff --git a/frontend/src/locale/en/translation.json b/frontend/src/locale/en/translation.json index 21ce389..e376565 100644 --- a/frontend/src/locale/en/translation.json +++ b/frontend/src/locale/en/translation.json @@ -24,9 +24,9 @@ }, "twitch": { "configuration": "Configuration", - "bot-commands": "Chat commands", - "bot-timers": "Chat timers", - "bot-alerts": "Chat alerts" + "chat-commands": "Chat commands", + "chat-timers": "Chat timers", + "chat-alerts": "Chat alerts" }, "loyalty": { "configuration": "Configuration", @@ -66,18 +66,16 @@ "apiguide-4": "Once made, create a <1>New Secret, then copy both fields below and save!", "app-client-id": "App Client ID", "app-client-secret": "App Client Secret", - "subtitle": "Twitch integration with streams including chat bot and API access. If you stream on Twitch, you definitely want this on.", + "subtitle": "Twitch integration with streams including chat interactions and API access. If you stream on Twitch, you definitely want this on.", "api-subheader": "Application info", "api-configuration": "API access", "eventsub": "Events", - "bot-settings": "Bot settings", - "enable-bot": "Enable Twitch bot", + "chat-settings": "Chat settings", + "enable-bot": "Enable chat features", "bot-channel": "Twitch channel", "bot-username": "Twitch account username", "bot-oauth": "Authorization token", "bot-oauth-note": "You can get this by logging in with the bot account and going here: <1>https://twitchapps.com/tmi/", - "bot-info-header": "Bot account info", - "bot-settings-copy": "A bot can interact with chat messages and provide extra events for the platform (chat events, some notifications) but requires access to a Twitch account. You can use your own or make a new one (if enabled on your main account, you can re-use the same email for your second account!)", "bot-chat-header": "Chat settings", "bot-chat-history": "How many messages to keep in history (0 to disable)", "events": { @@ -107,7 +105,7 @@ "bot-chat-cooldown-tip": "Global chat cooldown for commands (in seconds)" }, "botcommands": { - "title": "Bot commands", + "title": "Chat commands", "desc": "Define custom chat commands to set up autoresponders, counters, etc.", "add-button": "New command", "search-placeholder": "Search command by name", @@ -135,12 +133,12 @@ "streamer": "Streamer only" }, "remove-command-title": "Remove command {{name}}?", - "no-commands": "Chatbot has no commands configured", + "no-commands": "There are no commands configured", "command-already-in-use": "Command name already in use", "command-invalid-format": "The response template contains errors" }, "bottimers": { - "title": "Bot timers", + "title": "Chat timers", "desc": "Define reminders such as checking out your social media or ongoing events", "add-button": "New timer", "search-placeholder": "Search timer by name", @@ -301,7 +299,7 @@ "landing": "Welcome", "twitch-config": "Twitch integration", "twitch-events": "Twitch events", - "twitch-bot": "Twitch bot", + "twitch-bot": "Twitch chat", "done": "All done!" }, "twitch-p1": "To set-up Twitch you will need to create an application on the Developer portal. Follow the instructions below or click the button at the bottom to skip this step.", @@ -311,7 +309,7 @@ "twitch-ev-p3": "If the above shows your account name and picture correctly, you're all set! Click the button below to complete Twitch integration.", "twitch-complete": "Complete Twitch integration", "done-header": "You're all set!", - "done-p1": "That should be enough for now. You can always change any option later, including custom configurations not covered in this procedure (e.g. using a different Twitch account for the bot).", + "done-p1": "That should be enough for now. You can always change any option later, including custom configurations not covered in this procedure (e.g. using a different Twitch account for the chat integrations).", "done-p2": "If you have questions or issues, please reach out at any of these places:", "done-button": "Complete onboarding", "done-p3": "Click the button below to finish the onboarding and go to {{APPNAME}}'s dashboard.", diff --git a/frontend/src/locale/it/translation.json b/frontend/src/locale/it/translation.json index fbde935..6fdb176 100644 --- a/frontend/src/locale/it/translation.json +++ b/frontend/src/locale/it/translation.json @@ -74,9 +74,9 @@ "extensions": "Estensioni" }, "twitch": { - "bot-alerts": "Avvisi in chat", - "bot-commands": "Comandi bot", - "bot-timers": "Timer bot", + "chat-alerts": "Avvisi in chat", + "chat-commands": "Comandi chat", + "chat-timers": "Timer chat", "configuration": "Configurazione" } }, @@ -332,10 +332,9 @@ "bot-channel": "Canale Twitch", "bot-chat-header": "Impostazioni chat", "bot-chat-history": "Quanti messaggi tenere nello storico (0 per disabilitare)", - "bot-info-header": "Informazioni account del bot", "bot-oauth": "Token di autorizzazione", "bot-oauth-note": "Puoi ottenerlo accedendo con l'account del bot e andando qui: <1>https://twitchapps.com/tmi/", - "bot-settings": "Impostazioni bot", + "chat-settings": "Impostazioni chat", "bot-settings-copy": "Un bot può interagire con i messaggi in chat e scriverci per avvertimenti ed altre funzionalità ma richiede l'accesso ad un account Twitch. \nPuoi usare il tuo account o crearne uno apposta (se abilitato sul tuo account principale, puoi riutilizzare la stessa email per un secondo account!)", "bot-username": "Nome utente dell'account Twitch", "enable": "Abilita integrazione Twitch", diff --git a/frontend/src/store/api/reducer.ts b/frontend/src/store/api/reducer.ts index 82388ef..f6ddb76 100644 --- a/frontend/src/store/api/reducer.ts +++ b/frontend/src/store/api/reducer.ts @@ -20,11 +20,11 @@ import { LoyaltyPointsEntry, LoyaltyRedeem, LoyaltyStorage, - TwitchBotConfig, + TwitchChatConfig, TwitchConfig, - TwitchBotCustomCommands, - TwitchBotTimersConfig, - TwitchBotAlertsConfig, + TwitchChatCustomCommands, + TwitchChatTimersConfig, + TwitchChatAlertsConfig, LoyaltyConfig, LoyaltyReward, LoyaltyGoal, @@ -165,32 +165,32 @@ export const modules = { state.moduleConfigs.twitchConfig = payload as TwitchConfig; }, ), - twitchBotConfig: makeModule( - 'twitch/bot-config', - (state) => state.moduleConfigs?.twitchBotConfig, + twitchChatConfig: makeModule( + 'twitch/chat/config', + (state) => state.moduleConfigs?.twitchChatConfig, (state, { payload }) => { - state.moduleConfigs.twitchBotConfig = payload as TwitchBotConfig; + state.moduleConfigs.twitchChatConfig = payload as TwitchChatConfig; }, ), - twitchBotCommands: makeModule( - 'twitch/bot-custom-commands', - (state) => state.twitchBot?.commands, + twitchChatCommands: makeModule( + 'twitch/chat/custom-commands', + (state) => state.twitchChat?.commands, (state, { payload }) => { - state.twitchBot.commands = payload as TwitchBotCustomCommands; + state.twitchChat.commands = payload as TwitchChatCustomCommands; }, ), - twitchBotTimers: makeModule( - 'twitch/bot-modules/timers/config', - (state) => state.twitchBot?.timers, + twitchChatTimers: makeModule( + 'twitch/timers/config', + (state) => state.twitchChat?.timers, (state, { payload }) => { - state.twitchBot.timers = payload as TwitchBotTimersConfig; + state.twitchChat.timers = payload as TwitchChatTimersConfig; }, ), - twitchBotAlerts: makeModule( - 'twitch/bot-modules/alerts/config', - (state) => state.twitchBot?.alerts, + twitchChatAlerts: makeModule( + 'twitch/alerts/config', + (state) => state.twitchChat?.alerts, (state, { payload }) => { - state.twitchBot.alerts = payload as TwitchBotAlertsConfig; + state.twitchChat.alerts = payload as TwitchChatAlertsConfig; }, ), loyaltyConfig: makeModule( @@ -269,7 +269,7 @@ const initialState: APIState = { goals: null, redeemQueue: null, }, - twitchBot: { + twitchChat: { commands: null, timers: null, alerts: null, @@ -277,7 +277,7 @@ const initialState: APIState = { moduleConfigs: { httpConfig: null, twitchConfig: null, - twitchBotConfig: null, + twitchChatConfig: null, loyaltyConfig: null, }, uiConfig: null, diff --git a/frontend/src/store/api/types.ts b/frontend/src/store/api/types.ts index 656e13e..f0dc1e0 100644 --- a/frontend/src/store/api/types.ts +++ b/frontend/src/store/api/types.ts @@ -12,16 +12,11 @@ export interface HTTPConfig { export interface TwitchConfig { enabled: boolean; - enable_bot: boolean; api_client_id: string; api_client_secret: string; } -export interface TwitchBotConfig { - username: string; - oauth: string; - channel: string; - chat_history: number; +export interface TwitchChatConfig { command_cooldown: number; } @@ -36,7 +31,7 @@ export const accessLevels = [ export type AccessLevelType = (typeof accessLevels)[number]; export type ReplyType = 'chat' | 'reply' | 'whisper' | 'announce'; -export interface TwitchBotCustomCommand { +export interface TwitchChatCustomCommand { description: string; access_level: AccessLevelType; response: string; @@ -44,7 +39,7 @@ export interface TwitchBotCustomCommand { enabled: boolean; } -export type TwitchBotCustomCommands = Record; +export type TwitchChatCustomCommands = Record; export interface LoyaltyConfig { enabled: boolean; @@ -57,7 +52,7 @@ export interface LoyaltyConfig { banlist: string[]; } -export interface TwitchBotTimer { +export interface TwitchChatTimer { enabled: boolean; name: string; minimum_chat_activity: number; @@ -65,11 +60,11 @@ export interface TwitchBotTimer { messages: string[]; } -export interface TwitchBotTimersConfig { - timers: Record; +export interface TwitchChatTimersConfig { + timers: Record; } -export interface TwitchBotAlertsConfig { +export interface TwitchChatAlertsConfig { follow: { enabled: boolean; messages: string[]; @@ -176,15 +171,15 @@ export interface APIState { goals: LoyaltyGoal[]; redeemQueue: LoyaltyRedeem[]; }; - twitchBot: { - commands: TwitchBotCustomCommands; - timers: TwitchBotTimersConfig; - alerts: TwitchBotAlertsConfig; + twitchChat: { + commands: TwitchChatCustomCommands; + timers: TwitchChatTimersConfig; + alerts: TwitchChatAlertsConfig; }; moduleConfigs: { httpConfig: HTTPConfig; twitchConfig: TwitchConfig; - twitchBotConfig: TwitchBotConfig; + twitchChatConfig: TwitchChatConfig; loyaltyConfig: LoyaltyConfig; }; uiConfig: UISettings; diff --git a/frontend/src/ui/App.tsx b/frontend/src/ui/App.tsx index 8d762b4..5634309 100644 --- a/frontend/src/ui/App.tsx +++ b/frontend/src/ui/App.tsx @@ -31,8 +31,8 @@ import { initializeServerInfo } from '~/store/server/reducer'; import LogViewer from './components/LogViewer'; import Sidebar, { RouteSection } from './components/Sidebar'; import Scrollbar from './components/utils/Scrollbar'; -import TwitchBotCommandsPage from './pages/BotCommands'; -import TwitchBotTimersPage from './pages/BotTimers'; +import TwitchChatCommandsPage from './pages/ChatCommands'; +import TwitchChatTimersPage from './pages/ChatTimers'; import ChatAlertsPage from './pages/ChatAlerts'; import Dashboard from './pages/Dashboard'; import DebugPage from './pages/Debug'; @@ -92,18 +92,18 @@ const sections: RouteSection[] = [ icon: , }, { - title: 'menu.pages.twitch.bot-commands', - url: '/twitch/bot/commands', + title: 'menu.pages.twitch.chat-commands', + url: '/twitch/chat/commands', icon: , }, { - title: 'menu.pages.twitch.bot-timers', - url: '/twitch/bot/timers', + title: 'menu.pages.twitch.chat-timers', + url: '/twitch/chat/timers', icon: , }, { - title: 'menu.pages.twitch.bot-alerts', - url: '/twitch/bot/alerts', + title: 'menu.pages.twitch.chat-alerts', + url: '/twitch/chat/alerts', icon: , }, ], @@ -277,14 +277,14 @@ export default function App(): JSX.Element { } /> } /> } + path="/twitch/chat/commands" + element={} /> } + path="/twitch/chat/timers" + element={} /> - } /> + } /> } /> } /> } /> diff --git a/frontend/src/ui/pages/ChatAlerts.tsx b/frontend/src/ui/pages/ChatAlerts.tsx index 183b2aa..fd9c70f 100644 --- a/frontend/src/ui/pages/ChatAlerts.tsx +++ b/frontend/src/ui/pages/ChatAlerts.tsx @@ -25,7 +25,7 @@ import SaveButton from '../components/forms/SaveButton'; export default function ChatAlertsPage(): React.ReactElement { const { t } = useTranslation(); const dispatch = useAppDispatch(); - const [alerts, setAlerts, loadStatus] = useModule(modules.twitchBotAlerts); + const [alerts, setAlerts, loadStatus] = useModule(modules.twitchChatAlerts); const status = useStatus(loadStatus.save); return ( @@ -63,7 +63,7 @@ export default function ChatAlertsPage(): React.ReactElement { checked={alerts?.follow?.enabled ?? false} onCheckedChange={(ev) => { void dispatch( - apiReducer.actions.twitchBotAlertsChanged({ + apiReducer.actions.twitchChatAlertsChanged({ ...alerts, follow: { ...alerts.follow, @@ -93,7 +93,7 @@ export default function ChatAlertsPage(): React.ReactElement { required={alerts?.follow?.enabled ?? false} onChange={(messages) => { dispatch( - apiReducer.actions.twitchBotAlertsChanged({ + apiReducer.actions.twitchChatAlertsChanged({ ...alerts, follow: { ...alerts.follow, messages }, }), @@ -109,7 +109,7 @@ export default function ChatAlertsPage(): React.ReactElement { checked={alerts?.subscription?.enabled ?? false} onCheckedChange={(ev) => { void dispatch( - apiReducer.actions.twitchBotAlertsChanged({ + apiReducer.actions.twitchChatAlertsChanged({ ...alerts, subscription: { ...alerts.subscription, @@ -139,7 +139,7 @@ export default function ChatAlertsPage(): React.ReactElement { required={alerts?.subscription?.enabled ?? false} onChange={(messages) => { void dispatch( - apiReducer.actions.twitchBotAlertsChanged({ + apiReducer.actions.twitchChatAlertsChanged({ ...alerts, subscription: { ...alerts.subscription, messages }, }), @@ -156,7 +156,7 @@ export default function ChatAlertsPage(): React.ReactElement { checked={alerts?.gift_sub?.enabled ?? false} onCheckedChange={(ev) => { void dispatch( - apiReducer.actions.twitchBotAlertsChanged({ + apiReducer.actions.twitchChatAlertsChanged({ ...alerts, gift_sub: { ...alerts.gift_sub, @@ -186,7 +186,7 @@ export default function ChatAlertsPage(): React.ReactElement { required={alerts?.gift_sub?.enabled ?? false} onChange={(messages) => { void dispatch( - apiReducer.actions.twitchBotAlertsChanged({ + apiReducer.actions.twitchChatAlertsChanged({ ...alerts, gift_sub: { ...alerts.gift_sub, messages }, }), @@ -203,7 +203,7 @@ export default function ChatAlertsPage(): React.ReactElement { checked={alerts?.raid?.enabled ?? false} onCheckedChange={(ev) => { void dispatch( - apiReducer.actions.twitchBotAlertsChanged({ + apiReducer.actions.twitchChatAlertsChanged({ ...alerts, raid: { ...alerts.raid, @@ -233,7 +233,7 @@ export default function ChatAlertsPage(): React.ReactElement { required={alerts?.raid?.enabled ?? false} onChange={(messages) => { void dispatch( - apiReducer.actions.twitchBotAlertsChanged({ + apiReducer.actions.twitchChatAlertsChanged({ ...alerts, raid: { ...alerts.raid, messages }, }), @@ -250,7 +250,7 @@ export default function ChatAlertsPage(): React.ReactElement { checked={alerts?.cheer?.enabled ?? false} onCheckedChange={(ev) => { void dispatch( - apiReducer.actions.twitchBotAlertsChanged({ + apiReducer.actions.twitchChatAlertsChanged({ ...alerts, cheer: { ...alerts.cheer, @@ -280,7 +280,7 @@ export default function ChatAlertsPage(): React.ReactElement { required={alerts?.cheer?.enabled ?? false} onChange={(messages) => { void dispatch( - apiReducer.actions.twitchBotAlertsChanged({ + apiReducer.actions.twitchChatAlertsChanged({ ...alerts, cheer: { ...alerts.cheer, messages }, }), diff --git a/frontend/src/ui/pages/BotCommands.tsx b/frontend/src/ui/pages/ChatCommands.tsx similarity index 96% rename from frontend/src/ui/pages/BotCommands.tsx rename to frontend/src/ui/pages/ChatCommands.tsx index 9dc4b9c..e99a23a 100644 --- a/frontend/src/ui/pages/BotCommands.tsx +++ b/frontend/src/ui/pages/ChatCommands.tsx @@ -8,7 +8,7 @@ import { accessLevels, AccessLevelType, ReplyType, - TwitchBotCustomCommand, + TwitchChatCustomCommand, } from '~/store/api/types'; import { TestCommandTemplate } from '@wailsapp/go/main/App'; import AlertContent from '../components/AlertContent'; @@ -137,7 +137,7 @@ const ACLIndicator = styled('span', { interface CommandItemProps { name: string; - item: TwitchBotCustomCommand; + item: TwitchChatCustomCommand; onToggle?: () => void; onEdit?: () => void; onDelete?: () => void; @@ -212,7 +212,7 @@ function CommandItem({ type DialogPrompt = | { kind: 'new' } - | { kind: 'edit'; name: string; item: TwitchBotCustomCommand }; + | { kind: 'edit'; name: string; item: TwitchChatCustomCommand }; function CommandDialog({ kind, @@ -222,10 +222,10 @@ function CommandDialog({ }: { kind: 'new' | 'edit'; name?: string; - item?: TwitchBotCustomCommand; - onSubmit?: (name: string, item: TwitchBotCustomCommand) => void; + item?: TwitchChatCustomCommand; + onSubmit?: (name: string, item: TwitchChatCustomCommand) => void; }) { - const [commands] = useModule(modules.twitchBotCommands); + const [commands] = useModule(modules.twitchChatCommands); const [commandName, setCommandName] = useState(name ?? ''); const [description, setDescription] = useState(item?.description ?? ''); const [responseType, setResponseType] = useState( @@ -376,8 +376,8 @@ function CommandDialog({ ); } -export default function TwitchBotCommandsPage(): React.ReactElement { - const [commands, setCommands] = useModule(modules.twitchBotCommands); +export default function TwitchChatCommandsPage(): React.ReactElement { + const [commands, setCommands] = useModule(modules.twitchChatCommands); const [filter, setFilter] = useState(''); const [activeDialog, setActiveDialog] = useState(null); const { t } = useTranslation(); @@ -385,7 +385,7 @@ export default function TwitchBotCommandsPage(): React.ReactElement { const filterLC = filter.toLowerCase(); - const setCommand = (newName: string, data: TwitchBotCustomCommand): void => { + const setCommand = (newName: string, data: TwitchChatCustomCommand): void => { switch (activeDialog.kind) { case 'new': void dispatch( diff --git a/frontend/src/ui/pages/BotTimers.tsx b/frontend/src/ui/pages/ChatTimers.tsx similarity index 96% rename from frontend/src/ui/pages/BotTimers.tsx rename to frontend/src/ui/pages/ChatTimers.tsx index 5e02c7f..0cfb885 100644 --- a/frontend/src/ui/pages/BotTimers.tsx +++ b/frontend/src/ui/pages/ChatTimers.tsx @@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next'; import { useModule } from '~/lib/react'; import { useAppDispatch } from '~/store'; import { modules } from '~/store/api/reducer'; -import { TwitchBotTimer } from '~/store/api/types'; +import { TwitchChatTimer } from '~/store/api/types'; import AlertContent from '../components/AlertContent'; import DialogContent from '../components/DialogContent'; import Interval from '../components/forms/Interval'; @@ -108,7 +108,7 @@ function humanTime(t: TFunction<'translation'>, secs: number): string { interface TimerItemProps { name: string; - item: TwitchBotTimer; + item: TwitchChatTimer; onToggle?: () => void; onEdit?: () => void; onDelete?: () => void; @@ -182,7 +182,7 @@ function TimerItem({ type DialogPrompt = | { kind: 'new' } - | { kind: 'edit'; name: string; item: TwitchBotTimer }; + | { kind: 'edit'; name: string; item: TwitchChatTimer }; function TimerDialog({ kind, @@ -192,10 +192,10 @@ function TimerDialog({ }: { kind: 'new' | 'edit'; name?: string; - item?: TwitchBotTimer; - onSubmit?: (name: string, item: TwitchBotTimer) => void; + item?: TwitchChatTimer; + onSubmit?: (name: string, item: TwitchChatTimer) => void; }) { - const [timerConfig] = useModule(modules.twitchBotTimers); + const [timerConfig] = useModule(modules.twitchChatTimers); const [timerName, setName] = useState(name ?? ''); const [messages, setMessages] = useState(item?.messages ?? ['']); const [minDelay, setMinDelay] = useState(item?.minimum_delay ?? 300); @@ -308,8 +308,8 @@ function TimerDialog({ ); } -export default function TwitchBotTimersPage(): React.ReactElement { - const [timerConfig, setTimerConfig] = useModule(modules.twitchBotTimers); +export default function TwitchChatTimersPage(): React.ReactElement { + const [timerConfig, setTimerConfig] = useModule(modules.twitchChatTimers); const [filter, setFilter] = useState(''); const [activeDialog, setActiveDialog] = useState(null); const { t } = useTranslation(); @@ -317,7 +317,7 @@ export default function TwitchBotTimersPage(): React.ReactElement { const filterLC = filter.toLowerCase(); - const setTimer = (newName: string, data: TwitchBotTimer): void => { + const setTimer = (newName: string, data: TwitchChatTimer): void => { switch (activeDialog.kind) { case 'new': void dispatch( diff --git a/frontend/src/ui/pages/Onboarding.tsx b/frontend/src/ui/pages/Onboarding.tsx index 2d6efcc..3008151 100644 --- a/frontend/src/ui/pages/Onboarding.tsx +++ b/frontend/src/ui/pages/Onboarding.tsx @@ -450,7 +450,7 @@ function TwitchEventsStep() { const { t } = useTranslation(); const [userStatus, setUserStatus] = useState(null); const [twitchConfig, setTwitchConfig] = useModule(modules.twitchConfig); - const [botConfig, setBotConfig] = useModule(modules.twitchBotConfig); + const [botConfig, setBotConfig] = useModule(modules.twitchChatConfig); const [uiConfig, setUiConfig] = useModule(modules.uiConfig); const [authKeys, setAuthKeys] = useState(null); const kv = useSelector((state: RootState) => state.api.client); diff --git a/frontend/src/ui/pages/TwitchSettings.tsx b/frontend/src/ui/pages/TwitchSettings.tsx index 84fb3a9..e4c7176 100644 --- a/frontend/src/ui/pages/TwitchSettings.tsx +++ b/frontend/src/ui/pages/TwitchSettings.tsx @@ -19,7 +19,6 @@ import { Checkbox, CheckboxIndicator, Field, - FieldNote, FlexRow, InputBox, Label, @@ -54,143 +53,27 @@ const Step = styled('li', { }, }); -function TwitchBotSettings() { - const [botConfig, setBotConfig, loadStatus] = useModule( - modules.twitchBotConfig, +function TwitchChatSettings() { + const [chatConfig, setChatConfig, loadStatus] = useModule( + modules.twitchChatConfig, ); const [twitchConfig, setTwitchConfig] = useModule(modules.twitchConfig); const status = useStatus(loadStatus.save); const dispatch = useAppDispatch(); const { t } = useTranslation(); - const [revealBotToken, setRevealBotToken] = useState(false); - const active = twitchConfig?.enable_bot ?? false; - const disabled = !active || status?.type === 'pending'; + const disabled = status?.type === 'pending'; return (
{ void dispatch(setTwitchConfig(twitchConfig)); - void dispatch(setBotConfig(botConfig)); + void dispatch(setChatConfig(chatConfig)); ev.preventDefault(); }} > - {t('pages.twitch-settings.bot-settings-copy')} - - - - dispatch( - apiReducer.actions.twitchConfigChanged({ - ...twitchConfig, - enable_bot: !!ev, - }), - ) - } - id="enable-bot" - > - {active && } - - - - - - - - - dispatch( - apiReducer.actions.twitchBotConfigChanged({ - ...botConfig, - channel: ev.target.value, - }), - ) - } - /> - - - {t('pages.twitch-settings.bot-info-header')} - - - - - dispatch( - apiReducer.actions.twitchBotConfigChanged({ - ...botConfig, - username: ev.target.value, - }), - ) - } - /> - - - - - dispatch( - apiReducer.actions.twitchBotConfigChanged({ - ...botConfig, - oauth: ev.target.value, - }), - ) - } - /> - - - - https://twitchapps.com/tmi/ - - - - {t('pages.twitch-settings.bot-chat-header')} - - - - dispatch( - apiReducer.actions.twitchBotConfigChanged({ - ...botConfig, - chat_history: parseInt(ev.target.value, 10), - }), - ) - } - /> -