@webority/mobile-chat 0.128.0 → 0.133.0

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.
Files changed (256) hide show
  1. package/lib/commonjs/AgentByline.js +1 -0
  2. package/lib/commonjs/ChatComposer.js +1 -0
  3. package/lib/commonjs/ChatConversationActions.js +1 -0
  4. package/lib/commonjs/ChatDictationButton.js +1 -0
  5. package/lib/commonjs/ChatEmbed.js +1 -0
  6. package/lib/commonjs/ChatEntrance.js +1 -0
  7. package/lib/commonjs/ChatFooter.js +1 -0
  8. package/lib/commonjs/ChatFrame.js +1 -0
  9. package/lib/commonjs/ChatHistory.js +1 -0
  10. package/lib/commonjs/ChatLiveBar.js +1 -0
  11. package/lib/commonjs/ChatMessageActions.js +1 -0
  12. package/lib/commonjs/ChatNudge.js +1 -0
  13. package/lib/commonjs/ChatOpenTickets.js +1 -0
  14. package/lib/commonjs/ChatScreen.js +1 -0
  15. package/lib/commonjs/ChatSheet.js +1 -0
  16. package/lib/commonjs/ChatStarters.js +1 -0
  17. package/lib/commonjs/ChatThread.js +1 -0
  18. package/lib/commonjs/ReadAloudButton.js +1 -0
  19. package/lib/commonjs/chatShared.js +1 -0
  20. package/lib/commonjs/features.map.json +40 -0
  21. package/lib/commonjs/index.js +1 -1
  22. package/lib/commonjs/loaders/ChatLoader.js +1 -0
  23. package/lib/commonjs/loaders/OrbLoader.js +1 -0
  24. package/lib/commonjs/loaders/PhrasesLoader.js +1 -0
  25. package/lib/commonjs/loaders/SkeletonLoader.js +1 -0
  26. package/lib/commonjs/loaders/StepsLoader.js +1 -0
  27. package/lib/commonjs/loaders/TypingPill.js +1 -0
  28. package/lib/commonjs/pushOpen.js +1 -0
  29. package/lib/commonjs/renderers/ActionPart.js +1 -0
  30. package/lib/commonjs/renderers/ChartPart.js +1 -0
  31. package/lib/commonjs/renderers/FigureText.js +1 -0
  32. package/lib/commonjs/renderers/FiguresPart.js +1 -0
  33. package/lib/commonjs/renderers/FilePart.js +1 -0
  34. package/lib/commonjs/renderers/HandoffPart.js +1 -0
  35. package/lib/commonjs/renderers/ImagePart.js +1 -0
  36. package/lib/commonjs/renderers/InputRequestPart.js +1 -0
  37. package/lib/commonjs/renderers/NoticePart.js +1 -0
  38. package/lib/commonjs/renderers/QuickRepliesPart.js +1 -0
  39. package/lib/commonjs/renderers/RecordCardPart.js +1 -0
  40. package/lib/commonjs/renderers/SourcesPart.js +1 -0
  41. package/lib/commonjs/renderers/TablePart.js +1 -0
  42. package/lib/commonjs/renderers/TextPart.js +1 -0
  43. package/lib/commonjs/renderers/TicketPart.js +1 -0
  44. package/lib/commonjs/renderers/VoiceClipPart.js +1 -0
  45. package/lib/commonjs/renderers/index.js +1 -0
  46. package/lib/commonjs/speech/azureSpeech.js +1 -0
  47. package/lib/commonjs/speech/expoAudio.js +1 -0
  48. package/lib/commonjs/speech/phoneSpeech.js +1 -0
  49. package/lib/commonjs/speech/speechText.js +1 -0
  50. package/lib/commonjs/types.js +1 -0
  51. package/lib/commonjs/useChat.js +1 -1
  52. package/lib/commonjs/useChatHaptics.js +1 -0
  53. package/lib/commonjs/useChatSpeech.js +1 -0
  54. package/lib/commonjs/useTranscriptActions.js +1 -0
  55. package/lib/module/AgentByline.js +1 -0
  56. package/lib/module/ChatComposer.js +1 -0
  57. package/lib/module/ChatConversationActions.js +1 -0
  58. package/lib/module/ChatDictationButton.js +1 -0
  59. package/lib/module/ChatEmbed.js +1 -0
  60. package/lib/module/ChatEntrance.js +1 -0
  61. package/lib/module/ChatFooter.js +1 -0
  62. package/lib/module/ChatFrame.js +1 -0
  63. package/lib/module/ChatHistory.js +1 -0
  64. package/lib/module/ChatLiveBar.js +1 -0
  65. package/lib/module/ChatMessageActions.js +1 -0
  66. package/lib/module/ChatNudge.js +1 -0
  67. package/lib/module/ChatOpenTickets.js +1 -0
  68. package/lib/module/ChatScreen.js +1 -0
  69. package/lib/module/ChatSheet.js +1 -0
  70. package/lib/module/ChatStarters.js +1 -0
  71. package/lib/module/ChatThread.js +1 -0
  72. package/lib/module/ReadAloudButton.js +1 -0
  73. package/lib/module/chatShared.js +1 -0
  74. package/lib/module/features.map.json +40 -0
  75. package/lib/module/index.js +1 -1
  76. package/lib/module/loaders/ChatLoader.js +1 -0
  77. package/lib/module/loaders/OrbLoader.js +1 -0
  78. package/lib/module/loaders/PhrasesLoader.js +1 -0
  79. package/lib/module/loaders/SkeletonLoader.js +1 -0
  80. package/lib/module/loaders/StepsLoader.js +1 -0
  81. package/lib/module/loaders/TypingPill.js +1 -0
  82. package/lib/module/pushOpen.js +1 -0
  83. package/lib/module/renderers/ActionPart.js +1 -0
  84. package/lib/module/renderers/ChartPart.js +1 -0
  85. package/lib/module/renderers/FigureText.js +1 -0
  86. package/lib/module/renderers/FiguresPart.js +1 -0
  87. package/lib/module/renderers/FilePart.js +1 -0
  88. package/lib/module/renderers/HandoffPart.js +1 -0
  89. package/lib/module/renderers/ImagePart.js +1 -0
  90. package/lib/module/renderers/InputRequestPart.js +1 -0
  91. package/lib/module/renderers/NoticePart.js +1 -0
  92. package/lib/module/renderers/QuickRepliesPart.js +1 -0
  93. package/lib/module/renderers/RecordCardPart.js +1 -0
  94. package/lib/module/renderers/SourcesPart.js +1 -0
  95. package/lib/module/renderers/TablePart.js +1 -0
  96. package/lib/module/renderers/TextPart.js +1 -0
  97. package/lib/module/renderers/TicketPart.js +1 -0
  98. package/lib/module/renderers/VoiceClipPart.js +1 -0
  99. package/lib/module/renderers/index.js +1 -0
  100. package/lib/module/speech/azureSpeech.js +1 -0
  101. package/lib/module/speech/expoAudio.js +1 -0
  102. package/lib/module/speech/phoneSpeech.js +1 -0
  103. package/lib/module/speech/speechText.js +1 -0
  104. package/lib/module/types.js +1 -0
  105. package/lib/module/useChat.js +1 -1
  106. package/lib/module/useChatHaptics.js +1 -0
  107. package/lib/module/useChatSpeech.js +1 -0
  108. package/lib/module/useTranscriptActions.js +1 -0
  109. package/lib/typescript/commonjs/AgentByline.d.ts +9 -0
  110. package/lib/typescript/commonjs/ChatComposer.d.ts +14 -0
  111. package/lib/typescript/commonjs/ChatConversationActions.d.ts +10 -0
  112. package/lib/typescript/commonjs/ChatDictationButton.d.ts +17 -0
  113. package/lib/typescript/commonjs/ChatEmbed.d.ts +11 -0
  114. package/lib/typescript/commonjs/ChatEntrance.d.ts +8 -0
  115. package/lib/typescript/commonjs/ChatFooter.d.ts +9 -0
  116. package/lib/typescript/commonjs/ChatFrame.d.ts +39 -0
  117. package/lib/typescript/commonjs/ChatHistory.d.ts +11 -0
  118. package/lib/typescript/commonjs/ChatLiveBar.d.ts +11 -0
  119. package/lib/typescript/commonjs/ChatMessageActions.d.ts +15 -0
  120. package/lib/typescript/commonjs/ChatNudge.d.ts +14 -0
  121. package/lib/typescript/commonjs/ChatOpenTickets.d.ts +12 -0
  122. package/lib/typescript/commonjs/ChatScreen.d.ts +5 -0
  123. package/lib/typescript/commonjs/ChatSheet.d.ts +21 -0
  124. package/lib/typescript/commonjs/ChatStarters.d.ts +12 -0
  125. package/lib/typescript/commonjs/ChatThread.d.ts +34 -0
  126. package/lib/typescript/commonjs/ReadAloudButton.d.ts +11 -0
  127. package/lib/typescript/commonjs/chatShared.d.ts +4 -0
  128. package/lib/typescript/commonjs/index.d.ts +26 -21
  129. package/lib/typescript/commonjs/loaders/ChatLoader.d.ts +13 -0
  130. package/lib/typescript/commonjs/loaders/OrbLoader.d.ts +8 -0
  131. package/lib/typescript/commonjs/loaders/PhrasesLoader.d.ts +8 -0
  132. package/lib/typescript/commonjs/loaders/SkeletonLoader.d.ts +8 -0
  133. package/lib/typescript/commonjs/loaders/StepsLoader.d.ts +8 -0
  134. package/lib/typescript/commonjs/loaders/TypingPill.d.ts +7 -0
  135. package/lib/typescript/commonjs/pushOpen.d.ts +3 -0
  136. package/lib/typescript/commonjs/renderers/ActionPart.d.ts +3 -0
  137. package/lib/typescript/commonjs/renderers/ChartPart.d.ts +8 -0
  138. package/lib/typescript/commonjs/renderers/FigureText.d.ts +21 -0
  139. package/lib/typescript/commonjs/renderers/FiguresPart.d.ts +8 -0
  140. package/lib/typescript/commonjs/renderers/FilePart.d.ts +3 -0
  141. package/lib/typescript/commonjs/renderers/HandoffPart.d.ts +9 -0
  142. package/lib/typescript/commonjs/renderers/ImagePart.d.ts +8 -0
  143. package/lib/typescript/commonjs/renderers/InputRequestPart.d.ts +3 -0
  144. package/lib/typescript/commonjs/renderers/NoticePart.d.ts +8 -0
  145. package/lib/typescript/commonjs/renderers/QuickRepliesPart.d.ts +8 -0
  146. package/lib/typescript/commonjs/renderers/RecordCardPart.d.ts +8 -0
  147. package/lib/typescript/commonjs/renderers/SourcesPart.d.ts +8 -0
  148. package/lib/typescript/commonjs/renderers/TablePart.d.ts +8 -0
  149. package/lib/typescript/commonjs/renderers/TextPart.d.ts +8 -0
  150. package/lib/typescript/commonjs/renderers/TicketPart.d.ts +9 -0
  151. package/lib/typescript/commonjs/renderers/VoiceClipPart.d.ts +9 -0
  152. package/lib/typescript/commonjs/renderers/index.d.ts +3 -0
  153. package/lib/typescript/commonjs/speech/azureSpeech.d.ts +25 -0
  154. package/lib/typescript/commonjs/speech/expoAudio.d.ts +23 -0
  155. package/lib/typescript/commonjs/speech/phoneSpeech.d.ts +16 -0
  156. package/lib/typescript/commonjs/speech/speechText.d.ts +16 -0
  157. package/lib/typescript/commonjs/types.d.ts +21 -0
  158. package/lib/typescript/commonjs/useChat.d.ts +38 -10
  159. package/lib/typescript/commonjs/useChatHaptics.d.ts +3 -0
  160. package/lib/typescript/commonjs/useChatSpeech.d.ts +4 -0
  161. package/lib/typescript/commonjs/useTranscriptActions.d.ts +10 -0
  162. package/lib/typescript/module/AgentByline.d.ts +9 -0
  163. package/lib/typescript/module/ChatComposer.d.ts +14 -0
  164. package/lib/typescript/module/ChatConversationActions.d.ts +10 -0
  165. package/lib/typescript/module/ChatDictationButton.d.ts +17 -0
  166. package/lib/typescript/module/ChatEmbed.d.ts +11 -0
  167. package/lib/typescript/module/ChatEntrance.d.ts +8 -0
  168. package/lib/typescript/module/ChatFooter.d.ts +9 -0
  169. package/lib/typescript/module/ChatFrame.d.ts +39 -0
  170. package/lib/typescript/module/ChatHistory.d.ts +11 -0
  171. package/lib/typescript/module/ChatLiveBar.d.ts +11 -0
  172. package/lib/typescript/module/ChatMessageActions.d.ts +15 -0
  173. package/lib/typescript/module/ChatNudge.d.ts +14 -0
  174. package/lib/typescript/module/ChatOpenTickets.d.ts +12 -0
  175. package/lib/typescript/module/ChatScreen.d.ts +5 -0
  176. package/lib/typescript/module/ChatSheet.d.ts +21 -0
  177. package/lib/typescript/module/ChatStarters.d.ts +12 -0
  178. package/lib/typescript/module/ChatThread.d.ts +34 -0
  179. package/lib/typescript/module/ReadAloudButton.d.ts +11 -0
  180. package/lib/typescript/module/chatShared.d.ts +4 -0
  181. package/lib/typescript/module/index.d.ts +26 -21
  182. package/lib/typescript/module/loaders/ChatLoader.d.ts +13 -0
  183. package/lib/typescript/module/loaders/OrbLoader.d.ts +8 -0
  184. package/lib/typescript/module/loaders/PhrasesLoader.d.ts +8 -0
  185. package/lib/typescript/module/loaders/SkeletonLoader.d.ts +8 -0
  186. package/lib/typescript/module/loaders/StepsLoader.d.ts +8 -0
  187. package/lib/typescript/module/loaders/TypingPill.d.ts +7 -0
  188. package/lib/typescript/module/pushOpen.d.ts +3 -0
  189. package/lib/typescript/module/renderers/ActionPart.d.ts +3 -0
  190. package/lib/typescript/module/renderers/ChartPart.d.ts +8 -0
  191. package/lib/typescript/module/renderers/FigureText.d.ts +21 -0
  192. package/lib/typescript/module/renderers/FiguresPart.d.ts +8 -0
  193. package/lib/typescript/module/renderers/FilePart.d.ts +3 -0
  194. package/lib/typescript/module/renderers/HandoffPart.d.ts +9 -0
  195. package/lib/typescript/module/renderers/ImagePart.d.ts +8 -0
  196. package/lib/typescript/module/renderers/InputRequestPart.d.ts +3 -0
  197. package/lib/typescript/module/renderers/NoticePart.d.ts +8 -0
  198. package/lib/typescript/module/renderers/QuickRepliesPart.d.ts +8 -0
  199. package/lib/typescript/module/renderers/RecordCardPart.d.ts +8 -0
  200. package/lib/typescript/module/renderers/SourcesPart.d.ts +8 -0
  201. package/lib/typescript/module/renderers/TablePart.d.ts +8 -0
  202. package/lib/typescript/module/renderers/TextPart.d.ts +8 -0
  203. package/lib/typescript/module/renderers/TicketPart.d.ts +9 -0
  204. package/lib/typescript/module/renderers/VoiceClipPart.d.ts +9 -0
  205. package/lib/typescript/module/renderers/index.d.ts +3 -0
  206. package/lib/typescript/module/speech/azureSpeech.d.ts +25 -0
  207. package/lib/typescript/module/speech/expoAudio.d.ts +23 -0
  208. package/lib/typescript/module/speech/phoneSpeech.d.ts +16 -0
  209. package/lib/typescript/module/speech/speechText.d.ts +16 -0
  210. package/lib/typescript/module/types.d.ts +21 -0
  211. package/lib/typescript/module/useChat.d.ts +38 -10
  212. package/lib/typescript/module/useChatHaptics.d.ts +3 -0
  213. package/lib/typescript/module/useChatSpeech.d.ts +4 -0
  214. package/lib/typescript/module/useTranscriptActions.d.ts +10 -0
  215. package/package.json +42 -15
  216. package/README.md +0 -185
  217. package/lib/commonjs/components/ActionCard.js +0 -1
  218. package/lib/commonjs/components/ChatComposer.js +0 -1
  219. package/lib/commonjs/components/ChatConversationList.js +0 -1
  220. package/lib/commonjs/components/ChatLauncher.js +0 -1
  221. package/lib/commonjs/components/ChatMarkdown.js +0 -1
  222. package/lib/commonjs/components/ChatMessage.js +0 -1
  223. package/lib/commonjs/components/ChatScreen.js +0 -1
  224. package/lib/commonjs/components/ChatThread.js +0 -1
  225. package/lib/commonjs/components/ComposerAttachments.js +0 -1
  226. package/lib/commonjs/components/ReplyRating.js +0 -1
  227. package/lib/module/components/ActionCard.js +0 -1
  228. package/lib/module/components/ChatComposer.js +0 -1
  229. package/lib/module/components/ChatConversationList.js +0 -1
  230. package/lib/module/components/ChatLauncher.js +0 -1
  231. package/lib/module/components/ChatMarkdown.js +0 -1
  232. package/lib/module/components/ChatMessage.js +0 -1
  233. package/lib/module/components/ChatScreen.js +0 -1
  234. package/lib/module/components/ChatThread.js +0 -1
  235. package/lib/module/components/ComposerAttachments.js +0 -1
  236. package/lib/module/components/ReplyRating.js +0 -1
  237. package/lib/typescript/commonjs/components/ActionCard.d.ts +0 -23
  238. package/lib/typescript/commonjs/components/ChatComposer.d.ts +0 -42
  239. package/lib/typescript/commonjs/components/ChatConversationList.d.ts +0 -22
  240. package/lib/typescript/commonjs/components/ChatLauncher.d.ts +0 -22
  241. package/lib/typescript/commonjs/components/ChatMarkdown.d.ts +0 -24
  242. package/lib/typescript/commonjs/components/ChatMessage.d.ts +0 -55
  243. package/lib/typescript/commonjs/components/ChatScreen.d.ts +0 -40
  244. package/lib/typescript/commonjs/components/ChatThread.d.ts +0 -30
  245. package/lib/typescript/commonjs/components/ComposerAttachments.d.ts +0 -12
  246. package/lib/typescript/commonjs/components/ReplyRating.d.ts +0 -19
  247. package/lib/typescript/module/components/ActionCard.d.ts +0 -23
  248. package/lib/typescript/module/components/ChatComposer.d.ts +0 -42
  249. package/lib/typescript/module/components/ChatConversationList.d.ts +0 -22
  250. package/lib/typescript/module/components/ChatLauncher.d.ts +0 -22
  251. package/lib/typescript/module/components/ChatMarkdown.d.ts +0 -24
  252. package/lib/typescript/module/components/ChatMessage.d.ts +0 -55
  253. package/lib/typescript/module/components/ChatScreen.d.ts +0 -40
  254. package/lib/typescript/module/components/ChatThread.d.ts +0 -30
  255. package/lib/typescript/module/components/ComposerAttachments.d.ts +0 -12
  256. package/lib/typescript/module/components/ReplyRating.d.ts +0 -19
@@ -0,0 +1,16 @@
1
+ export declare const DEFAULT_SPEECH_LANGUAGE = "en-IN";
2
+ export declare const DEFAULT_SPEECH_VOICE = "en-IN-NeerjaNeural";
3
+ export declare const MAX_SPEAK_CHARS = 4000;
4
+ export declare const MAX_DICTATION_MS = 60000;
5
+ export declare const MIN_DICTATION_MS = 600;
6
+ /** The file extension a recording's bytes stand for. m4a is the fallback, the format the phone records. */
7
+ export declare function audioExtension(bytes: Uint8Array): string;
8
+ export declare function escapeSsml(text: string): string;
9
+ export declare function buildSsml(text: string, language: string, voice: string): string;
10
+ /** Cuts at the last sentence end past the floor, so a long reply is read whole sentences at a time. */
11
+ export declare function clampSpeakText(text: string): string;
12
+ /** Whole seconds as m:ss. A negative or non-finite value reads as 0:00. */
13
+ export declare function formatClipTime(ms: number): string;
14
+ /** Appends what was heard to the draft, with one space between, and keeps the result within maxLength. */
15
+ export declare function joinDictation(draft: string, heard: string, maxLength: number): string;
16
+ //# sourceMappingURL=speechText.d.ts.map
@@ -0,0 +1,21 @@
1
+ import type { ChatLiveMessage, ChatPart, ChatPartKind, ChatTurnApi, ChatUploadFile } from "@webority/chat-core";
2
+ import type React from "react";
3
+ export type { ChatMotion } from "@webority/chat-core";
4
+ export type ChatPartRendererProps<P extends ChatPart = ChatPart> = {
5
+ part: P;
6
+ message: ChatLiveMessage;
7
+ turn: ChatTurnApi;
8
+ pickAttachments?: () => Promise<ChatUploadFile[]>;
9
+ };
10
+ export type ChatRenderers = Partial<{
11
+ [K in ChatPartKind]: React.ComponentType<ChatPartRendererProps<Extract<ChatPart, {
12
+ kind: K;
13
+ }>>>;
14
+ }>;
15
+ export type ChatLayoutParts = (message: ChatLiveMessage) => Array<ChatPart | ChatPart[]>;
16
+ export interface ChatTicketRef {
17
+ ticketId: string;
18
+ number: string;
19
+ }
20
+ export type ChatOpenTicketHandler = (ticket: ChatTicketRef) => void;
21
+ //# sourceMappingURL=types.d.ts.map
@@ -1,19 +1,47 @@
1
- import type { ChatClient, ChatSession, ChatSessionState } from "@webority/markdown-core/chat";
2
- export type { ChatTurn, ChatTurnError } from "@webority/markdown-core/chat";
1
+ import type { ChatBehaviour, ChatClient, ChatFeature, ChatSession, ChatSessionState } from "@webority/chat-core";
2
+ import type { ChatLayout } from "./ChatFrame.js";
3
+ export interface ChatPrefs {
4
+ get(key: string): string | null;
5
+ set(key: string, value: string): void;
6
+ }
3
7
  export interface UseChatOptions {
4
- /** From `createChatClient`. */
5
8
  client: ChatClient;
6
- /** Sent with each question; read at the moment of sending. */
9
+ /** The screen key the profile resolves for; the phone has no URL. */
10
+ screen?: string;
11
+ /** The shell that hosts the session, named in its open and close events. */
12
+ layout?: ChatLayout;
13
+ /** Features switched off on this surface, on top of the server profile. */
14
+ narrow?: Partial<Record<ChatFeature, false>>;
15
+ /** Opens this conversation once after the profile loads. */
16
+ conversationId?: string | null;
17
+ /** Sent with each message; read at the moment of sending. */
7
18
  pageContext?: unknown;
19
+ /** The behaviour the host app measured; read at the moment of sending. */
20
+ behaviour?: () => ChatBehaviour | null;
21
+ /** Where the session keeps the mute choice (key wchat:muted). */
22
+ prefs: ChatPrefs;
23
+ getCaptchaToken?: (action: string) => Promise<string | null>;
24
+ onEvent?: (name: string, data: Record<string, unknown>) => void;
25
+ onError?: (error: unknown) => void;
26
+ /** Receives the path of a relative link in a reply; the host decides how to navigate to it. */
27
+ onNavigate?: (path: string) => void;
8
28
  }
9
- type ChatActions = Pick<ChatSession, "submit" | "stop" | "retry" | "regenerate" | "startEdit" | "cancelEdit" | "attach" | "removeAttachment" | "openConversation" | "newConversation" | "rate" | "refreshAllowance" | "reset">;
10
- export type UseChatResult = ChatSessionState & ChatActions & {
29
+ type ChatActions = Pick<ChatSession, "load" | "submit" | "chooseQuickReply" | "answerInput" | "confirmAction" | "rejectAction" | "stop" | "retry" | "regenerate" | "startEdit" | "cancelEdit" | "attach" | "removeAttachment" | "openConversation" | "resumeLast" | "newConversation" | "rate" | "reset" | "requestHandoff" | "notifyTyping" | "resumeLive">;
30
+ export interface UseChatResult extends ChatSessionState, ChatActions {
31
+ session: ChatSession;
11
32
  client: ChatClient;
12
- };
33
+ emit: (name: string, data: Record<string, unknown>) => void;
34
+ /** The host reports whether the chat is on screen; the live stream runs only while it is and the app is active. */
35
+ setChatVisible: (visible: boolean) => void;
36
+ /** Present only when the host passed `onNavigate`; the turn API of each message hands relative links to it. */
37
+ onNavigate?: (path: string) => void;
38
+ }
13
39
  /**
14
40
  * The chat's state and actions. The session lives in the component that calls it: one per client,
15
- * disposed when the client changes or the component unmounts. Call `reset()` when the signed-in
16
- * person or account changes so nothing of one person's chat shows to the next.
41
+ * screen and narrowing, created in a mount effect (StrictMode runs effects twice and a disposed session never
42
+ * loads again) and disposed when those change or the component unmounts. Until it exists the state is idle and
43
+ * the actions do nothing. Call `reset()` when the signed-in person changes so nothing of one person's chat shows to the next.
17
44
  */
18
- export declare const useChat: ({ client, pageContext }: UseChatOptions) => UseChatResult;
45
+ export declare function useChat(options: UseChatOptions): UseChatResult;
46
+ export {};
19
47
  //# sourceMappingURL=useChat.d.ts.map
@@ -0,0 +1,3 @@
1
+ import type { UseChatResult } from "./useChat.js";
2
+ export declare function useChatHaptics(chat: UseChatResult): void;
3
+ //# sourceMappingURL=useChatHaptics.d.ts.map
@@ -0,0 +1,4 @@
1
+ import type { ChatSpeechAdapter } from "@webority/chat-core";
2
+ import type { UseChatResult } from "./useChat.js";
3
+ export declare function useChatSpeech(chat: UseChatResult): ChatSpeechAdapter | null;
4
+ //# sourceMappingURL=useChatSpeech.d.ts.map
@@ -0,0 +1,10 @@
1
+ import { type ChatLabels, type ChatLiveMessage } from "@webority/chat-core";
2
+ import type { UseChatResult } from "./useChat.js";
3
+ export interface TranscriptActions {
4
+ canShare: boolean;
5
+ notice: string | null;
6
+ shareReply(message: ChatLiveMessage): Promise<void>;
7
+ shareConversation(): Promise<void>;
8
+ }
9
+ export default function useTranscriptActions(chat: UseChatResult, labels: ChatLabels): TranscriptActions;
10
+ //# sourceMappingURL=useTranscriptActions.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@webority/mobile-chat",
3
- "version": "0.128.0",
4
- "description": "AI assistant chat for Webority React Native apps: a streaming chat client, a store-agnostic chat hook, and the chat screen, thread, composer, past chats, reply rating and support action cards, built on @webority/mobile-ui.",
3
+ "version": "0.133.0",
4
+ "description": "Webority Chat for React Native apps: the chat screen, sheet and embedded shells, thread, composer, one renderer per message part kind and the useChat hook, built on @webority/chat-core and @webority/mobile-ui.",
5
5
  "keywords": [
6
6
  "react-native",
7
7
  "chat",
@@ -41,19 +41,25 @@
41
41
  "!**/*.spec.*",
42
42
  "!**/*.map"
43
43
  ],
44
- "dependencies": {
45
- "@webority/markdown-core": "0.128.0"
46
- },
47
44
  "peerDependencies": {
48
- "@webority/mobile-core": "0.128.0",
49
- "@webority/mobile-ui": "0.128.0",
50
- "expo-clipboard": ">=57.0.0",
45
+ "@webority/chat-core": "0.133.0",
46
+ "@webority/mobile-core": "^0.130.0",
47
+ "@webority/mobile-ui": "^0.130.1",
48
+ "expo-audio": ">=57.0.0",
49
+ "expo-file-system": ">=57.0.0",
51
50
  "react": "^19.1.0",
52
51
  "react-native": ">=0.81.0",
53
52
  "react-native-keyboard-controller": ">=1.21.9",
54
53
  "react-native-safe-area-context": ">=5.4.0"
55
54
  },
56
- "peerDependenciesMeta": {},
55
+ "peerDependenciesMeta": {
56
+ "expo-audio": {
57
+ "optional": true
58
+ },
59
+ "expo-file-system": {
60
+ "optional": true
61
+ }
62
+ },
57
63
  "publishConfig": {
58
64
  "access": "public",
59
65
  "registry": "https://registry.npmjs.org/"
@@ -85,25 +91,46 @@
85
91
  ]
86
92
  },
87
93
  "devDependencies": {
94
+ "@react-native/babel-preset": "0.86.3",
95
+ "@react-native/jest-preset": "0.86.3",
88
96
  "@react-native/metro-config": "0.86.3",
89
97
  "@testing-library/react-native": "12.9.0",
90
98
  "@types/react": "19.2.18",
91
- "@webority/mobile-core": "0.128.0",
92
- "@webority/mobile-dev": "0.0.0",
93
- "@webority/mobile-ui": "0.128.0",
99
+ "@webority/canvas-kit": "0.130.2",
100
+ "@webority/chat-core": "0.133.0",
101
+ "@webority/markdown-core": "0.130.2",
102
+ "@webority/mobile-core": "0.130.2",
103
+ "@webority/mobile-ui": "0.130.2",
104
+ "babel-jest": "29.7.0",
105
+ "expo": "57.0.31",
106
+ "expo-application": "57.0.3",
107
+ "expo-audio": "57.0.5",
108
+ "expo-clipboard": "57.0.2",
109
+ "expo-crypto": "57.0.4",
110
+ "expo-file-system": "57.0.7",
111
+ "expo-haptics": "57.0.3",
112
+ "expo-image": "57.0.5",
113
+ "expo-network": "57.0.3",
114
+ "expo-secure-store": "57.0.4",
115
+ "expo-sqlite": "57.0.4",
94
116
  "jest": "29.7.0",
95
117
  "react": "19.2.8",
118
+ "react-hook-form": "7.89.0",
96
119
  "react-native": "0.86.3",
97
120
  "react-native-builder-bob": "0.43.0",
121
+ "react-native-gesture-handler": "3.2.1",
98
122
  "react-native-keyboard-controller": "1.21.9",
123
+ "react-native-reanimated": "4.5.3",
99
124
  "react-native-safe-area-context": "5.9.1",
125
+ "react-native-svg": "15.15.5",
126
+ "react-native-worklets": "0.10.4",
100
127
  "react-test-renderer": "19.2.8",
101
- "rimraf": "6.1.3",
128
+ "terser": "5.49.1",
102
129
  "typescript": "5.9.3"
103
130
  },
104
131
  "scripts": {
105
- "build": "bob build && node ../mobile-dev/scripts/minify-lib.mjs",
106
- "clean": "rimraf lib",
132
+ "build": "bob build && node ../../scripts/minify-lib.mjs",
133
+ "clean": "node -e \"require('node:fs').rmSync('lib',{recursive:true,force:true})\"",
107
134
  "lint": "biome lint ./src",
108
135
  "lint:fix": "biome lint --write ./src",
109
136
  "test": "jest",
package/README.md DELETED
@@ -1,185 +0,0 @@
1
- # @webority/mobile-chat
2
-
3
- An AI assistant for a Webority React Native app: a client that streams the assistant's reply, a
4
- chat hook with no store of its own, and the chat screen and its parts (the conversation with
5
- Markdown replies, the question box, past chats with delete, reply ratings, support action cards,
6
- the questions left today and an optional floating launcher). It talks to the chat endpoints a
7
- product hosts with `Webority.Ai.Chat.AspNetCore`, the same contract as the web package
8
- `@webority/chat-react`, and it is built on `@webority/mobile-ui`, so it follows the app's theme.
9
-
10
- ```bash
11
- npm install @webority/mobile-chat
12
- ```
13
-
14
- ## Peers
15
-
16
- | Package | Why |
17
- |---|---|
18
- | `@webority/mobile-core`, `@webority/mobile-ui` | the HTTP client the app passes in, dates, theme and components |
19
- | `react-native-keyboard-controller` | the question box rises with the keyboard (mobile-ui needs it too) |
20
- | `react-native-safe-area-context` | the question box and the launcher clear the home indicator (mobile-ui needs it too) |
21
- | `expo-clipboard` | the copy action on a reply; the package reaches it through `@webority/mobile-core/clipboard` |
22
-
23
- All are required. An app on mobile-ui already has the first three; `expo-clipboard` is the one an app adds.
24
-
25
- ## Wire it up
26
-
27
- Give the client the app's own signed-in axios instance. It already carries the bearer token, the
28
- tenant header and the refresh on 401, so chat calls sign in like every other call. The package
29
- never handles auth.
30
-
31
- ```tsx
32
- import { userClient } from '@webority/mobile-core';
33
- import { createChatClient, useChat } from '@webority/mobile-chat';
34
- import { createSupportClient } from '@webority/mobile-support';
35
-
36
- const chatClient = createChatClient(userClient, { base: '/api/assistant' });
37
- const supportClient = createSupportClient(userClient, '/api/support');
38
-
39
- // Reply links look like [label](scheme:kind/id); map the ones the app knows to a screen.
40
- const resolveLink = (href: string) => {
41
- const [scheme, rest] = href.split(':');
42
- if (scheme === 'ticket') return { screen: 'SupportTicket', params: { id: rest.split('/')[1] } };
43
- return null;
44
- };
45
-
46
- // Above the navigator, so the conversation survives leaving the chat screen.
47
- export const AssistantProvider = ({ children }) => {
48
- const chat = useChat({ client: chatClient, pageContext: { screen: currentRouteName() } });
49
- return <AssistantContext.Provider value={chat}>{children}</AssistantContext.Provider>;
50
- };
51
-
52
- // A stack screen. pickFiles opens the app's own picker and resolves to { uri, name, type } files.
53
- export const AssistantScreen = ({ navigation }) => (
54
- <ChatScreen
55
- chat={useAssistant()}
56
- title="Ask the assistant"
57
- headerActions={<Button label="All chats" size="sm" variant="ghost" onPress={() => navigation.navigate('PastChats')} />}
58
- resolveLink={resolveLink}
59
- onLinkPress={(target) => navigation.navigate(target.screen, target.params)}
60
- confirmAction={supportClient.confirmAction}
61
- onViewTicket={(ticket) => navigation.navigate('SupportTicket', { id: ticket.id })}
62
- pickAttachments={pickFiles}
63
- onOpenAttachment={(attachment) => openAttachment(attachment)}
64
- />
65
- );
66
- ```
67
-
68
- Call `chat.reset()` when the person signs out or switches account, so nothing of one person's chat
69
- shows to the next. Call `chat.refreshAllowance()` when the chat opens if the allowance should show
70
- before the first question.
71
-
72
- ### Streaming
73
-
74
- The reply streams through axios's XMLHttpRequest adapter, the React Native default: React
75
- Native's XMLHttpRequest hands over text as it arrives once a progress listener is attached, and
76
- the client attaches one through `onDownloadProgress`. Incremental delivery on iOS has not yet been
77
- confirmed on a device; where it buffers, the reply appears whole when it ends. Give the POST a timeout long enough for a
78
- whole answer (the app's own client may default to a short one). An instance forced onto axios's
79
- fetch adapter still works, but the reply then appears whole at the end.
80
-
81
- ## The client
82
-
83
- `createChatClient(http, { base })` takes an axios instance (`get`, `post`, `put`, `delete`
84
- resolving to `{ data }`) and the prefix the API maps the chat endpoints under. Every method
85
- rejects with a `ChatApiError` carrying `code`, `status`, `resetsAtUtc` and a `message` written for
86
- the person, which the components show as is. `code` is the server's code, `network` when no
87
- response arrived, `aborted` when the request was cancelled, or `invalid-response`.
88
-
89
- | Method | Request |
90
- |---|---|
91
- | `sendMessage({ message, conversationId, pageContext, replacesMessageId, attachmentIds }, { signal, onEvent })` | `POST {base}/chat`, streamed; resolves with the `done` event, which carries `questionId` |
92
- | `getSettings()` | `GET {base}/settings`: the attachment limits, `{ attachments: null }` when the server takes none |
93
- | `uploadAttachment(file, { signal, onProgress })` | `POST {base}/attachments`, multipart |
94
- | `deleteAttachment(id)` | `DELETE {base}/attachments/{id}` |
95
- | `getAttachment(id)` | `GET {base}/attachments/{id}`, resolves with the bytes |
96
- | `getAllowance()` | `GET {base}/allowance` |
97
- | `listConversations({ page, pageSize })` | `GET {base}/conversations?page=&pageSize=`, one page of `{ items, page, pageSize, totalCount, totalPages }` |
98
- | `getConversation(id)` | `GET {base}/conversations/{id}` |
99
- | `renameConversation(id, title)` | `PUT {base}/conversations/{id}/title`, the new title in the body |
100
- | `deleteConversation(id)` | `DELETE {base}/conversations/{id}` |
101
- | `rateMessage(conversationId, messageId, { rating, note })` | `PUT {base}/conversations/{conversationId}/messages/{messageId}/rating` |
102
-
103
- The server must answer `GET {base}/settings`. An older server that does not answers 404, and each
104
- question then fails with `assistant_outdated` ("The assistant needs an update before it can answer. Please try again later.").
105
-
106
- `onEvent(name, data)` is called with `delta { text }`, `reset {}`, `tool {}` and `actions { actions }` as they
107
- arrive. `createSseParser(onEvent)` is exported too, for reading the same stream elsewhere. The
108
- server contract (refusal codes, the event stream, the read endpoints) is the one
109
- `@webority/chat-react` documents.
110
-
111
- ## The hook
112
-
113
- `useChat({ client, pageContext })` returns `turns` (`[{ id, question, answer, streaming, error,
114
- actions, messageId, rating, ratingNote }]`, oldest first), `conversationId`, `messagesLeftToday`,
115
- `streaming`, `loading`, `loadError`, `settings`, `settingsError`, `editing`, `attachments`, and
116
- `submit(message)`, `stop()`, `retry(turnId)`, `regenerate(turnId)`, `startEdit(turnId)`,
117
- `cancelEdit()`, `attach(files)`, `removeAttachment(key)`, `openConversation(id)`,
118
- `newConversation()`, `rate(turnId, rating, note?)`, `refreshAllowance()` and `reset()`.
119
- `pageContext` is read at the moment each question is sent.
120
-
121
- An answer still arriving is cancelled on `reset`, `newConversation`, `openConversation` and
122
- unmount. A failed turn keeps the question, drops the half-streamed text and carries `error`
123
- (`{ code, message, resetsAtUtc }`). After `daily_limit`, `messagesLeftToday` becomes 0; after
124
- `conversation_not_found`, the next question starts a new conversation. A question asked while an
125
- answer is arriving is ignored.
126
-
127
- ## Components
128
-
129
- Every component takes `labels`, any subset of `DEFAULT_CHAT_LABELS`. The keys are the web
130
- package's, so a product passes one label set to both; `composerHint` is not shown on a phone.
131
-
132
- - **`ChatScreen`**: the whole chat for one navigator screen. `chat` (the `useChat` result),
133
- `title` (default "Assistant"), `headerActions` (before New chat, e.g. "All chats"), `empty`
134
- (shown before the first question), `disclaimer` (null hides it), `maxLength` (default 4000),
135
- `allowanceThreshold` (show the questions left at this many or fewer, default 10), `rating`
136
- (default true), `resolveLink`, `onLinkPress`, `confirmAction`, `onViewTicket`, `pickAttachments`,
137
- `onOpenAttachment`, `onAskSuggestion(text)` (sends a suggested follow-up question under the last
138
- settled answer), `isCitation(inner)` and `onOpenCitation(citation)` (a run of the reply that
139
- `isCitation` accepts draws as an inline pressable text run, not a chip, and pressing it calls
140
- `onOpenCitation`), `renderReply`,
141
- `keyboardOffset`.
142
- New chat is disabled until there is something to clear; the question box is disabled with no
143
- questions left, and the thread follows the newest text while an answer streams.
144
- The five controls: Stop ends an answer while it streams and marks its turn stopped;
145
- Try again sends a stopped or failed question again; New answer asks for another reply to the last
146
- answered turn; Edit puts a question back in the box to change and resend; Attach a file adds files
147
- to the next question. Attach a file shows only when `pickAttachments` is given and the server's
148
- settings allow attachments; `pickAttachments` resolves to the files the person picked, and
149
- `onOpenAttachment(attachment)` opens one shown in a message.
150
- - **`ChatThread`**, **`ChatMessage`**, **`ChatComposer`**: its parts, built on mobile-ui's
151
- `MessageList`, `MessageBubble`, `TypingIndicator` and `Composer`, for an app that lays out its
152
- own chat. The thread and the composer handle the keyboard themselves; pass
153
- `keyboardAware={false}` to both inside a container that already does, and `keyboardOffset` (the
154
- tab bar height) above a tab bar. The composer's return key adds a new line; only the send button
155
- sends.
156
- - **`ChatMarkdown`**: renders a reply through mobile-ui's `Markdown`, the one Markdown renderer
157
- the phone uses, so the reply draws the same subset of Markdown as every other surface: paragraphs,
158
- bold, italics, inline code, bullet and numbered lists, simple tables (scrolling sideways),
159
- headings, code blocks and rules. A link shows only when its href has the form `scheme:kind/id`
160
- and `resolveLink(href)` returns something; pressing it calls `onLinkPress(target)`. A web address
161
- never opens, and shows its label as plain text.
162
- - **`ReplyRating`**: Helpful and Not helpful under a stored reply; Not helpful then offers an
163
- optional note (`noteMaxLength`, default 1000).
164
- - **`ActionCard`**: one support action under a reply, with Confirm and Not now. It moves through
165
- sending to done (with View ticket when `onViewTicket` is given); an expired action shows
166
- without a button. `confirmAction(token)` is mobile-support's `supportClient.confirmAction`.
167
- - **`ChatConversationList`**: past chats, newest first: `client`, `onOpen(conversation)`,
168
- `onDeleted(id)`, `pageSize` (default 20). Show more, pull to refresh, delete after a confirm,
169
- and empty and error states with Try again.
170
- - **`ChatLauncher`**: an optional floating button (`onPress`, `position` `end` or `start`,
171
- `bottomOffset` to clear a tab bar, `compact`). Most apps open the chat from a header action or a
172
- Help row instead.
173
-
174
- The labels the new parts read, all keys of `DEFAULT_CHAT_LABELS`: `copy` and `copied` (the reply's
175
- Copy action and its confirmation); `toolStep(toolName)` (the waiting line while the assistant runs a
176
- tool; it receives the server's tool name and defaults to "Looking this up", so the app maps each
177
- tool to the person's words); `suggestions` (the heading over suggested questions); `renameConversation`, `conversationTitle`,
178
- `renameSave` and `renameFailed` (the rename dialog in `ChatConversationList`).
179
-
180
- `ChatConversationList` pages by `page` and `pageSize` (default 20) and renames a chat in place
181
- through `renameConversation`.
182
-
183
- `renderReply(turn, { streaming })` on `ChatScreen`, `ChatThread` or `ChatMessage` draws each
184
- assistant reply your way (charts, maths); the question, thinking state, errors, action cards and
185
- rating stay the library's.
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ActionCard=void 0;var _chat=require("@webority/markdown-core/chat"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),_jsxRuntime=require("react/jsx-runtime");const titleOf=(e,i)=>"Reply"===e.kind?i.actionReply(e.ticketNumber??""):"Reopen"===e.kind?i.actionReopen(e.ticketNumber??""):i.actionRaiseTicket,doneText=(e,i,t)=>"Reply"===e.kind?t.actionDoneReply(i):"Reopen"===e.kind?t.actionDoneReopen(i):t.actionDoneRaiseTicket(i),ActionCard=({action:e,confirmAction:i,onViewTicket:t,labels:n,testID:s="chat-action"})=>{const a=(0,_chat.mergeLabels)(n),o=(0,_mobileUi.useTheme)(),[r,c]=(0,_react.useState)("ready"),[l,d]=(0,_react.useState)(null),[m,x]=(0,_react.useState)("");if("dismissed"===r)return(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"secondary",testID:s,children:a.actionDismissed});if("done"===r&&l)return(0,_jsxRuntime.jsx)(_mobileUi.Banner,{tone:"success",message:doneText(e,l.number,a),actions:t?[{label:a.viewTicket,onPress:()=>t(l)}]:void 0,testID:s});const u="sending"===r,_=new Date(e.expiresDateTimeUtc).getTime()<=Date.now(),b="RaiseTicket"===e.kind?[e.category,e.subject].filter(Boolean).join(", "):"";return(0,_jsxRuntime.jsx)(_mobileUi.Card,{variant:"outline",padding:"sm",testID:s,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{gap:o.space.sm},children:[(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"label",children:titleOf(e,a)}),""!==b&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"secondary",children:b}),"Reopen"!==e.kind&&e.body?(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",children:e.body}):null,_?(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"secondary",children:a.actionExpired}):(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:"secondary",children:a.actionNote}),""!==m&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:m}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flexDirection:"row",flexWrap:"wrap",gap:o.space.sm},children:[(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:a.actionConfirm,size:"sm",loading:u,disabled:u,onPress:()=>{(async()=>{c("sending"),x("");try{d(await i(e.token)),c("done")}catch(e){const i=e?.message;x("string"==typeof i&&i?i:a.actionFailed),c("ready")}})()},testID:`${s}-confirm`}),(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:a.actionDismiss,size:"sm",variant:"outline",disabled:u,onPress:()=>c("dismissed"),testID:`${s}-dismiss`})]})]})]})})};exports.ActionCard=ActionCard;
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatComposer=void 0;var _chat=require("@webority/markdown-core/chat"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_ComposerAttachments=require("./ComposerAttachments.js"),_jsxRuntime=require("react/jsx-runtime");const ChatComposer=({onSubmit:e,busy:t=!1,onStop:s,disabled:a=!1,maxLength:o=4e3,above:n,below:i,keyboardAware:r,keyboardOffset:c,safeArea:l,attachments:m=[],onAttach:d,onRemoveAttachment:b,editing:u,onCancelEdit:h,labels:p,testID:x="chat-composer"})=>{const _=(0,_chat.mergeLabels)(p),j=m.some(e=>"Uploading"===e.status),C=m.some(e=>"Ready"===e.status),[g,v]=(0,_react.useState)("");(0,_react.useEffect)(()=>{v(u?u.text:"")},[u]);const y=u?(0,_jsxRuntime.jsx)(_mobileUi.Banner,{message:_.editing,accessibilityRole:"summary",actions:h?[{label:_.cancel,onPress:h,testID:`${x}-cancel-edit`}]:void 0,testID:`${x}-editing`}):null,R=m.length>0?(0,_jsxRuntime.jsx)(_ComposerAttachments.ComposerAttachments,{attachments:m,onRemove:b,labels:p,testID:`${x}-attachments`}):null,A=y||R||n?(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[y,R,n]}):void 0,f=d?(0,_jsxRuntime.jsx)(_mobileUi.IconButton,{icon:"paperclip",accessibilityLabel:_.attach,variant:"ghost",tone:"neutral",disabled:a||t,onPress:d,testID:`${x}-attach`}):void 0;return(0,_jsxRuntime.jsx)(_mobileUi.Composer,{onSend:e,value:g,onChangeText:v,loading:t,onStop:s,stopLabel:_.stop,disabled:a,maxLength:o,canSend:!j&&(!!C||void 0),placeholder:_.placeholder,accessibilityLabel:_.composer,labels:{send:_.send},leading:f,above:A,below:i,keyboardAware:r,keyboardOffset:c,safeArea:l,testID:x})};exports.ChatComposer=ChatComposer;
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatConversationList=void 0;var _chat=require("@webority/markdown-core/chat"),_mobileCore=require("@webority/mobile-core"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),_jsxRuntime=require("react/jsx-runtime");const messageOf=(e,t)=>{const i=e?.message;return"string"==typeof i&&i?i:t},IDLE_STATE={items:[],totalCount:null,loading:!0,error:null,hasMore:!1},IDLE={getState:()=>IDLE_STATE,subscribe:()=>()=>{}},ChatConversationList=({client:e,onOpen:t,onDeleted:i,pageSize:s=20,labels:n,style:a,testID:r="chat-conversations"})=>{const l=(0,_chat.mergeLabels)(n),o=(0,_mobileUi.useTheme)(),[c,m]=(0,_react.useState)(null),u=c??IDLE,{items:d,loading:_,error:b,hasMore:x}=(0,_react.useSyncExternalStore)(u.subscribe,u.getState),[g,j]=(0,_react.useState)(!1),[h,p]=(0,_react.useState)(null),[v,y]=(0,_react.useState)(!1),[S,f]=(0,_react.useState)(""),[I,C]=(0,_react.useState)(null),[R,D]=(0,_react.useState)(""),[U,L]=(0,_react.useState)(!1),[T,w]=(0,_react.useState)(""),[E,$]=(0,_react.useState)(void 0),[P,O]=(0,_react.useState)("");(0,_react.useEffect)(()=>{const t=(0,_chat.createConversationList)({client:e,pageSize:s});return m(t),t.load(),()=>t.dispose()},[e,s]),(0,_react.useEffect)(()=>{let t=!0;return e.getSettings().then(e=>{t&&$(e.titleMaxLength)},e=>{t&&O(messageOf(e,l.renameFailed))}),()=>{t=!1}},[e,l.renameFailed]);const M=R.trim(),save=async()=>{if(I&&""!==M){L(!0),w("");try{await(c?.rename(I.publicId,M)),C(null)}catch(e){w(messageOf(e,l.renameFailed))}finally{L(!1)}}},q=!_&&!b&&0===d.length;return(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{style:a,contentContainerStyle:{padding:o.space.md,gap:o.space.sm,flexGrow:1},refreshControl:(0,_jsxRuntime.jsx)(_reactNative.RefreshControl,{refreshing:g,onRefresh:()=>{(async()=>{j(!0),await(c?.load()),j(!1)})()}}),accessibilityLabel:l.conversations,testID:r,children:[b&&(0,_jsxRuntime.jsx)(_mobileUi.Banner,{tone:"danger",message:b.message||l.loadFailed,actions:[{label:l.retry,onPress:()=>{c?.load()}}],testID:`${r}-error`}),q&&(0,_jsxRuntime.jsx)(_mobileUi.EmptyState,{size:"sm",title:l.conversationsEmptyTitle,description:l.conversationsEmptyText,testID:`${r}-empty`}),d.map(e=>(0,_jsxRuntime.jsx)(_mobileUi.Card,{variant:"outline",padding:"sm",onPress:()=>t(e),accessibilityLabel:e.title||l.untitled,testID:`${r}-item-${e.publicId}`,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flexDirection:"row",alignItems:"center",gap:o.space.sm},children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flex:1,minWidth:0},children:[(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"label",numberOfLines:1,children:e.title||l.untitled}),(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:"secondary",children:(0,_mobileCore.formatDateTime)(e.lastMessageDateTimeUtc)})]}),(0,_jsxRuntime.jsx)(_mobileUi.IconButton,{icon:"edit",variant:"ghost",accessibilityLabel:l.renameConversation,onPress:()=>{w(""),D(e.title??""),C(e)},testID:`${r}-rename-${e.publicId}`}),(0,_jsxRuntime.jsx)(_mobileUi.IconButton,{icon:"trash",tone:"danger",variant:"ghost",accessibilityLabel:l.deleteConversation,onPress:()=>{f(""),p(e)},testID:`${r}-delete-${e.publicId}`})]})},e.publicId)),_&&!g&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{gap:o.space.sm},accessibilityElementsHidden:!0,children:[(0,_jsxRuntime.jsx)(_mobileUi.Skeleton,{height:56}),(0,_jsxRuntime.jsx)(_mobileUi.Skeleton,{height:56}),(0,_jsxRuntime.jsx)(_mobileUi.Skeleton,{height:56})]}),!_&&x&&(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:l.loadMore,variant:"outline",onPress:()=>{c?.loadMore()},testID:`${r}-more`}),(0,_jsxRuntime.jsxs)(_mobileUi.Dialog,{visible:null!==I,onClose:()=>{U||C(null)},title:l.renameConversation,dismissOnAction:!1,actions:[{label:l.cancel,tone:"neutral",disabled:U,onPress:()=>C(null)},{label:l.renameSave,disabled:""===M||U,loading:U,onPress:()=>{save()}}],testID:`${r}-rename`,children:[(0,_jsxRuntime.jsx)(_mobileUi.Input,{label:l.conversationTitle,value:R,onChangeText:D,maxLength:E,returnKeyType:"done",onSubmitEditing:()=>{save()},testID:`${r}-rename-input`}),""!==(T||P)&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:"danger",testID:`${r}-rename-error`,children:T||P})]}),(0,_jsxRuntime.jsx)(_mobileUi.Dialog,{visible:null!==h,onClose:()=>{v||p(null)},tone:"warning",title:l.deleteConfirmTitle,message:S||l.deleteConfirmMessage,dismissOnAction:!1,actions:[{label:l.cancel,tone:"neutral",disabled:v,onPress:()=>p(null)},{label:l.deleteConfirm,tone:"danger",loading:v,onPress:()=>{(async()=>{if(h){y(!0),f("");try{await(c?.remove(h.publicId)),i?.(h.publicId),p(null)}catch(e){f(messageOf(e,l.deleteFailed))}finally{y(!1)}}})()}}],testID:`${r}-confirm`})]})};exports.ChatConversationList=ChatConversationList;
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatLauncher=void 0;var _chat=require("@webority/markdown-core/chat"),_mobileUi=require("@webority/mobile-ui"),_jsxRuntime=require("react/jsx-runtime");const ChatLauncher=({onPress:e,position:t="end",bottomOffset:o,compact:r=!1,labels:i,testID:s="chat-launcher"})=>{const a=(0,_chat.mergeLabels)(i);return(0,_jsxRuntime.jsx)(_mobileUi.FloatingActionButton,{icon:"messages",label:r?void 0:a.launcher,accessibilityLabel:a.launcher,position:"end"===t?"bottomRight":"bottomLeft",bottomOffset:o,onPress:e,testID:s})};exports.ChatLauncher=ChatLauncher;
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatMarkdown=ChatMarkdown;var _mobileUi=require("@webority/mobile-ui"),_jsxRuntime=require("react/jsx-runtime");function ChatMarkdown({text:e,resolveLink:i,onLinkPress:t,isCitation:n,onOpenCitation:r,testID:o}){return(0,_jsxRuntime.jsx)(_mobileUi.Markdown,{links:"app",headings:"text",resolveLink:i,onAppLinkPress:t,isCitation:n,onOpenCitation:r,testID:o,children:e})}
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatMessage=void 0;var _markdownCore=require("@webority/markdown-core"),_chat=require("@webority/markdown-core/chat"),_clipboard=require("@webority/mobile-core/clipboard"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),_ActionCard=require("./ActionCard.js"),_ChatMarkdown=require("./ChatMarkdown.js"),_ReplyRating=require("./ReplyRating.js"),_jsxRuntime=require("react/jsx-runtime");function ChatMessageView({turn:e,canRegenerate:t=!1,onRetry:i,onRegenerate:s,onEdit:n,onOpenAttachment:a,onRate:r,resolveLink:o,onLinkPress:l,isCitation:c,onOpenCitation:m,onAskSuggestion:u,confirmAction:x,onViewTicket:_,renderReply:p,labels:g,testID:d="chat-message"}){const b=(0,_chat.mergeLabels)(g),j=(0,_mobileUi.useTheme)(),[w,R]=(0,_react.useState)(!1),h=(0,_react.useRef)(null);(0,_react.useEffect)(()=>()=>{null!==h.current&&clearTimeout(h.current)},[]);const y=e.streaming&&!e.answer,k=(0,_react.useMemo)(()=>e.streaming?e.answer:(0,_markdownCore.markdownToPlainText)(e.answer),[e.streaming,e.answer]),C=(0,_react.useMemo)(()=>({you:b.you}),[b.you]),v=!e.streaming&&(e.stopped||null!==e.error),I=!e.streaming&&null!==e.questionId,T=e.attachments.length>0||e.stopped||i&&v||n&&I?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{gap:j.space.xs},children:[e.attachments.length>0?(0,_jsxRuntime.jsx)(_reactNative.View,{style:{flexDirection:"row",flexWrap:"wrap",gap:j.space.xs},children:e.attachments.map(e=>(0,_jsxRuntime.jsx)(_mobileUi.Chip,{label:e.fileName,onPress:a?()=>a(e):void 0,testID:`${d}-attachment-${e.publicId}`},e.publicId))}):null,e.stopped?(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"secondary",accessibilityLiveRegion:"polite",testID:`${d}-stopped`,children:b.stopped}):null,i&&v||n&&I?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flexDirection:"row",flexWrap:"wrap",gap:j.space.xs},children:[i&&v?(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:b.retry,variant:"link",size:"sm",onPress:()=>i(e.id),testID:`${d}-retry`}):null,n&&I?(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:b.edit,variant:"link",size:"sm",onPress:()=>n(e.id),testID:`${d}-edit`}):null]}):null]}):null;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{gap:j.space.sm},testID:d,children:[""!==e.question&&(0,_jsxRuntime.jsx)(_mobileUi.MessageBubble,{side:"mine",text:e.question,labels:C,footer:T,testID:`${d}-question`}),y?(0,_jsxRuntime.jsx)(_mobileUi.TypingIndicator,{label:b.thinking,testID:`${d}-thinking`}):null,""!==e.answer?(0,_jsxRuntime.jsx)(_mobileUi.MessageBubble,{side:"theirs",author:b.assistant,text:k,streaming:e.streaming,onCopy:()=>{(0,_clipboard.copyText)((0,_markdownCore.markdownToPlainText)(e.answer))},testID:`${d}-answer`,children:p?p(e,{streaming:e.streaming}):(0,_jsxRuntime.jsx)(_ChatMarkdown.ChatMarkdown,{text:e.answer,resolveLink:o,onLinkPress:l,isCitation:c,onOpenCitation:m})}):null,e.streaming&&e.step?(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:"secondary",accessibilityLiveRegion:"polite",testID:`${d}-step`,children:b.toolStep(e.step)}):null,e.streaming||""===e.answer?null:(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:w?b.copied:b.copy,variant:"link",size:"sm",onPress:()=>{(async()=>{await(0,_clipboard.copyText)((0,_markdownCore.markdownToPlainText)(e.answer))&&(R(!0),null!==h.current&&clearTimeout(h.current),h.current=setTimeout(()=>R(!1),2e3))})()},testID:`${d}-copy`}),u&&!e.streaming&&e.suggestions.length>0?(0,_jsxRuntime.jsx)(_reactNative.View,{accessibilityRole:"list",accessibilityLabel:b.suggestions,style:{flexDirection:"row",flexWrap:"wrap",gap:j.space.xs},children:e.suggestions.map((e,t)=>(0,_jsxRuntime.jsx)(_mobileUi.Chip,{label:e,onPress:()=>u(e),testID:`${d}-suggestion-${t}`},e))}):null,t&&s&&!e.streaming&&""!==e.answer?(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:b.regenerate,variant:"link",size:"sm",onPress:()=>s(e.id),testID:`${d}-regenerate`}):null,e.error&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:e.error.message}),x&&!e.streaming&&e.actions.map(e=>(0,_jsxRuntime.jsx)(_ActionCard.ActionCard,{action:e,confirmAction:x,onViewTicket:_,labels:g},e.token)),r&&e.messageId&&!e.streaming&&(0,_jsxRuntime.jsx)(_ReplyRating.ReplyRating,{rating:e.rating,onRate:(t,i)=>r(e.id,t,i),labels:g})]})}const ChatMessage=exports.ChatMessage=(0,_react.memo)(ChatMessageView);
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatScreen=ChatScreen;var _chat=require("@webority/markdown-core/chat"),_mobileUi=require("@webority/mobile-ui"),_reactNative=require("react-native"),_ChatComposer=require("./ChatComposer.js"),_ChatThread=require("./ChatThread.js"),_jsxRuntime=require("react/jsx-runtime");function ChatScreen({chat:e,pickAttachments:t,onOpenAttachment:s,title:i,headerActions:a,empty:n,disclaimer:r,maxLength:o=4e3,allowanceThreshold:l=10,rating:m=!0,keyboardOffset:c,testID:d="chat-screen",...h}){const u=(0,_chat.mergeLabels)(h.labels),x=(0,_mobileUi.useTheme)(),b=e.messagesLeftToday,g=void 0===r?u.disclaimer:r,_=t&&e.settings?.attachments?async()=>e.attach(await t()):void 0;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flex:1,backgroundColor:x.colors.bg},testID:d,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flexDirection:"row",alignItems:"center",gap:x.space.sm,paddingHorizontal:x.space.md,paddingVertical:x.space.sm,borderBottomWidth:1,borderBottomColor:x.colors["border-subtle"]},children:[(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"title",accessibilityRole:"header",style:{flex:1},numberOfLines:1,children:i??u.panelTitle}),a,(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:u.newChat,size:"sm",variant:"soft",leftIcon:"add",disabled:0===e.turns.length&&!e.loading,onPress:e.newConversation,testID:`${d}-new`})]}),e.loading?(0,_jsxRuntime.jsx)(_reactNative.View,{style:{flex:1,alignItems:"center",justifyContent:"center"},children:(0,_jsxRuntime.jsx)(_mobileUi.Spinner,{message:u.loadingConversation,testID:`${d}-loading`})}):(0,_jsxRuntime.jsx)(_ChatThread.ChatThread,{turns:e.turns,style:{flex:1},keyboardOffset:c,onRate:m?e.rate:void 0,onRetry:e.retry,onRegenerate:e.regenerate,onEdit:e.startEdit,onOpenAttachment:s,empty:n??(0,_jsxRuntime.jsx)(_mobileUi.EmptyState,{fill:!0,size:"sm",title:u.emptyTitle,description:u.emptyText,testID:`${d}-empty`}),testID:`${d}-thread`,...h,onAskSuggestion:e.submit}),(0,_jsxRuntime.jsx)(_ChatComposer.ChatComposer,{onSubmit:t=>{e.submit(t)},busy:e.streaming,onStop:e.stop,disabled:0===b||e.loading,maxLength:o,keyboardOffset:c,labels:h.labels,onAttach:_,attachments:e.attachments,onRemoveAttachment:t=>{e.removeAttachment(t)},editing:e.editing,onCancelEdit:e.cancelEdit,testID:`${d}-composer`,above:(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[e.loadError&&(0,_jsxRuntime.jsx)(_mobileUi.Banner,{tone:"danger",message:e.loadError.message,testID:`${d}-load-error`}),e.settingsError&&(0,_jsxRuntime.jsx)(_mobileUi.Banner,{tone:"danger",message:e.settingsError.message,testID:`${d}-settings-error`}),null!==b&&b<=l&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:0===b?"danger":"secondary",accessibilityLiveRegion:"polite",testID:`${d}-allowance`,children:u.allowance(b)})]}),below:g?(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:"tertiary",testID:`${d}-disclaimer`,children:g}):null})]})}
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatThread=ChatThread;var _chat=require("@webority/markdown-core/chat"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),_ChatMessage=require("./ChatMessage.js"),_jsxRuntime=require("react/jsx-runtime");const turnKey=e=>e.id,followTurn=()=>!0,TurnGap=()=>{const e=(0,_mobileUi.useTheme)();return(0,_jsxRuntime.jsx)(_reactNative.View,{style:{height:e.space.lg}})};function ChatThread({turns:e,empty:t,keyboardAware:r,keyboardOffset:a,onRetry:s,onRegenerate:n,onEdit:i,onOpenAttachment:o,onAskSuggestion:u,style:c,testID:l="chat-thread",...d}){const m=(0,_chat.mergeLabels)(d.labels),h=(0,_react.useMemo)(()=>[...e].reverse(),[e]),g=(0,_react.useMemo)(()=>{const t=e[e.length-1];return t&&null!==t.messageId&&!t.streaming?t.id:null},[e]),y=e[e.length-1]?.id;return(0,_jsxRuntime.jsx)(_mobileUi.MessageList,{messages:h,keyExtractor:turnKey,renderMessage:({item:e})=>(0,_jsxRuntime.jsx)(_ChatMessage.ChatMessage,{turn:e,onRetry:s,canRegenerate:e.id===g,onRegenerate:e.id===g?n:void 0,onEdit:i,onOpenAttachment:o,testID:`${l}-${e.id}`,...d,onAskSuggestion:e.id===y?u:void 0}),followNew:followTurn,empty:t,ItemSeparatorComponent:TurnGap,keyboardAware:r,keyboardOffset:a,accessibilityLabel:m.thread,style:c,testID:l})}
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ComposerAttachments=void 0;var _chat=require("@webority/markdown-core/chat"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),_jsxRuntime=require("react/jsx-runtime");const ComposerAttachments=({attachments:e,onRemove:t,labels:r,testID:s="composer-attachments"})=>{const a=(0,_mobileUi.useTheme)(),i=(0,_react.useMemo)(()=>buildStyles(a),[a]),o=(0,_chat.mergeLabels)(r),m=(0,_react.useMemo)(()=>({remove:o.removeAttachment}),[o.removeAttachment]);return(0,_jsxRuntime.jsx)(_reactNative.View,{style:i.root,testID:s,children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:i.row,children:e.map(e=>(0,_jsxRuntime.jsxs)(_reactNative.View,{style:i.item,children:[(0,_jsxRuntime.jsx)(_mobileUi.Chip,{label:e.fileName,variant:"soft",onRemove:t?()=>t(e.key):void 0,labels:m,removeTestID:`chat-attachment-remove-${e.key}`,testID:`${s}-${e.key}`}),"Uploading"===e.status?(0,_jsxRuntime.jsx)(_mobileUi.ProgressBar,{progress:e.progress??void 0,label:o.attachmentUploading,height:4,containerStyle:i.progress}):null,"Failed"===e.status?(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:"danger",accessibilityLiveRegion:"polite",children:o.attachmentFailed}):null]},e.key))})})};exports.ComposerAttachments=ComposerAttachments;const buildStyles=e=>_reactNative.StyleSheet.create({root:{gap:e.space.xs},row:{flexDirection:"row",flexWrap:"wrap",gap:e.space.xs},item:{gap:e.space.xxs,maxWidth:"100%"},progress:{minWidth:120}});
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ReplyRating=void 0;var _chat=require("@webority/markdown-core/chat"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),_jsxRuntime=require("react/jsx-runtime");const ReplyRating=({rating:e=null,onRate:t,noteMaxLength:i=1e3,labels:a,testID:s="chat-rating"})=>{const n=(0,_chat.mergeLabels)(a),r=(0,_mobileUi.useTheme)(),[l,o]=(0,_react.useState)(!1),[c,d]=(0,_react.useState)(!1),[u,m]=(0,_react.useState)(""),[x,_]=(0,_react.useState)(""),[b,p]=(0,_react.useState)(!1),save=async(e,i)=>{o(!0),_("");try{await t(e,i),d("Down"===e&&void 0===i),p("Up"===e||void 0!==i),void 0!==i&&m("")}catch{_(n.ratingFailed)}finally{o(!1)}};return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{gap:r.space.sm},testID:s,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flexDirection:"row",flexWrap:"wrap",alignItems:"center",gap:r.space.xs},children:[(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:n.rateUp,size:"sm",leftIcon:"like",variant:"Up"===e?"soft":"ghost",accessibilityState:{selected:"Up"===e,disabled:l},"aria-selected":"Up"===e,"aria-disabled":l,disabled:l,onPress:()=>{save("Up")},testID:`${s}-up`}),(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:n.rateDown,size:"sm",leftIcon:"dislike",variant:"Down"===e?"soft":"ghost",accessibilityState:{selected:"Down"===e,disabled:l},"aria-selected":"Down"===e,"aria-disabled":l,disabled:l,onPress:()=>{save("Down")},testID:`${s}-down`}),b&&!c&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:"secondary",accessibilityLiveRegion:"polite",children:n.rated})]}),""!==x&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:x}),c&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{gap:r.space.sm},children:[(0,_jsxRuntime.jsx)(_mobileUi.Input,{label:n.ratingNote,helperText:n.ratingNoteHint,multiline:!0,maxLength:i,value:u,onChangeText:m,testID:`${s}-note`}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flexDirection:"row",gap:r.space.sm},children:[(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:n.ratingNoteSend,size:"sm",loading:l,disabled:l,onPress:()=>{save("Down",u)},testID:`${s}-note-send`}),(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:n.ratingNoteSkip,size:"sm",variant:"outline",disabled:l,onPress:()=>{d(!1),p(!0)},testID:`${s}-note-skip`})]})]})]})};exports.ReplyRating=ReplyRating;
@@ -1 +0,0 @@
1
- "use strict";import{mergeLabels}from"@webority/markdown-core/chat";import{Banner,Button,Card,Text,useTheme}from"@webority/mobile-ui";import{useState}from"react";import{View}from"react-native";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const titleOf=(e,t)=>"Reply"===e.kind?t.actionReply(e.ticketNumber??""):"Reopen"===e.kind?t.actionReopen(e.ticketNumber??""):t.actionRaiseTicket,doneText=(e,t,i)=>"Reply"===e.kind?i.actionDoneReply(t):"Reopen"===e.kind?i.actionDoneReopen(t):i.actionDoneRaiseTicket(t);export const ActionCard=({action:e,confirmAction:t,onViewTicket:i,labels:n,testID:s="chat-action"})=>{const a=mergeLabels(n),o=useTheme(),[r,c]=useState("ready"),[l,d]=useState(null),[m,x]=useState("");if("dismissed"===r)return _jsx(Text,{variant:"bodySmall",color:"secondary",testID:s,children:a.actionDismissed});if("done"===r&&l)return _jsx(Banner,{tone:"success",message:doneText(e,l.number,a),actions:i?[{label:a.viewTicket,onPress:()=>i(l)}]:void 0,testID:s});const p="sending"===r,y=new Date(e.expiresDateTimeUtc).getTime()<=Date.now(),b="RaiseTicket"===e.kind?[e.category,e.subject].filter(Boolean).join(", "):"";return _jsx(Card,{variant:"outline",padding:"sm",testID:s,children:_jsxs(View,{style:{gap:o.space.sm},children:[_jsx(Text,{variant:"label",children:titleOf(e,a)}),""!==b&&_jsx(Text,{variant:"bodySmall",color:"secondary",children:b}),"Reopen"!==e.kind&&e.body?_jsx(Text,{variant:"bodySmall",children:e.body}):null,y?_jsx(Text,{variant:"bodySmall",color:"secondary",children:a.actionExpired}):_jsxs(_Fragment,{children:[_jsx(Text,{variant:"caption",color:"secondary",children:a.actionNote}),""!==m&&_jsx(Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:m}),_jsxs(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:o.space.sm},children:[_jsx(Button,{label:a.actionConfirm,size:"sm",loading:p,disabled:p,onPress:()=>{(async()=>{c("sending"),x("");try{d(await t(e.token)),c("done")}catch(e){const t=e?.message;x("string"==typeof t&&t?t:a.actionFailed),c("ready")}})()},testID:`${s}-confirm`}),_jsx(Button,{label:a.actionDismiss,size:"sm",variant:"outline",disabled:p,onPress:()=>c("dismissed"),testID:`${s}-dismiss`})]})]})]})})};
@@ -1 +0,0 @@
1
- "use strict";import{mergeLabels}from"@webority/markdown-core/chat";import{Banner,Composer,IconButton}from"@webority/mobile-ui";import{useEffect,useState}from"react";import{ComposerAttachments}from"./ComposerAttachments.js";import{jsx as _jsx,Fragment as _Fragment,jsxs as _jsxs}from"react/jsx-runtime";export const ChatComposer=({onSubmit:e,busy:t=!1,onStop:s,disabled:a=!1,maxLength:o=4e3,above:n,below:r,keyboardAware:i,keyboardOffset:c,safeArea:m,attachments:l=[],onAttach:d,onRemoveAttachment:b,editing:p,onCancelEdit:h,labels:u,testID:g="chat-composer"})=>{const f=mergeLabels(u),x=l.some(e=>"Uploading"===e.status),y=l.some(e=>"Ready"===e.status),[j,v]=useState("");useEffect(()=>{v(p?p.text:"")},[p]);const A=p?_jsx(Banner,{message:f.editing,accessibilityRole:"summary",actions:h?[{label:f.cancel,onPress:h,testID:`${g}-cancel-edit`}]:void 0,testID:`${g}-editing`}):null,C=l.length>0?_jsx(ComposerAttachments,{attachments:l,onRemove:b,labels:u,testID:`${g}-attachments`}):null,_=A||C||n?_jsxs(_Fragment,{children:[A,C,n]}):void 0,I=d?_jsx(IconButton,{icon:"paperclip",accessibilityLabel:f.attach,variant:"ghost",tone:"neutral",disabled:a||t,onPress:d,testID:`${g}-attach`}):void 0;return _jsx(Composer,{onSend:e,value:j,onChangeText:v,loading:t,onStop:s,stopLabel:f.stop,disabled:a,maxLength:o,canSend:!x&&(!!y||void 0),placeholder:f.placeholder,accessibilityLabel:f.composer,labels:{send:f.send},leading:I,above:_,below:r,keyboardAware:i,keyboardOffset:c,safeArea:m,testID:g})};
@@ -1 +0,0 @@
1
- "use strict";import{createConversationList,mergeLabels}from"@webority/markdown-core/chat";import{formatDateTime}from"@webority/mobile-core";import{Banner,Button,Card,Dialog,EmptyState,IconButton,Input,Skeleton,Text,useTheme}from"@webority/mobile-ui";import{useEffect,useState,useSyncExternalStore}from"react";import{RefreshControl,ScrollView,View}from"react-native";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const messageOf=(e,t)=>{const s=e?.message;return"string"==typeof s&&s?s:t},IDLE_STATE={items:[],totalCount:null,loading:!0,error:null,hasMore:!1},IDLE={getState:()=>IDLE_STATE,subscribe:()=>()=>{}};export const ChatConversationList=({client:e,onOpen:t,onDeleted:s,pageSize:n=20,labels:a,style:i,testID:l="chat-conversations"})=>{const r=mergeLabels(a),o=useTheme(),[c,m]=useState(null),d=c??IDLE,{items:u,loading:g,error:b,hasMore:p}=useSyncExternalStore(d.subscribe,d.getState),[x,h]=useState(!1),[f,S]=useState(null),[y,I]=useState(!1),[j,v]=useState(""),[D,_]=useState(null),[C,T]=useState(""),[E,w]=useState(!1),[L,$]=useState(""),[P,O]=useState(void 0),[B,M]=useState("");useEffect(()=>{const t=createConversationList({client:e,pageSize:n});return m(t),t.load(),()=>t.dispose()},[e,n]),useEffect(()=>{let t=!0;return e.getSettings().then(e=>{t&&O(e.titleMaxLength)},e=>{t&&M(messageOf(e,r.renameFailed))}),()=>{t=!1}},[e,r.renameFailed]);const V=C.trim(),save=async()=>{if(D&&""!==V){w(!0),$("");try{await(c?.rename(D.publicId,V)),_(null)}catch(e){$(messageOf(e,r.renameFailed))}finally{w(!1)}}},k=!g&&!b&&0===u.length;return _jsxs(ScrollView,{style:i,contentContainerStyle:{padding:o.space.md,gap:o.space.sm,flexGrow:1},refreshControl:_jsx(RefreshControl,{refreshing:x,onRefresh:()=>{(async()=>{h(!0),await(c?.load()),h(!1)})()}}),accessibilityLabel:r.conversations,testID:l,children:[b&&_jsx(Banner,{tone:"danger",message:b.message||r.loadFailed,actions:[{label:r.retry,onPress:()=>{c?.load()}}],testID:`${l}-error`}),k&&_jsx(EmptyState,{size:"sm",title:r.conversationsEmptyTitle,description:r.conversationsEmptyText,testID:`${l}-empty`}),u.map(e=>_jsx(Card,{variant:"outline",padding:"sm",onPress:()=>t(e),accessibilityLabel:e.title||r.untitled,testID:`${l}-item-${e.publicId}`,children:_jsxs(View,{style:{flexDirection:"row",alignItems:"center",gap:o.space.sm},children:[_jsxs(View,{style:{flex:1,minWidth:0},children:[_jsx(Text,{variant:"label",numberOfLines:1,children:e.title||r.untitled}),_jsx(Text,{variant:"caption",color:"secondary",children:formatDateTime(e.lastMessageDateTimeUtc)})]}),_jsx(IconButton,{icon:"edit",variant:"ghost",accessibilityLabel:r.renameConversation,onPress:()=>{$(""),T(e.title??""),_(e)},testID:`${l}-rename-${e.publicId}`}),_jsx(IconButton,{icon:"trash",tone:"danger",variant:"ghost",accessibilityLabel:r.deleteConversation,onPress:()=>{v(""),S(e)},testID:`${l}-delete-${e.publicId}`})]})},e.publicId)),g&&!x&&_jsxs(View,{style:{gap:o.space.sm},accessibilityElementsHidden:!0,children:[_jsx(Skeleton,{height:56}),_jsx(Skeleton,{height:56}),_jsx(Skeleton,{height:56})]}),!g&&p&&_jsx(Button,{label:r.loadMore,variant:"outline",onPress:()=>{c?.loadMore()},testID:`${l}-more`}),_jsxs(Dialog,{visible:null!==D,onClose:()=>{E||_(null)},title:r.renameConversation,dismissOnAction:!1,actions:[{label:r.cancel,tone:"neutral",disabled:E,onPress:()=>_(null)},{label:r.renameSave,disabled:""===V||E,loading:E,onPress:()=>{save()}}],testID:`${l}-rename`,children:[_jsx(Input,{label:r.conversationTitle,value:C,onChangeText:T,maxLength:P,returnKeyType:"done",onSubmitEditing:()=>{save()},testID:`${l}-rename-input`}),""!==(L||B)&&_jsx(Text,{variant:"caption",color:"danger",testID:`${l}-rename-error`,children:L||B})]}),_jsx(Dialog,{visible:null!==f,onClose:()=>{y||S(null)},tone:"warning",title:r.deleteConfirmTitle,message:j||r.deleteConfirmMessage,dismissOnAction:!1,actions:[{label:r.cancel,tone:"neutral",disabled:y,onPress:()=>S(null)},{label:r.deleteConfirm,tone:"danger",loading:y,onPress:()=>{(async()=>{if(f){I(!0),v("");try{await(c?.remove(f.publicId)),s?.(f.publicId),S(null)}catch(e){v(messageOf(e,r.deleteFailed))}finally{I(!1)}}})()}}],testID:`${l}-confirm`})]})};
@@ -1 +0,0 @@
1
- "use strict";import{mergeLabels}from"@webority/markdown-core/chat";import{FloatingActionButton}from"@webority/mobile-ui";import{jsx as _jsx}from"react/jsx-runtime";export const ChatLauncher=({onPress:t,position:o="end",bottomOffset:e,compact:s=!1,labels:r,testID:i="chat-launcher"})=>{const n=mergeLabels(r);return _jsx(FloatingActionButton,{icon:"messages",label:s?void 0:n.launcher,accessibilityLabel:n.launcher,position:"end"===o?"bottomRight":"bottomLeft",bottomOffset:e,onPress:t,testID:i})};
@@ -1 +0,0 @@
1
- "use strict";import{Markdown}from"@webority/mobile-ui";import{jsx as _jsx}from"react/jsx-runtime";export function ChatMarkdown({text:t,resolveLink:i,onLinkPress:n,isCitation:e,onOpenCitation:o,testID:r}){return _jsx(Markdown,{links:"app",headings:"text",resolveLink:i,onAppLinkPress:n,isCitation:e,onOpenCitation:o,testID:r,children:t})}
@@ -1 +0,0 @@
1
- "use strict";import{markdownToPlainText}from"@webority/markdown-core";import{mergeLabels}from"@webority/markdown-core/chat";import{copyText}from"@webority/mobile-core/clipboard";import{Button,Chip,MessageBubble,Text,TypingIndicator,useTheme}from"@webority/mobile-ui";import{memo,useEffect,useMemo,useRef,useState}from"react";import{View}from"react-native";import{ActionCard}from"./ActionCard.js";import{ChatMarkdown}from"./ChatMarkdown.js";import{ReplyRating}from"./ReplyRating.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";function ChatMessageView({turn:e,canRegenerate:t=!1,onRetry:s,onRegenerate:n,onEdit:i,onOpenAttachment:a,onRate:r,resolveLink:o,onLinkPress:l,isCitation:c,onOpenCitation:m,onAskSuggestion:p,confirmAction:u,onViewTicket:g,renderReply:d,labels:x,testID:w="chat-message"}){const y=mergeLabels(x),b=useTheme(),[h,j]=useState(!1),f=useRef(null);useEffect(()=>()=>{null!==f.current&&clearTimeout(f.current)},[]);const T=e.streaming&&!e.answer,k=useMemo(()=>e.streaming?e.answer:markdownToPlainText(e.answer),[e.streaming,e.answer]),_=useMemo(()=>({you:y.you}),[y.you]),I=!e.streaming&&(e.stopped||null!==e.error),R=!e.streaming&&null!==e.questionId,C=e.attachments.length>0||e.stopped||s&&I||i&&R?_jsxs(View,{style:{gap:b.space.xs},children:[e.attachments.length>0?_jsx(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:b.space.xs},children:e.attachments.map(e=>_jsx(Chip,{label:e.fileName,onPress:a?()=>a(e):void 0,testID:`${w}-attachment-${e.publicId}`},e.publicId))}):null,e.stopped?_jsx(Text,{variant:"bodySmall",color:"secondary",accessibilityLiveRegion:"polite",testID:`${w}-stopped`,children:y.stopped}):null,s&&I||i&&R?_jsxs(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:b.space.xs},children:[s&&I?_jsx(Button,{label:y.retry,variant:"link",size:"sm",onPress:()=>s(e.id),testID:`${w}-retry`}):null,i&&R?_jsx(Button,{label:y.edit,variant:"link",size:"sm",onPress:()=>i(e.id),testID:`${w}-edit`}):null]}):null]}):null;return _jsxs(View,{style:{gap:b.space.sm},testID:w,children:[""!==e.question&&_jsx(MessageBubble,{side:"mine",text:e.question,labels:_,footer:C,testID:`${w}-question`}),T?_jsx(TypingIndicator,{label:y.thinking,testID:`${w}-thinking`}):null,""!==e.answer?_jsx(MessageBubble,{side:"theirs",author:y.assistant,text:k,streaming:e.streaming,onCopy:()=>{copyText(markdownToPlainText(e.answer))},testID:`${w}-answer`,children:d?d(e,{streaming:e.streaming}):_jsx(ChatMarkdown,{text:e.answer,resolveLink:o,onLinkPress:l,isCitation:c,onOpenCitation:m})}):null,e.streaming&&e.step?_jsx(Text,{variant:"caption",color:"secondary",accessibilityLiveRegion:"polite",testID:`${w}-step`,children:y.toolStep(e.step)}):null,e.streaming||""===e.answer?null:_jsx(Button,{label:h?y.copied:y.copy,variant:"link",size:"sm",onPress:()=>{(async()=>{await copyText(markdownToPlainText(e.answer))&&(j(!0),null!==f.current&&clearTimeout(f.current),f.current=setTimeout(()=>j(!1),2e3))})()},testID:`${w}-copy`}),p&&!e.streaming&&e.suggestions.length>0?_jsx(View,{accessibilityRole:"list",accessibilityLabel:y.suggestions,style:{flexDirection:"row",flexWrap:"wrap",gap:b.space.xs},children:e.suggestions.map((e,t)=>_jsx(Chip,{label:e,onPress:()=>p(e),testID:`${w}-suggestion-${t}`},e))}):null,t&&n&&!e.streaming&&""!==e.answer?_jsx(Button,{label:y.regenerate,variant:"link",size:"sm",onPress:()=>n(e.id),testID:`${w}-regenerate`}):null,e.error&&_jsx(Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:e.error.message}),u&&!e.streaming&&e.actions.map(e=>_jsx(ActionCard,{action:e,confirmAction:u,onViewTicket:g,labels:x},e.token)),r&&e.messageId&&!e.streaming&&_jsx(ReplyRating,{rating:e.rating,onRate:(t,s)=>r(e.id,t,s),labels:x})]})}export const ChatMessage=memo(ChatMessageView);
@@ -1 +0,0 @@
1
- "use strict";import{mergeLabels}from"@webority/markdown-core/chat";import{Banner,Button,EmptyState,Spinner,Text,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{ChatComposer}from"./ChatComposer.js";import{ChatThread}from"./ChatThread.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";export function ChatScreen({chat:e,pickAttachments:t,onOpenAttachment:s,title:a,headerActions:r,empty:n,disclaimer:o,maxLength:i=4e3,allowanceThreshold:l=10,rating:m=!0,keyboardOffset:c,testID:d="chat-screen",...g}){const h=mergeLabels(g.labels),p=useTheme(),x=e.messagesLeftToday,b=void 0===o?h.disclaimer:o,y=t&&e.settings?.attachments?async()=>e.attach(await t()):void 0;return _jsxs(View,{style:{flex:1,backgroundColor:p.colors.bg},testID:d,children:[_jsxs(View,{style:{flexDirection:"row",alignItems:"center",gap:p.space.sm,paddingHorizontal:p.space.md,paddingVertical:p.space.sm,borderBottomWidth:1,borderBottomColor:p.colors["border-subtle"]},children:[_jsx(Text,{variant:"title",accessibilityRole:"header",style:{flex:1},numberOfLines:1,children:a??h.panelTitle}),r,_jsx(Button,{label:h.newChat,size:"sm",variant:"soft",leftIcon:"add",disabled:0===e.turns.length&&!e.loading,onPress:e.newConversation,testID:`${d}-new`})]}),e.loading?_jsx(View,{style:{flex:1,alignItems:"center",justifyContent:"center"},children:_jsx(Spinner,{message:h.loadingConversation,testID:`${d}-loading`})}):_jsx(ChatThread,{turns:e.turns,style:{flex:1},keyboardOffset:c,onRate:m?e.rate:void 0,onRetry:e.retry,onRegenerate:e.regenerate,onEdit:e.startEdit,onOpenAttachment:s,empty:n??_jsx(EmptyState,{fill:!0,size:"sm",title:h.emptyTitle,description:h.emptyText,testID:`${d}-empty`}),testID:`${d}-thread`,...g,onAskSuggestion:e.submit}),_jsx(ChatComposer,{onSubmit:t=>{e.submit(t)},busy:e.streaming,onStop:e.stop,disabled:0===x||e.loading,maxLength:i,keyboardOffset:c,labels:g.labels,onAttach:y,attachments:e.attachments,onRemoveAttachment:t=>{e.removeAttachment(t)},editing:e.editing,onCancelEdit:e.cancelEdit,testID:`${d}-composer`,above:_jsxs(_Fragment,{children:[e.loadError&&_jsx(Banner,{tone:"danger",message:e.loadError.message,testID:`${d}-load-error`}),e.settingsError&&_jsx(Banner,{tone:"danger",message:e.settingsError.message,testID:`${d}-settings-error`}),null!==x&&x<=l&&_jsx(Text,{variant:"caption",color:0===x?"danger":"secondary",accessibilityLiveRegion:"polite",testID:`${d}-allowance`,children:h.allowance(x)})]}),below:b?_jsx(Text,{variant:"caption",color:"tertiary",testID:`${d}-disclaimer`,children:b}):null})]})}
@@ -1 +0,0 @@
1
- "use strict";import{mergeLabels}from"@webority/markdown-core/chat";import{MessageList,useTheme}from"@webority/mobile-ui";import{useMemo}from"react";import{View}from"react-native";import{ChatMessage}from"./ChatMessage.js";import{jsx as _jsx}from"react/jsx-runtime";const turnKey=e=>e.id,followTurn=()=>!0,TurnGap=()=>{const e=useTheme();return _jsx(View,{style:{height:e.space.lg}})};export function ChatThread({turns:e,empty:t,keyboardAware:r,keyboardOffset:s,onRetry:o,onRegenerate:n,onEdit:a,onOpenAttachment:i,onAskSuggestion:m,style:u,testID:l="chat-thread",...g}){const d=mergeLabels(g.labels),c=useMemo(()=>[...e].reverse(),[e]),h=useMemo(()=>{const t=e[e.length-1];return t&&null!==t.messageId&&!t.streaming?t.id:null},[e]),y=e[e.length-1]?.id;return _jsx(MessageList,{messages:c,keyExtractor:turnKey,renderMessage:({item:e})=>_jsx(ChatMessage,{turn:e,onRetry:o,canRegenerate:e.id===h,onRegenerate:e.id===h?n:void 0,onEdit:a,onOpenAttachment:i,testID:`${l}-${e.id}`,...g,onAskSuggestion:e.id===y?m:void 0}),followNew:followTurn,empty:t,ItemSeparatorComponent:TurnGap,keyboardAware:r,keyboardOffset:s,accessibilityLabel:d.thread,style:u,testID:l})}
@@ -1 +0,0 @@
1
- "use strict";import{mergeLabels}from"@webority/markdown-core/chat";import{Chip,ProgressBar,Text,useTheme}from"@webority/mobile-ui";import{useMemo}from"react";import{StyleSheet,View}from"react-native";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const ComposerAttachments=({attachments:e,onRemove:t,labels:s,testID:r="composer-attachments"})=>{const o=useTheme(),a=useMemo(()=>buildStyles(o),[o]),i=mergeLabels(s),m=useMemo(()=>({remove:i.removeAttachment}),[i.removeAttachment]);return _jsx(View,{style:a.root,testID:r,children:_jsx(View,{style:a.row,children:e.map(e=>_jsxs(View,{style:a.item,children:[_jsx(Chip,{label:e.fileName,variant:"soft",onRemove:t?()=>t(e.key):void 0,labels:m,removeTestID:`chat-attachment-remove-${e.key}`,testID:`${r}-${e.key}`}),"Uploading"===e.status?_jsx(ProgressBar,{progress:e.progress??void 0,label:i.attachmentUploading,height:4,containerStyle:a.progress}):null,"Failed"===e.status?_jsx(Text,{variant:"caption",color:"danger",accessibilityLiveRegion:"polite",children:i.attachmentFailed}):null]},e.key))})})};const buildStyles=e=>StyleSheet.create({root:{gap:e.space.xs},row:{flexDirection:"row",flexWrap:"wrap",gap:e.space.xs},item:{gap:e.space.xxs,maxWidth:"100%"},progress:{minWidth:120}});
@@ -1 +0,0 @@
1
- "use strict";import{mergeLabels}from"@webority/markdown-core/chat";import{Button,Input,Text,useTheme}from"@webority/mobile-ui";import{useState}from"react";import{View}from"react-native";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const ReplyRating=({rating:e=null,onRate:t,noteMaxLength:s=1e3,labels:a,testID:i="chat-rating"})=>{const n=mergeLabels(a),o=useTheme(),[l,r]=useState(!1),[c,d]=useState(!1),[p,m]=useState(""),[x,b]=useState(""),[g,u]=useState(!1),save=async(e,s)=>{r(!0),b("");try{await t(e,s),d("Down"===e&&void 0===s),u("Up"===e||void 0!==s),void 0!==s&&m("")}catch{b(n.ratingFailed)}finally{r(!1)}};return _jsxs(View,{style:{gap:o.space.sm},testID:i,children:[_jsxs(View,{style:{flexDirection:"row",flexWrap:"wrap",alignItems:"center",gap:o.space.xs},children:[_jsx(Button,{label:n.rateUp,size:"sm",leftIcon:"like",variant:"Up"===e?"soft":"ghost",accessibilityState:{selected:"Up"===e,disabled:l},"aria-selected":"Up"===e,"aria-disabled":l,disabled:l,onPress:()=>{save("Up")},testID:`${i}-up`}),_jsx(Button,{label:n.rateDown,size:"sm",leftIcon:"dislike",variant:"Down"===e?"soft":"ghost",accessibilityState:{selected:"Down"===e,disabled:l},"aria-selected":"Down"===e,"aria-disabled":l,disabled:l,onPress:()=>{save("Down")},testID:`${i}-down`}),g&&!c&&_jsx(Text,{variant:"caption",color:"secondary",accessibilityLiveRegion:"polite",children:n.rated})]}),""!==x&&_jsx(Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:x}),c&&_jsxs(View,{style:{gap:o.space.sm},children:[_jsx(Input,{label:n.ratingNote,helperText:n.ratingNoteHint,multiline:!0,maxLength:s,value:p,onChangeText:m,testID:`${i}-note`}),_jsxs(View,{style:{flexDirection:"row",gap:o.space.sm},children:[_jsx(Button,{label:n.ratingNoteSend,size:"sm",loading:l,disabled:l,onPress:()=>{save("Down",p)},testID:`${i}-note-send`}),_jsx(Button,{label:n.ratingNoteSkip,size:"sm",variant:"outline",disabled:l,onPress:()=>{d(!1),u(!0)},testID:`${i}-note-skip`})]})]})]})};
@@ -1,23 +0,0 @@
1
- import type { SupportAction, SupportActionTicket } from "@webority/markdown-core/chat";
2
- import { type ChatLabels } from "@webority/markdown-core/chat";
3
- import type React from "react";
4
- export interface ActionCardProps {
5
- action: SupportAction;
6
- /**
7
- * Sends the person's yes, e.g. mobile-support's `supportClient.confirmAction`; resolves to the
8
- * ticket raised, replied on or reopened. A rejection's `message` is shown when present.
9
- */
10
- confirmAction: (token: string) => Promise<SupportActionTicket>;
11
- /** Shows a View ticket button once confirmed. */
12
- onViewTicket?: (ticket: SupportActionTicket) => void;
13
- labels?: Partial<ChatLabels>;
14
- testID?: string;
15
- }
16
- /**
17
- * One support action the assistant prepared, shown under its reply. Nothing reaches support until
18
- * the person confirms. The card moves from ready to sending to done (with View ticket), or to
19
- * dismissed on Not now. An expired action (a reopened conversation) still shows what was offered,
20
- * without a button that could only fail.
21
- */
22
- export declare const ActionCard: React.FC<ActionCardProps>;
23
- //# sourceMappingURL=ActionCard.d.ts.map