@webority/mobile-chat 0.135.1 → 0.137.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 (61) hide show
  1. package/lib/commonjs/AgentByline.js +1 -1
  2. package/lib/commonjs/ChatComposer.js +1 -1
  3. package/lib/commonjs/ChatFrame.js +1 -1
  4. package/lib/commonjs/ChatLauncher.js +1 -1
  5. package/lib/commonjs/ChatLiveBar.js +1 -1
  6. package/lib/commonjs/ChatMessageActions.js +1 -1
  7. package/lib/commonjs/ChatSheet.js +1 -1
  8. package/lib/commonjs/ChatStarters.js +1 -1
  9. package/lib/commonjs/ChatThread.js +1 -1
  10. package/lib/commonjs/chatShared.js +1 -1
  11. package/lib/commonjs/loaders/ReplyRing.js +1 -0
  12. package/lib/commonjs/renderers/ActionPart.js +1 -1
  13. package/lib/commonjs/renderers/InputRequestPart.js +1 -1
  14. package/lib/commonjs/renderers/QuickRepliesPart.js +1 -1
  15. package/lib/commonjs/renderers/TextPart.js +1 -1
  16. package/lib/commonjs/renderers/chipLook.js +1 -0
  17. package/lib/commonjs/speech/azureSpeech.js +1 -1
  18. package/lib/commonjs/useChat.js +1 -1
  19. package/lib/commonjs/useTranscriptActions.js +1 -1
  20. package/lib/module/AgentByline.js +1 -1
  21. package/lib/module/ChatComposer.js +1 -1
  22. package/lib/module/ChatFrame.js +1 -1
  23. package/lib/module/ChatLauncher.js +1 -1
  24. package/lib/module/ChatLiveBar.js +1 -1
  25. package/lib/module/ChatMessageActions.js +1 -1
  26. package/lib/module/ChatSheet.js +1 -1
  27. package/lib/module/ChatStarters.js +1 -1
  28. package/lib/module/ChatThread.js +1 -1
  29. package/lib/module/chatShared.js +1 -1
  30. package/lib/module/loaders/ReplyRing.js +1 -0
  31. package/lib/module/renderers/ActionPart.js +1 -1
  32. package/lib/module/renderers/InputRequestPart.js +1 -1
  33. package/lib/module/renderers/QuickRepliesPart.js +1 -1
  34. package/lib/module/renderers/TextPart.js +1 -1
  35. package/lib/module/renderers/chipLook.js +1 -0
  36. package/lib/module/speech/azureSpeech.js +1 -1
  37. package/lib/module/useChat.js +1 -1
  38. package/lib/module/useTranscriptActions.js +1 -1
  39. package/lib/typescript/commonjs/AgentByline.d.ts +2 -1
  40. package/lib/typescript/commonjs/ChatComposer.d.ts +6 -3
  41. package/lib/typescript/commonjs/ChatFrame.d.ts +3 -3
  42. package/lib/typescript/commonjs/ChatLauncher.d.ts +6 -2
  43. package/lib/typescript/commonjs/ChatStarters.d.ts +4 -1
  44. package/lib/typescript/commonjs/ChatThread.d.ts +10 -4
  45. package/lib/typescript/commonjs/chatShared.d.ts +1 -0
  46. package/lib/typescript/commonjs/loaders/ReplyRing.d.ts +9 -0
  47. package/lib/typescript/commonjs/renderers/chipLook.d.ts +7 -0
  48. package/lib/typescript/commonjs/types.d.ts +6 -1
  49. package/lib/typescript/commonjs/useChat.d.ts +3 -1
  50. package/lib/typescript/module/AgentByline.d.ts +2 -1
  51. package/lib/typescript/module/ChatComposer.d.ts +6 -3
  52. package/lib/typescript/module/ChatFrame.d.ts +3 -3
  53. package/lib/typescript/module/ChatLauncher.d.ts +6 -2
  54. package/lib/typescript/module/ChatStarters.d.ts +4 -1
  55. package/lib/typescript/module/ChatThread.d.ts +10 -4
  56. package/lib/typescript/module/chatShared.d.ts +1 -0
  57. package/lib/typescript/module/loaders/ReplyRing.d.ts +9 -0
  58. package/lib/typescript/module/renderers/chipLook.d.ts +7 -0
  59. package/lib/typescript/module/types.d.ts +6 -1
  60. package/lib/typescript/module/useChat.d.ts +3 -1
  61. package/package.json +12 -11
@@ -1 +1 @@
1
- "use strict";import{mergeLabels,mergeLook}from"@webority/chat-core";import{BottomSheet,useReducedMotion,useTheme}from"@webority/mobile-ui";import{useEffect,useMemo,useRef,useState}from"react";import{StyleSheet,View}from"react-native";import{ChatAppearanceScope}from"./ChatAppearanceScope.js";import{ChatFrame}from"./ChatFrame.js";import{ChatLauncher}from"./ChatLauncher.js";import{ChatNudge}from"./ChatNudge.js";import{focusForAccessibility}from"./chatShared.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const DEFAULT_SNAP_POINTS=["92%"],DEFAULT_BOTTOM_OFFSET=16;export function ChatSheet({chat:e,labels:t,renderers:o,layoutParts:s,loader:n="Steps",look:r,appearance:a,pickAttachments:i,onOpenAttachment:c,onOpenTarget:l,onNavigate:u,keyboardOffset:f,open:p,defaultOpen:h=!1,onOpenChange:m,snapPoints:d=DEFAULT_SNAP_POINTS,openTicket:b,handoffHosts:g,resolveLink:C,conversationId:S,onClose:j,testID:y="chat-sheet"}){const k=useTheme(),T=mergeLabels(t),x=useMemo(()=>mergeLook(r),[r]),A=useReducedMotion(),_="Reduced"===x.motion||A,O=a?.position??"end",E=void 0!==p,L=E?p:e.open,F=useRef(null),P=useRef(!1),R=useRef(S??null),v=e.setChatVisible,N=useRef(!1),D=!N.current,[I,w]=useState(0),M=useRef(L);useEffect(()=>{L&&(N.current=!0)},[L]),useEffect(()=>{L&&!M.current&&w(e=>e+1),M.current=L},[L]),useEffect(()=>{P.current||(P.current=!0,E||!h||null===e.profile||e.open||e.session.open({trigger:"manual"}))},[E,h,e.profile,e.open,e.session]),useEffect(()=>{E&&(p&&!e.open&&e.session.open({trigger:"manual"}),!p&&e.open&&e.session.close("button"))},[E,p,e.open,e.session]);const V=useRef(L);if(useEffect(()=>{V.current&&!L&&focusForAccessibility(F.current),V.current=L},[L]),useEffect(()=>{v(L)},[v,L]),useEffect(()=>{!E&&S&&S!==R.current&&null!==e.profile&&(R.current=S,e.open||(e.session.open({trigger:"manual"}),m?.(!0)))},[E,S,e.profile,e.open,e.session,m]),null===e.profile||!e.features.VisitorChat)return null;const setOpen=t=>{t?e.session.open({trigger:"manual"}):e.session.close("button"),m?.(t)},closeSheet=()=>{setOpen(!1),j?.()},B=a?.offsetY??16;return _jsx(View,{testID:y,style:StyleSheet.absoluteFill,pointerEvents:"box-none",children:_jsxs(ChatAppearanceScope,{appearance:a,children:[L?null:_jsx(ChatLauncher,{look:x,label:T.launcher,side:O,offsetX:a?.offsetX??0,offsetY:B,enter:D,reduced:_,buttonRef:F,onPress:()=>setOpen(!0),testID:`${y}-launcher`}),_jsx(ChatNudge,{chat:e,labels:T,enabled:!L&&e.features.Nudges,onActivate:()=>setOpen(!0),bottomOffset:B,position:O,testID:`${y}-nudge`}),_jsx(BottomSheet,{open:L,onClose:closeSheet,snapPoints:d,keyboardBehavior:"shift",scrollable:!1,enablePanDownToClose:!0,enableBackdropPress:!0,accessibilityViewIsModal:!0,accessibilityLabel:T.panelTitle,children:_jsx(View,{style:{flex:1,backgroundColor:k.colors.bg},children:_jsx(ChatFrame,{chat:e,labels:T,renderers:o,layoutParts:s,loader:n,look:r,pickAttachments:i,onOpenAttachment:c,onOpenTarget:l,onNavigate:u,openTicket:b,handoffHosts:g,resolveLink:C,keyboardOffset:f,onClose:closeSheet,layout:"sheet",enterKey:I,testID:`${y}-frame`})})})]})})}
1
+ "use strict";import{mergeLabels,mergeLook}from"@webority/chat-core";import{BottomSheet,useReducedMotion,useTheme}from"@webority/mobile-ui";import{useEffect,useMemo,useRef,useState}from"react";import{StyleSheet,View}from"react-native";import{ChatAppearanceScope}from"./ChatAppearanceScope.js";import{ChatFrame}from"./ChatFrame.js";import{ChatLauncher}from"./ChatLauncher.js";import{ChatNudge}from"./ChatNudge.js";import{focusForAccessibility}from"./chatShared.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const DEFAULT_SNAP_POINTS=["92%"],DEFAULT_BOTTOM_OFFSET=16;export function ChatSheet({chat:e,labels:t,renderers:o,layoutParts:s,loader:r="Steps",look:n,appearance:a,pickAttachments:i,onOpenAttachment:c,onOpenTarget:l,onNavigate:u,keyboardOffset:f,open:p,defaultOpen:h=!1,onOpenChange:m,snapPoints:d=DEFAULT_SNAP_POINTS,openTicket:b,handoffHosts:g,resolveLink:C,conversationId:S,onClose:k,testID:j="chat-sheet"}){const y=useTheme(),x=mergeLabels(t),T=useMemo(()=>mergeLook(n),[n]),A=useReducedMotion(),_="Reduced"===T.motion||A,L=a?.position??"end",O=void 0!==p,v=O?p:e.open,E=useRef(null),F=useRef(!1),P=useRef(S??null),R=e.setChatVisible,N=useRef(!1),D=!N.current,[I,w]=useState(0),M=useRef(v);useEffect(()=>{v&&(N.current=!0)},[v]),useEffect(()=>{v&&!M.current&&w(e=>e+1),M.current=v},[v]),useEffect(()=>{F.current||(F.current=!0,O||!h||null===e.profile||e.open||e.session.open({trigger:"manual"}))},[O,h,e.profile,e.open,e.session]),useEffect(()=>{O&&(p&&!e.open&&e.session.open({trigger:"manual"}),!p&&e.open&&e.session.close("button"))},[O,p,e.open,e.session]);const V=useRef(v);if(useEffect(()=>{V.current&&!v&&focusForAccessibility(E.current),V.current=v},[v]),useEffect(()=>{R(v)},[R,v]),useEffect(()=>{!O&&S&&S!==P.current&&null!==e.profile&&(P.current=S,e.open||(e.session.open({trigger:"manual"}),m?.(!0)))},[O,S,e.profile,e.open,e.session,m]),null===e.profile||!e.features.VisitorChat)return null;const setOpen=t=>{t?e.session.open({trigger:"manual"}):e.session.close("button"),m?.(t)},closeSheet=()=>{setOpen(!1),k?.()},B=a?.offsetY??16;return _jsx(View,{testID:j,style:StyleSheet.absoluteFill,pointerEvents:"box-none",children:_jsxs(ChatAppearanceScope,{appearance:a,children:[_jsx(ChatLauncher,{look:T,hidden:v,label:e.profile?.experience.launcher?.hoverLabel||x.launcher,side:L,offsetX:a?.offsetX??0,offsetY:B,enter:D,reduced:_,mark:T.launcher.mark,avatar:T.avatar,buttonRef:E,onPress:()=>setOpen(!0),testID:`${j}-launcher`}),_jsx(ChatNudge,{chat:e,labels:x,enabled:!v&&e.features.Nudges,onActivate:()=>setOpen(!0),bottomOffset:B,position:L,testID:`${j}-nudge`}),_jsx(BottomSheet,{open:v,onClose:closeSheet,snapPoints:d,keyboardBehavior:"shift",scrollable:!1,enablePanDownToClose:!0,enableBackdropPress:!0,accessibilityViewIsModal:!0,accessibilityLabel:x.panelTitle,children:_jsx(View,{style:{flex:1,backgroundColor:y.colors.bg},children:_jsx(ChatFrame,{chat:e,labels:x,renderers:o,layoutParts:s,loader:r,look:n,pickAttachments:i,onOpenAttachment:c,onOpenTarget:l,onNavigate:u,openTicket:b,handoffHosts:g,resolveLink:C,keyboardOffset:f,onClose:closeSheet,layout:"sheet",enterKey:I,testID:`${j}-frame`})})})]})})}
@@ -1 +1 @@
1
- "use strict";import{formatDate}from"@webority/mobile-core";import{Card,Chip,Text,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{ChatEntrance}from"./ChatEntrance.js";import{ChatOpenTickets}from"./ChatOpenTickets.js";import{ChatPastChats}from"./ChatPastChats.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export function ChatStarters({chat:t,labels:e,openTicket:s,testID:a="chat-starters"}){const r=useTheme(),i=t.profile,n=t.greeting??"";if(!i)return null;const l=t.features.Starters&&t.starters.length>0,c=t.lastConversation,o=t.features.ResumeLast&&!t.features.History&&null!==c;return _jsxs(View,{accessibilityLabel:e.emptyTitle,style:{flex:1,justifyContent:"center",alignItems:"center",gap:r.space.md,padding:r.space.md},testID:a,children:[_jsx(Text,{variant:"h2",align:"center",children:n}),l?_jsx(View,{accessibilityRole:"none",accessibilityLabel:e.starters,style:{flexDirection:"row",flexWrap:"wrap",justifyContent:"center",gap:r.space.xs},children:t.starters.map((e,s)=>_jsx(ChatEntrance,{index:s,children:_jsx(Chip,{label:e.label,leftIcon:e.icon?e.icon:void 0,onPress:()=>{t.submit(e.message)},testID:`${a}-${e.id}`})},e.id))}):null,o&&c?_jsxs(Card,{variant:"outline",padding:"sm",onPress:()=>{t.resumeLast()},testID:`${a}-resume`,children:[_jsx(Text,{variant:"caption",color:"secondary",children:e.resumeLast}),_jsx(Text,{variant:"label",numberOfLines:1,children:c.title||e.untitled}),_jsx(Text,{variant:"caption",color:"secondary",children:formatDate(c.lastActivityDateTimeUtc)})]}):null,t.features.History?_jsx(ChatPastChats,{chat:t,labels:e,testID:`${a}-past-chats`}):null,_jsx(ChatOpenTickets,{chat:t,labels:e,onOpenTicket:s})]})}
1
+ "use strict";import{formatDate}from"@webority/mobile-core";import{Avatar,Card,Chip,Text,useTheme}from"@webority/mobile-ui";import{useEffect,useState}from"react";import{View}from"react-native";import{ChatEntrance}from"./ChatEntrance.js";import{ChatOpenTickets}from"./ChatOpenTickets.js";import{ChatPastChats}from"./ChatPastChats.js";import{TypingPill}from"./loaders/TypingPill.js";import{chipLook}from"./renderers/chipLook.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";export function ChatStarters({chat:e,labels:t,openTicket:s,avatar:a,motion:r="On",greetingLoaderMs:i=0,testID:n="chat-starters"}){const l=useTheme(),[o,c]=useState(!(i>0));useEffect(()=>{if(o)return;const e=setTimeout(()=>c(!0),i);return()=>clearTimeout(e)},[o,i]);const m=e.profile,p=e.greeting??"";if(!m)return null;const u=m.assistant.intro,h=e.features.Starters&&e.starters.length>0,d=e.lastConversation,x=e.features.ResumeLast&&!e.features.History&&null!==d;return _jsx(View,{accessibilityLabel:t.emptyTitle,style:{flex:1,justifyContent:"center",alignItems:"center",gap:l.space.md,padding:l.space.md},testID:n,children:o?_jsxs(_Fragment,{children:[a?_jsx(View,{accessibilityElementsHidden:!0,importantForAccessibility:"no-hide-descendants",children:_jsx(Avatar,{size:"lg",name:e.profile?.assistant.name??t.panelTitle,source:{uri:a}})}):null,_jsx(Text,{variant:"h2",align:"center",children:p}),u?_jsx(Text,{variant:"body",color:"secondary",align:"center",children:u}):null,h?_jsx(View,{accessibilityRole:"none",accessibilityLabel:t.starters,style:{flexDirection:"row",flexWrap:"wrap",justifyContent:"center",gap:l.space.xs},children:e.starters.map((t,s)=>_jsx(ChatEntrance,{index:s,children:_jsx(Chip,{...t.variant?chipLook(t.variant):null,label:t.label,leftIcon:t.icon?t.icon:void 0,onPress:()=>{e.submit(t.message)},testID:`${n}-${t.id}`})},t.id))}):null,x&&d?_jsxs(Card,{variant:"outline",padding:"sm",onPress:()=>{e.resumeLast()},testID:`${n}-resume`,children:[_jsx(Text,{variant:"caption",color:"secondary",children:t.resumeLast}),_jsx(Text,{variant:"label",numberOfLines:1,children:d.title||t.untitled}),_jsx(Text,{variant:"caption",color:"secondary",children:formatDate(d.lastActivityDateTimeUtc)})]}):null,e.features.History?_jsx(ChatPastChats,{chat:e,labels:t,testID:`${n}-past-chats`}):null,_jsx(ChatOpenTickets,{chat:e,labels:t,onOpenTicket:s})]}):_jsx(View,{children:_jsx(TypingPill,{motion:r,mark:a?_jsx(Avatar,{size:"xs",name:e.profile?.assistant.name??t.panelTitle,source:{uri:a}}):null})})})}
@@ -1 +1 @@
1
- "use strict";import{createTurnApi,formatChatDateTime,handoffSettledIds,messagePlainText}from"@webority/chat-core";import{Button,MessageBubble,MessageList,Text,useTheme}from"@webority/mobile-ui";import{createElement,memo,useEffect,useMemo,useRef}from"react";import{AccessibilityInfo,View}from"react-native";import{AgentByline}from"./AgentByline.js";import{ChatEntrance}from"./ChatEntrance.js";import{ChatMessageActions}from"./ChatMessageActions.js";import{defaultOpenTarget,focusForAccessibility,messageSignature}from"./chatShared.js";import{ChatLoader}from"./loaders/ChatLoader.js";import{TypingPill}from"./loaders/TypingPill.js";import{defaultRenderers}from"./renderers/index.js";import{NoticePart}from"./renderers/NoticePart.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const MINE=new Set(["Visitor","Customer"]),joinedText=e=>e.filter(e=>"Text"===e.kind).map(e=>e.text).join("\n\n"),renderPart=(e,t,s,a,r,i)=>{const n=e[t.kind];if(n)return createElement(n,{key:i,part:t,message:s,turn:a,pickAttachments:r});const o={kind:"Notice",code:"NeedsNewerApp",text:a.labels.needsNewerApp};return createElement(NoticePart,{key:i,part:o,message:s,turn:a})},sameMessage=(e,t)=>e.signature===t.signature&&e.message.id===t.message.id&&e.message.rating===t.message.rating&&e.message.stored===t.message.stored&&e.groupPosition===t.groupPosition&&e.isLast===t.isLast&&e.handoffSettled===t.handoffSettled&&e.isLastVisitor===t.isLastVisitor&&e.thinking===t.thinking&&e.streaming===t.streaming&&e.pickAttachments===t.pickAttachments&&e.labels===t.labels&&e.all===t.all&&e.layoutParts===t.layoutParts&&e.chat.session===t.chat.session&&e.chat.features===t.chat.features&&e.chat.onNavigate===t.chat.onNavigate&&e.onNavigate===t.onNavigate&&e.onOpenAttachment===t.onOpenAttachment&&e.onOpenTarget===t.onOpenTarget&&e.openTicket===t.openTicket&&e.resolveLink===t.resolveLink&&e.focusComposer===t.focusComposer&&e.byline===t.byline&&e.handoffHosts===t.handoffHosts;function ThreadMessageView({chat:e,message:t,labels:s,all:a,layoutParts:r,groupPosition:i,isLast:n,isLastVisitor:o,pickAttachments:l,onOpenAttachment:c,onOpenTarget:g,onNavigate:m,openTicket:d,handoffHosts:p,resolveLink:u,focusComposer:h,byline:f,sourceRows:y,testID:x}){const T=useTheme(),k=Object.assign(createTurnApi(e.session,{messageId:t.id,labels:s,openAttachment:c,openTarget:g??defaultOpenTarget,onNavigate:m??e.onNavigate,openTicket:d,handoffHosts:p,openCitation:e=>{return t=String(e),void focusForAccessibility(y.current.get(t));var t}}),{resolveLink:u,focusComposer:h,registerSourceRow:(e,t)=>{t?y.current.set(e,t):y.current.delete(e)}});let b=0;const nextSlot=()=>(b+=1,b),A=_jsx(ChatMessageActions,{chat:e,message:t,labels:s,isLast:n,isLastVisitor:o,testID:`${x}-actions`});if(MINE.has(t.author.kind)){const e=t.parts.filter(e=>"File"===e.kind),r=_jsxs(View,{style:{gap:T.space.xs},children:[e.map(e=>renderPart(a,e,t,k,l,`${t.id}-file-${nextSlot()}`)),A]});return _jsx(MessageBubble,{side:"mine",text:joinedText(t.parts),labels:{you:s.you},groupPosition:i,footer:r,testID:x})}const j="Agent"===t.author.kind,w=t.author.displayName||s.agent,v=(r?r(t):t.parts).map(e=>Array.isArray(e)?_jsx(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:T.space.xs},children:e.map(e=>renderPart(a,e,t,k,l,`${t.id}-part-${nextSlot()}`))},`${t.id}-group-${nextSlot()}`):renderPart(a,e,t,k,l,`${t.id}-item-${nextSlot()}`)),N=j&&f?[_jsx(AgentByline,{author:t.author,labels:s},`${t.id}-byline`),...v]:v,_=messagePlainText(t.parts);return _jsx(MessageBubble,{side:"theirs",author:j?void 0:t.author.displayName||s.assistant,text:j?`${s.agentSays(w)} ${_}`:_,streaming:t.streaming,groupPosition:i,footer:A,testID:x,children:N})}const ThreadMessage=memo(ThreadMessageView,sameMessage),TYPING_ORB_MARK=14,TYPING_ASSISTANT_MARK=8,TypingMark=({size:e})=>{const t=useTheme();return _jsx(View,{style:{width:e,height:e,borderRadius:t.radius.pill,backgroundColor:t.colors.primary}})},TYPING_DOT=6,TypingDots=()=>{const e=useTheme();return _jsx(View,{style:{flexDirection:"row",alignItems:"center",gap:e.space.xxs},children:[0,1,2].map(t=>_jsx(View,{style:{width:6,height:6,borderRadius:3,backgroundColor:e.colors["text-muted"]}},t))})},TurnGap=()=>{const e=useTheme();return _jsx(View,{style:{height:e.space.lg}})},followNew=()=>!0;export function ChatThread({chat:e,labels:t,renderers:s,layoutParts:a,loader:r="Steps",motion:i="On",pickAttachments:n,onOpenAttachment:o,onOpenTarget:l,onNavigate:c,openTicket:g,handoffHosts:m,resolveLink:d,focusComposer:p,keyboardAware:u,keyboardOffset:h,empty:f,style:y,testID:x="chat-thread"}){const T=useTheme(),k=useMemo(()=>({...defaultRenderers,...s}),[s]),b=e.messages[0],A=e.greeting??"",j=useMemo(()=>""!==A&&void 0!==b&&MINE.has(b.author.kind)?{...b,id:"greeting",author:{...b.author,kind:"Assistant",displayName:null,avatarUrl:null},parts:[{kind:"Text",text:A}],stored:!1,streaming:!1,restored:!1,rating:null}:null,[A,b]),w=useMemo(()=>{const t=e.messages.filter(e=>!(e.streaming&&0===e.parts.length)).reverse();return j?[...t,j]:t},[e.messages,j]),v=e.messages[e.messages.length-1]?.id,N=useRef(new Map),_=useRef(null);useEffect(()=>{if(null!==_.current)for(const s of e.messages){if(MINE.has(s.author.kind)||s.streaming||s.restored||_.current.has(s.id))continue;if("Agent"===s.author.kind&&!s.stored)continue;_.current.add(s.id);const e=messagePlainText(s.parts);""!==e&&AccessibilityInfo.announceForAccessibility("Agent"===s.author.kind?`${t.agentSays(s.author.displayName||t.agent)} ${e}`:e)}else _.current=new Set(e.messages.map(e=>e.id))},[e.messages,t]);const M=useMemo(()=>{for(let t=e.messages.length-1;t>=0;t-=1){const s=e.messages[t];if(s?.stored&&"Visitor"===s.author.kind)return s.id}},[e.messages]),P=useMemo(()=>{const t=new Set;return e.messages.forEach((s,a)=>{if("Agent"!==s.author.kind)return;const r=e.messages[a-1];"Agent"===r?.author.kind&&(r.author.displayName||"")===(s.author.displayName||"")||t.add(s.id)}),t},[e.messages]),L=useMemo(()=>handoffSettledIds(e.messages),[e.messages]),I=e.turnError,S="daily_limit"===I?.code,C=null!==I&&/feature_off$/.test(I.code),$=S&&I?.resetsDateTimeUtc?` ${t.dailyLimitRefresh(formatChatDateTime(I.resetsDateTimeUtc))}`:"",D=e.streaming||null===I&&!e.stopped?null:_jsxs(View,{style:{gap:T.space.xs},testID:`${x}-error`,children:[_jsx(Text,null!==I?{variant:"bodySmall",color:"danger",accessibilityRole:S?void 0:"alert",accessibilityLiveRegion:S?"polite":void 0,children:`${I.message}${$}`}:{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:t.stopped}),!e.features.Retry||S||C?null:_jsx(View,{style:{flexDirection:"row"},children:_jsx(Button,{label:t.retry,variant:"link",size:"sm",onPress:()=>{e.retry()},testID:`${x}-retry`})})]}),V=e.thinking&&null!==e.profile?_jsx(ChatLoader,{style:r,steps:e.steps,phrases:e.profile.experience.pacing.thinkingPhrases,intervalMs:e.profile.experience.pacing.phraseIntervalMs,announce:t.preparingAnswer(e.profile.assistant.name),motion:i}):null,O=!0===e.pending?.typing?_jsx(TypingPill,{motion:i,mark:_jsx(TypingMark,{size:"Orb"===r?14:8})}):null,R=null!==e.agentTyping&&"WithAgent"===e.conversationState?_jsxs(View,{style:{gap:T.space.xs,alignSelf:"flex-start"},children:[_jsx(TypingPill,{motion:i,mark:_jsx(TypingDots,{})}),_jsx(Text,{variant:"caption",color:"secondary",accessibilityLiveRegion:"polite",children:t.agentTyping(e.agentTyping.displayName||t.agent)})]}):null,E=O||V||D||R?_jsxs(View,{style:{gap:T.space.sm},children:[O,V,R,D]}):void 0;return _jsx(MessageList,{messages:w,keyExtractor:e=>e.id,renderMessage:({item:s,groupPosition:r})=>_jsx(ChatEntrance,{animate:!s.restored,children:_jsx(ThreadMessage,{chat:e,message:s,signature:messageSignature(s),labels:t,all:k,layoutParts:a,groupPosition:r,isLast:s.id===v,isLastVisitor:s.id===M,handoffSettled:L.has(s.id),thinking:e.thinking,streaming:e.streaming,pickAttachments:n,onOpenAttachment:o,onOpenTarget:l,onNavigate:c,openTicket:g,handoffHosts:m,resolveLink:d,focusComposer:p,byline:P.has(s.id),sourceRows:N,testID:`${x}-${s.id}`})}),getAuthorKey:e=>e.author.kind,getDate:e=>e.createdDateTimeUtc,followNew:followNew,typing:E,empty:f,ItemSeparatorComponent:TurnGap,keyboardAware:u,keyboardOffset:h,accessibilityLabel:t.thread,style:y,testID:x})}
1
+ "use strict";import{createTurnApi,formatChatDateTime,handoffSettledIds,messagePlainText}from"@webority/chat-core";import{Avatar,Button,MessageBubble,MessageList,Text,useReducedMotion,useTheme}from"@webority/mobile-ui";import{createElement,memo,useEffect,useMemo,useRef}from"react";import{AccessibilityInfo,Platform,View}from"react-native";import{AgentByline}from"./AgentByline.js";import{ChatEntrance}from"./ChatEntrance.js";import{ChatMessageActions}from"./ChatMessageActions.js";import{defaultOpenTarget,focusForAccessibility,messageSignature}from"./chatShared.js";import{ChatLoader}from"./loaders/ChatLoader.js";import{ReplyRing}from"./loaders/ReplyRing.js";import{TypingPill}from"./loaders/TypingPill.js";import{defaultRenderers}from"./renderers/index.js";import{NoticePart}from"./renderers/NoticePart.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const MINE=new Set(["Visitor","Customer"]),visuallyHidden={position:"absolute",left:-1e4,width:1,height:1,overflow:"hidden"},joinedText=e=>e.filter(e=>"Text"===e.kind).map(e=>e.text).join("\n\n"),renderPart=(e,t,s,a,i,r)=>{const n=e[t.kind];if(n)return createElement(n,{key:r,part:t,message:s,turn:a,pickAttachments:i});const o={kind:"Notice",code:"NeedsNewerApp",text:a.labels.needsNewerApp};return createElement(NoticePart,{key:r,part:o,message:s,turn:a})},sameMessage=(e,t)=>e.signature===t.signature&&e.message.id===t.message.id&&e.message.rating===t.message.rating&&e.message.stored===t.message.stored&&e.groupPosition===t.groupPosition&&e.isLast===t.isLast&&e.handoffSettled===t.handoffSettled&&e.isLastVisitor===t.isLastVisitor&&e.thinking===t.thinking&&e.streaming===t.streaming&&e.pickAttachments===t.pickAttachments&&e.labels===t.labels&&e.all===t.all&&e.layoutParts===t.layoutParts&&e.chat.session===t.chat.session&&e.chat.features===t.chat.features&&e.chat.onNavigate===t.chat.onNavigate&&e.onNavigate===t.onNavigate&&e.onOpenAttachment===t.onOpenAttachment&&e.onOpenTarget===t.onOpenTarget&&e.openTicket===t.openTicket&&e.resolveLink===t.resolveLink&&e.focusComposer===t.focusComposer&&e.byline===t.byline&&e.avatar===t.avatar&&e.replyAvatars===t.replyAvatars&&e.avatarStart===t.avatarStart&&e.expressive===t.expressive&&e.reduced===t.reduced&&e.handoffHosts===t.handoffHosts;function ThreadMessageView({chat:e,message:t,labels:s,all:a,layoutParts:i,groupPosition:r,isLast:n,isLastVisitor:o,pickAttachments:l,onOpenAttachment:d,onOpenTarget:c,onNavigate:g,openTicket:m,handoffHosts:p,resolveLink:u,focusComposer:h,byline:f,avatar:y,replyAvatars:x,avatarStart:v,expressive:T,reduced:k,sourceRows:A,testID:b}){const j=useTheme(),w=Object.assign(createTurnApi(e.session,{messageId:t.id,labels:s,openAttachment:d,openTarget:c??defaultOpenTarget,onNavigate:g??e.onNavigate,openTicket:m,handoffHosts:p,openCitation:e=>{return t=String(e),void focusForAccessibility(A.current.get(t));var t}}),{resolveLink:u,focusComposer:h,registerSourceRow:(e,t)=>{t?A.current.set(e,t):A.current.delete(e)}});let _=0;const nextSlot=()=>(_+=1,_),M=_jsx(ChatMessageActions,{chat:e,message:t,labels:s,isLast:n,isLastVisitor:o,testID:`${b}-actions`});if(MINE.has(t.author.kind)){const e=t.parts.filter(e=>"File"===e.kind),s=_jsxs(View,{style:{gap:j.space.xs},children:[e.map(e=>renderPart(a,e,t,w,l,`${t.id}-file-${nextSlot()}`)),M]});return _jsx(MessageBubble,{side:"mine",text:joinedText(t.parts),labels:{you:""},groupPosition:r,footer:s,testID:b})}const N="Agent"===t.author.kind,P=t.author.displayName||s.agent,R=(i?i(t):t.parts).map(e=>Array.isArray(e)?_jsx(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:j.space.xs},children:e.map(e=>renderPart(a,e,t,w,l,`${t.id}-part-${nextSlot()}`))},`${t.id}-group-${nextSlot()}`):renderPart(a,e,t,w,l,`${t.id}-item-${nextSlot()}`)),S=N&&f?_jsx(AgentByline,{author:t.author,labels:s,showAvatar:x},`${t.id}-byline`):null,I=S?[S,...R]:R,L=messagePlainText(t.parts),V=_jsx(MessageBubble,{side:"theirs",author:N?void 0:t.author.displayName||(e.profile?.assistant.name??s.assistant),text:N?`${s.agentSays(P)} ${L}`:L,streaming:t.streaming,groupPosition:r,footer:M,testID:b,children:I});if(!x||!y||"Assistant"!==t.author.kind)return V;const C=t.author.displayName||(e.profile?.assistant.name??s.assistant);return _jsxs(View,{style:{flexDirection:"row",alignItems:"flex-end",gap:j.space.xs},children:[_jsx(View,{accessibilityElementsHidden:!0,importantForAccessibility:"no-hide-descendants",style:v?void 0:{opacity:0},children:_jsx(ReplyRing,{active:T&&t.streaming&&v,reduced:k,children:_jsx(Avatar,{size:"xs",name:C,source:v?{uri:y}:void 0})})}),_jsx(View,{style:{flex:1,minWidth:0},children:V})]})}const ThreadMessage=memo(ThreadMessageView,sameMessage),TYPING_ORB_MARK=14,TYPING_ASSISTANT_MARK=8,TypingMark=({size:e})=>{const t=useTheme();return _jsx(View,{style:{width:e,height:e,borderRadius:t.radius.pill,backgroundColor:t.colors.primary}})},TYPING_DOT=6,TypingDots=()=>{const e=useTheme();return _jsx(View,{style:{flexDirection:"row",alignItems:"center",gap:e.space.xxs},children:[0,1,2].map(t=>_jsx(View,{style:{width:6,height:6,borderRadius:3,backgroundColor:e.colors["text-muted"]}},t))})},TurnGap=()=>{const e=useTheme();return _jsx(View,{style:{height:e.space.lg}})},followNew=()=>!0;export function ChatThread({chat:e,labels:t,renderers:s,layoutParts:a,loader:i="Steps",motion:r="On",avatar:n,replyAvatars:o=!0,expressive:l=!1,pickAttachments:d,onOpenAttachment:c,onOpenTarget:g,onNavigate:m,openTicket:p,handoffHosts:u,resolveLink:h,focusComposer:f,keyboardAware:y,keyboardOffset:x,empty:v,style:T,testID:k="chat-thread"}){const A=useTheme(),b=useReducedMotion(),j="Reduced"===r||b,w=useMemo(()=>({...defaultRenderers,...s}),[s]),_=e.messages[0],M=e.greeting??"",N=useMemo(()=>""!==M&&void 0!==_&&MINE.has(_.author.kind)?{..._,id:"greeting",author:{..._.author,kind:"Assistant",displayName:null,avatarUrl:null},parts:[{kind:"Text",text:M}],stored:!1,streaming:!1,restored:!1,rating:null}:null,[M,_]),P=useMemo(()=>{const t=e.messages.filter(e=>!(e.streaming&&0===e.parts.length)).reverse();return N?[...t,N]:t},[e.messages,N]),R=e.messages[e.messages.length-1]?.id,S=useRef(new Map),I=useRef(null);useEffect(()=>{if(null!==I.current)for(const s of e.messages){if(MINE.has(s.author.kind)||s.streaming||s.restored||I.current.has(s.id))continue;if("Agent"===s.author.kind&&!s.stored)continue;I.current.add(s.id);const e=messagePlainText(s.parts);""!==e&&AccessibilityInfo.announceForAccessibility("Agent"===s.author.kind?`${t.agentSays(s.author.displayName||t.agent)} ${e}`:e)}else I.current=new Set(e.messages.map(e=>e.id))},[e.messages,t]);const L=useMemo(()=>{for(let t=e.messages.length-1;t>=0;t-=1){const s=e.messages[t];if(s?.stored&&"Visitor"===s.author.kind)return s.id}},[e.messages]),V=useMemo(()=>{const t=new Set;return e.messages.forEach((s,a)=>{if("Agent"!==s.author.kind)return;const i=e.messages[a-1];"Agent"===i?.author.kind&&(i.author.displayName||"")===(s.author.displayName||"")||t.add(s.id)}),t},[e.messages]),C=useMemo(()=>{const t=new Set,s=e.messages.filter(e=>!(e.streaming&&0===e.parts.length));return N&&t.add(N.id),s.forEach((e,a)=>{"Assistant"===e.author.kind&&"Assistant"!==s[a-1]?.author.kind&&t.add(e.id)}),t},[e.messages,N]),$=useMemo(()=>handoffSettledIds(e.messages),[e.messages]),D=e.turnError,O="daily_limit"===D?.code,E=null!==D&&/feature_off$/.test(D.code),B=O&&D?.resetsDateTimeUtc?` ${t.dailyLimitRefresh(formatChatDateTime(D.resetsDateTimeUtc))}`:"",H=e.streaming||null===D&&!e.stopped?null:_jsxs(View,{style:{gap:A.space.xs},testID:`${k}-error`,children:[_jsx(Text,null!==D?{variant:"bodySmall",color:"danger",accessibilityRole:O?void 0:"alert",accessibilityLiveRegion:O?"polite":void 0,children:`${D.message}${B}`}:{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:t.stopped}),!e.features.Retry||O||E?null:_jsx(View,{style:{flexDirection:"row"},children:_jsx(Button,{label:t.retry,variant:"link",size:"sm",onPress:()=>{e.retry()},testID:`${k}-retry`})})]}),z=e.thinking&&null!==e.profile?_jsx(ChatLoader,{style:i,steps:e.steps,phrases:e.profile.experience.pacing.thinkingPhrases,intervalMs:e.profile.experience.pacing.phraseIntervalMs,announce:t.preparingAnswer(e.profile.assistant.name),motion:r}):null,F=!0===e.pending?.typing?_jsx(TypingPill,{motion:r,mark:_jsx(ReplyRing,{active:l,reduced:j,children:n?_jsx(Avatar,{size:"xs",name:e.profile?.assistant.name??t.panelTitle,source:{uri:n}}):_jsx(TypingMark,{size:"Orb"===i?14:8})})}):null,G=null!==e.agentTyping&&"WithAgent"===e.conversationState?_jsxs(View,{style:{gap:A.space.xs,alignSelf:"flex-start"},children:[_jsx(TypingPill,{motion:r,mark:_jsx(TypingDots,{})}),_jsx(Text,{variant:"caption",color:"secondary",accessibilityLiveRegion:"polite",children:t.agentTyping(e.agentTyping.displayName||t.agent)})]}):null,U=F||z||H||G?_jsxs(View,{style:{gap:A.space.sm},children:[F,z,G,H]}):void 0,K=_jsx(MessageList,{messages:P,keyExtractor:e=>e.id,renderMessage:({item:s,groupPosition:i})=>_jsxs(View,{role:"listitem",children:[MINE.has(s.author.kind)?_jsx(Text,{style:visuallyHidden,children:`${t.you}: `}):null,_jsx(ChatEntrance,{animate:!s.restored,children:_jsx(ThreadMessage,{chat:e,message:s,signature:messageSignature(s),labels:t,all:w,layoutParts:a,groupPosition:i,isLast:s.id===R,isLastVisitor:s.id===L,handoffSettled:$.has(s.id),thinking:e.thinking,streaming:e.streaming,pickAttachments:d,onOpenAttachment:c,onOpenTarget:g,onNavigate:m,openTicket:p,handoffHosts:u,resolveLink:h,focusComposer:f,byline:V.has(s.id),avatar:n,replyAvatars:o,avatarStart:C.has(s.id),expressive:l,reduced:j,sourceRows:S,testID:`${k}-${s.id}`})})]}),getAuthorKey:e=>e.author.kind,getDate:e=>e.createdDateTimeUtc,followNew:followNew,typing:U,empty:v,ItemSeparatorComponent:TurnGap,keyboardAware:y,keyboardOffset:x,accessibilityLabel:t.thread,accessibilityRole:"list",style:T,testID:k});return"web"!==Platform.OS?K:_jsx(View,{role:"log","aria-live":"polite","aria-label":t.thread,style:{flex:1},children:K})}
@@ -1 +1 @@
1
- "use strict";import{AccessibilityInfo,findNodeHandle,Linking,Platform}from"react-native";export function focusForAccessibility(t){if(null==t)return;if("web"===Platform.OS)return void t.focus?.();const e=findNodeHandle(t);null!==e&&AccessibilityInfo.setAccessibilityFocus(e)}export function messageSignature(t){let e=0;for(const i of t.parts)"Text"===i.kind&&(e+=i.text.length);return`${t.id}|${t.parts.length}|${e}`}const ABSOLUTE_WEB_URL=/^https?:\/\//i;export function defaultOpenTarget(t){ABSOLUTE_WEB_URL.test(t)&&Linking.openURL(t).catch(()=>{})}
1
+ "use strict";import{AccessibilityInfo,findNodeHandle,Linking,Platform}from"react-native";export function focusForAccessibility(t){if(null==t)return;if("web"===Platform.OS)return void t.focus?.();const e=findNodeHandle(t);null!==e&&AccessibilityInfo.setAccessibilityFocus(e)}export function messageSignature(t){let e=0;for(const n of t.parts)"Text"===n.kind&&(e+=n.text.length);return`${t.id}|${t.parts.length}|${e}`}const ABSOLUTE_WEB_URL=/^https?:\/\//i;export function defaultOpenTarget(t){ABSOLUTE_WEB_URL.test(t)&&Linking.openURL(t).catch(()=>{})}export const WEB_STRONG="web"===Platform.OS?{role:"strong"}:{};
@@ -0,0 +1 @@
1
+ "use strict";import{useTheme}from"@webority/mobile-ui";import{useEffect,useRef}from"react";import{Animated,Easing,View}from"react-native";import{Fragment as _Fragment,jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const TURN_MS=1400;export function ReplyRing({active:e,reduced:t,children:r}){return _jsx(!e||t?_Fragment:TurningRing,{children:r})}const TurningRing=({children:e})=>{const t=useTheme(),r=useRef(new Animated.Value(0)).current;useEffect(()=>{const e=Animated.loop(Animated.timing(r,{toValue:1,duration:1400,easing:Easing.linear,useNativeDriver:!0}));return e.start(),()=>e.stop()},[r]);const i=-t.space.xxs,n=r.interpolate({inputRange:[0,1],outputRange:["0deg","360deg"]});return _jsxs(View,{children:[e,_jsx(Animated.View,{pointerEvents:"none",accessibilityElementsHidden:!0,importantForAccessibility:"no-hide-descendants",style:{position:"absolute",top:i,right:i,bottom:i,left:i,borderWidth:t.space.xxs,borderRadius:t.radius.pill,borderColor:t.colors.primary,borderTopColor:t.colors.info,transform:[{rotate:n}]}})]})};
@@ -1 +1 @@
1
- "use strict";import{formatChatDate}from"@webority/chat-core";import{parseInline}from"@webority/markdown-core";import{Button,Card,OptionSheet,Text,useTheme}from"@webority/mobile-ui";import{useState}from"react";import{Linking,Text as RNText,View}from"react-native";import{NoticePart}from"./NoticePart.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const LEAD_CAPTURE="ChatLeadCapture",SAFE_LINK=/^https?:/,inlineNodes=(e,t)=>e.map(e=>{if("text"===e.type||"code"===e.type||"citation"===e.type)return e.text;if("link"===e.type){const n=inlineNodes(e.children,t);return SAFE_LINK.test(e.href)?_jsx(RNText,{accessibilityRole:"link",style:{color:t.colors.link,textDecorationLine:"underline"},onPress:()=>{Linking.openURL(e.href).catch(()=>{})},children:n},e.key):_jsx(RNText,{children:n},e.key)}if("image"===e.type)return null;const n="strong"===e.type?{fontWeight:t.weight.bold}:"em"===e.type?{fontStyle:"italic"}:{textDecorationLine:"line-through"};return _jsx(RNText,{style:n,children:inlineNodes(e.children,t)},e.key)}),splitLine=e=>{const t=e.indexOf(": ");return t<0?{term:e,detail:null}:{term:e.slice(0,t),detail:e.slice(t+2)}},statusLine=(e,t)=>{switch(e.state){case"Confirmed":return t.actionConfirmed;case"Done":return e.decidedDateTimeUtc?`${t.actionDone} ${formatChatDate(e.decidedDateTimeUtc)}`:t.actionDone;case"Rejected":return t.actionRejected;case"Expired":return t.actionExpired;case"Failed":return t.actionFailed;case"Repeat":return e.decidedDateTimeUtc?t.actionRepeat(formatChatDate(e.decidedDateTimeUtc)):t.actionDone;case"Pending":return""}};function ActionBody({part:e,turn:t}){const n=useTheme(),{labels:i,features:a}=t,[r,o]=useState(null),[s,l]=useState(""),[c,d]=useState(!1),run=async(e,t)=>{o(e),l("");try{await t()}catch(e){const t=e?.message;l("string"==typeof t&&""!==t?t:i.actionFailed),o(null)}},u=(e.editFields??[]).map(e=>({label:e.label,value:e.id})),m=a.LeadRecap&&e.actionKind===LEAD_CAPTURE,p=m&&u.length>0,x=m&&e.confirmLabel||i.actionConfirm,h=m&&e.rejectLabel||i.actionDismiss,f=null!==r;return _jsxs(Card,{variant:"outline",padding:"sm",children:[_jsxs(View,{style:{gap:n.space.sm},children:[_jsx(Text,{variant:"label",children:e.title}),e.lines.map(e=>{if(!m)return _jsx(Text,{variant:"bodySmall",children:e},e);const{term:t,detail:i}=splitLine(e);return _jsxs(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:n.space.xs},children:[_jsx(Text,{variant:"label",children:t}),null!==i?_jsx(Text,{variant:"bodySmall",children:i}):null]},e)}),m&&e.consentText?_jsx(Text,{variant:"caption",color:"secondary",children:inlineNodes(parseInline(e.consentText),n)}):null,"Pending"===e.state?_jsxs(_Fragment,{children:[""!==s?_jsx(Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:s}):null,_jsxs(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:n.space.sm},children:[_jsx(Button,{label:"confirm"===r?i.actionWorking:x,loading:"confirm"===r,disabled:f,onPress:()=>{run("confirm",()=>t.confirmAction(e.actionId))}}),_jsx(Button,{label:h,variant:"ghost",disabled:f,onPress:()=>{run("reject",()=>t.rejectAction(e.actionId))}})]})]}):_jsx(Text,{variant:"bodySmall",color:"Done"===e.state||"Confirmed"===e.state||"Repeat"===e.state?"success":"secondary",children:statusLine(e,i)}),p?_jsx(Button,{label:i.editSomething,variant:"ghost",disabled:f||"Pending"!==e.state,onPress:()=>d(!0)}):null,e.note?_jsx(Text,{variant:"caption",color:"secondary",children:e.note}):null]}),p?_jsx(OptionSheet,{open:c,onClose:()=>d(!1),title:i.editSomething,options:u,onChange:(e,n)=>{d(!1),t.chooseQuickReply({id:`lead.edit:${String(n.value)}`,label:n.label,action:"Send",target:null,navigateAfterMs:null,icon:null,variant:null})}}):null]})}export function ActionPart(e){const{part:t,message:n,turn:i}=e;if("Action"!==t.kind){const e={kind:"Notice",code:"NeedsNewerApp",text:i.labels.needsNewerApp};return _jsx(NoticePart,{part:e,message:n,turn:i})}return _jsx(ActionBody,{part:t,turn:i},t.actionId)}
1
+ "use strict";import{formatChatDate}from"@webority/chat-core";import{parseInline}from"@webority/markdown-core";import{Button,Card,OptionSheet,Text,useTheme}from"@webority/mobile-ui";import{useState}from"react";import{Linking,Text as RNText,View}from"react-native";import{NoticePart}from"./NoticePart.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const LEAD_CAPTURE="ChatLeadCapture",SAFE_LINK=/^https?:\/\//i,inlineNodes=(e,t)=>e.map(e=>{if("text"===e.type||"code"===e.type||"citation"===e.type)return e.text;if("link"===e.type){const n=inlineNodes(e.children,t);return SAFE_LINK.test(e.href)?_jsx(RNText,{accessibilityRole:"link",style:{color:t.colors.link,textDecorationLine:"underline"},onPress:()=>{Linking.openURL(e.href).catch(()=>{})},children:n},e.key):_jsx(RNText,{children:n},e.key)}if("image"===e.type)return null;const n="strong"===e.type?{fontWeight:t.weight.bold}:"em"===e.type?{fontStyle:"italic"}:{textDecorationLine:"line-through"};return _jsx(RNText,{style:n,children:inlineNodes(e.children,t)},e.key)}),splitLine=e=>{const t=e.indexOf(": ");return t<0?{term:e,detail:null}:{term:e.slice(0,t),detail:e.slice(t+2)}},statusLine=(e,t)=>{switch(e.state){case"Confirmed":return t.actionConfirmed;case"Done":return e.decidedDateTimeUtc?`${t.actionDone} ${formatChatDate(e.decidedDateTimeUtc)}`:t.actionDone;case"Rejected":return t.actionRejected;case"Expired":return t.actionExpired;case"Failed":return t.actionFailed;case"Repeat":return e.decidedDateTimeUtc?t.actionRepeat(formatChatDate(e.decidedDateTimeUtc)):t.actionDone;case"Pending":return""}};function ActionBody({part:e,turn:t}){const n=useTheme(),{labels:i,features:a}=t,[r,o]=useState(null),[s,l]=useState(""),[c,d]=useState(!1),run=async(e,t)=>{o(e),l("");try{await t()}catch(e){const t=e?.message;l("string"==typeof t&&""!==t?t:i.actionFailed),o(null)}},u=(e.editFields??[]).map(e=>({label:e.label,value:e.id})),m=a.LeadRecap&&e.actionKind===LEAD_CAPTURE,p=m&&u.length>0,x=m&&e.confirmLabel||i.actionConfirm,h=m&&e.rejectLabel||i.actionDismiss,f=null!==r;return _jsxs(Card,{variant:"outline",padding:"sm",children:[_jsxs(View,{style:{gap:n.space.sm},children:[_jsx(Text,{variant:"label",children:e.title}),e.lines.map(e=>{if(!m)return _jsx(Text,{variant:"bodySmall",children:e},e);const{term:t,detail:i}=splitLine(e);return _jsxs(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:n.space.xs},children:[_jsx(Text,{variant:"label",children:t}),null!==i?_jsx(Text,{variant:"bodySmall",children:i}):null]},e)}),m&&e.consentText?_jsx(Text,{variant:"caption",color:"secondary",children:inlineNodes(parseInline(e.consentText),n)}):null,"Pending"===e.state?_jsxs(_Fragment,{children:[""!==s?_jsx(Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:s}):null,_jsxs(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:n.space.sm},children:[_jsx(Button,{label:"confirm"===r?i.actionWorking:x,loading:"confirm"===r,disabled:f,onPress:()=>{run("confirm",()=>t.confirmAction(e.actionId))}}),_jsx(Button,{label:h,variant:"ghost",disabled:f,onPress:()=>{run("reject",()=>t.rejectAction(e.actionId))}})]})]}):_jsx(Text,{variant:"bodySmall",color:"Done"===e.state||"Confirmed"===e.state||"Repeat"===e.state?"success":"secondary",children:statusLine(e,i)}),p?_jsx(Button,{label:i.editSomething,variant:"ghost",disabled:f||"Pending"!==e.state,onPress:()=>d(!0)}):null,e.note?_jsx(Text,{variant:"caption",color:"secondary",children:e.note}):null]}),p?_jsx(OptionSheet,{open:c,onClose:()=>d(!1),title:i.editSomething,options:u,onChange:(e,n)=>{d(!1),t.chooseQuickReply({id:`lead.edit:${String(n.value)}`,label:n.label,action:"Send",target:null,navigateAfterMs:null,icon:null,variant:null})}}):null]})}export function ActionPart(e){const{part:t,message:n,turn:i}=e;if("Action"!==t.kind){const e={kind:"Notice",code:"NeedsNewerApp",text:i.labels.needsNewerApp};return _jsx(NoticePart,{part:e,message:n,turn:i})}return _jsx(ActionBody,{part:t,turn:i},t.actionId)}
@@ -1 +1 @@
1
- "use strict";import{Button,Card,Checkbox,Chip,ChoiceGroup,Input,ProgressBar,Text,useTheme}from"@webority/mobile-ui";import{useCallback,useEffect,useRef,useState}from"react";import{View}from"react-native";import{focusForAccessibility}from"../chatShared.js";import{NoticePart}from"./NoticePart.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const FIELD_TYPES=new Set(["Email","Phone","Name","Company","Text","LongText","Choice","MultiChoice","TimeSlot","File","Consent"]),isUndrawnField=e=>!FIELD_TYPES.has(e.type),fileNameOf=(e,t)=>{const i=e.name;return"string"==typeof i&&""!==i?i:t},slotFormat=new Intl.DateTimeFormat(void 0,{weekday:"short",day:"numeric",month:"short",hour:"numeric",minute:"2-digit"}),selectedIds=e=>""===e?[]:JSON.parse(e),KEYBOARD_TYPES={Email:"email-address",Phone:"phone-pad"},AUTO_COMPLETE={Email:"email",Phone:"tel",Name:"name",Company:"organization"},optionalSuffix=(e,t)=>e.required?"":` (${t.inputOptional})`,firstErrorKey=(e,t)=>e.find(e=>void 0!==t[e.key])?.key;function OpenRequest({part:e,turn:t,pickAttachments:i}){const r=useTheme(),{labels:s,features:a}=t,[n,l]=useState({}),[o,c]=useState({}),[u,d]=useState(""),[p,y]=useState(!1),[f,m]=useState({}),[x,h]=useState({}),[b,k]=useState({}),v=useRef({}),g=useRef({}),j=useRef(f),_=useRef(0),T=useRef(!1),C=useCallback(e=>{const t=v.current[e];if(t)return void t.focus();const i=g.current[e];i&&focusForAccessibility(i)},[]);useEffect(()=>{if(p||!T.current)return;T.current=!1;const t=firstErrorKey(e.fields,o);void 0!==t&&C(t)},[p,o,e.fields,C]);const setValue=(e,t)=>l(i=>({...i,[e]:t})),commitUploads=e=>{j.current=e,m(e)},patchUpload=(e,t)=>{const i=j.current[e];i&&commitUploads({...j.current,[e]:{...i,...t}})},isLiveUpload=(e,t)=>j.current[e]?.token===t,S=Object.values(f).some(e=>"Ready"!==e.status),leave=async e=>{y(!0),d("");try{await e()}catch{d(s.errorGeneric),y(!1)}},w=a.LeadShortcuts,R=w&&1===e.fields.length&&!e.fields[0].required,E=w&&e.cancellable;return _jsx(Card,{variant:"outline",padding:"sm",accessibilityLabel:e.title||void 0,children:_jsxs(View,{style:{gap:r.space.sm},children:[e.title?_jsx(Text,{variant:"label",accessibilityRole:"header",children:e.title}):null,e.allowTyped?_jsx(Text,{variant:"caption",color:"secondary",children:s.typeAnswer}):null,e.fields.map(a=>{const l=n[a.key]??"",c=o[a.key];if("File"===a.type){const e=f[a.key];return _jsxs(View,{style:{gap:r.space.xs},children:[_jsx(Text,{variant:"label",children:`${a.label}${optionalSuffix(a,s)}`}),e?_jsxs(View,{style:{gap:r.space.xxs},children:[_jsx(Chip,{label:e.fileName,variant:"soft",onRemove:()=>{return e=a.key,commitUploads(Object.fromEntries(Object.entries(j.current).filter(([t])=>t!==e))),void setValue(e,"");var e},labels:{remove:s.inputRemoveFile}}),"Uploading"===e.status?_jsx(ProgressBar,{progress:e.progress??void 0,label:s.attachmentUploading,height:4}):null,"Failed"===e.status?_jsx(Text,{variant:"caption",color:"danger",accessibilityLiveRegion:"assertive",children:s.attachmentFailed}):null]}):_jsx(View,{style:{flexDirection:"row"},children:_jsx(Button,{label:s.inputChooseFile,variant:"soft",size:"sm",leftIcon:"paperclip",disabled:p||void 0===i,onPress:()=>{(async e=>{if(!i)return;let r;try{r=await i()}catch{return void d(s.errorGeneric)}const a=r[0];if(!a)return;_.current+=1;const n=_.current;commitUploads({...j.current,[e.key]:{fileName:fileNameOf(a,e.label),status:"Uploading",progress:null,token:n}});try{const i=await t.uploadInputFile(a,t=>{isLiveUpload(e.key,n)&&patchUpload(e.key,{progress:t})});isLiveUpload(e.key,n)&&(setValue(e.key,i),patchUpload(e.key,{status:"Ready",progress:null}))}catch{isLiveUpload(e.key,n)&&(setValue(e.key,""),patchUpload(e.key,{status:"Failed",progress:null}))}})(a)}})}),c?_jsx(Text,{variant:"caption",color:"danger",accessibilityLiveRegion:"assertive",children:c}):null]},a.key)}if("MultiChoice"===a.type){const e=(a.options??[]).map(e=>({label:e.label,value:e.id}));return _jsxs(View,{style:{gap:r.space.xs},children:[_jsx(Text,{variant:"label",children:`${a.label}${optionalSuffix(a,s)}`}),_jsx(View,{ref:e=>{g.current[a.key]=e},children:_jsx(ChoiceGroup,{selectionMode:"multiple",options:e,value:selectedIds(l),onChange:t=>setValue(a.key,JSON.stringify(e.filter(e=>t.includes(e.value)).map(e=>e.value))),accessibilityLabel:a.label,error:c,disabled:p})})]},a.key)}if("Choice"===a.type||"TimeSlot"===a.type){const e="TimeSlot"===a.type?(a.slots??[]).map(e=>({label:slotFormat.format(new Date(e.startDateTimeUtc)),value:e.id})):(a.options??[]).map(e=>({label:e.label,value:e.id}));return _jsxs(View,{style:{gap:r.space.xs},children:[_jsx(Text,{variant:"label",children:`${a.label}${optionalSuffix(a,s)}`}),_jsx(View,{ref:e=>{g.current[a.key]=e},children:_jsx(ChoiceGroup,{options:e,value:""===l?void 0:l,onChange:e=>setValue(a.key,String(e)),accessibilityLabel:a.label,error:c,disabled:p})})]},a.key)}if("Consent"===a.type)return _jsx(Checkbox,{checked:"true"===l,onChange:e=>setValue(a.key,e?"true":"false"),label:a.consentText??a.label,error:c,disabled:p},a.key);const u=_jsx(Input,{ref:e=>{v.current[a.key]=e},label:a.label,placeholder:a.placeholder??void 0,value:l,onChangeText:e=>setValue(a.key,e),maxLength:a.maxLength??void 0,required:a.required,error:c,help:a.required?void 0:s.inputOptional,labelMode:"top",disabled:p,type:a.secret?"password":"LongText"===a.type?"textarea":"input",keyboardType:KEYBOARD_TYPES[a.type]??"default",autoCapitalize:"Email"===a.type?"none":void 0,autoComplete:AUTO_COMPLETE[a.type]},a.key);if(!("Otp"===a.verify&&("Email"===a.type||"Phone"===a.type)))return u;const y=b[a.key];return _jsxs(View,{style:{gap:r.space.xs},children:[u,_jsxs(View,{style:{gap:r.space.xs},children:[_jsx(Button,{label:s.inputSendCode,variant:"soft",size:"sm",disabled:p,onPress:()=>{(async i=>{if("Otp"===i.verify)try{await t.sendOtp(e.requestId,{fieldKey:i.key,value:(n[i.key]??"").trim()}),k(e=>({...e,[i.key]:"sent"}))}catch{k(e=>({...e,[i.key]:"failed"}))}})(a)},testID:`otp-send-${a.key}`}),_jsx(Input,{label:s.inputEnterCode,value:x[a.key]??"",onChangeText:e=>h(t=>({...t,[a.key]:e})),keyboardType:"number-pad",autoComplete:"one-time-code",disabled:p}),y?_jsx(Text,{variant:"caption",color:"failed"===y?"danger":"secondary",accessibilityLiveRegion:"polite",children:"failed"===y?s.inputCodeFailed:s.inputCodeSent}):null]})]},a.key)}),""!==u?_jsx(Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:u}):null,_jsxs(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:r.space.sm},children:[_jsx(Button,{label:p?s.inputSubmitting:e.submitLabel,loading:p,disabled:p||S,onPress:()=>{(async()=>{if(S)return;const i={},r={};for(const t of e.fields){const e=n[t.key]??"";if("Consent"===t.type){const a="true"===e;t.required&&!a&&(i[t.key]=s.inputConsentRequired),r[t.key]=a?"true":"false"}else if("Choice"===t.type||"TimeSlot"===t.type)t.required&&""===e&&(i[t.key]=s.inputRequired),r[t.key]=e;else if("MultiChoice"===t.type){const a=selectedIds(e);t.required&&0===a.length&&(i[t.key]=s.inputRequired),r[t.key]=JSON.stringify(a)}else if("File"===t.type)t.required&&""===e&&(i[t.key]=s.inputRequired),r[t.key]=e;else{const a=t.secret?e:e.trim();t.required&&""===a&&(i[t.key]=s.inputRequired),r[t.key]=a}}const a={};for(const t of e.fields){if("Otp"!==t.verify)continue;const e=(x[t.key]??"").trim();""===e&&(i[t.key]=s.inputRequired),a[t.key]=e}if(c(i),Object.keys(i).length>0){const t=firstErrorKey(e.fields,i);return void(void 0!==t&&C(t))}y(!0),d("");try{const i=await t.answerInput(e.requestId,r,Object.keys(a).length>0?a:null);if(i.ok)return;c(i.errors),T.current=!0,d(i.message??"")}catch{d(s.errorGeneric)}y(!1)})()}}),S?_jsx(Text,{variant:"caption",color:"secondary",children:s.attachmentUploading}):null,R?_jsx(Button,{label:s.skip,variant:"ghost",disabled:p,onPress:()=>{leave(()=>t.skipInput(e.requestId))}}):null,E?_jsx(Button,{label:s.cancel,variant:"ghost",disabled:p,onPress:()=>{leave(()=>t.cancelLead())}}):null]})]})})}export function InputRequestPart(e){const{part:t,message:i,turn:r,pickAttachments:s}=e;if("InputRequest"!==t.kind||t.fields.some(isUndrawnField)){const e={kind:"Notice",code:"NeedsNewerApp",text:r.labels.needsNewerApp};return _jsx(NoticePart,{part:e,message:i,turn:r})}return"Answered"===t.state?_jsx(Text,{variant:"bodySmall",color:"secondary",children:t.answeredSummary||r.labels.inputAnswered}):"Skipped"===t.state?_jsx(Text,{variant:"bodySmall",color:"secondary",children:r.labels.inputSkipped}):"Expired"===t.state?_jsx(Text,{variant:"bodySmall",color:"secondary",children:r.labels.inputExpired}):_jsx(OpenRequest,{part:t,turn:r,pickAttachments:s},t.requestId)}
1
+ "use strict";import{Button,Card,Checkbox,Chip,ChoiceGroup,Input,ProgressBar,Text,useTheme}from"@webority/mobile-ui";import{useCallback,useEffect,useRef,useState}from"react";import{View}from"react-native";import{focusForAccessibility}from"../chatShared.js";import{NoticePart}from"./NoticePart.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const FIELD_TYPES=new Set(["Email","Phone","Name","Company","Text","LongText","Choice","MultiChoice","TimeSlot","File","Consent"]),isUndrawnField=e=>!FIELD_TYPES.has(e.type),fileNameOf=(e,t)=>{const i=e.name;return"string"==typeof i&&""!==i?i:t},slotFormat=new Intl.DateTimeFormat(void 0,{weekday:"short",day:"numeric",month:"short",hour:"numeric",minute:"2-digit"}),selectedIds=e=>""===e?[]:JSON.parse(e),KEYBOARD_TYPES={Email:"email-address",Phone:"phone-pad"},AUTO_COMPLETE={Email:"email",Phone:"tel",Name:"name",Company:"organization"},optionalSuffix=(e,t)=>e.required?"":` (${t.inputOptional})`,firstErrorKey=(e,t)=>e.find(e=>void 0!==t[e.key])?.key;function OpenRequest({part:e,turn:t,pickAttachments:i}){const r=useTheme(),{labels:s,features:a}=t,[n,l]=useState({}),[o,c]=useState({}),[u,d]=useState(""),[p,y]=useState(!1),[f,m]=useState({}),[x,h]=useState({}),[b,k]=useState({}),v=useRef({}),g=useRef({}),j=useRef(f),_=useRef(0),T=useRef(!1),C=useCallback(e=>{const t=v.current[e];if(t)return void t.focus();const i=g.current[e];i&&focusForAccessibility(i)},[]);useEffect(()=>{if(p||!T.current)return;T.current=!1;const t=firstErrorKey(e.fields,o);void 0!==t&&C(t)},[p,o,e.fields,C]);const setValue=(e,t)=>l(i=>({...i,[e]:t})),commitUploads=e=>{j.current=e,m(e)},patchUpload=(e,t)=>{const i=j.current[e];i&&commitUploads({...j.current,[e]:{...i,...t}})},isLiveUpload=(e,t)=>j.current[e]?.token===t,S=Object.values(f).some(e=>"Ready"!==e.status),leave=async e=>{y(!0),d("");try{await e()}catch{d(s.errorGeneric),y(!1)}},w=a.LeadShortcuts,R=w&&1===e.fields.length&&!e.fields[0].required,E=w&&e.cancellable;return _jsx(Card,{variant:"outline",padding:"sm",accessibilityLabel:e.title||void 0,children:_jsxs(View,{style:{gap:r.space.sm},children:[e.title?_jsx(Text,{variant:"label",accessibilityRole:"header",children:e.title}):null,e.allowTyped?_jsx(Text,{variant:"caption",color:"secondary",children:s.typeAnswer}):null,e.fields.map(a=>{const l=n[a.key]??"",c=o[a.key];if("File"===a.type){const e=f[a.key];return _jsxs(View,{style:{gap:r.space.xs},children:[_jsx(Text,{variant:"label",children:`${a.label}${optionalSuffix(a,s)}`}),e?_jsxs(View,{style:{gap:r.space.xxs},children:[_jsx(Chip,{label:e.fileName,variant:"soft",onRemove:()=>{return e=a.key,commitUploads(Object.fromEntries(Object.entries(j.current).filter(([t])=>t!==e))),void setValue(e,"");var e},labels:{remove:s.inputRemoveFile}}),"Uploading"===e.status?_jsx(ProgressBar,{progress:e.progress??void 0,label:s.attachmentUploading,height:4}):null,"Failed"===e.status?_jsx(Text,{variant:"caption",color:"danger",accessibilityLiveRegion:"assertive",children:s.attachmentFailed}):null]}):_jsx(View,{style:{flexDirection:"row"},children:_jsx(Button,{label:s.inputChooseFile,variant:"soft",size:"sm",leftIcon:"paperclip",disabled:p||void 0===i,onPress:()=>{(async e=>{if(!i)return;let r;try{r=await i(e.accept??void 0)}catch{return void d(s.errorGeneric)}const a=r[0];if(!a)return;_.current+=1;const n=_.current;commitUploads({...j.current,[e.key]:{fileName:fileNameOf(a,e.label),status:"Uploading",progress:null,token:n}});try{const i=await t.uploadInputFile(a,t=>{isLiveUpload(e.key,n)&&patchUpload(e.key,{progress:t})});isLiveUpload(e.key,n)&&(setValue(e.key,i),patchUpload(e.key,{status:"Ready",progress:null}))}catch{isLiveUpload(e.key,n)&&(setValue(e.key,""),patchUpload(e.key,{status:"Failed",progress:null}))}})(a)}})}),c?_jsx(Text,{variant:"caption",color:"danger",accessibilityLiveRegion:"assertive",children:c}):null]},a.key)}if("MultiChoice"===a.type){const e=(a.options??[]).map(e=>({label:e.label,value:e.id}));return _jsxs(View,{style:{gap:r.space.xs},children:[_jsx(Text,{variant:"label",children:`${a.label}${optionalSuffix(a,s)}`}),_jsx(View,{ref:e=>{g.current[a.key]=e},children:_jsx(ChoiceGroup,{selectionMode:"multiple",options:e,value:selectedIds(l),onChange:t=>setValue(a.key,JSON.stringify(e.filter(e=>t.includes(e.value)).map(e=>e.value))),accessibilityLabel:a.label,error:c,disabled:p})})]},a.key)}if("Choice"===a.type||"TimeSlot"===a.type){const e="TimeSlot"===a.type?(a.slots??[]).map(e=>({label:slotFormat.format(new Date(e.startDateTimeUtc)),value:e.id})):(a.options??[]).map(e=>({label:e.label,value:e.id}));return _jsxs(View,{style:{gap:r.space.xs},children:[_jsx(Text,{variant:"label",children:`${a.label}${optionalSuffix(a,s)}`}),_jsx(View,{ref:e=>{g.current[a.key]=e},children:_jsx(ChoiceGroup,{options:e,value:""===l?void 0:l,onChange:e=>setValue(a.key,String(e)),accessibilityLabel:a.label,error:c,disabled:p})})]},a.key)}if("Consent"===a.type)return _jsx(Checkbox,{checked:"true"===l,onChange:e=>setValue(a.key,e?"true":"false"),label:a.consentText??a.label,error:c,disabled:p},a.key);const u=_jsx(Input,{ref:e=>{v.current[a.key]=e},label:a.label,placeholder:a.placeholder??void 0,value:l,onChangeText:e=>setValue(a.key,e),maxLength:a.maxLength??void 0,required:a.required,error:c,help:a.required?void 0:s.inputOptional,labelMode:"top",disabled:p,type:a.secret?"password":"LongText"===a.type?"textarea":"input",keyboardType:KEYBOARD_TYPES[a.type]??"default",autoCapitalize:"Email"===a.type?"none":void 0,autoComplete:AUTO_COMPLETE[a.type]},a.key);if(!("Otp"===a.verify&&("Email"===a.type||"Phone"===a.type)))return u;const y=b[a.key];return _jsxs(View,{style:{gap:r.space.xs},children:[u,_jsxs(View,{style:{gap:r.space.xs},children:[_jsx(Button,{label:s.inputSendCode,variant:"soft",size:"sm",disabled:p,onPress:()=>{(async i=>{if("Otp"===i.verify)try{await t.sendOtp(e.requestId,{fieldKey:i.key,value:(n[i.key]??"").trim()}),k(e=>({...e,[i.key]:"sent"}))}catch{k(e=>({...e,[i.key]:"failed"}))}})(a)},testID:`otp-send-${a.key}`}),_jsx(Input,{label:s.inputEnterCode,value:x[a.key]??"",onChangeText:e=>h(t=>({...t,[a.key]:e})),keyboardType:"number-pad",autoComplete:"one-time-code",disabled:p}),y?_jsx(Text,{variant:"caption",color:"failed"===y?"danger":"secondary",accessibilityLiveRegion:"polite",children:"failed"===y?s.inputCodeFailed:s.inputCodeSent}):null]})]},a.key)}),""!==u?_jsx(Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:u}):null,_jsxs(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:r.space.sm},children:[_jsx(Button,{label:p?s.inputSubmitting:e.submitLabel,loading:p,disabled:p||S,onPress:()=>{(async()=>{if(S)return;const i={},r={};for(const t of e.fields){const e=n[t.key]??"";if("Consent"===t.type){const a="true"===e;t.required&&!a&&(i[t.key]=s.inputConsentRequired),r[t.key]=a?"true":"false"}else if("Choice"===t.type||"TimeSlot"===t.type)t.required&&""===e&&(i[t.key]=s.inputRequired),r[t.key]=e;else if("MultiChoice"===t.type){const a=selectedIds(e);t.required&&0===a.length&&(i[t.key]=s.inputRequired),r[t.key]=JSON.stringify(a)}else if("File"===t.type)t.required&&""===e&&(i[t.key]=s.inputRequired),r[t.key]=e;else{const a=t.secret?e:e.trim();t.required&&""===a&&(i[t.key]=s.inputRequired),r[t.key]=a}}const a={};for(const t of e.fields){if("Otp"!==t.verify)continue;const e=(x[t.key]??"").trim();""===e&&(i[t.key]=s.inputRequired),a[t.key]=e}if(c(i),Object.keys(i).length>0){const t=firstErrorKey(e.fields,i);return void(void 0!==t&&C(t))}y(!0),d("");try{const i=await t.answerInput(e.requestId,r,Object.keys(a).length>0?a:null);if(i.ok)return;c(i.errors),T.current=!0,d(i.message??"")}catch{d(s.errorGeneric)}y(!1)})()}}),S?_jsx(Text,{variant:"caption",color:"secondary",children:s.attachmentUploading}):null,R?_jsx(Button,{label:s.skip,variant:"ghost",disabled:p,onPress:()=>{leave(()=>t.skipInput(e.requestId))}}):null,E?_jsx(Button,{label:s.cancel,variant:"ghost",disabled:p,onPress:()=>{leave(()=>t.cancelLead())}}):null]})]})})}export function InputRequestPart(e){const{part:t,message:i,turn:r,pickAttachments:s}=e;if("InputRequest"!==t.kind||t.fields.some(isUndrawnField)){const e={kind:"Notice",code:"NeedsNewerApp",text:r.labels.needsNewerApp};return _jsx(NoticePart,{part:e,message:i,turn:r})}return"Answered"===t.state?_jsx(Text,{variant:"bodySmall",color:"secondary",children:t.answeredSummary||r.labels.inputAnswered}):"Skipped"===t.state?_jsx(Text,{variant:"bodySmall",color:"secondary",children:r.labels.inputSkipped}):"Expired"===t.state?_jsx(Text,{variant:"bodySmall",color:"secondary",children:r.labels.inputExpired}):_jsx(OpenRequest,{part:t,turn:r,pickAttachments:s},t.requestId)}
@@ -1 +1 @@
1
- "use strict";import{CHAT_HANDOFF_REQUEST_ID,isHandoffTarget}from"@webority/chat-core";import{Chip,Text,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{ChatEntrance}from"../ChatEntrance.js";import{defaultOpenTarget}from"../chatShared.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const QUIET_LOOK={variant:"outline"};function lookOf(e){switch(e){case"Primary":case"Cta":return{variant:"solid",tone:"primary"};default:return QUIET_LOOK}}export function QuickRepliesPart({part:e,turn:n}){const t=useTheme();if(!n.features.SuggestedReplies||!n.isLast||n.busy||0===e.replies.length)return null;const i=n.openTarget,a=n.onNavigate,r=void 0!==i&&i!==defaultOpenTarget,o="Composer"===e.placement,s=e.replies.filter(e=>"Send"===e.action||"Open"===e.action&&e.target&&i||"Navigate"===e.action&&n.features.LinkHandoff);if(0===s.length)return null;const l=o?void 0:s.find(e=>e.id===CHAT_HANDOFF_REQUEST_ID&&"Send"===e.action),c=l?s.filter(e=>e!==l):s,f=l?1:0,sendChip=(e,t)=>_jsx(Chip,{label:e.label,variant:t.variant,tone:t.tone,leftIcon:e.icon?e.icon:void 0,onPress:()=>{n.chooseQuickReply(e),n.focusComposer?.()}});return _jsxs(View,{accessibilityRole:"summary",accessibilityLabel:n.labels.quickReplies,accessibilityLiveRegion:n.handoffPause?"polite":void 0,style:{flexDirection:"row",flexWrap:"wrap",gap:t.space.xs,...o?{paddingHorizontal:t.space.md}:null},children:[l?_jsx(ChatEntrance,{index:0,children:_jsxs(View,{style:{flexBasis:"100%",alignItems:"flex-start",gap:t.space.xs},children:[_jsx(Text,{variant:"label",children:l.label}),sendChip(l,lookOf("Primary"))]})},l.id):null,c.map((e,t)=>{const o=t+f,s=l?QUIET_LOOK:lookOf(e.variant),c=e.icon?e.icon:void 0;if("Send"===e.action)return _jsx(ChatEntrance,{index:o,children:sendChip(e,s)},e.id);const d=e.target;if("Open"===e.action&&d&&i)return _jsx(ChatEntrance,{index:o,children:_jsx(Chip,{label:e.label,variant:s.variant,tone:s.tone,leftIcon:c,onPress:()=>i(d)})},e.id);if("Navigate"===e.action){const t=(e=>{if(!e)return null;if(isHandoffTarget(e,n.handoffHosts))return e;const t=n.resolveLink?.(e);return"string"==typeof t&&""!==t?t:null})(d),l=null===t?void 0:(e=>e.startsWith("/")?i&&r?()=>i(e):a?()=>a(e):void 0:i?()=>i(e):void 0)(t);return _jsx(ChatEntrance,null===t||void 0===l?{index:o,children:_jsx(Text,{variant:"bodySmall",color:"primary",children:e.label})}:{index:o,children:_jsx(Chip,{label:n.handoffPause?n.labels.handoffMoment:e.label,variant:n.handoffPause?QUIET_LOOK.variant:s.variant,tone:n.handoffPause?void 0:s.tone,leftIcon:c,disabled:n.handoffPause,onPress:()=>n.beginHandoff(e,l)})},e.id)}return null})]})}
1
+ "use strict";import{CHAT_HANDOFF_REQUEST_ID,isHandoffTarget}from"@webority/chat-core";import{Chip,Text,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{ChatEntrance}from"../ChatEntrance.js";import{defaultOpenTarget}from"../chatShared.js";import{chipLook}from"./chipLook.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const QUIET_LOOK={variant:"outline"};export function QuickRepliesPart({part:e,turn:n}){const i=useTheme();if(!n.features.SuggestedReplies||!n.isLast||n.busy||0===e.replies.length)return null;const t=n.openTarget,a=n.onNavigate,r=void 0!==t&&t!==defaultOpenTarget,o="Composer"===e.placement,s=e.replies.filter(e=>"Send"===e.action||"Open"===e.action&&e.target&&t||"Navigate"===e.action&&n.features.LinkHandoff);if(0===s.length)return null;const l=o?void 0:s.find(e=>e.id===CHAT_HANDOFF_REQUEST_ID&&"Send"===e.action),c=l?s.filter(e=>e!==l):s,d=l?1:0,sendChip=(e,i)=>_jsx(Chip,{label:e.label,variant:i.variant,tone:i.tone,leftIcon:e.icon?e.icon:void 0,onPress:()=>{n.chooseQuickReply(e),n.focusComposer?.()}});return _jsxs(View,{role:"group",accessibilityLabel:n.labels.quickReplies,accessibilityLiveRegion:n.handoffPause?"polite":void 0,style:{flexDirection:"row",flexWrap:"wrap",gap:i.space.xs,...o?{paddingHorizontal:i.space.md}:null},children:[l?_jsx(ChatEntrance,{index:0,children:_jsxs(View,{style:{flexBasis:"100%",alignItems:"flex-start",gap:i.space.xs},children:[_jsx(Text,{variant:"label",children:l.label}),sendChip(l,chipLook("Primary"))]})},l.id):null,c.map((e,i)=>{const o=i+d,s=l?QUIET_LOOK:chipLook(e.variant),c=e.icon?e.icon:void 0;if("Send"===e.action)return _jsx(ChatEntrance,{index:o,children:sendChip(e,s)},e.id);const f=e.target;if("Open"===e.action&&f&&t)return _jsx(ChatEntrance,{index:o,children:_jsx(Chip,{label:e.label,variant:s.variant,tone:s.tone,leftIcon:c,onPress:()=>t(f)})},e.id);if("Navigate"===e.action){const i=(e=>{if(!e)return null;if(isHandoffTarget(e,n.handoffHosts))return e;const i=n.resolveLink?.(e);return"string"==typeof i&&""!==i?i:null})(f),l=null===i?void 0:(e=>e.startsWith("/")?t&&r?()=>t(e):a?()=>a(e):void 0:t?()=>t(e):void 0)(i);return _jsx(ChatEntrance,null===i||void 0===l?{index:o,children:_jsx(Text,{variant:"bodySmall",color:"primary",children:e.label})}:{index:o,children:_jsx(Chip,{label:n.handoffPause?n.labels.handoffMoment:e.label,variant:n.handoffPause?QUIET_LOOK.variant:s.variant,tone:n.handoffPause?void 0:s.tone,leftIcon:c,disabled:n.handoffPause,onPress:()=>n.beginHandoff(e,l)})},e.id)}return null})]})}
@@ -1 +1 @@
1
- "use strict";import{isHandoffTarget}from"@webority/chat-core";import{Markdown,Text}from"@webority/mobile-ui";import{FigureText}from"./FigureText.js";import{jsx as _jsx}from"react/jsx-runtime";const CITATION=/^\d+$/;export function TextPart({part:t,message:e,turn:r}){return"Visitor"===e.author.kind||"Customer"===e.author.kind?r.features.FigureText?_jsx(FigureText,{text:t.text,variant:"body",color:"primary"}):_jsx(Text,{variant:"body",children:t.text}):_jsx(Markdown,{links:"app",headings:"text",resolveLink:t=>r.openTarget&&isHandoffTarget(t,r.handoffHosts)?t:null,onAppLinkPress:t=>r.openTarget?.(t),isCitation:t=>CITATION.test(t),onOpenCitation:r.openCitation?t=>r.openCitation?.(Number(t)):void 0,children:t.text})}
1
+ "use strict";import{isHandoffTarget,toFigureRuns}from"@webority/chat-core";import{Markdown,Text}from"@webority/mobile-ui";import{View}from"react-native";import{FigureText}from"./FigureText.js";import{jsx as _jsx}from"react/jsx-runtime";const CITATION=/^\d+$/,PARAGRAPH_ROLE="paragraph";export function TextPart({part:t,message:e,turn:r}){const i="Visitor"===e.author.kind||"Customer"===e.author.kind;return _jsx(View,{role:"paragraph",children:i?r.features.FigureText?_jsx(FigureText,{text:t.text,variant:"body",color:"primary"}):_jsx(Text,{variant:"body",children:t.text}):_jsx(Markdown,{links:"app",headings:"text",resolveLink:t=>r.openTarget&&isHandoffTarget(t,r.handoffHosts)?t:null,onAppLinkPress:t=>r.openTarget?.(t),isCitation:t=>CITATION.test(t),figureText:r.features.FigureText?toFigureRuns:void 0,onOpenCitation:r.openCitation?t=>r.openCitation?.(Number(t)):void 0,children:t.text})})}
@@ -0,0 +1 @@
1
+ "use strict";export function chipLook(t){switch(t){case"Primary":case"Cta":return{variant:"solid",tone:"primary"};default:return{variant:"outline"}}}
@@ -1 +1 @@
1
- "use strict";import{ChatSpeechError}from"@webority/chat-core";import{buildSsml,clampSpeakText}from"./speechText.js";const TRANSCRIBE_API_VERSION="2024-11-15",TTS_OUTPUT_FORMAT="audio-24khz-48kbitrate-mono-mp3",REQUEST_TIMEOUT_MS=15e3,REGION_PATTERN=/^[a-z0-9]+$/;export class SpeechRequestError extends Error{constructor(e){super(`Speech request failed with status ${e}`),this.name="SpeechRequestError",this.status=e}}const assertRegion=e=>{if(!REGION_PATTERN.test(e))throw new ChatSpeechError("Unavailable","Speech is not available.")},withTimeout=async(e,t)=>{const r=new AbortController,abort=()=>r.abort(),o=setTimeout(abort,15e3);e?.aborted&&r.abort(),e?.addEventListener("abort",abort);try{return await t(r.signal)}finally{clearTimeout(o),e?.removeEventListener("abort",abort)}};export async function transcribeClip(e){const{token:t,uri:r,language:o,signal:a,fetchImpl:i=fetch}=e;assertRegion(t.region);const n=new FormData;return n.append("audio",{uri:r,name:"dictation.m4a",type:"audio/mp4"}),n.append("definition",JSON.stringify({locales:[o]})),withTimeout(a,async e=>{const r=await i(`https://${t.region}.api.cognitive.microsoft.com/speechtotext/transcriptions:transcribe?api-version=2024-11-15`,{method:"POST",headers:{Authorization:`Bearer ${t.token}`},body:n,signal:e});if(!r.ok)throw new SpeechRequestError(r.status);return((await r.json()).combinedPhrases??[]).map(e=>e.text??"").join(" ").trim()})}export async function synthesizeSpeech(e){const{token:t,text:r,language:o,voice:a,signal:i,fetchImpl:n=fetch}=e;return assertRegion(t.region),withTimeout(i,async e=>{const i=await n(`https://${t.region}.tts.speech.microsoft.com/cognitiveservices/v1`,{method:"POST",headers:{Authorization:`Bearer ${t.token}`,"Content-Type":"application/ssml+xml","X-Microsoft-OutputFormat":TTS_OUTPUT_FORMAT,"User-Agent":"webority-chat"},body:buildSsml(clampSpeakText(r),o,a),signal:e});if(!i.ok)throw new SpeechRequestError(i.status);return new Uint8Array(await i.arrayBuffer())})}
1
+ "use strict";import{ChatSpeechError}from"@webority/chat-core";import{fetchWithRetry}from"@webority/mobile-core";import{buildSsml,clampSpeakText}from"./speechText.js";const TRANSCRIBE_API_VERSION="2024-11-15",TTS_OUTPUT_FORMAT="audio-24khz-48kbitrate-mono-mp3",REQUEST_TIMEOUT_MS=15e3,REGION_PATTERN=/^[a-z0-9]+$/;export class SpeechRequestError extends Error{constructor(e){super(`Speech request failed with status ${e}`),this.name="SpeechRequestError",this.status=e}}const assertRegion=e=>{if(!REGION_PATTERN.test(e))throw new ChatSpeechError("Unavailable","Speech is not available.")},withTimeout=async(e,t)=>{const r=new AbortController,abort=()=>r.abort(),o=setTimeout(abort,15e3);e?.aborted&&r.abort(),e?.addEventListener("abort",abort);try{return await t(r.signal)}finally{clearTimeout(o),e?.removeEventListener("abort",abort)}};export async function transcribeClip(e){const{token:t,uri:r,language:o,signal:i,fetchImpl:a=fetch}=e;assertRegion(t.region);const n=new FormData;return n.append("audio",{uri:r,name:"dictation.m4a",type:"audio/mp4"}),n.append("definition",JSON.stringify({locales:[o]})),withTimeout(i,async e=>{const r=await fetchWithRetry(a,`https://${t.region}.api.cognitive.microsoft.com/speechtotext/transcriptions:transcribe?api-version=2024-11-15`,{method:"POST",headers:{Authorization:`Bearer ${t.token}`},body:n,signal:e});if(!r.ok)throw new SpeechRequestError(r.status);return((await r.json()).combinedPhrases??[]).map(e=>e.text??"").join(" ").trim()})}export async function synthesizeSpeech(e){const{token:t,text:r,language:o,voice:i,signal:a,fetchImpl:n=fetch}=e;return assertRegion(t.region),withTimeout(a,async e=>{const a=await fetchWithRetry(n,`https://${t.region}.tts.speech.microsoft.com/cognitiveservices/v1`,{method:"POST",headers:{Authorization:`Bearer ${t.token}`,"Content-Type":"application/ssml+xml","X-Microsoft-OutputFormat":TTS_OUTPUT_FORMAT,"User-Agent":"webority-chat"},body:buildSsml(clampSpeakText(r),o,i),signal:e});if(!a.ok)throw new SpeechRequestError(a.status);return new Uint8Array(await a.arrayBuffer())})}
@@ -1 +1 @@
1
- "use strict";import{createChatSession,DEFAULT_CHAT_LABELS,emptyFeatures}from"@webority/chat-core";import{useReducedMotion}from"@webority/mobile-ui";import{useCallback,useEffect,useMemo,useRef,useState,useSyncExternalStore}from"react";import{AppState}from"react-native";const requestFrame=e=>{const t=requestAnimationFrame(e);return()=>cancelAnimationFrame(t)},NO_SUBSCRIPTION=()=>()=>{},IDLE_STATE=Object.freeze({profile:null,profileError:null,features:Object.freeze(emptyFeatures()),conversationId:null,conversationState:"Open",title:null,continuesConversationId:null,messages:[],thinking:!1,steps:[],streaming:!1,loading:!1,loadError:null,turnError:null,stopped:!1,messagesLeftToday:null,editing:null,attachments:[],lastConversation:null,open:!1,muted:!1,greeting:null,starters:[],pending:null,agent:null,agentTyping:null,live:"Off",handoffPending:!1,handoffPause:!1,openTickets:[],draft:null}),IDLE_SESSION=new Proxy({},{get:(e,t)=>{if("symbol"!=typeof t&&"client"!==t&&"toJSON"!==t&&!t.startsWith("$$")){if("getState"===t)return()=>IDLE_STATE;if("subscribe"===t)return NO_SUBSCRIPTION;if("then"!==t)return()=>Promise.resolve()}}});export function useChat(e){const{client:t,screen:r,layout:n,narrow:s,conversationId:o,pageContext:a,behaviour:c,prefs:u,getCaptchaToken:i,onEvent:l,onError:f,onNavigate:p}=e,m=JSON.stringify(s??{}),d=useRef(p);d.current=p;const S=useCallback(e=>d.current?.(e),[]),E=useRef(o);E.current=o;const v=useRef(a);v.current=a;const g=useRef(c);g.current=c;const h=useRef(i);h.current=i;const y=useRef(l);y.current=l;const C=useRef(f);C.current=f;const b=useRef(u);b.current=u;const A=useReducedMotion(),R=useRef(A);R.current=A;const[I,L]=useState(null),[T,w]=useState(null);useEffect(()=>{const e=createChatSession(t,{screen:r,layout:n,pathname:()=>r||"/",narrow:JSON.parse(m),conversationId:E.current??void 0,pageContext:()=>v.current,behaviour:()=>g.current?.()??null,prefs:b.current,getCaptchaToken:e=>h.current?.(e)??Promise.reject(new Error("No captcha handler.")),onEvent:(e,t)=>y.current?.(e,t),onError:e=>C.current?.(e),schedule:requestFrame,reducedMotion:()=>R.current});return L({client:t,screen:r,layout:n,narrowKey:m,session:e}),()=>e.dispose()},[t,r,n,m]);const O=null!==I&&I.client===t&&I.screen===r&&I.layout===n&&I.narrowKey===m?I.session:IDLE_SESSION,N=useSyncExternalStore(O.subscribe,O.getState),k=useMemo(()=>({load:()=>O.load(),submit:e=>O.submit(e),chooseQuickReply:e=>O.chooseQuickReply(e),answerInput:(e,t)=>O.answerInput(e,t),confirmAction:e=>O.confirmAction(e),rejectAction:(e,t)=>O.rejectAction(e,t),stop:()=>O.stop(),retry:()=>O.retry(),regenerate:()=>O.regenerate(),startEdit:e=>O.startEdit(e),cancelEdit:()=>O.cancelEdit(),attach:e=>O.attach(e),removeAttachment:e=>O.removeAttachment(e),openConversation:e=>O.openConversation(e),resumeLast:()=>O.resumeLast(),newConversation:()=>O.newConversation(),rate:(e,t,r)=>O.rate(e,t,r),reset:()=>O.reset(),requestHandoff:async e=>{w(null);try{await O.requestHandoff(e)}catch(e){const t=e instanceof Error&&""!==e.message?e.message:DEFAULT_CHAT_LABELS.errorGeneric;throw w(t),e}},notifyTyping:()=>O.notifyTyping(),resumeLive:()=>O.resumeLive()}),[O]),_=useRef(o);useEffect(()=>{O!==IDLE_SESSION&&o&&o!==_.current&&(_.current=o,O.openConversation(o))},[o,O]);const F=useRef("active"===AppState.currentState),P=useRef(!0),D=useCallback(()=>O.setLiveActive(F.current&&P.current),[O]),x=useCallback(e=>{P.current=e,D()},[D]);useEffect(()=>{D();const e=AppState.addEventListener("change",e=>{"active"===e?(F.current=!0,O.endHandoffPause()):F.current=!1,D()});return()=>e.remove()},[D,O]);const j=useCallback((e,t)=>{y.current?.(e,t)},[]);return{...N,...k,session:O,client:t,emit:j,setChatVisible:x,handoffError:T,onNavigate:p?S:void 0}}
1
+ "use strict";import{createChatSession,DEFAULT_CHAT_LABELS,emptyFeatures}from"@webority/chat-core";import{useReducedMotion}from"@webority/mobile-ui";import{useCallback,useEffect,useMemo,useRef,useState,useSyncExternalStore}from"react";import{AppState}from"react-native";const requestFrame=e=>{const t=requestAnimationFrame(e);return()=>cancelAnimationFrame(t)},NO_SUBSCRIPTION=()=>()=>{},IDLE_STATE=Object.freeze({profile:null,profileError:null,features:Object.freeze(emptyFeatures()),conversationId:null,conversationState:"Open",title:null,continuesConversationId:null,messages:[],thinking:!1,steps:[],streaming:!1,loading:!1,loadError:null,turnError:null,stopped:!1,messagesLeftToday:null,editing:null,attachments:[],lastConversation:null,open:!1,muted:!1,greeting:null,starters:[],pending:null,agent:null,agentTyping:null,live:"Off",handoffPending:!1,handoffContactRequestId:null,handoffPause:!1,openTickets:[],draft:null}),IDLE_SESSION=new Proxy({},{get:(e,t)=>{if("symbol"!=typeof t&&"client"!==t&&"toJSON"!==t&&!t.startsWith("$$")){if("getState"===t)return()=>IDLE_STATE;if("subscribe"===t)return NO_SUBSCRIPTION;if("then"!==t)return()=>Promise.resolve()}}});export function useChat(e){const{client:t,screen:r,layout:n,narrow:o,conversationId:s,pageContext:a,behaviour:u,attribution:c,prefs:i,getCaptchaToken:l,onEvent:f,onError:p,onNavigate:m}=e,d=JSON.stringify(o??{}),S=useRef(m);S.current=m;const E=useCallback(e=>S.current?.(e),[]),v=useRef(s);v.current=s;const g=useRef(a);g.current=a;const h=useRef(u);h.current=u;const y=useRef(c);y.current=c;const C=useRef(l);C.current=l;const b=useRef(f);b.current=f;const R=useRef(p);R.current=p;const A=useRef(i);A.current=i;const I=useReducedMotion(),L=useRef(I);L.current=I;const[T,w]=useState(null),[O,N]=useState(null);useEffect(()=>{const e=createChatSession(t,{screen:r,layout:n,pathname:()=>r||"/",narrow:JSON.parse(d),conversationId:v.current??void 0,pageContext:()=>g.current,behaviour:()=>h.current?.()??null,attribution:()=>y.current?.()??null,prefs:A.current,getCaptchaToken:e=>C.current?.(e)??Promise.reject(new Error("No captcha handler.")),onEvent:(e,t)=>b.current?.(e,t),onError:e=>R.current?.(e),schedule:requestFrame,reducedMotion:()=>L.current});return w({client:t,screen:r,layout:n,narrowKey:d,session:e}),()=>e.dispose()},[t,r,n,d]);const k=null!==T&&T.client===t&&T.screen===r&&T.layout===n&&T.narrowKey===d?T.session:IDLE_SESSION,_=useSyncExternalStore(k.subscribe,k.getState),F=useMemo(()=>({load:()=>k.load(),submit:e=>k.submit(e),chooseQuickReply:e=>k.chooseQuickReply(e),answerInput:(e,t)=>k.answerInput(e,t),confirmAction:e=>k.confirmAction(e),rejectAction:(e,t)=>k.rejectAction(e,t),stop:()=>k.stop(),retry:()=>k.retry(),regenerate:()=>k.regenerate(),startEdit:e=>k.startEdit(e),cancelEdit:()=>k.cancelEdit(),attach:e=>k.attach(e),removeAttachment:e=>k.removeAttachment(e),openConversation:e=>k.openConversation(e),resumeLast:()=>k.resumeLast(),newConversation:()=>k.newConversation(),rate:(e,t,r)=>k.rate(e,t,r),reset:()=>k.reset(),requestHandoff:async e=>{N(null);try{await k.requestHandoff(e)}catch(e){const t=e instanceof Error&&""!==e.message?e.message:DEFAULT_CHAT_LABELS.errorGeneric;throw N(t),e}},notifyTyping:()=>k.notifyTyping(),resumeLive:()=>k.resumeLive()}),[k]),P=useRef(s);useEffect(()=>{k!==IDLE_SESSION&&s&&s!==P.current&&(P.current=s,k.openConversation(s))},[s,k]);const D=useRef("active"===AppState.currentState),q=useRef(!0),x=useCallback(()=>k.setLiveActive(D.current&&q.current),[k]),j=useCallback(e=>{q.current=e,x()},[x]);useEffect(()=>{x();const e=AppState.addEventListener("change",e=>{"active"===e?(D.current=!0,k.endHandoffPause()):D.current=!1,x()});return()=>e.remove()},[x,k]);const H=useCallback((e,t)=>{b.current?.(e,t)},[]);return{..._,...F,session:k,client:t,emit:H,setChatVisible:j,handoffError:O,onNavigate:m?E:void 0}}
@@ -1 +1 @@
1
- "use strict";import{buildTranscript,transcriptToText}from"@webority/chat-core";import{Logger}from"@webority/mobile-core";import{useCallback,useEffect,useRef,useState}from"react";import{Share}from"react-native";const NOTICE_MS=3e3;async function shareMessages(e,r,t,s){const a=buildTranscript(e,r);if(0===a.entries.length)return;const c=transcriptToText(a,{heading:t,speakers:t});try{await Share.share({message:c,title:a.title})}catch(e){Logger.error("[chat] share failed",e),s()}}export default function useTranscriptActions(e,r){const[t,s]=useState(null),a=useRef(null),c=useRef(!1);useEffect(()=>(c.current=!0,()=>{c.current=!1,null!==a.current&&clearTimeout(a.current)}),[]);const u=useCallback(e=>{c.current&&(null!==a.current&&clearTimeout(a.current),s(e),a.current=setTimeout(()=>s(null),3e3))},[]),{messages:i,title:n}=e,l=e.features.FigureText,o=useCallback(e=>shareMessages([e],{labels:r,title:n,figureText:l},!1,()=>u(r.shareFailed)),[r,n,l,u]),f=useCallback(()=>shareMessages(i,{labels:r,title:n,figureText:l},!0,()=>u(r.shareFailed)),[i,r,n,l,u]);return{canShare:e.features.Share,notice:t,shareReply:o,shareConversation:f}}
1
+ "use strict";import{buildTranscript,transcriptToText}from"@webority/chat-core";import{Logger}from"@webority/mobile-core";import{useCallback,useEffect,useRef,useState}from"react";import{Share}from"react-native";const NOTICE_MS=3e3;async function shareMessages(e,t,r,s){const a=buildTranscript(e,t);if(0===a.entries.length)return;const i=transcriptToText(a,{heading:r,speakers:r});try{await Share.share({message:i,title:a.title})}catch(e){Logger.error("[chat] share failed",e),s()}}export default function useTranscriptActions(e,t){const[r,s]=useState(null),a=useRef(null),i=useRef(!1);useEffect(()=>(i.current=!0,()=>{i.current=!1,null!==a.current&&clearTimeout(a.current)}),[]);const n=useCallback(e=>{i.current&&(null!==a.current&&clearTimeout(a.current),s(e),a.current=setTimeout(()=>s(null),3e3))},[]),{messages:c,title:u}=e,l=e.features.FigureText,o=e.profile?.assistant.name,f=useCallback(e=>shareMessages([e],{labels:t,title:u,figureText:l,assistantName:o},!1,()=>n(t.shareFailed)),[t,u,l,o,n]),h=useCallback(()=>shareMessages(c,{labels:t,title:u,figureText:l,assistantName:o},!0,()=>n(t.shareFailed)),[c,t,u,l,o,n]);return{canShare:e.features.Share,notice:r,shareReply:f,shareConversation:h}}
@@ -3,7 +3,8 @@ import type React from "react";
3
3
  export interface AgentBylineProps {
4
4
  author: ChatAuthor;
5
5
  labels: ChatLabels;
6
+ showAvatar?: boolean;
6
7
  }
7
8
  /** The name and picture of the person who wrote an agent message. The spoken text carries the name instead. */
8
- export declare function AgentByline({ author, labels }: AgentBylineProps): React.ReactElement;
9
+ export declare function AgentByline({ author, labels, showAvatar }: AgentBylineProps): React.ReactElement;
9
10
  //# sourceMappingURL=AgentByline.d.ts.map
@@ -1,10 +1,11 @@
1
- import { type ChatLabels, type ChatLook, type ChatUploadFile } from "@webority/chat-core";
1
+ import { type ChatLabels, type ChatLook } from "@webority/chat-core";
2
2
  import type React from "react";
3
+ import type { PickAttachments } from "./types";
3
4
  import type { UseChatResult } from "./useChat";
4
5
  export interface ChatComposerProps {
5
6
  chat: UseChatResult;
6
7
  labels: ChatLabels;
7
- pickAttachments?: () => Promise<ChatUploadFile[]>;
8
+ pickAttachments?: PickAttachments;
8
9
  keyboardOffset?: number;
9
10
  keyboardAware?: boolean;
10
11
  safeArea?: boolean;
@@ -12,6 +13,8 @@ export interface ChatComposerProps {
12
13
  focusRef?: React.MutableRefObject<(() => void) | null>;
13
14
  /** The resolved look: its input ring and send reveal draw the box and the send button. */
14
15
  look?: ChatLook;
16
+ /** Icon name for the send button; the look's input.sendIcon. */
17
+ sendIcon?: string;
15
18
  }
16
- export declare function ChatComposer({ chat, labels, pickAttachments, keyboardOffset, keyboardAware, safeArea, testID, focusRef, look, }: ChatComposerProps): React.ReactElement;
19
+ export declare function ChatComposer({ chat, labels, pickAttachments, keyboardOffset, keyboardAware, safeArea, testID, focusRef, look, sendIcon, }: ChatComposerProps): React.ReactElement;
17
20
  //# sourceMappingURL=ChatComposer.d.ts.map
@@ -1,6 +1,6 @@
1
- import { type ChatLabels, type ChatLoaderStyle, type ChatLookInput, type ChatPart, type ChatUploadFile } from "@webority/chat-core";
1
+ import { type ChatLabels, type ChatLoaderStyle, type ChatLookInput, type ChatPart } from "@webority/chat-core";
2
2
  import type React from "react";
3
- import type { ChatAppearance, ChatLayoutParts, ChatOpenTicketHandler, ChatRenderers } from "./types";
3
+ import type { ChatAppearance, ChatLayoutParts, ChatOpenTicketHandler, ChatRenderers, PickAttachments } from "./types";
4
4
  import type { UseChatResult } from "./useChat";
5
5
  export type ChatLayout = "screen" | "sheet" | "embedded";
6
6
  /** The props every shell passes down to its frame. */
@@ -12,7 +12,7 @@ export interface ChatCommonProps {
12
12
  loader?: ChatLoaderStyle;
13
13
  /** The look: its input ring and send reveal, its panel motion and its motion switch. Unset values take the defaults. */
14
14
  look?: ChatLookInput;
15
- pickAttachments?: () => Promise<ChatUploadFile[]>;
15
+ pickAttachments?: PickAttachments;
16
16
  onOpenAttachment?: (part: Extract<ChatPart, {
17
17
  kind: "File";
18
18
  }>) => void;
@@ -1,8 +1,10 @@
1
- import type { ChatLook } from "@webority/chat-core";
1
+ import type { ChatLauncherMark, ChatLook } from "@webority/chat-core";
2
2
  import type React from "react";
3
3
  import { type View } from "react-native";
4
4
  export interface ChatLauncherProps {
5
5
  look: ChatLook;
6
+ /** The chat is open. The launcher leaves: at once, or by shrinking first when the look is expressive. */
7
+ hidden: boolean;
6
8
  label: string;
7
9
  side: "start" | "end";
8
10
  offsetX: number;
@@ -10,6 +12,8 @@ export interface ChatLauncherProps {
10
12
  /** Plays the entrance once, on the first show of the launcher. */
11
13
  enter: boolean;
12
14
  reduced: boolean;
15
+ mark?: ChatLauncherMark;
16
+ avatar?: string | null;
13
17
  buttonRef: React.RefObject<View | null>;
14
18
  onPress: () => void;
15
19
  testID: string;
@@ -18,5 +22,5 @@ export interface ChatLauncherProps {
18
22
  * The floating launcher as the look draws it: round or pill, with its label, the chosen entrance and the
19
23
  * float idle. The entrance moves the button's own wrapper, so a scale or a turn happens around the button.
20
24
  */
21
- export declare function ChatLauncher({ look, label, side, offsetX, offsetY, enter, reduced, buttonRef, onPress, testID, }: ChatLauncherProps): React.ReactElement;
25
+ export declare function ChatLauncher({ look, hidden, label, side, offsetX, offsetY, enter, reduced, mark, avatar, buttonRef, onPress, testID, }: ChatLauncherProps): React.ReactElement | null;
22
26
  //# sourceMappingURL=ChatLauncher.d.ts.map
@@ -6,7 +6,10 @@ export interface ChatStartersProps {
6
6
  chat: UseChatResult;
7
7
  labels: ChatLabels;
8
8
  openTicket?: ChatOpenTicketHandler;
9
+ avatar?: string | null;
10
+ motion?: "On" | "Reduced";
11
+ greetingLoaderMs?: number;
9
12
  testID?: string;
10
13
  }
11
- export declare function ChatStarters({ chat, labels, openTicket, testID }: ChatStartersProps): React.ReactElement | null;
14
+ export declare function ChatStarters({ chat, labels, openTicket, avatar, motion, greetingLoaderMs, testID, }: ChatStartersProps): React.ReactElement | null;
12
15
  //# sourceMappingURL=ChatStarters.d.ts.map
@@ -1,7 +1,7 @@
1
- import type { ChatLabels, ChatLoaderStyle, ChatMotion, ChatPart, ChatUploadFile } from "@webority/chat-core";
1
+ import type { ChatLabels, ChatLoaderStyle, ChatMotion, ChatPart } from "@webority/chat-core";
2
2
  import type React from "react";
3
3
  import { type StyleProp, type ViewStyle } from "react-native";
4
- import type { ChatLayoutParts, ChatOpenTicketHandler, ChatRenderers } from "./types";
4
+ import type { ChatLayoutParts, ChatOpenTicketHandler, ChatRenderers, PickAttachments } from "./types";
5
5
  import type { UseChatResult } from "./useChat";
6
6
  export interface ChatThreadProps {
7
7
  chat: UseChatResult;
@@ -10,7 +10,13 @@ export interface ChatThreadProps {
10
10
  layoutParts?: ChatLayoutParts;
11
11
  loader?: ChatLoaderStyle;
12
12
  motion?: ChatMotion;
13
- pickAttachments?: () => Promise<ChatUploadFile[]>;
13
+ /** The assistant's picture, drawn beside its replies. */
14
+ avatar?: string | null;
15
+ /** False hides the pictures beside replies. */
16
+ replyAvatars?: boolean;
17
+ /** A ring turns around the thinking mark and the streaming reply's picture. Off unless the look sets it. */
18
+ expressive?: boolean;
19
+ pickAttachments?: PickAttachments;
14
20
  onOpenAttachment?: (part: Extract<ChatPart, {
15
21
  kind: "File";
16
22
  }>) => void;
@@ -32,5 +38,5 @@ export interface ChatThreadProps {
32
38
  * pill while a paced reply is held, the loader while a reply is awaited and the error row after a
33
39
  * failed or stopped turn.
34
40
  */
35
- export declare function ChatThread({ chat, labels, renderers, layoutParts, loader, motion, pickAttachments, onOpenAttachment, onOpenTarget, onNavigate, openTicket, handoffHosts, resolveLink, focusComposer, keyboardAware, keyboardOffset, empty, style, testID, }: ChatThreadProps): React.ReactElement;
41
+ export declare function ChatThread({ chat, labels, renderers, layoutParts, loader, motion, avatar, replyAvatars, expressive, pickAttachments, onOpenAttachment, onOpenTarget, onNavigate, openTicket, handoffHosts, resolveLink, focusComposer, keyboardAware, keyboardOffset, empty, style, testID, }: ChatThreadProps): React.ReactElement;
36
42
  //# sourceMappingURL=ChatThread.d.ts.map
@@ -3,4 +3,5 @@ import type { ChatLiveMessage } from "@webority/chat-core";
3
3
  export declare function focusForAccessibility(node: unknown): void;
4
4
  export declare function messageSignature(message: ChatLiveMessage): string;
5
5
  export declare function defaultOpenTarget(target: string): void;
6
+ export declare const WEB_STRONG: object;
6
7
  //# sourceMappingURL=chatShared.d.ts.map
@@ -0,0 +1,9 @@
1
+ import type React from "react";
2
+ export interface ReplyRingProps {
3
+ active: boolean;
4
+ reduced: boolean;
5
+ children: React.ReactNode;
6
+ }
7
+ /** A two-tone ring that turns around its children while a reply is in progress; plain children otherwise. */
8
+ export declare function ReplyRing({ active, reduced, children }: ReplyRingProps): React.JSX.Element;
9
+ //# sourceMappingURL=ReplyRing.d.ts.map
@@ -0,0 +1,7 @@
1
+ import type { ChatQuickReplyVariant } from "@webority/chat-core";
2
+ import type { ChipTone, ChipVariant } from "@webority/mobile-ui";
3
+ export declare function chipLook(variant: ChatQuickReplyVariant | null): {
4
+ variant: ChipVariant;
5
+ tone?: ChipTone;
6
+ };
7
+ //# sourceMappingURL=chipLook.d.ts.map
@@ -27,11 +27,16 @@ export interface ChatTurnHostApi {
27
27
  /** Moves focus to the composer input after a quick reply is chosen. */
28
28
  focusComposer?: () => void;
29
29
  }
30
+ /**
31
+ * Opens the app's file picker. accept lists the media types a file question takes;
32
+ * an app may ignore it, the server checks every upload.
33
+ */
34
+ export type PickAttachments = (accept?: readonly string[]) => Promise<ChatUploadFile[]>;
30
35
  export type ChatPartRendererProps<P extends ChatPart = ChatPart> = {
31
36
  part: P;
32
37
  message: ChatLiveMessage;
33
38
  turn: ChatTurnApi & ChatTurnHostApi;
34
- pickAttachments?: () => Promise<ChatUploadFile[]>;
39
+ pickAttachments?: PickAttachments;
35
40
  };
36
41
  export type ChatRenderers = Partial<{
37
42
  [K in ChatPartKind]: React.ComponentType<ChatPartRendererProps<Extract<ChatPart, {
@@ -1,4 +1,4 @@
1
- import type { ChatBehaviour, ChatClient, ChatFeature, ChatSession, ChatSessionState } from "@webority/chat-core";
1
+ import type { ChatAttribution, ChatBehaviour, ChatClient, ChatFeature, ChatSession, ChatSessionState } from "@webority/chat-core";
2
2
  import type { ChatLayout } from "./ChatFrame";
3
3
  export interface ChatPrefs {
4
4
  get(key: string): string | null;
@@ -18,6 +18,8 @@ export interface UseChatOptions {
18
18
  pageContext?: unknown;
19
19
  /** The behaviour the host app measured; read at the moment of sending. */
20
20
  behaviour?: () => ChatBehaviour | null;
21
+ /** The campaign touch a lead captured in the chat carries; read at the moment of sending. */
22
+ attribution?: () => ChatAttribution | null;
21
23
  /** Where the session keeps the mute choice (key wchat:muted). */
22
24
  prefs: ChatPrefs;
23
25
  getCaptchaToken?: (action: string) => Promise<string | null>;
@@ -3,7 +3,8 @@ import type React from "react";
3
3
  export interface AgentBylineProps {
4
4
  author: ChatAuthor;
5
5
  labels: ChatLabels;
6
+ showAvatar?: boolean;
6
7
  }
7
8
  /** The name and picture of the person who wrote an agent message. The spoken text carries the name instead. */
8
- export declare function AgentByline({ author, labels }: AgentBylineProps): React.ReactElement;
9
+ export declare function AgentByline({ author, labels, showAvatar }: AgentBylineProps): React.ReactElement;
9
10
  //# sourceMappingURL=AgentByline.d.ts.map
@@ -1,10 +1,11 @@
1
- import { type ChatLabels, type ChatLook, type ChatUploadFile } from "@webority/chat-core";
1
+ import { type ChatLabels, type ChatLook } from "@webority/chat-core";
2
2
  import type React from "react";
3
+ import type { PickAttachments } from "./types.js";
3
4
  import type { UseChatResult } from "./useChat.js";
4
5
  export interface ChatComposerProps {
5
6
  chat: UseChatResult;
6
7
  labels: ChatLabels;
7
- pickAttachments?: () => Promise<ChatUploadFile[]>;
8
+ pickAttachments?: PickAttachments;
8
9
  keyboardOffset?: number;
9
10
  keyboardAware?: boolean;
10
11
  safeArea?: boolean;
@@ -12,6 +13,8 @@ export interface ChatComposerProps {
12
13
  focusRef?: React.MutableRefObject<(() => void) | null>;
13
14
  /** The resolved look: its input ring and send reveal draw the box and the send button. */
14
15
  look?: ChatLook;
16
+ /** Icon name for the send button; the look's input.sendIcon. */
17
+ sendIcon?: string;
15
18
  }
16
- export declare function ChatComposer({ chat, labels, pickAttachments, keyboardOffset, keyboardAware, safeArea, testID, focusRef, look, }: ChatComposerProps): React.ReactElement;
19
+ export declare function ChatComposer({ chat, labels, pickAttachments, keyboardOffset, keyboardAware, safeArea, testID, focusRef, look, sendIcon, }: ChatComposerProps): React.ReactElement;
17
20
  //# sourceMappingURL=ChatComposer.d.ts.map
@@ -1,6 +1,6 @@
1
- import { type ChatLabels, type ChatLoaderStyle, type ChatLookInput, type ChatPart, type ChatUploadFile } from "@webority/chat-core";
1
+ import { type ChatLabels, type ChatLoaderStyle, type ChatLookInput, type ChatPart } from "@webority/chat-core";
2
2
  import type React from "react";
3
- import type { ChatAppearance, ChatLayoutParts, ChatOpenTicketHandler, ChatRenderers } from "./types.js";
3
+ import type { ChatAppearance, ChatLayoutParts, ChatOpenTicketHandler, ChatRenderers, PickAttachments } from "./types.js";
4
4
  import type { UseChatResult } from "./useChat.js";
5
5
  export type ChatLayout = "screen" | "sheet" | "embedded";
6
6
  /** The props every shell passes down to its frame. */
@@ -12,7 +12,7 @@ export interface ChatCommonProps {
12
12
  loader?: ChatLoaderStyle;
13
13
  /** The look: its input ring and send reveal, its panel motion and its motion switch. Unset values take the defaults. */
14
14
  look?: ChatLookInput;
15
- pickAttachments?: () => Promise<ChatUploadFile[]>;
15
+ pickAttachments?: PickAttachments;
16
16
  onOpenAttachment?: (part: Extract<ChatPart, {
17
17
  kind: "File";
18
18
  }>) => void;
@@ -1,8 +1,10 @@
1
- import type { ChatLook } from "@webority/chat-core";
1
+ import type { ChatLauncherMark, ChatLook } from "@webority/chat-core";
2
2
  import type React from "react";
3
3
  import { type View } from "react-native";
4
4
  export interface ChatLauncherProps {
5
5
  look: ChatLook;
6
+ /** The chat is open. The launcher leaves: at once, or by shrinking first when the look is expressive. */
7
+ hidden: boolean;
6
8
  label: string;
7
9
  side: "start" | "end";
8
10
  offsetX: number;
@@ -10,6 +12,8 @@ export interface ChatLauncherProps {
10
12
  /** Plays the entrance once, on the first show of the launcher. */
11
13
  enter: boolean;
12
14
  reduced: boolean;
15
+ mark?: ChatLauncherMark;
16
+ avatar?: string | null;
13
17
  buttonRef: React.RefObject<View | null>;
14
18
  onPress: () => void;
15
19
  testID: string;
@@ -18,5 +22,5 @@ export interface ChatLauncherProps {
18
22
  * The floating launcher as the look draws it: round or pill, with its label, the chosen entrance and the
19
23
  * float idle. The entrance moves the button's own wrapper, so a scale or a turn happens around the button.
20
24
  */
21
- export declare function ChatLauncher({ look, label, side, offsetX, offsetY, enter, reduced, buttonRef, onPress, testID, }: ChatLauncherProps): React.ReactElement;
25
+ export declare function ChatLauncher({ look, hidden, label, side, offsetX, offsetY, enter, reduced, mark, avatar, buttonRef, onPress, testID, }: ChatLauncherProps): React.ReactElement | null;
22
26
  //# sourceMappingURL=ChatLauncher.d.ts.map
@@ -6,7 +6,10 @@ export interface ChatStartersProps {
6
6
  chat: UseChatResult;
7
7
  labels: ChatLabels;
8
8
  openTicket?: ChatOpenTicketHandler;
9
+ avatar?: string | null;
10
+ motion?: "On" | "Reduced";
11
+ greetingLoaderMs?: number;
9
12
  testID?: string;
10
13
  }
11
- export declare function ChatStarters({ chat, labels, openTicket, testID }: ChatStartersProps): React.ReactElement | null;
14
+ export declare function ChatStarters({ chat, labels, openTicket, avatar, motion, greetingLoaderMs, testID, }: ChatStartersProps): React.ReactElement | null;
12
15
  //# sourceMappingURL=ChatStarters.d.ts.map
@@ -1,7 +1,7 @@
1
- import type { ChatLabels, ChatLoaderStyle, ChatMotion, ChatPart, ChatUploadFile } from "@webority/chat-core";
1
+ import type { ChatLabels, ChatLoaderStyle, ChatMotion, ChatPart } from "@webority/chat-core";
2
2
  import type React from "react";
3
3
  import { type StyleProp, type ViewStyle } from "react-native";
4
- import type { ChatLayoutParts, ChatOpenTicketHandler, ChatRenderers } from "./types.js";
4
+ import type { ChatLayoutParts, ChatOpenTicketHandler, ChatRenderers, PickAttachments } from "./types.js";
5
5
  import type { UseChatResult } from "./useChat.js";
6
6
  export interface ChatThreadProps {
7
7
  chat: UseChatResult;
@@ -10,7 +10,13 @@ export interface ChatThreadProps {
10
10
  layoutParts?: ChatLayoutParts;
11
11
  loader?: ChatLoaderStyle;
12
12
  motion?: ChatMotion;
13
- pickAttachments?: () => Promise<ChatUploadFile[]>;
13
+ /** The assistant's picture, drawn beside its replies. */
14
+ avatar?: string | null;
15
+ /** False hides the pictures beside replies. */
16
+ replyAvatars?: boolean;
17
+ /** A ring turns around the thinking mark and the streaming reply's picture. Off unless the look sets it. */
18
+ expressive?: boolean;
19
+ pickAttachments?: PickAttachments;
14
20
  onOpenAttachment?: (part: Extract<ChatPart, {
15
21
  kind: "File";
16
22
  }>) => void;
@@ -32,5 +38,5 @@ export interface ChatThreadProps {
32
38
  * pill while a paced reply is held, the loader while a reply is awaited and the error row after a
33
39
  * failed or stopped turn.
34
40
  */
35
- export declare function ChatThread({ chat, labels, renderers, layoutParts, loader, motion, pickAttachments, onOpenAttachment, onOpenTarget, onNavigate, openTicket, handoffHosts, resolveLink, focusComposer, keyboardAware, keyboardOffset, empty, style, testID, }: ChatThreadProps): React.ReactElement;
41
+ export declare function ChatThread({ chat, labels, renderers, layoutParts, loader, motion, avatar, replyAvatars, expressive, pickAttachments, onOpenAttachment, onOpenTarget, onNavigate, openTicket, handoffHosts, resolveLink, focusComposer, keyboardAware, keyboardOffset, empty, style, testID, }: ChatThreadProps): React.ReactElement;
36
42
  //# sourceMappingURL=ChatThread.d.ts.map
@@ -3,4 +3,5 @@ import type { ChatLiveMessage } from "@webority/chat-core";
3
3
  export declare function focusForAccessibility(node: unknown): void;
4
4
  export declare function messageSignature(message: ChatLiveMessage): string;
5
5
  export declare function defaultOpenTarget(target: string): void;
6
+ export declare const WEB_STRONG: object;
6
7
  //# sourceMappingURL=chatShared.d.ts.map