@eshal-bot/chat-widget 0.1.45 → 0.1.47
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/dist/chat-widget.esm.js +5 -5
- package/dist/chat-widget.js +44 -25
- package/dist/chat-widget.min.js +5 -5
- package/dist/chat-widget.umd.js +5 -5
- package/package.json +1 -1
package/dist/chat-widget.js
CHANGED
|
@@ -9062,6 +9062,27 @@
|
|
|
9062
9062
|
};
|
|
9063
9063
|
};
|
|
9064
9064
|
|
|
9065
|
+
// Merge the text (SSE) and voice (Bidi) message arrays into one chronological
|
|
9066
|
+
// transcript: tag text messages with a default source, dedupe by id, and sort
|
|
9067
|
+
// by timestamp. Used for BOTH live display (activeMessages) and the
|
|
9068
|
+
// localStorage snapshot — so voice turns persist across reload exactly like
|
|
9069
|
+
// text turns. (Previously the snapshot saved only the text array, so voice
|
|
9070
|
+
// vanished on reload even though it rendered live and was saved server-side
|
|
9071
|
+
// in the Inbox.)
|
|
9072
|
+
const mergeTranscript = (messages, bidiMessages) => {
|
|
9073
|
+
const allMessages = [...messages.map(msg => _objectSpread2(_objectSpread2({}, msg), {}, {
|
|
9074
|
+
metadata: msg.metadata || {
|
|
9075
|
+
source: "sse"
|
|
9076
|
+
}
|
|
9077
|
+
})), ...bidiMessages];
|
|
9078
|
+
const uniqueMessages = Array.from(new Map(allMessages.map(msg => [msg.id, msg])).values());
|
|
9079
|
+
return uniqueMessages.sort((a, b) => {
|
|
9080
|
+
const timeA = a.timestamp instanceof Date ? a.timestamp.getTime() : new Date(a.timestamp).getTime();
|
|
9081
|
+
const timeB = b.timestamp instanceof Date ? b.timestamp.getTime() : new Date(b.timestamp).getTime();
|
|
9082
|
+
return timeA - timeB;
|
|
9083
|
+
});
|
|
9084
|
+
};
|
|
9085
|
+
|
|
9065
9086
|
// Helper functions for onboarding
|
|
9066
9087
|
const getOnboardingQuestions = onboardingQuestions => {
|
|
9067
9088
|
if (onboardingQuestions && onboardingQuestions.length > 0) {
|
|
@@ -9457,8 +9478,12 @@
|
|
|
9457
9478
|
reactExports.useEffect(() => {
|
|
9458
9479
|
if (!organizationId || !bidiSessionId) return;
|
|
9459
9480
|
if (isConversationLoading || isLoading) return;
|
|
9460
|
-
|
|
9461
|
-
|
|
9481
|
+
// Persist the MERGED transcript (text + voice). Previously only `messages`
|
|
9482
|
+
// (text) was saved, so bidi/voice turns — which live in `bidiMessages` —
|
|
9483
|
+
// were dropped on reload even though they render live and are saved
|
|
9484
|
+
// server-side (Inbox). Merging here makes voice survive reload like text.
|
|
9485
|
+
saveSessionMessages(organizationId, bidiSessionId, mergeTranscript(messages, bidiMessages), resolvedMessageLimits);
|
|
9486
|
+
}, [messages, bidiMessages, organizationId, bidiSessionId, isConversationLoading, isLoading, resolvedMessageLimits]);
|
|
9462
9487
|
|
|
9463
9488
|
// Show the onboarding form on first load; bypass it if already completed (persisted in session)
|
|
9464
9489
|
reactExports.useEffect(() => {
|
|
@@ -10950,28 +10975,7 @@
|
|
|
10950
10975
|
|
|
10951
10976
|
// Merge and sort messages from both sources (text and voice) by timestamp
|
|
10952
10977
|
// This ensures all messages persist regardless of voice session state
|
|
10953
|
-
const activeMessages = reactExports.useMemo(() =>
|
|
10954
|
-
// Merge both message arrays
|
|
10955
|
-
const allMessages = [
|
|
10956
|
-
// Convert regular messages to include metadata if not present
|
|
10957
|
-
...messages.map(msg => _objectSpread2(_objectSpread2({}, msg), {}, {
|
|
10958
|
-
metadata: msg.metadata || {
|
|
10959
|
-
source: "sse"
|
|
10960
|
-
}
|
|
10961
|
-
})),
|
|
10962
|
-
// Include bidi messages
|
|
10963
|
-
...bidiMessages];
|
|
10964
|
-
|
|
10965
|
-
// Remove duplicates based on message ID (in case same message exists in both arrays)
|
|
10966
|
-
const uniqueMessages = Array.from(new Map(allMessages.map(msg => [msg.id, msg])).values());
|
|
10967
|
-
|
|
10968
|
-
// Sort by timestamp to maintain chronological order
|
|
10969
|
-
return uniqueMessages.sort((a, b) => {
|
|
10970
|
-
const timeA = a.timestamp instanceof Date ? a.timestamp.getTime() : new Date(a.timestamp).getTime();
|
|
10971
|
-
const timeB = b.timestamp instanceof Date ? b.timestamp.getTime() : new Date(b.timestamp).getTime();
|
|
10972
|
-
return timeA - timeB;
|
|
10973
|
-
});
|
|
10974
|
-
}, [bidiMessages, messages]);
|
|
10978
|
+
const activeMessages = reactExports.useMemo(() => mergeTranscript(messages, bidiMessages), [bidiMessages, messages]);
|
|
10975
10979
|
|
|
10976
10980
|
// Log message state changes for debugging
|
|
10977
10981
|
reactExports.useEffect(() => {
|
|
@@ -60077,6 +60081,21 @@
|
|
|
60077
60081
|
// Handle X button: first click shows form, second click closes
|
|
60078
60082
|
const handleCloseClick = reactExports.useCallback(() => {
|
|
60079
60083
|
if (!isCsatEnabled) {
|
|
60084
|
+
// CSAT disabled: closing the chat should also clear out the
|
|
60085
|
+
// conversation, mirroring the post-CSAT clear in
|
|
60086
|
+
// handleResolveSubmission. Without this the X button only hides
|
|
60087
|
+
// the window while the old transcript persists in the session and
|
|
60088
|
+
// re-appears on reopen / reload. Route through onRefreshChat (same
|
|
60089
|
+
// entry point the kebab "Refresh Chat" uses) so any change to the
|
|
60090
|
+
// refresh path applies here too, and clear widgetFilter explicitly.
|
|
60091
|
+
if (onWidgetFilterChange) {
|
|
60092
|
+
onWidgetFilterChange(null);
|
|
60093
|
+
}
|
|
60094
|
+
if (onRefreshChat) {
|
|
60095
|
+
onRefreshChat();
|
|
60096
|
+
} else if (onResetConversation) {
|
|
60097
|
+
onResetConversation();
|
|
60098
|
+
}
|
|
60080
60099
|
onClose === null || onClose === void 0 || onClose();
|
|
60081
60100
|
return;
|
|
60082
60101
|
}
|
|
@@ -60088,7 +60107,7 @@
|
|
|
60088
60107
|
} else {
|
|
60089
60108
|
onClose === null || onClose === void 0 || onClose();
|
|
60090
60109
|
}
|
|
60091
|
-
}, [isCsatEnabled, showResolveForm, isConversationResolved, onClose]);
|
|
60110
|
+
}, [isCsatEnabled, showResolveForm, isConversationResolved, onClose, onWidgetFilterChange, onRefreshChat, onResetConversation]);
|
|
60092
60111
|
reactExports.useEffect(() => {
|
|
60093
60112
|
if (isCsatEnabled) return;
|
|
60094
60113
|
if (showResolveForm) setShowResolveForm(false);
|