@seamly/web-ui 19.1.5 → 19.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,9 +2,16 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 19.1.6 (14 September 2022)
6
+
7
+ ### Bugfixes
8
+
9
+ - Fix an issue where destructuring the `type` of an `entry` would result in an error when the `payload` was `undefined`.
10
+
5
11
  ## 19.1.5 (17 August 2022)
6
12
 
7
13
  ### Bugfixes
14
+
8
15
  - Fix an issue where the interface would not be translated when translation had started before the user had sent a message.
9
16
 
10
17
  ## 19.1.4 (16 February 2022)
@@ -2310,7 +2310,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2310
2310
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2311
2311
 
2312
2312
  "use strict";
2313
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"eventTypes\": () => (/* binding */ eventTypes),\n/* harmony export */ \"payloadTypes\": () => (/* binding */ payloadTypes),\n/* harmony export */ \"entryTypes\": () => (/* binding */ entryTypes),\n/* harmony export */ \"readStates\": () => (/* binding */ readStates),\n/* harmony export */ \"actionTypes\": () => (/* binding */ actionTypes),\n/* harmony export */ \"dismissTypes\": () => (/* binding */ dismissTypes),\n/* harmony export */ \"ariaLiveLevels\": () => (/* binding */ ariaLiveLevels),\n/* harmony export */ \"dividerKeys\": () => (/* binding */ dividerKeys),\n/* harmony export */ \"featureKeys\": () => (/* binding */ featureKeys),\n/* harmony export */ \"seamlyActions\": () => (/* binding */ seamlyActions),\n/* harmony export */ \"cardTypes\": () => (/* binding */ cardTypes),\n/* harmony export */ \"isUnreadMessage\": () => (/* binding */ isUnreadMessage),\n/* harmony export */ \"mergeHistory\": () => (/* binding */ mergeHistory),\n/* harmony export */ \"seamlyStateReducer\": () => (/* binding */ seamlyStateReducer)\n/* harmony export */ });\n/* harmony import */ var _general_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./general-utils */ \"./src/javascripts/ui/utils/general-utils.js\");\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n\nconst eventTypes = {\n info: 'info',\n message: 'message',\n participant: 'participant',\n system: 'system'\n};\nconst payloadTypes = {\n choicePrompt: 'choice_prompt',\n text: 'text',\n image: 'image',\n video: 'video',\n participant: 'participant',\n divider: 'divider',\n translation: 'translation',\n message: 'message',\n countdown: 'countdown',\n upload: 'upload',\n cta: 'cta'\n};\nconst entryTypes = {\n text: 'text',\n upload: 'upload'\n};\nconst readStates = {\n received: 'received',\n read: 'read'\n};\nconst actionTypes = {\n pickChoice: 'pick_choice',\n navigate: 'navigate',\n custom: 'custom',\n typing: 'typing',\n read: 'read',\n detachService: 'detach_service',\n interactivityUpdate: 'interactivity_update',\n dismiss: 'dismiss',\n sendTranscript: 'send_transcript',\n setTranslation: 'set_translation',\n clickCta: 'click_cta',\n clickCard: 'click_card'\n};\nconst dismissTypes = {\n resumeConversationPrompt: 'resume_conversation_prompt'\n};\nconst ariaLiveLevels = {\n assertive: 'assertive',\n polite: 'polite'\n};\nconst dividerKeys = {\n new_topic: 'newTopic',\n new_translation: 'newTranslation'\n};\nconst featureKeys = {\n cobrowsing: 'cobrowsing',\n sendTranscript: 'sendTranscript',\n typingPeekahead: 'typingPeekahead',\n uploads: 'uploads'\n};\nconst seamlyActions = {\n ADD_EVENT: 'ADD_EVENT',\n CLEAR_EVENTS: 'CLEAR_EVENTS',\n SET_HISTORY: 'SET_HISTORY',\n SET_EVENTS_READ: 'SET_EVENTS_READ',\n ACK_EVENT: 'ACK_EVENT',\n SET_IS_LOADING: 'SET_IS_LOADING',\n CLEAR_PARTICIPANTS: 'CLEAR_PARTICIPANTS',\n SET_PARTICIPANT: 'SET_PARTICIPANT',\n SET_HEADER_TITLE: 'SET_HEADER_TITLE',\n SET_HEADER_SUB_TITLE: 'SET_HEADER_SUB_TITLE',\n RESET_HISTORY_LOADED_FLAG: 'RESET_HISTORY_LOADED_FLAG',\n SET_ACTIVE_SERVICE: 'SET_ACTIVE_SERVICE',\n INIT_IDLE_DETACH_COUNTDOWN: 'INIT_IDLE_DETACH_COUNTDOWN',\n DECREMENT_IDLE_DETACH_COUNTDOWN_COUNTER: 'DECREMENT_IDLE_DETACH_COUNTDOWN_COUNTER',\n STOP_IDLE_DETACH_COUNTDOWN_COUNTER: 'STOP_IDLE_DETACH_COUNTDOWN_COUNTER',\n CLEAR_IDLE_DETACH_COUNTDOWN: 'CLEAR_IDLE_DETACH_COUNTDOWN',\n INIT_RESUME_CONVERSATION_PROMPT: 'INIT_RESUME_CONVERSATION_PROMPT',\n CLEAR_RESUME_CONVERSATION_PROMPT: 'CLEAR_RESUME_CONVERSATION_PROMPT',\n SET_SERVICE_DATA_ITEM: 'SET_SERVICE_DATA_ITEM',\n SET_FEATURES: 'SET_FEATURES',\n SET_FEATURE_ENABLED_STATE: 'SET_FEATURE_ENABLED_STATE',\n CLEAR_FEATURES: 'CLEAR_FEATURES',\n SET_INITIAL_STATE: 'SET_INITIAL_STATE',\n SET_USER_SELECTED_OPTIONS: 'SET_USER_SELECTED_OPTIONS',\n SET_USER_SELECTED_OPTION: 'SET_USER_SELECTED_OPTION',\n SHOW_OPTION: 'SHOW_OPTION',\n HIDE_OPTION: 'HIDE_OPTION',\n SET_SERVICE_ENTRY_METADATA: 'SET_SERVICE_ENTRY_METADATA',\n SET_BLOCK_AUTO_ENTRY_SWITCH: 'SET_BLOCK_AUTO_ENTRY_SWITCH',\n SET_ACTIVE_ENTRY_TYPE: 'SET_ACTIVE_ENTRY_TYPE',\n SET_USER_ENTRY_TYPE: 'SET_USER_ENTRY_TYPE',\n REGISTER_UPLOAD: 'REGISTER_UPLOAD',\n SET_UPLOAD_PROGRESS: 'SET_UPLOAD_PROGRESS',\n SET_UPLOAD_COMPLETE: 'SET_UPLOAD_COMPLETE',\n SET_UPLOAD_ERROR: 'SET_UPLOAD_ERROR',\n CLEAR_UPLOAD: 'CLEAR_UPLOAD',\n CLEAR_ALL_UPLOADS: 'CLEAR_ALL_UPLOADS',\n SET_SEAMLY_CONTAINER_ELEMENT: 'SET_SEAMLY_CONTAINER_ELEMENT'\n};\nconst cardTypes = {\n ask: 'ask',\n navigate: 'navigate',\n topic: 'topic'\n};\nconst {\n ADD_EVENT,\n CLEAR_EVENTS,\n SET_HISTORY,\n SET_EVENTS_READ,\n ACK_EVENT,\n SET_IS_LOADING,\n CLEAR_PARTICIPANTS,\n SET_PARTICIPANT,\n SET_HEADER_TITLE,\n SET_HEADER_SUB_TITLE,\n RESET_HISTORY_LOADED_FLAG,\n SET_ACTIVE_SERVICE,\n INIT_IDLE_DETACH_COUNTDOWN,\n DECREMENT_IDLE_DETACH_COUNTDOWN_COUNTER,\n STOP_IDLE_DETACH_COUNTDOWN_COUNTER,\n CLEAR_IDLE_DETACH_COUNTDOWN,\n INIT_RESUME_CONVERSATION_PROMPT,\n CLEAR_RESUME_CONVERSATION_PROMPT,\n SET_SERVICE_DATA_ITEM,\n SET_FEATURES,\n SET_FEATURE_ENABLED_STATE,\n CLEAR_FEATURES,\n SET_INITIAL_STATE,\n SET_USER_SELECTED_OPTION,\n SET_USER_SELECTED_OPTIONS,\n SHOW_OPTION,\n HIDE_OPTION,\n SET_BLOCK_AUTO_ENTRY_SWITCH,\n SET_USER_ENTRY_TYPE,\n SET_ACTIVE_ENTRY_TYPE,\n SET_SERVICE_ENTRY_METADATA,\n REGISTER_UPLOAD,\n SET_UPLOAD_PROGRESS,\n SET_UPLOAD_COMPLETE,\n SET_UPLOAD_ERROR,\n CLEAR_UPLOAD,\n CLEAR_ALL_UPLOADS,\n SET_SEAMLY_CONTAINER_ELEMENT\n} = seamlyActions;\nconst isUnreadMessage = ({\n type,\n payload\n}) => type === eventTypes.message && !payload.fromClient || type === eventTypes.info && payload.type === payloadTypes.text;\n\nconst orderHistory = events => {\n return events.sort(({\n payload: {\n occurredAt: occurredAtA\n }\n }, {\n payload: {\n occurredAt: occurredAtB\n }\n }) => occurredAtA - occurredAtB);\n};\n\nconst mergeHistory = (stateEvents, historyEvents) => {\n const newHistoryEvents = historyEvents.filter(historyEvent => // Deduplicate the event streams\n !stateEvents.find(stateEvent => stateEvent.payload.id === historyEvent.payload.id) && // Remove all non displayable participant messages\n !(historyEvent.type === 'participant' && !historyEvent.payload.participant.introduction)) // Reverse is done here because the server sends the history in the order\n // newest to oldest. In the case of exactly the same occurredAt timestamps\n // these messages will be shown in the wrong order if not reversed. For\n // the normal merging logic there is no added effect.\n .reverse();\n return orderHistory([...newHistoryEvents, ...stateEvents]);\n};\n\nconst participantReducer = (state, action) => {\n switch (action.type) {\n case CLEAR_PARTICIPANTS:\n return {\n participants: {},\n currentAgent: ''\n };\n\n case SET_PARTICIPANT:\n const {\n participants\n } = state;\n const {\n id,\n avatar,\n name,\n introduction\n } = action.participant;\n const oldParticipant = participants[id];\n\n const newParticipants = _objectSpread(_objectSpread({}, participants), {}, {\n [id]: oldParticipant ? _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, oldParticipant), avatar ? {\n avatar\n } : {}), name ? {\n name\n } : {}), introduction ? {\n introduction\n } : {}) : action.participant\n });\n\n return _objectSpread(_objectSpread({}, state), {}, {\n participants: newParticipants,\n currentAgent: state.currentAgent !== id && !action.fromClient ? id : state.currentAgent\n });\n\n default:\n return state;\n }\n};\n\nconst headerTitlesReducer = (state, action) => {\n switch (action.type) {\n case SET_HEADER_TITLE:\n return _objectSpread(_objectSpread({}, state), {}, {\n title: action.title\n });\n\n case SET_HEADER_SUB_TITLE:\n return _objectSpread(_objectSpread({}, state), {}, {\n subTitle: action.title\n });\n\n default:\n return state;\n }\n};\n\nconst calculateNewEntryMeta = (entryMeta, payload) => {\n const {\n entry\n } = payload;\n const {\n blockAutoEntrySwitch\n } = entryMeta;\n\n if (!entry) {\n return _objectSpread(_objectSpread({}, entryMeta), {}, {\n optionsOverride: {}\n });\n }\n\n const {\n type,\n options\n } = entry;\n let newActive = entryMeta.active;\n\n if (!blockAutoEntrySwitch && type !== entryMeta.userSelected) {\n newActive = type;\n }\n\n return _objectSpread(_objectSpread({}, entryMeta), {}, {\n active: newActive,\n optionsOverride: _objectSpread(_objectSpread({}, entryMeta.optionsOverride), {}, {\n [type]: options || {}\n })\n });\n};\n\nconst seamlyStateReducer = (state, action) => {\n switch (action.type) {\n case ADD_EVENT:\n const {\n type: eventType,\n payload\n } = action.event;\n const accountHasUploads = state.options.features.hasOwnProperty(featureKeys.uploads);\n const newEntryMeta = calculateNewEntryMeta(state.entryMeta, payload);\n\n let newOptions = _objectSpread({}, state.options); // This enabled override of the service enabled value for uploads.\n // If a message is sent with entry of type upload it will temporarily\n // override service value and enable uploads.\n\n\n if (accountHasUploads && (eventType === eventTypes.message || eventType === eventTypes.participant) && !payload.fromClient) {\n const {\n type: entryType\n } = payload.entry || {};\n newOptions = _objectSpread(_objectSpread({}, newOptions), {}, {\n features: _objectSpread(_objectSpread({}, newOptions.features), {}, {\n uploads: _objectSpread(_objectSpread({}, newOptions.features.uploads), {}, {\n enabledFromEntry: entryType === entryTypes.upload\n })\n })\n });\n }\n\n const incrementUnread = isUnreadMessage(action.event); // We check for duplicated and ignore them as in some error of the websocket\n // a duplicate join can be active for a while until the server connection\n // times out.\n\n const eventExists = state.events.find(e => e.payload.id === payload.id);\n\n if (eventExists) {\n return state;\n }\n\n return _objectSpread(_objectSpread({}, state), {}, {\n entryMeta: !accountHasUploads && newEntryMeta.active === entryTypes.upload ? _objectSpread({}, state.entryMeta) : newEntryMeta,\n options: newOptions,\n unreadEvents: incrementUnread ? state.unreadEvents + 1 : state.unreadEvents,\n events: [...state.events, _objectSpread(_objectSpread({}, action.event), {}, {\n // The payload spread should be done after adding the message\n // status to enable overriding the status when setting\n // event optimistically.\n payload: _objectSpread(_objectSpread({}, incrementUnread && {\n messageStatus: payload.fromClient ? readStates.read : readStates.received\n }), payload)\n })]\n });\n\n case ACK_EVENT:\n // If any ACKs are sent without transactionID the conversation crashes.\n // Ensure that this edge case is handled gracefully.\n if (!action.event.payload.transactionId) {\n console.warn('ACK received without transaction ID.');\n return state;\n }\n\n const matchedEvent = state.events.find(m => m.payload.transactionId === action.event.payload.transactionId);\n const {\n id,\n occurredAt\n } = action.event.payload;\n return matchedEvent ? _objectSpread(_objectSpread({}, state), {}, {\n events: orderHistory(state.events.map(m => m.payload.id === matchedEvent.payload.id ? _objectSpread(_objectSpread({}, m), {}, {\n payload: _objectSpread(_objectSpread({}, m.payload), {}, {\n id,\n occurredAt\n })\n }) : m))\n }) : state;\n\n case CLEAR_EVENTS:\n return _objectSpread(_objectSpread({}, state), {}, {\n unreadEvents: 0,\n events: []\n });\n\n case SET_EVENTS_READ:\n return _objectSpread(_objectSpread({}, state), {}, {\n unreadEvents: 0,\n events: state.events.map(event => {\n if (action.ids.indexOf(event.payload.id) !== -1) {\n return _objectSpread(_objectSpread({}, event), {}, {\n payload: _objectSpread(_objectSpread({}, event.payload), event.payload.messageStatus === readStates.received && {\n messageStatus: readStates.read\n })\n });\n }\n\n return event;\n })\n });\n\n case SET_HISTORY:\n const {\n events: history,\n participants,\n activeServiceSessionId,\n activeServiceSettings = {},\n serviceData,\n resumeConversationPrompt\n } = action.history;\n const events = mergeHistory(state.events, history);\n\n const mergedParticipants = _objectSpread(_objectSpread({}, state.participantInfo.participants), participants);\n\n const lastParticipantEvent = events.slice().reverse().find(m => (m.type === 'message' || m.type === 'participant') && !m.payload.fromClient);\n let lastParticipantId = null;\n\n if (lastParticipantEvent) {\n if (lastParticipantEvent.type === 'message') {\n lastParticipantId = lastParticipantEvent.payload.participant;\n }\n\n if (lastParticipantEvent.type === 'participant') {\n lastParticipantId = lastParticipantEvent.payload.participant.id;\n }\n }\n\n const {\n cobrowsing,\n entry,\n uploads\n } = activeServiceSettings;\n const historyNewEntryMeta = calculateNewEntryMeta(_objectSpread(_objectSpread(_objectSpread({}, state.entryMeta), entry), {}, {\n active: entry.default || payloadTypes.text,\n options: _objectSpread({}, entry && entry.options ? entry.options : {})\n }), events[events.length - 1].payload);\n\n let newFeatures = _objectSpread({}, state.options.features); // Only set cobrowsing if it was initialised by the account config.\n\n\n if (newFeatures.hasOwnProperty(featureKeys.cobrowsing)) {\n newFeatures = _objectSpread(_objectSpread({}, newFeatures), {}, {\n cobrowsing: {\n enabled: !!(cobrowsing && cobrowsing.enabled)\n }\n });\n }\n\n const newFeaturesHasUpload = newFeatures.hasOwnProperty(featureKeys.uploads); // Only set uploads if it was initialised by the account config.\n\n if (newFeaturesHasUpload) {\n const {\n payload: lastParticipantEventPayload\n } = lastParticipantEvent;\n const {\n type: entryType\n } = lastParticipantEventPayload.entry || {};\n newFeatures = _objectSpread(_objectSpread({}, newFeatures), {}, {\n uploads: {\n enabled: !!(uploads && uploads.enabled),\n enabledFromEntry: entryType === entryTypes.upload\n }\n });\n }\n\n const returnState = _objectSpread(_objectSpread({}, state), {}, {\n unreadEvents: events.filter(event => event.type === 'message' && event.payload.messageStatus === readStates.received).length,\n events: events.filter(e => e.type !== 'participant' || !!e.payload.participant.introduction),\n participantInfo: _objectSpread(_objectSpread(_objectSpread({}, state.participantInfo), lastParticipantId ? participantReducer(state.participantInfo, {\n type: SET_PARTICIPANT,\n participant: mergedParticipants[lastParticipantId]\n }) : {}), {}, {\n participants: mergedParticipants\n }),\n historyLoaded: true,\n serviceInfo: _objectSpread(_objectSpread({}, state.serviceInfo), {}, {\n activeServiceSessionId\n }),\n serviceData: serviceData || {},\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n features: newFeatures\n }),\n entryMeta: !newFeaturesHasUpload && historyNewEntryMeta.active === entryTypes.upload ? _objectSpread({}, state.entryMeta) : historyNewEntryMeta,\n resumeConversationPrompt: resumeConversationPrompt || false\n });\n\n if (lastParticipantId) {\n returnState.headerTitles = headerTitlesReducer(state.headerTitles, {\n type: SET_HEADER_SUB_TITLE,\n title: mergedParticipants[lastParticipantId].name\n });\n }\n\n return returnState;\n\n case RESET_HISTORY_LOADED_FLAG:\n return _objectSpread(_objectSpread({}, state), {}, {\n historyLoaded: false\n });\n\n case SET_IS_LOADING:\n return _objectSpread(_objectSpread({}, state), {}, {\n isLoading: action.isLoading\n });\n\n case INIT_IDLE_DETACH_COUNTDOWN:\n const {\n delaySeconds,\n delayTime\n } = action;\n return _objectSpread(_objectSpread({}, state), {}, {\n idleDetachCountdown: {\n hasCountdown: true,\n isActive: true,\n wasStopped: false,\n count: delaySeconds,\n remaining: delaySeconds,\n timer: delayTime\n }\n });\n\n case DECREMENT_IDLE_DETACH_COUNTDOWN_COUNTER:\n const {\n idleDetachCountdown\n } = state;\n const {\n remaining: prevRemaining\n } = idleDetachCountdown;\n const remaining = prevRemaining - 1;\n return _objectSpread(_objectSpread({}, state), {}, {\n idleDetachCountdown: _objectSpread(_objectSpread({}, state.idleDetachCountdown), {}, {\n remaining,\n timer: (0,_general_utils__WEBPACK_IMPORTED_MODULE_0__.getTimeFromSeconds)(remaining)\n })\n });\n\n case STOP_IDLE_DETACH_COUNTDOWN_COUNTER:\n {\n return _objectSpread(_objectSpread({}, state), {}, {\n idleDetachCountdown: _objectSpread(_objectSpread({}, state.idleDetachCountdown), {}, {\n isActive: false,\n wasStopped: true\n })\n });\n }\n\n case CLEAR_IDLE_DETACH_COUNTDOWN:\n return _objectSpread(_objectSpread({}, state), {}, {\n idleDetachCountdown: {\n hasCountdown: false,\n isActive: false\n }\n });\n\n case INIT_RESUME_CONVERSATION_PROMPT:\n return _objectSpread(_objectSpread({}, state), {}, {\n resumeConversationPrompt: true\n });\n\n case CLEAR_RESUME_CONVERSATION_PROMPT:\n return _objectSpread(_objectSpread({}, state), {}, {\n resumeConversationPrompt: false\n });\n\n case SET_PARTICIPANT:\n case CLEAR_PARTICIPANTS:\n return _objectSpread(_objectSpread({}, state), {}, {\n participantInfo: participantReducer(state.participantInfo, action)\n });\n\n case SET_ACTIVE_SERVICE:\n if (state.serviceInfo.activeServiceSessionId !== action.activeServiceSessionId) {\n return _objectSpread(_objectSpread({}, state), {}, {\n serviceInfo: _objectSpread(_objectSpread({}, state.serviceInfo), {}, {\n activeServiceSessionId: action.activeServiceSessionId\n })\n });\n }\n\n return state;\n\n case SET_HEADER_TITLE:\n case SET_HEADER_SUB_TITLE:\n return _objectSpread(_objectSpread({}, state), {}, {\n headerTitles: headerTitlesReducer(state.headerTitles, action)\n });\n\n case SET_INITIAL_STATE:\n return _objectSpread(_objectSpread({}, state), {}, {\n initialState: action.initialState\n });\n\n case SET_SERVICE_DATA_ITEM:\n return _objectSpread(_objectSpread({}, state), {}, {\n serviceData: _objectSpread(_objectSpread({}, state.serviceData), {}, {\n [action.payload.type]: action.payload\n })\n });\n\n case SET_FEATURES:\n return _objectSpread(_objectSpread({}, state), {}, {\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n features: action.features\n })\n });\n\n case SET_FEATURE_ENABLED_STATE:\n // Only set cobrowsing if it already exists in the object.\n // Otherwise we may set if for accounts not allowing it at all.\n return state.options.features.hasOwnProperty(action.key) ? _objectSpread(_objectSpread({}, state), {}, {\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n features: _objectSpread(_objectSpread({}, state.options.features), {}, {\n [action.key]: _objectSpread(_objectSpread({}, state.options.features[action.key] || {}), {}, {\n enabled: action.enabled\n })\n })\n })\n }) : state;\n\n case CLEAR_FEATURES:\n return _objectSpread(_objectSpread({}, state), {}, {\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n features: {}\n })\n });\n\n case SHOW_OPTION:\n return _objectSpread(_objectSpread({}, state), {}, {\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n panelActive: true,\n optionActive: action.optionName\n })\n });\n\n case HIDE_OPTION:\n return _objectSpread(_objectSpread({}, state), {}, {\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n panelActive: false,\n optionActive: ''\n })\n });\n\n case SET_USER_SELECTED_OPTIONS:\n return _objectSpread(_objectSpread({}, state), {}, {\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n userSelectedOptions: action.options\n })\n });\n\n case SET_USER_SELECTED_OPTION:\n const {\n option,\n value\n } = action;\n return _objectSpread(_objectSpread({}, state), {}, {\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n userSelectedOptions: _objectSpread(_objectSpread({}, state.options.userSelectedOptions), {}, {\n [option]: value\n })\n })\n });\n\n case SET_BLOCK_AUTO_ENTRY_SWITCH:\n const {\n value: blockAutoEntrySwitch\n } = action;\n return _objectSpread(_objectSpread({}, state), {}, {\n entryMeta: _objectSpread(_objectSpread({}, state.entryMeta), {}, {\n blockAutoEntrySwitch\n })\n });\n\n case SET_SERVICE_ENTRY_METADATA:\n const {\n entryMeta\n } = action;\n return _objectSpread(_objectSpread({}, state), {}, {\n entryMeta: _objectSpread(_objectSpread(_objectSpread({}, state.entryMeta), entryMeta), {}, {\n active: entryMeta.default,\n options: _objectSpread({}, entryMeta.options || {}),\n overrideOptions: {}\n })\n });\n\n case SET_ACTIVE_ENTRY_TYPE:\n const {\n entryType: active\n } = action;\n return _objectSpread(_objectSpread({}, state), {}, {\n entryMeta: _objectSpread(_objectSpread({}, state.entryMeta), {}, {\n active\n })\n });\n\n case SET_USER_ENTRY_TYPE:\n const {\n entryType: userSelected\n } = action;\n return _objectSpread(_objectSpread({}, state), {}, {\n entryMeta: _objectSpread(_objectSpread({}, state.entryMeta), {}, {\n userSelected\n })\n });\n\n case REGISTER_UPLOAD:\n return _objectSpread(_objectSpread({}, state), {}, {\n currentUploads: [...state.currentUploads, {\n id: action.fileId,\n name: action.fileName,\n progress: 1,\n uploading: true,\n complete: false,\n error: '',\n uploadHandle: action.uploadHandle\n }]\n });\n\n case SET_UPLOAD_PROGRESS:\n return _objectSpread(_objectSpread({}, state), {}, {\n currentUploads: state.currentUploads.map(fileUpload => {\n if (fileUpload.id === action.fileId) {\n return _objectSpread(_objectSpread({}, fileUpload), {}, {\n progress: action.progress,\n uploading: action.progress !== 100,\n uploadHandle: action.progress === 100 ? null : fileUpload.uploadHandle\n });\n }\n\n return fileUpload;\n })\n });\n\n case SET_UPLOAD_ERROR:\n return _objectSpread(_objectSpread({}, state), {}, {\n currentUploads: state.currentUploads.map(fileUpload => {\n if (fileUpload.id === action.fileId) {\n return _objectSpread(_objectSpread({}, fileUpload), {}, {\n error: action.errorText,\n progress: 0,\n uploading: false,\n uploadHandle: null\n });\n }\n\n return fileUpload;\n })\n });\n\n case SET_UPLOAD_COMPLETE:\n return _objectSpread(_objectSpread({}, state), {}, {\n currentUploads: state.currentUploads.map(fileUpload => {\n if (fileUpload.id === action.fileId) {\n return _objectSpread(_objectSpread({}, fileUpload), {}, {\n complete: true\n });\n }\n\n return fileUpload;\n })\n });\n\n case CLEAR_UPLOAD:\n return _objectSpread(_objectSpread({}, state), {}, {\n currentUploads: state.currentUploads.filter(fileUpload => fileUpload.id !== action.fileId)\n });\n\n case CLEAR_ALL_UPLOADS:\n return _objectSpread(_objectSpread({}, state), {}, {\n currentUploads: []\n });\n\n case SET_SEAMLY_CONTAINER_ELEMENT:\n {\n return _objectSpread(_objectSpread({}, state), {}, {\n seamlyContainerElement: action.element\n });\n }\n\n default:\n return state;\n }\n};\n\n//# sourceURL=webpack://@seamly/web-ui/./src/javascripts/ui/utils/seamly-utils.js?");
2313
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"eventTypes\": () => (/* binding */ eventTypes),\n/* harmony export */ \"payloadTypes\": () => (/* binding */ payloadTypes),\n/* harmony export */ \"entryTypes\": () => (/* binding */ entryTypes),\n/* harmony export */ \"readStates\": () => (/* binding */ readStates),\n/* harmony export */ \"actionTypes\": () => (/* binding */ actionTypes),\n/* harmony export */ \"dismissTypes\": () => (/* binding */ dismissTypes),\n/* harmony export */ \"ariaLiveLevels\": () => (/* binding */ ariaLiveLevels),\n/* harmony export */ \"dividerKeys\": () => (/* binding */ dividerKeys),\n/* harmony export */ \"featureKeys\": () => (/* binding */ featureKeys),\n/* harmony export */ \"seamlyActions\": () => (/* binding */ seamlyActions),\n/* harmony export */ \"cardTypes\": () => (/* binding */ cardTypes),\n/* harmony export */ \"isUnreadMessage\": () => (/* binding */ isUnreadMessage),\n/* harmony export */ \"mergeHistory\": () => (/* binding */ mergeHistory),\n/* harmony export */ \"seamlyStateReducer\": () => (/* binding */ seamlyStateReducer)\n/* harmony export */ });\n/* harmony import */ var _general_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./general-utils */ \"./src/javascripts/ui/utils/general-utils.js\");\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n\nconst eventTypes = {\n info: 'info',\n message: 'message',\n participant: 'participant',\n system: 'system'\n};\nconst payloadTypes = {\n choicePrompt: 'choice_prompt',\n text: 'text',\n image: 'image',\n video: 'video',\n participant: 'participant',\n divider: 'divider',\n translation: 'translation',\n message: 'message',\n countdown: 'countdown',\n upload: 'upload',\n cta: 'cta'\n};\nconst entryTypes = {\n text: 'text',\n upload: 'upload'\n};\nconst readStates = {\n received: 'received',\n read: 'read'\n};\nconst actionTypes = {\n pickChoice: 'pick_choice',\n navigate: 'navigate',\n custom: 'custom',\n typing: 'typing',\n read: 'read',\n detachService: 'detach_service',\n interactivityUpdate: 'interactivity_update',\n dismiss: 'dismiss',\n sendTranscript: 'send_transcript',\n setTranslation: 'set_translation',\n clickCta: 'click_cta',\n clickCard: 'click_card'\n};\nconst dismissTypes = {\n resumeConversationPrompt: 'resume_conversation_prompt'\n};\nconst ariaLiveLevels = {\n assertive: 'assertive',\n polite: 'polite'\n};\nconst dividerKeys = {\n new_topic: 'newTopic',\n new_translation: 'newTranslation'\n};\nconst featureKeys = {\n cobrowsing: 'cobrowsing',\n sendTranscript: 'sendTranscript',\n typingPeekahead: 'typingPeekahead',\n uploads: 'uploads'\n};\nconst seamlyActions = {\n ADD_EVENT: 'ADD_EVENT',\n CLEAR_EVENTS: 'CLEAR_EVENTS',\n SET_HISTORY: 'SET_HISTORY',\n SET_EVENTS_READ: 'SET_EVENTS_READ',\n ACK_EVENT: 'ACK_EVENT',\n SET_IS_LOADING: 'SET_IS_LOADING',\n CLEAR_PARTICIPANTS: 'CLEAR_PARTICIPANTS',\n SET_PARTICIPANT: 'SET_PARTICIPANT',\n SET_HEADER_TITLE: 'SET_HEADER_TITLE',\n SET_HEADER_SUB_TITLE: 'SET_HEADER_SUB_TITLE',\n RESET_HISTORY_LOADED_FLAG: 'RESET_HISTORY_LOADED_FLAG',\n SET_ACTIVE_SERVICE: 'SET_ACTIVE_SERVICE',\n INIT_IDLE_DETACH_COUNTDOWN: 'INIT_IDLE_DETACH_COUNTDOWN',\n DECREMENT_IDLE_DETACH_COUNTDOWN_COUNTER: 'DECREMENT_IDLE_DETACH_COUNTDOWN_COUNTER',\n STOP_IDLE_DETACH_COUNTDOWN_COUNTER: 'STOP_IDLE_DETACH_COUNTDOWN_COUNTER',\n CLEAR_IDLE_DETACH_COUNTDOWN: 'CLEAR_IDLE_DETACH_COUNTDOWN',\n INIT_RESUME_CONVERSATION_PROMPT: 'INIT_RESUME_CONVERSATION_PROMPT',\n CLEAR_RESUME_CONVERSATION_PROMPT: 'CLEAR_RESUME_CONVERSATION_PROMPT',\n SET_SERVICE_DATA_ITEM: 'SET_SERVICE_DATA_ITEM',\n SET_FEATURES: 'SET_FEATURES',\n SET_FEATURE_ENABLED_STATE: 'SET_FEATURE_ENABLED_STATE',\n CLEAR_FEATURES: 'CLEAR_FEATURES',\n SET_INITIAL_STATE: 'SET_INITIAL_STATE',\n SET_USER_SELECTED_OPTIONS: 'SET_USER_SELECTED_OPTIONS',\n SET_USER_SELECTED_OPTION: 'SET_USER_SELECTED_OPTION',\n SHOW_OPTION: 'SHOW_OPTION',\n HIDE_OPTION: 'HIDE_OPTION',\n SET_SERVICE_ENTRY_METADATA: 'SET_SERVICE_ENTRY_METADATA',\n SET_BLOCK_AUTO_ENTRY_SWITCH: 'SET_BLOCK_AUTO_ENTRY_SWITCH',\n SET_ACTIVE_ENTRY_TYPE: 'SET_ACTIVE_ENTRY_TYPE',\n SET_USER_ENTRY_TYPE: 'SET_USER_ENTRY_TYPE',\n REGISTER_UPLOAD: 'REGISTER_UPLOAD',\n SET_UPLOAD_PROGRESS: 'SET_UPLOAD_PROGRESS',\n SET_UPLOAD_COMPLETE: 'SET_UPLOAD_COMPLETE',\n SET_UPLOAD_ERROR: 'SET_UPLOAD_ERROR',\n CLEAR_UPLOAD: 'CLEAR_UPLOAD',\n CLEAR_ALL_UPLOADS: 'CLEAR_ALL_UPLOADS',\n SET_SEAMLY_CONTAINER_ELEMENT: 'SET_SEAMLY_CONTAINER_ELEMENT'\n};\nconst cardTypes = {\n ask: 'ask',\n navigate: 'navigate',\n topic: 'topic'\n};\nconst {\n ADD_EVENT,\n CLEAR_EVENTS,\n SET_HISTORY,\n SET_EVENTS_READ,\n ACK_EVENT,\n SET_IS_LOADING,\n CLEAR_PARTICIPANTS,\n SET_PARTICIPANT,\n SET_HEADER_TITLE,\n SET_HEADER_SUB_TITLE,\n RESET_HISTORY_LOADED_FLAG,\n SET_ACTIVE_SERVICE,\n INIT_IDLE_DETACH_COUNTDOWN,\n DECREMENT_IDLE_DETACH_COUNTDOWN_COUNTER,\n STOP_IDLE_DETACH_COUNTDOWN_COUNTER,\n CLEAR_IDLE_DETACH_COUNTDOWN,\n INIT_RESUME_CONVERSATION_PROMPT,\n CLEAR_RESUME_CONVERSATION_PROMPT,\n SET_SERVICE_DATA_ITEM,\n SET_FEATURES,\n SET_FEATURE_ENABLED_STATE,\n CLEAR_FEATURES,\n SET_INITIAL_STATE,\n SET_USER_SELECTED_OPTION,\n SET_USER_SELECTED_OPTIONS,\n SHOW_OPTION,\n HIDE_OPTION,\n SET_BLOCK_AUTO_ENTRY_SWITCH,\n SET_USER_ENTRY_TYPE,\n SET_ACTIVE_ENTRY_TYPE,\n SET_SERVICE_ENTRY_METADATA,\n REGISTER_UPLOAD,\n SET_UPLOAD_PROGRESS,\n SET_UPLOAD_COMPLETE,\n SET_UPLOAD_ERROR,\n CLEAR_UPLOAD,\n CLEAR_ALL_UPLOADS,\n SET_SEAMLY_CONTAINER_ELEMENT\n} = seamlyActions;\nconst isUnreadMessage = ({\n type,\n payload\n}) => type === eventTypes.message && !payload.fromClient || type === eventTypes.info && payload.type === payloadTypes.text;\n\nconst orderHistory = events => {\n return events.sort(({\n payload: {\n occurredAt: occurredAtA\n }\n }, {\n payload: {\n occurredAt: occurredAtB\n }\n }) => occurredAtA - occurredAtB);\n};\n\nconst mergeHistory = (stateEvents, historyEvents) => {\n const newHistoryEvents = historyEvents.filter(historyEvent => // Deduplicate the event streams\n !stateEvents.find(stateEvent => stateEvent.payload.id === historyEvent.payload.id) && // Remove all non displayable participant messages\n !(historyEvent.type === 'participant' && !historyEvent.payload.participant.introduction)) // Reverse is done here because the server sends the history in the order\n // newest to oldest. In the case of exactly the same occurredAt timestamps\n // these messages will be shown in the wrong order if not reversed. For\n // the normal merging logic there is no added effect.\n .reverse();\n return orderHistory([...newHistoryEvents, ...stateEvents]);\n};\n\nconst participantReducer = (state, action) => {\n switch (action.type) {\n case CLEAR_PARTICIPANTS:\n return {\n participants: {},\n currentAgent: ''\n };\n\n case SET_PARTICIPANT:\n const {\n participants\n } = state;\n const {\n id,\n avatar,\n name,\n introduction\n } = action.participant;\n const oldParticipant = participants[id];\n\n const newParticipants = _objectSpread(_objectSpread({}, participants), {}, {\n [id]: oldParticipant ? _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, oldParticipant), avatar ? {\n avatar\n } : {}), name ? {\n name\n } : {}), introduction ? {\n introduction\n } : {}) : action.participant\n });\n\n return _objectSpread(_objectSpread({}, state), {}, {\n participants: newParticipants,\n currentAgent: state.currentAgent !== id && !action.fromClient ? id : state.currentAgent\n });\n\n default:\n return state;\n }\n};\n\nconst headerTitlesReducer = (state, action) => {\n switch (action.type) {\n case SET_HEADER_TITLE:\n return _objectSpread(_objectSpread({}, state), {}, {\n title: action.title\n });\n\n case SET_HEADER_SUB_TITLE:\n return _objectSpread(_objectSpread({}, state), {}, {\n subTitle: action.title\n });\n\n default:\n return state;\n }\n};\n\nconst calculateNewEntryMeta = (entryMeta, payload) => {\n const {\n entry\n } = payload;\n const {\n blockAutoEntrySwitch\n } = entryMeta;\n\n if (!entry) {\n return _objectSpread(_objectSpread({}, entryMeta), {}, {\n optionsOverride: {}\n });\n }\n\n const {\n type,\n options\n } = entry;\n let newActive = entryMeta.active;\n\n if (!blockAutoEntrySwitch && type !== entryMeta.userSelected) {\n newActive = type;\n }\n\n return _objectSpread(_objectSpread({}, entryMeta), {}, {\n active: newActive,\n optionsOverride: _objectSpread(_objectSpread({}, entryMeta.optionsOverride), {}, {\n [type]: options || {}\n })\n });\n};\n\nconst seamlyStateReducer = (state, action) => {\n switch (action.type) {\n case ADD_EVENT:\n const {\n type: eventType,\n payload\n } = action.event;\n const accountHasUploads = state.options.features.hasOwnProperty(featureKeys.uploads);\n const newEntryMeta = calculateNewEntryMeta(state.entryMeta, payload);\n\n let newOptions = _objectSpread({}, state.options); // This enabled override of the service enabled value for uploads.\n // If a message is sent with entry of type upload it will temporarily\n // override service value and enable uploads.\n\n\n if (accountHasUploads && (eventType === eventTypes.message || eventType === eventTypes.participant) && !payload.fromClient) {\n var _payload$entry;\n\n const entryType = payload === null || payload === void 0 ? void 0 : (_payload$entry = payload.entry) === null || _payload$entry === void 0 ? void 0 : _payload$entry.type;\n newOptions = _objectSpread(_objectSpread({}, newOptions), {}, {\n features: _objectSpread(_objectSpread({}, newOptions.features), {}, {\n uploads: _objectSpread(_objectSpread({}, newOptions.features.uploads), {}, {\n enabledFromEntry: entryType === entryTypes.upload\n })\n })\n });\n }\n\n const incrementUnread = isUnreadMessage(action.event); // We check for duplicated and ignore them as in some error of the websocket\n // a duplicate join can be active for a while until the server connection\n // times out.\n\n const eventExists = state.events.find(e => e.payload.id === payload.id);\n\n if (eventExists) {\n return state;\n }\n\n return _objectSpread(_objectSpread({}, state), {}, {\n entryMeta: !accountHasUploads && newEntryMeta.active === entryTypes.upload ? _objectSpread({}, state.entryMeta) : newEntryMeta,\n options: newOptions,\n unreadEvents: incrementUnread ? state.unreadEvents + 1 : state.unreadEvents,\n events: [...state.events, _objectSpread(_objectSpread({}, action.event), {}, {\n // The payload spread should be done after adding the message\n // status to enable overriding the status when setting\n // event optimistically.\n payload: _objectSpread(_objectSpread({}, incrementUnread && {\n messageStatus: payload.fromClient ? readStates.read : readStates.received\n }), payload)\n })]\n });\n\n case ACK_EVENT:\n // If any ACKs are sent without transactionID the conversation crashes.\n // Ensure that this edge case is handled gracefully.\n if (!action.event.payload.transactionId) {\n console.warn('ACK received without transaction ID.');\n return state;\n }\n\n const matchedEvent = state.events.find(m => m.payload.transactionId === action.event.payload.transactionId);\n const {\n id,\n occurredAt\n } = action.event.payload;\n return matchedEvent ? _objectSpread(_objectSpread({}, state), {}, {\n events: orderHistory(state.events.map(m => m.payload.id === matchedEvent.payload.id ? _objectSpread(_objectSpread({}, m), {}, {\n payload: _objectSpread(_objectSpread({}, m.payload), {}, {\n id,\n occurredAt\n })\n }) : m))\n }) : state;\n\n case CLEAR_EVENTS:\n return _objectSpread(_objectSpread({}, state), {}, {\n unreadEvents: 0,\n events: []\n });\n\n case SET_EVENTS_READ:\n return _objectSpread(_objectSpread({}, state), {}, {\n unreadEvents: 0,\n events: state.events.map(event => {\n if (action.ids.indexOf(event.payload.id) !== -1) {\n return _objectSpread(_objectSpread({}, event), {}, {\n payload: _objectSpread(_objectSpread({}, event.payload), event.payload.messageStatus === readStates.received && {\n messageStatus: readStates.read\n })\n });\n }\n\n return event;\n })\n });\n\n case SET_HISTORY:\n const {\n events: history,\n participants,\n activeServiceSessionId,\n activeServiceSettings = {},\n serviceData,\n resumeConversationPrompt\n } = action.history;\n const events = mergeHistory(state.events, history);\n\n const mergedParticipants = _objectSpread(_objectSpread({}, state.participantInfo.participants), participants);\n\n const lastParticipantEvent = events.slice().reverse().find(m => (m.type === 'message' || m.type === 'participant') && !m.payload.fromClient);\n let lastParticipantId = null;\n\n if (lastParticipantEvent) {\n if (lastParticipantEvent.type === 'message') {\n lastParticipantId = lastParticipantEvent.payload.participant;\n }\n\n if (lastParticipantEvent.type === 'participant') {\n lastParticipantId = lastParticipantEvent.payload.participant.id;\n }\n }\n\n const {\n cobrowsing,\n entry,\n uploads\n } = activeServiceSettings;\n const historyNewEntryMeta = calculateNewEntryMeta(_objectSpread(_objectSpread(_objectSpread({}, state.entryMeta), entry), {}, {\n active: entry.default || payloadTypes.text,\n options: _objectSpread({}, entry && entry.options ? entry.options : {})\n }), events[events.length - 1].payload);\n\n let newFeatures = _objectSpread({}, state.options.features); // Only set cobrowsing if it was initialised by the account config.\n\n\n if (newFeatures.hasOwnProperty(featureKeys.cobrowsing)) {\n newFeatures = _objectSpread(_objectSpread({}, newFeatures), {}, {\n cobrowsing: {\n enabled: !!(cobrowsing && cobrowsing.enabled)\n }\n });\n }\n\n const newFeaturesHasUpload = newFeatures.hasOwnProperty(featureKeys.uploads); // Only set uploads if it was initialised by the account config.\n\n if (newFeaturesHasUpload) {\n var _lastParticipantEvent, _lastParticipantEvent2;\n\n const entryType = lastParticipantEvent === null || lastParticipantEvent === void 0 ? void 0 : (_lastParticipantEvent = lastParticipantEvent.payload) === null || _lastParticipantEvent === void 0 ? void 0 : (_lastParticipantEvent2 = _lastParticipantEvent.entry) === null || _lastParticipantEvent2 === void 0 ? void 0 : _lastParticipantEvent2.type;\n newFeatures = _objectSpread(_objectSpread({}, newFeatures), {}, {\n uploads: {\n enabled: !!(uploads && uploads.enabled),\n enabledFromEntry: entryType === entryTypes.upload\n }\n });\n }\n\n const returnState = _objectSpread(_objectSpread({}, state), {}, {\n unreadEvents: events.filter(event => event.type === 'message' && event.payload.messageStatus === readStates.received).length,\n events: events.filter(e => e.type !== 'participant' || !!e.payload.participant.introduction),\n participantInfo: _objectSpread(_objectSpread(_objectSpread({}, state.participantInfo), lastParticipantId ? participantReducer(state.participantInfo, {\n type: SET_PARTICIPANT,\n participant: mergedParticipants[lastParticipantId]\n }) : {}), {}, {\n participants: mergedParticipants\n }),\n historyLoaded: true,\n serviceInfo: _objectSpread(_objectSpread({}, state.serviceInfo), {}, {\n activeServiceSessionId\n }),\n serviceData: serviceData || {},\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n features: newFeatures\n }),\n entryMeta: !newFeaturesHasUpload && historyNewEntryMeta.active === entryTypes.upload ? _objectSpread({}, state.entryMeta) : historyNewEntryMeta,\n resumeConversationPrompt: resumeConversationPrompt || false\n });\n\n if (lastParticipantId) {\n returnState.headerTitles = headerTitlesReducer(state.headerTitles, {\n type: SET_HEADER_SUB_TITLE,\n title: mergedParticipants[lastParticipantId].name\n });\n }\n\n return returnState;\n\n case RESET_HISTORY_LOADED_FLAG:\n return _objectSpread(_objectSpread({}, state), {}, {\n historyLoaded: false\n });\n\n case SET_IS_LOADING:\n return _objectSpread(_objectSpread({}, state), {}, {\n isLoading: action.isLoading\n });\n\n case INIT_IDLE_DETACH_COUNTDOWN:\n const {\n delaySeconds,\n delayTime\n } = action;\n return _objectSpread(_objectSpread({}, state), {}, {\n idleDetachCountdown: {\n hasCountdown: true,\n isActive: true,\n wasStopped: false,\n count: delaySeconds,\n remaining: delaySeconds,\n timer: delayTime\n }\n });\n\n case DECREMENT_IDLE_DETACH_COUNTDOWN_COUNTER:\n const {\n idleDetachCountdown\n } = state;\n const {\n remaining: prevRemaining\n } = idleDetachCountdown;\n const remaining = prevRemaining - 1;\n return _objectSpread(_objectSpread({}, state), {}, {\n idleDetachCountdown: _objectSpread(_objectSpread({}, state.idleDetachCountdown), {}, {\n remaining,\n timer: (0,_general_utils__WEBPACK_IMPORTED_MODULE_0__.getTimeFromSeconds)(remaining)\n })\n });\n\n case STOP_IDLE_DETACH_COUNTDOWN_COUNTER:\n {\n return _objectSpread(_objectSpread({}, state), {}, {\n idleDetachCountdown: _objectSpread(_objectSpread({}, state.idleDetachCountdown), {}, {\n isActive: false,\n wasStopped: true\n })\n });\n }\n\n case CLEAR_IDLE_DETACH_COUNTDOWN:\n return _objectSpread(_objectSpread({}, state), {}, {\n idleDetachCountdown: {\n hasCountdown: false,\n isActive: false\n }\n });\n\n case INIT_RESUME_CONVERSATION_PROMPT:\n return _objectSpread(_objectSpread({}, state), {}, {\n resumeConversationPrompt: true\n });\n\n case CLEAR_RESUME_CONVERSATION_PROMPT:\n return _objectSpread(_objectSpread({}, state), {}, {\n resumeConversationPrompt: false\n });\n\n case SET_PARTICIPANT:\n case CLEAR_PARTICIPANTS:\n return _objectSpread(_objectSpread({}, state), {}, {\n participantInfo: participantReducer(state.participantInfo, action)\n });\n\n case SET_ACTIVE_SERVICE:\n if (state.serviceInfo.activeServiceSessionId !== action.activeServiceSessionId) {\n return _objectSpread(_objectSpread({}, state), {}, {\n serviceInfo: _objectSpread(_objectSpread({}, state.serviceInfo), {}, {\n activeServiceSessionId: action.activeServiceSessionId\n })\n });\n }\n\n return state;\n\n case SET_HEADER_TITLE:\n case SET_HEADER_SUB_TITLE:\n return _objectSpread(_objectSpread({}, state), {}, {\n headerTitles: headerTitlesReducer(state.headerTitles, action)\n });\n\n case SET_INITIAL_STATE:\n return _objectSpread(_objectSpread({}, state), {}, {\n initialState: action.initialState\n });\n\n case SET_SERVICE_DATA_ITEM:\n return _objectSpread(_objectSpread({}, state), {}, {\n serviceData: _objectSpread(_objectSpread({}, state.serviceData), {}, {\n [action.payload.type]: action.payload\n })\n });\n\n case SET_FEATURES:\n return _objectSpread(_objectSpread({}, state), {}, {\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n features: action.features\n })\n });\n\n case SET_FEATURE_ENABLED_STATE:\n // Only set cobrowsing if it already exists in the object.\n // Otherwise we may set if for accounts not allowing it at all.\n return state.options.features.hasOwnProperty(action.key) ? _objectSpread(_objectSpread({}, state), {}, {\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n features: _objectSpread(_objectSpread({}, state.options.features), {}, {\n [action.key]: _objectSpread(_objectSpread({}, state.options.features[action.key] || {}), {}, {\n enabled: action.enabled\n })\n })\n })\n }) : state;\n\n case CLEAR_FEATURES:\n return _objectSpread(_objectSpread({}, state), {}, {\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n features: {}\n })\n });\n\n case SHOW_OPTION:\n return _objectSpread(_objectSpread({}, state), {}, {\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n panelActive: true,\n optionActive: action.optionName\n })\n });\n\n case HIDE_OPTION:\n return _objectSpread(_objectSpread({}, state), {}, {\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n panelActive: false,\n optionActive: ''\n })\n });\n\n case SET_USER_SELECTED_OPTIONS:\n return _objectSpread(_objectSpread({}, state), {}, {\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n userSelectedOptions: action.options\n })\n });\n\n case SET_USER_SELECTED_OPTION:\n const {\n option,\n value\n } = action;\n return _objectSpread(_objectSpread({}, state), {}, {\n options: _objectSpread(_objectSpread({}, state.options), {}, {\n userSelectedOptions: _objectSpread(_objectSpread({}, state.options.userSelectedOptions), {}, {\n [option]: value\n })\n })\n });\n\n case SET_BLOCK_AUTO_ENTRY_SWITCH:\n const {\n value: blockAutoEntrySwitch\n } = action;\n return _objectSpread(_objectSpread({}, state), {}, {\n entryMeta: _objectSpread(_objectSpread({}, state.entryMeta), {}, {\n blockAutoEntrySwitch\n })\n });\n\n case SET_SERVICE_ENTRY_METADATA:\n const {\n entryMeta\n } = action;\n return _objectSpread(_objectSpread({}, state), {}, {\n entryMeta: _objectSpread(_objectSpread(_objectSpread({}, state.entryMeta), entryMeta), {}, {\n active: entryMeta.default,\n options: _objectSpread({}, entryMeta.options || {}),\n overrideOptions: {}\n })\n });\n\n case SET_ACTIVE_ENTRY_TYPE:\n const {\n entryType: active\n } = action;\n return _objectSpread(_objectSpread({}, state), {}, {\n entryMeta: _objectSpread(_objectSpread({}, state.entryMeta), {}, {\n active\n })\n });\n\n case SET_USER_ENTRY_TYPE:\n const {\n entryType: userSelected\n } = action;\n return _objectSpread(_objectSpread({}, state), {}, {\n entryMeta: _objectSpread(_objectSpread({}, state.entryMeta), {}, {\n userSelected\n })\n });\n\n case REGISTER_UPLOAD:\n return _objectSpread(_objectSpread({}, state), {}, {\n currentUploads: [...state.currentUploads, {\n id: action.fileId,\n name: action.fileName,\n progress: 1,\n uploading: true,\n complete: false,\n error: '',\n uploadHandle: action.uploadHandle\n }]\n });\n\n case SET_UPLOAD_PROGRESS:\n return _objectSpread(_objectSpread({}, state), {}, {\n currentUploads: state.currentUploads.map(fileUpload => {\n if (fileUpload.id === action.fileId) {\n return _objectSpread(_objectSpread({}, fileUpload), {}, {\n progress: action.progress,\n uploading: action.progress !== 100,\n uploadHandle: action.progress === 100 ? null : fileUpload.uploadHandle\n });\n }\n\n return fileUpload;\n })\n });\n\n case SET_UPLOAD_ERROR:\n return _objectSpread(_objectSpread({}, state), {}, {\n currentUploads: state.currentUploads.map(fileUpload => {\n if (fileUpload.id === action.fileId) {\n return _objectSpread(_objectSpread({}, fileUpload), {}, {\n error: action.errorText,\n progress: 0,\n uploading: false,\n uploadHandle: null\n });\n }\n\n return fileUpload;\n })\n });\n\n case SET_UPLOAD_COMPLETE:\n return _objectSpread(_objectSpread({}, state), {}, {\n currentUploads: state.currentUploads.map(fileUpload => {\n if (fileUpload.id === action.fileId) {\n return _objectSpread(_objectSpread({}, fileUpload), {}, {\n complete: true\n });\n }\n\n return fileUpload;\n })\n });\n\n case CLEAR_UPLOAD:\n return _objectSpread(_objectSpread({}, state), {}, {\n currentUploads: state.currentUploads.filter(fileUpload => fileUpload.id !== action.fileId)\n });\n\n case CLEAR_ALL_UPLOADS:\n return _objectSpread(_objectSpread({}, state), {}, {\n currentUploads: []\n });\n\n case SET_SEAMLY_CONTAINER_ELEMENT:\n {\n return _objectSpread(_objectSpread({}, state), {}, {\n seamlyContainerElement: action.element\n });\n }\n\n default:\n return state;\n }\n};\n\n//# sourceURL=webpack://@seamly/web-ui/./src/javascripts/ui/utils/seamly-utils.js?");
2314
2314
 
2315
2315
  /***/ }),
2316
2316