@webority/mobile-chat 0.133.0 → 0.134.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 (119) hide show
  1. package/lib/commonjs/AgentByline.js +1 -1
  2. package/lib/commonjs/ChatComposer.js +1 -1
  3. package/lib/commonjs/ChatConversationActions.js +1 -1
  4. package/lib/commonjs/ChatDictationButton.js +1 -1
  5. package/lib/commonjs/ChatEmbed.js +1 -1
  6. package/lib/commonjs/ChatFooter.js +1 -1
  7. package/lib/commonjs/ChatFrame.js +1 -1
  8. package/lib/commonjs/ChatHistory.js +1 -1
  9. package/lib/commonjs/ChatLiveBar.js +1 -1
  10. package/lib/commonjs/ChatMessageActions.js +1 -1
  11. package/lib/commonjs/ChatNudge.js +1 -1
  12. package/lib/commonjs/ChatOpenTickets.js +1 -1
  13. package/lib/commonjs/ChatPastChats.js +1 -0
  14. package/lib/commonjs/ChatScreen.js +1 -1
  15. package/lib/commonjs/ChatSheet.js +1 -1
  16. package/lib/commonjs/ChatStarters.js +1 -1
  17. package/lib/commonjs/ChatThread.js +1 -1
  18. package/lib/commonjs/ReadAloudButton.js +1 -1
  19. package/lib/commonjs/features.map.json +3 -3
  20. package/lib/commonjs/index.js +1 -1
  21. package/lib/commonjs/loaders/ChatLoader.js +1 -1
  22. package/lib/commonjs/renderers/ActionPart.js +1 -1
  23. package/lib/commonjs/renderers/ChartPart.js +1 -1
  24. package/lib/commonjs/renderers/FigureText.js +1 -1
  25. package/lib/commonjs/renderers/FiguresPart.js +1 -1
  26. package/lib/commonjs/renderers/FilePart.js +1 -1
  27. package/lib/commonjs/renderers/HandoffPart.js +1 -1
  28. package/lib/commonjs/renderers/ImagePart.js +1 -1
  29. package/lib/commonjs/renderers/InputRequestPart.js +1 -1
  30. package/lib/commonjs/renderers/NoticePart.js +1 -1
  31. package/lib/commonjs/renderers/QuickRepliesPart.js +1 -1
  32. package/lib/commonjs/renderers/RecordCardPart.js +1 -1
  33. package/lib/commonjs/renderers/SourcesPart.js +1 -1
  34. package/lib/commonjs/renderers/TablePart.js +1 -1
  35. package/lib/commonjs/renderers/TicketPart.js +1 -1
  36. package/lib/commonjs/renderers/VoiceClipPart.js +1 -1
  37. package/lib/commonjs/speech/phoneSpeech.js +1 -1
  38. package/lib/commonjs/speech/speechText.js +1 -1
  39. package/lib/commonjs/useChat.js +1 -1
  40. package/lib/commonjs/useChatHaptics.js +1 -1
  41. package/lib/commonjs/useChatSound.js +1 -0
  42. package/lib/module/AgentByline.js +1 -1
  43. package/lib/module/ChatComposer.js +1 -1
  44. package/lib/module/ChatConversationActions.js +1 -1
  45. package/lib/module/ChatDictationButton.js +1 -1
  46. package/lib/module/ChatEmbed.js +1 -1
  47. package/lib/module/ChatFooter.js +1 -1
  48. package/lib/module/ChatFrame.js +1 -1
  49. package/lib/module/ChatHistory.js +1 -1
  50. package/lib/module/ChatLiveBar.js +1 -1
  51. package/lib/module/ChatMessageActions.js +1 -1
  52. package/lib/module/ChatNudge.js +1 -1
  53. package/lib/module/ChatOpenTickets.js +1 -1
  54. package/lib/module/ChatPastChats.js +1 -0
  55. package/lib/module/ChatScreen.js +1 -1
  56. package/lib/module/ChatSheet.js +1 -1
  57. package/lib/module/ChatStarters.js +1 -1
  58. package/lib/module/ChatThread.js +1 -1
  59. package/lib/module/ReadAloudButton.js +1 -1
  60. package/lib/module/features.map.json +3 -3
  61. package/lib/module/index.js +1 -1
  62. package/lib/module/loaders/ChatLoader.js +1 -1
  63. package/lib/module/renderers/ActionPart.js +1 -1
  64. package/lib/module/renderers/ChartPart.js +1 -1
  65. package/lib/module/renderers/FigureText.js +1 -1
  66. package/lib/module/renderers/FiguresPart.js +1 -1
  67. package/lib/module/renderers/FilePart.js +1 -1
  68. package/lib/module/renderers/HandoffPart.js +1 -1
  69. package/lib/module/renderers/ImagePart.js +1 -1
  70. package/lib/module/renderers/InputRequestPart.js +1 -1
  71. package/lib/module/renderers/NoticePart.js +1 -1
  72. package/lib/module/renderers/QuickRepliesPart.js +1 -1
  73. package/lib/module/renderers/RecordCardPart.js +1 -1
  74. package/lib/module/renderers/SourcesPart.js +1 -1
  75. package/lib/module/renderers/TablePart.js +1 -1
  76. package/lib/module/renderers/TicketPart.js +1 -1
  77. package/lib/module/renderers/VoiceClipPart.js +1 -1
  78. package/lib/module/speech/phoneSpeech.js +1 -1
  79. package/lib/module/speech/speechText.js +1 -1
  80. package/lib/module/useChat.js +1 -1
  81. package/lib/module/useChatHaptics.js +1 -1
  82. package/lib/module/useChatSound.js +1 -0
  83. package/lib/typescript/commonjs/ChatComposer.d.ts +2 -1
  84. package/lib/typescript/commonjs/ChatConversationActions.d.ts +1 -1
  85. package/lib/typescript/commonjs/ChatDictationButton.d.ts +3 -1
  86. package/lib/typescript/commonjs/ChatEmbed.d.ts +1 -1
  87. package/lib/typescript/commonjs/ChatFrame.d.ts +7 -1
  88. package/lib/typescript/commonjs/ChatPastChats.d.ts +21 -0
  89. package/lib/typescript/commonjs/ChatScreen.d.ts +1 -1
  90. package/lib/typescript/commonjs/ChatSheet.d.ts +1 -1
  91. package/lib/typescript/commonjs/ChatThread.d.ts +3 -1
  92. package/lib/typescript/commonjs/index.d.ts +1 -0
  93. package/lib/typescript/commonjs/renderers/ChartPart.d.ts +1 -1
  94. package/lib/typescript/commonjs/renderers/FigureText.d.ts +4 -2
  95. package/lib/typescript/commonjs/renderers/HandoffPart.d.ts +1 -1
  96. package/lib/typescript/commonjs/renderers/VoiceClipPart.d.ts +1 -1
  97. package/lib/typescript/commonjs/speech/speechText.d.ts +3 -3
  98. package/lib/typescript/commonjs/types.d.ts +9 -1
  99. package/lib/typescript/commonjs/useChat.d.ts +2 -0
  100. package/lib/typescript/commonjs/useChatSound.d.ts +35 -0
  101. package/lib/typescript/module/ChatComposer.d.ts +2 -1
  102. package/lib/typescript/module/ChatConversationActions.d.ts +1 -1
  103. package/lib/typescript/module/ChatDictationButton.d.ts +3 -1
  104. package/lib/typescript/module/ChatEmbed.d.ts +1 -1
  105. package/lib/typescript/module/ChatFrame.d.ts +7 -1
  106. package/lib/typescript/module/ChatPastChats.d.ts +21 -0
  107. package/lib/typescript/module/ChatScreen.d.ts +1 -1
  108. package/lib/typescript/module/ChatSheet.d.ts +1 -1
  109. package/lib/typescript/module/ChatThread.d.ts +3 -1
  110. package/lib/typescript/module/index.d.ts +1 -0
  111. package/lib/typescript/module/renderers/ChartPart.d.ts +1 -1
  112. package/lib/typescript/module/renderers/FigureText.d.ts +4 -2
  113. package/lib/typescript/module/renderers/HandoffPart.d.ts +1 -1
  114. package/lib/typescript/module/renderers/VoiceClipPart.d.ts +1 -1
  115. package/lib/typescript/module/speech/speechText.d.ts +3 -3
  116. package/lib/typescript/module/types.d.ts +9 -1
  117. package/lib/typescript/module/useChat.d.ts +2 -0
  118. package/lib/typescript/module/useChatSound.d.ts +35 -0
  119. package/package.json +10 -9
@@ -1 +1 @@
1
- "use strict";import{formatFigure,toFigureText}from"@webority/chat-core";import{formatCompactNumber,formatNumber,formatPercent}from"@webority/mobile-core";import{BarChart,ProgressBar,Sparkline,Text,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{FigureText,runsToText}from"./FigureText.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const TONES=["primary","info","success","warning","danger","neutral"],toneAt=e=>TONES[e%TONES.length]??"primary",withPositions=e=>e.reduce((e,t)=>(e.push({key:e.length,item:t}),e),[]),writeValue=(e,t)=>{const r=0!==e&&Math.abs(e)<.001?runsToText(formatFigure(e)):formatNumber(e,{maximumFractionDigits:2});return t?`${r} ${t}`:r};export function ChartPart({part:e,turn:t}){const r=useTheme();if(e.series.every(e=>0===e.points.length))return null;const{unit:a}=e,i=e.title?toFigureText(e.title):t.labels.chart,l=e.series.length>1;return _jsxs(View,{accessibilityLabel:i,style:{gap:r.space.sm},children:[e.title?_jsx(FigureText,{text:e.title,variant:"label",color:"primary",strong:!0}):null,withPositions(e.series).map(({key:s,item:o})=>{const n=toneAt(s),c=toFigureText(o.name)||i,u=o.points;if(0===u.length)return _jsxs(View,{style:{gap:r.space.xs},children:[l?_jsx(Text,{variant:"caption",color:"secondary",children:toFigureText(o.name)}):null,_jsx(Text,{variant:"bodySmall",color:"secondary",children:t.labels.chartEmpty})]},s);const m=u.map(e=>e.value),x=m.reduce((e,t)=>Math.min(e,t)),h=m.reduce((e,t)=>Math.max(e,t)),p=u[0],g=u[u.length-1];let b;if("Bar"===e.chartType)b=_jsx(BarChart,{data:u.map(e=>({label:toFigureText(e.label),value:e.value})),height:u.length>4?300:240,label:c,formatValue:e=>writeValue(e,a),formatTick:e=>a?`${formatCompactNumber(e)} ${a}`:formatCompactNumber(e),tone:n});else if("Line"===e.chartType)b=_jsxs(View,{style:{gap:r.space.xs},children:[_jsx(Sparkline,{data:m,height:160,fill:!0,tone:n,label:c,formatLabel:e=>writeValue(e,a)}),_jsxs(View,{style:{flexDirection:"row",justifyContent:"space-between"},children:[_jsx(Text,{variant:"caption",color:"tertiary",children:toFigureText(p.label)}),u.length>1?_jsx(Text,{variant:"caption",color:"tertiary",children:toFigureText(g.label)}):null]}),_jsx(Text,{variant:"caption",color:"secondary",children:`${t.labels.chartLow(writeValue(x,a))} ${t.labels.chartHigh(writeValue(h,a))}`})]});else{const e=m.reduce((e,t)=>e+(Number.isFinite(t)&&t>0?t:0),0);b=_jsx(View,{accessibilityRole:"list",style:{gap:r.space.sm},children:withPositions(u).map(({key:t,item:r})=>{const i=e>0&&Number.isFinite(r.value)&&r.value>0?r.value/e:0;return _jsx(ProgressBar,{progress:i,height:8,tone:toneAt(t),label:_jsx(FigureText,{text:r.label,variant:"bodySmall"}),valueLabel:`${writeValue(r.value,a)} (${formatPercent(i,{maximumFractionDigits:0})})`},t)})})}return _jsxs(View,{style:{gap:r.space.xs},children:[l?_jsx(Text,{variant:"caption",color:"secondary",children:toFigureText(o.name)}):null,b]},s)})]})}
1
+ "use strict";import{formatFigure,toFigureText}from"@webority/chat-core";import{formatCompactNumber,formatNumber,formatPercent}from"@webority/mobile-core";import{BarChart,Button,ProgressBar,Sparkline,Text,useTheme}from"@webority/mobile-ui";import{useState}from"react";import{View}from"react-native";import{FigureText,runsToText}from"./FigureText.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const TONES=["primary","info","success","warning","danger","neutral"],toneAt=e=>TONES[e%TONES.length]??"primary",MAX_SERIES=8,withPositions=e=>e.reduce((e,t)=>(e.push({key:e.length,item:t}),e),[]),writeValue=(e,t)=>{const r=0!==e&&Math.abs(e)<.001?runsToText(formatFigure(e)):formatNumber(e,{maximumFractionDigits:2});return t?`${r} ${t}`:r};export function ChartPart({part:e,turn:t}){const r=useTheme(),[a,i]=useState(!1),l="Donut"===e.chartType?e.series.slice(0,1):e.series.slice(0,8);if(l.every(e=>0===e.points.length))return _jsxs(View,{style:{gap:r.space.sm},children:[e.title?_jsx(FigureText,{text:e.title,variant:"label",color:"primary",strong:!0}):null,_jsx(Text,{variant:"bodySmall",color:"secondary",children:t.labels.chartEmpty})]});const{unit:s}=e,o=e.title?toFigureText(e.title):t.labels.chart,n=l.length>1;return _jsxs(View,{accessibilityLabel:o,style:{gap:r.space.sm},children:[e.title?_jsx(FigureText,{text:e.title,variant:"label",color:"primary",strong:!0}):null,_jsx(Button,{label:a?t.labels.chartShowChart:t.labels.chartShowTable,variant:"link",size:"sm",onPress:()=>i(e=>!e)}),withPositions(l).map(({key:i,item:l})=>{const c=toneAt(i),m=toFigureText(l.name)||o,u=l.points;if(0===u.length)return _jsxs(View,{style:{gap:r.space.xs},children:[n?_jsx(Text,{variant:"caption",color:"secondary",children:toFigureText(l.name)}):null,_jsx(Text,{variant:"bodySmall",color:"secondary",children:t.labels.chartEmpty})]},i);const x=u.map(e=>e.value),h=x.reduce((e,t)=>Math.min(e,t)),p=x.reduce((e,t)=>Math.max(e,t)),b=u[0],y=u[u.length-1];let g;if(a)g=_jsx(View,{accessibilityRole:"summary",style:{gap:r.space.xs},children:withPositions(u).map(({key:e,item:t})=>_jsxs(View,{style:{flexDirection:"row",justifyContent:"space-between",gap:r.space.sm},children:[_jsx(Text,{variant:"bodySmall",color:"primary",children:toFigureText(t.label)}),_jsx(Text,{variant:"bodySmall",color:"primary",children:writeValue(t.value,s)})]},e))});else if("Bar"===e.chartType)g=_jsx(BarChart,{data:u.map(e=>({label:toFigureText(e.label),value:e.value})),height:u.length>4?300:240,label:m,formatValue:e=>writeValue(e,s),formatTick:e=>s?`${formatCompactNumber(e)} ${s}`:formatCompactNumber(e),tone:c});else if("Line"===e.chartType)g=_jsxs(View,{style:{gap:r.space.xs},children:[_jsx(Sparkline,{data:x,height:160,fill:!0,tone:c,label:m,formatLabel:e=>writeValue(e,s)}),_jsxs(View,{style:{flexDirection:"row",justifyContent:"space-between"},children:[_jsx(Text,{variant:"caption",color:"tertiary",children:toFigureText(b.label)}),u.length>1?_jsx(Text,{variant:"caption",color:"tertiary",children:toFigureText(y.label)}):null]}),_jsx(Text,{variant:"caption",color:"secondary",children:`${t.labels.chartLow(writeValue(h,s))} ${t.labels.chartHigh(writeValue(p,s))}`})]});else{const e=x.reduce((e,t)=>e+(Number.isFinite(t)&&t>0?t:0),0);g=_jsx(View,{accessibilityRole:"list",style:{gap:r.space.sm},children:withPositions(u).map(({key:t,item:r})=>{const a=e>0&&Number.isFinite(r.value)&&r.value>0?r.value/e:0;return _jsx(ProgressBar,{progress:a,height:8,tone:toneAt(t),label:_jsx(FigureText,{text:r.label,variant:"bodySmall"}),valueLabel:`${writeValue(r.value,s)} (${formatPercent(a,{maximumFractionDigits:0})})`},t)})})}return _jsxs(View,{style:{gap:r.space.xs},children:[n?_jsx(Text,{variant:"caption",color:"secondary",children:toFigureText(l.name)}):null,g]},i)})]})}
@@ -1 +1 @@
1
- "use strict";import{toFigureRuns}from"@webority/chat-core";import{Text,useTheme}from"@webority/mobile-ui";import{Fragment,useMemo}from"react";import{Text as RNText,View}from"react-native";import{jsx as _jsx}from"react/jsx-runtime";const sizeStepOf=t=>"caption"===t?"xs":"bodySmall"===t||"label"===t?"sm":"title"===t?"lg":"base",inkFor=(t,e)=>"secondary"===e?t.colors["text-muted"]:"tertiary"===e?t.colors["text-subtle"]:"success"===e||"warning"===e||"danger"===e||"info"===e?t.colors[`${e}-text`]:t.colors["text-body"];export function runsToText(t){return t.map(t=>t.text).join("")}const withOffsets=t=>t.reduce((t,e)=>{const r=t[t.length-1],n=r?r.offset+r.run.text.length:0;return t.push({offset:n,run:e}),t},[]);function runNode(t,e,r){if("text"===t.kind)return t.text;const n="sub"===t.kind?Math.round(.4*e):-Math.round(.45*e),o=Math.round(.75*e);return _jsx(View,{style:{transform:[{translateY:n}]},children:_jsx(RNText,{style:{fontSize:o,lineHeight:o,includeFontPadding:!1,color:r},children:t.text})})}export function FigureRuns({runs:t,variant:e="bodySmall",color:r,strong:n=!1,numberOfLines:o,accessibilityLabel:s,testID:i}){const u=useTheme(),a=u.text[sizeStepOf(e)].size,c=inkFor(u,r);return _jsx(Text,{variant:e,color:r,weight:n?"semibold":void 0,numberOfLines:o,testID:i,accessibilityLabel:s??runsToText(t),children:withOffsets(t).map(({offset:t,run:e})=>_jsx(Fragment,{children:runNode(e,a,c)},t))})}export function FigureText({text:t,variant:e="bodySmall",...r}){const n=useMemo(()=>toFigureRuns(t),[t]);return _jsx(FigureRuns,{runs:n,variant:e,...r})}
1
+ "use strict";import{toFigureRuns}from"@webority/chat-core";import{Text,useTheme}from"@webority/mobile-ui";import{Fragment,useMemo}from"react";import{Text as RNText,View}from"react-native";import{jsx as _jsx}from"react/jsx-runtime";const sizeStepOf=e=>"caption"===e?"xs":"bodySmall"===e||"label"===e?"sm":"title"===e?"lg":"base",inkFor=(e,t)=>"secondary"===t?e.colors["text-muted"]:"tertiary"===t?e.colors["text-subtle"]:"success"===t||"warning"===t||"danger"===t||"info"===t?e.colors[`${t}-text`]:e.colors["text-body"];export function runsToText(e){return e.map(e=>e.text).join("")}const withOffsets=e=>e.reduce((e,t)=>{const r=e[e.length-1],n=r?r.offset+r.run.text.length:0;return e.push({offset:n,run:t}),e},[]);function runNode(e,t,r){if("text"===e.kind)return e.text;const n="sub"===e.kind?Math.round(.4*t):-Math.round(.45*t),o=Math.round(.75*t);return _jsx(View,{style:{transform:[{translateY:n}]},children:_jsx(RNText,{style:{fontSize:o,lineHeight:o,includeFontPadding:!1,color:r},children:e.text})})}export function FigureRuns({runs:e,variant:t="bodySmall",color:r,strong:n=!1,numberOfLines:o,accessibilityLabel:s,testID:i,heading:u}){const a=useTheme(),c=a.text[sizeStepOf(t)].size,l=inkFor(a,r);return _jsx(Text,{variant:t,color:r,weight:n?"semibold":void 0,numberOfLines:o,testID:i,accessibilityRole:u?"header":void 0,accessibilityLabel:s??runsToText(e),children:withOffsets(e).map(({offset:e,run:t})=>_jsx(Fragment,{children:runNode(t,c,l)},e))})}export function FigureText({text:e,variant:t="bodySmall",enabled:r=!0,...n}){const o=useMemo(()=>r?toFigureRuns(e):[{kind:"text",text:e}],[e,r]);return _jsx(FigureRuns,{runs:o,variant:t,...n})}
@@ -1 +1 @@
1
- "use strict";import{formatFigure,toFigureText}from"@webority/chat-core";import{formatNumber}from"@webority/mobile-core";import{StatTile,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{FigureRuns,runsToText}from"./FigureText.js";import{jsx as _jsx}from"react/jsx-runtime";const TONE={Neutral:"neutral",Positive:"success",Caution:"warning",Negative:"danger"},withPositions=e=>e.reduce((e,t)=>(e.push({key:e.length,item:t}),e),[]),valueRunsOf=e=>{const t=0!==e.value&&Math.abs(e.value)<.001?formatFigure(e.value):[{kind:"text",text:formatNumber(e.value,{maximumFractionDigits:2})}];return e.unit?[...t,{kind:"text",text:` ${e.unit}`}]:t};export function FiguresPart({part:e,turn:t}){const i=useTheme();return 0===e.figures.length?null:_jsx(View,{accessibilityRole:"list",accessibilityLabel:t.labels.figures,style:{flexDirection:"row",flexWrap:"wrap",gap:i.space.sm},children:withPositions(e.figures).map(({key:e,item:i})=>{const r=valueRunsOf(i),s=t.labels.figureStatus(i.status),a=toFigureText(i.label);return _jsx(View,{style:{flexBasis:"48%",flexGrow:1,minWidth:140},children:_jsx(StatTile,{label:a,value:_jsx(FigureRuns,{runs:r,variant:"title",color:"primary",strong:!0}),tone:TONE[i.status],caption:s||void 0,accessibilityLabel:`${a}: ${runsToText(r)}${s?`, ${s}`:""}`})},e)})})}
1
+ "use strict";import{formatFigure,toFigureRuns,toFigureText}from"@webority/chat-core";import{formatNumber}from"@webority/mobile-core";import{StatTile,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{FigureRuns,runsToText}from"./FigureText.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const TONE={Neutral:"neutral",Positive:"success",Caution:"warning",Negative:"danger"},withPositions=e=>e.reduce((e,t)=>(e.push({key:e.length,item:t}),e),[]),valueRunsOf=e=>{if(0!==e.value&&Math.abs(e.value)<.001)return formatFigure(e.value);const t=formatNumber(e.value,{maximumFractionDigits:2});return[{kind:"text",text:e.value<0?t.replace("-","−"):t}]};export function FiguresPart({part:e,turn:t}){const i=useTheme();return 0===e.figures.length?null:_jsx(View,{accessibilityRole:"summary",accessibilityLabel:t.labels.figures,style:{flexDirection:"row",flexWrap:"wrap",gap:i.space.sm},children:withPositions(e.figures).map(({key:e,item:i})=>{const r=valueRunsOf(i),s=t.labels.figureStatus(i.status),u=toFigureText(i.label);return _jsx(View,{style:{flexGrow:1,minWidth:110},children:_jsx(StatTile,{label:u,value:_jsxs(View,{style:{flexDirection:"row",alignItems:"flex-end",flexWrap:"wrap"},children:[_jsx(FigureRuns,{runs:r,variant:"title",color:"primary",strong:!0}),i.unit?_jsx(FigureRuns,{runs:[{kind:"text",text:" "},...toFigureRuns(i.unit)],variant:"bodySmall",color:"secondary"}):null]}),tone:TONE[i.status],caption:s||void 0,accessibilityLabel:`${u}: ${runsToText(r)}${i.unit?` ${i.unit}`:""}${s?`, ${s}`:""}`})},e)})})}
@@ -1 +1 @@
1
- "use strict";import{formatFileSize}from"@webority/chat-core";import{Chip}from"@webority/mobile-ui";import{NoticePart}from"./NoticePart.js";import{jsx as _jsx}from"react/jsx-runtime";export function FilePart(e){const{part:t,message:i,turn:r}=e;if("File"!==t.kind){const e={kind:"Notice",code:"NeedsNewerApp",text:r.labels.needsNewerApp};return _jsx(NoticePart,{part:e,message:i,turn:r})}const{openAttachment:o}=r;return _jsx(Chip,{label:`${t.fileName} (${formatFileSize(t.length)})`,leftIcon:"paperclip",variant:"soft",size:"sm",accessibilityLabel:r.labels.fileOpen(t.fileName),onPress:o?()=>o(t):void 0})}
1
+ "use strict";import{formatFileSize}from"@webority/chat-core";import{Chip}from"@webority/mobile-ui";import{NoticePart}from"./NoticePart.js";import{jsx as _jsx}from"react/jsx-runtime";export function FilePart(e){const{part:t,message:i,turn:r}=e;if("File"!==t.kind){const e={kind:"Notice",code:"NeedsNewerApp",text:r.labels.needsNewerApp};return _jsx(NoticePart,{part:e,message:i,turn:r})}const{openAttachment:o}=r;return _jsx(Chip,{label:`${t.fileName} (${formatFileSize(t.length)})`,leftIcon:"document-text",variant:"soft",size:"sm",accessibilityLabel:r.labels.fileOpen(t.fileName),onPress:o?()=>o(t):void 0})}
@@ -1 +1 @@
1
- "use strict";import{Avatar,Card,Spinner,Text,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export function HandoffPart({part:e,turn:a}){const i=useTheme(),{labels:s}=a,t=!a.isLast&&("Requested"===e.state||"Waiting"===e.state),n=e.agent?.displayName||s.agent,r=e.agent?.avatarUrl;let o;switch(e.state){case"Requested":o=_jsxs(View,{style:{flexDirection:"row",alignItems:"center",gap:i.space.sm},children:[_jsx(Spinner,{size:"sm"}),_jsx(Text,{variant:"bodySmall",children:s.handoffRequested})]});break;case"Waiting":o=_jsxs(View,{style:{gap:i.space.xs},children:[_jsxs(View,{style:{flexDirection:"row",alignItems:"center",gap:i.space.sm},children:[_jsx(Spinner,{size:"sm"}),_jsx(Text,{variant:"label",children:s.handoffWaiting})]}),"number"==typeof e.queuePosition?_jsx(Text,{variant:"caption",color:"secondary",children:s.handoffQueued(e.queuePosition)}):null,_jsx(Text,{variant:"caption",color:"secondary",children:s.handoffQueuedText})]});break;case"Joined":o=_jsxs(View,{style:{flexDirection:"row",alignItems:"center",gap:i.space.sm},children:[_jsx(Avatar,{size:"sm",name:n,source:r?{uri:r}:void 0}),_jsx(Text,{variant:"label",children:s.handoffJoined(n)})]});break;case"Left":o=_jsx(Text,{variant:"bodySmall",children:s.handoffLeft(n)});break;case"Ended":o=_jsx(Text,{variant:"bodySmall",children:s.handoffEnded})}return _jsx(Card,{variant:"outline",padding:"sm",accessibilityLiveRegion:t?void 0:"polite",children:o})}
1
+ "use strict";import{Avatar,Card,Spinner,Text,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export function HandoffPart({part:e,turn:t}){const s=useTheme(),{labels:i}=t;if(!0===t.handoffSettled&&("Requested"===e.state||"Waiting"===e.state))return null;const a=t.isLast&&("Requested"===e.state||"Waiting"===e.state||"Joined"===e.state),n=e.agent?.displayName||i.handoffAgentFallback,r=e.agent?.avatarUrl;let o;switch(e.state){case"Requested":o=_jsxs(View,{style:{flexDirection:"row",alignItems:"center",gap:s.space.sm},children:[_jsx(Spinner,{size:"sm"}),_jsx(Text,{variant:"bodySmall",children:i.handoffRequested})]});break;case"Waiting":o=_jsxs(View,{style:{gap:s.space.xs},children:[_jsxs(View,{style:{flexDirection:"row",alignItems:"center",gap:s.space.sm},children:[_jsx(Spinner,{size:"sm"}),"number"==typeof e.queuePosition?null:_jsx(Text,{variant:"label",children:i.handoffWaiting})]}),"number"==typeof e.queuePosition?_jsx(Text,{variant:"caption",color:"secondary",children:i.handoffQueued(e.queuePosition)}):null,_jsx(Text,{variant:"caption",color:"secondary",children:i.handoffQueuedText})]});break;case"Joined":o=_jsxs(View,{style:{gap:s.space.xs},children:[_jsxs(View,{style:{flexDirection:"row",alignItems:"center",gap:s.space.sm},children:[_jsxs(View,{style:{position:"relative"},children:[_jsx(Avatar,{size:"sm",name:n,source:r?{uri:r}:void 0}),_jsx(View,{accessibilityElementsHidden:!0,importantForAccessibility:"no-hide-descendants",style:{position:"absolute",right:0,bottom:0,width:8,height:8,borderRadius:s.radius.pill,backgroundColor:s.colors["success-text"]}})]}),_jsx(Text,{variant:"label",children:i.handoffJoined(n)})]}),_jsx(Text,{variant:"caption",color:"secondary",children:i.handoffJoinedText(n)})]});break;case"Left":o=_jsxs(View,{style:{gap:s.space.xs},children:[_jsx(Text,{variant:"bodySmall",children:i.handoffLeft(n)}),_jsx(Text,{variant:"caption",color:"secondary",children:i.handoffLeftText})]});break;case"Ended":o=_jsxs(View,{style:{gap:s.space.xs},children:[_jsx(Text,{variant:"bodySmall",children:i.handoffEnded}),_jsx(Text,{variant:"caption",color:"secondary",children:i.handoffEndedText})]})}return void 0===o?null:_jsx(Card,{variant:"outline",padding:"sm",accessibilityLiveRegion:a?"polite":void 0,children:o})}
@@ -1 +1 @@
1
- "use strict";import{AuthedImage,Button,Modal,Text,useTheme,ZoomableImage}from"@webority/mobile-ui";import{useState}from"react";import{Pressable,View}from"react-native";import{useSafeAreaInsets}from"react-native-safe-area-context";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const DEFAULT_RATIO=4/3;export function ImagePart({part:e,turn:t}){const a=useTheme(),s=useSafeAreaInsets(),[i,l]=useState(!1),r=t.attachmentUrl?t.attachmentUrl(e.attachmentId):void 0;if(void 0===r)return _jsx(Text,{variant:"bodySmall",color:"secondary",children:e.alt});const o=null!==e.width&&null!==e.height&&e.width>0&&e.height>0?e.width/e.height:DEFAULT_RATIO,n=_jsx(Text,{variant:"bodySmall",color:"secondary",children:e.alt});return _jsxs(_Fragment,{children:[_jsx(Pressable,{accessibilityRole:"imagebutton",accessibilityLabel:t.labels.imageOpen(e.alt),onPress:()=>l(!0),children:_jsx(AuthedImage,{uri:r,contentFit:"cover",accessible:!0,accessibilityLabel:e.alt,style:{width:"100%",aspectRatio:o,maxHeight:320,borderRadius:a.radius.md},fallback:n})}),_jsx(Modal,{open:i,onClose:()=>l(!1),backdropPressClose:!1,presentation:"fullScreen",accessibilityLabel:e.alt,children:_jsxs(View,{style:{flex:1,backgroundColor:a.colors.bg},children:[_jsx(ZoomableImage,{style:{flex:1},accessibilityLabel:e.alt,children:_jsx(AuthedImage,{uri:r,contentFit:"contain",style:{flex:1},accessibilityLabel:e.alt})}),_jsx(View,{style:{position:"absolute",top:s.top+a.space.sm,right:a.space.sm},children:_jsx(Button,{variant:"soft",size:"sm",label:t.labels.close,onPress:()=>l(!1)})})]})})]})}
1
+ "use strict";import{AuthedImage,Button,Modal,Text,useTheme,ZoomableImage}from"@webority/mobile-ui";import{useCallback,useEffect,useRef,useState}from"react";import{Pressable,View}from"react-native";import{useSafeAreaInsets}from"react-native-safe-area-context";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";export function ImagePart({part:e,turn:t}){const a=useTheme(),s=useSafeAreaInsets(),[l,r]=useState(!1),[i,n]=useState(null),[o,c]=useState(!1),u=useRef(t.loadAttachmentUrl);u.current=t.loadAttachmentUrl;const m=useRef(0),d=useCallback(e=>{const t=++m.current;n(null),c(!1),u.current(e).then(e=>{m.current===t&&n(e)},()=>{m.current===t&&c(!0)})},[]);if(useEffect(()=>(d(e.attachmentId),()=>{m.current++}),[e.attachmentId,d]),o)return _jsxs(View,{style:{gap:a.space.xs},children:[_jsx(Text,{variant:"bodySmall",color:"secondary",children:e.alt}),_jsx(Button,{variant:"soft",size:"sm",label:t.labels.retry,onPress:()=>d(e.attachmentId),testID:`image-retry-${e.attachmentId}`})]});if(null===i)return _jsx(Text,{variant:"bodySmall",color:"secondary",children:e.alt});const b=null!==e.width&&null!==e.height&&e.width>0&&e.height>0?e.width/e.height:null,h=_jsx(Text,{variant:"bodySmall",color:"secondary",children:e.alt});return _jsxs(_Fragment,{children:[_jsx(Pressable,{accessibilityRole:"imagebutton",accessibilityLabel:t.labels.imageOpen(e.alt),onPress:()=>r(!0),children:_jsx(AuthedImage,{uri:i,contentFit:"contain",accessible:!0,accessibilityLabel:e.alt,labels:{loading:t.labels.imageLoading},style:{width:"100%",...null===b?{minHeight:160}:{aspectRatio:b},maxHeight:320,borderRadius:a.radius.md},fallback:h})}),_jsx(Modal,{open:l,onClose:()=>r(!1),backdropPressClose:!1,presentation:"fullScreen",accessibilityLabel:e.alt,children:_jsxs(View,{style:{flex:1,backgroundColor:a.colors.bg},children:[_jsx(ZoomableImage,{style:{flex:1},accessibilityLabel:e.alt,children:_jsx(AuthedImage,{uri:i,contentFit:"contain",style:{flex:1},accessibilityLabel:e.alt})}),_jsx(View,{style:{position:"absolute",top:s.top+a.space.sm,right:a.space.sm},children:_jsx(Button,{variant:"soft",size:"sm",label:t.labels.close,onPress:()=>r(!1)})})]})})]})}
@@ -1 +1 @@
1
- "use strict";import{Button,Card,Checkbox,Chip,ChoiceGroup,Input,ProgressBar,Text,useTheme}from"@webority/mobile-ui";import{useState}from"react";import{View}from"react-native";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,t)=>!FIELD_TYPES.has(e.type)||"File"===e.type&&!t,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})`;function OpenRequest({part:e,turn:t,pickAttachments:i}){const a=useTheme(),{labels:s,features:l}=t,[r,n]=useState({}),[o,c]=useState({}),[p,d]=useState(""),[u,y]=useState(!1),[m,x]=useState({}),setValue=(e,t)=>n(i=>({...i,[e]:t})),patchUpload=(e,t)=>x(i=>{const a=i[e];return a?{...i,[e]:{...a,...t}}:i}),h=Object.values(m).some(e=>"Ready"!==e.status),leave=async e=>{y(!0),d("");try{await e()}catch{d(s.errorGeneric),y(!1)}},b=l.LeadShortcuts,f=b&&1===e.fields.length&&!e.fields[0].required,g=b&&e.cancellable;return _jsx(Card,{variant:"outline",padding:"sm",children:_jsxs(View,{style:{gap:a.space.sm},children:[e.title?_jsx(Text,{variant:"label",children:e.title}):null,b&&e.allowTyped?_jsx(Text,{variant:"caption",color:"secondary",children:s.typeAnswer}):null,e.fields.map(e=>{const l=r[e.key]??"",n=o[e.key];if("File"===e.type){const l=m[e.key];return _jsxs(View,{style:{gap:a.space.xs},children:[_jsx(Text,{variant:"label",children:`${e.label}${optionalSuffix(e,s)}`}),l?_jsxs(View,{style:{gap:a.space.xxs},children:[_jsx(Chip,{label:l.fileName,variant:"soft",onRemove:"Uploading"===l.status?void 0:()=>{return t=e.key,x(e=>Object.fromEntries(Object.entries(e).filter(([e])=>e!==t))),void setValue(t,"");var t},labels:{remove:s.inputRemoveFile}}),"Uploading"===l.status?_jsx(ProgressBar,{progress:l.progress??void 0,label:s.attachmentUploading,height:4}):null,"Failed"===l.status?_jsx(Text,{variant:"caption",color:"danger",accessibilityLiveRegion:"polite",children:s.attachmentFailed}):null]}):_jsx(View,{style:{flexDirection:"row"},children:_jsx(Button,{label:s.inputChooseFile,variant:"soft",size:"sm",leftIcon:"paperclip",disabled:u,onPress:()=>{(async e=>{if(!i)return;let a;try{a=await i()}catch{return void d(s.errorGeneric)}const l=a[0];if(l){x(t=>({...t,[e.key]:{fileName:fileNameOf(l,e.label),status:"Uploading",progress:null}}));try{const i=await t.uploadInputFile(l,t=>patchUpload(e.key,{progress:t}));setValue(e.key,i),patchUpload(e.key,{status:"Ready",progress:null})}catch{setValue(e.key,""),patchUpload(e.key,{status:"Failed",progress:null})}}})(e)}})}),n?_jsx(Text,{variant:"caption",color:"danger",accessibilityLiveRegion:"polite",children:n}):null]},e.key)}if("MultiChoice"===e.type){const t=(e.options??[]).map(e=>({label:e.label,value:e.id}));return _jsxs(View,{style:{gap:a.space.xs},children:[_jsx(Text,{variant:"label",children:`${e.label}${optionalSuffix(e,s)}`}),_jsx(ChoiceGroup,{selectionMode:"multiple",options:t,value:selectedIds(l),onChange:i=>setValue(e.key,JSON.stringify(t.filter(e=>i.includes(e.value)).map(e=>e.value))),accessibilityLabel:e.label,error:n,disabled:u})]},e.key)}if("Choice"===e.type||"TimeSlot"===e.type){const t="TimeSlot"===e.type?(e.slots??[]).map(e=>({label:slotFormat.format(new Date(e.startDateTimeUtc)),value:e.id})):(e.options??[]).map(e=>({label:e.label,value:e.id}));return _jsxs(View,{style:{gap:a.space.xs},children:[_jsx(Text,{variant:"label",children:`${e.label}${optionalSuffix(e,s)}`}),_jsx(ChoiceGroup,{options:t,value:""===l?void 0:l,onChange:t=>setValue(e.key,String(t)),accessibilityLabel:e.label,error:n,disabled:u})]},e.key)}return"Consent"===e.type?_jsx(Checkbox,{checked:"true"===l,onChange:t=>setValue(e.key,t?"true":"false"),label:`${e.consentText??e.label}${optionalSuffix(e,s)}`,error:n,disabled:u},e.key):_jsx(Input,{label:e.label,placeholder:e.placeholder??void 0,value:l,onChangeText:t=>setValue(e.key,t),maxLength:e.maxLength??void 0,required:e.required,error:n,help:e.required?void 0:s.inputOptional,labelMode:"top",disabled:u,type:"LongText"===e.type?"textarea":e.secret?"password":"input",keyboardType:KEYBOARD_TYPES[e.type]??"default",autoCapitalize:"Email"===e.type?"none":void 0,autoComplete:AUTO_COMPLETE[e.type]},e.key)}),""!==p?_jsx(Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:p}):null,_jsxs(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:a.space.sm},children:[_jsx(Button,{label:u?s.inputSubmitting:e.submitLabel,loading:u,disabled:u||h,onPress:()=>{(async()=>{if(h)return;const i={},a={};for(const t of e.fields){const e=r[t.key]??"";if("Consent"===t.type){const l="true"===e;t.required&&!l&&(i[t.key]=s.inputConsentRequired),a[t.key]=l?"true":"false"}else if("Choice"===t.type||"TimeSlot"===t.type)t.required&&""===e&&(i[t.key]=s.inputRequired),a[t.key]=e;else if("MultiChoice"===t.type){const l=selectedIds(e);t.required&&0===l.length&&(i[t.key]=s.inputRequired),a[t.key]=JSON.stringify(l)}else if("File"===t.type)t.required&&""===e&&(i[t.key]=s.inputRequired),a[t.key]=e;else{const l=e.trim();t.required&&""===l&&(i[t.key]=s.inputRequired),a[t.key]=l}}if(c(i),!(Object.keys(i).length>0)){y(!0),d("");try{const i=await t.answerInput(e.requestId,a);if(i.ok)return;c(i.errors),d(i.message??"")}catch{d(s.errorGeneric)}y(!1)}})()}}),f?_jsx(Button,{label:s.skip,variant:"ghost",disabled:u,onPress:()=>{leave(()=>t.skipInput(e.requestId))}}):null,g?_jsx(Button,{label:s.cancel,variant:"ghost",disabled:u,onPress:()=>{leave(()=>t.cancelLead())}}):null]})]})})}export function InputRequestPart(e){const{part:t,message:i,turn:a,pickAttachments:s}=e,l=void 0!==s;if("InputRequest"!==t.kind||t.fields.some(e=>isUndrawnField(e,l))){const e={kind:"Notice",code:"NeedsNewerApp",text:a.labels.needsNewerApp};return _jsx(NoticePart,{part:e,message:i,turn:a})}return"Answered"===t.state?_jsx(Text,{variant:"bodySmall",color:"secondary",children:t.answeredSummary??a.labels.inputAnswered}):"Skipped"===t.state?_jsx(Text,{variant:"bodySmall",color:"secondary",children:a.labels.inputSkipped}):"Expired"===t.state?_jsx(Text,{variant:"bodySmall",color:"secondary",children:a.labels.inputExpired}):_jsx(OpenRequest,{part:t,turn:a,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{AccessibilityInfo,findNodeHandle,View}from"react-native";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:n}=t,[a,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];if(!i)return;const r=findNodeHandle(i);null!==r&&AccessibilityInfo.setAccessibilityFocus(r)},[]);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,w=Object.values(f).some(e=>"Ready"!==e.status),leave=async e=>{y(!0),d("");try{await e()}catch{d(s.errorGeneric),y(!1)}},S=n.LeadShortcuts,R=S&&1===e.fields.length&&!e.fields[0].required,E=S&&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(n=>{const l=a[n.key]??"",c=o[n.key];if("File"===n.type){const e=f[n.key];return _jsxs(View,{style:{gap:r.space.xs},children:[_jsx(Text,{variant:"label",children:`${n.label}${optionalSuffix(n,s)}`}),e?_jsxs(View,{style:{gap:r.space.xxs},children:[_jsx(Chip,{label:e.fileName,variant:"soft",onRemove:()=>{return e=n.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 n=r[0];if(!n)return;_.current+=1;const a=_.current;commitUploads({...j.current,[e.key]:{fileName:fileNameOf(n,e.label),status:"Uploading",progress:null,token:a}});try{const i=await t.uploadInputFile(n,t=>{isLiveUpload(e.key,a)&&patchUpload(e.key,{progress:t})});isLiveUpload(e.key,a)&&(setValue(e.key,i),patchUpload(e.key,{status:"Ready",progress:null}))}catch{isLiveUpload(e.key,a)&&(setValue(e.key,""),patchUpload(e.key,{status:"Failed",progress:null}))}})(n)}})}),c?_jsx(Text,{variant:"caption",color:"danger",accessibilityLiveRegion:"assertive",children:c}):null]},n.key)}if("MultiChoice"===n.type){const e=(n.options??[]).map(e=>({label:e.label,value:e.id}));return _jsxs(View,{style:{gap:r.space.xs},children:[_jsx(Text,{variant:"label",children:`${n.label}${optionalSuffix(n,s)}`}),_jsx(View,{ref:e=>{g.current[n.key]=e},children:_jsx(ChoiceGroup,{selectionMode:"multiple",options:e,value:selectedIds(l),onChange:t=>setValue(n.key,JSON.stringify(e.filter(e=>t.includes(e.value)).map(e=>e.value))),accessibilityLabel:n.label,error:c,disabled:p})})]},n.key)}if("Choice"===n.type||"TimeSlot"===n.type){const e="TimeSlot"===n.type?(n.slots??[]).map(e=>({label:slotFormat.format(new Date(e.startDateTimeUtc)),value:e.id})):(n.options??[]).map(e=>({label:e.label,value:e.id}));return _jsxs(View,{style:{gap:r.space.xs},children:[_jsx(Text,{variant:"label",children:`${n.label}${optionalSuffix(n,s)}`}),_jsx(View,{ref:e=>{g.current[n.key]=e},children:_jsx(ChoiceGroup,{options:e,value:""===l?void 0:l,onChange:e=>setValue(n.key,String(e)),accessibilityLabel:n.label,error:c,disabled:p})})]},n.key)}if("Consent"===n.type)return _jsx(Checkbox,{checked:"true"===l,onChange:e=>setValue(n.key,e?"true":"false"),label:n.consentText??n.label,error:c,disabled:p},n.key);const u=_jsx(Input,{ref:e=>{v.current[n.key]=e},label:n.label,placeholder:n.placeholder??void 0,value:l,onChangeText:e=>setValue(n.key,e),maxLength:n.maxLength??void 0,required:n.required,error:c,help:n.required?void 0:s.inputOptional,labelMode:"top",disabled:p,type:n.secret?"password":"LongText"===n.type?"textarea":"input",keyboardType:KEYBOARD_TYPES[n.type]??"default",autoCapitalize:"Email"===n.type?"none":void 0,autoComplete:AUTO_COMPLETE[n.type]},n.key);if(!("Otp"===n.verify&&("Email"===n.type||"Phone"===n.type)))return u;const y=b[n.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:(a[i.key]??"").trim()}),k(e=>({...e,[i.key]:"sent"}))}catch{k(e=>({...e,[i.key]:"failed"}))}})(n)},testID:`otp-send-${n.key}`}),_jsx(Input,{label:s.inputEnterCode,value:x[n.key]??"",onChangeText:e=>h(t=>({...t,[n.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]})]},n.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||w,onPress:()=>{(async()=>{if(w)return;const i={},r={};for(const t of e.fields){const e=a[t.key]??"";if("Consent"===t.type){const n="true"===e;t.required&&!n&&(i[t.key]=s.inputConsentRequired),r[t.key]=n?"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 n=selectedIds(e);t.required&&0===n.length&&(i[t.key]=s.inputRequired),r[t.key]=JSON.stringify(n)}else if("File"===t.type)t.required&&""===e&&(i[t.key]=s.inputRequired),r[t.key]=e;else{const n=t.secret?e:e.trim();t.required&&""===n&&(i[t.key]=s.inputRequired),r[t.key]=n}}const n={};for(const t of e.fields){if("Otp"!==t.verify)continue;const e=(x[t.key]??"").trim();""===e&&(i[t.key]=s.inputRequired),n[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(n).length>0?n:null);if(i.ok)return;c(i.errors),T.current=!0,d(i.message??"")}catch{d(s.errorGeneric)}y(!1)})()}}),w?_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{Banner}from"@webority/mobile-ui";import{jsx as _jsx}from"react/jsx-runtime";export function NoticePart({part:t}){const e="ActionLimitReached"===t.code||"AssistantUnavailable"===t.code?"warning":"info";return _jsx(Banner,{message:t.text,tone:e,accessibilityRole:"summary"})}
1
+ "use strict";import{Banner}from"@webority/mobile-ui";import{jsx as _jsx}from"react/jsx-runtime";export function NoticePart({part:e}){const t="AssistantUnavailable"===e.code?"danger":"ActionLimitReached"===e.code||"ConversationTooLong"===e.code?"warning":"info";return _jsx(Banner,{message:e.text,tone:t,accessibilityRole:"alert"})}
@@ -1 +1 @@
1
- "use strict";import{isHandoffTarget}from"@webority/chat-core";import{Chip,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{ChatEntrance}from"../ChatEntrance.js";import{defaultOpenTarget}from"../chatShared.js";import{jsx as _jsx}from"react/jsx-runtime";function lookOf(e){switch(e){case"Primary":return{variant:"soft",tone:"primary"};case"Cta":return{variant:"solid",tone:"primary"};default:return{variant:"outline"}}}export function QuickRepliesPart({part:e,turn:t}){const a=useTheme();if(!t.features.SuggestedReplies||!t.isLast||t.busy||t.handoffPause||0===e.replies.length)return null;const n=t.openTarget,r=void 0!==n&&n!==defaultOpenTarget;return _jsx(View,{accessibilityRole:"list",accessibilityLabel:t.labels.quickReplies,style:{flexDirection:"row",flexWrap:"wrap",gap:a.space.xs},children:e.replies.map((e,a)=>{const i=lookOf(e.variant),o=e.icon?e.icon:void 0;if("Send"===e.action)return _jsx(ChatEntrance,{index:a,children:_jsx(Chip,{label:e.label,variant:i.variant,tone:i.tone,leftIcon:o,onPress:()=>t.chooseQuickReply(e)})},e.id);const s=e.target;if("Open"===e.action&&s&&n)return _jsx(ChatEntrance,{index:a,children:_jsx(Chip,{label:e.label,variant:i.variant,tone:i.tone,leftIcon:o,onPress:()=>n(s)})},e.id);if("Navigate"===e.action&&t.features.LinkHandoff&&s&&n){const l=isHandoffTarget(s,t.handoffHosts)&&(!s.startsWith("/")||r);return _jsx(ChatEntrance,{index:a,children:_jsx(Chip,{label:e.label,variant:i.variant,tone:i.tone,leftIcon:o,onPress:l?()=>t.beginHandoff(e,()=>n(s)):void 0})},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{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 +1 @@
1
- "use strict";import{formatChatValue}from"@webority/chat-core";import{Card,useTheme}from"@webority/mobile-ui";import{StyleSheet,View}from"react-native";import{FigureText}from"./FigureText.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const withPositions=e=>e.reduce((e,t)=>(e.push({key:e.length,item:t}),e),[]);export function RecordCardPart({part:e,turn:t}){const r=useTheme(),i=void 0!==t.openRecord&&null!==e.target;return _jsx(Card,{variant:"outline",padding:"sm",accessibilityRole:i?"button":"summary",accessibilityLabel:i?t.labels.recordOpenFor(e.title):void 0,onPress:i?()=>t.openRecord?.(e):void 0,children:_jsxs(View,{style:{gap:r.space.xs},children:[_jsx(FigureText,{text:e.title,variant:"label",color:"primary",strong:!0,numberOfLines:2}),e.subtitle?_jsx(FigureText,{text:e.subtitle,variant:"bodySmall",color:"secondary"}):null,withPositions(e.fields).map(({key:e,item:t})=>_jsxs(View,{style:{gap:r.space.xs},children:[e>0?_jsx(View,{style:{height:StyleSheet.hairlineWidth,backgroundColor:r.colors["border-subtle"]}}):null,_jsxs(View,{style:{flexDirection:"row",justifyContent:"space-between",gap:r.space.sm},children:[_jsx(View,{style:{flexShrink:1},children:_jsx(FigureText,{text:t.label,variant:"caption",color:"secondary"})}),_jsx(View,{style:{flex:1,alignItems:"flex-end"},children:_jsx(FigureText,{text:formatChatValue(t.value,t.type,null),variant:"bodySmall",color:"primary"})})]})]},e))]})})}
1
+ "use strict";import{formatChatValue,toFigureText}from"@webority/chat-core";import{Button,Card,useTheme}from"@webority/mobile-ui";import{StyleSheet,View}from"react-native";import{FigureText}from"./FigureText.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const withPositions=e=>e.reduce((e,t)=>(e.push({key:e.length,item:t}),e),[]),NUMERIC=new Set(["Integer","Decimal","MoneyMinor","Percent"]);export function RecordCardPart({part:e,turn:t}){const r=useTheme(),i=void 0!==t.openRecord&&null!==e.target;return _jsx(Card,{variant:"outline",padding:"sm",accessibilityRole:"summary",children:_jsxs(View,{style:{gap:r.space.xs},children:[_jsx(FigureText,{text:e.title,variant:"label",color:"primary",strong:!0,numberOfLines:2,enabled:t.features.FigureText,heading:!0}),e.subtitle?_jsx(FigureText,{text:e.subtitle,variant:"bodySmall",color:"secondary",enabled:t.features.FigureText}):null,withPositions(e.fields).map(({key:e,item:i})=>_jsxs(View,{style:{gap:r.space.xs},children:[e>0?_jsx(View,{style:{height:StyleSheet.hairlineWidth,backgroundColor:r.colors["border-subtle"]}}):null,_jsxs(View,{style:{flexDirection:"row",justifyContent:"space-between",gap:r.space.sm},children:[_jsx(View,{style:{flexShrink:1},children:_jsx(FigureText,{text:i.label,variant:"caption",color:"secondary",enabled:t.features.FigureText})}),_jsx(View,{style:{flex:1,alignItems:NUMERIC.has(i.type)?"flex-end":"flex-start"},children:_jsx(FigureText,{text:formatChatValue(i.value,i.type,null),variant:"bodySmall",color:"primary",enabled:t.features.FigureText})})]})]},e)),i?_jsx(Button,{label:t.labels.recordOpen,variant:"link",size:"sm",accessibilityLabel:t.labels.recordOpenFor(toFigureText(e.title)),onPress:()=>t.openRecord?.(e),testID:`record-open-${e.recordId}`}):null]})})}
@@ -1 +1 @@
1
- "use strict";import{Chip,Text,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{ChatEntrance}from"../ChatEntrance.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const HTTP_LINK=/^https?:\/\//i;export function SourcesPart({part:e,turn:s}){const r=useTheme();if(!s.features.Sources||0===e.sources.length)return null;const t=s.openTarget;return _jsxs(View,{accessibilityRole:"list",accessibilityLabel:s.labels.sources,style:{gap:r.space.xs},children:[_jsx(Text,{variant:"caption",color:"secondary",children:s.labels.sources}),_jsx(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:r.space.xs},children:e.sources.map((e,r)=>{const i=e.url;return _jsx(ChatEntrance,{index:r,children:_jsx(Chip,{label:`${e.marker} ${e.title}`,variant:"outline",size:"sm",accessibilityLabel:s.labels.openSource(e.title),onPress:null!==i&&HTTP_LINK.test(i)&&t?()=>t(i):void 0})},e.marker)})})]})}
1
+ "use strict";import{Chip,Text,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{ChatEntrance}from"../ChatEntrance.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const HTTP_LINK=/^https?:\/\//i;export function SourcesPart({part:e,turn:r}){const s=useTheme();if(!r.features.Sources||0===e.sources.length)return null;const t=r.openTarget;return _jsxs(View,{style:{gap:s.space.xs},children:[_jsx(Text,{variant:"caption",color:"secondary",children:r.labels.sources}),_jsx(View,{accessibilityRole:"list",accessibilityLabel:r.labels.sources,style:{flexDirection:"row",flexWrap:"wrap",gap:s.space.xs},children:e.sources.map((e,s)=>{const i=e.url,a=null!==i&&HTTP_LINK.test(i)&&void 0!==t?()=>t(i):void 0;return _jsx(ChatEntrance,{index:s,animate:!1,children:_jsx(View,{ref:s=>r.registerSourceRow?.(String(e.marker),s),children:_jsx(Chip,{label:`${e.marker} ${e.title}`,variant:"outline",size:"sm",accessibilityLabel:a?r.labels.openSource(e.title):void 0,onPress:a})})},e.marker)})})]})}
@@ -1 +1 @@
1
- "use strict";import{formatChatValue,toFigureText}from"@webority/chat-core";import{Button,Card,Text,useTheme}from"@webority/mobile-ui";import{useState}from"react";import{ScrollView,StyleSheet,View}from"react-native";import{FigureText}from"./FigureText.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const PREVIEW_ROWS=10,COLUMN_WIDTH={Text:140,Integer:88,Decimal:96,MoneyMinor:112,Percent:80,Date:112,DateTimeUtc:152},NUMERIC=new Set(["Integer","Decimal","MoneyMinor","Percent"]),withPositions=e=>e.reduce((e,t)=>(e.push({key:e.length,item:t}),e),[]);export function TablePart({part:e,turn:t}){const r=useTheme(),[i,l]=useState(!1);if(0===e.columns.length||0===e.rows.length)return null;const s=i?e.rows:e.rows.slice(0,10),n={height:StyleSheet.hairlineWidth,backgroundColor:r.colors["border-subtle"]},o={paddingVertical:r.space.xs,paddingHorizontal:r.space.sm},cellValue=(t,r,i)=>{const l=t[r];return null==l?null:formatChatValue(l,i.type,e.currency)};return _jsxs(View,{accessibilityLabel:e.title?toFigureText(e.title):t.labels.table,style:{gap:r.space.xs},children:[e.title?_jsx(FigureText,{text:e.title,variant:"label",color:"primary",strong:!0}):null,_jsx(Card,{variant:"outline",padding:"sm",children:_jsx(ScrollView,{horizontal:!0,showsHorizontalScrollIndicator:!0,nestedScrollEnabled:!0,children:_jsxs(View,{children:[_jsx(View,{style:{flexDirection:"row"},children:e.columns.map(e=>_jsx(View,{style:[o,{width:COLUMN_WIDTH[e.type],alignItems:NUMERIC.has(e.type)?"flex-end":"flex-start"}],children:_jsx(FigureText,{text:e.label,variant:"label",color:"secondary",strong:!0,numberOfLines:2})},e.key))}),_jsx(View,{style:n}),withPositions(s).map(({key:t,item:r})=>{const i=e.columns.map((e,t)=>`${toFigureText(e.label)}: ${cellValue(r,t,e)??"-"}`).join(", ");return _jsxs(View,{accessible:!0,accessibilityLabel:i,children:[_jsx(View,{accessibilityElementsHidden:!0,importantForAccessibility:"no-hide-descendants",style:{flexDirection:"row"},children:e.columns.map((e,t)=>{const i=cellValue(r,t,e);return _jsx(View,{style:[o,{width:COLUMN_WIDTH[e.type],alignItems:NUMERIC.has(e.type)?"flex-end":"flex-start"}],children:null===i?_jsx(Text,{variant:"bodySmall",color:"tertiary",children:"-"}):_jsx(FigureText,{text:i,variant:"bodySmall",color:"primary",numberOfLines:3})},e.key)})}),_jsx(View,{style:n})]},t)})]})})}),!i&&e.rows.length>10?_jsx(Button,{variant:"link",size:"sm",label:t.labels.tableShowAll(e.rows.length),onPress:()=>l(!0)}):null]})}
1
+ "use strict";import{formatChatValue,toFigureText}from"@webority/chat-core";import{AppIcon,Button,Card,Text,useTheme}from"@webority/mobile-ui";import{useState}from"react";import{ScrollView,StyleSheet,View}from"react-native";import{FigureText}from"./FigureText.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const PREVIEW_ROWS=25,COLUMN_WIDTH={Text:140,Integer:88,Decimal:96,MoneyMinor:112,Percent:80,Date:112,DateTimeUtc:152},NUMERIC=new Set(["Integer","Decimal","MoneyMinor","Percent"]),withPositions=e=>e.reduce((e,t)=>(e.push({key:e.length,item:t}),e),[]);export function TablePart({part:e,turn:t}){const r=useTheme(),[i,l]=useState(!1),[n,s]=useState(0),[o,a]=useState(0),[c,u]=useState(0);if(0===e.columns.length||0===e.rows.length)return null;const plain=e=>t.features.FigureText?toFigureText(e):e,x=o>c+n+1,m=i?e.rows:e.rows.slice(0,25),h={height:StyleSheet.hairlineWidth,backgroundColor:r.colors["border-subtle"]},d={paddingVertical:r.space.xs,paddingHorizontal:r.space.sm},cellValue=(t,r,i)=>{const l=t[r];return null==l?null:formatChatValue(l,i.type,e.currency)};return _jsxs(View,{accessibilityLabel:e.title?plain(e.title):t.labels.table,style:{gap:r.space.xs},children:[e.title?_jsx(FigureText,{text:e.title,variant:"label",color:"primary",strong:!0,enabled:t.features.FigureText}):null,_jsxs(Card,{variant:"outline",padding:"sm",onLayout:e=>u(e.nativeEvent.layout.width),children:[_jsx(ScrollView,{horizontal:!0,showsHorizontalScrollIndicator:!0,nestedScrollEnabled:!0,onScroll:e=>s(e.nativeEvent.contentOffset.x),onContentSizeChange:e=>a(e),scrollEventThrottle:16,children:_jsxs(View,{children:[_jsx(View,{style:{flexDirection:"row"},children:e.columns.map(e=>_jsx(View,{style:[d,{width:COLUMN_WIDTH[e.type],alignItems:NUMERIC.has(e.type)?"flex-end":"flex-start"}],children:_jsx(FigureText,{text:e.label,variant:"label",color:"secondary",strong:!0,numberOfLines:2,enabled:t.features.FigureText})},e.key))}),_jsx(View,{style:h}),withPositions(m).map(({key:r,item:i})=>{const l=e.columns.map((e,t)=>`${plain(e.label)}: ${cellValue(i,t,e)??"-"}`).join(", ");return _jsxs(View,{accessible:!0,accessibilityLabel:l,children:[_jsx(View,{accessibilityElementsHidden:!0,importantForAccessibility:"no-hide-descendants",style:{flexDirection:"row"},children:e.columns.map((e,r)=>{const l=cellValue(i,r,e);return _jsx(View,{style:[d,{width:COLUMN_WIDTH[e.type],alignItems:NUMERIC.has(e.type)?"flex-end":"flex-start"}],children:null===l?_jsx(Text,{variant:"bodySmall",color:"tertiary",children:"-"}):_jsx(FigureText,{text:l,variant:"bodySmall",color:"primary",numberOfLines:3,enabled:t.features.FigureText})},e.key)})}),_jsx(View,{style:h})]},r)})]})}),x?_jsx(View,{pointerEvents:"none",style:{position:"absolute",right:0,top:0,bottom:0,justifyContent:"center"},children:_jsx(AppIcon,{name:"chevron-right",size:"sm",color:"tertiary"})}):null]}),!i&&e.rows.length>25?_jsx(Button,{variant:"link",size:"sm",label:t.labels.tableShowAll(e.rows.length),onPress:()=>l(!0)}):null]})}
@@ -1 +1 @@
1
- "use strict";import{Card,Chip,Text,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export function TicketPart({part:e,turn:t}){const i=useTheme(),{labels:s,openTicket:r}=t,a=s.ticketAria(e.number),n=r?()=>r({ticketId:e.ticketId,number:e.number}):void 0;return _jsx(Card,{variant:"outline",padding:"sm",interactive:void 0!==n,onPress:n,accessibilityLabel:`${a}, ${e.status}`,children:_jsxs(View,{style:{gap:i.space.xs},children:[_jsxs(View,{style:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:i.space.sm},children:[_jsx(Text,{variant:"label",children:a}),_jsx(Chip,{size:"sm",variant:"soft",label:e.status})]}),_jsx(Text,{variant:"bodySmall",numberOfLines:2,children:e.subject}),n?_jsx(Text,{variant:"caption",color:"secondary",children:s.ticketView}):null]})})}
1
+ "use strict";import{Button,Card,Chip,Text,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export function TicketPart({part:e,turn:t}){const i=useTheme(),{labels:s,openTicket:r}=t,a=s.ticketAria(e.number),n=s.ticketStatus(e.status),l=r?()=>r({ticketId:e.ticketId,number:e.number}):void 0;return _jsx(Card,{variant:"outline",padding:"sm",accessibilityLabel:n?`${a}, ${n}`:a,children:_jsxs(View,{style:{gap:i.space.xs},children:[_jsxs(View,{style:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:i.space.sm},children:[_jsx(Text,{variant:"label",children:a}),n?_jsx(Chip,{size:"sm",variant:"soft",label:n}):null]}),_jsx(Text,{variant:"bodySmall",children:e.subject}),l?_jsx(Button,{label:s.ticketView,variant:"link",size:"sm",onPress:l,testID:`ticket-view-${e.ticketId}`}):null]})})}
@@ -1 +1 @@
1
- "use strict";import{Logger}from"@webority/mobile-core";import{IconButton,ProgressBar,Text,useTheme}from"@webority/mobile-ui";import{useEffect,useMemo,useRef,useState}from"react";import{StyleSheet,View}from"react-native";import{playFile}from"../speech/expoAudio.js";import{discardFile,PhoneSpeechError}from"../speech/phoneSpeech.js";import{audioExtension,formatClipTime}from"../speech/speechText.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const expoFileSystem=()=>{try{return require("expo-file-system")}catch{throw new PhoneSpeechError("Unavailable","Unavailable","Voice files are not available in this app.")}};export function VoiceClipPart({part:e,turn:t}){const r=useTheme(),i=useMemo(()=>buildStyles(r),[r]),s=t.labels,[n,a]=useState(!1),[o,c]=useState(!1),[l,u]=useState(!1),[p,m]=useState(0),h=useRef(null),d=useRef(null),f=useRef(!0);useEffect(()=>(f.current=!0,()=>{f.current=!1,h.current?.stop(),h.current=null,null!==d.current&&discardFile(d.current)}),[]);const startPlayback=e=>{const t=playFile(e,e=>{f.current&&(m(e.positionMs),u(e.playing))});h.current=t;const release=()=>!(!f.current||h.current!==t)&&(h.current=null,u(!1),!0);t.finished.then(()=>{release()&&m(0)},e=>{release()&&(c(!0),Logger.error("[chat] voice clip playback failed",e))})},x=t.features.VoiceClips&&!o,y=null!==e.transcript&&""!==e.transcript.trim()?e.transcript:null,g=e.durationMs>0?Math.min(1,Math.max(0,p/e.durationMs)):0;return _jsxs(View,{accessibilityLabel:s.voiceClip,testID:"chat-voice-clip",style:i.root,children:[x?_jsxs(_Fragment,{children:[_jsxs(View,{style:i.row,children:[_jsx(IconButton,{icon:l?"pause":"play",accessibilityLabel:l?s.voiceClipPause:s.voiceClipPlay,variant:"ghost",tone:"neutral",size:"sm",loading:n,onPress:()=>{const r=h.current;null===r?null===d.current?n||(async()=>{a(!0),c(!1);try{const r=new Uint8Array(await t.readAttachment(e.attachmentId)),{File:i,Paths:s}=expoFileSystem(),n=new i(s.cache,`wchat-clip-${e.attachmentId}${audioExtension(r)}`);if(n.create({overwrite:!0}),n.write(r),!f.current)return void discardFile(n.uri);d.current=n.uri,startPlayback(n.uri)}catch(e){if(!f.current)return;c(!0),Logger.error("[chat] voice clip failed to load",e)}finally{f.current&&a(!1)}})():startPlayback(d.current):l?r.pause():r.resume()},testID:"chat-voice-clip-play"}),_jsx(Text,{variant:"caption",color:"secondary",children:s.voiceClipTime(formatClipTime(p),formatClipTime(e.durationMs))})]}),p>0?_jsx(ProgressBar,{progress:g,height:4}):null]}):null,null!==y?_jsx(Text,{variant:"body",children:y}):null,x||null!==y?null:_jsx(Text,{variant:"caption",color:o?"danger":"secondary",accessibilityLiveRegion:"polite",children:s.voiceClipFailed})]})}const buildStyles=e=>StyleSheet.create({root:{gap:e.space.xs},row:{flexDirection:"row",alignItems:"center",gap:e.space.xs}});
1
+ "use strict";import{voiceClipBars}from"@webority/chat-core";import{Logger}from"@webority/mobile-core";import{Button,IconButton,Text,useTheme}from"@webority/mobile-ui";import{useEffect,useMemo,useRef,useState}from"react";import{StyleSheet,View}from"react-native";import{playFile}from"../speech/expoAudio.js";import{discardFile,PhoneSpeechError}from"../speech/phoneSpeech.js";import{audioExtension,formatClipTime}from"../speech/speechText.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const expoFileSystem=()=>{try{return require("expo-file-system")}catch{throw new PhoneSpeechError("Unavailable","Unavailable","Voice files are not available in this app.")}};export function VoiceClipPart({part:e,turn:t}){const r=useTheme(),i=useMemo(()=>buildStyles(r),[r]),a=t.labels,[o,s]=useState(!1),[c,l]=useState(!1),[n,u]=useState(!1),[p,m]=useState(0),[h,d]=useState(!1),x=useRef(null),y=useRef(null),f=useRef(!0);useEffect(()=>(f.current=!0,()=>{f.current=!1,x.current?.stop(),x.current=null,null!==y.current&&discardFile(y.current)}),[]);const startPlayback=e=>{const t=playFile(e,e=>{f.current&&(m(e.positionMs),u(e.playing))});x.current=t;const release=()=>!(!f.current||x.current!==t)&&(x.current=null,u(!1),!0);t.finished.then(()=>{release()&&m(0)},e=>{release()&&(l(!0),Logger.error("[chat] voice clip playback failed",e))})},v=t.features.VoiceClips,b=null!==e.transcript&&""!==e.transcript?e.transcript:null,w=e.durationMs>0?Math.min(1,Math.max(0,p/e.durationMs)):0,g=useMemo(()=>voiceClipBars(e.attachmentId,40).map((e,t)=>({id:`bar-${t}`,position:t,level:e})),[e.attachmentId]);return _jsxs(View,{accessibilityRole:"summary",accessibilityLabel:a.voiceClip,testID:"chat-voice-clip",style:i.root,children:[v?_jsxs(View,{style:i.row,children:[_jsx(IconButton,{icon:n?"pause":"play",accessibilityLabel:n?a.voiceClipPause:a.voiceClipPlay,variant:"ghost",tone:"neutral",size:"sm",loading:o,disabled:o,onPress:()=>{const r=x.current;null===r?null===y.current?o||(async()=>{s(!0),l(!1);try{const r=new Uint8Array(await t.readAttachment(e.attachmentId)),{File:i,Paths:a}=expoFileSystem(),o=new i(a.cache,`wchat-clip-${e.attachmentId}${audioExtension(r)}`);if(o.create({overwrite:!0}),o.write(r),!f.current)return void discardFile(o.uri);y.current=o.uri,startPlayback(o.uri)}catch(e){if(!f.current)return;l(!0),Logger.error("[chat] voice clip failed to load",e)}finally{f.current&&s(!1)}})():startPlayback(y.current):n?r.pause():r.resume()},testID:"chat-voice-clip-play"}),_jsx(View,{style:i.wave,children:g.map(e=>_jsx(View,{testID:"chat-voice-clip-bar",style:[i.bar,{height:Math.max(4,Math.round(28*e.level)),backgroundColor:e.position<Math.floor(40*w)?r.colors.primary:r.colors["text-subtle"]}]},e.id))}),_jsx(Text,{variant:"caption",color:"secondary",children:a.voiceClipTime(formatClipTime(p),formatClipTime(e.durationMs))})]}):null,v&&null!==b?_jsxs(_Fragment,{children:[_jsx(Button,{label:h?a.voiceClipHideTranscript:a.voiceClipShowTranscript,variant:"link",size:"sm",accessibilityState:{expanded:h},onPress:()=>d(e=>!e),testID:"chat-voice-clip-transcript-toggle"}),h?_jsx(Text,{variant:"body",children:b}):null]}):null,v||null===b?null:_jsx(Text,{variant:"body",children:b}),c?_jsx(Text,{variant:"caption",color:"danger",accessibilityLiveRegion:"polite",children:a.voiceClipFailed}):null]})}const buildStyles=e=>StyleSheet.create({root:{gap:e.space.xs},row:{flexDirection:"row",alignItems:"center",gap:e.space.xs},wave:{flexDirection:"row",alignItems:"center",gap:e.space.xxs},bar:{width:3}});
@@ -1 +1 @@
1
- "use strict";import{ChatSpeechError,createSpeechTokenSource}from"@webority/chat-core";import{Logger}from"@webority/mobile-core";import{Permissions}from"@webority/mobile-core/permissions";import{synthesizeSpeech,transcribeClip}from"./azureSpeech.js";import{playFile,startRecording}from"./expoAudio.js";import{clampSpeakText,DEFAULT_SPEECH_LANGUAGE,DEFAULT_SPEECH_VOICE,MAX_DICTATION_MS,MIN_DICTATION_MS}from"./speechText.js";export class PhoneSpeechError extends ChatSpeechError{constructor(e,t,r){super(e,r),this.name="PhoneSpeechError",this.phoneCode=t}}const expoFileSystem=()=>{try{return require("expo-file-system")}catch{throw new PhoneSpeechError("Unavailable","Unavailable","Voice files are not available in this app.")}};export function discardFile(e){try{const{File:t}=expoFileSystem();new t(e).delete()}catch(e){Logger.warn("Removing a temporary audio file failed:",e)}}const failed=e=>e instanceof ChatSpeechError?e:(Logger.error("[chat] speech failed",e),new PhoneSpeechError("Failed","Failed")),waitForDictation=e=>new Promise(t=>{if(e?.aborted)return void t();const done=()=>{clearTimeout(r),e?.removeEventListener("abort",done),t()},r=setTimeout(done,MAX_DICTATION_MS);e?.addEventListener("abort",done)});export function createPhoneSpeech(e){const t=e.language??DEFAULT_SPEECH_LANGUAGE,r=e.voice??DEFAULT_SPEECH_VOICE,o=createSpeechTokenSource(e.getToken);let a=null,n=null,i=Promise.resolve();const token=async()=>{try{return await o.get()}catch(e){throw failed(e)}},dictate=async e=>{n?.abort();const r=i,o=new AbortController,forward=()=>o.abort();e.signal?.aborted&&o.abort(),e.signal?.addEventListener("abort",forward),n=o;const a=r.then(()=>(async(e,r)=>{const o=await Permissions.ensure("microphone").catch(()=>{throw new PhoneSpeechError("Blocked","MicDenied","The microphone permission could not be checked.")});if("blocked"===o)throw new PhoneSpeechError("Blocked","MicBlocked");if("unavailable"===o)throw new PhoneSpeechError("NoMicrophone","MicUnavailable");if("granted"!==o)throw new PhoneSpeechError("Blocked","MicDenied");let a,n;try{a=await startRecording()}catch(e){throw failed(e)}e.onStarted?.(),await waitForDictation(r);try{n=await a.stop()}catch(t){throw e.onEnd?.(),failed(t)}if(n.durationMs<MIN_DICTATION_MS)return discardFile(n.uri),void e.onEnd?.();try{const r=await transcribeClip({token:await token(),uri:n.uri,language:e.language??t});""!==r&&e.onText?.(r,!0),e.onEnd?.()}catch(t){throw e.onEnd?.(),failed(t)}finally{discardFile(n.uri)}})(e,o.signal));i=a.then(()=>{},()=>{});try{await a}finally{e.signal?.removeEventListener("abort",forward),n===o&&(n=null)}};return{dictation:!0,readAloud:!0,streamsText:!1,startDictation:e=>dictate(e),speak:(e,o)=>(async(e,o)=>{a?.abort();const n=new AbortController;a=n;const forward=()=>n.abort();o.signal?.aborted&&n.abort(),o.signal?.addEventListener("abort",forward);const i=n.signal;let c=null,s=null;const onAbort=()=>{s?.stop()};try{const a=clampSpeakText(e);if(""===a)return;const n=await synthesizeSpeech({token:await token(),text:a,language:o.language??t,voice:r,signal:i});if(i.aborted)return;const{File:l,Paths:h}=expoFileSystem();if(c=new l(h.cache,`wchat-read-${Date.now()}.mp3`),c.create({overwrite:!0}),c.write(n),i.aborted)return;s=playFile(c.uri),i.addEventListener("abort",onAbort),i.aborted&&s.stop(),await s.finished}catch(e){if(i.aborted)return;throw failed(e)}finally{i.removeEventListener("abort",onAbort),o.signal?.removeEventListener("abort",forward),a===n&&(a=null),null!==c&&discardFile(c.uri)}})(e,o)}}
1
+ "use strict";import{ChatSpeechError,createSpeechTokenSource}from"@webority/chat-core";import{Logger}from"@webority/mobile-core";import{Permissions}from"@webority/mobile-core/permissions";import{synthesizeSpeech,transcribeClip}from"./azureSpeech.js";import{playFile,startRecording}from"./expoAudio.js";import{clampSpeakText,DEFAULT_SPEECH_LANGUAGE,DEFAULT_SPEECH_VOICE,MAX_DICTATION_MS,MIN_DICTATION_MS}from"./speechText.js";export class PhoneSpeechError extends ChatSpeechError{constructor(e,r,t){super(e,t),this.name="PhoneSpeechError",this.phoneCode=r}}const expoFileSystem=()=>{try{return require("expo-file-system")}catch{throw new PhoneSpeechError("Unavailable","Unavailable","Voice files are not available in this app.")}};export function discardFile(e){try{const{File:r}=expoFileSystem();new r(e).delete()}catch(e){Logger.warn("Removing a temporary audio file failed:",e)}}const failed=e=>e instanceof ChatSpeechError?e:(Logger.error("[chat] speech failed",e),new PhoneSpeechError("Failed","Failed")),waitForDictation=e=>new Promise(r=>{if(e?.aborted)return void r();const done=()=>{clearTimeout(t),e?.removeEventListener("abort",done),r()},t=setTimeout(done,MAX_DICTATION_MS);e?.addEventListener("abort",done)});export function createPhoneSpeech(e){const r=e.language??DEFAULT_SPEECH_LANGUAGE,t=e.voice??DEFAULT_SPEECH_VOICE,o=createSpeechTokenSource(e.getToken);let a=null,i=null,n=Promise.resolve();const token=async()=>{try{return await o.get()}catch(e){throw failed(e)}},dictate=async e=>{a?.abort(),i?.abort();const t=n,o=new AbortController,forward=()=>o.abort();e.signal?.aborted&&o.abort(),e.signal?.addEventListener("abort",forward),i=o;const c=t.then(()=>(async(e,t)=>{const o=await Permissions.ensure("microphone").catch(()=>{throw new PhoneSpeechError("Blocked","MicDenied","The microphone permission could not be checked.")});if("blocked"===o)throw new PhoneSpeechError("Blocked","MicBlocked");if("unavailable"===o)throw new PhoneSpeechError("NoMicrophone","MicUnavailable");if("granted"!==o)throw new PhoneSpeechError("Blocked","MicDenied");let a,i;try{a=await startRecording()}catch(e){throw failed(e)}e.onStarted?.(),await waitForDictation(t);try{i=await a.stop()}catch(r){throw e.onEnd?.(),failed(r)}if(e.shouldDiscard?.())return discardFile(i.uri),void e.onEnd?.();if(i.durationMs<MIN_DICTATION_MS)return discardFile(i.uri),void e.onEnd?.();try{const t=await transcribeClip({token:await token(),uri:i.uri,language:e.language??r});""!==t&&e.onText?.(t,!0),e.onEnd?.()}catch(r){throw e.onEnd?.(),failed(r)}finally{discardFile(i.uri)}})(e,o.signal));n=c.then(()=>{},()=>{});try{await c}finally{e.signal?.removeEventListener("abort",forward),i===o&&(i=null)}};return{dictation:!0,readAloud:!0,streamsText:!1,startDictation:e=>dictate(e),speak:(e,o)=>(async(e,o)=>{a?.abort();const i=new AbortController;a=i;const forward=()=>i.abort();o.signal?.aborted&&i.abort(),o.signal?.addEventListener("abort",forward);const n=i.signal;let c=null,s=null;const onAbort=()=>{s?.stop()};try{const a=clampSpeakText(e);if(""===a)return;const i=await synthesizeSpeech({token:await token(),text:a,language:o.language??r,voice:t,signal:n});if(n.aborted)return;const{File:l,Paths:d}=expoFileSystem();if(c=new l(d.cache,`wchat-read-${Date.now()}.mp3`),c.create({overwrite:!0}),c.write(i),n.aborted)return;s=playFile(c.uri),n.addEventListener("abort",onAbort),n.aborted&&s.stop(),await s.finished}catch(e){if(n.aborted)return;throw failed(e)}finally{n.removeEventListener("abort",onAbort),o.signal?.removeEventListener("abort",forward),a===i&&(a=null),null!==c&&discardFile(c.uri)}})(e,o)}}
@@ -1 +1 @@
1
- "use strict";export const DEFAULT_SPEECH_LANGUAGE="en-IN";export const DEFAULT_SPEECH_VOICE="en-IN-NeerjaNeural";export const MAX_SPEAK_CHARS=4e3;export const MAX_DICTATION_MS=6e4;export const MIN_DICTATION_MS=600;const SENTENCE_END_FLOOR=2e3,ascii=t=>Array.from(t,t=>t.charCodeAt(0)),OGG=ascii("OggS"),RIFF=ascii("RIFF"),EBML=[26,69,223,163],ID3=ascii("ID3"),MPEG_FRAME_HEADERS=[[255,251],[255,243],[255,242]],startsWith=(t,e,r)=>r.every((r,s)=>t[e+s]===r);export function audioExtension(t){return startsWith(t,0,OGG)?".ogg":startsWith(t,0,RIFF)?".wav":startsWith(t,0,EBML)?".webm":startsWith(t,0,ID3)||MPEG_FRAME_HEADERS.some(e=>startsWith(t,0,e))?".mp3":".m4a"}export function escapeSsml(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}export function buildSsml(t,e,r){return`<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="${escapeSsml(e)}"><voice name="${escapeSsml(r)}">${escapeSsml(t)}</voice></speak>`}export function clampSpeakText(t){const e=t.trim();if(e.length<=4e3)return e;const r=e.slice(0,4e3),s=Math.max(r.lastIndexOf("."),r.lastIndexOf("?"),r.lastIndexOf("!"));return s>2e3?r.slice(0,s+1):r}export function formatClipTime(t){if(!Number.isFinite(t)||t<0)return"0:00";const e=Math.floor(t/1e3);return`${Math.floor(e/60)}:${String(e%60).padStart(2,"0")}`}export function joinDictation(t,e,r){const s=e.trim();if(""===s)return t;return`${t}${t.length>0&&!/\s$/.test(t)?" ":""}${s}`.slice(0,r)}
1
+ "use strict";export const DEFAULT_SPEECH_LANGUAGE="en-IN";export const DEFAULT_SPEECH_VOICE="en-IN-NeerjaNeural";export const MAX_SPEAK_CHARS=6e3;export const MAX_DICTATION_MS=3e5;export const MIN_DICTATION_MS=600;const ascii=t=>Array.from(t,t=>t.charCodeAt(0)),OGG=ascii("OggS"),RIFF=ascii("RIFF"),EBML=[26,69,223,163],ID3=ascii("ID3"),MPEG_FRAME_HEADERS=[[255,251],[255,243],[255,242]],startsWith=(t,e,r)=>r.every((r,s)=>t[e+s]===r);export function audioExtension(t){return startsWith(t,0,OGG)?".ogg":startsWith(t,0,RIFF)?".wav":startsWith(t,0,EBML)?".webm":startsWith(t,0,ID3)||MPEG_FRAME_HEADERS.some(e=>startsWith(t,0,e))?".mp3":".m4a"}export function escapeSsml(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}export function buildSsml(t,e,r){return`<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="${escapeSsml(e)}"><voice name="${escapeSsml(r)}">${escapeSsml(t)}</voice></speak>`}export function clampSpeakText(t){const e=t.trim();if(e.length<=6e3)return e;const r=e.slice(0,6e3),s=r.lastIndexOf(". ");return-1===s?r.trim():r.slice(0,s+1)}export function formatClipTime(t){if(!Number.isFinite(t)||t<0)return"0:00";const e=Math.round(t/1e3);return`${Math.floor(e/60)}:${String(e%60).padStart(2,"0")}`}export function joinDictation(t,e,r){const s=e.trim();if(""===s)return t;return`${t}${t.length>0&&!/\s$/.test(t)?" ":""}${s}`.slice(0,r)}
@@ -1 +1 @@
1
- "use strict";import{createChatSession,emptyFeatures}from"@webority/chat-core";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:n,layout:r,narrow:s,conversationId:o,pageContext:a,behaviour:u,prefs:c,getCaptchaToken:i,onEvent:l,onError:f,onNavigate:p}=e,m=JSON.stringify(s??{}),v=useRef(p);v.current=p;const S=useCallback(e=>v.current?.(e),[]),d=useRef(o);d.current=o;const g=useRef(a);g.current=a;const E=useRef(u);E.current=u;const y=useRef(i);y.current=i;const h=useRef(l);h.current=l;const C=useRef(f);C.current=f;const b=useRef(c);b.current=c;const[I,R]=useState(null);useEffect(()=>{const e=createChatSession(t,{screen:n,layout:r,narrow:JSON.parse(m),conversationId:d.current??void 0,pageContext:()=>g.current,behaviour:()=>E.current?.()??null,prefs:b.current,getCaptchaToken:e=>y.current?.(e)??Promise.resolve(null),onEvent:(e,t)=>h.current?.(e,t),onError:e=>C.current?.(e),schedule:requestFrame});return R({client:t,screen:n,layout:r,narrowKey:m,session:e}),()=>e.dispose()},[t,n,r,m]);const A=null!==I&&I.client===t&&I.screen===n&&I.layout===r&&I.narrowKey===m?I.session:IDLE_SESSION,O=useSyncExternalStore(A.subscribe,A.getState),T=useMemo(()=>({load:()=>A.load(),submit:e=>A.submit(e),chooseQuickReply:e=>A.chooseQuickReply(e),answerInput:(e,t)=>A.answerInput(e,t),confirmAction:e=>A.confirmAction(e),rejectAction:(e,t)=>A.rejectAction(e,t),stop:()=>A.stop(),retry:()=>A.retry(),regenerate:()=>A.regenerate(),startEdit:e=>A.startEdit(e),cancelEdit:()=>A.cancelEdit(),attach:e=>A.attach(e),removeAttachment:e=>A.removeAttachment(e),openConversation:e=>A.openConversation(e),resumeLast:()=>A.resumeLast(),newConversation:()=>A.newConversation(),rate:(e,t,n)=>A.rate(e,t,n),reset:()=>A.reset(),requestHandoff:e=>A.requestHandoff(e),notifyTyping:()=>A.notifyTyping(),resumeLive:()=>A.resumeLive()}),[A]),L=useRef(o);useEffect(()=>{A!==IDLE_SESSION&&o&&o!==L.current&&(L.current=o,A.openConversation(o))},[o,A]);const N=useRef("active"===AppState.currentState),k=useRef(!0),w=useCallback(()=>A.setLiveActive(N.current&&k.current),[A]),P=useCallback(e=>{k.current=e,w()},[w]);useEffect(()=>{w();const e=AppState.addEventListener("change",e=>{"active"===e?(N.current=!0,A.endHandoffPause()):N.current=!1,w()});return()=>e.remove()},[w,A]);const _=useCallback((e,t)=>{h.current?.(e,t)},[]);return{...O,...T,session:A,client:t,emit:_,setChatVisible:P,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,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 +1 @@
1
- "use strict";import{useEffect,useRef}from"react";import{AppState,Vibration}from"react-native";const isReply=e=>"Assistant"===e.author.kind||"Agent"===e.author.kind&&e.stored;export function useChatHaptics(e){const t=useRef(null),r=e.features.Sounds&&!0===e.profile?.experience.sound.vibrate&&!e.muted,s=e.profile?.experience.sound.vibrateMs??0;useEffect(()=>{if(null!==t.current)for(const i of e.messages){if(!isReply(i)||i.streaming||t.current.has(i.id))continue;if(t.current.add(i.id),i.restored)continue;const e=i.parts.length>0&&i.parts.every(e=>"Notice"===e.kind),n="Agent"!==i.author.kind||"active"===AppState.currentState;r&&!e&&n&&Vibration.vibrate(s)}else t.current=new Set(e.messages.map(e=>e.id))},[e.messages,r,s])}
1
+ "use strict";import{useEffect,useRef}from"react";import{Vibration}from"react-native";const isReply=e=>"Assistant"===e.author.kind||"Script"===e.author.kind||"Agent"===e.author.kind;export function useChatHaptics(e){const t=useRef(null),s=e.features.Sounds&&!0===e.profile?.experience.sound.vibrate&&!e.muted,i=e.profile?.experience.sound.vibrateMs??0;useEffect(()=>{if(null!==t.current)for(const r of e.messages){if(!isReply(r)||r.streaming||t.current.has(r.id))continue;if(t.current.add(r.id),r.restored)continue;const e=r.parts.some(e=>"Notice"===e.kind);s&&!e&&Vibration.vibrate(i)}else t.current=new Set(e.messages.map(e=>e.id))},[e.messages,s,i])}
@@ -0,0 +1 @@
1
+ "use strict";import{Logger}from"@webority/mobile-core";import{useEffect,useRef}from"react";export const CUES={open:{from:420,to:920,seconds:.16,peak:.16},reply:{from:680,to:540,seconds:.11,peak:.06},sent:{from:540,to:760,seconds:.09,peak:.05}};const SAMPLE_RATE=22050,ATTACK_SECONDS=.01,written=new Map;function cueBytes(e){const t=Math.round(22050*e.seconds),n=2*t,s=new Uint8Array(44+n),o=new DataView(s.buffer),text=(e,t)=>{for(let n=0;n<t.length;n+=1)o.setUint8(e+n,t.charCodeAt(n))};text(0,"RIFF"),o.setUint32(4,36+n,!0),text(8,"WAVE"),text(12,"fmt "),o.setUint32(16,16,!0),o.setUint16(20,1,!0),o.setUint16(22,1,!0),o.setUint32(24,22050,!0),o.setUint32(28,44100,!0),o.setUint16(32,2,!0),o.setUint16(34,16,!0),text(36,"data"),o.setUint32(40,n,!0);const r=Math.min(.01,e.seconds/2);let i=0;for(let n=0;n<t;n+=1){const t=n/22050,s=e.from+(e.to-e.from)*t/e.seconds;i+=2*Math.PI*s/22050;const a=t<r?t/r:(e.seconds-t)/(e.seconds-r);o.setInt16(44+2*n,Math.round(32767*e.peak*a*Math.sin(i)),!0)}return s}export function playCue(e,t=1){(async()=>{let n=written.get(e);if(void 0===n){const{File:t,Paths:s}=require("expo-file-system"),o=new t(s.cache,`wchat-cue-${e}.wav`);o.create({overwrite:!0}),o.write(cueBytes(CUES[e])),n=o.uri,written.set(e,n)}const{createAudioPlayer:s}=require("expo-audio"),o=s({uri:n});o.volume=t,o.addListener("playbackStatusUpdate",e=>{e.didJustFinish&&o.remove()}),o.play()})().catch(e=>{Logger.warn("[chat] sound cue failed",e)})}function takeUnseen(e,t,n){if(t){e.wasLoading=!0;for(const t of n)e.seen.add(t.id);return[]}if(e.wasLoading||!e.seeded){e.wasLoading=!1,e.seeded=!0;for(const t of n)e.seen.add(t.id);return[]}const s=[];for(const t of n)e.seen.has(t.id)||(e.seen.add(t.id),s.push(t));return s}export function useChatSound(e){const t=e.features.Sounds?e.profile?.experience.sound??null:null,n=useRef(e);n.current=e;const s=useRef(e.open),o=useRef({seen:new Set,seeded:!1,wasLoading:!1}),{open:r,loading:i,messages:a}=e;useEffect(()=>{const e=s.current;s.current=r;const c=takeUnseen(o.current,i,a);if(null!==t&&!n.current.muted&&t.volume>0){r&&!e&&t.open&&playCue("open",t.volume);for(const e of c){if(e.restored||e.parts.some(e=>"Notice"===e.kind))continue;const n=e.author.kind;"Visitor"===n?!e.stored&&t.sent&&playCue("sent",t.volume):"Assistant"!==n&&"Script"!==n&&"Agent"!==n||!t.reply||playCue("reply",t.volume)}}},[r,i,a,t])}
@@ -9,6 +9,7 @@ export interface ChatComposerProps {
9
9
  keyboardAware?: boolean;
10
10
  safeArea?: boolean;
11
11
  testID?: string;
12
+ focusRef?: React.MutableRefObject<(() => void) | null>;
12
13
  }
13
- export declare function ChatComposer({ chat, labels, pickAttachments, keyboardOffset, keyboardAware, safeArea, testID, }: ChatComposerProps): React.ReactElement;
14
+ export declare function ChatComposer({ chat, labels, pickAttachments, keyboardOffset, keyboardAware, safeArea, testID, focusRef, }: ChatComposerProps): React.ReactElement;
14
15
  //# sourceMappingURL=ChatComposer.d.ts.map
@@ -1,4 +1,4 @@
1
- import type { ChatLabels } from "@webority/chat-core";
1
+ import { type ChatLabels } from "@webority/chat-core";
2
2
  import type React from "react";
3
3
  import type { UseChatResult } from "./useChat";
4
4
  export interface ChatConversationActionsProps {
@@ -4,6 +4,7 @@ import type { UseChatResult } from "./useChat";
4
4
  export interface DictationNotice {
5
5
  message: string;
6
6
  openSettings: boolean;
7
+ tone: "danger" | "info";
7
8
  }
8
9
  export interface ChatDictationButtonProps {
9
10
  chat: UseChatResult;
@@ -12,6 +13,7 @@ export interface ChatDictationButtonProps {
12
13
  onText: (text: string) => void;
13
14
  onNotice: (notice: DictationNotice | null) => void;
14
15
  testID?: string;
16
+ stopRef?: React.MutableRefObject<(() => void) | null>;
15
17
  }
16
- export declare function ChatDictationButton({ chat, labels, disabled, onText, onNotice, testID, }: ChatDictationButtonProps): React.ReactElement | null;
18
+ export declare function ChatDictationButton({ chat, labels, disabled, onText, onNotice, testID, stopRef, }: ChatDictationButtonProps): React.ReactElement | null;
17
19
  //# sourceMappingURL=ChatDictationButton.d.ts.map
@@ -7,5 +7,5 @@ export interface ChatEmbedProps extends ChatShellProps {
7
7
  height?: number;
8
8
  }
9
9
  /** The chat drawn inside a bounded area of a screen, with a border and rounded corners. */
10
- export declare function ChatEmbed({ chat, labels, renderers, layoutParts, loader, motion, pickAttachments, onOpenAttachment, onOpenTarget, onNavigate, openTicket, handoffHosts, keyboardOffset, title, headerActions, height, testID, }: ChatEmbedProps): React.ReactElement | null;
10
+ export declare function ChatEmbed({ chat, labels, renderers, layoutParts, loader, motion, pickAttachments, onOpenAttachment, onOpenTarget, onNavigate, openTicket, handoffHosts, resolveLink, keyboardOffset, title, headerActions, onClose, height, testID, }: ChatEmbedProps): React.ReactElement | null;
11
11
  //# sourceMappingURL=ChatEmbed.d.ts.map
@@ -21,6 +21,8 @@ export interface ChatCommonProps {
21
21
  openTicket?: ChatOpenTicketHandler;
22
22
  /** Hosts an absolute https link or Navigate chip may open; any other absolute target is not linked. */
23
23
  handoffHosts?: readonly string[];
24
+ /** Resolves a link in a reply to a host route or address; null leaves the link as text. */
25
+ resolveLink?: (href: string) => string | null;
24
26
  keyboardOffset?: number;
25
27
  testID?: string;
26
28
  }
@@ -28,12 +30,16 @@ export interface ChatFrameProps extends ChatCommonProps {
28
30
  layout: ChatLayout;
29
31
  title?: string;
30
32
  headerActions?: React.ReactNode;
33
+ /** The host sheet closes through this callback. */
34
+ onClose?: () => void;
31
35
  }
32
36
  /** The props of the three shells: the frame's, with labels as a partial merged over the defaults. */
33
37
  export interface ChatShellProps extends Omit<ChatCommonProps, "labels"> {
34
38
  labels?: Partial<ChatLabels>;
35
39
  title?: string;
36
40
  headerActions?: React.ReactNode;
41
+ /** The host sheet closes through this callback. */
42
+ onClose?: () => void;
37
43
  }
38
- export declare function ChatFrame({ chat, labels, renderers, layoutParts, loader, motion, pickAttachments, onOpenAttachment, onOpenTarget, onNavigate, openTicket, handoffHosts, keyboardOffset, layout, title, headerActions, testID, }: ChatFrameProps): React.ReactElement | null;
44
+ export declare function ChatFrame({ chat, labels, renderers, layoutParts, loader, motion, pickAttachments, onOpenAttachment, onOpenTarget, onNavigate, openTicket, handoffHosts, resolveLink, keyboardOffset, layout, title, headerActions, onClose, testID, }: ChatFrameProps): React.ReactElement | null;
39
45
  //# sourceMappingURL=ChatFrame.d.ts.map
@@ -0,0 +1,21 @@
1
+ import type { ChatConversationSummary, ChatLabels } from "@webority/chat-core";
2
+ import { type ConversationList } from "@webority/chat-core";
3
+ import type React from "react";
4
+ import type { UseChatResult } from "./useChat";
5
+ export interface ChatPastChatsProps {
6
+ chat: UseChatResult;
7
+ labels: ChatLabels;
8
+ testID?: string;
9
+ }
10
+ export interface ConversationRowProps {
11
+ conversation: ChatConversationSummary;
12
+ list: ConversationList | null;
13
+ chat: UseChatResult;
14
+ labels: ChatLabels;
15
+ testID: string;
16
+ onOpen: (conversation: ChatConversationSummary) => void;
17
+ untitledTitle?: string;
18
+ }
19
+ export declare function ChatPastChats({ chat, labels, testID }: ChatPastChatsProps): React.ReactElement | null;
20
+ export declare function ConversationRow({ conversation, list, chat, labels, testID, onOpen, untitledTitle, }: ConversationRowProps): React.ReactElement;
21
+ //# sourceMappingURL=ChatPastChats.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import type React from "react";
2
2
  import { type ChatShellProps } from "./ChatFrame";
3
3
  /** The whole chat for one screen of the app's navigator. Keep `useChat` above the navigator so the conversation survives leaving the screen. */
4
- export declare function ChatScreen({ chat, labels, renderers, layoutParts, loader, motion, pickAttachments, onOpenAttachment, onOpenTarget, onNavigate, openTicket, handoffHosts, keyboardOffset, title, headerActions, testID, }: ChatShellProps): React.ReactElement | null;
4
+ export declare function ChatScreen({ chat, labels, renderers, layoutParts, loader, motion, pickAttachments, onOpenAttachment, onOpenTarget, onNavigate, openTicket, handoffHosts, resolveLink, keyboardOffset, title, headerActions, onClose, testID, }: ChatShellProps): React.ReactElement | null;
5
5
  //# sourceMappingURL=ChatScreen.d.ts.map
@@ -17,5 +17,5 @@ export interface ChatSheetProps extends ChatShellProps {
17
17
  conversationId?: string | null;
18
18
  }
19
19
  /** The chat in a bottom sheet over the screen, opened from a floating launcher. */
20
- export declare function ChatSheet({ chat, labels, renderers, layoutParts, loader, motion, pickAttachments, onOpenAttachment, onOpenTarget, onNavigate, keyboardOffset, open, defaultOpen, onOpenChange, position, bottomOffset, snapPoints, compact, openTicket, handoffHosts, conversationId, testID, }: ChatSheetProps): React.ReactElement | null;
20
+ export declare function ChatSheet({ chat, labels, renderers, layoutParts, loader, motion, pickAttachments, onOpenAttachment, onOpenTarget, onNavigate, keyboardOffset, open, defaultOpen, onOpenChange, position, bottomOffset, snapPoints, compact, openTicket, handoffHosts, resolveLink, conversationId, onClose, testID, }: ChatSheetProps): React.ReactElement | null;
21
21
  //# sourceMappingURL=ChatSheet.d.ts.map
@@ -18,6 +18,8 @@ export interface ChatThreadProps {
18
18
  onNavigate?: (path: string) => void;
19
19
  openTicket?: ChatOpenTicketHandler;
20
20
  handoffHosts?: readonly string[];
21
+ resolveLink?: (href: string) => string | null;
22
+ focusComposer?: () => void;
21
23
  keyboardAware?: boolean;
22
24
  keyboardOffset?: number;
23
25
  /** Drawn before the first message. */
@@ -30,5 +32,5 @@ export interface ChatThreadProps {
30
32
  * pill while a paced reply is held, the loader while a reply is awaited and the error row after a
31
33
  * failed or stopped turn.
32
34
  */
33
- export declare function ChatThread({ chat, labels, renderers, layoutParts, loader, motion, pickAttachments, onOpenAttachment, onOpenTarget, onNavigate, openTicket, handoffHosts, keyboardAware, keyboardOffset, empty, style, testID, }: ChatThreadProps): React.ReactElement;
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;
34
36
  //# sourceMappingURL=ChatThread.d.ts.map
@@ -10,6 +10,7 @@ export { ChatLiveBar } from "./ChatLiveBar";
10
10
  export { ChatMessageActions } from "./ChatMessageActions";
11
11
  export { ChatNudge } from "./ChatNudge";
12
12
  export { ChatOpenTickets } from "./ChatOpenTickets";
13
+ export { ChatPastChats } from "./ChatPastChats";
13
14
  export { ChatScreen } from "./ChatScreen";
14
15
  export type { ChatSheetProps } from "./ChatSheet";
15
16
  export { ChatSheet } from "./ChatSheet";
@@ -3,6 +3,6 @@ import type { ChatPartRendererProps } from "../types";
3
3
  type ChartPartProps = ChatPartRendererProps<Extract<ChatPart, {
4
4
  kind: "Chart";
5
5
  }>>;
6
- export declare function ChartPart({ part, turn }: Pick<ChartPartProps, "part" | "turn">): import("react").JSX.Element | null;
6
+ export declare function ChartPart({ part, turn }: Pick<ChartPartProps, "part" | "turn">): import("react").JSX.Element;
7
7
  export {};
8
8
  //# sourceMappingURL=ChartPart.d.ts.map
@@ -10,12 +10,14 @@ export interface FigureRunsProps {
10
10
  numberOfLines?: number;
11
11
  accessibilityLabel?: string;
12
12
  testID?: string;
13
+ heading?: boolean;
13
14
  }
14
15
  export interface FigureTextProps extends Omit<FigureRunsProps, "runs"> {
15
16
  text: string;
17
+ enabled?: boolean;
16
18
  }
17
19
  export declare function runsToText(runs: readonly ChatFigureRun[]): string;
18
- export declare function FigureRuns({ runs, variant, color, strong, numberOfLines, accessibilityLabel, testID, }: FigureRunsProps): import("react").JSX.Element;
19
- export declare function FigureText({ text, variant, ...rest }: FigureTextProps): import("react").JSX.Element;
20
+ export declare function FigureRuns({ runs, variant, color, strong, numberOfLines, accessibilityLabel, testID, heading, }: FigureRunsProps): import("react").JSX.Element;
21
+ export declare function FigureText({ text, variant, enabled, ...rest }: FigureTextProps): import("react").JSX.Element;
20
22
  export {};
21
23
  //# sourceMappingURL=FigureText.d.ts.map
@@ -4,6 +4,6 @@ import type { ChatPartRendererProps } from "../types";
4
4
  type HandoffView = Extract<ChatPart, {
5
5
  kind: "Handoff";
6
6
  }>;
7
- export declare function HandoffPart({ part, turn }: ChatPartRendererProps<HandoffView>): React.ReactElement;
7
+ export declare function HandoffPart({ part, turn }: ChatPartRendererProps<HandoffView>): React.ReactElement | null;
8
8
  export {};
9
9
  //# sourceMappingURL=HandoffPart.d.ts.map
@@ -1,4 +1,4 @@
1
- import type { ChatPart } from "@webority/chat-core";
1
+ import { type ChatPart } from "@webority/chat-core";
2
2
  import type React from "react";
3
3
  import type { ChatPartRendererProps } from "../types";
4
4
  type VoiceClipProps = ChatPartRendererProps<Extract<ChatPart, {
@@ -1,13 +1,13 @@
1
1
  export declare const DEFAULT_SPEECH_LANGUAGE = "en-IN";
2
2
  export declare const DEFAULT_SPEECH_VOICE = "en-IN-NeerjaNeural";
3
- export declare const MAX_SPEAK_CHARS = 4000;
4
- export declare const MAX_DICTATION_MS = 60000;
3
+ export declare const MAX_SPEAK_CHARS = 6000;
4
+ export declare const MAX_DICTATION_MS = 300000;
5
5
  export declare const MIN_DICTATION_MS = 600;
6
6
  /** The file extension a recording's bytes stand for. m4a is the fallback, the format the phone records. */
7
7
  export declare function audioExtension(bytes: Uint8Array): string;
8
8
  export declare function escapeSsml(text: string): string;
9
9
  export declare function buildSsml(text: string, language: string, voice: string): string;
10
- /** Cuts at the last sentence end past the floor, so a long reply is read whole sentences at a time. */
10
+ /** Cuts at the last sentence end within the limit, so a long reply is read whole sentences at a time. */
11
11
  export declare function clampSpeakText(text: string): string;
12
12
  /** Whole seconds as m:ss. A negative or non-finite value reads as 0:00. */
13
13
  export declare function formatClipTime(ms: number): string;
@@ -1,10 +1,18 @@
1
1
  import type { ChatLiveMessage, ChatPart, ChatPartKind, ChatTurnApi, ChatUploadFile } from "@webority/chat-core";
2
2
  import type React from "react";
3
+ import type { View } from "react-native";
3
4
  export type { ChatMotion } from "@webority/chat-core";
5
+ /** Host values the thread adds to each part's turn: the host's link resolver and the source rows a citation focuses. */
6
+ export interface ChatTurnHostApi {
7
+ resolveLink?: (href: string) => string | null;
8
+ registerSourceRow?: (marker: string, row: View | null) => void;
9
+ /** Moves focus to the composer input after a quick reply is chosen. */
10
+ focusComposer?: () => void;
11
+ }
4
12
  export type ChatPartRendererProps<P extends ChatPart = ChatPart> = {
5
13
  part: P;
6
14
  message: ChatLiveMessage;
7
- turn: ChatTurnApi;
15
+ turn: ChatTurnApi & ChatTurnHostApi;
8
16
  pickAttachments?: () => Promise<ChatUploadFile[]>;
9
17
  };
10
18
  export type ChatRenderers = Partial<{
@@ -33,6 +33,8 @@ export interface UseChatResult extends ChatSessionState, ChatActions {
33
33
  emit: (name: string, data: Record<string, unknown>) => void;
34
34
  /** The host reports whether the chat is on screen; the live stream runs only while it is and the app is active. */
35
35
  setChatVisible: (visible: boolean) => void;
36
+ /** The message of the last hand-off request that failed, cleared by the next request. */
37
+ handoffError: string | null;
36
38
  /** Present only when the host passed `onNavigate`; the turn API of each message hands relative links to it. */
37
39
  onNavigate?: (path: string) => void;
38
40
  }
@@ -0,0 +1,35 @@
1
+ import type { UseChatResult } from "./useChat";
2
+ /**
3
+ * Plays the open cue when the panel opens, and the sent and reply cues for each new message, as the web chat does
4
+ * (chat-elements/src/WuiChat.js _playSounds). A send, an edit and a retry each add a new visitor message; an assistant,
5
+ * script or agent message plays the reply cue. Restored messages, notices and a history load stay silent, and the
6
+ * visitor message the server's copy replaces after a turn is stored, so it does not play the sent cue again.
7
+ * The phone has no WebAudio, so each cue is a short 16-bit WAV written once to the cache and played from there.
8
+ */
9
+ export declare const CUES: {
10
+ readonly open: {
11
+ readonly from: 420;
12
+ readonly to: 920;
13
+ readonly seconds: 0.16;
14
+ readonly peak: 0.16;
15
+ };
16
+ readonly reply: {
17
+ readonly from: 680;
18
+ readonly to: 540;
19
+ readonly seconds: 0.11;
20
+ readonly peak: 0.06;
21
+ };
22
+ readonly sent: {
23
+ readonly from: 540;
24
+ readonly to: 760;
25
+ readonly seconds: 0.09;
26
+ readonly peak: 0.05;
27
+ };
28
+ };
29
+ /**
30
+ * Plays one cue at the given volume (0 to 1). The file is written on the first play and reused after that.
31
+ * A failure is logged, never thrown, so a missing sound never breaks the chat.
32
+ */
33
+ export declare function playCue(name: keyof typeof CUES, volume?: number): void;
34
+ export declare function useChatSound(chat: UseChatResult): void;
35
+ //# sourceMappingURL=useChatSound.d.ts.map