import { IOptions, IChatItem, Language, VoiceType, IAgentSettings, ICozeSettings, IDifySettings, } from "@/types" import { createSlice, PayloadAction } from "@reduxjs/toolkit" import { EMobileActiveTab, DEFAULT_OPTIONS, COLOR_LIST, setOptionsToLocal, genRandomChatList, DEFAULT_AGENT_SETTINGS, DEFAULT_COZE_SETTINGS, setAgentSettingsToLocal, setCozeSettingsToLocal, resetCozeSettings as resetCozeSettingsLocal, DEFAULT_DIFY_SETTINGS, setDifySettingsToLocal, resetDifySettings as resetDifySettingsLocal, } from "@/common" export interface InitialState { options: IOptions roomConnected: boolean agentConnected: boolean rtmConnected: boolean themeColor: string language: Language voiceType: VoiceType chatItems: IChatItem[] graphName: string agentSettings: IAgentSettings cozeSettings: ICozeSettings difySettings: IDifySettings mobileActiveTab: EMobileActiveTab globalSettingsDialog: { open?: boolean tab?: string } } const getInitialState = (): InitialState => { return { options: DEFAULT_OPTIONS, themeColor: COLOR_LIST[0].active, roomConnected: false, agentConnected: false, rtmConnected: false, language: "en-US", voiceType: "male", chatItems: [], graphName: "va_openai_azure", agentSettings: DEFAULT_AGENT_SETTINGS, cozeSettings: DEFAULT_COZE_SETTINGS, difySettings: DEFAULT_DIFY_SETTINGS, mobileActiveTab: EMobileActiveTab.AGENT, globalSettingsDialog: { open: false }, } } export const globalSlice = createSlice({ name: "global", initialState: getInitialState(), reducers: { setOptions: (state, action: PayloadAction>) => { state.options = { ...state.options, ...action.payload } setOptionsToLocal(state.options) }, setThemeColor: (state, action: PayloadAction) => { state.themeColor = action.payload document.documentElement.style.setProperty( "--theme-color", action.payload, ) }, setRoomConnected: (state, action: PayloadAction) => { state.roomConnected = action.payload }, setRtmConnected: (state, action: PayloadAction) => { state.rtmConnected = action.payload }, addChatItem: (state, action: PayloadAction) => { const { userId, text, isFinal, type, time } = action.payload const LastFinalIndex = state.chatItems.findLastIndex((el) => { return el.userId == userId && el.isFinal }) const LastNonFinalIndex = state.chatItems.findLastIndex((el) => { return el.userId == userId && !el.isFinal }) let LastFinalItem = state.chatItems[LastFinalIndex] let LastNonFinalItem = state.chatItems[LastNonFinalIndex] if (LastFinalItem) { // has last final Item if (time <= LastFinalItem.time) { // discard console.log( "[test] addChatItem, time < last final item, discard!:", text, isFinal, type, ) return } else { if (LastNonFinalItem) { console.log( "[test] addChatItem, update last item(none final):", text, isFinal, type, ) state.chatItems[LastNonFinalIndex] = action.payload } else { console.log( "[test] addChatItem, add new item:", text, isFinal, type, ) state.chatItems.push(action.payload) } } } else { // no last final Item if (LastNonFinalItem) { console.log( "[test] addChatItem, update last item(none final):", text, isFinal, type, ) state.chatItems[LastNonFinalIndex] = action.payload } else { console.log("[test] addChatItem, add new item:", text, isFinal, type) state.chatItems.push(action.payload) } } state.chatItems.sort((a, b) => a.time - b.time) }, setAgentConnected: (state, action: PayloadAction) => { state.agentConnected = action.payload }, setLanguage: (state, action: PayloadAction) => { state.language = action.payload }, setGraphName: (state, action: PayloadAction) => { state.graphName = action.payload }, setAgentSettings: ( state: { agentSettings: any }, action: PayloadAction>, ) => { state.agentSettings = { ...state.agentSettings, ...action.payload } setAgentSettingsToLocal(state.agentSettings) }, setCozeSettings: (state, action: PayloadAction>) => { state.cozeSettings = { ...state.cozeSettings, ...action.payload } setCozeSettingsToLocal(state.cozeSettings) }, setDifySettings: (state, action: PayloadAction>) => { state.difySettings = { ...state.difySettings, ...action.payload } setDifySettingsToLocal(state.difySettings) }, resetCozeSettings: (state) => { state.cozeSettings = DEFAULT_COZE_SETTINGS resetCozeSettingsLocal() }, resetDifySettings: (state) => { state.difySettings = DEFAULT_DIFY_SETTINGS resetDifySettingsLocal() }, setVoiceType: (state, action: PayloadAction) => { state.voiceType = action.payload }, setMobileActiveTab: (state, action: PayloadAction) => { state.mobileActiveTab = action.payload }, setGlobalSettingsDialog: ( state, action: PayloadAction>, ) => { state.globalSettingsDialog = { ...state.globalSettingsDialog, ...action.payload, } }, reset: (state) => { Object.assign(state, getInitialState()) document.documentElement.style.setProperty( "--theme-color", COLOR_LIST[0].active, ) }, }, }) export const { reset, setOptions, setRoomConnected, setAgentConnected, setRtmConnected, setVoiceType, addChatItem, setThemeColor, setLanguage, setGraphName, setAgentSettings, setCozeSettings, resetCozeSettings, setDifySettings, resetDifySettings, setMobileActiveTab, setGlobalSettingsDialog, } = globalSlice.actions export default globalSlice.reducer