import { createAsyncThunk } from '@reduxjs/toolkit' import { ChannelConversation } from 'api/api.types' import SeamlySessionExpiredError from 'api/errors/seamly-session-expired-error' import SeamlyUnavailableError from 'api/errors/seamly-unavailable-error' import type { Config } from 'config.types' import { initializeConfig, resetConfig } from 'domains/config/actions' import createDebouncedAsyncThunk from 'domains/redux/create-debounced-async-thunk' import { ThunkAPI } from 'domains/redux/redux.types' import { initializeVisibility } from 'domains/visibility/actions' import { actionTypes } from 'ui/utils/seamly-utils' export const initializeApp = createAsyncThunk< { initialState?: ChannelConversation | null contentLocale?: string userLocale?: string config?: Config }, void, ThunkAPI >('initializeApp', async (_, { extra: { api, config }, rejectWithValue }) => { const contentLocale = config?.context?.contentLocale const userLocale = config?.context?.userLocale try { if (api.hasConversation()) { const initialState = await api.getConversationIntitialState() return { initialState, contentLocale, userLocale, config } } else { if (config?.context?.topic) { api.send('action', { type: actionTypes.setTopic, body: { name: config.context.topic, // Separate fallback message is not needed here. Only an attached service will use this, but none will // be attached before the conversation has started (meaning the fallback message will never be shown). fallbackMessage: config.context.topic, }, }) } return { initialState: undefined, contentLocale, userLocale, config } } } catch (e) { if (e instanceof SeamlySessionExpiredError) { const err = new SeamlySessionExpiredError() return rejectWithValue({ name: err.name, message: err.message, originalEvent: err.originalEvent, originalError: err.originalError, action: err.action, }) } const err = new SeamlyUnavailableError() return rejectWithValue({ name: err.name, message: err.message, langKey: err.langKey, }) } }) export const resetApp = createDebouncedAsyncThunk( 'resetApp', async (_, { dispatch, extra: { api } }) => { await api.disconnect() api.clearStore() dispatch(resetConfig()) await dispatch(initializeConfig()) await dispatch(initializeApp()) dispatch(initializeVisibility()) }, { wait: 2000, leading: true, }, )