@paymanai/payman-ask-sdk 1.2.20 → 1.2.22
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/dist/index.d.mts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +17 -0
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +97 -13
- package/dist/index.native.js.map +1 -1
- package/package.json +5 -1
package/dist/index.native.js
CHANGED
|
@@ -116,7 +116,8 @@ function ChatInput({
|
|
|
116
116
|
recordingDurationSeconds = 0,
|
|
117
117
|
onConfirmRecording,
|
|
118
118
|
onCancelRecording,
|
|
119
|
-
transcribedText
|
|
119
|
+
transcribedText,
|
|
120
|
+
onInputFocus
|
|
120
121
|
}) {
|
|
121
122
|
const isInputDisabled = disabled || isWaitingForResponse;
|
|
122
123
|
const showVoiceButton = enableVoice && onVoicePress != null;
|
|
@@ -223,6 +224,7 @@ function ChatInput({
|
|
|
223
224
|
ref: inputRef,
|
|
224
225
|
value,
|
|
225
226
|
onChangeText: onChange,
|
|
227
|
+
onFocus: onInputFocus,
|
|
226
228
|
onPress: onClick,
|
|
227
229
|
editable: !isInputDisabled,
|
|
228
230
|
placeholder: getPlaceholder(),
|
|
@@ -1296,16 +1298,57 @@ function MessageList({
|
|
|
1296
1298
|
streamingStepsText,
|
|
1297
1299
|
completedStepsText,
|
|
1298
1300
|
onExecutionTraceClick,
|
|
1299
|
-
className
|
|
1301
|
+
className,
|
|
1302
|
+
isWaitingForResponse = false,
|
|
1303
|
+
scrollToEndHandleRef
|
|
1300
1304
|
}) {
|
|
1301
1305
|
const flatListRef = React.useRef(null);
|
|
1306
|
+
const messagesRef = React.useRef(messages);
|
|
1307
|
+
messagesRef.current = messages;
|
|
1308
|
+
const prevWaitingRef = React.useRef(isWaitingForResponse);
|
|
1309
|
+
const prevLastStreamingRef = React.useRef(void 0);
|
|
1310
|
+
const scrollToEnd = React.useCallback(() => {
|
|
1311
|
+
flatListRef.current?.scrollToEnd({ animated: true });
|
|
1312
|
+
}, []);
|
|
1313
|
+
const scrollToEndOnAssistantLayout = React.useCallback(() => {
|
|
1314
|
+
const list = messagesRef.current;
|
|
1315
|
+
const last = list[list.length - 1];
|
|
1316
|
+
const shouldFollow = isWaitingForResponse || last?.role === "assistant" && last.isStreaming;
|
|
1317
|
+
if (!shouldFollow) return;
|
|
1318
|
+
const run = () => flatListRef.current?.scrollToEnd({ animated: false });
|
|
1319
|
+
run();
|
|
1320
|
+
requestAnimationFrame(run);
|
|
1321
|
+
setTimeout(run, 16);
|
|
1322
|
+
setTimeout(run, 48);
|
|
1323
|
+
}, [isWaitingForResponse]);
|
|
1324
|
+
React.useEffect(() => {
|
|
1325
|
+
if (!scrollToEndHandleRef) return;
|
|
1326
|
+
scrollToEndHandleRef.current = scrollToEnd;
|
|
1327
|
+
return () => {
|
|
1328
|
+
scrollToEndHandleRef.current = null;
|
|
1329
|
+
};
|
|
1330
|
+
}, [scrollToEndHandleRef, scrollToEnd]);
|
|
1302
1331
|
React.useEffect(() => {
|
|
1303
1332
|
if (messages.length > 0) {
|
|
1304
1333
|
setTimeout(() => {
|
|
1305
|
-
|
|
1334
|
+
scrollToEnd();
|
|
1306
1335
|
}, 100);
|
|
1307
1336
|
}
|
|
1308
|
-
}, [messages.length]);
|
|
1337
|
+
}, [messages.length, scrollToEnd]);
|
|
1338
|
+
React.useEffect(() => {
|
|
1339
|
+
const last = messages[messages.length - 1];
|
|
1340
|
+
const streaming = last?.isStreaming;
|
|
1341
|
+
if (prevLastStreamingRef.current === true && streaming === false) {
|
|
1342
|
+
setTimeout(() => scrollToEnd(), 0);
|
|
1343
|
+
}
|
|
1344
|
+
prevLastStreamingRef.current = streaming;
|
|
1345
|
+
}, [messages, scrollToEnd]);
|
|
1346
|
+
React.useEffect(() => {
|
|
1347
|
+
if (prevWaitingRef.current === true && isWaitingForResponse === false) {
|
|
1348
|
+
setTimeout(() => scrollToEnd(), 50);
|
|
1349
|
+
}
|
|
1350
|
+
prevWaitingRef.current = isWaitingForResponse;
|
|
1351
|
+
}, [isWaitingForResponse, scrollToEnd]);
|
|
1309
1352
|
if (isLoading) {
|
|
1310
1353
|
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: s5.container, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: s5.skeletonContent, children: Array.from({ length: 5 }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1311
1354
|
MessageRowSkeleton,
|
|
@@ -1332,8 +1375,11 @@ function MessageList({
|
|
|
1332
1375
|
reactNative.FlatList,
|
|
1333
1376
|
{
|
|
1334
1377
|
ref: flatListRef,
|
|
1378
|
+
style: s5.list,
|
|
1335
1379
|
data: messages,
|
|
1336
1380
|
keyExtractor: (item) => item.id,
|
|
1381
|
+
keyboardShouldPersistTaps: "handled",
|
|
1382
|
+
keyboardDismissMode: "interactive",
|
|
1337
1383
|
renderItem: ({ item }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1338
1384
|
MessageRow,
|
|
1339
1385
|
{
|
|
@@ -1356,11 +1402,15 @@ function MessageList({
|
|
|
1356
1402
|
s5.listContent,
|
|
1357
1403
|
layout === "centered" && s5.listContentCentered
|
|
1358
1404
|
],
|
|
1405
|
+
ListFooterComponent: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: s5.listFooterSpacer }),
|
|
1406
|
+
onContentSizeChange: scrollToEndOnAssistantLayout,
|
|
1359
1407
|
showsVerticalScrollIndicator: false
|
|
1360
1408
|
}
|
|
1361
1409
|
);
|
|
1362
1410
|
}
|
|
1363
1411
|
var s5 = reactNative.StyleSheet.create({
|
|
1412
|
+
/** Fills space above the input so messages stay in the scroll region, not behind it. */
|
|
1413
|
+
list: { flex: 1 },
|
|
1364
1414
|
container: { flex: 1 },
|
|
1365
1415
|
skeletonContent: { padding: 16, gap: 16 },
|
|
1366
1416
|
emptyContainer: {
|
|
@@ -1393,8 +1443,17 @@ var s5 = reactNative.StyleSheet.create({
|
|
|
1393
1443
|
textAlign: "center",
|
|
1394
1444
|
lineHeight: 20
|
|
1395
1445
|
},
|
|
1396
|
-
listContent: {
|
|
1397
|
-
|
|
1446
|
+
listContent: {
|
|
1447
|
+
paddingTop: 16,
|
|
1448
|
+
paddingHorizontal: 16,
|
|
1449
|
+
paddingBottom: 16,
|
|
1450
|
+
gap: 16
|
|
1451
|
+
},
|
|
1452
|
+
listContentCentered: { maxWidth: 672, alignSelf: "center", width: "100%" },
|
|
1453
|
+
/** Extra space below last message — thinking/stream text can wrap to multiple lines before scroll runs. */
|
|
1454
|
+
listFooterSpacer: {
|
|
1455
|
+
height: reactNative.Platform.select({ ios: 52, android: 60, default: 52 })
|
|
1456
|
+
}
|
|
1398
1457
|
});
|
|
1399
1458
|
|
|
1400
1459
|
// src/assets/payman-mono-crop-blue.png
|
|
@@ -2057,6 +2116,7 @@ function PaymanChat({
|
|
|
2057
2116
|
const recordingStartRef = React.useRef(null);
|
|
2058
2117
|
const recordingIntervalRef = React.useRef(null);
|
|
2059
2118
|
const prevInputValueRef = React.useRef(inputValue);
|
|
2119
|
+
const scrollMessagesToEndRef = React.useRef(null);
|
|
2060
2120
|
const chat = paymanTypescriptAskSdk.useChat(config, callbacks);
|
|
2061
2121
|
const {
|
|
2062
2122
|
messages,
|
|
@@ -2201,6 +2261,13 @@ function PaymanChat({
|
|
|
2201
2261
|
const handleCancelRecording = React.useCallback(() => {
|
|
2202
2262
|
stopRecording();
|
|
2203
2263
|
}, [stopRecording]);
|
|
2264
|
+
const handleInputFocus = React.useCallback(() => {
|
|
2265
|
+
const run = () => scrollMessagesToEndRef.current?.();
|
|
2266
|
+
run();
|
|
2267
|
+
requestAnimationFrame(run);
|
|
2268
|
+
setTimeout(run, 100);
|
|
2269
|
+
setTimeout(run, 280);
|
|
2270
|
+
}, []);
|
|
2204
2271
|
if (isChatDisabled) {
|
|
2205
2272
|
if (disabledComponent) {
|
|
2206
2273
|
return /* @__PURE__ */ jsxRuntime.jsx(PaymanChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [s8.container, style], children: [
|
|
@@ -2217,14 +2284,15 @@ function PaymanChat({
|
|
|
2217
2284
|
reactNative.KeyboardAvoidingView,
|
|
2218
2285
|
{
|
|
2219
2286
|
style: [s8.container, style],
|
|
2220
|
-
behavior:
|
|
2287
|
+
behavior: "padding",
|
|
2221
2288
|
keyboardVerticalOffset: reactNative.Platform.OS === "ios" ? 90 : 0,
|
|
2222
2289
|
children: [
|
|
2223
2290
|
children,
|
|
2224
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2291
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: s8.messageListWrap, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2225
2292
|
MessageList,
|
|
2226
2293
|
{
|
|
2227
2294
|
messages,
|
|
2295
|
+
isWaitingForResponse,
|
|
2228
2296
|
isLoading: false,
|
|
2229
2297
|
emptyStateText,
|
|
2230
2298
|
showEmptyStateIcon,
|
|
@@ -2241,10 +2309,11 @@ function PaymanChat({
|
|
|
2241
2309
|
showStreamingDot,
|
|
2242
2310
|
streamingStepsText,
|
|
2243
2311
|
completedStepsText,
|
|
2244
|
-
onExecutionTraceClick
|
|
2312
|
+
onExecutionTraceClick,
|
|
2313
|
+
scrollToEndHandleRef: scrollMessagesToEndRef
|
|
2245
2314
|
}
|
|
2246
|
-
),
|
|
2247
|
-
hasAskPermission && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2315
|
+
) }),
|
|
2316
|
+
hasAskPermission && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: s8.inputBarWrap, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2248
2317
|
ChatInput,
|
|
2249
2318
|
{
|
|
2250
2319
|
value: inputValue,
|
|
@@ -2265,9 +2334,10 @@ function PaymanChat({
|
|
|
2265
2334
|
recordingDurationSeconds: recordingElapsedSeconds,
|
|
2266
2335
|
onConfirmRecording: enableVoice ? handleConfirmRecording : void 0,
|
|
2267
2336
|
onCancelRecording: enableVoice ? handleCancelRecording : void 0,
|
|
2268
|
-
transcribedText: enableVoice && isRecording ? transcribedText : void 0
|
|
2337
|
+
transcribedText: enableVoice && isRecording ? transcribedText : void 0,
|
|
2338
|
+
onInputFocus: handleInputFocus
|
|
2269
2339
|
}
|
|
2270
|
-
),
|
|
2340
|
+
) }),
|
|
2271
2341
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2272
2342
|
UserActionModal,
|
|
2273
2343
|
{
|
|
@@ -2284,6 +2354,20 @@ function PaymanChat({
|
|
|
2284
2354
|
) });
|
|
2285
2355
|
}
|
|
2286
2356
|
var s8 = reactNative.StyleSheet.create({
|
|
2357
|
+
/** Lets the message list shrink when the keyboard opens; pairs with FlatList flex:1. */
|
|
2358
|
+
messageListWrap: { flex: 1, minHeight: 0, zIndex: 0 },
|
|
2359
|
+
/**
|
|
2360
|
+
* Keeps the composer above the message list when scrolling so rows (e.g. stream step toggles)
|
|
2361
|
+
* do not paint over the input. Elevation applies on Android only.
|
|
2362
|
+
*/
|
|
2363
|
+
inputBarWrap: {
|
|
2364
|
+
width: "100%",
|
|
2365
|
+
zIndex: 2,
|
|
2366
|
+
...reactNative.Platform.select({
|
|
2367
|
+
android: { elevation: 8 },
|
|
2368
|
+
default: {}
|
|
2369
|
+
})
|
|
2370
|
+
},
|
|
2287
2371
|
container: {
|
|
2288
2372
|
flex: 1,
|
|
2289
2373
|
backgroundColor: "#FFFFFF",
|