@webority/mobile-chat 0.121.0 → 0.124.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.
- package/README.md +39 -7
- package/lib/commonjs/components/ActionCard.js +1 -1
- package/lib/commonjs/components/ChatComposer.js +1 -1
- package/lib/commonjs/components/ChatConversationList.js +1 -1
- package/lib/commonjs/components/ChatLauncher.js +1 -1
- package/lib/commonjs/components/ChatMarkdown.js +1 -1
- package/lib/commonjs/components/ChatMessage.js +1 -1
- package/lib/commonjs/components/ChatScreen.js +1 -1
- package/lib/commonjs/components/ChatThread.js +1 -1
- package/lib/commonjs/components/ComposerAttachments.js +1 -0
- package/lib/commonjs/components/ReplyRating.js +1 -1
- package/lib/commonjs/index.js +1 -1
- package/lib/commonjs/useChat.js +1 -1
- package/lib/module/components/ActionCard.js +1 -1
- package/lib/module/components/ChatComposer.js +1 -1
- package/lib/module/components/ChatConversationList.js +1 -1
- package/lib/module/components/ChatLauncher.js +1 -1
- package/lib/module/components/ChatMarkdown.js +1 -1
- package/lib/module/components/ChatMessage.js +1 -1
- package/lib/module/components/ChatScreen.js +1 -1
- package/lib/module/components/ChatThread.js +1 -1
- package/lib/module/components/ComposerAttachments.js +1 -0
- package/lib/module/components/ReplyRating.js +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/useChat.js +1 -1
- package/lib/typescript/commonjs/components/ActionCard.d.ts +2 -2
- package/lib/typescript/commonjs/components/ChatComposer.d.ts +12 -1
- package/lib/typescript/commonjs/components/ChatConversationList.d.ts +3 -4
- package/lib/typescript/commonjs/components/ChatLauncher.d.ts +1 -1
- package/lib/typescript/commonjs/components/ChatMarkdown.d.ts +8 -1
- package/lib/typescript/commonjs/components/ChatMessage.d.ts +23 -6
- package/lib/typescript/commonjs/components/ChatScreen.d.ts +7 -2
- package/lib/typescript/commonjs/components/ChatThread.d.ts +9 -1
- package/lib/typescript/commonjs/components/ComposerAttachments.d.ts +12 -0
- package/lib/typescript/commonjs/components/ReplyRating.d.ts +2 -2
- package/lib/typescript/commonjs/index.d.ts +2 -7
- package/lib/typescript/commonjs/useChat.d.ts +9 -53
- package/lib/typescript/module/components/ActionCard.d.ts +2 -2
- package/lib/typescript/module/components/ChatComposer.d.ts +12 -1
- package/lib/typescript/module/components/ChatConversationList.d.ts +3 -4
- package/lib/typescript/module/components/ChatLauncher.d.ts +1 -1
- package/lib/typescript/module/components/ChatMarkdown.d.ts +8 -1
- package/lib/typescript/module/components/ChatMessage.d.ts +23 -6
- package/lib/typescript/module/components/ChatScreen.d.ts +7 -2
- package/lib/typescript/module/components/ChatThread.d.ts +9 -1
- package/lib/typescript/module/components/ComposerAttachments.d.ts +12 -0
- package/lib/typescript/module/components/ReplyRating.d.ts +2 -2
- package/lib/typescript/module/index.d.ts +2 -7
- package/lib/typescript/module/useChat.d.ts +9 -53
- package/package.json +8 -6
- package/lib/commonjs/client.js +0 -1
- package/lib/commonjs/labels.js +0 -1
- package/lib/commonjs/sse.js +0 -1
- package/lib/commonjs/types.js +0 -1
- package/lib/module/client.js +0 -1
- package/lib/module/labels.js +0 -1
- package/lib/module/sse.js +0 -1
- package/lib/module/types.js +0 -1
- package/lib/typescript/commonjs/client.d.ts +0 -73
- package/lib/typescript/commonjs/labels.d.ts +0 -63
- package/lib/typescript/commonjs/sse.d.ts +0 -23
- package/lib/typescript/commonjs/types.d.ts +0 -71
- package/lib/typescript/module/client.d.ts +0 -73
- package/lib/typescript/module/labels.d.ts +0 -63
- package/lib/typescript/module/sse.d.ts +0 -23
- package/lib/typescript/module/types.d.ts +0 -71
package/README.md
CHANGED
|
@@ -18,8 +18,9 @@ npm install @webority/mobile-chat
|
|
|
18
18
|
| `@webority/mobile-core`, `@webority/mobile-ui` | the HTTP client the app passes in, dates, theme and components |
|
|
19
19
|
| `react-native-keyboard-controller` | the question box rises with the keyboard (mobile-ui needs it too) |
|
|
20
20
|
| `react-native-safe-area-context` | the question box and the launcher clear the home indicator (mobile-ui needs it too) |
|
|
21
|
+
| `expo-clipboard` | the copy action on a reply; the package reaches it through `@webority/mobile-core/clipboard` |
|
|
21
22
|
|
|
22
|
-
All are required
|
|
23
|
+
All are required. An app on mobile-ui already has the first three; `expo-clipboard` is the one an app adds.
|
|
23
24
|
|
|
24
25
|
## Wire it up
|
|
25
26
|
|
|
@@ -48,7 +49,7 @@ export const AssistantProvider = ({ children }) => {
|
|
|
48
49
|
return <AssistantContext.Provider value={chat}>{children}</AssistantContext.Provider>;
|
|
49
50
|
};
|
|
50
51
|
|
|
51
|
-
// A stack screen.
|
|
52
|
+
// A stack screen. pickFiles opens the app's own picker and resolves to { uri, name, type } files.
|
|
52
53
|
export const AssistantScreen = ({ navigation }) => (
|
|
53
54
|
<ChatScreen
|
|
54
55
|
chat={useAssistant()}
|
|
@@ -58,6 +59,8 @@ export const AssistantScreen = ({ navigation }) => (
|
|
|
58
59
|
onLinkPress={(target) => navigation.navigate(target.screen, target.params)}
|
|
59
60
|
confirmAction={supportClient.confirmAction}
|
|
60
61
|
onViewTicket={(ticket) => navigation.navigate('SupportTicket', { id: ticket.id })}
|
|
62
|
+
pickAttachments={pickFiles}
|
|
63
|
+
onOpenAttachment={(attachment) => openAttachment(attachment)}
|
|
61
64
|
/>
|
|
62
65
|
);
|
|
63
66
|
```
|
|
@@ -85,14 +88,22 @@ response arrived, `aborted` when the request was cancelled, or `invalid-response
|
|
|
85
88
|
|
|
86
89
|
| Method | Request |
|
|
87
90
|
|---|---|
|
|
88
|
-
| `sendMessage({ message, conversationId, pageContext }, { signal, onEvent })` | `POST {base}/chat`, streamed; resolves with the `done` event |
|
|
91
|
+
| `sendMessage({ message, conversationId, pageContext, replacesMessageId, attachmentIds }, { signal, onEvent })` | `POST {base}/chat`, streamed; resolves with the `done` event, which carries `questionId` |
|
|
92
|
+
| `getSettings()` | `GET {base}/settings`: the attachment limits, `{ attachments: null }` when the server takes none |
|
|
93
|
+
| `uploadAttachment(file, { signal, onProgress })` | `POST {base}/attachments`, multipart |
|
|
94
|
+
| `deleteAttachment(id)` | `DELETE {base}/attachments/{id}` |
|
|
95
|
+
| `getAttachment(id)` | `GET {base}/attachments/{id}`, resolves with the bytes |
|
|
89
96
|
| `getAllowance()` | `GET {base}/allowance` |
|
|
90
|
-
| `listConversations({
|
|
97
|
+
| `listConversations({ page, pageSize })` | `GET {base}/conversations?page=&pageSize=`, one page of `{ items, page, pageSize, totalCount, totalPages }` |
|
|
91
98
|
| `getConversation(id)` | `GET {base}/conversations/{id}` |
|
|
99
|
+
| `renameConversation(id, title)` | `PUT {base}/conversations/{id}/title`, the new title in the body |
|
|
92
100
|
| `deleteConversation(id)` | `DELETE {base}/conversations/{id}` |
|
|
93
101
|
| `rateMessage(conversationId, messageId, { rating, note })` | `PUT {base}/conversations/{conversationId}/messages/{messageId}/rating` |
|
|
94
102
|
|
|
95
|
-
|
|
103
|
+
The server must answer `GET {base}/settings`. An older server that does not answers 404, and each
|
|
104
|
+
question then fails with `assistant_outdated` ("The assistant needs an update before it can answer. Please try again later.").
|
|
105
|
+
|
|
106
|
+
`onEvent(name, data)` is called with `delta { text }`, `reset {}`, `tool {}` and `actions { actions }` as they
|
|
96
107
|
arrive. `createSseParser(onEvent)` is exported too, for reading the same stream elsewhere. The
|
|
97
108
|
server contract (refusal codes, the event stream, the read endpoints) is the one
|
|
98
109
|
`@webority/chat-react` documents.
|
|
@@ -101,7 +112,9 @@ server contract (refusal codes, the event stream, the read endpoints) is the one
|
|
|
101
112
|
|
|
102
113
|
`useChat({ client, pageContext })` returns `turns` (`[{ id, question, answer, streaming, error,
|
|
103
114
|
actions, messageId, rating, ratingNote }]`, oldest first), `conversationId`, `messagesLeftToday`,
|
|
104
|
-
`streaming`, `loading`, `loadError`,
|
|
115
|
+
`streaming`, `loading`, `loadError`, `settings`, `settingsError`, `editing`, `attachments`, and
|
|
116
|
+
`submit(message)`, `stop()`, `retry(turnId)`, `regenerate(turnId)`, `startEdit(turnId)`,
|
|
117
|
+
`cancelEdit()`, `attach(files)`, `removeAttachment(key)`, `openConversation(id)`,
|
|
105
118
|
`newConversation()`, `rate(turnId, rating, note?)`, `refreshAllowance()` and `reset()`.
|
|
106
119
|
`pageContext` is read at the moment each question is sent.
|
|
107
120
|
|
|
@@ -120,10 +133,20 @@ package's, so a product passes one label set to both; `composerHint` is not show
|
|
|
120
133
|
`title` (default "Assistant"), `headerActions` (before New chat, e.g. "All chats"), `empty`
|
|
121
134
|
(shown before the first question), `disclaimer` (null hides it), `maxLength` (default 4000),
|
|
122
135
|
`allowanceThreshold` (show the questions left at this many or fewer, default 10), `rating`
|
|
123
|
-
(default true), `resolveLink`, `onLinkPress`, `confirmAction`, `onViewTicket`, `
|
|
136
|
+
(default true), `resolveLink`, `onLinkPress`, `confirmAction`, `onViewTicket`, `pickAttachments`,
|
|
137
|
+
`onOpenAttachment`, `onAskSuggestion(text)` (sends a suggested follow-up question under the last
|
|
138
|
+
settled answer), `isCitation(inner)` and `onOpenCitation(citation)` (a run of the reply that
|
|
139
|
+
`isCitation` accepts draws as an inline pressable text run, not a chip, and pressing it calls
|
|
140
|
+
`onOpenCitation`), `renderReply`,
|
|
124
141
|
`keyboardOffset`.
|
|
125
142
|
New chat is disabled until there is something to clear; the question box is disabled with no
|
|
126
143
|
questions left, and the thread follows the newest text while an answer streams.
|
|
144
|
+
The five controls: Stop ends an answer while it streams and marks its turn stopped;
|
|
145
|
+
Try again sends a stopped or failed question again; New answer asks for another reply to the last
|
|
146
|
+
answered turn; Edit puts a question back in the box to change and resend; Attach a file adds files
|
|
147
|
+
to the next question. Attach a file shows only when `pickAttachments` is given and the server's
|
|
148
|
+
settings allow attachments; `pickAttachments` resolves to the files the person picked, and
|
|
149
|
+
`onOpenAttachment(attachment)` opens one shown in a message.
|
|
127
150
|
- **`ChatThread`**, **`ChatMessage`**, **`ChatComposer`**: its parts, built on mobile-ui's
|
|
128
151
|
`MessageList`, `MessageBubble`, `TypingIndicator` and `Composer`, for an app that lays out its
|
|
129
152
|
own chat. The thread and the composer handle the keyboard themselves; pass
|
|
@@ -148,6 +171,15 @@ package's, so a product passes one label set to both; `composerHint` is not show
|
|
|
148
171
|
`bottomOffset` to clear a tab bar, `compact`). Most apps open the chat from a header action or a
|
|
149
172
|
Help row instead.
|
|
150
173
|
|
|
174
|
+
The labels the new parts read, all keys of `DEFAULT_CHAT_LABELS`: `copy` and `copied` (the reply's
|
|
175
|
+
Copy action and its confirmation); `toolStep(toolName)` (the waiting line while the assistant runs a
|
|
176
|
+
tool; it receives the server's tool name and defaults to "Looking this up", so the app maps each
|
|
177
|
+
tool to the person's words); `suggestions` (the heading over suggested questions); `renameConversation`, `conversationTitle`,
|
|
178
|
+
`renameSave` and `renameFailed` (the rename dialog in `ChatConversationList`).
|
|
179
|
+
|
|
180
|
+
`ChatConversationList` pages by `page` and `pageSize` (default 20) and renames a chat in place
|
|
181
|
+
through `renameConversation`.
|
|
182
|
+
|
|
151
183
|
`renderReply(turn, { streaming })` on `ChatScreen`, `ChatThread` or `ChatMessage` draws each
|
|
152
184
|
assistant reply your way (charts, maths); the question, thinking state, errors, action cards and
|
|
153
185
|
rating stay the library's.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ActionCard=void 0;var _mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ActionCard=void 0;var _chatCore=require("@webority/chat-core"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),_jsxRuntime=require("react/jsx-runtime");const titleOf=(e,i)=>"Reply"===e.kind?i.actionReply(e.ticketNumber??""):"Reopen"===e.kind?i.actionReopen(e.ticketNumber??""):i.actionRaiseTicket,doneText=(e,i,t)=>"Reply"===e.kind?t.actionDoneReply(i):"Reopen"===e.kind?t.actionDoneReopen(i):t.actionDoneRaiseTicket(i),ActionCard=({action:e,confirmAction:i,onViewTicket:t,labels:n,testID:s="chat-action"})=>{const o=(0,_chatCore.mergeLabels)(n),a=(0,_mobileUi.useTheme)(),[r,c]=(0,_react.useState)("ready"),[l,d]=(0,_react.useState)(null),[m,x]=(0,_react.useState)("");if("dismissed"===r)return(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"secondary",testID:s,children:o.actionDismissed});if("done"===r&&l)return(0,_jsxRuntime.jsx)(_mobileUi.Banner,{tone:"success",message:doneText(e,l.number,o),actions:t?[{label:o.viewTicket,onPress:()=>t(l)}]:void 0,testID:s});const u="sending"===r,_=new Date(e.expiresDateTimeUtc).getTime()<=Date.now(),b="RaiseTicket"===e.kind?[e.category,e.subject].filter(Boolean).join(", "):"";return(0,_jsxRuntime.jsx)(_mobileUi.Card,{variant:"outline",padding:"sm",testID:s,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{gap:a.space.sm},children:[(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"label",children:titleOf(e,o)}),""!==b&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"secondary",children:b}),"Reopen"!==e.kind&&e.body?(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",children:e.body}):null,_?(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"secondary",children:o.actionExpired}):(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:"secondary",children:o.actionNote}),""!==m&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:m}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flexDirection:"row",flexWrap:"wrap",gap:a.space.sm},children:[(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:o.actionConfirm,size:"sm",loading:u,disabled:u,onPress:()=>{(async()=>{c("sending"),x("");try{d(await i(e.token)),c("done")}catch(e){const i=e?.message;x("string"==typeof i&&i?i:o.actionFailed),c("ready")}})()},testID:`${s}-confirm`}),(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:o.actionDismiss,size:"sm",variant:"outline",disabled:u,onPress:()=>c("dismissed"),testID:`${s}-dismiss`})]})]})]})})};exports.ActionCard=ActionCard;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatComposer=void 0;var _mobileUi=require("@webority/mobile-ui"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatComposer=void 0;var _chatCore=require("@webority/chat-core"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_ComposerAttachments=require("./ComposerAttachments.js"),_jsxRuntime=require("react/jsx-runtime");const ChatComposer=({onSubmit:e,busy:t=!1,onStop:s,disabled:a=!1,maxLength:o=4e3,above:n,below:i,keyboardAware:r,keyboardOffset:c,safeArea:l,attachments:m=[],onAttach:d,onRemoveAttachment:b,editing:u,onCancelEdit:h,labels:p,testID:x="chat-composer"})=>{const _=(0,_chatCore.mergeLabels)(p),C=m.some(e=>"Uploading"===e.status),j=m.some(e=>"Ready"===e.status),[g,v]=(0,_react.useState)("");(0,_react.useEffect)(()=>{v(u?u.text:"")},[u]);const y=u?(0,_jsxRuntime.jsx)(_mobileUi.Banner,{message:_.editing,accessibilityRole:"summary",actions:h?[{label:_.cancel,onPress:h,testID:`${x}-cancel-edit`}]:void 0,testID:`${x}-editing`}):null,R=m.length>0?(0,_jsxRuntime.jsx)(_ComposerAttachments.ComposerAttachments,{attachments:m,onRemove:b,labels:p,testID:`${x}-attachments`}):null,A=y||R||n?(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[y,R,n]}):void 0,f=d?(0,_jsxRuntime.jsx)(_mobileUi.IconButton,{icon:"paperclip",accessibilityLabel:_.attach,variant:"ghost",tone:"neutral",disabled:a||t,onPress:d,testID:`${x}-attach`}):void 0;return(0,_jsxRuntime.jsx)(_mobileUi.Composer,{onSend:e,value:g,onChangeText:v,loading:t,onStop:s,stopLabel:_.stop,disabled:a,maxLength:o,canSend:!C&&(!!j||void 0),placeholder:_.placeholder,accessibilityLabel:_.composer,labels:{send:_.send},leading:f,above:A,below:i,keyboardAware:r,keyboardOffset:c,safeArea:l,testID:x})};exports.ChatComposer=ChatComposer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatConversationList=void 0;var _mobileCore=require("@webority/mobile-core"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatConversationList=void 0;var _chatCore=require("@webority/chat-core"),_mobileCore=require("@webority/mobile-core"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),_jsxRuntime=require("react/jsx-runtime");const messageOf=(e,t)=>{const i=e?.message;return"string"==typeof i&&i?i:t},IDLE_STATE={items:[],totalCount:null,loading:!0,error:null,hasMore:!1},IDLE={getState:()=>IDLE_STATE,subscribe:()=>()=>{}},ChatConversationList=({client:e,onOpen:t,onDeleted:i,pageSize:s=20,labels:n,style:a,testID:r="chat-conversations"})=>{const l=(0,_chatCore.mergeLabels)(n),o=(0,_mobileUi.useTheme)(),[c,m]=(0,_react.useState)(null),u=c??IDLE,{items:d,loading:_,error:b,hasMore:x}=(0,_react.useSyncExternalStore)(u.subscribe,u.getState),[g,j]=(0,_react.useState)(!1),[h,p]=(0,_react.useState)(null),[v,y]=(0,_react.useState)(!1),[C,S]=(0,_react.useState)(""),[f,I]=(0,_react.useState)(null),[R,D]=(0,_react.useState)(""),[U,L]=(0,_react.useState)(!1),[T,E]=(0,_react.useState)(""),[w,$]=(0,_react.useState)(void 0),[P,O]=(0,_react.useState)("");(0,_react.useEffect)(()=>{const t=(0,_chatCore.createConversationList)({client:e,pageSize:s});return m(t),t.load(),()=>t.dispose()},[e,s]),(0,_react.useEffect)(()=>{let t=!0;return e.getSettings().then(e=>{t&&$(e.titleMaxLength)},e=>{t&&O(messageOf(e,l.renameFailed))}),()=>{t=!1}},[e,l.renameFailed]);const M=R.trim(),save=async()=>{if(f&&""!==M){L(!0),E("");try{await(c?.rename(f.publicId,M)),I(null)}catch(e){E(messageOf(e,l.renameFailed))}finally{L(!1)}}},q=!_&&!b&&0===d.length;return(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{style:a,contentContainerStyle:{padding:o.space.md,gap:o.space.sm,flexGrow:1},refreshControl:(0,_jsxRuntime.jsx)(_reactNative.RefreshControl,{refreshing:g,onRefresh:()=>{(async()=>{j(!0),await(c?.load()),j(!1)})()}}),accessibilityLabel:l.conversations,testID:r,children:[b&&(0,_jsxRuntime.jsx)(_mobileUi.Banner,{tone:"danger",message:b.message||l.loadFailed,actions:[{label:l.retry,onPress:()=>{c?.load()}}],testID:`${r}-error`}),q&&(0,_jsxRuntime.jsx)(_mobileUi.EmptyState,{size:"sm",title:l.conversationsEmptyTitle,description:l.conversationsEmptyText,testID:`${r}-empty`}),d.map(e=>(0,_jsxRuntime.jsx)(_mobileUi.Card,{variant:"outline",padding:"sm",onPress:()=>t(e),accessibilityLabel:e.title||l.untitled,testID:`${r}-item-${e.publicId}`,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flexDirection:"row",alignItems:"center",gap:o.space.sm},children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flex:1,minWidth:0},children:[(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"label",numberOfLines:1,children:e.title||l.untitled}),(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:"secondary",children:(0,_mobileCore.formatDateTime)(e.lastMessageDateTimeUtc)})]}),(0,_jsxRuntime.jsx)(_mobileUi.IconButton,{icon:"edit",variant:"ghost",accessibilityLabel:l.renameConversation,onPress:()=>{E(""),D(e.title??""),I(e)},testID:`${r}-rename-${e.publicId}`}),(0,_jsxRuntime.jsx)(_mobileUi.IconButton,{icon:"trash",tone:"danger",variant:"ghost",accessibilityLabel:l.deleteConversation,onPress:()=>{S(""),p(e)},testID:`${r}-delete-${e.publicId}`})]})},e.publicId)),_&&!g&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{gap:o.space.sm},accessibilityElementsHidden:!0,children:[(0,_jsxRuntime.jsx)(_mobileUi.Skeleton,{height:56}),(0,_jsxRuntime.jsx)(_mobileUi.Skeleton,{height:56}),(0,_jsxRuntime.jsx)(_mobileUi.Skeleton,{height:56})]}),!_&&x&&(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:l.loadMore,variant:"outline",onPress:()=>{c?.loadMore()},testID:`${r}-more`}),(0,_jsxRuntime.jsxs)(_mobileUi.Dialog,{visible:null!==f,onClose:()=>{U||I(null)},title:l.renameConversation,dismissOnAction:!1,actions:[{label:l.cancel,tone:"neutral",disabled:U,onPress:()=>I(null)},{label:l.renameSave,disabled:""===M||U,loading:U,onPress:()=>{save()}}],testID:`${r}-rename`,children:[(0,_jsxRuntime.jsx)(_mobileUi.Input,{label:l.conversationTitle,value:R,onChangeText:D,maxLength:w,returnKeyType:"done",onSubmitEditing:()=>{save()},testID:`${r}-rename-input`}),""!==(T||P)&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:"danger",testID:`${r}-rename-error`,children:T||P})]}),(0,_jsxRuntime.jsx)(_mobileUi.Dialog,{visible:null!==h,onClose:()=>{v||p(null)},tone:"warning",title:l.deleteConfirmTitle,message:C||l.deleteConfirmMessage,dismissOnAction:!1,actions:[{label:l.cancel,tone:"neutral",disabled:v,onPress:()=>p(null)},{label:l.deleteConfirm,tone:"danger",loading:v,onPress:()=>{(async()=>{if(h){y(!0),S("");try{await(c?.remove(h.publicId)),i?.(h.publicId),p(null)}catch(e){S(messageOf(e,l.deleteFailed))}finally{y(!1)}}})()}}],testID:`${r}-confirm`})]})};exports.ChatConversationList=ChatConversationList;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatLauncher=void 0;var
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatLauncher=void 0;var _chatCore=require("@webority/chat-core"),_mobileUi=require("@webority/mobile-ui"),_jsxRuntime=require("react/jsx-runtime");const ChatLauncher=({onPress:e,position:t="end",bottomOffset:o,compact:r=!1,labels:i,testID:s="chat-launcher"})=>{const a=(0,_chatCore.mergeLabels)(i);return(0,_jsxRuntime.jsx)(_mobileUi.FloatingActionButton,{icon:"messages",label:r?void 0:a.launcher,accessibilityLabel:a.launcher,position:"end"===t?"bottomRight":"bottomLeft",bottomOffset:o,onPress:e,testID:s})};exports.ChatLauncher=ChatLauncher;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatMarkdown=ChatMarkdown;var _mobileUi=require("@webority/mobile-ui"),_jsxRuntime=require("react/jsx-runtime");function ChatMarkdown({text:e,resolveLink:
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatMarkdown=ChatMarkdown;var _mobileUi=require("@webority/mobile-ui"),_jsxRuntime=require("react/jsx-runtime");function ChatMarkdown({text:e,resolveLink:i,onLinkPress:t,isCitation:n,onOpenCitation:r,testID:o}){return(0,_jsxRuntime.jsx)(_mobileUi.Markdown,{links:"app",headings:"text",resolveLink:i,onAppLinkPress:t,isCitation:n,onOpenCitation:r,testID:o,children:e})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatMessage=void 0;var _markdownCore=require("@webority/markdown-core"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatMessage=void 0;var _chatCore=require("@webority/chat-core"),_markdownCore=require("@webority/markdown-core"),_clipboard=require("@webority/mobile-core/clipboard"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),_ActionCard=require("./ActionCard.js"),_ChatMarkdown=require("./ChatMarkdown.js"),_ReplyRating=require("./ReplyRating.js"),_jsxRuntime=require("react/jsx-runtime");function ChatMessageView({turn:e,canRegenerate:t=!1,onRetry:i,onRegenerate:s,onEdit:n,onOpenAttachment:a,onRate:r,resolveLink:o,onLinkPress:l,isCitation:c,onOpenCitation:m,onAskSuggestion:u,confirmAction:x,onViewTicket:_,renderReply:p,labels:g,testID:d="chat-message"}){const b=(0,_chatCore.mergeLabels)(g),j=(0,_mobileUi.useTheme)(),[w,R]=(0,_react.useState)(!1),h=(0,_react.useRef)(null);(0,_react.useEffect)(()=>()=>{null!==h.current&&clearTimeout(h.current)},[]);const y=e.streaming&&!e.answer,k=(0,_react.useMemo)(()=>e.streaming?e.answer:(0,_markdownCore.markdownToPlainText)(e.answer),[e.streaming,e.answer]),C=(0,_react.useMemo)(()=>({you:b.you}),[b.you]),v=!e.streaming&&(e.stopped||null!==e.error),I=!e.streaming&&null!==e.questionId,T=e.attachments.length>0||e.stopped||i&&v||n&&I?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{gap:j.space.xs},children:[e.attachments.length>0?(0,_jsxRuntime.jsx)(_reactNative.View,{style:{flexDirection:"row",flexWrap:"wrap",gap:j.space.xs},children:e.attachments.map(e=>(0,_jsxRuntime.jsx)(_mobileUi.Chip,{label:e.fileName,onPress:a?()=>a(e):void 0,testID:`${d}-attachment-${e.publicId}`},e.publicId))}):null,e.stopped?(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"secondary",accessibilityLiveRegion:"polite",testID:`${d}-stopped`,children:b.stopped}):null,i&&v||n&&I?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flexDirection:"row",flexWrap:"wrap",gap:j.space.xs},children:[i&&v?(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:b.retry,variant:"link",size:"sm",onPress:()=>i(e.id),testID:`${d}-retry`}):null,n&&I?(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:b.edit,variant:"link",size:"sm",onPress:()=>n(e.id),testID:`${d}-edit`}):null]}):null]}):null;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{gap:j.space.sm},testID:d,children:[""!==e.question&&(0,_jsxRuntime.jsx)(_mobileUi.MessageBubble,{side:"mine",text:e.question,labels:C,footer:T,testID:`${d}-question`}),y?(0,_jsxRuntime.jsx)(_mobileUi.TypingIndicator,{label:b.thinking,testID:`${d}-thinking`}):null,""!==e.answer?(0,_jsxRuntime.jsx)(_mobileUi.MessageBubble,{side:"theirs",author:b.assistant,text:k,streaming:e.streaming,onCopy:()=>{(0,_clipboard.copyText)((0,_markdownCore.markdownToPlainText)(e.answer))},testID:`${d}-answer`,children:p?p(e,{streaming:e.streaming}):(0,_jsxRuntime.jsx)(_ChatMarkdown.ChatMarkdown,{text:e.answer,resolveLink:o,onLinkPress:l,isCitation:c,onOpenCitation:m})}):null,e.streaming&&e.step?(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:"secondary",accessibilityLiveRegion:"polite",testID:`${d}-step`,children:b.toolStep(e.step)}):null,e.streaming||""===e.answer?null:(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:w?b.copied:b.copy,variant:"link",size:"sm",onPress:()=>{(async()=>{await(0,_clipboard.copyText)((0,_markdownCore.markdownToPlainText)(e.answer))&&(R(!0),null!==h.current&&clearTimeout(h.current),h.current=setTimeout(()=>R(!1),2e3))})()},testID:`${d}-copy`}),u&&!e.streaming&&e.suggestions.length>0?(0,_jsxRuntime.jsx)(_reactNative.View,{accessibilityRole:"list",accessibilityLabel:b.suggestions,style:{flexDirection:"row",flexWrap:"wrap",gap:j.space.xs},children:e.suggestions.map((e,t)=>(0,_jsxRuntime.jsx)(_mobileUi.Chip,{label:e,onPress:()=>u(e),testID:`${d}-suggestion-${t}`},e))}):null,t&&s&&!e.streaming&&""!==e.answer?(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:b.regenerate,variant:"link",size:"sm",onPress:()=>s(e.id),testID:`${d}-regenerate`}):null,e.error&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:e.error.message}),x&&!e.streaming&&e.actions.map(e=>(0,_jsxRuntime.jsx)(_ActionCard.ActionCard,{action:e,confirmAction:x,onViewTicket:_,labels:g},e.token)),r&&e.messageId&&!e.streaming&&(0,_jsxRuntime.jsx)(_ReplyRating.ReplyRating,{rating:e.rating,onRate:(t,i)=>r(e.id,t,i),labels:g})]})}const ChatMessage=exports.ChatMessage=(0,_react.memo)(ChatMessageView);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatScreen=ChatScreen;var
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatScreen=ChatScreen;var _chatCore=require("@webority/chat-core"),_mobileUi=require("@webority/mobile-ui"),_reactNative=require("react-native"),_ChatComposer=require("./ChatComposer.js"),_ChatThread=require("./ChatThread.js"),_jsxRuntime=require("react/jsx-runtime");function ChatScreen({chat:e,pickAttachments:t,onOpenAttachment:s,title:i,headerActions:a,empty:r,disclaimer:n,maxLength:o=4e3,allowanceThreshold:l=10,rating:m=!0,keyboardOffset:c,testID:d="chat-screen",...h}){const u=(0,_chatCore.mergeLabels)(h.labels),x=(0,_mobileUi.useTheme)(),b=e.messagesLeftToday,g=void 0===n?u.disclaimer:n,_=t&&e.settings?.attachments?async()=>e.attach(await t()):void 0;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flex:1,backgroundColor:x.colors.bg},testID:d,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flexDirection:"row",alignItems:"center",gap:x.space.sm,paddingHorizontal:x.space.md,paddingVertical:x.space.sm,borderBottomWidth:1,borderBottomColor:x.colors["border-subtle"]},children:[(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"title",accessibilityRole:"header",style:{flex:1},numberOfLines:1,children:i??u.panelTitle}),a,(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:u.newChat,size:"sm",variant:"soft",leftIcon:"add",disabled:0===e.turns.length&&!e.loading,onPress:e.newConversation,testID:`${d}-new`})]}),e.loading?(0,_jsxRuntime.jsx)(_reactNative.View,{style:{flex:1,alignItems:"center",justifyContent:"center"},children:(0,_jsxRuntime.jsx)(_mobileUi.Spinner,{message:u.loadingConversation,testID:`${d}-loading`})}):(0,_jsxRuntime.jsx)(_ChatThread.ChatThread,{turns:e.turns,style:{flex:1},keyboardOffset:c,onRate:m?e.rate:void 0,onRetry:e.retry,onRegenerate:e.regenerate,onEdit:e.startEdit,onOpenAttachment:s,empty:r??(0,_jsxRuntime.jsx)(_mobileUi.EmptyState,{fill:!0,size:"sm",title:u.emptyTitle,description:u.emptyText,testID:`${d}-empty`}),testID:`${d}-thread`,...h,onAskSuggestion:e.submit}),(0,_jsxRuntime.jsx)(_ChatComposer.ChatComposer,{onSubmit:t=>{e.submit(t)},busy:e.streaming,onStop:e.stop,disabled:0===b||e.loading,maxLength:o,keyboardOffset:c,labels:h.labels,onAttach:_,attachments:e.attachments,onRemoveAttachment:t=>{e.removeAttachment(t)},editing:e.editing,onCancelEdit:e.cancelEdit,testID:`${d}-composer`,above:(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[e.loadError&&(0,_jsxRuntime.jsx)(_mobileUi.Banner,{tone:"danger",message:e.loadError.message,testID:`${d}-load-error`}),e.settingsError&&(0,_jsxRuntime.jsx)(_mobileUi.Banner,{tone:"danger",message:e.settingsError.message,testID:`${d}-settings-error`}),null!==b&&b<=l&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:0===b?"danger":"secondary",accessibilityLiveRegion:"polite",testID:`${d}-allowance`,children:u.allowance(b)})]}),below:g?(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:"tertiary",testID:`${d}-disclaimer`,children:g}):null})]})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatThread=ChatThread;var _mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatThread=ChatThread;var _chatCore=require("@webority/chat-core"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),_ChatMessage=require("./ChatMessage.js"),_jsxRuntime=require("react/jsx-runtime");const turnKey=e=>e.id,followTurn=()=>!0,TurnGap=()=>{const e=(0,_mobileUi.useTheme)();return(0,_jsxRuntime.jsx)(_reactNative.View,{style:{height:e.space.lg}})};function ChatThread({turns:e,empty:t,keyboardAware:r,keyboardOffset:a,onRetry:s,onRegenerate:n,onEdit:i,onOpenAttachment:o,onAskSuggestion:u,style:c,testID:l="chat-thread",...d}){const h=(0,_chatCore.mergeLabels)(d.labels),m=(0,_react.useMemo)(()=>[...e].reverse(),[e]),g=(0,_react.useMemo)(()=>{const t=e[e.length-1];return t&&null!==t.messageId&&!t.streaming?t.id:null},[e]),y=e[e.length-1]?.id;return(0,_jsxRuntime.jsx)(_mobileUi.MessageList,{messages:m,keyExtractor:turnKey,renderMessage:({item:e})=>(0,_jsxRuntime.jsx)(_ChatMessage.ChatMessage,{turn:e,onRetry:s,canRegenerate:e.id===g,onRegenerate:e.id===g?n:void 0,onEdit:i,onOpenAttachment:o,testID:`${l}-${e.id}`,...d,onAskSuggestion:e.id===y?u:void 0}),followNew:followTurn,empty:t,ItemSeparatorComponent:TurnGap,keyboardAware:r,keyboardOffset:a,accessibilityLabel:h.thread,style:c,testID:l})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ComposerAttachments=void 0;var _chatCore=require("@webority/chat-core"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),_jsxRuntime=require("react/jsx-runtime");const ComposerAttachments=({attachments:e,onRemove:t,labels:r,testID:s="composer-attachments"})=>{const a=(0,_mobileUi.useTheme)(),i=(0,_react.useMemo)(()=>buildStyles(a),[a]),o=(0,_chatCore.mergeLabels)(r),c=(0,_react.useMemo)(()=>({remove:o.removeAttachment}),[o.removeAttachment]);return(0,_jsxRuntime.jsx)(_reactNative.View,{style:i.root,testID:s,children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:i.row,children:e.map(e=>(0,_jsxRuntime.jsxs)(_reactNative.View,{style:i.item,children:[(0,_jsxRuntime.jsx)(_mobileUi.Chip,{label:e.fileName,variant:"soft",onRemove:t?()=>t(e.key):void 0,labels:c,removeTestID:`chat-attachment-remove-${e.key}`,testID:`${s}-${e.key}`}),"Uploading"===e.status?(0,_jsxRuntime.jsx)(_mobileUi.ProgressBar,{progress:e.progress??void 0,label:o.attachmentUploading,height:4,containerStyle:i.progress}):null,"Failed"===e.status?(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:"danger",accessibilityLiveRegion:"polite",children:o.attachmentFailed}):null]},e.key))})})};exports.ComposerAttachments=ComposerAttachments;const buildStyles=e=>_reactNative.StyleSheet.create({root:{gap:e.space.xs},row:{flexDirection:"row",flexWrap:"wrap",gap:e.space.xs},item:{gap:e.space.xxs,maxWidth:"100%"},progress:{minWidth:120}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ReplyRating=void 0;var _mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ReplyRating=void 0;var _chatCore=require("@webority/chat-core"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),_jsxRuntime=require("react/jsx-runtime");const ReplyRating=({rating:e=null,onRate:t,noteMaxLength:i=1e3,labels:a,testID:s="chat-rating"})=>{const n=(0,_chatCore.mergeLabels)(a),r=(0,_mobileUi.useTheme)(),[l,o]=(0,_react.useState)(!1),[c,d]=(0,_react.useState)(!1),[u,x]=(0,_react.useState)(""),[m,_]=(0,_react.useState)(""),[b,p]=(0,_react.useState)(!1),save=async(e,i)=>{o(!0),_("");try{await t(e,i),d("Down"===e&&void 0===i),p("Up"===e||void 0!==i),void 0!==i&&x("")}catch{_(n.ratingFailed)}finally{o(!1)}};return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{gap:r.space.sm},testID:s,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flexDirection:"row",flexWrap:"wrap",alignItems:"center",gap:r.space.xs},children:[(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:n.rateUp,size:"sm",leftIcon:"like",variant:"Up"===e?"soft":"ghost",accessibilityState:{selected:"Up"===e,disabled:l},"aria-selected":"Up"===e,"aria-disabled":l,disabled:l,onPress:()=>{save("Up")},testID:`${s}-up`}),(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:n.rateDown,size:"sm",leftIcon:"dislike",variant:"Down"===e?"soft":"ghost",accessibilityState:{selected:"Down"===e,disabled:l},"aria-selected":"Down"===e,"aria-disabled":l,disabled:l,onPress:()=>{save("Down")},testID:`${s}-down`}),b&&!c&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"caption",color:"secondary",accessibilityLiveRegion:"polite",children:n.rated})]}),""!==m&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:m}),c&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{gap:r.space.sm},children:[(0,_jsxRuntime.jsx)(_mobileUi.Input,{label:n.ratingNote,helperText:n.ratingNoteHint,multiline:!0,maxLength:i,value:u,onChangeText:x,testID:`${s}-note`}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flexDirection:"row",gap:r.space.sm},children:[(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:n.ratingNoteSend,size:"sm",loading:l,disabled:l,onPress:()=>{save("Down",u)},testID:`${s}-note-send`}),(0,_jsxRuntime.jsx)(_mobileUi.Button,{label:n.ratingNoteSkip,size:"sm",variant:"outline",disabled:l,onPress:()=>{d(!1),p(!0)},testID:`${s}-note-skip`})]})]})]})};exports.ReplyRating=ReplyRating;
|
package/lib/commonjs/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"ActionCard",{enumerable:!0,get:function(){return _ActionCard.ActionCard}}),Object.defineProperty(exports,"ChatApiError",{enumerable:!0,get:function(){return
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"ActionCard",{enumerable:!0,get:function(){return _ActionCard.ActionCard}}),Object.defineProperty(exports,"ChatApiError",{enumerable:!0,get:function(){return _chatCore.ChatApiError}}),Object.defineProperty(exports,"ChatComposer",{enumerable:!0,get:function(){return _ChatComposer.ChatComposer}}),Object.defineProperty(exports,"ChatConversationList",{enumerable:!0,get:function(){return _ChatConversationList.ChatConversationList}}),Object.defineProperty(exports,"ChatLauncher",{enumerable:!0,get:function(){return _ChatLauncher.ChatLauncher}}),Object.defineProperty(exports,"ChatMarkdown",{enumerable:!0,get:function(){return _ChatMarkdown.ChatMarkdown}}),Object.defineProperty(exports,"ChatMessage",{enumerable:!0,get:function(){return _ChatMessage.ChatMessage}}),Object.defineProperty(exports,"ChatScreen",{enumerable:!0,get:function(){return _ChatScreen.ChatScreen}}),Object.defineProperty(exports,"ChatThread",{enumerable:!0,get:function(){return _ChatThread.ChatThread}}),Object.defineProperty(exports,"DEFAULT_CHAT_LABELS",{enumerable:!0,get:function(){return _chatCore.DEFAULT_CHAT_LABELS}}),Object.defineProperty(exports,"ReplyRating",{enumerable:!0,get:function(){return _ReplyRating.ReplyRating}}),Object.defineProperty(exports,"createChatClient",{enumerable:!0,get:function(){return _chatCore.createChatClient}}),Object.defineProperty(exports,"createChatSession",{enumerable:!0,get:function(){return _chatCore.createChatSession}}),Object.defineProperty(exports,"createConversationList",{enumerable:!0,get:function(){return _chatCore.createConversationList}}),Object.defineProperty(exports,"createSseParser",{enumerable:!0,get:function(){return _chatCore.createSseParser}}),Object.defineProperty(exports,"useChat",{enumerable:!0,get:function(){return _useChat.useChat}});var _chatCore=require("@webority/chat-core"),_ActionCard=require("./components/ActionCard.js"),_ChatComposer=require("./components/ChatComposer.js"),_ChatConversationList=require("./components/ChatConversationList.js"),_ChatLauncher=require("./components/ChatLauncher.js"),_ChatMarkdown=require("./components/ChatMarkdown.js"),_ChatMessage=require("./components/ChatMessage.js"),_ChatScreen=require("./components/ChatScreen.js"),_ChatThread=require("./components/ChatThread.js"),_ReplyRating=require("./components/ReplyRating.js"),_useChat=require("./useChat.js");
|
package/lib/commonjs/useChat.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.useChat=void 0;var _react=require("react");const
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.useChat=void 0;var _chatCore=require("@webority/chat-core"),_react=require("react");const requestFrame=e=>{const t=requestAnimationFrame(e);return()=>cancelAnimationFrame(t)},useChat=({client:e,pageContext:t})=>{const r=(0,_react.useRef)(t);r.current=t;const a=(0,_react.useMemo)(()=>(0,_chatCore.createChatSession)({client:e,pageContext:()=>r.current,schedule:requestFrame}),[e]);(0,_react.useEffect)(()=>()=>a.dispose(),[a]);return{...(0,_react.useSyncExternalStore)(a.subscribe,a.getState),...(0,_react.useMemo)(()=>({submit:e=>a.submit(e),stop:()=>a.stop(),retry:e=>a.retry(e),regenerate:e=>a.regenerate(e),startEdit:e=>a.startEdit(e),cancelEdit:()=>a.cancelEdit(),attach:e=>a.attach(e),removeAttachment:e=>a.removeAttachment(e),openConversation:e=>a.openConversation(e),newConversation:()=>a.newConversation(),rate:(e,t,r)=>a.rate(e,t,r),refreshAllowance:()=>a.refreshAllowance(),reset:()=>a.reset()}),[a]),client:a.client}};exports.useChat=useChat;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{Banner,Button,Card,Text,useTheme}from"@webority/mobile-ui";import{useState}from"react";import{View}from"react-native";import{
|
|
1
|
+
"use strict";import{mergeLabels}from"@webority/chat-core";import{Banner,Button,Card,Text,useTheme}from"@webority/mobile-ui";import{useState}from"react";import{View}from"react-native";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const titleOf=(e,t)=>"Reply"===e.kind?t.actionReply(e.ticketNumber??""):"Reopen"===e.kind?t.actionReopen(e.ticketNumber??""):t.actionRaiseTicket,doneText=(e,t,i)=>"Reply"===e.kind?i.actionDoneReply(t):"Reopen"===e.kind?i.actionDoneReopen(t):i.actionDoneRaiseTicket(t);export const ActionCard=({action:e,confirmAction:t,onViewTicket:i,labels:n,testID:s="chat-action"})=>{const a=mergeLabels(n),o=useTheme(),[r,c]=useState("ready"),[l,d]=useState(null),[m,x]=useState("");if("dismissed"===r)return _jsx(Text,{variant:"bodySmall",color:"secondary",testID:s,children:a.actionDismissed});if("done"===r&&l)return _jsx(Banner,{tone:"success",message:doneText(e,l.number,a),actions:i?[{label:a.viewTicket,onPress:()=>i(l)}]:void 0,testID:s});const p="sending"===r,y=new Date(e.expiresDateTimeUtc).getTime()<=Date.now(),b="RaiseTicket"===e.kind?[e.category,e.subject].filter(Boolean).join(", "):"";return _jsx(Card,{variant:"outline",padding:"sm",testID:s,children:_jsxs(View,{style:{gap:o.space.sm},children:[_jsx(Text,{variant:"label",children:titleOf(e,a)}),""!==b&&_jsx(Text,{variant:"bodySmall",color:"secondary",children:b}),"Reopen"!==e.kind&&e.body?_jsx(Text,{variant:"bodySmall",children:e.body}):null,y?_jsx(Text,{variant:"bodySmall",color:"secondary",children:a.actionExpired}):_jsxs(_Fragment,{children:[_jsx(Text,{variant:"caption",color:"secondary",children:a.actionNote}),""!==m&&_jsx(Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:m}),_jsxs(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:o.space.sm},children:[_jsx(Button,{label:a.actionConfirm,size:"sm",loading:p,disabled:p,onPress:()=>{(async()=>{c("sending"),x("");try{d(await t(e.token)),c("done")}catch(e){const t=e?.message;x("string"==typeof t&&t?t:a.actionFailed),c("ready")}})()},testID:`${s}-confirm`}),_jsx(Button,{label:a.actionDismiss,size:"sm",variant:"outline",disabled:p,onPress:()=>c("dismissed"),testID:`${s}-dismiss`})]})]})]})})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{Composer}from"@webority/mobile-ui";import{
|
|
1
|
+
"use strict";import{mergeLabels}from"@webority/chat-core";import{Banner,Composer,IconButton}from"@webority/mobile-ui";import{useEffect,useState}from"react";import{ComposerAttachments}from"./ComposerAttachments.js";import{jsx as _jsx,Fragment as _Fragment,jsxs as _jsxs}from"react/jsx-runtime";export const ChatComposer=({onSubmit:e,busy:t=!1,onStop:s,disabled:a=!1,maxLength:o=4e3,above:n,below:r,keyboardAware:i,keyboardOffset:c,safeArea:l,attachments:m=[],onAttach:d,onRemoveAttachment:b,editing:p,onCancelEdit:h,labels:u,testID:g="chat-composer"})=>{const f=mergeLabels(u),x=m.some(e=>"Uploading"===e.status),y=m.some(e=>"Ready"===e.status),[j,v]=useState("");useEffect(()=>{v(p?p.text:"")},[p]);const A=p?_jsx(Banner,{message:f.editing,accessibilityRole:"summary",actions:h?[{label:f.cancel,onPress:h,testID:`${g}-cancel-edit`}]:void 0,testID:`${g}-editing`}):null,C=m.length>0?_jsx(ComposerAttachments,{attachments:m,onRemove:b,labels:u,testID:`${g}-attachments`}):null,_=A||C||n?_jsxs(_Fragment,{children:[A,C,n]}):void 0,I=d?_jsx(IconButton,{icon:"paperclip",accessibilityLabel:f.attach,variant:"ghost",tone:"neutral",disabled:a||t,onPress:d,testID:`${g}-attach`}):void 0;return _jsx(Composer,{onSend:e,value:j,onChangeText:v,loading:t,onStop:s,stopLabel:f.stop,disabled:a,maxLength:o,canSend:!x&&(!!y||void 0),placeholder:f.placeholder,accessibilityLabel:f.composer,labels:{send:f.send},leading:I,above:_,below:r,keyboardAware:i,keyboardOffset:c,safeArea:l,testID:g})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{formatDateTime}from"@webority/mobile-core";import{Banner,Button,Card,Dialog,EmptyState,IconButton,Skeleton,Text,useTheme}from"@webority/mobile-ui";import{
|
|
1
|
+
"use strict";import{createConversationList,mergeLabels}from"@webority/chat-core";import{formatDateTime}from"@webority/mobile-core";import{Banner,Button,Card,Dialog,EmptyState,IconButton,Input,Skeleton,Text,useTheme}from"@webority/mobile-ui";import{useEffect,useState,useSyncExternalStore}from"react";import{RefreshControl,ScrollView,View}from"react-native";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const messageOf=(e,t)=>{const s=e?.message;return"string"==typeof s&&s?s:t},IDLE_STATE={items:[],totalCount:null,loading:!0,error:null,hasMore:!1},IDLE={getState:()=>IDLE_STATE,subscribe:()=>()=>{}};export const ChatConversationList=({client:e,onOpen:t,onDeleted:s,pageSize:n=20,labels:a,style:i,testID:l="chat-conversations"})=>{const r=mergeLabels(a),o=useTheme(),[c,m]=useState(null),d=c??IDLE,{items:u,loading:g,error:b,hasMore:p}=useSyncExternalStore(d.subscribe,d.getState),[x,h]=useState(!1),[f,S]=useState(null),[y,I]=useState(!1),[j,v]=useState(""),[D,_]=useState(null),[C,T]=useState(""),[E,L]=useState(!1),[w,$]=useState(""),[P,O]=useState(void 0),[B,M]=useState("");useEffect(()=>{const t=createConversationList({client:e,pageSize:n});return m(t),t.load(),()=>t.dispose()},[e,n]),useEffect(()=>{let t=!0;return e.getSettings().then(e=>{t&&O(e.titleMaxLength)},e=>{t&&M(messageOf(e,r.renameFailed))}),()=>{t=!1}},[e,r.renameFailed]);const V=C.trim(),save=async()=>{if(D&&""!==V){L(!0),$("");try{await(c?.rename(D.publicId,V)),_(null)}catch(e){$(messageOf(e,r.renameFailed))}finally{L(!1)}}},F=!g&&!b&&0===u.length;return _jsxs(ScrollView,{style:i,contentContainerStyle:{padding:o.space.md,gap:o.space.sm,flexGrow:1},refreshControl:_jsx(RefreshControl,{refreshing:x,onRefresh:()=>{(async()=>{h(!0),await(c?.load()),h(!1)})()}}),accessibilityLabel:r.conversations,testID:l,children:[b&&_jsx(Banner,{tone:"danger",message:b.message||r.loadFailed,actions:[{label:r.retry,onPress:()=>{c?.load()}}],testID:`${l}-error`}),F&&_jsx(EmptyState,{size:"sm",title:r.conversationsEmptyTitle,description:r.conversationsEmptyText,testID:`${l}-empty`}),u.map(e=>_jsx(Card,{variant:"outline",padding:"sm",onPress:()=>t(e),accessibilityLabel:e.title||r.untitled,testID:`${l}-item-${e.publicId}`,children:_jsxs(View,{style:{flexDirection:"row",alignItems:"center",gap:o.space.sm},children:[_jsxs(View,{style:{flex:1,minWidth:0},children:[_jsx(Text,{variant:"label",numberOfLines:1,children:e.title||r.untitled}),_jsx(Text,{variant:"caption",color:"secondary",children:formatDateTime(e.lastMessageDateTimeUtc)})]}),_jsx(IconButton,{icon:"edit",variant:"ghost",accessibilityLabel:r.renameConversation,onPress:()=>{$(""),T(e.title??""),_(e)},testID:`${l}-rename-${e.publicId}`}),_jsx(IconButton,{icon:"trash",tone:"danger",variant:"ghost",accessibilityLabel:r.deleteConversation,onPress:()=>{v(""),S(e)},testID:`${l}-delete-${e.publicId}`})]})},e.publicId)),g&&!x&&_jsxs(View,{style:{gap:o.space.sm},accessibilityElementsHidden:!0,children:[_jsx(Skeleton,{height:56}),_jsx(Skeleton,{height:56}),_jsx(Skeleton,{height:56})]}),!g&&p&&_jsx(Button,{label:r.loadMore,variant:"outline",onPress:()=>{c?.loadMore()},testID:`${l}-more`}),_jsxs(Dialog,{visible:null!==D,onClose:()=>{E||_(null)},title:r.renameConversation,dismissOnAction:!1,actions:[{label:r.cancel,tone:"neutral",disabled:E,onPress:()=>_(null)},{label:r.renameSave,disabled:""===V||E,loading:E,onPress:()=>{save()}}],testID:`${l}-rename`,children:[_jsx(Input,{label:r.conversationTitle,value:C,onChangeText:T,maxLength:P,returnKeyType:"done",onSubmitEditing:()=>{save()},testID:`${l}-rename-input`}),""!==(w||B)&&_jsx(Text,{variant:"caption",color:"danger",testID:`${l}-rename-error`,children:w||B})]}),_jsx(Dialog,{visible:null!==f,onClose:()=>{y||S(null)},tone:"warning",title:r.deleteConfirmTitle,message:j||r.deleteConfirmMessage,dismissOnAction:!1,actions:[{label:r.cancel,tone:"neutral",disabled:y,onPress:()=>S(null)},{label:r.deleteConfirm,tone:"danger",loading:y,onPress:()=>{(async()=>{if(f){I(!0),v("");try{await(c?.remove(f.publicId)),s?.(f.publicId),S(null)}catch(e){v(messageOf(e,r.deleteFailed))}finally{I(!1)}}})()}}],testID:`${l}-confirm`})]})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{
|
|
1
|
+
"use strict";import{mergeLabels}from"@webority/chat-core";import{FloatingActionButton}from"@webority/mobile-ui";import{jsx as _jsx}from"react/jsx-runtime";export const ChatLauncher=({onPress:t,position:o="end",bottomOffset:e,compact:s=!1,labels:i,testID:r="chat-launcher"})=>{const n=mergeLabels(i);return _jsx(FloatingActionButton,{icon:"messages",label:s?void 0:n.launcher,accessibilityLabel:n.launcher,position:"end"===o?"bottomRight":"bottomLeft",bottomOffset:e,onPress:t,testID:r})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{Markdown}from"@webority/mobile-ui";import{jsx as _jsx}from"react/jsx-runtime";export function ChatMarkdown({text:
|
|
1
|
+
"use strict";import{Markdown}from"@webority/mobile-ui";import{jsx as _jsx}from"react/jsx-runtime";export function ChatMarkdown({text:t,resolveLink:i,onLinkPress:n,isCitation:e,onOpenCitation:o,testID:r}){return _jsx(Markdown,{links:"app",headings:"text",resolveLink:i,onAppLinkPress:n,isCitation:e,onOpenCitation:o,testID:r,children:t})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{markdownToPlainText}from"@webority/markdown-core";import{MessageBubble,Text,TypingIndicator,useTheme}from"@webority/mobile-ui";import{memo,useMemo}from"react";import{View}from"react-native";import{
|
|
1
|
+
"use strict";import{mergeLabels}from"@webority/chat-core";import{markdownToPlainText}from"@webority/markdown-core";import{copyText}from"@webority/mobile-core/clipboard";import{Button,Chip,MessageBubble,Text,TypingIndicator,useTheme}from"@webority/mobile-ui";import{memo,useEffect,useMemo,useRef,useState}from"react";import{View}from"react-native";import{ActionCard}from"./ActionCard.js";import{ChatMarkdown}from"./ChatMarkdown.js";import{ReplyRating}from"./ReplyRating.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";function ChatMessageView({turn:e,canRegenerate:t=!1,onRetry:s,onRegenerate:n,onEdit:i,onOpenAttachment:a,onRate:r,resolveLink:o,onLinkPress:l,isCitation:c,onOpenCitation:m,onAskSuggestion:p,confirmAction:u,onViewTicket:g,renderReply:x,labels:d,testID:w="chat-message"}){const y=mergeLabels(d),b=useTheme(),[h,j]=useState(!1),f=useRef(null);useEffect(()=>()=>{null!==f.current&&clearTimeout(f.current)},[]);const T=e.streaming&&!e.answer,k=useMemo(()=>e.streaming?e.answer:markdownToPlainText(e.answer),[e.streaming,e.answer]),_=useMemo(()=>({you:y.you}),[y.you]),I=!e.streaming&&(e.stopped||null!==e.error),R=!e.streaming&&null!==e.questionId,C=e.attachments.length>0||e.stopped||s&&I||i&&R?_jsxs(View,{style:{gap:b.space.xs},children:[e.attachments.length>0?_jsx(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:b.space.xs},children:e.attachments.map(e=>_jsx(Chip,{label:e.fileName,onPress:a?()=>a(e):void 0,testID:`${w}-attachment-${e.publicId}`},e.publicId))}):null,e.stopped?_jsx(Text,{variant:"bodySmall",color:"secondary",accessibilityLiveRegion:"polite",testID:`${w}-stopped`,children:y.stopped}):null,s&&I||i&&R?_jsxs(View,{style:{flexDirection:"row",flexWrap:"wrap",gap:b.space.xs},children:[s&&I?_jsx(Button,{label:y.retry,variant:"link",size:"sm",onPress:()=>s(e.id),testID:`${w}-retry`}):null,i&&R?_jsx(Button,{label:y.edit,variant:"link",size:"sm",onPress:()=>i(e.id),testID:`${w}-edit`}):null]}):null]}):null;return _jsxs(View,{style:{gap:b.space.sm},testID:w,children:[""!==e.question&&_jsx(MessageBubble,{side:"mine",text:e.question,labels:_,footer:C,testID:`${w}-question`}),T?_jsx(TypingIndicator,{label:y.thinking,testID:`${w}-thinking`}):null,""!==e.answer?_jsx(MessageBubble,{side:"theirs",author:y.assistant,text:k,streaming:e.streaming,onCopy:()=>{copyText(markdownToPlainText(e.answer))},testID:`${w}-answer`,children:x?x(e,{streaming:e.streaming}):_jsx(ChatMarkdown,{text:e.answer,resolveLink:o,onLinkPress:l,isCitation:c,onOpenCitation:m})}):null,e.streaming&&e.step?_jsx(Text,{variant:"caption",color:"secondary",accessibilityLiveRegion:"polite",testID:`${w}-step`,children:y.toolStep(e.step)}):null,e.streaming||""===e.answer?null:_jsx(Button,{label:h?y.copied:y.copy,variant:"link",size:"sm",onPress:()=>{(async()=>{await copyText(markdownToPlainText(e.answer))&&(j(!0),null!==f.current&&clearTimeout(f.current),f.current=setTimeout(()=>j(!1),2e3))})()},testID:`${w}-copy`}),p&&!e.streaming&&e.suggestions.length>0?_jsx(View,{accessibilityRole:"list",accessibilityLabel:y.suggestions,style:{flexDirection:"row",flexWrap:"wrap",gap:b.space.xs},children:e.suggestions.map((e,t)=>_jsx(Chip,{label:e,onPress:()=>p(e),testID:`${w}-suggestion-${t}`},e))}):null,t&&n&&!e.streaming&&""!==e.answer?_jsx(Button,{label:y.regenerate,variant:"link",size:"sm",onPress:()=>n(e.id),testID:`${w}-regenerate`}):null,e.error&&_jsx(Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:e.error.message}),u&&!e.streaming&&e.actions.map(e=>_jsx(ActionCard,{action:e,confirmAction:u,onViewTicket:g,labels:d},e.token)),r&&e.messageId&&!e.streaming&&_jsx(ReplyRating,{rating:e.rating,onRate:(t,s)=>r(e.id,t,s),labels:d})]})}export const ChatMessage=memo(ChatMessageView);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{Banner,Button,EmptyState,Spinner,Text,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{
|
|
1
|
+
"use strict";import{mergeLabels}from"@webority/chat-core";import{Banner,Button,EmptyState,Spinner,Text,useTheme}from"@webority/mobile-ui";import{View}from"react-native";import{ChatComposer}from"./ChatComposer.js";import{ChatThread}from"./ChatThread.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";export function ChatScreen({chat:e,pickAttachments:t,onOpenAttachment:s,title:a,headerActions:r,empty:n,disclaimer:o,maxLength:i=4e3,allowanceThreshold:l=10,rating:m=!0,keyboardOffset:c,testID:d="chat-screen",...g}){const h=mergeLabels(g.labels),p=useTheme(),x=e.messagesLeftToday,b=void 0===o?h.disclaimer:o,y=t&&e.settings?.attachments?async()=>e.attach(await t()):void 0;return _jsxs(View,{style:{flex:1,backgroundColor:p.colors.bg},testID:d,children:[_jsxs(View,{style:{flexDirection:"row",alignItems:"center",gap:p.space.sm,paddingHorizontal:p.space.md,paddingVertical:p.space.sm,borderBottomWidth:1,borderBottomColor:p.colors["border-subtle"]},children:[_jsx(Text,{variant:"title",accessibilityRole:"header",style:{flex:1},numberOfLines:1,children:a??h.panelTitle}),r,_jsx(Button,{label:h.newChat,size:"sm",variant:"soft",leftIcon:"add",disabled:0===e.turns.length&&!e.loading,onPress:e.newConversation,testID:`${d}-new`})]}),e.loading?_jsx(View,{style:{flex:1,alignItems:"center",justifyContent:"center"},children:_jsx(Spinner,{message:h.loadingConversation,testID:`${d}-loading`})}):_jsx(ChatThread,{turns:e.turns,style:{flex:1},keyboardOffset:c,onRate:m?e.rate:void 0,onRetry:e.retry,onRegenerate:e.regenerate,onEdit:e.startEdit,onOpenAttachment:s,empty:n??_jsx(EmptyState,{fill:!0,size:"sm",title:h.emptyTitle,description:h.emptyText,testID:`${d}-empty`}),testID:`${d}-thread`,...g,onAskSuggestion:e.submit}),_jsx(ChatComposer,{onSubmit:t=>{e.submit(t)},busy:e.streaming,onStop:e.stop,disabled:0===x||e.loading,maxLength:i,keyboardOffset:c,labels:g.labels,onAttach:y,attachments:e.attachments,onRemoveAttachment:t=>{e.removeAttachment(t)},editing:e.editing,onCancelEdit:e.cancelEdit,testID:`${d}-composer`,above:_jsxs(_Fragment,{children:[e.loadError&&_jsx(Banner,{tone:"danger",message:e.loadError.message,testID:`${d}-load-error`}),e.settingsError&&_jsx(Banner,{tone:"danger",message:e.settingsError.message,testID:`${d}-settings-error`}),null!==x&&x<=l&&_jsx(Text,{variant:"caption",color:0===x?"danger":"secondary",accessibilityLiveRegion:"polite",testID:`${d}-allowance`,children:h.allowance(x)})]}),below:b?_jsx(Text,{variant:"caption",color:"tertiary",testID:`${d}-disclaimer`,children:b}):null})]})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{MessageList,useTheme}from"@webority/mobile-ui";import{useMemo}from"react";import{View}from"react-native";import{
|
|
1
|
+
"use strict";import{mergeLabels}from"@webority/chat-core";import{MessageList,useTheme}from"@webority/mobile-ui";import{useMemo}from"react";import{View}from"react-native";import{ChatMessage}from"./ChatMessage.js";import{jsx as _jsx}from"react/jsx-runtime";const turnKey=e=>e.id,followTurn=()=>!0,TurnGap=()=>{const e=useTheme();return _jsx(View,{style:{height:e.space.lg}})};export function ChatThread({turns:e,empty:t,keyboardAware:r,keyboardOffset:s,onRetry:o,onRegenerate:n,onEdit:a,onOpenAttachment:i,onAskSuggestion:m,style:u,testID:l="chat-thread",...g}){const d=mergeLabels(g.labels),c=useMemo(()=>[...e].reverse(),[e]),h=useMemo(()=>{const t=e[e.length-1];return t&&null!==t.messageId&&!t.streaming?t.id:null},[e]),y=e[e.length-1]?.id;return _jsx(MessageList,{messages:c,keyExtractor:turnKey,renderMessage:({item:e})=>_jsx(ChatMessage,{turn:e,onRetry:o,canRegenerate:e.id===h,onRegenerate:e.id===h?n:void 0,onEdit:a,onOpenAttachment:i,testID:`${l}-${e.id}`,...g,onAskSuggestion:e.id===y?m:void 0}),followNew:followTurn,empty:t,ItemSeparatorComponent:TurnGap,keyboardAware:r,keyboardOffset:s,accessibilityLabel:d.thread,style:u,testID:l})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{mergeLabels}from"@webority/chat-core";import{Chip,ProgressBar,Text,useTheme}from"@webority/mobile-ui";import{useMemo}from"react";import{StyleSheet,View}from"react-native";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const ComposerAttachments=({attachments:e,onRemove:t,labels:s,testID:r="composer-attachments"})=>{const o=useTheme(),a=useMemo(()=>buildStyles(o),[o]),i=mergeLabels(s),m=useMemo(()=>({remove:i.removeAttachment}),[i.removeAttachment]);return _jsx(View,{style:a.root,testID:r,children:_jsx(View,{style:a.row,children:e.map(e=>_jsxs(View,{style:a.item,children:[_jsx(Chip,{label:e.fileName,variant:"soft",onRemove:t?()=>t(e.key):void 0,labels:m,removeTestID:`chat-attachment-remove-${e.key}`,testID:`${r}-${e.key}`}),"Uploading"===e.status?_jsx(ProgressBar,{progress:e.progress??void 0,label:i.attachmentUploading,height:4,containerStyle:a.progress}):null,"Failed"===e.status?_jsx(Text,{variant:"caption",color:"danger",accessibilityLiveRegion:"polite",children:i.attachmentFailed}):null]},e.key))})})};const buildStyles=e=>StyleSheet.create({root:{gap:e.space.xs},row:{flexDirection:"row",flexWrap:"wrap",gap:e.space.xs},item:{gap:e.space.xxs,maxWidth:"100%"},progress:{minWidth:120}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{Button,Input,Text,useTheme}from"@webority/mobile-ui";import{useState}from"react";import{View}from"react-native";import{
|
|
1
|
+
"use strict";import{mergeLabels}from"@webority/chat-core";import{Button,Input,Text,useTheme}from"@webority/mobile-ui";import{useState}from"react";import{View}from"react-native";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const ReplyRating=({rating:e=null,onRate:t,noteMaxLength:s=1e3,labels:a,testID:i="chat-rating"})=>{const n=mergeLabels(a),o=useTheme(),[l,r]=useState(!1),[c,d]=useState(!1),[p,x]=useState(""),[m,b]=useState(""),[g,u]=useState(!1),save=async(e,s)=>{r(!0),b("");try{await t(e,s),d("Down"===e&&void 0===s),u("Up"===e||void 0!==s),void 0!==s&&x("")}catch{b(n.ratingFailed)}finally{r(!1)}};return _jsxs(View,{style:{gap:o.space.sm},testID:i,children:[_jsxs(View,{style:{flexDirection:"row",flexWrap:"wrap",alignItems:"center",gap:o.space.xs},children:[_jsx(Button,{label:n.rateUp,size:"sm",leftIcon:"like",variant:"Up"===e?"soft":"ghost",accessibilityState:{selected:"Up"===e,disabled:l},"aria-selected":"Up"===e,"aria-disabled":l,disabled:l,onPress:()=>{save("Up")},testID:`${i}-up`}),_jsx(Button,{label:n.rateDown,size:"sm",leftIcon:"dislike",variant:"Down"===e?"soft":"ghost",accessibilityState:{selected:"Down"===e,disabled:l},"aria-selected":"Down"===e,"aria-disabled":l,disabled:l,onPress:()=>{save("Down")},testID:`${i}-down`}),g&&!c&&_jsx(Text,{variant:"caption",color:"secondary",accessibilityLiveRegion:"polite",children:n.rated})]}),""!==m&&_jsx(Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:m}),c&&_jsxs(View,{style:{gap:o.space.sm},children:[_jsx(Input,{label:n.ratingNote,helperText:n.ratingNoteHint,multiline:!0,maxLength:s,value:p,onChangeText:x,testID:`${i}-note`}),_jsxs(View,{style:{flexDirection:"row",gap:o.space.sm},children:[_jsx(Button,{label:n.ratingNoteSend,size:"sm",loading:l,disabled:l,onPress:()=>{save("Down",p)},testID:`${i}-note-send`}),_jsx(Button,{label:n.ratingNoteSkip,size:"sm",variant:"outline",disabled:l,onPress:()=>{d(!1),u(!0)},testID:`${i}-note-skip`})]})]})]})};
|
package/lib/module/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";export{ChatApiError,createChatClient}from"
|
|
1
|
+
"use strict";export{ChatApiError,createChatClient,createChatSession,createConversationList,createSseParser,DEFAULT_CHAT_LABELS}from"@webority/chat-core";export{ActionCard}from"./components/ActionCard.js";export{ChatComposer}from"./components/ChatComposer.js";export{ChatConversationList}from"./components/ChatConversationList.js";export{ChatLauncher}from"./components/ChatLauncher.js";export{ChatMarkdown}from"./components/ChatMarkdown.js";export{ChatMessage}from"./components/ChatMessage.js";export{ChatScreen}from"./components/ChatScreen.js";export{ChatThread}from"./components/ChatThread.js";export{ReplyRating}from"./components/ReplyRating.js";export{useChat}from"./useChat.js";
|
package/lib/module/useChat.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{
|
|
1
|
+
"use strict";import{createChatSession}from"@webority/chat-core";import{useEffect,useMemo,useRef,useSyncExternalStore}from"react";const requestFrame=e=>{const t=requestAnimationFrame(e);return()=>cancelAnimationFrame(t)};export const useChat=({client:e,pageContext:t})=>{const r=useRef(t);r.current=t;const n=useMemo(()=>createChatSession({client:e,pageContext:()=>r.current,schedule:requestFrame}),[e]);useEffect(()=>()=>n.dispose(),[n]);return{...useSyncExternalStore(n.subscribe,n.getState),...useMemo(()=>({submit:e=>n.submit(e),stop:()=>n.stop(),retry:e=>n.retry(e),regenerate:e=>n.regenerate(e),startEdit:e=>n.startEdit(e),cancelEdit:()=>n.cancelEdit(),attach:e=>n.attach(e),removeAttachment:e=>n.removeAttachment(e),openConversation:e=>n.openConversation(e),newConversation:()=>n.newConversation(),rate:(e,t,r)=>n.rate(e,t,r),refreshAllowance:()=>n.refreshAllowance(),reset:()=>n.reset()}),[n]),client:n.client}};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { SupportAction, SupportActionTicket } from "@webority/chat-core";
|
|
2
|
+
import { type ChatLabels } from "@webority/chat-core";
|
|
1
3
|
import type React from "react";
|
|
2
|
-
import { type ChatLabels } from "../labels";
|
|
3
|
-
import type { SupportAction, SupportActionTicket } from "../types";
|
|
4
4
|
export interface ActionCardProps {
|
|
5
5
|
action: SupportAction;
|
|
6
6
|
/**
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { type ChatEditing, type ChatLabels, type ComposerAttachment } from "@webority/chat-core";
|
|
1
2
|
import type React from "react";
|
|
2
|
-
import { type ChatLabels } from "../labels";
|
|
3
3
|
export interface ChatComposerProps {
|
|
4
4
|
/** Called with the trimmed question; the box clears once it is handed over. */
|
|
5
5
|
onSubmit: (message: string) => unknown;
|
|
6
6
|
/** An answer is arriving: the question can be typed but not sent. */
|
|
7
7
|
busy?: boolean;
|
|
8
|
+
/** While busy, the send button becomes a stop button that calls this. */
|
|
9
|
+
onStop?: () => void;
|
|
8
10
|
/** No question can be asked, e.g. none left today. */
|
|
9
11
|
disabled?: boolean;
|
|
10
12
|
/** The server's message limit. Default 4000. */
|
|
@@ -19,6 +21,15 @@ export interface ChatComposerProps {
|
|
|
19
21
|
keyboardOffset?: number;
|
|
20
22
|
/** Pads for the bottom safe area. Default true. */
|
|
21
23
|
safeArea?: boolean;
|
|
24
|
+
/** The files on the question being written. */
|
|
25
|
+
attachments?: ComposerAttachment[];
|
|
26
|
+
/** Opens the app's file picker. The attach button shows only when this is given. */
|
|
27
|
+
onAttach?: () => void;
|
|
28
|
+
/** Removes one file by its key. */
|
|
29
|
+
onRemoveAttachment?: (key: string) => void;
|
|
30
|
+
/** The question being edited; its banner's Cancel calls `onCancelEdit`. */
|
|
31
|
+
editing?: ChatEditing | null;
|
|
32
|
+
onCancelEdit?: () => void;
|
|
22
33
|
labels?: Partial<ChatLabels>;
|
|
23
34
|
testID?: string;
|
|
24
35
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
+
import type { ConversationSummary } from "@webority/chat-core";
|
|
2
|
+
import { type ChatClient, type ChatLabels } from "@webority/chat-core";
|
|
1
3
|
import type React from "react";
|
|
2
4
|
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
|
-
import type { ChatClient } from "../client";
|
|
4
|
-
import { type ChatLabels } from "../labels";
|
|
5
|
-
import type { ConversationSummary } from "../types";
|
|
6
5
|
export interface ChatConversationListProps {
|
|
7
6
|
client: ChatClient;
|
|
8
7
|
/** E.g. go to the chat and call `chat.openConversation(conversation.publicId)`. */
|
|
@@ -17,7 +16,7 @@ export interface ChatConversationListProps {
|
|
|
17
16
|
}
|
|
18
17
|
/**
|
|
19
18
|
* The person's past chats, newest first. It pages with Show more, refreshes on pull, opens one
|
|
20
|
-
* through `onOpen`, and deletes one after a confirm.
|
|
19
|
+
* through `onOpen`, renames and deletes one after a confirm.
|
|
21
20
|
*/
|
|
22
21
|
export declare const ChatConversationList: React.FC<ChatConversationListProps>;
|
|
23
22
|
//# sourceMappingURL=ChatConversationList.d.ts.map
|
|
@@ -10,8 +10,15 @@ export interface ChatMarkdownProps<T = string> {
|
|
|
10
10
|
resolveLink?: (href: string) => T | null | undefined;
|
|
11
11
|
/** Opens what `resolveLink` returned. Without it, links show as plain text. */
|
|
12
12
|
onLinkPress?: (target: T) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Tells a citation marker (the bracketed inner text, e.g. `1` for `[1]`) from an ordinary link.
|
|
15
|
+
* A citation draws as a pressable marker and never as a link.
|
|
16
|
+
*/
|
|
17
|
+
isCitation?: (inner: string) => boolean;
|
|
18
|
+
/** Opens the citation a reply marker names. Without it, citation markers show as plain text. */
|
|
19
|
+
onOpenCitation?: (citation: string) => void;
|
|
13
20
|
testID?: string;
|
|
14
21
|
}
|
|
15
22
|
/** A reply never opens a web address, and its headings draw as bold lines, not large type. */
|
|
16
|
-
export declare function ChatMarkdown<T = string>({ text, resolveLink, onLinkPress, testID }: ChatMarkdownProps<T>): React.ReactElement;
|
|
23
|
+
export declare function ChatMarkdown<T = string>({ text, resolveLink, onLinkPress, isCitation, onOpenCitation, testID, }: ChatMarkdownProps<T>): React.ReactElement;
|
|
17
24
|
//# sourceMappingURL=ChatMarkdown.d.ts.map
|