import { createAsyncThunk } from '@reduxjs/toolkit' import type { VisibilityOptions } from 'config.types' import { selectUserHasResponded } from 'domains/app/selectors' import * as ConfigSelectors from 'domains/config/selectors' import type { ThunkAPI } from 'domains/redux/redux.types' import { calculateVisibility } from 'domains/visibility/utils' import { selectState } from 'ui/hooks/seamly-state-hooks' import { StoreKey, visibilityStates } from './constants' import * as Selectors from './selectors' import type { VisibilityActionArgs } from './visibility.types' const validVisibilityStates = [ visibilityStates.open, visibilityStates.minimized, visibilityStates.hidden, ] satisfies VisibilityOptions[] export const setVisibility = createAsyncThunk< VisibilityActionArgs, VisibilityActionArgs, ThunkAPI >('setVisibility', (args, { getState, extra: { api, eventBus } }) => { const state = getState() const requestedVisibility = args.visibility const previousVisibility = Selectors.selectVisibility(state) const userHasResponded = selectUserHasResponded(state) const hasConversation = api.hasConversation() const config = ConfigSelectors.selectConfig(state) const showPreChat = args.showPreChat const showContinueChat = args.showContinueChat const { visibilityCallback = calculateVisibility, layoutMode } = config const { unreadEvents: unreadMessageCount } = selectState(state) const calculatedVisibility = visibilityCallback({ hasResponded: userHasResponded, previousVisibility, requestedVisibility, config, }) if ( calculatedVisibility && !validVisibilityStates.includes(calculatedVisibility) ) { console.error( 'The visibilityCallback function should return "open", "minimized" or "hidden".', ) return { visibility: null, setInputFocus: args.setInputFocus, showPreChat, showContinueChat, } } if (previousVisibility === calculatedVisibility) { return { visibility: null, setInputFocus: args.setInputFocus, showPreChat, showContinueChat, } } const visibility = api.store.get(StoreKey) as object | undefined // Store the user-requested visibility in order to reinitialize after refresh api.store.set(StoreKey, { ...(visibility || {}), [layoutMode]: requestedVisibility, }) if (requestedVisibility) { eventBus.emit('ui.visible', requestedVisibility, { visibility: requestedVisibility, hasConversation, hasResponded: userHasResponded, unreadMessageCount, }) } return { visibility: calculatedVisibility, setInputFocus: args.setInputFocus, showPreChat, showContinueChat, } }) export const initializeVisibility = createAsyncThunk( 'initialize', async (_, { dispatch, getState, extra: { api } }) => { // initialize stored visibility const { layoutMode } = ConfigSelectors.selectConfig(getState()) const storedVisibility = api.store.get(StoreKey)?.[layoutMode] || visibilityStates.initialize dispatch(setVisibility({ visibility: storedVisibility })) return storedVisibility }, )