diff --git a/frontend/src/store/api/reducer.ts b/frontend/src/store/api/reducer.ts index 1703a68..c6c6315 100644 --- a/frontend/src/store/api/reducer.ts +++ b/frontend/src/store/api/reducer.ts @@ -15,6 +15,7 @@ const moduleConfigKey = 'stul-meta/modules'; const httpConfigKey = 'http/config'; const twitchConfigKey = 'twitch/config'; const twitchBotConfigKey = 'twitch/bot-config'; +const twitchBotCommandsKey = 'twitch/bot-custom-commands'; const stulbeConfigKey = 'stulbe/config'; const loyaltyConfigKey = 'loyalty/config'; const loyaltyPointsPrefix = 'loyalty/points/'; @@ -54,6 +55,17 @@ interface TwitchBotConfig { chat_history: number; } +type AccessLevelType = 'everyone' | 'vip' | 'moderators' | 'streamer'; + +interface TwitchBotCustomCommand { + description: string; + access_level: AccessLevelType; + response: string; + enabled: boolean; +} + +type TwitchBotCustomCommands = Record; + interface StulbeConfig { endpoint: string; username: string; @@ -116,6 +128,9 @@ export interface APIState { goals: LoyaltyGoal[]; redeemQueue: LoyaltyRedeem[]; }; + twitchBot: { + commands: TwitchBotCustomCommands; + }; moduleConfigs: { moduleConfig: ModuleConfig; httpConfig: HTTPConfig; @@ -136,6 +151,9 @@ const initialState: APIState = { goals: null, redeemQueue: null, }, + twitchBot: { + commands: null, + }, moduleConfigs: { moduleConfig: null, httpConfig: null, @@ -268,6 +286,13 @@ export const modules = { state.moduleConfigs.twitchBotConfig = payload; }, ), + twitchBotCommands: makeModule( + twitchBotCommandsKey, + (state) => state.twitchBot?.commands, + (state, { payload }) => { + state.twitchBot.commands = payload; + }, + ), stulbeConfig: makeModule( stulbeConfigKey, (state) => state.moduleConfigs?.stulbeConfig, @@ -321,40 +346,33 @@ export const removeRedeem = createAsyncThunk( }, ); +const moduleChangeReducers = Object.fromEntries( + Object.entries(modules).map(([key, mod]) => [ + `${key}Changed`, + mod.stateSetter, + ]), +) as Record< + `${keyof typeof modules}Changed`, + ( + state: unknown, + action: { + payload: unknown; + type: string; + }, + ) => never +>; + const apiReducer = createSlice({ name: 'api', initialState, reducers: { + ...moduleChangeReducers, initialLoadCompleted(state) { state.initialLoadComplete = true; }, connectionStatusChanged(state, { payload }: PayloadAction) { state.connected = payload; }, - moduleConfigChanged(state, { payload }: PayloadAction) { - state.moduleConfigs.moduleConfig = payload; - }, - httpConfigChanged(state, { payload }: PayloadAction) { - state.moduleConfigs.httpConfig = payload; - }, - twitchConfigChanged(state, { payload }: PayloadAction) { - state.moduleConfigs.twitchConfig = payload; - }, - twitchBotConfigChanged(state, { payload }: PayloadAction) { - state.moduleConfigs.twitchBotConfig = payload; - }, - stulbeConfigChanged(state, { payload }: PayloadAction) { - state.moduleConfigs.stulbeConfig = payload; - }, - loyaltyConfigChanged(state, { payload }: PayloadAction) { - state.moduleConfigs.loyaltyConfig = payload; - }, - loyaltyRewardsChanged(state, { payload }: PayloadAction) { - state.loyalty.rewards = payload; - }, - loyaltyGoalsChanged(state, { payload }: PayloadAction) { - state.loyalty.goals = payload; - }, loyaltyUserPointsChanged( state, {