@cossistant/react 0.0.3 → 0.0.5
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/README.md +74 -0
- package/_virtual/rolldown_runtime.js +19 -0
- package/conversation.d.ts +26 -3
- package/conversation.d.ts.map +1 -1
- package/hooks/index.d.ts +5 -3
- package/hooks/index.js +7 -5
- package/hooks/private/store/use-conversations-store.d.ts +8 -0
- package/hooks/private/store/use-conversations-store.d.ts.map +1 -1
- package/hooks/private/store/use-conversations-store.js +8 -0
- package/hooks/private/store/use-conversations-store.js.map +1 -1
- package/hooks/private/store/use-store-selector.d.ts +4 -0
- package/hooks/private/store/use-store-selector.d.ts.map +1 -1
- package/hooks/private/store/use-store-selector.js +5 -2
- package/hooks/private/store/use-store-selector.js.map +1 -1
- package/hooks/private/store/use-website-store.d.ts +4 -0
- package/hooks/private/store/use-website-store.d.ts.map +1 -1
- package/hooks/private/store/use-website-store.js +6 -3
- package/hooks/private/store/use-website-store.js.map +1 -1
- package/hooks/private/typing.d.ts +35 -0
- package/hooks/private/typing.d.ts.map +1 -0
- package/hooks/private/typing.js +49 -0
- package/hooks/private/typing.js.map +1 -0
- package/hooks/private/use-client-query.d.ts +5 -0
- package/hooks/private/use-client-query.d.ts.map +1 -1
- package/hooks/private/use-client-query.js +5 -0
- package/hooks/private/use-client-query.js.map +1 -1
- package/hooks/private/use-grouped-messages.d.ts +10 -4
- package/hooks/private/use-grouped-messages.d.ts.map +1 -1
- package/hooks/private/use-grouped-messages.js +24 -4
- package/hooks/private/use-grouped-messages.js.map +1 -1
- package/hooks/private/use-multimodal-input.d.ts.map +1 -1
- package/hooks/private/use-rest-client.d.ts.map +1 -1
- package/hooks/private/use-visitor-typing-reporter.d.ts +6 -0
- package/hooks/private/use-visitor-typing-reporter.d.ts.map +1 -1
- package/hooks/private/use-visitor-typing-reporter.js +6 -0
- package/hooks/private/use-visitor-typing-reporter.js.map +1 -1
- package/hooks/use-composer-refocus.d.ts.map +1 -1
- package/hooks/use-conversation-auto-seen.d.ts +9 -0
- package/hooks/use-conversation-auto-seen.d.ts.map +1 -1
- package/hooks/use-conversation-auto-seen.js +44 -3
- package/hooks/use-conversation-auto-seen.js.map +1 -1
- package/hooks/use-conversation-history-page.d.ts.map +1 -1
- package/hooks/use-conversation-history-page.js +16 -18
- package/hooks/use-conversation-history-page.js.map +1 -1
- package/hooks/use-conversation-lifecycle.d.ts.map +1 -1
- package/hooks/use-conversation-lifecycle.js +2 -4
- package/hooks/use-conversation-lifecycle.js.map +1 -1
- package/hooks/use-conversation-page.d.ts +6 -0
- package/hooks/use-conversation-page.d.ts.map +1 -1
- package/hooks/use-conversation-page.js +41 -3
- package/hooks/use-conversation-page.js.map +1 -1
- package/hooks/use-conversation-preview.d.ts +61 -0
- package/hooks/use-conversation-preview.d.ts.map +1 -0
- package/hooks/use-conversation-preview.js +173 -0
- package/hooks/use-conversation-preview.js.map +1 -0
- package/hooks/use-conversation-seen.d.ts +4 -0
- package/hooks/use-conversation-seen.d.ts.map +1 -1
- package/hooks/use-conversation-seen.js +4 -0
- package/hooks/use-conversation-seen.js.map +1 -1
- package/hooks/use-conversation-timeline-items.d.ts +4 -0
- package/hooks/use-conversation-timeline-items.d.ts.map +1 -1
- package/hooks/use-conversation-timeline-items.js +4 -0
- package/hooks/use-conversation-timeline-items.js.map +1 -1
- package/hooks/use-conversation-timeline.d.ts +32 -0
- package/hooks/use-conversation-timeline.d.ts.map +1 -0
- package/hooks/use-conversation-timeline.js +41 -0
- package/hooks/use-conversation-timeline.js.map +1 -0
- package/hooks/use-conversation-typing.d.ts +4 -0
- package/hooks/use-conversation-typing.d.ts.map +1 -1
- package/hooks/use-conversation-typing.js +4 -0
- package/hooks/use-conversation-typing.js.map +1 -1
- package/hooks/use-conversation.d.ts +11 -0
- package/hooks/use-conversation.d.ts.map +1 -1
- package/hooks/use-conversation.js +11 -0
- package/hooks/use-conversation.js.map +1 -1
- package/hooks/use-conversations.d.ts +12 -0
- package/hooks/use-conversations.d.ts.map +1 -1
- package/hooks/use-conversations.js +12 -0
- package/hooks/use-conversations.js.map +1 -1
- package/hooks/use-create-conversation.d.ts +5 -0
- package/hooks/use-create-conversation.d.ts.map +1 -1
- package/hooks/use-create-conversation.js +12 -9
- package/hooks/use-create-conversation.js.map +1 -1
- package/hooks/use-home-page.d.ts.map +1 -1
- package/hooks/use-home-page.js +6 -4
- package/hooks/use-home-page.js.map +1 -1
- package/hooks/use-message-composer.d.ts.map +1 -1
- package/hooks/use-realtime-support.d.ts.map +1 -1
- package/hooks/use-send-message.d.ts +9 -0
- package/hooks/use-send-message.d.ts.map +1 -1
- package/hooks/use-send-message.js +15 -13
- package/hooks/use-send-message.js.map +1 -1
- package/hooks/use-visitor.d.ts.map +1 -1
- package/hooks/use-visitor.js +28 -30
- package/hooks/use-visitor.js.map +1 -1
- package/hooks/use-window-visibility-focus.d.ts +4 -0
- package/hooks/use-window-visibility-focus.d.ts.map +1 -1
- package/hooks/use-window-visibility-focus.js +5 -2
- package/hooks/use-window-visibility-focus.js.map +1 -1
- package/identify-visitor.d.ts +12 -3
- package/identify-visitor.d.ts.map +1 -1
- package/identify-visitor.js +58 -9
- package/identify-visitor.js.map +1 -1
- package/index.d.ts +10 -7
- package/index.js +10 -9
- package/package.json +14 -17
- package/primitives/avatar/avatar.d.ts.map +1 -1
- package/primitives/avatar/fallback.d.ts.map +1 -1
- package/primitives/avatar/fallback.js +1 -3
- package/primitives/avatar/fallback.js.map +1 -1
- package/primitives/avatar/image.d.ts.map +1 -1
- package/primitives/avatar/index.d.ts +1 -0
- package/primitives/bubble.d.ts +2 -0
- package/primitives/bubble.d.ts.map +1 -1
- package/primitives/bubble.js +8 -2
- package/primitives/bubble.js.map +1 -1
- package/primitives/button.d.ts.map +1 -1
- package/primitives/conversation-timeline.d.ts.map +1 -1
- package/primitives/conversation-timeline.js +58 -5
- package/primitives/conversation-timeline.js.map +1 -1
- package/primitives/index.d.ts +1 -0
- package/primitives/index.parts.d.ts +1 -0
- package/primitives/multimodal-input.d.ts.map +1 -1
- package/primitives/timeline-item-group.d.ts +7 -7
- package/primitives/timeline-item-group.d.ts.map +1 -1
- package/primitives/timeline-item-group.js.map +1 -1
- package/primitives/timeline-item.d.ts +1 -1
- package/primitives/timeline-item.d.ts.map +1 -1
- package/primitives/timeline-item.js +7 -1
- package/primitives/timeline-item.js.map +1 -1
- package/primitives/window.d.ts +1 -1
- package/primitives/window.d.ts.map +1 -1
- package/primitives/window.js +4 -4
- package/primitives/window.js.map +1 -1
- package/provider.d.ts +23 -43
- package/provider.d.ts.map +1 -1
- package/provider.js +152 -49
- package/provider.js.map +1 -1
- package/realtime/event-filter.d.ts +4 -0
- package/realtime/event-filter.d.ts.map +1 -1
- package/realtime/event-filter.js +4 -0
- package/realtime/event-filter.js.map +1 -1
- package/realtime/index.js +1 -1
- package/realtime/provider.d.ts +7 -2
- package/realtime/provider.d.ts.map +1 -1
- package/realtime/provider.js +23 -1
- package/realtime/provider.js.map +1 -1
- package/realtime/seen-store.d.ts +13 -0
- package/realtime/seen-store.d.ts.map +1 -1
- package/realtime/seen-store.js +14 -2
- package/realtime/seen-store.js.map +1 -1
- package/realtime/support-provider.d.ts +1 -2
- package/realtime/support-provider.d.ts.map +1 -1
- package/realtime/support-provider.js +19 -20
- package/realtime/support-provider.js.map +1 -1
- package/realtime/typing-store.d.ts +18 -0
- package/realtime/typing-store.d.ts.map +1 -1
- package/realtime/typing-store.js +19 -2
- package/realtime/typing-store.js.map +1 -1
- package/realtime/use-realtime.d.ts +8 -4
- package/realtime/use-realtime.d.ts.map +1 -1
- package/realtime/use-realtime.js +4 -0
- package/realtime/use-realtime.js.map +1 -1
- package/realtime-events.d.ts +17 -3
- package/realtime-events.d.ts.map +1 -1
- package/schemas.d.ts +7 -1
- package/schemas.d.ts.map +1 -1
- package/support/components/avatar-stack.d.ts +8 -4
- package/support/components/avatar-stack.d.ts.map +1 -1
- package/support/components/avatar-stack.js +4 -0
- package/support/components/avatar-stack.js.map +1 -1
- package/support/components/avatar.d.ts +11 -6
- package/support/components/avatar.d.ts.map +1 -1
- package/support/components/avatar.js +4 -0
- package/support/components/avatar.js.map +1 -1
- package/support/components/bubble.d.ts.map +1 -1
- package/support/components/bubble.js +29 -6
- package/support/components/bubble.js.map +1 -1
- package/support/components/button.d.ts +8 -5
- package/support/components/button.d.ts.map +1 -1
- package/support/components/button.js +5 -1
- package/support/components/button.js.map +1 -1
- package/support/components/container.d.ts +0 -1
- package/support/components/container.d.ts.map +1 -1
- package/support/components/container.js +2 -8
- package/support/components/container.js.map +1 -1
- package/support/components/conversation-button-link.d.ts +8 -21
- package/support/components/conversation-button-link.d.ts.map +1 -1
- package/support/components/conversation-button-link.js +62 -178
- package/support/components/conversation-button-link.js.map +1 -1
- package/support/components/conversation-event.d.ts.map +1 -1
- package/support/components/conversation-event.js +4 -0
- package/support/components/conversation-event.js.map +1 -1
- package/support/components/conversation-timeline.d.ts +10 -1
- package/support/components/conversation-timeline.d.ts.map +1 -1
- package/support/components/conversation-timeline.js +63 -57
- package/support/components/conversation-timeline.js.map +1 -1
- package/support/components/cossistant-branding.d.ts +5 -2
- package/support/components/cossistant-branding.d.ts.map +1 -1
- package/support/components/cossistant-branding.js +3 -0
- package/support/components/cossistant-branding.js.map +1 -1
- package/support/components/header.d.ts.map +1 -1
- package/support/components/header.js +2 -2
- package/support/components/header.js.map +1 -1
- package/support/components/icons.d.ts.map +1 -1
- package/support/components/multimodal-input.d.ts.map +1 -1
- package/support/components/multimodal-input.js +5 -24
- package/support/components/multimodal-input.js.map +1 -1
- package/support/components/navigation-tab.d.ts +7 -2
- package/support/components/navigation-tab.d.ts.map +1 -1
- package/support/components/navigation-tab.js +4 -0
- package/support/components/navigation-tab.js.map +1 -1
- package/support/components/support-content.d.ts +1 -1
- package/support/components/support-content.d.ts.map +1 -1
- package/support/components/support-content.js +7 -10
- package/support/components/support-content.js.map +1 -1
- package/support/components/text-effect.d.ts +5 -2
- package/support/components/text-effect.d.ts.map +1 -1
- package/support/components/text-effect.js +4 -0
- package/support/components/text-effect.js.map +1 -1
- package/support/components/timeline-identification-tool.d.ts +7 -0
- package/support/components/timeline-identification-tool.d.ts.map +1 -0
- package/support/components/timeline-identification-tool.js +139 -0
- package/support/components/timeline-identification-tool.js.map +1 -0
- package/support/components/timeline-message-group.d.ts +2 -1
- package/support/components/timeline-message-group.d.ts.map +1 -1
- package/support/components/timeline-message-group.js +4 -19
- package/support/components/timeline-message-group.js.map +1 -1
- package/support/components/timeline-message-item.d.ts +6 -2
- package/support/components/timeline-message-item.d.ts.map +1 -1
- package/support/components/timeline-message-item.js +8 -4
- package/support/components/timeline-message-item.js.map +1 -1
- package/support/components/typing-indicator.d.ts +5 -2
- package/support/components/typing-indicator.d.ts.map +1 -1
- package/support/components/typing-indicator.js +4 -4
- package/support/components/typing-indicator.js.map +1 -1
- package/support/components/watermark.d.ts.map +1 -1
- package/support/context/websocket.d.ts +8 -0
- package/support/context/websocket.d.ts.map +1 -1
- package/support/context/websocket.js +12 -6
- package/support/context/websocket.js.map +1 -1
- package/support/index.d.ts +8 -8
- package/support/index.d.ts.map +1 -1
- package/support/index.js +18 -18
- package/support/index.js.map +1 -1
- package/support/pages/conversation-history.js +46 -54
- package/support/pages/conversation-history.js.map +1 -1
- package/support/pages/conversation.d.ts +3 -6
- package/support/pages/conversation.d.ts.map +1 -1
- package/support/pages/conversation.js +19 -9
- package/support/pages/conversation.js.map +1 -1
- package/support/pages/home.d.ts +2 -2
- package/support/pages/home.d.ts.map +1 -1
- package/support/pages/home.js +64 -77
- package/support/pages/home.js.map +1 -1
- package/support/store/support-store.d.ts +18 -2
- package/support/store/support-store.d.ts.map +1 -1
- package/support/store/support-store.js +20 -5
- package/support/store/support-store.js.map +1 -1
- package/support/{support-CMoDLQoC.css → support-Ck4jy29i.css} +1 -2
- package/support/support-Ck4jy29i.css.map +1 -0
- package/support/text/index.d.ts +15 -2
- package/support/text/index.d.ts.map +1 -1
- package/support/text/index.js +15 -2
- package/support/text/index.js.map +1 -1
- package/support/text/locales/en.js +22 -4
- package/support/text/locales/en.js.map +1 -1
- package/support/text/locales/es.js +18 -0
- package/support/text/locales/es.js.map +1 -1
- package/support/text/locales/fr.js +18 -0
- package/support/text/locales/fr.js.map +1 -1
- package/support/text/locales/keys.d.ts +69 -9
- package/support/text/locales/keys.d.ts.map +1 -1
- package/support/text/locales/keys.js +18 -0
- package/support/text/locales/keys.js.map +1 -1
- package/support/text/runtime.d.ts +21 -0
- package/support/text/runtime.d.ts.map +1 -1
- package/support/text/runtime.js +21 -0
- package/support/text/runtime.js.map +1 -1
- package/support/utils/index.d.ts +4 -0
- package/support/utils/index.d.ts.map +1 -1
- package/support/utils/index.js +4 -1
- package/support/utils/index.js.map +1 -1
- package/support/utils/time.d.ts +3 -0
- package/support/utils/time.d.ts.map +1 -1
- package/support/utils/time.js +3 -0
- package/support/utils/time.js.map +1 -1
- package/support-config.d.ts +2 -1
- package/support-config.d.ts.map +1 -1
- package/support-config.js.map +1 -1
- package/support.css +2 -2
- package/timeline-item.d.ts +10 -0
- package/timeline-item.d.ts.map +1 -1
- package/utils/conversation.d.ts +7 -0
- package/utils/conversation.d.ts.map +1 -0
- package/utils/conversation.js +18 -0
- package/utils/conversation.js.map +1 -0
- package/utils/id.d.ts +3 -0
- package/utils/id.d.ts.map +1 -1
- package/utils/id.js +3 -0
- package/utils/id.js.map +1 -1
- package/utils/index.d.ts +2 -1
- package/utils/index.js +2 -1
- package/utils/metadata-hash.d.ts +12 -0
- package/utils/metadata-hash.d.ts.map +1 -0
- package/utils/metadata-hash.js +26 -0
- package/utils/metadata-hash.js.map +1 -0
- package/utils/text.d.ts +3 -0
- package/utils/text.d.ts.map +1 -1
- package/utils/text.js +3 -0
- package/utils/text.js.map +1 -1
- package/utils/use-render-element.d.ts +3 -0
- package/utils/use-render-element.d.ts.map +1 -1
- package/utils/use-render-element.js +3 -0
- package/utils/use-render-element.js.map +1 -1
- package/support/context/config.d.ts +0 -32
- package/support/context/config.d.ts.map +0 -1
- package/support/context/config.js +0 -27
- package/support/context/config.js.map +0 -1
- package/support/support-CMoDLQoC.css.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeline-message-group.d.ts","names":[],"sources":["../../../src/support/components/timeline-message-group.tsx"],"sourcesContent":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"timeline-message-group.d.ts","names":[],"sources":["../../../src/support/components/timeline-message-group.tsx"],"sourcesContent":[],"mappings":";;;;;KAoCY,yBAAA;SACJ;EADI,iBAAA,EAEQ,gBAFiB,EAAA;EAC7B,oBAAA,EAEe,mBAFf,EAAA;EACY,gBAAA,CAAA,EAAA,MAAA;EACG,SAAA,CAAA,EAAA,SAAA,MAAA,EAAA;EAAmB,WAAA,CAAA,EAAA,SAAA,MAAA,EAAA;AAS1C,CAAA;cAAa,sBAAsB,KAAA,CAAM,GAAG"}
|
|
@@ -3,7 +3,6 @@ import { Avatar } from "./avatar.js";
|
|
|
3
3
|
import { CossistantLogo } from "./cossistant-branding.js";
|
|
4
4
|
import { TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupSeenIndicator } from "../../primitives/timeline-item-group.js";
|
|
5
5
|
import { TimelineMessageItem } from "./timeline-message-item.js";
|
|
6
|
-
import { useMemo } from "react";
|
|
7
6
|
import { SenderType } from "@cossistant/types";
|
|
8
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
8
|
import { motion } from "motion/react";
|
|
@@ -37,27 +36,12 @@ const SEEN_ANIMATION = {
|
|
|
37
36
|
ease: "easeOut"
|
|
38
37
|
}
|
|
39
38
|
};
|
|
40
|
-
const
|
|
39
|
+
const EMPTY_SEEN_BY_IDS = Object.freeze([]);
|
|
40
|
+
const EMPTY_SEEN_BY_NAMES = Object.freeze([]);
|
|
41
|
+
const TimelineMessageGroup = ({ items, availableAIAgents, availableHumanAgents, currentVisitorId, seenByIds = EMPTY_SEEN_BY_IDS, seenByNames = EMPTY_SEEN_BY_NAMES }) => {
|
|
41
42
|
const firstItem = items[0];
|
|
42
43
|
const humanAgent = availableHumanAgents.find((agent) => agent.id === firstItem?.userId);
|
|
43
44
|
const aiAgent = availableAIAgents.find((agent) => agent.id === firstItem?.aiAgentId);
|
|
44
|
-
const seenByNames = useMemo(() => {
|
|
45
|
-
const deduped = /* @__PURE__ */ new Set();
|
|
46
|
-
for (const id of seenByIds) {
|
|
47
|
-
const human = availableHumanAgents.find((agent) => agent.id === id);
|
|
48
|
-
if (human?.name) {
|
|
49
|
-
deduped.add(human.name);
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
const ai = availableAIAgents.find((agent) => agent.id === id);
|
|
53
|
-
if (ai?.name) deduped.add(ai.name);
|
|
54
|
-
}
|
|
55
|
-
return Array.from(deduped);
|
|
56
|
-
}, [
|
|
57
|
-
seenByIds,
|
|
58
|
-
availableHumanAgents,
|
|
59
|
-
availableAIAgents
|
|
60
|
-
]);
|
|
61
45
|
if (items.length === 0) return null;
|
|
62
46
|
const hasSeenIndicator = seenByIds.length > 0 && seenByNames.length > 0;
|
|
63
47
|
return /* @__PURE__ */ jsx(TimelineItemGroup, {
|
|
@@ -111,6 +95,7 @@ const TimelineMessageGroup = ({ items, availableAIAgents, availableHumanAgents,
|
|
|
111
95
|
})
|
|
112
96
|
});
|
|
113
97
|
};
|
|
98
|
+
TimelineMessageGroup.displayName = "TimelineMessageGroup";
|
|
114
99
|
|
|
115
100
|
//#endregion
|
|
116
101
|
export { TimelineMessageGroup };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeline-message-group.js","names":["TimelineMessageGroup: React.FC<TimelineMessageGroupProps>","PrimitiveTimelineItemGroup"],"sources":["../../../src/support/components/timeline-message-group.tsx"],"sourcesContent":["import type { AvailableAIAgent, AvailableHumanAgent } from \"@cossistant/types\";\nimport { SenderType } from \"@cossistant/types\";\nimport type { TimelineItem } from \"@cossistant/types/api/timeline-item\";\nimport { motion } from \"motion/react\";\nimport type React from \"react\";\nimport {
|
|
1
|
+
{"version":3,"file":"timeline-message-group.js","names":["EMPTY_SEEN_BY_IDS: readonly string[]","EMPTY_SEEN_BY_NAMES: readonly string[]","TimelineMessageGroup: React.FC<TimelineMessageGroupProps>","PrimitiveTimelineItemGroup"],"sources":["../../../src/support/components/timeline-message-group.tsx"],"sourcesContent":["import type { AvailableAIAgent, AvailableHumanAgent } from \"@cossistant/types\";\nimport { SenderType } from \"@cossistant/types\";\nimport type { TimelineItem } from \"@cossistant/types/api/timeline-item\";\nimport { motion } from \"motion/react\";\nimport type React from \"react\";\nimport {\n\tTimelineItemGroup as PrimitiveTimelineItemGroup,\n\tTimelineItemGroupAvatar,\n\tTimelineItemGroupContent,\n\tTimelineItemGroupHeader,\n\tTimelineItemGroupSeenIndicator,\n} from \"../../primitives/timeline-item-group\";\nimport { cn } from \"../utils\";\nimport { Avatar } from \"./avatar\";\nimport { CossistantLogo } from \"./cossistant-branding\";\nimport { TimelineMessageItem } from \"./timeline-message-item\";\n\nconst MESSAGE_ANIMATION = {\n\tinitial: { opacity: 0, y: 6 },\n\tanimate: { opacity: 1, y: 0 },\n\texit: { opacity: 0 },\n\ttransition: {\n\t\tduration: 0.1,\n\t\tease: [0.25, 0.46, 0.45, 0.94] as const, // easeOutCubic\n\t},\n} as const;\n\nconst SEEN_ANIMATION = {\n\tinitial: { opacity: 0 },\n\tanimate: { opacity: 1 },\n\ttransition: {\n\t\tduration: 0.1,\n\t\tease: \"easeOut\" as const,\n\t},\n} as const;\n\nexport type TimelineMessageGroupProps = {\n\titems: TimelineItem[];\n\tavailableAIAgents: AvailableAIAgent[];\n\tavailableHumanAgents: AvailableHumanAgent[];\n\tcurrentVisitorId?: string;\n\tseenByIds?: readonly string[];\n\tseenByNames?: readonly string[];\n};\n\nconst EMPTY_SEEN_BY_IDS: readonly string[] = Object.freeze([]);\nconst EMPTY_SEEN_BY_NAMES: readonly string[] = Object.freeze([]);\n\nexport const TimelineMessageGroup: React.FC<TimelineMessageGroupProps> = ({\n\titems,\n\tavailableAIAgents,\n\tavailableHumanAgents,\n\tcurrentVisitorId,\n\tseenByIds = EMPTY_SEEN_BY_IDS,\n\tseenByNames = EMPTY_SEEN_BY_NAMES,\n}) => {\n\t// Get agent info for the sender\n\tconst firstItem = items[0];\n\tconst humanAgent = availableHumanAgents.find(\n\t\t(agent) => agent.id === firstItem?.userId\n\t);\n\tconst aiAgent = availableAIAgents.find(\n\t\t(agent) => agent.id === firstItem?.aiAgentId\n\t);\n\n\tif (items.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst hasSeenIndicator = seenByIds.length > 0 && seenByNames.length > 0;\n\n\treturn (\n\t\t<PrimitiveTimelineItemGroup\n\t\t\titems={items}\n\t\t\tseenByIds={seenByIds}\n\t\t\tviewerId={currentVisitorId}\n\t\t\tviewerType={SenderType.VISITOR}\n\t\t>\n\t\t\t{({\n\t\t\t\tisSentByViewer,\n\t\t\t\tisReceivedByViewer,\n\t\t\t\tisVisitor,\n\t\t\t\tisAI,\n\t\t\t\tisTeamMember,\n\t\t\t}) => (\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"flex w-full gap-2\",\n\t\t\t\t\t\t// Support widget POV: visitor messages are sent (right side)\n\t\t\t\t\t\t// Agent messages are received (left side)\n\t\t\t\t\t\tisSentByViewer && \"flex-row-reverse\",\n\t\t\t\t\t\tisReceivedByViewer && \"flex-row\"\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{/* Avatar - only show for received messages (agents) */}\n\t\t\t\t\t{isReceivedByViewer && (\n\t\t\t\t\t\t<TimelineItemGroupAvatar className=\"flex flex-shrink-0 flex-col justify-end\">\n\t\t\t\t\t\t\t{isAI ? (\n\t\t\t\t\t\t\t\t<div className=\"flex size-6 items-center justify-center rounded-full bg-primary/10\">\n\t\t\t\t\t\t\t\t\t<CossistantLogo className=\"h-4 w-4 text-primary\" />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<Avatar\n\t\t\t\t\t\t\t\t\tclassName=\"size-6\"\n\t\t\t\t\t\t\t\t\timage={humanAgent?.image}\n\t\t\t\t\t\t\t\t\tname={humanAgent?.name || \"Support\"}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</TimelineItemGroupAvatar>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<TimelineItemGroupContent\n\t\t\t\t\t\tclassName={cn(\"flex flex-col gap-1\", isSentByViewer && \"items-end\")}\n\t\t\t\t\t>\n\t\t\t\t\t\t{/* Header - show sender name for received messages (agents) */}\n\t\t\t\t\t\t{isReceivedByViewer && (\n\t\t\t\t\t\t\t<TimelineItemGroupHeader className=\"px-1 text-muted-foreground text-xs\">\n\t\t\t\t\t\t\t\t{isAI\n\t\t\t\t\t\t\t\t\t? aiAgent?.name || \"AI Assistant\"\n\t\t\t\t\t\t\t\t\t: humanAgent?.name || \"Support\"}\n\t\t\t\t\t\t\t</TimelineItemGroupHeader>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{items.map((item, index) => (\n\t\t\t\t\t\t\t<motion.div key={item.id} {...MESSAGE_ANIMATION}>\n\t\t\t\t\t\t\t\t<TimelineMessageItem\n\t\t\t\t\t\t\t\t\tisLast={index === items.length - 1}\n\t\t\t\t\t\t\t\t\tisSentByViewer={isSentByViewer}\n\t\t\t\t\t\t\t\t\titem={item}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t))}\n\n\t\t\t\t\t\t{isSentByViewer && (\n\t\t\t\t\t\t\t<div className={cn(\"\", hasSeenIndicator && \"mt-2\")}>\n\t\t\t\t\t\t\t\t<div className=\"min-h-[1.25rem]\">\n\t\t\t\t\t\t\t\t\t{hasSeenIndicator && (\n\t\t\t\t\t\t\t\t\t\t<motion.div key=\"seen-indicator\" {...SEEN_ANIMATION}>\n\t\t\t\t\t\t\t\t\t\t\t<TimelineItemGroupSeenIndicator\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"px-1 text-muted-foreground text-xs\"\n\t\t\t\t\t\t\t\t\t\t\t\tseenByIds={seenByIds}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{() => `Seen by ${seenByNames.join(\", \")}`}\n\t\t\t\t\t\t\t\t\t\t\t</TimelineItemGroupSeenIndicator>\n\t\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</TimelineItemGroupContent>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</PrimitiveTimelineItemGroup>\n\t);\n};\n\nTimelineMessageGroup.displayName = \"TimelineMessageGroup\";\n"],"mappings":";;;;;;;;;;AAiBA,MAAM,oBAAoB;CACzB,SAAS;EAAE,SAAS;EAAG,GAAG;EAAG;CAC7B,SAAS;EAAE,SAAS;EAAG,GAAG;EAAG;CAC7B,MAAM,EAAE,SAAS,GAAG;CACpB,YAAY;EACX,UAAU;EACV,MAAM;GAAC;GAAM;GAAM;GAAM;GAAK;EAC9B;CACD;AAED,MAAM,iBAAiB;CACtB,SAAS,EAAE,SAAS,GAAG;CACvB,SAAS,EAAE,SAAS,GAAG;CACvB,YAAY;EACX,UAAU;EACV,MAAM;EACN;CACD;AAWD,MAAMA,oBAAuC,OAAO,OAAO,EAAE,CAAC;AAC9D,MAAMC,sBAAyC,OAAO,OAAO,EAAE,CAAC;AAEhE,MAAaC,wBAA6D,EACzE,OACA,mBACA,sBACA,kBACA,YAAY,mBACZ,cAAc,0BACT;CAEL,MAAM,YAAY,MAAM;CACxB,MAAM,aAAa,qBAAqB,MACtC,UAAU,MAAM,OAAO,WAAW,OACnC;CACD,MAAM,UAAU,kBAAkB,MAChC,UAAU,MAAM,OAAO,WAAW,UACnC;AAED,KAAI,MAAM,WAAW,EACpB,QAAO;CAGR,MAAM,mBAAmB,UAAU,SAAS,KAAK,YAAY,SAAS;AAEtE,QACC,oBAACC;EACO;EACI;EACX,UAAU;EACV,YAAY,WAAW;aAErB,EACD,gBACA,oBACA,WACA,MACA,mBAEA,qBAAC;GACA,WAAW,GACV,qBAGA,kBAAkB,oBAClB,sBAAsB,WACtB;cAGA,sBACA,oBAAC;IAAwB,WAAU;cACjC,OACA,oBAAC;KAAI,WAAU;eACd,oBAAC,kBAAe,WAAU,yBAAyB;MAC9C,GAEN,oBAAC;KACA,WAAU;KACV,OAAO,YAAY;KACnB,MAAM,YAAY,QAAQ;MACzB;KAEsB,EAG3B,qBAAC;IACA,WAAW,GAAG,uBAAuB,kBAAkB,YAAY;;KAGlE,sBACA,oBAAC;MAAwB,WAAU;gBACjC,OACE,SAAS,QAAQ,iBACjB,YAAY,QAAQ;OACE;KAG1B,MAAM,KAAK,MAAM,UACjB,oBAAC,OAAO;MAAkB,GAAI;gBAC7B,oBAAC;OACA,QAAQ,UAAU,MAAM,SAAS;OACjB;OACV;QACL;QALc,KAAK,GAMT,CACZ;KAED,kBACA,oBAAC;MAAI,WAAW,GAAG,IAAI,oBAAoB,OAAO;gBACjD,oBAAC;OAAI,WAAU;iBACb,oBACA,oBAAC,OAAO;QAAyB,GAAI;kBACpC,oBAAC;SACA,WAAU;SACC;yBAEJ,WAAW,YAAY,KAAK,KAAK;UACR;UANlB,iBAOH;QAET;OACD;;KAEmB;IACtB;GAEqB;;AAI/B,qBAAqB,cAAc"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TimelineItem } from "../../timeline-item.js";
|
|
2
|
-
import
|
|
2
|
+
import React from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/support/components/timeline-message-item.d.ts
|
|
5
5
|
type TimelineMessageItemProps = {
|
|
@@ -7,11 +7,15 @@ type TimelineMessageItemProps = {
|
|
|
7
7
|
isLast?: boolean;
|
|
8
8
|
isSentByViewer?: boolean;
|
|
9
9
|
};
|
|
10
|
+
/**
|
|
11
|
+
* Message bubble renderer that adapts layout depending on whether the visitor
|
|
12
|
+
* or an agent sent the message.
|
|
13
|
+
*/
|
|
10
14
|
declare function TimelineMessageItem({
|
|
11
15
|
item,
|
|
12
16
|
isLast,
|
|
13
17
|
isSentByViewer
|
|
14
|
-
}: TimelineMessageItemProps):
|
|
18
|
+
}: TimelineMessageItemProps): React.ReactElement;
|
|
15
19
|
//#endregion
|
|
16
20
|
export { TimelineMessageItem, TimelineMessageItemProps };
|
|
17
21
|
//# sourceMappingURL=timeline-message-item.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeline-message-item.d.ts","names":[],"sources":["../../../src/support/components/timeline-message-item.tsx"],"sourcesContent":[],"mappings":";;;;KAUY,wBAAA;QACL
|
|
1
|
+
{"version":3,"file":"timeline-message-item.d.ts","names":[],"sources":["../../../src/support/components/timeline-message-item.tsx"],"sourcesContent":[],"mappings":";;;;KAUY,wBAAA;QACL;EADK,MAAA,CAAA,EAAA,OAAA;EAUI,cAAA,CAAA,EAAA,OAAmB;CAClC;;;;;AAG+C,iBAJhC,mBAAA,CAIgC;EAAA,IAAA;EAAA,MAAA;EAAA;AAAA,CAAA,EAA7C,wBAA6C,CAAA,EAAlB,KAAA,CAAM,YAAY"}
|
|
@@ -4,19 +4,23 @@ import { useSupportText } from "../text/index.js";
|
|
|
4
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
|
|
6
6
|
//#region src/support/components/timeline-message-item.tsx
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Message bubble renderer that adapts layout depending on whether the visitor
|
|
9
|
+
* or an agent sent the message.
|
|
10
|
+
*/
|
|
11
|
+
function TimelineMessageItem({ item, isLast = false, isSentByViewer = false }) {
|
|
8
12
|
const text = useSupportText();
|
|
9
13
|
return /* @__PURE__ */ jsx(TimelineItem, {
|
|
10
14
|
item,
|
|
11
|
-
children: ({
|
|
12
|
-
const isSentByViewerFinal = isSentByViewer
|
|
15
|
+
children: ({ isAI, timestamp }) => {
|
|
16
|
+
const isSentByViewerFinal = isSentByViewer;
|
|
13
17
|
return /* @__PURE__ */ jsx("div", {
|
|
14
18
|
className: cn("flex w-full gap-2", isSentByViewerFinal && "flex-row-reverse", !isSentByViewerFinal && "flex-row"),
|
|
15
19
|
children: /* @__PURE__ */ jsxs("div", {
|
|
16
20
|
className: cn("flex w-full flex-1 flex-col gap-1", isSentByViewerFinal && "items-end"),
|
|
17
21
|
children: [/* @__PURE__ */ jsx(TimelineItemContent, {
|
|
18
22
|
className: cn("block w-max max-w-[300px] rounded-lg px-3.5 py-2.5 text-sm", {
|
|
19
|
-
"bg-
|
|
23
|
+
"bg-background-300 text-foreground dark:bg-background-600": !isSentByViewerFinal,
|
|
20
24
|
"bg-primary text-primary-foreground": isSentByViewerFinal,
|
|
21
25
|
"rounded-br-sm": isLast && isSentByViewerFinal,
|
|
22
26
|
"rounded-bl-sm": isLast && !isSentByViewerFinal
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeline-message-item.js","names":["PrimitiveTimelineItem"],"sources":["../../../src/support/components/timeline-message-item.tsx"],"sourcesContent":["import type { TimelineItem } from \"@cossistant/types/api/timeline-item\";\nimport type React from \"react\";\nimport {\n\tTimelineItem as PrimitiveTimelineItem,\n\tTimelineItemContent,\n\tTimelineItemTimestamp,\n} from \"../../primitives/timeline-item\";\nimport { useSupportText } from \"../text\";\nimport { cn } from \"../utils\";\n\nexport type TimelineMessageItemProps = {\n\titem: TimelineItem;\n\tisLast?: boolean;\n\tisSentByViewer?: boolean;\n};\n\nexport function TimelineMessageItem({\n\titem,\n\tisLast = false,\n\tisSentByViewer,\n}: TimelineMessageItemProps) {\n\tconst text = useSupportText();\n\treturn (\n\t\t<PrimitiveTimelineItem item={item}>\n\t\t\t{({
|
|
1
|
+
{"version":3,"file":"timeline-message-item.js","names":["PrimitiveTimelineItem"],"sources":["../../../src/support/components/timeline-message-item.tsx"],"sourcesContent":["import type { TimelineItem } from \"@cossistant/types/api/timeline-item\";\nimport type React from \"react\";\nimport {\n\tTimelineItem as PrimitiveTimelineItem,\n\tTimelineItemContent,\n\tTimelineItemTimestamp,\n} from \"../../primitives/timeline-item\";\nimport { useSupportText } from \"../text\";\nimport { cn } from \"../utils\";\n\nexport type TimelineMessageItemProps = {\n\titem: TimelineItem;\n\tisLast?: boolean;\n\tisSentByViewer?: boolean;\n};\n\n/**\n * Message bubble renderer that adapts layout depending on whether the visitor\n * or an agent sent the message.\n */\nexport function TimelineMessageItem({\n\titem,\n\tisLast = false,\n\tisSentByViewer = false,\n}: TimelineMessageItemProps): React.ReactElement {\n\tconst text = useSupportText();\n\treturn (\n\t\t<PrimitiveTimelineItem item={item}>\n\t\t\t{({ isAI, timestamp }) => {\n\t\t\t\t// isSentByViewer defaults to false, meaning messages are treated as received\n\t\t\t\t// (left side with background) unless explicitly marked as sent by viewer\n\t\t\t\tconst isSentByViewerFinal = isSentByViewer;\n\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"flex w-full gap-2\",\n\t\t\t\t\t\t\tisSentByViewerFinal && \"flex-row-reverse\",\n\t\t\t\t\t\t\t!isSentByViewerFinal && \"flex-row\"\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"flex w-full flex-1 flex-col gap-1\",\n\t\t\t\t\t\t\t\tisSentByViewerFinal && \"items-end\"\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<TimelineItemContent\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"block w-max max-w-[300px] rounded-lg px-3.5 py-2.5 text-sm\",\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"bg-background-300 text-foreground dark:bg-background-600\":\n\t\t\t\t\t\t\t\t\t\t\t!isSentByViewerFinal,\n\t\t\t\t\t\t\t\t\t\t\"bg-primary text-primary-foreground\": isSentByViewerFinal,\n\t\t\t\t\t\t\t\t\t\t\"rounded-br-sm\": isLast && isSentByViewerFinal,\n\t\t\t\t\t\t\t\t\t\t\"rounded-bl-sm\": isLast && !isSentByViewerFinal,\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\trenderMarkdown\n\t\t\t\t\t\t\t\ttext={item.text}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{isLast && (\n\t\t\t\t\t\t\t\t<TimelineItemTimestamp\n\t\t\t\t\t\t\t\t\tclassName=\"px-1 text-muted-foreground text-xs\"\n\t\t\t\t\t\t\t\t\ttimestamp={timestamp}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{() => (\n\t\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t\t{timestamp.toLocaleTimeString([], {\n\t\t\t\t\t\t\t\t\t\t\t\thour: \"2-digit\",\n\t\t\t\t\t\t\t\t\t\t\t\tminute: \"2-digit\",\n\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t\t{isAI &&\n\t\t\t\t\t\t\t\t\t\t\t\t` ${text(\"component.message.timestamp.aiIndicator\")}`}\n\t\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</TimelineItemTimestamp>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t}}\n\t\t</PrimitiveTimelineItem>\n\t);\n}\n"],"mappings":";;;;;;;;;;AAoBA,SAAgB,oBAAoB,EACnC,MACA,SAAS,OACT,iBAAiB,SAC+B;CAChD,MAAM,OAAO,gBAAgB;AAC7B,QACC,oBAACA;EAA4B;aAC1B,EAAE,MAAM,gBAAgB;GAGzB,MAAM,sBAAsB;AAE5B,UACC,oBAAC;IACA,WAAW,GACV,qBACA,uBAAuB,oBACvB,CAAC,uBAAuB,WACxB;cAED,qBAAC;KACA,WAAW,GACV,qCACA,uBAAuB,YACvB;gBAED,oBAAC;MACA,WAAW,GACV,8DACA;OACC,4DACC,CAAC;OACF,sCAAsC;OACtC,iBAAiB,UAAU;OAC3B,iBAAiB,UAAU,CAAC;OAC5B,CACD;MACD;MACA,MAAM,KAAK;OACV,EACD,UACA,oBAAC;MACA,WAAU;MACC;sBAGV,4CACE,UAAU,mBAAmB,EAAE,EAAE;OACjC,MAAM;OACN,QAAQ;OACR,CAAC,EACD,QACA,IAAI,KAAK,0CAA0C,MAClD;OAEmB;MAEpB;KACD;;GAGe"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as React$1 from "react";
|
|
2
2
|
import { AvailableAIAgent, AvailableHumanAgent } from "@cossistant/types";
|
|
3
|
-
import * as react_jsx_runtime9 from "react/jsx-runtime";
|
|
4
3
|
|
|
5
4
|
//#region src/support/components/typing-indicator.d.ts
|
|
6
5
|
type TypingParticipantType = "visitor" | "team_member" | "ai";
|
|
@@ -14,7 +13,11 @@ type TypingIndicatorProps = React$1.HTMLAttributes<HTMLDivElement> & {
|
|
|
14
13
|
availableHumanAgents?: AvailableHumanAgent[];
|
|
15
14
|
withAvatars?: boolean;
|
|
16
15
|
};
|
|
17
|
-
declare const BouncingDots: (
|
|
16
|
+
declare const BouncingDots: ({
|
|
17
|
+
className
|
|
18
|
+
}: {
|
|
19
|
+
className?: string;
|
|
20
|
+
}) => React$1.ReactElement;
|
|
18
21
|
declare const TypingIndicator: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & {
|
|
19
22
|
participants: TypingParticipant[];
|
|
20
23
|
availableAIAgents?: AvailableAIAgent[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typing-indicator.d.ts","names":[],"sources":["../../../src/support/components/typing-indicator.tsx"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"typing-indicator.d.ts","names":[],"sources":["../../../src/support/components/typing-indicator.tsx"],"sourcesContent":[],"mappings":";;;;KAKY,qBAAA;KAEA,iBAAA;EAFA,EAAA,EAAA,MAAA;EAEA,IAAA,EAEL,qBAFsB;AAK7B,CAAA;AAAwD,KAA5C,oBAAA,GAAuB,OAAA,CAAM,cAAe,CAAA,cAAA,CAAA,GAAA;EAArB,YAAM,EAC1B,iBAD0B,EAAA;EAC1B,iBAAA,CAAA,EACM,gBADN,EAAA;EACM,oBAAA,CAAA,EACG,mBADH,EAAA;EACG,WAAA,CAAA,EAAA,OAAA;CAAmB;AAI9B,cAAA,YAAgB,EAAA,CAAA;EAAA;CAIzB,EAAM;EAuBG,SAAA,CAAA,EAAA,MAuDZ;CAvD2B,EAAA,GAvBxB,OAAA,CAAM,YAuBkB;AAAA,cAAf,eAAe,EAAA,OAAA,CAAA,yBAAA,CAAA,OAAA,CAAA,cAAA,CAAA,cAAA,CAAA,GAAA;EAjCb,YAAA,EAAA,iBAAA,EAAA;EACM,iBAAA,CAAA,EAAA,gBAAA,EAAA;EACG,oBAAA,CAAA,EAAA,mBAAA,EAAA"}
|
|
@@ -4,12 +4,12 @@ import * as React$1 from "react";
|
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
|
|
6
6
|
//#region src/support/components/typing-indicator.tsx
|
|
7
|
-
const BouncingDots = () => /* @__PURE__ */ jsxs("div", {
|
|
7
|
+
const BouncingDots = ({ className }) => /* @__PURE__ */ jsxs("div", {
|
|
8
8
|
className: "flex gap-1",
|
|
9
9
|
children: [
|
|
10
|
-
/* @__PURE__ */ jsx("span", { className: "dot-bounce-1 size-1 rounded-full bg-co-primary" }),
|
|
11
|
-
/* @__PURE__ */ jsx("span", { className: "dot-bounce-2 size-1 rounded-full bg-co-primary" }),
|
|
12
|
-
/* @__PURE__ */ jsx("span", { className: "dot-bounce-3 size-1 rounded-full bg-co-primary" })
|
|
10
|
+
/* @__PURE__ */ jsx("span", { className: cn("dot-bounce-1 size-1 rounded-full bg-co-primary", className) }),
|
|
11
|
+
/* @__PURE__ */ jsx("span", { className: cn("dot-bounce-2 size-1 rounded-full bg-co-primary", className) }),
|
|
12
|
+
/* @__PURE__ */ jsx("span", { className: cn("dot-bounce-3 size-1 rounded-full bg-co-primary", className) })
|
|
13
13
|
]
|
|
14
14
|
});
|
|
15
15
|
const TypingIndicator = React$1.forwardRef(({ participants, availableAIAgents = [], availableHumanAgents = [], withAvatars = true, className,...props }, ref) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typing-indicator.js","names":["React"],"sources":["../../../src/support/components/typing-indicator.tsx"],"sourcesContent":["import type { AvailableAIAgent, AvailableHumanAgent } from \"@cossistant/types\";\nimport * as React from \"react\";\nimport { cn } from \"../utils\";\nimport { AvatarStack } from \"./avatar-stack\";\n\nexport type TypingParticipantType = \"visitor\" | \"team_member\" | \"ai\";\n\nexport type TypingParticipant = {\n\tid: string;\n\ttype: TypingParticipantType;\n};\n\nexport type TypingIndicatorProps = React.HTMLAttributes<HTMLDivElement> & {\n\tparticipants: TypingParticipant[];\n\tavailableAIAgents?: AvailableAIAgent[];\n\tavailableHumanAgents?: AvailableHumanAgent[];\n\twithAvatars?: boolean;\n};\n\nexport const BouncingDots = () => (\n\t<div className=\"flex gap-1\">\n\t\t<span
|
|
1
|
+
{"version":3,"file":"typing-indicator.js","names":["React"],"sources":["../../../src/support/components/typing-indicator.tsx"],"sourcesContent":["import type { AvailableAIAgent, AvailableHumanAgent } from \"@cossistant/types\";\nimport * as React from \"react\";\nimport { cn } from \"../utils\";\nimport { AvatarStack } from \"./avatar-stack\";\n\nexport type TypingParticipantType = \"visitor\" | \"team_member\" | \"ai\";\n\nexport type TypingParticipant = {\n\tid: string;\n\ttype: TypingParticipantType;\n};\n\nexport type TypingIndicatorProps = React.HTMLAttributes<HTMLDivElement> & {\n\tparticipants: TypingParticipant[];\n\tavailableAIAgents?: AvailableAIAgent[];\n\tavailableHumanAgents?: AvailableHumanAgent[];\n\twithAvatars?: boolean;\n};\n\nexport const BouncingDots = ({\n\tclassName,\n}: {\n\tclassName?: string;\n}): React.ReactElement => (\n\t<div className=\"flex gap-1\">\n\t\t<span\n\t\t\tclassName={cn(\n\t\t\t\t\"dot-bounce-1 size-1 rounded-full bg-co-primary\",\n\t\t\t\tclassName\n\t\t\t)}\n\t\t/>\n\t\t<span\n\t\t\tclassName={cn(\n\t\t\t\t\"dot-bounce-2 size-1 rounded-full bg-co-primary\",\n\t\t\t\tclassName\n\t\t\t)}\n\t\t/>\n\t\t<span\n\t\t\tclassName={cn(\n\t\t\t\t\"dot-bounce-3 size-1 rounded-full bg-co-primary\",\n\t\t\t\tclassName\n\t\t\t)}\n\t\t/>\n\t</div>\n);\n\nexport const TypingIndicator = React.forwardRef<\n\tHTMLDivElement,\n\tTypingIndicatorProps\n>(\n\t(\n\t\t{\n\t\t\tparticipants,\n\t\t\tavailableAIAgents = [],\n\t\t\tavailableHumanAgents = [],\n\t\t\twithAvatars = true,\n\t\t\tclassName,\n\t\t\t...props\n\t\t},\n\t\tref\n\t) => {\n\t\tif (!participants || participants.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Separate AI and human participants\n\t\tconst humanParticipantIds = participants\n\t\t\t.filter((p) => p.type === \"team_member\")\n\t\t\t.map((p) => p.id);\n\n\t\tconst aiParticipantIds = participants\n\t\t\t.filter((p) => p.type === \"ai\")\n\t\t\t.map((p) => p.id);\n\n\t\t// Get matching agents\n\t\tconst typingHumanAgents = availableHumanAgents.filter((agent) =>\n\t\t\thumanParticipantIds.includes(agent.id)\n\t\t);\n\n\t\tconst typingAIAgents = availableAIAgents.filter((agent) =>\n\t\t\taiParticipantIds.includes(agent.id)\n\t\t);\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={cn(\"flex items-center gap-6\", className)}\n\t\t\t\tref={ref}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{withAvatars && (\n\t\t\t\t\t<AvatarStack\n\t\t\t\t\t\taiAgents={typingAIAgents}\n\t\t\t\t\t\thumanAgents={typingHumanAgents}\n\t\t\t\t\t\tsize={24}\n\t\t\t\t\t\tspacing={16}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t<BouncingDots />\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nTypingIndicator.displayName = \"TypingIndicator\";\n"],"mappings":";;;;;;AAmBA,MAAa,gBAAgB,EAC5B,gBAIA,qBAAC;CAAI,WAAU;;EACd,oBAAC,UACA,WAAW,GACV,kDACA,UACA,GACA;EACF,oBAAC,UACA,WAAW,GACV,kDACA,UACA,GACA;EACF,oBAAC,UACA,WAAW,GACV,kDACA,UACA,GACA;;EACG;AAGP,MAAa,kBAAkBA,QAAM,YAKnC,EACC,cACA,oBAAoB,EAAE,EACtB,uBAAuB,EAAE,EACzB,cAAc,MACd,UACA,GAAG,SAEJ,QACI;AACJ,KAAI,CAAC,gBAAgB,aAAa,WAAW,EAC5C,QAAO;CAIR,MAAM,sBAAsB,aAC1B,QAAQ,MAAM,EAAE,SAAS,cAAc,CACvC,KAAK,MAAM,EAAE,GAAG;CAElB,MAAM,mBAAmB,aACvB,QAAQ,MAAM,EAAE,SAAS,KAAK,CAC9B,KAAK,MAAM,EAAE,GAAG;CAGlB,MAAM,oBAAoB,qBAAqB,QAAQ,UACtD,oBAAoB,SAAS,MAAM,GAAG,CACtC;CAED,MAAM,iBAAiB,kBAAkB,QAAQ,UAChD,iBAAiB,SAAS,MAAM,GAAG,CACnC;AAED,QACC,qBAAC;EACA,WAAW,GAAG,2BAA2B,UAAU;EAC9C;EACL,GAAI;aAEH,eACA,oBAAC;GACA,UAAU;GACV,aAAa;GACb,MAAM;GACN,SAAS;IACR,EAEH,oBAAC,iBAAe;GACX;EAGR;AAED,gBAAgB,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watermark.d.ts","names":[],"sources":["../../../src/support/components/watermark.tsx"],"sourcesContent":[],"mappings":";KAMY,cAAA;EAAA,SAAA,CAAA,EAAA,MAAc;AAI1B,CAAA;
|
|
1
|
+
{"version":3,"file":"watermark.d.ts","names":[],"sources":["../../../src/support/components/watermark.tsx"],"sourcesContent":[],"mappings":";KAMY,cAAA;EAAA,SAAA,CAAA,EAAA,MAAc;AAI1B,CAAA;cAAa,WAAW,KAAA,CAAM,GAAG"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RealtimeEvent } from "../../realtime-events.js";
|
|
2
2
|
import { RealtimeContextValue } from "../../realtime/provider.js";
|
|
3
|
+
import "../../realtime/index.js";
|
|
3
4
|
import React from "react";
|
|
4
5
|
|
|
5
6
|
//#region src/support/context/websocket.d.ts
|
|
@@ -15,7 +16,14 @@ type WebSocketProviderProps = {
|
|
|
15
16
|
onDisconnect?: () => void;
|
|
16
17
|
onError?: (error: Error) => void;
|
|
17
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* Support-specific realtime provider that authenticates visitors and keeps the
|
|
21
|
+
* connection alive with presence pings.
|
|
22
|
+
*/
|
|
18
23
|
declare const WebSocketProvider: React.FC<WebSocketProviderProps>;
|
|
24
|
+
/**
|
|
25
|
+
* Accessor for the support websocket context.
|
|
26
|
+
*/
|
|
19
27
|
declare const useWebSocket: () => WebSocketContextValue;
|
|
20
28
|
//#endregion
|
|
21
29
|
export { type RealtimeEvent, type WebSocketContextValue, WebSocketProvider, type WebSocketProviderProps, useWebSocket };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket.d.ts","names":[],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","names":[],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":[],"mappings":";;;;;;KAYK,qBAAA,GAAwB;KAExB,sBAAA;YACM,KAAA,CAAM;;EAHZ,SAAA,CAAA,EAAA,MAAA;EAEA,SAAA,CAAA,EAAA,MAAA;EAsJQ,KAAA,CAAA,EAAA,MAAA;EA8BA,WAAA,CAAA,EAAA,OAMZ;;;oBAjLkB;;;;;;cA6IN,mBAAmB,KAAA,CAAM,GAAG;;;;cA8B5B,oBAAmB"}
|
|
@@ -83,14 +83,17 @@ const WebSocketBridge = ({ children, onError }) => {
|
|
|
83
83
|
children
|
|
84
84
|
});
|
|
85
85
|
};
|
|
86
|
+
/**
|
|
87
|
+
* Support-specific realtime provider that authenticates visitors and keeps the
|
|
88
|
+
* connection alive with presence pings.
|
|
89
|
+
*/
|
|
86
90
|
const WebSocketProvider = ({ children, publicKey, websiteId, visitorId, wsUrl, autoConnect = true, onConnect, onDisconnect, onError }) => {
|
|
87
|
-
const auth = createVisitorAuthConfig({
|
|
88
|
-
publicKey,
|
|
89
|
-
websiteId,
|
|
90
|
-
visitorId
|
|
91
|
-
});
|
|
92
91
|
return /* @__PURE__ */ jsx(RealtimeProvider, {
|
|
93
|
-
auth
|
|
92
|
+
auth: createVisitorAuthConfig({
|
|
93
|
+
publicKey,
|
|
94
|
+
websiteId,
|
|
95
|
+
visitorId
|
|
96
|
+
}),
|
|
94
97
|
autoConnect,
|
|
95
98
|
onConnect,
|
|
96
99
|
onDisconnect,
|
|
@@ -102,6 +105,9 @@ const WebSocketProvider = ({ children, publicKey, websiteId, visitorId, wsUrl, a
|
|
|
102
105
|
})
|
|
103
106
|
});
|
|
104
107
|
};
|
|
108
|
+
/**
|
|
109
|
+
* Accessor for the support websocket context.
|
|
110
|
+
*/
|
|
105
111
|
const useWebSocket = () => {
|
|
106
112
|
const context = useContext(WebSocketContext);
|
|
107
113
|
if (!context) throw new Error("useWebSocket must be used within WebSocketProvider");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket.js","names":["WebSocketBridge: React.FC<WebSocketBridgeProps>","intervalId: number | null","WebSocketProvider: React.FC<WebSocketProviderProps>"],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":["\"use client\";\n\nimport { PRESENCE_PING_INTERVAL_MS } from \"@cossistant/types\";\nimport type React from \"react\";\nimport { createContext, useContext, useEffect, useMemo } from \"react\";\nimport {\n\ttype RealtimeAuthConfig,\n\ttype RealtimeContextValue,\n\tRealtimeProvider,\n\tuseRealtimeConnection,\n} from \"../../realtime\";\n\ntype WebSocketContextValue = RealtimeContextValue;\n\ntype WebSocketProviderProps = {\n\tchildren: React.ReactNode;\n\tpublicKey?: string;\n\twebsiteId?: string;\n\tvisitorId?: string;\n\twsUrl?: string;\n\tautoConnect?: boolean;\n\tonConnect?: () => void;\n\tonDisconnect?: () => void;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketContext = createContext<WebSocketContextValue | null>(null);\n\nfunction createVisitorAuthConfig({\n\tvisitorId,\n\twebsiteId,\n\tpublicKey,\n}: Pick<\n\tWebSocketProviderProps,\n\t\"visitorId\" | \"websiteId\" | \"publicKey\"\n>): RealtimeAuthConfig | null {\n\tconst normalizedVisitorId = visitorId?.trim();\n\tif (!normalizedVisitorId) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tkind: \"visitor\",\n\t\tvisitorId: normalizedVisitorId,\n\t\twebsiteId: websiteId?.trim() || null,\n\t\tpublicKey: publicKey?.trim() || null,\n\t} satisfies RealtimeAuthConfig;\n}\n\ntype WebSocketBridgeProps = {\n\tchildren: React.ReactNode;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketBridge: React.FC<WebSocketBridgeProps> = ({\n\tchildren,\n\tonError,\n}) => {\n\tconst connection = useRealtimeConnection();\n\tconst { visitorId, sendRaw, isConnected } = connection;\n\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\" || typeof document === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(visitorId && sendRaw)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst pingMessage = \"presence:ping\";\n\n\t\tconst sendPresencePing = () => {\n\t\t\tif (!isConnected) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tsendRaw(pingMessage);\n\t\t\t} catch (error) {\n\t\t\t\tif (!onError) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst normalizedError =\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error\n\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\ttypeof error === \"string\"\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: \"Unknown presence ping error\"\n\t\t\t\t\t\t\t);\n\n\t\t\t\tif (!normalizedError.message.includes(\"Failed to send presence ping\")) {\n\t\t\t\t\tnormalizedError.message = `Failed to send presence ping: ${normalizedError.message}`;\n\t\t\t\t}\n\n\t\t\t\tonError(normalizedError);\n\t\t\t}\n\t\t};\n\n\t\tlet intervalId: number | null = null;\n\n\t\tconst clearPresenceInterval = () => {\n\t\t\tif (intervalId !== null) {\n\t\t\t\twindow.clearInterval(intervalId);\n\t\t\t\tintervalId = null;\n\t\t\t}\n\t\t};\n\n\t\tconst startPresenceInterval = () => {\n\t\t\tclearPresenceInterval();\n\n\t\t\tif (!isConnected || document.visibilityState === \"hidden\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tintervalId = window.setInterval(\n\t\t\t\tsendPresencePing,\n\t\t\t\tPRESENCE_PING_INTERVAL_MS\n\t\t\t);\n\t\t};\n\n\t\tconst handleFocus = () => {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"hidden\") {\n\t\t\t\tclearPresenceInterval();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\twindow.addEventListener(\"focus\", handleFocus);\n\t\tdocument.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n\t\tif (isConnected && document.visibilityState !== \"hidden\") {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t}\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"focus\", handleFocus);\n\t\t\tdocument.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\t\tclearPresenceInterval();\n\t\t};\n\t}, [isConnected, onError, sendRaw, visitorId]);\n\tconst value = useMemo(() => connection, [connection]);\n\treturn (\n\t\t<WebSocketContext.Provider value={value}>\n\t\t\t{children}\n\t\t</WebSocketContext.Provider>\n\t);\n};\n\nexport const WebSocketProvider: React.FC<WebSocketProviderProps> = ({\n\tchildren,\n\tpublicKey,\n\twebsiteId,\n\tvisitorId,\n\twsUrl,\n\tautoConnect = true,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}) => {\n\tconst auth = createVisitorAuthConfig({ publicKey, websiteId, visitorId });\n\n\treturn (\n\t\t<RealtimeProvider\n\t\t\tauth={auth}\n\t\t\tautoConnect={autoConnect}\n\t\t\tonConnect={onConnect}\n\t\t\tonDisconnect={onDisconnect}\n\t\t\tonError={onError}\n\t\t\twsUrl={wsUrl}\n\t\t>\n\t\t\t<WebSocketBridge onError={onError}>{children}</WebSocketBridge>\n\t\t</RealtimeProvider>\n\t);\n};\n\nexport const useWebSocket = (): WebSocketContextValue => {\n\tconst context = useContext(WebSocketContext);\n\tif (!context) {\n\t\tthrow new Error(\"useWebSocket must be used within WebSocketProvider\");\n\t}\n\treturn context;\n};\n\nexport type { WebSocketContextValue, WebSocketProviderProps };\nexport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\n"],"mappings":";;;;;;;;;AA0BA,MAAM,mBAAmB,cAA4C,KAAK;AAE1E,SAAS,wBAAwB,EAChC,WACA,WACA,aAI6B;CAC7B,MAAM,sBAAsB,WAAW,MAAM;AAC7C,KAAI,CAAC,oBACJ,QAAO;AAGR,QAAO;EACN,MAAM;EACN,WAAW;EACX,WAAW,WAAW,MAAM,IAAI;EAChC,WAAW,WAAW,MAAM,IAAI;EAChC;;AAQF,MAAMA,mBAAmD,EACxD,UACA,cACK;CACL,MAAM,aAAa,uBAAuB;CAC1C,MAAM,EAAE,WAAW,SAAS,gBAAgB;AAE5C,iBAAgB;AACf,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YACxD;AAGD,MAAI,EAAE,aAAa,SAClB;EAGD,MAAM,cAAc;EAEpB,MAAM,yBAAyB;AAC9B,OAAI,CAAC,YACJ;AAGD,OAAI;AACH,YAAQ,YAAY;YACZ,OAAO;AACf,QAAI,CAAC,QACJ;IAGD,MAAM,kBACL,iBAAiB,QACd,QACA,IAAI,MACJ,OAAO,UAAU,WACd,QACA,8BACH;AAEJ,QAAI,CAAC,gBAAgB,QAAQ,SAAS,+BAA+B,CACpE,iBAAgB,UAAU,iCAAiC,gBAAgB;AAG5E,YAAQ,gBAAgB;;;EAI1B,IAAIC,aAA4B;EAEhC,MAAM,8BAA8B;AACnC,OAAI,eAAe,MAAM;AACxB,WAAO,cAAc,WAAW;AAChC,iBAAa;;;EAIf,MAAM,8BAA8B;AACnC,0BAAuB;AAEvB,OAAI,CAAC,eAAe,SAAS,oBAAoB,SAChD;AAGD,gBAAa,OAAO,YACnB,kBACA,0BACA;;EAGF,MAAM,oBAAoB;AACzB,qBAAkB;AAClB,0BAAuB;;EAGxB,MAAM,+BAA+B;AACpC,OAAI,SAAS,oBAAoB,UAAU;AAC1C,2BAAuB;AACvB;;AAGD,qBAAkB;AAClB,0BAAuB;;AAGxB,SAAO,iBAAiB,SAAS,YAAY;AAC7C,WAAS,iBAAiB,oBAAoB,uBAAuB;AAErE,MAAI,eAAe,SAAS,oBAAoB,UAAU;AACzD,qBAAkB;AAClB,0BAAuB;;AAGxB,eAAa;AACZ,UAAO,oBAAoB,SAAS,YAAY;AAChD,YAAS,oBAAoB,oBAAoB,uBAAuB;AACxE,0BAAuB;;IAEtB;EAAC;EAAa;EAAS;EAAS;EAAU,CAAC;CAC9C,MAAM,QAAQ,cAAc,YAAY,CAAC,WAAW,CAAC;AACrD,QACC,oBAAC,iBAAiB;EAAgB;EAChC;GAC0B
|
|
1
|
+
{"version":3,"file":"websocket.js","names":["WebSocketBridge: React.FC<WebSocketBridgeProps>","intervalId: number | null","WebSocketProvider: React.FC<WebSocketProviderProps>"],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":["\"use client\";\n\nimport { PRESENCE_PING_INTERVAL_MS } from \"@cossistant/types\";\nimport type React from \"react\";\nimport { createContext, useContext, useEffect, useMemo } from \"react\";\nimport {\n\ttype RealtimeAuthConfig,\n\ttype RealtimeContextValue,\n\tRealtimeProvider,\n\tuseRealtimeConnection,\n} from \"../../realtime\";\n\ntype WebSocketContextValue = RealtimeContextValue;\n\ntype WebSocketProviderProps = {\n\tchildren: React.ReactNode;\n\tpublicKey?: string;\n\twebsiteId?: string;\n\tvisitorId?: string;\n\twsUrl?: string;\n\tautoConnect?: boolean;\n\tonConnect?: () => void;\n\tonDisconnect?: () => void;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketContext = createContext<WebSocketContextValue | null>(null);\n\nfunction createVisitorAuthConfig({\n\tvisitorId,\n\twebsiteId,\n\tpublicKey,\n}: Pick<\n\tWebSocketProviderProps,\n\t\"visitorId\" | \"websiteId\" | \"publicKey\"\n>): RealtimeAuthConfig | null {\n\tconst normalizedVisitorId = visitorId?.trim();\n\tif (!normalizedVisitorId) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tkind: \"visitor\",\n\t\tvisitorId: normalizedVisitorId,\n\t\twebsiteId: websiteId?.trim() || null,\n\t\tpublicKey: publicKey?.trim() || null,\n\t} satisfies RealtimeAuthConfig;\n}\n\ntype WebSocketBridgeProps = {\n\tchildren: React.ReactNode;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketBridge: React.FC<WebSocketBridgeProps> = ({\n\tchildren,\n\tonError,\n}) => {\n\tconst connection = useRealtimeConnection();\n\tconst { visitorId, sendRaw, isConnected } = connection;\n\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\" || typeof document === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(visitorId && sendRaw)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst pingMessage = \"presence:ping\";\n\n\t\tconst sendPresencePing = () => {\n\t\t\tif (!isConnected) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tsendRaw(pingMessage);\n\t\t\t} catch (error) {\n\t\t\t\tif (!onError) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst normalizedError =\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error\n\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\ttypeof error === \"string\"\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: \"Unknown presence ping error\"\n\t\t\t\t\t\t\t);\n\n\t\t\t\tif (!normalizedError.message.includes(\"Failed to send presence ping\")) {\n\t\t\t\t\tnormalizedError.message = `Failed to send presence ping: ${normalizedError.message}`;\n\t\t\t\t}\n\n\t\t\t\tonError(normalizedError);\n\t\t\t}\n\t\t};\n\n\t\tlet intervalId: number | null = null;\n\n\t\tconst clearPresenceInterval = () => {\n\t\t\tif (intervalId !== null) {\n\t\t\t\twindow.clearInterval(intervalId);\n\t\t\t\tintervalId = null;\n\t\t\t}\n\t\t};\n\n\t\tconst startPresenceInterval = () => {\n\t\t\tclearPresenceInterval();\n\n\t\t\tif (!isConnected || document.visibilityState === \"hidden\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tintervalId = window.setInterval(\n\t\t\t\tsendPresencePing,\n\t\t\t\tPRESENCE_PING_INTERVAL_MS\n\t\t\t);\n\t\t};\n\n\t\tconst handleFocus = () => {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"hidden\") {\n\t\t\t\tclearPresenceInterval();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\twindow.addEventListener(\"focus\", handleFocus);\n\t\tdocument.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n\t\tif (isConnected && document.visibilityState !== \"hidden\") {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t}\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"focus\", handleFocus);\n\t\t\tdocument.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\t\tclearPresenceInterval();\n\t\t};\n\t}, [isConnected, onError, sendRaw, visitorId]);\n\tconst value = useMemo(() => connection, [connection]);\n\treturn (\n\t\t<WebSocketContext.Provider value={value}>\n\t\t\t{children}\n\t\t</WebSocketContext.Provider>\n\t);\n};\n\n/**\n * Support-specific realtime provider that authenticates visitors and keeps the\n * connection alive with presence pings.\n */\nexport const WebSocketProvider: React.FC<WebSocketProviderProps> = ({\n\tchildren,\n\tpublicKey,\n\twebsiteId,\n\tvisitorId,\n\twsUrl,\n\tautoConnect = true,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}) => {\n\tconst auth = createVisitorAuthConfig({ publicKey, websiteId, visitorId });\n\n\treturn (\n\t\t<RealtimeProvider\n\t\t\tauth={auth}\n\t\t\tautoConnect={autoConnect}\n\t\t\tonConnect={onConnect}\n\t\t\tonDisconnect={onDisconnect}\n\t\t\tonError={onError}\n\t\t\twsUrl={wsUrl}\n\t\t>\n\t\t\t<WebSocketBridge onError={onError}>{children}</WebSocketBridge>\n\t\t</RealtimeProvider>\n\t);\n};\n\n/**\n * Accessor for the support websocket context.\n */\nexport const useWebSocket = (): WebSocketContextValue => {\n\tconst context = useContext(WebSocketContext);\n\tif (!context) {\n\t\tthrow new Error(\"useWebSocket must be used within WebSocketProvider\");\n\t}\n\treturn context;\n};\n\nexport type { WebSocketContextValue, WebSocketProviderProps };\nexport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\n"],"mappings":";;;;;;;;;AA0BA,MAAM,mBAAmB,cAA4C,KAAK;AAE1E,SAAS,wBAAwB,EAChC,WACA,WACA,aAI6B;CAC7B,MAAM,sBAAsB,WAAW,MAAM;AAC7C,KAAI,CAAC,oBACJ,QAAO;AAGR,QAAO;EACN,MAAM;EACN,WAAW;EACX,WAAW,WAAW,MAAM,IAAI;EAChC,WAAW,WAAW,MAAM,IAAI;EAChC;;AAQF,MAAMA,mBAAmD,EACxD,UACA,cACK;CACL,MAAM,aAAa,uBAAuB;CAC1C,MAAM,EAAE,WAAW,SAAS,gBAAgB;AAE5C,iBAAgB;AACf,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YACxD;AAGD,MAAI,EAAE,aAAa,SAClB;EAGD,MAAM,cAAc;EAEpB,MAAM,yBAAyB;AAC9B,OAAI,CAAC,YACJ;AAGD,OAAI;AACH,YAAQ,YAAY;YACZ,OAAO;AACf,QAAI,CAAC,QACJ;IAGD,MAAM,kBACL,iBAAiB,QACd,QACA,IAAI,MACJ,OAAO,UAAU,WACd,QACA,8BACH;AAEJ,QAAI,CAAC,gBAAgB,QAAQ,SAAS,+BAA+B,CACpE,iBAAgB,UAAU,iCAAiC,gBAAgB;AAG5E,YAAQ,gBAAgB;;;EAI1B,IAAIC,aAA4B;EAEhC,MAAM,8BAA8B;AACnC,OAAI,eAAe,MAAM;AACxB,WAAO,cAAc,WAAW;AAChC,iBAAa;;;EAIf,MAAM,8BAA8B;AACnC,0BAAuB;AAEvB,OAAI,CAAC,eAAe,SAAS,oBAAoB,SAChD;AAGD,gBAAa,OAAO,YACnB,kBACA,0BACA;;EAGF,MAAM,oBAAoB;AACzB,qBAAkB;AAClB,0BAAuB;;EAGxB,MAAM,+BAA+B;AACpC,OAAI,SAAS,oBAAoB,UAAU;AAC1C,2BAAuB;AACvB;;AAGD,qBAAkB;AAClB,0BAAuB;;AAGxB,SAAO,iBAAiB,SAAS,YAAY;AAC7C,WAAS,iBAAiB,oBAAoB,uBAAuB;AAErE,MAAI,eAAe,SAAS,oBAAoB,UAAU;AACzD,qBAAkB;AAClB,0BAAuB;;AAGxB,eAAa;AACZ,UAAO,oBAAoB,SAAS,YAAY;AAChD,YAAS,oBAAoB,oBAAoB,uBAAuB;AACxE,0BAAuB;;IAEtB;EAAC;EAAa;EAAS;EAAS;EAAU,CAAC;CAC9C,MAAM,QAAQ,cAAc,YAAY,CAAC,WAAW,CAAC;AACrD,QACC,oBAAC,iBAAiB;EAAgB;EAChC;GAC0B;;;;;;AAQ9B,MAAaC,qBAAuD,EACnE,UACA,WACA,WACA,WACA,OACA,cAAc,MACd,WACA,cACA,cACK;AAGL,QACC,oBAAC;EACA,MAJW,wBAAwB;GAAE;GAAW;GAAW;GAAW,CAAC;EAK1D;EACF;EACG;EACL;EACF;YAEP,oBAAC;GAAyB;GAAU;IAA2B;GAC7C;;;;;AAOrB,MAAa,qBAA4C;CACxD,MAAM,UAAU,WAAW,iBAAiB;AAC5C,KAAI,CAAC,QACJ,OAAM,IAAI,MAAM,qDAAqD;AAEtE,QAAO"}
|
package/support/index.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { SupportLocale, SupportTextContentOverrides } from "./text/locales/keys.js";
|
|
2
2
|
import { Text, useSupportText } from "./text/index.js";
|
|
3
|
-
import { useSupportConfig } from "./context/config.js";
|
|
4
3
|
import { WebSocketContextValue, WebSocketProvider, useWebSocket } from "./context/websocket.js";
|
|
5
|
-
import { useSupportStore } from "./store/support-store.js";
|
|
4
|
+
import { useSupportConfig, useSupportNavigation, useSupportStore } from "./store/support-store.js";
|
|
5
|
+
import "./store/index.js";
|
|
6
|
+
import { ReactElement } from "react";
|
|
6
7
|
import { DefaultMessage } from "@cossistant/types";
|
|
7
|
-
import * as react_jsx_runtime1 from "react/jsx-runtime";
|
|
8
8
|
|
|
9
9
|
//#region src/support/index.d.ts
|
|
10
10
|
type SupportProps<Locale extends string = SupportLocale> = {
|
|
11
11
|
className?: string;
|
|
12
12
|
position?: "top" | "bottom";
|
|
13
13
|
align?: "right" | "left";
|
|
14
|
-
|
|
14
|
+
positioning?: "fixed" | "absolute";
|
|
15
15
|
quickOptions?: string[];
|
|
16
16
|
defaultMessages?: DefaultMessage[];
|
|
17
17
|
defaultOpen?: boolean;
|
|
@@ -19,7 +19,7 @@ type SupportProps<Locale extends string = SupportLocale> = {
|
|
|
19
19
|
content?: SupportTextContentOverrides<Locale>;
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
22
|
-
* Orchestrates the end-user support experience by nesting realtime
|
|
22
|
+
* Orchestrates the end-user support experience by nesting realtime and
|
|
23
23
|
* content providers. Renders nothing until website data is available to avoid
|
|
24
24
|
* flashing incomplete UI.
|
|
25
25
|
*/
|
|
@@ -27,13 +27,13 @@ declare function Support<Locale extends string = SupportLocale>({
|
|
|
27
27
|
className,
|
|
28
28
|
position,
|
|
29
29
|
align,
|
|
30
|
-
|
|
30
|
+
positioning,
|
|
31
31
|
quickOptions,
|
|
32
32
|
defaultMessages,
|
|
33
33
|
defaultOpen,
|
|
34
34
|
locale,
|
|
35
35
|
content
|
|
36
|
-
}: SupportProps<Locale>):
|
|
36
|
+
}: SupportProps<Locale>): ReactElement | null;
|
|
37
37
|
//#endregion
|
|
38
|
-
export { Support, Support as default, type SupportLocale, SupportProps, type SupportTextContentOverrides, Text, type WebSocketContextValue, WebSocketProvider, useSupportConfig, useSupportStore, useSupportText, useWebSocket };
|
|
38
|
+
export { Support, Support as default, type SupportLocale, SupportProps, type SupportTextContentOverrides, Text, type WebSocketContextValue, WebSocketProvider, useSupportConfig, useSupportNavigation, useSupportStore, useSupportText, useWebSocket };
|
|
39
39
|
//# sourceMappingURL=index.d.ts.map
|
package/support/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/support/index.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/support/index.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;KAYY,qCAAqC;;;;;EAArC,YAAA,CAAA,EAAY,MAAA,EAAA;EAAyB,eAAA,CAAA,EAM9B,cAN8B,EAAA;EAM9B,WAAA,CAAA,EAAA,OAAA;EAET,MAAA,CAAA,EAAA,MAAA;EAC6B,OAAA,CAAA,EAA5B,2BAA4B,CAAA,MAAA,CAAA;CAA5B;;AASX;;;;AAGC,iBAHe,OAGf,CAAA,eAAA,MAAA,GAH+C,aAG/C,CAAA,CAAA;EAAA,SAAA;EAAA,QAAA;EAAA,KAAA;EAAA,WAAA;EAAA,YAAA;EAAA,eAAA;EAAA,WAAA;EAAA,MAAA;EAAA;AAAA,CAAA,EAOE,YAPF,CAOe,MAPf,CAAA,CAAA,EAOyB,YAPzB,GAAA,IAAA"}
|
package/support/index.js
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
import "./support.js";
|
|
2
2
|
import { SupportRealtimeProvider } from "../realtime/support-provider.js";
|
|
3
3
|
import { SupportConfig } from "../support-config.js";
|
|
4
|
-
import { useSupportStore } from "./store/support-store.js";
|
|
5
|
-
import { SupportConfigProvider, useSupportConfig } from "./context/config.js";
|
|
4
|
+
import { initializeSupportStore, useSupportConfig, useSupportNavigation, useSupportStore } from "./store/support-store.js";
|
|
6
5
|
import { SupportTextProvider, Text, useSupportText } from "./text/index.js";
|
|
7
6
|
import { SupportContent } from "./components/support-content.js";
|
|
8
7
|
import { WebSocketProvider, useWebSocket } from "./context/websocket.js";
|
|
9
8
|
import { useSupport } from "../provider.js";
|
|
9
|
+
import React from "react";
|
|
10
10
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
11
11
|
|
|
12
12
|
//#region src/support/index.tsx
|
|
13
13
|
/**
|
|
14
|
-
* Orchestrates the end-user support experience by nesting realtime
|
|
14
|
+
* Orchestrates the end-user support experience by nesting realtime and
|
|
15
15
|
* content providers. Renders nothing until website data is available to avoid
|
|
16
16
|
* flashing incomplete UI.
|
|
17
17
|
*/
|
|
18
|
-
function Support({ className, position = "bottom", align = "right",
|
|
18
|
+
function Support({ className, position = "bottom", align = "right", positioning = "fixed", quickOptions, defaultMessages, defaultOpen, locale, content }) {
|
|
19
19
|
const { website } = useSupport();
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
defaultOpen
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
const isVisitorBlocked = website?.visitor?.isBlocked ?? false;
|
|
21
|
+
React.useEffect(() => {
|
|
22
|
+
if (defaultOpen !== void 0) initializeSupportStore({ defaultOpen });
|
|
23
|
+
}, [defaultOpen]);
|
|
24
|
+
if (!website || isVisitorBlocked) return null;
|
|
25
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(SupportRealtimeProvider, { children: /* @__PURE__ */ jsx(SupportTextProvider, {
|
|
26
|
+
content,
|
|
27
|
+
locale,
|
|
28
|
+
children: /* @__PURE__ */ jsx(SupportContent, {
|
|
29
|
+
align,
|
|
30
|
+
className,
|
|
31
|
+
position,
|
|
32
|
+
positioning
|
|
33
33
|
})
|
|
34
34
|
}) }), /* @__PURE__ */ jsx(SupportConfig, {
|
|
35
35
|
defaultMessages,
|
|
@@ -39,5 +39,5 @@ function Support({ className, position = "bottom", align = "right", mode = "floa
|
|
|
39
39
|
var support_default = Support;
|
|
40
40
|
|
|
41
41
|
//#endregion
|
|
42
|
-
export { Support, Text, WebSocketProvider, support_default as default, useSupportConfig, useSupportStore, useSupportText, useWebSocket };
|
|
42
|
+
export { Support, Text, WebSocketProvider, support_default as default, useSupportConfig, useSupportNavigation, useSupportStore, useSupportText, useWebSocket };
|
|
43
43
|
//# sourceMappingURL=index.js.map
|
package/support/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/support/index.tsx"],"sourcesContent":["import \"./support.css\";\n\nimport type { DefaultMessage } from \"@cossistant/types\";\nimport { useSupport } from \"../provider\";\nimport { SupportRealtimeProvider } from \"../realtime\";\nimport { SupportConfig } from \"../support-config\";\nimport { SupportContent } from \"./components/support-content\";\nimport {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/support/index.tsx"],"sourcesContent":["import \"./support.css\";\n\nimport type { DefaultMessage } from \"@cossistant/types\";\nimport React, { type ReactElement } from \"react\";\nimport { useSupport } from \"../provider\";\nimport { SupportRealtimeProvider } from \"../realtime\";\nimport { SupportConfig } from \"../support-config\";\nimport { SupportContent } from \"./components/support-content\";\nimport { initializeSupportStore } from \"./store/support-store\";\nimport type { SupportLocale, SupportTextContentOverrides } from \"./text\";\nimport { SupportTextProvider } from \"./text\";\n\nexport type SupportProps<Locale extends string = SupportLocale> = {\n\tclassName?: string;\n\tposition?: \"top\" | \"bottom\";\n\talign?: \"right\" | \"left\";\n\tpositioning?: \"fixed\" | \"absolute\";\n\tquickOptions?: string[];\n\tdefaultMessages?: DefaultMessage[];\n\tdefaultOpen?: boolean;\n\tlocale?: Locale;\n\tcontent?: SupportTextContentOverrides<Locale>;\n};\n\n// Internal component that needs the conversation context\n/**\n * Orchestrates the end-user support experience by nesting realtime and\n * content providers. Renders nothing until website data is available to avoid\n * flashing incomplete UI.\n */\nexport function Support<Locale extends string = SupportLocale>({\n\tclassName,\n\tposition = \"bottom\",\n\talign = \"right\",\n\tpositioning = \"fixed\",\n\tquickOptions,\n\tdefaultMessages,\n\tdefaultOpen,\n\tlocale,\n\tcontent,\n}: SupportProps<Locale>): ReactElement | null {\n\tconst { website } = useSupport();\n\tconst isVisitorBlocked = website?.visitor?.isBlocked ?? false;\n\n\t// Initialize support store with defaultOpen when component mounts or prop changes\n\tReact.useEffect(() => {\n\t\tif (defaultOpen !== undefined) {\n\t\t\tinitializeSupportStore({ defaultOpen });\n\t\t}\n\t}, [defaultOpen]);\n\n\tif (!website || isVisitorBlocked) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<SupportRealtimeProvider>\n\t\t\t\t<SupportTextProvider content={content} locale={locale}>\n\t\t\t\t\t<SupportContent\n\t\t\t\t\t\talign={align}\n\t\t\t\t\t\tclassName={className}\n\t\t\t\t\t\tposition={position}\n\t\t\t\t\t\tpositioning={positioning}\n\t\t\t\t\t/>\n\t\t\t\t</SupportTextProvider>\n\t\t\t</SupportRealtimeProvider>\n\t\t\t<SupportConfig\n\t\t\t\tdefaultMessages={defaultMessages}\n\t\t\t\tquickOptions={quickOptions}\n\t\t\t/>\n\t\t</>\n\t);\n}\n\nexport default Support;\n\nexport type { WebSocketContextValue } from \"./context/websocket\";\nexport { useWebSocket, WebSocketProvider } from \"./context/websocket\";\n// Export the store for direct access if needed\nexport {\n\tuseSupportConfig,\n\tuseSupportNavigation,\n\tuseSupportStore,\n} from \"./store\";\nexport type { SupportLocale, SupportTextContentOverrides } from \"./text\";\nexport { Text, useSupportText } from \"./text\";\n"],"mappings":";;;;;;;;;;;;;;;;;AA8BA,SAAgB,QAA+C,EAC9D,WACA,WAAW,UACX,QAAQ,SACR,cAAc,SACd,cACA,iBACA,aACA,QACA,WAC6C;CAC7C,MAAM,EAAE,YAAY,YAAY;CAChC,MAAM,mBAAmB,SAAS,SAAS,aAAa;AAGxD,OAAM,gBAAgB;AACrB,MAAI,gBAAgB,OACnB,wBAAuB,EAAE,aAAa,CAAC;IAEtC,CAAC,YAAY,CAAC;AAEjB,KAAI,CAAC,WAAW,iBACf,QAAO;AAGR,QACC,4CACC,oBAAC,qCACA,oBAAC;EAA6B;EAAiB;YAC9C,oBAAC;GACO;GACI;GACD;GACG;IACZ;GACmB,GACG,EAC1B,oBAAC;EACiB;EACH;GACb,IACA;;AAIL,sBAAe"}
|