@cossistant/react 0.0.1
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/_virtual/rolldown_runtime.js +13 -0
- package/conversation.d.ts +312 -0
- package/conversation.d.ts.map +1 -0
- package/hooks/index.d.ts +23 -0
- package/hooks/index.js +24 -0
- package/hooks/private/store/use-conversations-store.d.ts +13 -0
- package/hooks/private/store/use-conversations-store.d.ts.map +1 -0
- package/hooks/private/store/use-conversations-store.js +34 -0
- package/hooks/private/store/use-conversations-store.js.map +1 -0
- package/hooks/private/store/use-store-selector.d.ts +10 -0
- package/hooks/private/store/use-store-selector.d.ts.map +1 -0
- package/hooks/private/store/use-store-selector.js +17 -0
- package/hooks/private/store/use-store-selector.js.map +1 -0
- package/hooks/private/store/use-website-store.d.ts +18 -0
- package/hooks/private/store/use-website-store.d.ts.map +1 -0
- package/hooks/private/store/use-website-store.js +39 -0
- package/hooks/private/store/use-website-store.js.map +1 -0
- package/hooks/private/use-client-query.d.ts +25 -0
- package/hooks/private/use-client-query.d.ts.map +1 -0
- package/hooks/private/use-client-query.js +122 -0
- package/hooks/private/use-client-query.js.map +1 -0
- package/hooks/private/use-default-messages.d.ts +18 -0
- package/hooks/private/use-default-messages.d.ts.map +1 -0
- package/hooks/private/use-default-messages.js +45 -0
- package/hooks/private/use-default-messages.js.map +1 -0
- package/hooks/private/use-grouped-messages.d.ts +54 -0
- package/hooks/private/use-grouped-messages.d.ts.map +1 -0
- package/hooks/private/use-grouped-messages.js +157 -0
- package/hooks/private/use-grouped-messages.js.map +1 -0
- package/hooks/private/use-multimodal-input.d.ts +40 -0
- package/hooks/private/use-multimodal-input.d.ts.map +1 -0
- package/hooks/private/use-multimodal-input.js +129 -0
- package/hooks/private/use-multimodal-input.js.map +1 -0
- package/hooks/private/use-rest-client.d.ts +17 -0
- package/hooks/private/use-rest-client.d.ts.map +1 -0
- package/hooks/private/use-rest-client.js +41 -0
- package/hooks/private/use-rest-client.js.map +1 -0
- package/hooks/private/use-visitor-typing-reporter.d.ts +19 -0
- package/hooks/private/use-visitor-typing-reporter.d.ts.map +1 -0
- package/hooks/private/use-visitor-typing-reporter.js +140 -0
- package/hooks/private/use-visitor-typing-reporter.js.map +1 -0
- package/hooks/use-composer-refocus.d.ts +20 -0
- package/hooks/use-composer-refocus.d.ts.map +1 -0
- package/hooks/use-composer-refocus.js +32 -0
- package/hooks/use-composer-refocus.js.map +1 -0
- package/hooks/use-conversation-auto-seen.d.ts +54 -0
- package/hooks/use-conversation-auto-seen.d.ts.map +1 -0
- package/hooks/use-conversation-auto-seen.js +106 -0
- package/hooks/use-conversation-auto-seen.js.map +1 -0
- package/hooks/use-conversation-history-page.d.ts +86 -0
- package/hooks/use-conversation-history-page.d.ts.map +1 -0
- package/hooks/use-conversation-history-page.js +97 -0
- package/hooks/use-conversation-history-page.js.map +1 -0
- package/hooks/use-conversation-lifecycle.d.ts +80 -0
- package/hooks/use-conversation-lifecycle.d.ts.map +1 -0
- package/hooks/use-conversation-lifecycle.js +54 -0
- package/hooks/use-conversation-lifecycle.js.map +1 -0
- package/hooks/use-conversation-page.d.ts +82 -0
- package/hooks/use-conversation-page.d.ts.map +1 -0
- package/hooks/use-conversation-page.js +138 -0
- package/hooks/use-conversation-page.js.map +1 -0
- package/hooks/use-conversation-seen.d.ts +17 -0
- package/hooks/use-conversation-seen.d.ts.map +1 -0
- package/hooks/use-conversation-seen.js +58 -0
- package/hooks/use-conversation-seen.js.map +1 -0
- package/hooks/use-conversation-timeline-items.d.ts +21 -0
- package/hooks/use-conversation-timeline-items.d.ts.map +1 -0
- package/hooks/use-conversation-timeline-items.js +87 -0
- package/hooks/use-conversation-timeline-items.js.map +1 -0
- package/hooks/use-conversation-typing.d.ts +13 -0
- package/hooks/use-conversation-typing.d.ts.map +1 -0
- package/hooks/use-conversation-typing.js +34 -0
- package/hooks/use-conversation-typing.js.map +1 -0
- package/hooks/use-conversation.d.ts +18 -0
- package/hooks/use-conversation.d.ts.map +1 -0
- package/hooks/use-conversation.js +44 -0
- package/hooks/use-conversation.js.map +1 -0
- package/hooks/use-conversations.d.ts +20 -0
- package/hooks/use-conversations.d.ts.map +1 -0
- package/hooks/use-conversations.js +68 -0
- package/hooks/use-conversations.js.map +1 -0
- package/hooks/use-create-conversation.d.ts +30 -0
- package/hooks/use-create-conversation.d.ts.map +1 -0
- package/hooks/use-create-conversation.js +67 -0
- package/hooks/use-create-conversation.js.map +1 -0
- package/hooks/use-home-page.d.ts +82 -0
- package/hooks/use-home-page.d.ts.map +1 -0
- package/hooks/use-home-page.js +89 -0
- package/hooks/use-home-page.js.map +1 -0
- package/hooks/use-message-composer.d.ts +88 -0
- package/hooks/use-message-composer.d.ts.map +1 -0
- package/hooks/use-message-composer.js +94 -0
- package/hooks/use-message-composer.js.map +1 -0
- package/hooks/use-realtime-support.d.ts +25 -0
- package/hooks/use-realtime-support.d.ts.map +1 -0
- package/hooks/use-realtime-support.js +29 -0
- package/hooks/use-realtime-support.js.map +1 -0
- package/hooks/use-send-message.d.ts +34 -0
- package/hooks/use-send-message.d.ts.map +1 -0
- package/hooks/use-send-message.js +118 -0
- package/hooks/use-send-message.js.map +1 -0
- package/hooks/use-visitor.d.ts +28 -0
- package/hooks/use-visitor.d.ts.map +1 -0
- package/hooks/use-visitor.js +59 -0
- package/hooks/use-visitor.js.map +1 -0
- package/hooks/use-window-visibility-focus.d.ts +9 -0
- package/hooks/use-window-visibility-focus.d.ts.map +1 -0
- package/hooks/use-window-visibility-focus.js +53 -0
- package/hooks/use-window-visibility-focus.js.map +1 -0
- package/identify-visitor.d.ts +18 -0
- package/identify-visitor.d.ts.map +1 -0
- package/identify-visitor.js +26 -0
- package/identify-visitor.js.map +1 -0
- package/index.d.ts +38 -0
- package/index.js +38 -0
- package/package.json +121 -0
- package/primitives/avatar/avatar.d.ts +31 -0
- package/primitives/avatar/avatar.d.ts.map +1 -0
- package/primitives/avatar/avatar.js +49 -0
- package/primitives/avatar/avatar.js.map +1 -0
- package/primitives/avatar/fallback.d.ts +24 -0
- package/primitives/avatar/fallback.d.ts.map +1 -0
- package/primitives/avatar/fallback.js +57 -0
- package/primitives/avatar/fallback.js.map +1 -0
- package/primitives/avatar/image.d.ts +27 -0
- package/primitives/avatar/image.d.ts.map +1 -0
- package/primitives/avatar/image.js +58 -0
- package/primitives/avatar/image.js.map +1 -0
- package/primitives/avatar/index.d.ts +4 -0
- package/primitives/avatar/index.js +5 -0
- package/primitives/avatar/index.parts.d.ts +4 -0
- package/primitives/avatar/index.parts.js +5 -0
- package/primitives/bubble.d.ts +28 -0
- package/primitives/bubble.d.ts.map +1 -0
- package/primitives/bubble.js +43 -0
- package/primitives/bubble.js.map +1 -0
- package/primitives/button.d.ts +19 -0
- package/primitives/button.d.ts.map +1 -0
- package/primitives/button.js +27 -0
- package/primitives/button.js.map +1 -0
- package/primitives/conversation-timeline.d.ts +86 -0
- package/primitives/conversation-timeline.d.ts.map +1 -0
- package/primitives/conversation-timeline.js +119 -0
- package/primitives/conversation-timeline.js.map +1 -0
- package/primitives/index.d.ts +20 -0
- package/primitives/index.d.ts.map +1 -0
- package/primitives/index.js +45 -0
- package/primitives/index.js.map +1 -0
- package/primitives/index.parts.d.ts +13 -0
- package/primitives/index.parts.js +14 -0
- package/primitives/multimodal-input.d.ts +53 -0
- package/primitives/multimodal-input.d.ts.map +1 -0
- package/primitives/multimodal-input.js +106 -0
- package/primitives/multimodal-input.js.map +1 -0
- package/primitives/timeline-item-group.d.ts +166 -0
- package/primitives/timeline-item-group.d.ts.map +1 -0
- package/primitives/timeline-item-group.js +204 -0
- package/primitives/timeline-item-group.js.map +1 -0
- package/primitives/timeline-item.d.ts +75 -0
- package/primitives/timeline-item.d.ts.map +1 -0
- package/primitives/timeline-item.js +145 -0
- package/primitives/timeline-item.js.map +1 -0
- package/primitives/window.d.ts +31 -0
- package/primitives/window.d.ts.map +1 -0
- package/primitives/window.js +58 -0
- package/primitives/window.js.map +1 -0
- package/provider.d.ts +95 -0
- package/provider.d.ts.map +1 -0
- package/provider.js +124 -0
- package/provider.js.map +1 -0
- package/realtime/event-filter.d.ts +8 -0
- package/realtime/event-filter.d.ts.map +1 -0
- package/realtime/event-filter.js +21 -0
- package/realtime/event-filter.js.map +1 -0
- package/realtime/index.d.ts +6 -0
- package/realtime/index.js +7 -0
- package/realtime/provider.d.ts +57 -0
- package/realtime/provider.d.ts.map +1 -0
- package/realtime/provider.js +351 -0
- package/realtime/provider.js.map +1 -0
- package/realtime/seen-store.d.ts +23 -0
- package/realtime/seen-store.d.ts.map +1 -0
- package/realtime/seen-store.js +34 -0
- package/realtime/seen-store.js.map +1 -0
- package/realtime/support-provider.d.ts +17 -0
- package/realtime/support-provider.d.ts.map +1 -0
- package/realtime/support-provider.js +54 -0
- package/realtime/support-provider.js.map +1 -0
- package/realtime/typing-store.d.ts +30 -0
- package/realtime/typing-store.d.ts.map +1 -0
- package/realtime/typing-store.js +34 -0
- package/realtime/typing-store.js.map +1 -0
- package/realtime/use-realtime.d.ts +29 -0
- package/realtime/use-realtime.d.ts.map +1 -0
- package/realtime/use-realtime.js +47 -0
- package/realtime/use-realtime.js.map +1 -0
- package/realtime-events.d.ts +344 -0
- package/realtime-events.d.ts.map +1 -0
- package/schemas.d.ts +90 -0
- package/schemas.d.ts.map +1 -0
- package/support/components/avatar-stack.d.ts +45 -0
- package/support/components/avatar-stack.d.ts.map +1 -0
- package/support/components/avatar-stack.js +72 -0
- package/support/components/avatar-stack.js.map +1 -0
- package/support/components/avatar.d.ts +15 -0
- package/support/components/avatar.d.ts.map +1 -0
- package/support/components/avatar.js +23 -0
- package/support/components/avatar.js.map +1 -0
- package/support/components/bubble.d.ts +10 -0
- package/support/components/bubble.d.ts.map +1 -0
- package/support/components/bubble.js +95 -0
- package/support/components/bubble.js.map +1 -0
- package/support/components/button.d.ts +20 -0
- package/support/components/button.d.ts.map +1 -0
- package/support/components/button.js +41 -0
- package/support/components/button.js.map +1 -0
- package/support/components/container.d.ts +14 -0
- package/support/components/container.d.ts.map +1 -0
- package/support/components/container.js +115 -0
- package/support/components/container.js.map +1 -0
- package/support/components/conversation-button-link.d.ts +34 -0
- package/support/components/conversation-button-link.d.ts.map +1 -0
- package/support/components/conversation-button-link.js +195 -0
- package/support/components/conversation-button-link.js.map +1 -0
- package/support/components/conversation-event.d.ts +14 -0
- package/support/components/conversation-event.d.ts.map +1 -0
- package/support/components/conversation-event.js +76 -0
- package/support/components/conversation-event.js.map +1 -0
- package/support/components/conversation-timeline.d.ts +17 -0
- package/support/components/conversation-timeline.d.ts.map +1 -0
- package/support/components/conversation-timeline.js +95 -0
- package/support/components/conversation-timeline.js.map +1 -0
- package/support/components/cossistant-branding.d.ts +12 -0
- package/support/components/cossistant-branding.d.ts.map +1 -0
- package/support/components/cossistant-branding.js +22 -0
- package/support/components/cossistant-branding.js.map +1 -0
- package/support/components/header.d.ts +11 -0
- package/support/components/header.d.ts.map +1 -0
- package/support/components/header.js +43 -0
- package/support/components/header.js.map +1 -0
- package/support/components/icons.d.ts +21 -0
- package/support/components/icons.d.ts.map +1 -0
- package/support/components/icons.js +131 -0
- package/support/components/icons.js.map +1 -0
- package/support/components/index.d.ts +11 -0
- package/support/components/index.js +12 -0
- package/support/components/multimodal-input.d.ts +28 -0
- package/support/components/multimodal-input.d.ts.map +1 -0
- package/support/components/multimodal-input.js +138 -0
- package/support/components/multimodal-input.js.map +1 -0
- package/support/components/navigation-tab.d.ts +7 -0
- package/support/components/navigation-tab.d.ts.map +1 -0
- package/support/components/navigation-tab.js +40 -0
- package/support/components/navigation-tab.js.map +1 -0
- package/support/components/support-content.d.ts +22 -0
- package/support/components/support-content.d.ts.map +1 -0
- package/support/components/support-content.js +50 -0
- package/support/components/support-content.js.map +1 -0
- package/support/components/text-effect.d.ts +49 -0
- package/support/components/text-effect.d.ts.map +1 -0
- package/support/components/text-effect.js +221 -0
- package/support/components/text-effect.js.map +1 -0
- package/support/components/timeline-message-group.d.ts +16 -0
- package/support/components/timeline-message-group.d.ts.map +1 -0
- package/support/components/timeline-message-group.js +117 -0
- package/support/components/timeline-message-group.js.map +1 -0
- package/support/components/timeline-message-item.d.ts +17 -0
- package/support/components/timeline-message-item.d.ts.map +1 -0
- package/support/components/timeline-message-item.js +42 -0
- package/support/components/timeline-message-item.js.map +1 -0
- package/support/components/typing-indicator.d.ts +26 -0
- package/support/components/typing-indicator.d.ts.map +1 -0
- package/support/components/typing-indicator.js +37 -0
- package/support/components/typing-indicator.js.map +1 -0
- package/support/components/watermark.d.ts +8 -0
- package/support/components/watermark.d.ts.map +1 -0
- package/support/components/watermark.js +34 -0
- package/support/components/watermark.js.map +1 -0
- package/support/context/config.d.ts +32 -0
- package/support/context/config.d.ts.map +1 -0
- package/support/context/config.js +27 -0
- package/support/context/config.js.map +1 -0
- package/support/context/websocket.d.ts +22 -0
- package/support/context/websocket.d.ts.map +1 -0
- package/support/context/websocket.js +113 -0
- package/support/context/websocket.js.map +1 -0
- package/support/index.d.ts +39 -0
- package/support/index.d.ts.map +1 -0
- package/support/index.js +43 -0
- package/support/index.js.map +1 -0
- package/support/pages/articles.d.ts +7 -0
- package/support/pages/articles.d.ts.map +1 -0
- package/support/pages/articles.js +39 -0
- package/support/pages/articles.js.map +1 -0
- package/support/pages/conversation-history.d.ts +18 -0
- package/support/pages/conversation-history.d.ts.map +1 -0
- package/support/pages/conversation-history.js +120 -0
- package/support/pages/conversation-history.js.map +1 -0
- package/support/pages/conversation.d.ts +32 -0
- package/support/pages/conversation.d.ts.map +1 -0
- package/support/pages/conversation.js +92 -0
- package/support/pages/conversation.js.map +1 -0
- package/support/pages/home.d.ts +20 -0
- package/support/pages/home.d.ts.map +1 -0
- package/support/pages/home.js +184 -0
- package/support/pages/home.js.map +1 -0
- package/support/router.d.ts +14 -0
- package/support/router.d.ts.map +1 -0
- package/support/router.js +31 -0
- package/support/router.js.map +1 -0
- package/support/store/index.d.ts +2 -0
- package/support/store/index.js +3 -0
- package/support/store/support-store.d.ts +42 -0
- package/support/store/support-store.d.ts.map +1 -0
- package/support/store/support-store.js +66 -0
- package/support/store/support-store.js.map +1 -0
- package/support/support-CMoDLQoC.css +408 -0
- package/support/support-CMoDLQoC.css.map +1 -0
- package/support/support.js +1 -0
- package/support/text/index.d.ts +35 -0
- package/support/text/index.d.ts.map +1 -0
- package/support/text/index.js +71 -0
- package/support/text/index.js.map +1 -0
- package/support/text/locales/en.d.ts +7 -0
- package/support/text/locales/en.d.ts.map +1 -0
- package/support/text/locales/en.js +65 -0
- package/support/text/locales/en.js.map +1 -0
- package/support/text/locales/es.d.ts +7 -0
- package/support/text/locales/es.d.ts.map +1 -0
- package/support/text/locales/es.js +64 -0
- package/support/text/locales/es.js.map +1 -0
- package/support/text/locales/fr.d.ts +7 -0
- package/support/text/locales/fr.d.ts.map +1 -0
- package/support/text/locales/fr.js +64 -0
- package/support/text/locales/fr.js.map +1 -0
- package/support/text/locales/keys.d.ts +216 -0
- package/support/text/locales/keys.d.ts.map +1 -0
- package/support/text/locales/keys.js +54 -0
- package/support/text/locales/keys.js.map +1 -0
- package/support/text/runtime.d.ts +17 -0
- package/support/text/runtime.d.ts.map +1 -0
- package/support/text/runtime.js +156 -0
- package/support/text/runtime.js.map +1 -0
- package/support/utils/index.d.ts +7 -0
- package/support/utils/index.d.ts.map +1 -0
- package/support/utils/index.js +11 -0
- package/support/utils/index.js.map +1 -0
- package/support/utils/time.d.ts +5 -0
- package/support/utils/time.d.ts.map +1 -0
- package/support/utils/time.js +28 -0
- package/support/utils/time.js.map +1 -0
- package/support-config.d.ts +20 -0
- package/support-config.d.ts.map +1 -0
- package/support-config.js +25 -0
- package/support-config.js.map +1 -0
- package/support.css +2 -0
- package/timeline-item.d.ts +133 -0
- package/timeline-item.d.ts.map +1 -0
- package/utils/id.d.ts +6 -0
- package/utils/id.d.ts.map +1 -0
- package/utils/id.js +13 -0
- package/utils/id.js.map +1 -0
- package/utils/index.d.ts +3 -0
- package/utils/index.js +4 -0
- package/utils/text.d.ts +5 -0
- package/utils/text.d.ts.map +1 -0
- package/utils/text.js +9 -0
- package/utils/text.js.map +1 -0
- package/utils/use-render-element.d.ts +22 -0
- package/utils/use-render-element.d.ts.map +1 -0
- package/utils/use-render-element.js +35 -0
- package/utils/use-render-element.js.map +1 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CossistantClient } from "@cossistant/core";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/private/use-rest-client.d.ts
|
|
4
|
+
type UseClientResult = {
|
|
5
|
+
client: CossistantClient;
|
|
6
|
+
error: Error | null;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Creates a memoised `CossistantClient` instance using the provided endpoints
|
|
10
|
+
* and public key. When no key is passed the hook falls back to environment
|
|
11
|
+
* variables and surfaces missing configuration errors through the returned
|
|
12
|
+
* `error` field.
|
|
13
|
+
*/
|
|
14
|
+
declare function useClient(publicKey: string | undefined, apiUrl?: string, wsUrl?: string): UseClientResult;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { UseClientResult, useClient };
|
|
17
|
+
//# sourceMappingURL=use-rest-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-rest-client.d.ts","names":[],"sources":["../../../src/hooks/private/use-rest-client.ts"],"sourcesContent":[],"mappings":";;;KAMY,eAAA;UACH;EADG,KAAA,EAEJ,KAFI,GAAA,IAAe;CAAA;;;;AAW3B;;;iBAAgB,SAAA,kEAIb"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import { useMemo } from "react";
|
|
5
|
+
import { CossistantClient } from "@cossistant/core";
|
|
6
|
+
|
|
7
|
+
//#region src/hooks/private/use-rest-client.ts
|
|
8
|
+
/**
|
|
9
|
+
* Creates a memoised `CossistantClient` instance using the provided endpoints
|
|
10
|
+
* and public key. When no key is passed the hook falls back to environment
|
|
11
|
+
* variables and surfaces missing configuration errors through the returned
|
|
12
|
+
* `error` field.
|
|
13
|
+
*/
|
|
14
|
+
function useClient(publicKey, apiUrl = "https://api.cossistant.com/v1", wsUrl = "wss://api.cossistant.com/ws") {
|
|
15
|
+
return {
|
|
16
|
+
client: useMemo(() => {
|
|
17
|
+
const keyFromEnv = process.env.NEXT_PUBLIC_COSSISTANT_KEY || process.env.COSSISTANT_PUBLIC_KEY;
|
|
18
|
+
const keyToUse = publicKey ?? keyFromEnv;
|
|
19
|
+
if (!keyToUse) throw new Error("Public key is required. Please provide it as a prop or set NEXT_PUBLIC_COSSISTANT_KEY environment variable.");
|
|
20
|
+
const config = {
|
|
21
|
+
apiUrl,
|
|
22
|
+
wsUrl,
|
|
23
|
+
publicKey: keyToUse
|
|
24
|
+
};
|
|
25
|
+
try {
|
|
26
|
+
return new CossistantClient(config);
|
|
27
|
+
} catch (err) {
|
|
28
|
+
throw err instanceof Error ? err : /* @__PURE__ */ new Error("Failed to initialize Cossistant client");
|
|
29
|
+
}
|
|
30
|
+
}, [
|
|
31
|
+
publicKey,
|
|
32
|
+
apiUrl,
|
|
33
|
+
wsUrl
|
|
34
|
+
]),
|
|
35
|
+
error: null
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
//#endregion
|
|
40
|
+
export { useClient };
|
|
41
|
+
//# sourceMappingURL=use-rest-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-rest-client.js","names":["config: CossistantConfig","err: unknown"],"sources":["../../../src/hooks/private/use-rest-client.ts"],"sourcesContent":["\"use client\";\n\nimport { CossistantClient } from \"@cossistant/core\";\nimport type { CossistantConfig } from \"@cossistant/types\";\nimport { useMemo } from \"react\";\n\nexport type UseClientResult = {\n\tclient: CossistantClient;\n\terror: Error | null;\n};\n\n/**\n * Creates a memoised `CossistantClient` instance using the provided endpoints\n * and public key. When no key is passed the hook falls back to environment\n * variables and surfaces missing configuration errors through the returned\n * `error` field.\n */\nexport function useClient(\n\tpublicKey: string | undefined,\n\tapiUrl = \"https://api.cossistant.com/v1\",\n\twsUrl = \"wss://api.cossistant.com/ws\"\n): UseClientResult {\n\tconst client = useMemo(() => {\n\t\tconst keyFromEnv =\n\t\t\tprocess.env.NEXT_PUBLIC_COSSISTANT_KEY ||\n\t\t\tprocess.env.COSSISTANT_PUBLIC_KEY;\n\t\tconst keyToUse = publicKey ?? keyFromEnv;\n\n\t\tif (!keyToUse) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Public key is required. Please provide it as a prop or set NEXT_PUBLIC_COSSISTANT_KEY environment variable.\"\n\t\t\t);\n\t\t}\n\n\t\tconst config: CossistantConfig = {\n\t\t\tapiUrl,\n\t\t\twsUrl,\n\t\t\tpublicKey: keyToUse,\n\t\t};\n\n\t\ttry {\n\t\t\treturn new CossistantClient(config);\n\t\t} catch (err: unknown) {\n\t\t\tthrow err instanceof Error\n\t\t\t\t? err\n\t\t\t\t: new Error(\"Failed to initialize Cossistant client\");\n\t\t}\n\t}, [publicKey, apiUrl, wsUrl]);\n\n\treturn { client, error: null };\n}\n"],"mappings":";;;;;;;;;;;;;AAiBA,SAAgB,UACf,WACA,SAAS,iCACT,QAAQ,+BACU;AA4BlB,QAAO;EAAE,QA3BM,cAAc;GAC5B,MAAM,aACL,QAAQ,IAAI,8BACZ,QAAQ,IAAI;GACb,MAAM,WAAW,aAAa;AAE9B,OAAI,CAAC,SACJ,OAAM,IAAI,MACT,8GACA;GAGF,MAAMA,SAA2B;IAChC;IACA;IACA,WAAW;IACX;AAED,OAAI;AACH,WAAO,IAAI,iBAAiB,OAAO;YAC3BC,KAAc;AACtB,UAAM,eAAe,QAClB,sBACA,IAAI,MAAM,yCAAyC;;KAErD;GAAC;GAAW;GAAQ;GAAM,CAAC;EAEb,OAAO;EAAM"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CossistantClient } from "@cossistant/core";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/private/use-visitor-typing-reporter.d.ts
|
|
4
|
+
type UseVisitorTypingReporterOptions = {
|
|
5
|
+
client: CossistantClient | null;
|
|
6
|
+
conversationId: string | null;
|
|
7
|
+
};
|
|
8
|
+
type UseVisitorTypingReporterResult = {
|
|
9
|
+
handleInputChange: (value: string) => void;
|
|
10
|
+
handleSubmit: () => void;
|
|
11
|
+
stop: () => void;
|
|
12
|
+
};
|
|
13
|
+
declare function useVisitorTypingReporter({
|
|
14
|
+
client,
|
|
15
|
+
conversationId
|
|
16
|
+
}: UseVisitorTypingReporterOptions): UseVisitorTypingReporterResult;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { useVisitorTypingReporter };
|
|
19
|
+
//# sourceMappingURL=use-visitor-typing-reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-visitor-typing-reporter.d.ts","names":[],"sources":["../../../src/hooks/private/use-visitor-typing-reporter.ts"],"sourcesContent":[],"mappings":";;;KAQK,+BAAA;UACI;EADJ,cAAA,EAAA,MAAA,GAAA,IAAA;AACoB,CAAA;AAUzB,KANK,8BAAA,GAMmC;EAAA,iBAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GAAA,IAAA;cACvC,EAAA,GAAA,GAAA,IAAA;MACA,EAAA,GAAA,GAAA,IAAA;;AACoC,iBAHrB,wBAAA,CAGqB;EAAA,MAAA;EAAA;AAAA,CAAA,EAAlC,+BAAkC,CAAA,EAAA,8BAAA"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/private/use-visitor-typing-reporter.ts
|
|
4
|
+
const PREVIEW_MAX_LENGTH = 2e3;
|
|
5
|
+
const SEND_INTERVAL_MS = 800;
|
|
6
|
+
const KEEP_ALIVE_MS = 4e3;
|
|
7
|
+
const STOP_TYPING_DELAY_MS = 2e3;
|
|
8
|
+
function useVisitorTypingReporter({ client, conversationId }) {
|
|
9
|
+
const typingActiveRef = useRef(false);
|
|
10
|
+
const lastSentAtRef = useRef(0);
|
|
11
|
+
const latestPreviewRef = useRef("");
|
|
12
|
+
const keepAliveTimeoutRef = useRef(null);
|
|
13
|
+
const stopTypingTimeoutRef = useRef(null);
|
|
14
|
+
const clearKeepAlive = useCallback(() => {
|
|
15
|
+
if (keepAliveTimeoutRef.current) {
|
|
16
|
+
clearTimeout(keepAliveTimeoutRef.current);
|
|
17
|
+
keepAliveTimeoutRef.current = null;
|
|
18
|
+
}
|
|
19
|
+
}, []);
|
|
20
|
+
const clearStopTypingTimeout = useCallback(() => {
|
|
21
|
+
if (stopTypingTimeoutRef.current) {
|
|
22
|
+
clearTimeout(stopTypingTimeoutRef.current);
|
|
23
|
+
stopTypingTimeoutRef.current = null;
|
|
24
|
+
}
|
|
25
|
+
}, []);
|
|
26
|
+
const sendTyping = useCallback(async (isTyping, preview) => {
|
|
27
|
+
if (!(client && conversationId)) return;
|
|
28
|
+
try {
|
|
29
|
+
await client.setVisitorTyping({
|
|
30
|
+
conversationId,
|
|
31
|
+
isTyping,
|
|
32
|
+
visitorPreview: preview ?? void 0
|
|
33
|
+
});
|
|
34
|
+
} catch (error) {
|
|
35
|
+
console.error("[Support] Failed to send typing event", error);
|
|
36
|
+
}
|
|
37
|
+
}, [client, conversationId]);
|
|
38
|
+
const scheduleKeepAlive = useCallback(() => {
|
|
39
|
+
clearKeepAlive();
|
|
40
|
+
keepAliveTimeoutRef.current = setTimeout(() => {
|
|
41
|
+
if (typingActiveRef.current) {
|
|
42
|
+
sendTyping(true, latestPreviewRef.current);
|
|
43
|
+
scheduleKeepAlive();
|
|
44
|
+
}
|
|
45
|
+
}, KEEP_ALIVE_MS);
|
|
46
|
+
}, [clearKeepAlive, sendTyping]);
|
|
47
|
+
const scheduleStopTyping = useCallback(() => {
|
|
48
|
+
clearStopTypingTimeout();
|
|
49
|
+
stopTypingTimeoutRef.current = setTimeout(() => {
|
|
50
|
+
if (typingActiveRef.current) {
|
|
51
|
+
typingActiveRef.current = false;
|
|
52
|
+
clearKeepAlive();
|
|
53
|
+
sendTyping(false);
|
|
54
|
+
}
|
|
55
|
+
}, STOP_TYPING_DELAY_MS);
|
|
56
|
+
}, [
|
|
57
|
+
clearStopTypingTimeout,
|
|
58
|
+
clearKeepAlive,
|
|
59
|
+
sendTyping
|
|
60
|
+
]);
|
|
61
|
+
const handleInputChange = useCallback((value) => {
|
|
62
|
+
if (!(client && conversationId)) return;
|
|
63
|
+
const trimmed = value.trim();
|
|
64
|
+
latestPreviewRef.current = trimmed.slice(0, PREVIEW_MAX_LENGTH);
|
|
65
|
+
const now = Date.now();
|
|
66
|
+
if (trimmed.length === 0) {
|
|
67
|
+
if (typingActiveRef.current) {
|
|
68
|
+
typingActiveRef.current = false;
|
|
69
|
+
lastSentAtRef.current = now;
|
|
70
|
+
clearKeepAlive();
|
|
71
|
+
clearStopTypingTimeout();
|
|
72
|
+
sendTyping(false);
|
|
73
|
+
}
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
scheduleStopTyping();
|
|
77
|
+
if (!typingActiveRef.current) {
|
|
78
|
+
typingActiveRef.current = true;
|
|
79
|
+
lastSentAtRef.current = now;
|
|
80
|
+
sendTyping(true, latestPreviewRef.current);
|
|
81
|
+
scheduleKeepAlive();
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (now - lastSentAtRef.current >= SEND_INTERVAL_MS) {
|
|
85
|
+
lastSentAtRef.current = now;
|
|
86
|
+
sendTyping(true, latestPreviewRef.current);
|
|
87
|
+
scheduleKeepAlive();
|
|
88
|
+
}
|
|
89
|
+
}, [
|
|
90
|
+
client,
|
|
91
|
+
conversationId,
|
|
92
|
+
sendTyping,
|
|
93
|
+
scheduleKeepAlive,
|
|
94
|
+
scheduleStopTyping,
|
|
95
|
+
clearKeepAlive,
|
|
96
|
+
clearStopTypingTimeout
|
|
97
|
+
]);
|
|
98
|
+
const handleSubmit = useCallback(() => {
|
|
99
|
+
if (!typingActiveRef.current) return;
|
|
100
|
+
typingActiveRef.current = false;
|
|
101
|
+
lastSentAtRef.current = Date.now();
|
|
102
|
+
clearKeepAlive();
|
|
103
|
+
clearStopTypingTimeout();
|
|
104
|
+
sendTyping(false);
|
|
105
|
+
}, [
|
|
106
|
+
clearKeepAlive,
|
|
107
|
+
clearStopTypingTimeout,
|
|
108
|
+
sendTyping
|
|
109
|
+
]);
|
|
110
|
+
const stop = useCallback(() => {
|
|
111
|
+
if (!typingActiveRef.current) return;
|
|
112
|
+
typingActiveRef.current = false;
|
|
113
|
+
lastSentAtRef.current = Date.now();
|
|
114
|
+
clearKeepAlive();
|
|
115
|
+
clearStopTypingTimeout();
|
|
116
|
+
sendTyping(false);
|
|
117
|
+
}, [
|
|
118
|
+
clearKeepAlive,
|
|
119
|
+
clearStopTypingTimeout,
|
|
120
|
+
sendTyping
|
|
121
|
+
]);
|
|
122
|
+
useEffect(() => () => {
|
|
123
|
+
if (typingActiveRef.current) sendTyping(false);
|
|
124
|
+
clearKeepAlive();
|
|
125
|
+
clearStopTypingTimeout();
|
|
126
|
+
}, [
|
|
127
|
+
clearKeepAlive,
|
|
128
|
+
clearStopTypingTimeout,
|
|
129
|
+
sendTyping
|
|
130
|
+
]);
|
|
131
|
+
return {
|
|
132
|
+
handleInputChange,
|
|
133
|
+
handleSubmit,
|
|
134
|
+
stop
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
//#endregion
|
|
139
|
+
export { useVisitorTypingReporter };
|
|
140
|
+
//# sourceMappingURL=use-visitor-typing-reporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-visitor-typing-reporter.js","names":[],"sources":["../../../src/hooks/private/use-visitor-typing-reporter.ts"],"sourcesContent":["import type { CossistantClient } from \"@cossistant/core\";\nimport { useCallback, useEffect, useRef } from \"react\";\n\nconst PREVIEW_MAX_LENGTH = 2000;\nconst SEND_INTERVAL_MS = 800;\nconst KEEP_ALIVE_MS = 4000;\nconst STOP_TYPING_DELAY_MS = 2000; // Send isTyping: false after 2 seconds of inactivity\n\ntype UseVisitorTypingReporterOptions = {\n\tclient: CossistantClient | null;\n\tconversationId: string | null;\n};\n\ntype UseVisitorTypingReporterResult = {\n\thandleInputChange: (value: string) => void;\n\thandleSubmit: () => void;\n\tstop: () => void;\n};\n\nexport function useVisitorTypingReporter({\n\tclient,\n\tconversationId,\n}: UseVisitorTypingReporterOptions): UseVisitorTypingReporterResult {\n\tconst typingActiveRef = useRef(false);\n\tconst lastSentAtRef = useRef(0);\n\tconst latestPreviewRef = useRef<string>(\"\");\n\tconst keepAliveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(\n\t\tnull\n\t);\n\tconst stopTypingTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(\n\t\tnull\n\t);\n\n\tconst clearKeepAlive = useCallback(() => {\n\t\tif (keepAliveTimeoutRef.current) {\n\t\t\tclearTimeout(keepAliveTimeoutRef.current);\n\t\t\tkeepAliveTimeoutRef.current = null;\n\t\t}\n\t}, []);\n\n\tconst clearStopTypingTimeout = useCallback(() => {\n\t\tif (stopTypingTimeoutRef.current) {\n\t\t\tclearTimeout(stopTypingTimeoutRef.current);\n\t\t\tstopTypingTimeoutRef.current = null;\n\t\t}\n\t}, []);\n\n\tconst sendTyping = useCallback(\n\t\tasync (isTyping: boolean, preview?: string | null) => {\n\t\t\tif (!(client && conversationId)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tawait client.setVisitorTyping({\n\t\t\t\t\tconversationId,\n\t\t\t\t\tisTyping,\n\t\t\t\t\tvisitorPreview: preview ?? undefined,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"[Support] Failed to send typing event\", error);\n\t\t\t}\n\t\t},\n\t\t[client, conversationId]\n\t);\n\n\tconst scheduleKeepAlive = useCallback(() => {\n\t\tclearKeepAlive();\n\t\tkeepAliveTimeoutRef.current = setTimeout(() => {\n\t\t\tif (typingActiveRef.current) {\n\t\t\t\tvoid sendTyping(true, latestPreviewRef.current);\n\t\t\t\tscheduleKeepAlive();\n\t\t\t}\n\t\t}, KEEP_ALIVE_MS);\n\t}, [clearKeepAlive, sendTyping]);\n\n\tconst scheduleStopTyping = useCallback(() => {\n\t\tclearStopTypingTimeout();\n\t\tstopTypingTimeoutRef.current = setTimeout(() => {\n\t\t\tif (typingActiveRef.current) {\n\t\t\t\ttypingActiveRef.current = false;\n\t\t\t\tclearKeepAlive();\n\t\t\t\tvoid sendTyping(false);\n\t\t\t}\n\t\t}, STOP_TYPING_DELAY_MS);\n\t}, [clearStopTypingTimeout, clearKeepAlive, sendTyping]);\n\n\tconst handleInputChange = useCallback(\n\t\t(value: string) => {\n\t\t\tif (!(client && conversationId)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst trimmed = value.trim();\n\t\t\tlatestPreviewRef.current = trimmed.slice(0, PREVIEW_MAX_LENGTH);\n\t\t\tconst now = Date.now();\n\n\t\t\tif (trimmed.length === 0) {\n\t\t\t\tif (typingActiveRef.current) {\n\t\t\t\t\ttypingActiveRef.current = false;\n\t\t\t\t\tlastSentAtRef.current = now;\n\t\t\t\t\tclearKeepAlive();\n\t\t\t\t\tclearStopTypingTimeout();\n\t\t\t\t\tvoid sendTyping(false);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Schedule auto-stop after inactivity\n\t\t\tscheduleStopTyping();\n\n\t\t\tif (!typingActiveRef.current) {\n\t\t\t\ttypingActiveRef.current = true;\n\t\t\t\tlastSentAtRef.current = now;\n\t\t\t\tvoid sendTyping(true, latestPreviewRef.current);\n\t\t\t\tscheduleKeepAlive();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (now - lastSentAtRef.current >= SEND_INTERVAL_MS) {\n\t\t\t\tlastSentAtRef.current = now;\n\t\t\t\tvoid sendTyping(true, latestPreviewRef.current);\n\t\t\t\tscheduleKeepAlive();\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\tclient,\n\t\t\tconversationId,\n\t\t\tsendTyping,\n\t\t\tscheduleKeepAlive,\n\t\t\tscheduleStopTyping,\n\t\t\tclearKeepAlive,\n\t\t\tclearStopTypingTimeout,\n\t\t]\n\t);\n\n\tconst handleSubmit = useCallback(() => {\n\t\tif (!typingActiveRef.current) {\n\t\t\treturn;\n\t\t}\n\n\t\ttypingActiveRef.current = false;\n\t\tlastSentAtRef.current = Date.now();\n\t\tclearKeepAlive();\n\t\tclearStopTypingTimeout();\n\t\tvoid sendTyping(false);\n\t}, [clearKeepAlive, clearStopTypingTimeout, sendTyping]);\n\n\tconst stop = useCallback(() => {\n\t\tif (!typingActiveRef.current) {\n\t\t\treturn;\n\t\t}\n\n\t\ttypingActiveRef.current = false;\n\t\tlastSentAtRef.current = Date.now();\n\t\tclearKeepAlive();\n\t\tclearStopTypingTimeout();\n\t\tvoid sendTyping(false);\n\t}, [clearKeepAlive, clearStopTypingTimeout, sendTyping]);\n\n\tuseEffect(\n\t\t() => () => {\n\t\t\tif (typingActiveRef.current) {\n\t\t\t\tvoid sendTyping(false);\n\t\t\t}\n\t\t\tclearKeepAlive();\n\t\t\tclearStopTypingTimeout();\n\t\t},\n\t\t[clearKeepAlive, clearStopTypingTimeout, sendTyping]\n\t);\n\n\treturn {\n\t\thandleInputChange,\n\t\thandleSubmit,\n\t\tstop,\n\t};\n}\n"],"mappings":";;;AAGA,MAAM,qBAAqB;AAC3B,MAAM,mBAAmB;AACzB,MAAM,gBAAgB;AACtB,MAAM,uBAAuB;AAa7B,SAAgB,yBAAyB,EACxC,QACA,kBACmE;CACnE,MAAM,kBAAkB,OAAO,MAAM;CACrC,MAAM,gBAAgB,OAAO,EAAE;CAC/B,MAAM,mBAAmB,OAAe,GAAG;CAC3C,MAAM,sBAAsB,OAC3B,KACA;CACD,MAAM,uBAAuB,OAC5B,KACA;CAED,MAAM,iBAAiB,kBAAkB;AACxC,MAAI,oBAAoB,SAAS;AAChC,gBAAa,oBAAoB,QAAQ;AACzC,uBAAoB,UAAU;;IAE7B,EAAE,CAAC;CAEN,MAAM,yBAAyB,kBAAkB;AAChD,MAAI,qBAAqB,SAAS;AACjC,gBAAa,qBAAqB,QAAQ;AAC1C,wBAAqB,UAAU;;IAE9B,EAAE,CAAC;CAEN,MAAM,aAAa,YAClB,OAAO,UAAmB,YAA4B;AACrD,MAAI,EAAE,UAAU,gBACf;AAGD,MAAI;AACH,SAAM,OAAO,iBAAiB;IAC7B;IACA;IACA,gBAAgB,WAAW;IAC3B,CAAC;WACM,OAAO;AACf,WAAQ,MAAM,yCAAyC,MAAM;;IAG/D,CAAC,QAAQ,eAAe,CACxB;CAED,MAAM,oBAAoB,kBAAkB;AAC3C,kBAAgB;AAChB,sBAAoB,UAAU,iBAAiB;AAC9C,OAAI,gBAAgB,SAAS;AAC5B,IAAK,WAAW,MAAM,iBAAiB,QAAQ;AAC/C,uBAAmB;;KAElB,cAAc;IACf,CAAC,gBAAgB,WAAW,CAAC;CAEhC,MAAM,qBAAqB,kBAAkB;AAC5C,0BAAwB;AACxB,uBAAqB,UAAU,iBAAiB;AAC/C,OAAI,gBAAgB,SAAS;AAC5B,oBAAgB,UAAU;AAC1B,oBAAgB;AAChB,IAAK,WAAW,MAAM;;KAErB,qBAAqB;IACtB;EAAC;EAAwB;EAAgB;EAAW,CAAC;CAExD,MAAM,oBAAoB,aACxB,UAAkB;AAClB,MAAI,EAAE,UAAU,gBACf;EAGD,MAAM,UAAU,MAAM,MAAM;AAC5B,mBAAiB,UAAU,QAAQ,MAAM,GAAG,mBAAmB;EAC/D,MAAM,MAAM,KAAK,KAAK;AAEtB,MAAI,QAAQ,WAAW,GAAG;AACzB,OAAI,gBAAgB,SAAS;AAC5B,oBAAgB,UAAU;AAC1B,kBAAc,UAAU;AACxB,oBAAgB;AAChB,4BAAwB;AACxB,IAAK,WAAW,MAAM;;AAEvB;;AAID,sBAAoB;AAEpB,MAAI,CAAC,gBAAgB,SAAS;AAC7B,mBAAgB,UAAU;AAC1B,iBAAc,UAAU;AACxB,GAAK,WAAW,MAAM,iBAAiB,QAAQ;AAC/C,sBAAmB;AACnB;;AAGD,MAAI,MAAM,cAAc,WAAW,kBAAkB;AACpD,iBAAc,UAAU;AACxB,GAAK,WAAW,MAAM,iBAAiB,QAAQ;AAC/C,sBAAmB;;IAGrB;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA,CACD;CAED,MAAM,eAAe,kBAAkB;AACtC,MAAI,CAAC,gBAAgB,QACpB;AAGD,kBAAgB,UAAU;AAC1B,gBAAc,UAAU,KAAK,KAAK;AAClC,kBAAgB;AAChB,0BAAwB;AACxB,EAAK,WAAW,MAAM;IACpB;EAAC;EAAgB;EAAwB;EAAW,CAAC;CAExD,MAAM,OAAO,kBAAkB;AAC9B,MAAI,CAAC,gBAAgB,QACpB;AAGD,kBAAgB,UAAU;AAC1B,gBAAc,UAAU,KAAK,KAAK;AAClC,kBAAgB;AAChB,0BAAwB;AACxB,EAAK,WAAW,MAAM;IACpB;EAAC;EAAgB;EAAwB;EAAW,CAAC;AAExD,uBACa;AACX,MAAI,gBAAgB,QACnB,CAAK,WAAW,MAAM;AAEvB,kBAAgB;AAChB,0BAAwB;IAEzB;EAAC;EAAgB;EAAwB;EAAW,CACpD;AAED,QAAO;EACN;EACA;EACA;EACA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { MutableRefObject } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/use-composer-refocus.d.ts
|
|
4
|
+
type UseComposerRefocusOptions = {
|
|
5
|
+
disabled: boolean;
|
|
6
|
+
hasContent: boolean;
|
|
7
|
+
isSubmitting: boolean;
|
|
8
|
+
};
|
|
9
|
+
type UseComposerRefocusReturn = {
|
|
10
|
+
focusComposer: () => void;
|
|
11
|
+
inputRef: MutableRefObject<HTMLTextAreaElement | null>;
|
|
12
|
+
};
|
|
13
|
+
declare const useComposerRefocus: ({
|
|
14
|
+
disabled,
|
|
15
|
+
hasContent,
|
|
16
|
+
isSubmitting
|
|
17
|
+
}: UseComposerRefocusOptions) => UseComposerRefocusReturn;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { UseComposerRefocusOptions, UseComposerRefocusReturn, useComposerRefocus };
|
|
20
|
+
//# sourceMappingURL=use-composer-refocus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-composer-refocus.d.ts","names":[],"sources":["../../src/hooks/use-composer-refocus.ts"],"sourcesContent":[],"mappings":";;;KAGY,yBAAA;;EAAA,UAAA,EAAA,OAAA;EAMA,YAAA,EAAA,OAAA;CAAwB;AAER,KAFhB,wBAAA,GAEgB;eAAjB,EAAA,GAAA,GAAA,IAAA;EAAgB,QAAA,EAAhB,gBAAgB,CAAC,mBAAD,GAAA,IAAA,CAAA;AAG3B,CAAA;AAmCC,cAnCY,kBAmCZ,EAAA,CAAA;EAAA,QAAA;EAAA,UAAA;EAAA;AAAA,CAAA,EA/BE,yBA+BF,EAAA,GA/B8B,wBA+B9B"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/use-composer-refocus.ts
|
|
4
|
+
const useComposerRefocus = ({ disabled, hasContent, isSubmitting }) => {
|
|
5
|
+
const inputRef = useRef(null);
|
|
6
|
+
const previousStateRef = useRef({
|
|
7
|
+
isSubmitting,
|
|
8
|
+
hadContent: hasContent
|
|
9
|
+
});
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const previous = previousStateRef.current;
|
|
12
|
+
if (!(disabled || isSubmitting || hasContent) && (previous.isSubmitting || previous.hadContent)) inputRef.current?.focus();
|
|
13
|
+
previousStateRef.current = {
|
|
14
|
+
isSubmitting,
|
|
15
|
+
hadContent: hasContent
|
|
16
|
+
};
|
|
17
|
+
}, [
|
|
18
|
+
disabled,
|
|
19
|
+
hasContent,
|
|
20
|
+
isSubmitting
|
|
21
|
+
]);
|
|
22
|
+
return {
|
|
23
|
+
focusComposer: useCallback(() => {
|
|
24
|
+
inputRef.current?.focus();
|
|
25
|
+
}, []),
|
|
26
|
+
inputRef
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
export { useComposerRefocus };
|
|
32
|
+
//# sourceMappingURL=use-composer-refocus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-composer-refocus.js","names":[],"sources":["../../src/hooks/use-composer-refocus.ts"],"sourcesContent":["import type { MutableRefObject } from \"react\";\nimport { useCallback, useEffect, useRef } from \"react\";\n\nexport type UseComposerRefocusOptions = {\n\tdisabled: boolean;\n\thasContent: boolean;\n\tisSubmitting: boolean;\n};\n\nexport type UseComposerRefocusReturn = {\n\tfocusComposer: () => void;\n\tinputRef: MutableRefObject<HTMLTextAreaElement | null>;\n};\n\nexport const useComposerRefocus = ({\n\tdisabled,\n\thasContent,\n\tisSubmitting,\n}: UseComposerRefocusOptions): UseComposerRefocusReturn => {\n\tconst inputRef = useRef<HTMLTextAreaElement | null>(null);\n\tconst previousStateRef = useRef({\n\t\tisSubmitting,\n\t\thadContent: hasContent,\n\t});\n\n\tuseEffect(() => {\n\t\tconst previous = previousStateRef.current;\n\n\t\tif (\n\t\t\t!(disabled || isSubmitting || hasContent) &&\n\t\t\t(previous.isSubmitting || previous.hadContent)\n\t\t) {\n\t\t\tinputRef.current?.focus();\n\t\t}\n\n\t\tpreviousStateRef.current = {\n\t\t\tisSubmitting,\n\t\t\thadContent: hasContent,\n\t\t};\n\t}, [disabled, hasContent, isSubmitting]);\n\n\tconst focusComposer = useCallback(() => {\n\t\tinputRef.current?.focus();\n\t}, []);\n\n\treturn {\n\t\tfocusComposer,\n\t\tinputRef,\n\t};\n};\n"],"mappings":";;;AAcA,MAAa,sBAAsB,EAClC,UACA,YACA,mBAC0D;CAC1D,MAAM,WAAW,OAAmC,KAAK;CACzD,MAAM,mBAAmB,OAAO;EAC/B;EACA,YAAY;EACZ,CAAC;AAEF,iBAAgB;EACf,MAAM,WAAW,iBAAiB;AAElC,MACC,EAAE,YAAY,gBAAgB,gBAC7B,SAAS,gBAAgB,SAAS,YAEnC,UAAS,SAAS,OAAO;AAG1B,mBAAiB,UAAU;GAC1B;GACA,YAAY;GACZ;IACC;EAAC;EAAU;EAAY;EAAa,CAAC;AAMxC,QAAO;EACN,eALqB,kBAAkB;AACvC,YAAS,SAAS,OAAO;KACvB,EAAE,CAAC;EAIL;EACA"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { TimelineItem } from "../timeline-item.js";
|
|
2
|
+
import { CossistantClient } from "@cossistant/core";
|
|
3
|
+
|
|
4
|
+
//#region src/hooks/use-conversation-auto-seen.d.ts
|
|
5
|
+
declare const CONVERSATION_AUTO_SEEN_DELAY_MS = 2000;
|
|
6
|
+
type UseConversationAutoSeenOptions = {
|
|
7
|
+
/**
|
|
8
|
+
* The Cossistant client instance.
|
|
9
|
+
*/
|
|
10
|
+
client: CossistantClient | null;
|
|
11
|
+
/**
|
|
12
|
+
* The real conversation ID. Pass null if no conversation exists yet.
|
|
13
|
+
*/
|
|
14
|
+
conversationId: string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Current visitor ID.
|
|
17
|
+
*/
|
|
18
|
+
visitorId?: string;
|
|
19
|
+
/**
|
|
20
|
+
* The last timeline item in the conversation.
|
|
21
|
+
* Used to determine if we should mark as seen.
|
|
22
|
+
*/
|
|
23
|
+
lastTimelineItem: TimelineItem | null;
|
|
24
|
+
/**
|
|
25
|
+
* Whether to enable auto-seen tracking.
|
|
26
|
+
* Default: true
|
|
27
|
+
*/
|
|
28
|
+
enabled?: boolean;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Automatically marks timeline items as seen when:
|
|
32
|
+
* - A new timeline item arrives from someone else
|
|
33
|
+
* - The page is visible/focused
|
|
34
|
+
* - The visitor is the current user
|
|
35
|
+
*
|
|
36
|
+
* Also handles:
|
|
37
|
+
* - Fetching and hydrating initial seen data
|
|
38
|
+
* - Preventing duplicate API calls
|
|
39
|
+
* - Page visibility tracking
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```tsx
|
|
43
|
+
* useConversationAutoSeen({
|
|
44
|
+
* client,
|
|
45
|
+
* conversationId: realConversationId,
|
|
46
|
+
* visitorId: visitor?.id,
|
|
47
|
+
* lastTimelineItem: items[items.length - 1] ?? null,
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
declare function useConversationAutoSeen(options: UseConversationAutoSeenOptions): void;
|
|
52
|
+
//#endregion
|
|
53
|
+
export { CONVERSATION_AUTO_SEEN_DELAY_MS, UseConversationAutoSeenOptions, useConversationAutoSeen };
|
|
54
|
+
//# sourceMappingURL=use-conversation-auto-seen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-conversation-auto-seen.d.ts","names":[],"sources":["../../src/hooks/use-conversation-auto-seen.ts"],"sourcesContent":[],"mappings":";;;;cASa,+BAAA;KAED,8BAAA;EAFC;AAEb;;QAIS,EAAA,gBAAA,GAAA,IAAA;;;AA8CT;;;;;;;;;;oBA9BmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8BH,uBAAA,UACN"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { hydrateConversationSeen, upsertConversationSeen } from "../realtime/seen-store.js";
|
|
2
|
+
import { useWindowVisibilityFocus } from "./use-window-visibility-focus.js";
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/hooks/use-conversation-auto-seen.ts
|
|
6
|
+
const CONVERSATION_AUTO_SEEN_DELAY_MS = 2e3;
|
|
7
|
+
/**
|
|
8
|
+
* Automatically marks timeline items as seen when:
|
|
9
|
+
* - A new timeline item arrives from someone else
|
|
10
|
+
* - The page is visible/focused
|
|
11
|
+
* - The visitor is the current user
|
|
12
|
+
*
|
|
13
|
+
* Also handles:
|
|
14
|
+
* - Fetching and hydrating initial seen data
|
|
15
|
+
* - Preventing duplicate API calls
|
|
16
|
+
* - Page visibility tracking
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* useConversationAutoSeen({
|
|
21
|
+
* client,
|
|
22
|
+
* conversationId: realConversationId,
|
|
23
|
+
* visitorId: visitor?.id,
|
|
24
|
+
* lastTimelineItem: items[items.length - 1] ?? null,
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
function useConversationAutoSeen(options) {
|
|
29
|
+
const { client, conversationId, visitorId, lastTimelineItem, enabled = true } = options;
|
|
30
|
+
const lastSeenItemIdRef = useRef(null);
|
|
31
|
+
const markSeenInFlightRef = useRef(false);
|
|
32
|
+
const markSeenTimeoutRef = useRef(null);
|
|
33
|
+
const { isPageVisible, hasWindowFocus } = useWindowVisibilityFocus();
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
lastSeenItemIdRef.current = null;
|
|
36
|
+
markSeenInFlightRef.current = false;
|
|
37
|
+
if (markSeenTimeoutRef.current) {
|
|
38
|
+
clearTimeout(markSeenTimeoutRef.current);
|
|
39
|
+
markSeenTimeoutRef.current = null;
|
|
40
|
+
}
|
|
41
|
+
}, [conversationId]);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (enabled && client && conversationId) client.getConversationSeenData({ conversationId }).then((response) => {
|
|
44
|
+
if (response.seenData.length > 0) hydrateConversationSeen(conversationId, response.seenData);
|
|
45
|
+
}).catch((err) => {
|
|
46
|
+
console.error("Failed to fetch conversation seen data:", err);
|
|
47
|
+
});
|
|
48
|
+
}, [
|
|
49
|
+
enabled,
|
|
50
|
+
client,
|
|
51
|
+
conversationId
|
|
52
|
+
]);
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (markSeenTimeoutRef.current) {
|
|
55
|
+
clearTimeout(markSeenTimeoutRef.current);
|
|
56
|
+
markSeenTimeoutRef.current = null;
|
|
57
|
+
}
|
|
58
|
+
if (!(enabled && client && conversationId && visitorId && lastTimelineItem && isPageVisible && hasWindowFocus)) return;
|
|
59
|
+
if (lastTimelineItem.visitorId === visitorId) {
|
|
60
|
+
lastSeenItemIdRef.current = lastTimelineItem.id || null;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (lastSeenItemIdRef.current === lastTimelineItem.id) return;
|
|
64
|
+
if (markSeenInFlightRef.current) return;
|
|
65
|
+
const pendingItemId = lastTimelineItem.id || null;
|
|
66
|
+
markSeenTimeoutRef.current = setTimeout(() => {
|
|
67
|
+
if (!client || !conversationId) {
|
|
68
|
+
markSeenTimeoutRef.current = null;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
markSeenInFlightRef.current = true;
|
|
72
|
+
client.markConversationSeen({ conversationId }).then((response) => {
|
|
73
|
+
lastSeenItemIdRef.current = pendingItemId;
|
|
74
|
+
upsertConversationSeen({
|
|
75
|
+
conversationId,
|
|
76
|
+
actorType: "visitor",
|
|
77
|
+
actorId: visitorId,
|
|
78
|
+
lastSeenAt: new Date(response.lastSeenAt)
|
|
79
|
+
});
|
|
80
|
+
}).catch((err) => {
|
|
81
|
+
console.error("Failed to mark conversation as seen:", err);
|
|
82
|
+
}).finally(() => {
|
|
83
|
+
markSeenInFlightRef.current = false;
|
|
84
|
+
markSeenTimeoutRef.current = null;
|
|
85
|
+
});
|
|
86
|
+
}, CONVERSATION_AUTO_SEEN_DELAY_MS);
|
|
87
|
+
return () => {
|
|
88
|
+
if (markSeenTimeoutRef.current) {
|
|
89
|
+
clearTimeout(markSeenTimeoutRef.current);
|
|
90
|
+
markSeenTimeoutRef.current = null;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}, [
|
|
94
|
+
enabled,
|
|
95
|
+
client,
|
|
96
|
+
conversationId,
|
|
97
|
+
visitorId,
|
|
98
|
+
lastTimelineItem,
|
|
99
|
+
isPageVisible,
|
|
100
|
+
hasWindowFocus
|
|
101
|
+
]);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
//#endregion
|
|
105
|
+
export { CONVERSATION_AUTO_SEEN_DELAY_MS, useConversationAutoSeen };
|
|
106
|
+
//# sourceMappingURL=use-conversation-auto-seen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-conversation-auto-seen.js","names":[],"sources":["../../src/hooks/use-conversation-auto-seen.ts"],"sourcesContent":["import type { CossistantClient } from \"@cossistant/core\";\nimport type { TimelineItem } from \"@cossistant/types/api/timeline-item\";\nimport { useEffect, useRef } from \"react\";\nimport {\n hydrateConversationSeen,\n upsertConversationSeen,\n} from \"../realtime/seen-store\";\nimport { useWindowVisibilityFocus } from \"./use-window-visibility-focus\";\n\nexport const CONVERSATION_AUTO_SEEN_DELAY_MS = 2000;\n\nexport type UseConversationAutoSeenOptions = {\n\t/**\n\t * The Cossistant client instance.\n\t */\n\tclient: CossistantClient | null;\n\n\t/**\n\t * The real conversation ID. Pass null if no conversation exists yet.\n\t */\n\tconversationId: string | null;\n\n\t/**\n\t * Current visitor ID.\n\t */\n\tvisitorId?: string;\n\n\t/**\n\t * The last timeline item in the conversation.\n\t * Used to determine if we should mark as seen.\n\t */\n\tlastTimelineItem: TimelineItem | null;\n\n\t/**\n\t * Whether to enable auto-seen tracking.\n\t * Default: true\n\t */\n\tenabled?: boolean;\n};\n\n/**\n * Automatically marks timeline items as seen when:\n * - A new timeline item arrives from someone else\n * - The page is visible/focused\n * - The visitor is the current user\n *\n * Also handles:\n * - Fetching and hydrating initial seen data\n * - Preventing duplicate API calls\n * - Page visibility tracking\n *\n * @example\n * ```tsx\n * useConversationAutoSeen({\n * client,\n * conversationId: realConversationId,\n * visitorId: visitor?.id,\n * lastTimelineItem: items[items.length - 1] ?? null,\n * });\n * ```\n */\nexport function useConversationAutoSeen(\n\toptions: UseConversationAutoSeenOptions\n): void {\n\tconst {\n\t\tclient,\n\t\tconversationId,\n\t\tvisitorId,\n\t\tlastTimelineItem,\n\t\tenabled = true,\n\t} = options;\n\n const lastSeenItemIdRef = useRef<string | null>(null);\n const markSeenInFlightRef = useRef(false);\n const markSeenTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const { isPageVisible, hasWindowFocus } = useWindowVisibilityFocus();\n\n // Reset seen tracking when conversation changes\n useEffect(() => {\n lastSeenItemIdRef.current = null;\n markSeenInFlightRef.current = false;\n if (markSeenTimeoutRef.current) {\n clearTimeout(markSeenTimeoutRef.current);\n markSeenTimeoutRef.current = null;\n }\n }, [conversationId]);\n\n\t// Fetch and hydrate initial seen data when conversation loads\n\tuseEffect(() => {\n\t\tif (enabled && client && conversationId) {\n\t\t\tvoid client\n\t\t\t\t.getConversationSeenData({ conversationId })\n\t\t\t\t.then((response) => {\n\t\t\t\t\tif (response.seenData.length > 0) {\n\t\t\t\t\t\thydrateConversationSeen(conversationId, response.seenData);\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tconsole.error(\"Failed to fetch conversation seen data:\", err);\n\t\t\t\t});\n\t\t}\n\t}, [enabled, client, conversationId]);\n\n // Auto-mark timeline items as seen\n useEffect(() => {\n if (markSeenTimeoutRef.current) {\n clearTimeout(markSeenTimeoutRef.current);\n markSeenTimeoutRef.current = null;\n }\n\n const shouldMark =\n enabled &&\n client &&\n conversationId &&\n visitorId &&\n lastTimelineItem &&\n isPageVisible &&\n hasWindowFocus;\n\n if (!shouldMark) {\n return;\n }\n\n // Don't mark our own timeline items as seen via API (we already know we saw them)\n if (lastTimelineItem.visitorId === visitorId) {\n lastSeenItemIdRef.current = lastTimelineItem.id || null;\n return;\n }\n\n // Already marked this item\n if (lastSeenItemIdRef.current === lastTimelineItem.id) {\n return;\n }\n\n // Already in flight\n if (markSeenInFlightRef.current) {\n return;\n }\n\n const pendingItemId = lastTimelineItem.id || null;\n\n markSeenTimeoutRef.current = setTimeout(() => {\n if (!client || !conversationId) {\n markSeenTimeoutRef.current = null;\n return;\n }\n\n markSeenInFlightRef.current = true;\n\n client\n .markConversationSeen({ conversationId })\n .then((response) => {\n lastSeenItemIdRef.current = pendingItemId;\n\n // Optimistically update local seen store\n upsertConversationSeen({\n conversationId,\n actorType: \"visitor\",\n actorId: visitorId,\n lastSeenAt: new Date(response.lastSeenAt),\n });\n })\n .catch((err) => {\n console.error(\"Failed to mark conversation as seen:\", err);\n })\n .finally(() => {\n markSeenInFlightRef.current = false;\n markSeenTimeoutRef.current = null;\n });\n }, CONVERSATION_AUTO_SEEN_DELAY_MS);\n\n return () => {\n if (markSeenTimeoutRef.current) {\n clearTimeout(markSeenTimeoutRef.current);\n markSeenTimeoutRef.current = null;\n }\n };\n }, [\n enabled,\n client,\n conversationId,\n visitorId,\n lastTimelineItem,\n isPageVisible,\n hasWindowFocus,\n ]);\n}\n"],"mappings":";;;;;AASA,MAAa,kCAAkC;;;;;;;;;;;;;;;;;;;;;;AAoD/C,SAAgB,wBACf,SACO;CACP,MAAM,EACL,QACA,gBACA,WACA,kBACA,UAAU,SACP;CAEG,MAAM,oBAAoB,OAAsB,KAAK;CACrD,MAAM,sBAAsB,OAAO,MAAM;CACzC,MAAM,qBAAqB,OAA6C,KAAK;CAC7E,MAAM,EAAE,eAAe,mBAAmB,0BAA0B;AAGpE,iBAAgB;AACR,oBAAkB,UAAU;AAC5B,sBAAoB,UAAU;AAC9B,MAAI,mBAAmB,SAAS;AACxB,gBAAa,mBAAmB,QAAQ;AACxC,sBAAmB,UAAU;;IAE1C,CAAC,eAAe,CAAC;AAG3B,iBAAgB;AACf,MAAI,WAAW,UAAU,eACxB,CAAK,OACH,wBAAwB,EAAE,gBAAgB,CAAC,CAC3C,MAAM,aAAa;AACnB,OAAI,SAAS,SAAS,SAAS,EAC9B,yBAAwB,gBAAgB,SAAS,SAAS;IAE1D,CACD,OAAO,QAAQ;AACf,WAAQ,MAAM,2CAA2C,IAAI;IAC5D;IAEF;EAAC;EAAS;EAAQ;EAAe,CAAC;AAG9B,iBAAgB;AACR,MAAI,mBAAmB,SAAS;AACxB,gBAAa,mBAAmB,QAAQ;AACxC,sBAAmB,UAAU;;AAYrC,MAAI,EARI,WACA,UACA,kBACA,aACA,oBACA,iBACA,gBAGA;AAIR,MAAI,iBAAiB,cAAc,WAAW;AACtC,qBAAkB,UAAU,iBAAiB,MAAM;AACnD;;AAIR,MAAI,kBAAkB,YAAY,iBAAiB,GAC3C;AAIR,MAAI,oBAAoB,QAChB;EAGR,MAAM,gBAAgB,iBAAiB,MAAM;AAE7C,qBAAmB,UAAU,iBAAiB;AACtC,OAAI,CAAC,UAAU,CAAC,gBAAgB;AACxB,uBAAmB,UAAU;AAC7B;;AAGR,uBAAoB,UAAU;AAE9B,UACS,qBAAqB,EAAE,gBAAgB,CAAC,CACxC,MAAM,aAAa;AACZ,sBAAkB,UAAU;AAG5B,2BAAuB;KACf;KACA,WAAW;KACX,SAAS;KACT,YAAY,IAAI,KAAK,SAAS,WAAW;KAChD,CAAC;KACR,CACD,OAAO,QAAQ;AACR,YAAQ,MAAM,wCAAwC,IAAI;KAChE,CACD,cAAc;AACP,wBAAoB,UAAU;AAC9B,uBAAmB,UAAU;KACnC;KACf,gCAAgC;AAEnC,eAAa;AACL,OAAI,mBAAmB,SAAS;AACxB,iBAAa,mBAAmB,QAAQ;AACxC,uBAAmB,UAAU;;;IAGlD;EACK;EACA;EACA;EACA;EACA;EACA;EACA;EACP,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Conversation } from "@cossistant/types";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/use-conversation-history-page.d.ts
|
|
4
|
+
type UseConversationHistoryPageOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* Initial number of conversations to display.
|
|
7
|
+
* Default: 4
|
|
8
|
+
*/
|
|
9
|
+
initialVisibleCount?: number;
|
|
10
|
+
/**
|
|
11
|
+
* Whether to enable conversations fetching.
|
|
12
|
+
* Default: true
|
|
13
|
+
*/
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Callback when user wants to open a conversation.
|
|
17
|
+
*/
|
|
18
|
+
onOpenConversation?: (conversationId: string) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Callback when user wants to start a new conversation.
|
|
21
|
+
*/
|
|
22
|
+
onStartConversation?: (initialMessage?: string) => void;
|
|
23
|
+
};
|
|
24
|
+
type UseConversationHistoryPageReturn = {
|
|
25
|
+
conversations: Conversation[];
|
|
26
|
+
isLoading: boolean;
|
|
27
|
+
error: Error | null;
|
|
28
|
+
visibleConversations: Conversation[];
|
|
29
|
+
visibleCount: number;
|
|
30
|
+
hasMore: boolean;
|
|
31
|
+
remainingCount: number;
|
|
32
|
+
showMore: () => void;
|
|
33
|
+
showAll: () => void;
|
|
34
|
+
openConversation: (conversationId: string) => void;
|
|
35
|
+
startConversation: (initialMessage?: string) => void;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Main hook for the conversation history page.
|
|
39
|
+
*
|
|
40
|
+
* This hook:
|
|
41
|
+
* - Fetches all conversations
|
|
42
|
+
* - Manages pagination/visible count
|
|
43
|
+
* - Provides navigation actions
|
|
44
|
+
*
|
|
45
|
+
* It encapsulates all conversation history logic, making the component
|
|
46
|
+
* purely presentational.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```tsx
|
|
50
|
+
* export function ConversationHistoryPage() {
|
|
51
|
+
* const history = useConversationHistoryPage({
|
|
52
|
+
* initialVisibleCount: 4,
|
|
53
|
+
* onOpenConversation: (id) => {
|
|
54
|
+
* navigate('conversation', { conversationId: id });
|
|
55
|
+
* },
|
|
56
|
+
* onStartConversation: (msg) => {
|
|
57
|
+
* navigate('conversation', { conversationId: PENDING_CONVERSATION_ID, initialMessage: msg });
|
|
58
|
+
* },
|
|
59
|
+
* });
|
|
60
|
+
*
|
|
61
|
+
* return (
|
|
62
|
+
* <>
|
|
63
|
+
* <h1>Conversation History</h1>
|
|
64
|
+
*
|
|
65
|
+
* {history.hasMore && (
|
|
66
|
+
* <button onClick={history.showAll}>
|
|
67
|
+
* +{history.remainingCount} more
|
|
68
|
+
* </button>
|
|
69
|
+
* )}
|
|
70
|
+
*
|
|
71
|
+
* <ul>
|
|
72
|
+
* {history.visibleConversations.map(conv => (
|
|
73
|
+
* <li key={conv.id} onClick={() => history.openConversation(conv.id)}>
|
|
74
|
+
* {conv.title}
|
|
75
|
+
* </li>
|
|
76
|
+
* ))}
|
|
77
|
+
* </ul>
|
|
78
|
+
* </>
|
|
79
|
+
* );
|
|
80
|
+
* }
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
declare function useConversationHistoryPage(options?: UseConversationHistoryPageOptions): UseConversationHistoryPageReturn;
|
|
84
|
+
//#endregion
|
|
85
|
+
export { UseConversationHistoryPageOptions, UseConversationHistoryPageReturn, useConversationHistoryPage };
|
|
86
|
+
//# sourceMappingURL=use-conversation-history-page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-conversation-history-page.d.ts","names":[],"sources":["../../src/hooks/use-conversation-history-page.ts"],"sourcesContent":[],"mappings":";;;KAIY,iCAAA;;AAAZ;AAwBA;;qBAEgB,CAAA,EAAA,MAAA;;;;AA+DhB;EAA0C,OAAA,CAAA,EAAA,OAAA;;;;;;;;;;KAjE9B,gCAAA;iBAEI;;SAER;wBAGe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0DP,0BAAA,WACN,oCACP"}
|