@burdenoff/website-sdk 2026.829.5 → 2026.829.6
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/components/explore.js +439 -22
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +440 -23
- package/dist/components/explore.mjs.map +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +80 -7
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +80 -7
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +443 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +444 -27
- package/dist/index.mjs.map +1 -1
- package/dist/{use-explore-chat-B-E7jN1H.d.mts → use-explore-chat-BzXCz2UM.d.mts} +38 -3
- package/dist/{use-explore-chat-B-E7jN1H.d.ts → use-explore-chat-BzXCz2UM.d.ts} +38 -3
- package/package.json +1 -1
|
@@ -73,6 +73,12 @@ var EN = {
|
|
|
73
73
|
disclaimerShort: "Grounded in our docs \u2014 check anything important.",
|
|
74
74
|
dictate: "Dictate your question",
|
|
75
75
|
stopDictating: "Stop dictating",
|
|
76
|
+
attach: "Attach files",
|
|
77
|
+
attachHint: "Up to {{max}} files, {{size}} MB each",
|
|
78
|
+
removeAttachment: "Remove {{name}}",
|
|
79
|
+
attachmentNameOnly: "name and type only",
|
|
80
|
+
attachmentTooLarge: "{{name}} is larger than {{size}} MB and was not attached.",
|
|
81
|
+
attachmentTooMany: "Only {{max}} files can be attached, so {{name}} was skipped.",
|
|
76
82
|
noAnswer: "I couldn't find this in our documentation, so the answer below is not grounded in a source. Try rephrasing, or",
|
|
77
83
|
askHuman: "ask a human",
|
|
78
84
|
prevSuggestion: "Previous suggestion",
|
|
@@ -115,6 +121,12 @@ var ZH = {
|
|
|
115
121
|
disclaimerShort: "\u5185\u5BB9\u57FA\u4E8E\u6211\u4EEC\u7684\u6587\u6863\uFF0C\u91CD\u8981\u4FE1\u606F\u8BF7\u81EA\u884C\u6838\u5BF9\u3002",
|
|
116
122
|
dictate: "\u8BED\u97F3\u8F93\u5165",
|
|
117
123
|
stopDictating: "\u505C\u6B62\u8BED\u97F3\u8F93\u5165",
|
|
124
|
+
attach: "\u6DFB\u52A0\u6587\u4EF6",
|
|
125
|
+
attachHint: "\u6700\u591A {{max}} \u4E2A\u6587\u4EF6\uFF0C\u6BCF\u4E2A\u4E0D\u8D85\u8FC7 {{size}} MB",
|
|
126
|
+
removeAttachment: "\u79FB\u9664 {{name}}",
|
|
127
|
+
attachmentNameOnly: "\u4EC5\u6587\u4EF6\u540D\u548C\u7C7B\u578B",
|
|
128
|
+
attachmentTooLarge: "{{name}} \u8D85\u8FC7 {{size}} MB\uFF0C\u672A\u80FD\u6DFB\u52A0\u3002",
|
|
129
|
+
attachmentTooMany: "\u6700\u591A\u53EA\u80FD\u6DFB\u52A0 {{max}} \u4E2A\u6587\u4EF6\uFF0C\u5DF2\u8DF3\u8FC7 {{name}}\u3002",
|
|
118
130
|
noAnswer: "\u6211\u5728\u6587\u6863\u4E2D\u6CA1\u6709\u627E\u5230\u76F8\u5173\u5185\u5BB9\uFF0C\u4E0B\u9762\u7684\u56DE\u7B54\u6CA1\u6709\u6765\u6E90\u652F\u6301\u3002\u8BF7\u6362\u4E2A\u8BF4\u6CD5\uFF0C\u6216",
|
|
119
131
|
askHuman: "\u8054\u7CFB\u6211\u4EEC",
|
|
120
132
|
prevSuggestion: "\u4E0A\u4E00\u4E2A\u5EFA\u8BAE",
|
|
@@ -153,6 +165,12 @@ var HI = {
|
|
|
153
165
|
disclaimerShort: "\u092F\u0939 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 \u0939\u0948 \u2014 \u092E\u0939\u0924\u094D\u0935\u092A\u0942\u0930\u094D\u0923 \u092C\u093E\u0924\u0947\u0902 \u091C\u093C\u0930\u0942\u0930 \u091C\u093E\u0901\u091A \u0932\u0947\u0902\u0964",
|
|
154
166
|
dictate: "\u092C\u094B\u0932\u0915\u0930 \u092A\u0942\u091B\u0947\u0902",
|
|
155
167
|
stopDictating: "\u092C\u094B\u0932\u0928\u093E \u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
|
|
168
|
+
attach: "\u092B\u093C\u093E\u0907\u0932\u0947\u0902 \u091C\u094B\u0921\u093C\u0947\u0902",
|
|
169
|
+
attachHint: "\u0905\u0927\u093F\u0915\u0924\u092E {{max}} \u092B\u093C\u093E\u0907\u0932\u0947\u0902, \u092A\u094D\u0930\u0924\u094D\u092F\u0947\u0915 {{size}} MB \u0924\u0915",
|
|
170
|
+
removeAttachment: "{{name}} \u0939\u091F\u093E\u090F\u0901",
|
|
171
|
+
attachmentNameOnly: "\u0915\u0947\u0935\u0932 \u0928\u093E\u092E \u0914\u0930 \u092A\u094D\u0930\u0915\u093E\u0930",
|
|
172
|
+
attachmentTooLarge: "{{name}} {{size}} MB \u0938\u0947 \u092C\u0921\u093C\u0940 \u0939\u0948, \u0907\u0938\u0932\u093F\u090F \u091C\u094B\u0921\u093C\u0940 \u0928\u0939\u0940\u0902 \u0917\u0908\u0964",
|
|
173
|
+
attachmentTooMany: "\u0915\u0947\u0935\u0932 {{max}} \u092B\u093C\u093E\u0907\u0932\u0947\u0902 \u091C\u094B\u0921\u093C\u0940 \u091C\u093E \u0938\u0915\u0924\u0940 \u0939\u0948\u0902, \u0907\u0938\u0932\u093F\u090F {{name}} \u091B\u094B\u0921\u093C \u0926\u0940 \u0917\u0908\u0964",
|
|
156
174
|
noAnswer: "\u092F\u0939 \u092E\u0941\u091D\u0947 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092E\u0947\u0902 \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E, \u0907\u0938\u0932\u093F\u090F \u0928\u0940\u091A\u0947 \u0926\u093F\u092F\u093E \u0909\u0924\u094D\u0924\u0930 \u0915\u093F\u0938\u0940 \u0938\u094D\u0930\u094B\u0924 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 \u0928\u0939\u0940\u0902 \u0939\u0948\u0964 \u0926\u0942\u0938\u0930\u0947 \u0936\u092C\u094D\u0926\u094B\u0902 \u092E\u0947\u0902 \u092A\u0942\u091B\u0947\u0902, \u092F\u093E",
|
|
157
175
|
askHuman: "\u0939\u092E\u0938\u0947 \u0938\u0902\u092A\u0930\u094D\u0915 \u0915\u0930\u0947\u0902",
|
|
158
176
|
prevSuggestion: "\u092A\u093F\u091B\u0932\u093E \u0938\u0941\u091D\u093E\u0935",
|
|
@@ -195,6 +213,12 @@ var ES = {
|
|
|
195
213
|
disclaimerShort: "Basado en nuestra documentaci\xF3n: comprueba cualquier dato importante.",
|
|
196
214
|
dictate: "Dictar tu pregunta",
|
|
197
215
|
stopDictating: "Dejar de dictar",
|
|
216
|
+
attach: "Adjuntar archivos",
|
|
217
|
+
attachHint: "Hasta {{max}} archivos, {{size}} MB cada uno",
|
|
218
|
+
removeAttachment: "Quitar {{name}}",
|
|
219
|
+
attachmentNameOnly: "solo nombre y tipo",
|
|
220
|
+
attachmentTooLarge: "{{name}} supera los {{size}} MB y no se adjunt\xF3.",
|
|
221
|
+
attachmentTooMany: "Solo se pueden adjuntar {{max}} archivos, as\xED que se omiti\xF3 {{name}}.",
|
|
198
222
|
noAnswer: "No he encontrado esto en nuestra documentaci\xF3n, as\xED que la respuesta de abajo no se apoya en ninguna fuente. Prueba a reformularla, o",
|
|
199
223
|
askHuman: "habla con una persona",
|
|
200
224
|
prevSuggestion: "Sugerencia anterior",
|
|
@@ -237,6 +261,12 @@ var AR = {
|
|
|
237
261
|
disclaimerShort: "\u0645\u0628\u0646\u064A \u0639\u0644\u0649 \u0648\u062B\u0627\u0626\u0642\u0646\u0627 \u2014 \u062A\u062D\u0642\u0651\u0642 \u0645\u0646 \u0623\u064A \u0645\u0639\u0644\u0648\u0645\u0629 \u0645\u0647\u0645\u0629.",
|
|
238
262
|
dictate: "\u0623\u0645\u0644\u0650 \u0633\u0624\u0627\u0644\u0643",
|
|
239
263
|
stopDictating: "\u0625\u064A\u0642\u0627\u0641 \u0627\u0644\u0625\u0645\u0644\u0627\u0621",
|
|
264
|
+
attach: "\u0625\u0631\u0641\u0627\u0642 \u0645\u0644\u0641\u0627\u062A",
|
|
265
|
+
attachHint: "\u062D\u062A\u0649 {{max}} \u0645\u0644\u0641\u0627\u062A\u060C \u0628\u062D\u062F \u0623\u0642\u0635\u0649 {{size}} \u0645\u064A\u063A\u0627\u0628\u0627\u064A\u062A \u0644\u0643\u0644 \u0645\u0644\u0641",
|
|
266
|
+
removeAttachment: "\u0625\u0632\u0627\u0644\u0629 {{name}}",
|
|
267
|
+
attachmentNameOnly: "\u0627\u0644\u0627\u0633\u0645 \u0648\u0627\u0644\u0646\u0648\u0639 \u0641\u0642\u0637",
|
|
268
|
+
attachmentTooLarge: "{{name}} \u0623\u0643\u0628\u0631 \u0645\u0646 {{size}} \u0645\u064A\u063A\u0627\u0628\u0627\u064A\u062A \u0648\u0644\u0645 \u064A\u062A\u0645 \u0625\u0631\u0641\u0627\u0642\u0647.",
|
|
269
|
+
attachmentTooMany: "\u064A\u0645\u0643\u0646 \u0625\u0631\u0641\u0627\u0642 {{max}} \u0645\u0644\u0641\u0627\u062A \u0641\u0642\u0637\u060C \u0644\u0630\u0627 \u062A\u0645 \u062A\u062E\u0637\u064A {{name}}.",
|
|
240
270
|
noAnswer: "\u0644\u0645 \u0623\u062C\u062F \u0647\u0630\u0627 \u0641\u064A \u0648\u062B\u0627\u0626\u0642\u0646\u0627\u060C \u0644\u0630\u0627 \u0641\u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0623\u062F\u0646\u0627\u0647 \u063A\u064A\u0631 \u0645\u0633\u062A\u0646\u062F\u0629 \u0625\u0644\u0649 \u0645\u0635\u062F\u0631. \u062D\u0627\u0648\u0644 \u0625\u0639\u0627\u062F\u0629 \u0627\u0644\u0635\u064A\u0627\u063A\u0629\u060C \u0623\u0648",
|
|
241
271
|
askHuman: "\u062A\u062D\u062F\u0651\u062B \u0625\u0644\u0649 \u0634\u062E\u0635",
|
|
242
272
|
prevSuggestion: "\u0627\u0644\u0627\u0642\u062A\u0631\u0627\u062D \u0627\u0644\u0633\u0627\u0628\u0642",
|
|
@@ -279,6 +309,12 @@ var TA = {
|
|
|
279
309
|
disclaimerShort: "\u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BC8 \u0B85\u0B9F\u0BBF\u0BAA\u0BCD\u0BAA\u0B9F\u0BC8\u0BAF\u0BBE\u0B95\u0B95\u0BCD \u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BA4\u0BC1 \u2014 \u0BAE\u0BC1\u0B95\u0BCD\u0B95\u0BBF\u0BAF\u0BAE\u0BBE\u0BA9\u0BA4\u0BC8\u0B9A\u0BCD \u0B9A\u0BB0\u0BBF\u0BAA\u0BBE\u0BB0\u0BCD\u0B95\u0BCD\u0B95\u0BB5\u0BC1\u0BAE\u0BCD.",
|
|
280
310
|
dictate: "\u0B89\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B95\u0BC7\u0BB3\u0BCD\u0BB5\u0BBF\u0BAF\u0BC8\u0BAA\u0BCD \u0BAA\u0BC7\u0B9A\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
|
|
281
311
|
stopDictating: "\u0BAA\u0BC7\u0B9A\u0BC1\u0BB5\u0BA4\u0BC8 \u0BA8\u0BBF\u0BB1\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1",
|
|
312
|
+
attach: "\u0B95\u0BCB\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BC8 \u0B87\u0BA3\u0BC8\u0B95\u0BCD\u0B95",
|
|
313
|
+
attachHint: "\u0B85\u0BA4\u0BBF\u0B95\u0BAA\u0B9F\u0BCD\u0B9A\u0BAE\u0BCD {{max}} \u0B95\u0BCB\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BCD, \u0B92\u0BB5\u0BCD\u0BB5\u0BCA\u0BA9\u0BCD\u0BB1\u0BC1\u0BAE\u0BCD {{size}} MB \u0BB5\u0BB0\u0BC8",
|
|
314
|
+
removeAttachment: "{{name}} \u0B85\u0B95\u0BB1\u0BCD\u0BB1\u0BC1",
|
|
315
|
+
attachmentNameOnly: "\u0BAA\u0BC6\u0BAF\u0BB0\u0BC1\u0BAE\u0BCD \u0BB5\u0B95\u0BC8\u0BAF\u0BC1\u0BAE\u0BCD \u0BAE\u0B9F\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD",
|
|
316
|
+
attachmentTooLarge: "{{name}} {{size}} MB-\u0B90 \u0BB5\u0BBF\u0B9F \u0BAA\u0BC6\u0BB0\u0BBF\u0BAF\u0BA4\u0BC1, \u0B8E\u0BA9\u0BB5\u0BC7 \u0B87\u0BA3\u0BC8\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8.",
|
|
317
|
+
attachmentTooMany: "{{max}} \u0B95\u0BCB\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BCD \u0BAE\u0B9F\u0BCD\u0B9F\u0BC1\u0BAE\u0BC7 \u0B87\u0BA3\u0BC8\u0B95\u0BCD\u0B95 \u0BAE\u0BC1\u0B9F\u0BBF\u0BAF\u0BC1\u0BAE\u0BCD, \u0B8E\u0BA9\u0BB5\u0BC7 {{name}} \u0BA4\u0BB5\u0BBF\u0BB0\u0BCD\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1.",
|
|
282
318
|
noAnswer: "\u0B87\u0BA4\u0BC1 \u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0B95\u0BBF\u0B9F\u0BC8\u0B95\u0BCD\u0B95\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8, \u0B8E\u0BA9\u0BB5\u0BC7 \u0B95\u0BC0\u0BB4\u0BC7 \u0B89\u0BB3\u0BCD\u0BB3 \u0BAA\u0BA4\u0BBF\u0BB2\u0BC1\u0B95\u0BCD\u0B95\u0BC1 \u0BAE\u0BC2\u0BB2\u0BAE\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8. \u0BB5\u0BC7\u0BB1\u0BC1 \u0BB5\u0B95\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD, \u0B85\u0BB2\u0BCD\u0BB2\u0BA4\u0BC1",
|
|
283
319
|
askHuman: "\u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BC8\u0BA4\u0BCD \u0BA4\u0BCA\u0B9F\u0BB0\u0BCD\u0BAA\u0BC1 \u0B95\u0BCA\u0BB3\u0BCD\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
|
|
284
320
|
prevSuggestion: "\u0BAE\u0BC1\u0BA8\u0BCD\u0BA4\u0BC8\u0BAF \u0BAA\u0BB0\u0BBF\u0BA8\u0BCD\u0BA4\u0BC1\u0BB0\u0BC8",
|
|
@@ -782,6 +818,12 @@ var EXPLORE_MESSAGE_FIELDS = (
|
|
|
782
818
|
}
|
|
783
819
|
followUps
|
|
784
820
|
answered
|
|
821
|
+
attachments {
|
|
822
|
+
name
|
|
823
|
+
mimeType
|
|
824
|
+
size
|
|
825
|
+
textExtracted
|
|
826
|
+
}
|
|
785
827
|
errorCode
|
|
786
828
|
createdAt
|
|
787
829
|
completedAt
|
|
@@ -867,6 +909,16 @@ var CREATE_EXPLORE_SHARE_LINK_MUTATION = (
|
|
|
867
909
|
}
|
|
868
910
|
`
|
|
869
911
|
);
|
|
912
|
+
var EXPLORE_SHARED_CONVERSATION_QUERY = (
|
|
913
|
+
/* GraphQL */
|
|
914
|
+
`
|
|
915
|
+
query ExploreSharedConversation($shareToken: String!) {
|
|
916
|
+
exploreSharedConversation(shareToken: $shareToken) {
|
|
917
|
+
${EXPLORE_MESSAGE_FIELDS}
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
`
|
|
921
|
+
);
|
|
870
922
|
|
|
871
923
|
// src/data/products.ts
|
|
872
924
|
var ECOSYSTEM_PRODUCTS = [
|
|
@@ -1317,6 +1369,14 @@ function readPersisted(key) {
|
|
|
1317
1369
|
return null;
|
|
1318
1370
|
}
|
|
1319
1371
|
}
|
|
1372
|
+
function readShareToken() {
|
|
1373
|
+
if (typeof window === "undefined") return null;
|
|
1374
|
+
try {
|
|
1375
|
+
return new URL(window.location.href).searchParams.get("c");
|
|
1376
|
+
} catch {
|
|
1377
|
+
return null;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1320
1380
|
function visibleText(message) {
|
|
1321
1381
|
return message.content || message.partialContent || "";
|
|
1322
1382
|
}
|
|
@@ -1355,10 +1415,18 @@ function useExploreChat(options = {}) {
|
|
|
1355
1415
|
const pollGenerationRef = React.useRef(0);
|
|
1356
1416
|
const pollTimerRef = React.useRef(null);
|
|
1357
1417
|
const conversationTokenRef = React.useRef(null);
|
|
1418
|
+
const shareTokenRef = React.useRef(void 0);
|
|
1419
|
+
if (shareTokenRef.current === void 0) {
|
|
1420
|
+
shareTokenRef.current = readShareToken();
|
|
1421
|
+
}
|
|
1422
|
+
const isSharedView = shareTokenRef.current !== null;
|
|
1358
1423
|
const catalogRef = React.useRef(fallbackCatalog);
|
|
1359
1424
|
const turnCountRef = React.useRef(0);
|
|
1360
1425
|
const focusProductRef = React.useRef(null);
|
|
1361
1426
|
const lastSentTextRef = React.useRef(null);
|
|
1427
|
+
const lastSentAttachmentsRef = React.useRef(
|
|
1428
|
+
[]
|
|
1429
|
+
);
|
|
1362
1430
|
const inFlightRef = React.useRef(false);
|
|
1363
1431
|
catalogRef.current = catalog;
|
|
1364
1432
|
const clearPollTimer = React.useCallback(() => {
|
|
@@ -1383,6 +1451,43 @@ function useExploreChat(options = {}) {
|
|
|
1383
1451
|
};
|
|
1384
1452
|
}, []);
|
|
1385
1453
|
React.useEffect(() => {
|
|
1454
|
+
const shareToken = shareTokenRef.current;
|
|
1455
|
+
if (!shareToken) return;
|
|
1456
|
+
let cancelled = false;
|
|
1457
|
+
setHydrated(true);
|
|
1458
|
+
void client.query(
|
|
1459
|
+
EXPLORE_SHARED_CONVERSATION_QUERY,
|
|
1460
|
+
{ shareToken },
|
|
1461
|
+
{ cache: false }
|
|
1462
|
+
).then((res) => {
|
|
1463
|
+
if (cancelled || !mountedRef.current) return;
|
|
1464
|
+
const shared = res?.data?.exploreSharedConversation;
|
|
1465
|
+
if (shared && shared.length > 0) {
|
|
1466
|
+
setMessages(shared);
|
|
1467
|
+
return;
|
|
1468
|
+
}
|
|
1469
|
+
setError({
|
|
1470
|
+
kind: "unknown",
|
|
1471
|
+
code: "SHARE_NOT_FOUND",
|
|
1472
|
+
message: "That shared conversation could not be found. The link may have expired.",
|
|
1473
|
+
// Nothing to retry: a bad token will stay bad.
|
|
1474
|
+
retryable: false
|
|
1475
|
+
});
|
|
1476
|
+
}).catch(() => {
|
|
1477
|
+
if (cancelled || !mountedRef.current) return;
|
|
1478
|
+
setError({
|
|
1479
|
+
kind: "unknown",
|
|
1480
|
+
code: "SHARE_NOT_FOUND",
|
|
1481
|
+
message: "That shared conversation could not be loaded.",
|
|
1482
|
+
retryable: true
|
|
1483
|
+
});
|
|
1484
|
+
});
|
|
1485
|
+
return () => {
|
|
1486
|
+
cancelled = true;
|
|
1487
|
+
};
|
|
1488
|
+
}, [client]);
|
|
1489
|
+
React.useEffect(() => {
|
|
1490
|
+
if (shareTokenRef.current !== null) return;
|
|
1386
1491
|
if (!persist) {
|
|
1387
1492
|
setHydrated(true);
|
|
1388
1493
|
return;
|
|
@@ -1550,7 +1655,7 @@ function useExploreChat(options = {}) {
|
|
|
1550
1655
|
[client, pollIntervalMs, pollTimeoutMs]
|
|
1551
1656
|
);
|
|
1552
1657
|
const submit = React.useCallback(
|
|
1553
|
-
async (text, optimisticId, captchaAttempt) => {
|
|
1658
|
+
async (text, optimisticId, captchaAttempt, attachments) => {
|
|
1554
1659
|
const activeCatalog = catalogRef.current;
|
|
1555
1660
|
let recaptchaToken;
|
|
1556
1661
|
if (activeCatalog.captchaRequired && activeCatalog.recaptchaSiteKey) {
|
|
@@ -1568,7 +1673,8 @@ function useExploreChat(options = {}) {
|
|
|
1568
1673
|
...focusProductRef.current || productSlug ? { productSlug: focusProductRef.current ?? productSlug } : {},
|
|
1569
1674
|
...recaptchaToken ? { recaptchaToken } : {},
|
|
1570
1675
|
...locale ? { locale } : {},
|
|
1571
|
-
...pageUrl ? { pageUrl } : {}
|
|
1676
|
+
...pageUrl ? { pageUrl } : {},
|
|
1677
|
+
...attachments.length > 0 ? { attachments: [...attachments] } : {}
|
|
1572
1678
|
};
|
|
1573
1679
|
const res = await client.mutate(
|
|
1574
1680
|
SEND_EXPLORE_MESSAGE_MUTATION,
|
|
@@ -1582,7 +1688,7 @@ function useExploreChat(options = {}) {
|
|
|
1582
1688
|
const code = typeof first?.extensions?.code === "string" ? first.extensions.code : void 0;
|
|
1583
1689
|
const classified = classifyExploreError(code, first?.message);
|
|
1584
1690
|
if (classified.kind === "captcha" && captchaAttempt === 0) {
|
|
1585
|
-
await submit(text, optimisticId, 1);
|
|
1691
|
+
await submit(text, optimisticId, 1, attachments);
|
|
1586
1692
|
return;
|
|
1587
1693
|
}
|
|
1588
1694
|
inFlightRef.current = false;
|
|
@@ -1619,7 +1725,7 @@ function useExploreChat(options = {}) {
|
|
|
1619
1725
|
[client, locale, pageUrl, productSlug, startPolling]
|
|
1620
1726
|
);
|
|
1621
1727
|
const send = React.useCallback(
|
|
1622
|
-
async (message) => {
|
|
1728
|
+
async (message, attachments = []) => {
|
|
1623
1729
|
const text = message.trim();
|
|
1624
1730
|
if (!text) return;
|
|
1625
1731
|
if (inFlightRef.current) return;
|
|
@@ -1649,6 +1755,7 @@ function useExploreChat(options = {}) {
|
|
|
1649
1755
|
}
|
|
1650
1756
|
inFlightRef.current = true;
|
|
1651
1757
|
lastSentTextRef.current = text;
|
|
1758
|
+
lastSentAttachmentsRef.current = attachments;
|
|
1652
1759
|
setError(null);
|
|
1653
1760
|
setPhase("sending");
|
|
1654
1761
|
cancelPolling();
|
|
@@ -1671,7 +1778,7 @@ function useExploreChat(options = {}) {
|
|
|
1671
1778
|
setTurnCount(turnCountRef.current);
|
|
1672
1779
|
onSend?.(text);
|
|
1673
1780
|
try {
|
|
1674
|
-
await submit(text, optimistic.id, 0);
|
|
1781
|
+
await submit(text, optimistic.id, 0, attachments);
|
|
1675
1782
|
} catch (err) {
|
|
1676
1783
|
if (!mountedRef.current) return;
|
|
1677
1784
|
console.error("[WebSDK] Explore send failed", err);
|
|
@@ -1720,7 +1827,7 @@ function useExploreChat(options = {}) {
|
|
|
1720
1827
|
});
|
|
1721
1828
|
turnCountRef.current = Math.max(0, turnCountRef.current - 1);
|
|
1722
1829
|
setTurnCount(turnCountRef.current);
|
|
1723
|
-
void send(text);
|
|
1830
|
+
void send(text, lastSentAttachmentsRef.current);
|
|
1724
1831
|
}, [cancelPolling, send]);
|
|
1725
1832
|
const reset = React.useCallback(() => {
|
|
1726
1833
|
setArchive(
|
|
@@ -1734,6 +1841,7 @@ function useExploreChat(options = {}) {
|
|
|
1734
1841
|
inFlightRef.current = false;
|
|
1735
1842
|
conversationTokenRef.current = null;
|
|
1736
1843
|
lastSentTextRef.current = null;
|
|
1844
|
+
lastSentAttachmentsRef.current = [];
|
|
1737
1845
|
turnCountRef.current = 0;
|
|
1738
1846
|
setTurnCount(0);
|
|
1739
1847
|
setMessages([]);
|
|
@@ -1842,7 +1950,8 @@ function useExploreChat(options = {}) {
|
|
|
1842
1950
|
deleteConversation,
|
|
1843
1951
|
clearHistory,
|
|
1844
1952
|
recordClick,
|
|
1845
|
-
createShareLink
|
|
1953
|
+
createShareLink,
|
|
1954
|
+
isSharedView
|
|
1846
1955
|
};
|
|
1847
1956
|
}
|
|
1848
1957
|
var optimisticCounter = 0;
|
|
@@ -2226,6 +2335,145 @@ var Textarea = React__namespace.forwardRef(({ className, ...props }, ref) => {
|
|
|
2226
2335
|
);
|
|
2227
2336
|
});
|
|
2228
2337
|
Textarea.displayName = "Textarea";
|
|
2338
|
+
|
|
2339
|
+
// src/utils/explore-attachments.ts
|
|
2340
|
+
var MAX_ATTACHMENTS = 5;
|
|
2341
|
+
var MAX_ATTACHMENT_BYTES = 10 * 1024 * 1024;
|
|
2342
|
+
var MAX_TEXT_PER_ATTACHMENT = 2e4;
|
|
2343
|
+
var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
2344
|
+
"txt",
|
|
2345
|
+
"md",
|
|
2346
|
+
"markdown",
|
|
2347
|
+
"csv",
|
|
2348
|
+
"tsv",
|
|
2349
|
+
"json",
|
|
2350
|
+
"jsonl",
|
|
2351
|
+
"yaml",
|
|
2352
|
+
"yml",
|
|
2353
|
+
"toml",
|
|
2354
|
+
"ini",
|
|
2355
|
+
"cfg",
|
|
2356
|
+
"conf",
|
|
2357
|
+
"env",
|
|
2358
|
+
"log",
|
|
2359
|
+
"sql",
|
|
2360
|
+
"graphql",
|
|
2361
|
+
"gql",
|
|
2362
|
+
"html",
|
|
2363
|
+
"htm",
|
|
2364
|
+
"xml",
|
|
2365
|
+
"svg",
|
|
2366
|
+
"css",
|
|
2367
|
+
"scss",
|
|
2368
|
+
"js",
|
|
2369
|
+
"jsx",
|
|
2370
|
+
"mjs",
|
|
2371
|
+
"cjs",
|
|
2372
|
+
"ts",
|
|
2373
|
+
"tsx",
|
|
2374
|
+
"py",
|
|
2375
|
+
"rb",
|
|
2376
|
+
"go",
|
|
2377
|
+
"rs",
|
|
2378
|
+
"java",
|
|
2379
|
+
"kt",
|
|
2380
|
+
"c",
|
|
2381
|
+
"h",
|
|
2382
|
+
"cpp",
|
|
2383
|
+
"cs",
|
|
2384
|
+
"php",
|
|
2385
|
+
"sh",
|
|
2386
|
+
"bash",
|
|
2387
|
+
"zsh",
|
|
2388
|
+
"ps1",
|
|
2389
|
+
"dockerfile",
|
|
2390
|
+
"tf",
|
|
2391
|
+
"tfvars"
|
|
2392
|
+
]);
|
|
2393
|
+
function isTextualMimeType(mimeType) {
|
|
2394
|
+
if (mimeType.startsWith("text/")) return true;
|
|
2395
|
+
return mimeType === "application/json" || mimeType === "application/xml" || mimeType === "application/yaml" || mimeType === "application/x-yaml" || mimeType === "application/javascript" || mimeType === "application/graphql" || mimeType.endsWith("+json") || mimeType.endsWith("+xml");
|
|
2396
|
+
}
|
|
2397
|
+
function extensionOf(name) {
|
|
2398
|
+
const dot = name.lastIndexOf(".");
|
|
2399
|
+
if (dot <= 0 || dot === name.length - 1) return "";
|
|
2400
|
+
return name.slice(dot + 1).toLowerCase();
|
|
2401
|
+
}
|
|
2402
|
+
function looksTextual(name, mimeType) {
|
|
2403
|
+
if (isTextualMimeType(mimeType)) return true;
|
|
2404
|
+
return TEXT_EXTENSIONS.has(extensionOf(name));
|
|
2405
|
+
}
|
|
2406
|
+
function isDecodedTextUsable(decoded) {
|
|
2407
|
+
if (decoded.length === 0) return false;
|
|
2408
|
+
if (decoded.includes("\0")) return false;
|
|
2409
|
+
let replacements = 0;
|
|
2410
|
+
for (const char of decoded) if (char === "\uFFFD") replacements += 1;
|
|
2411
|
+
return replacements / decoded.length < 0.1;
|
|
2412
|
+
}
|
|
2413
|
+
function formatBytes(bytes) {
|
|
2414
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
2415
|
+
if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
|
|
2416
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
2417
|
+
}
|
|
2418
|
+
var counter = 0;
|
|
2419
|
+
function nextId() {
|
|
2420
|
+
counter += 1;
|
|
2421
|
+
return `att-${counter}`;
|
|
2422
|
+
}
|
|
2423
|
+
async function readArrayBuffer(blob) {
|
|
2424
|
+
if (typeof blob.arrayBuffer === "function") return blob.arrayBuffer();
|
|
2425
|
+
return new Promise((resolve, reject) => {
|
|
2426
|
+
const reader = new FileReader();
|
|
2427
|
+
reader.onload = () => resolve(reader.result);
|
|
2428
|
+
reader.onerror = () => reject(reader.error ?? new Error("file read failed"));
|
|
2429
|
+
reader.readAsArrayBuffer(blob);
|
|
2430
|
+
});
|
|
2431
|
+
}
|
|
2432
|
+
async function readTextPrefix(file) {
|
|
2433
|
+
try {
|
|
2434
|
+
const slice = file.slice(0, MAX_TEXT_PER_ATTACHMENT);
|
|
2435
|
+
const buffer = await readArrayBuffer(slice);
|
|
2436
|
+
const decoded = new TextDecoder("utf-8").decode(buffer);
|
|
2437
|
+
return isDecodedTextUsable(decoded) ? decoded : null;
|
|
2438
|
+
} catch {
|
|
2439
|
+
return null;
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
async function stageFiles(files, alreadyStaged) {
|
|
2443
|
+
const accepted = [];
|
|
2444
|
+
const rejected = [];
|
|
2445
|
+
let slots = MAX_ATTACHMENTS - alreadyStaged.length;
|
|
2446
|
+
for (const file of files) {
|
|
2447
|
+
if (slots <= 0) {
|
|
2448
|
+
rejected.push({ name: file.name, reason: "too-many" });
|
|
2449
|
+
continue;
|
|
2450
|
+
}
|
|
2451
|
+
if (file.size > MAX_ATTACHMENT_BYTES) {
|
|
2452
|
+
rejected.push({ name: file.name, reason: "too-large" });
|
|
2453
|
+
continue;
|
|
2454
|
+
}
|
|
2455
|
+
const mimeType = file.type || "application/octet-stream";
|
|
2456
|
+
const textContent = looksTextual(file.name, mimeType) ? await readTextPrefix(file) : null;
|
|
2457
|
+
accepted.push({
|
|
2458
|
+
id: nextId(),
|
|
2459
|
+
name: file.name,
|
|
2460
|
+
mimeType,
|
|
2461
|
+
size: file.size,
|
|
2462
|
+
textContent,
|
|
2463
|
+
textExtracted: textContent !== null
|
|
2464
|
+
});
|
|
2465
|
+
slots -= 1;
|
|
2466
|
+
}
|
|
2467
|
+
return { accepted, rejected };
|
|
2468
|
+
}
|
|
2469
|
+
function toPayload(staged) {
|
|
2470
|
+
return staged.map(({ name, mimeType, size, textContent }) => ({
|
|
2471
|
+
name,
|
|
2472
|
+
mimeType,
|
|
2473
|
+
size,
|
|
2474
|
+
textContent
|
|
2475
|
+
}));
|
|
2476
|
+
}
|
|
2229
2477
|
var EXPLORE_CSS = `
|
|
2230
2478
|
@keyframes boff-explore-pulse {
|
|
2231
2479
|
0%, 80%, 100% { opacity: 0.25; transform: translateY(0); }
|
|
@@ -2574,15 +2822,45 @@ function ThinkingIndicator({ activity }) {
|
|
|
2574
2822
|
}
|
|
2575
2823
|
);
|
|
2576
2824
|
}
|
|
2577
|
-
function UserBubble({
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2825
|
+
function UserBubble({
|
|
2826
|
+
strings: T,
|
|
2827
|
+
message
|
|
2828
|
+
}) {
|
|
2829
|
+
const attachments = message.attachments ?? [];
|
|
2830
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-end gap-1.5", children: [
|
|
2831
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2832
|
+
"div",
|
|
2833
|
+
{
|
|
2834
|
+
"data-boff-explore": "user",
|
|
2835
|
+
className: "max-w-[85%] whitespace-pre-wrap break-words rounded-2xl rounded-br-md bg-primary px-4 py-2.5 text-sm leading-relaxed text-primary-foreground shadow-sm",
|
|
2836
|
+
children: message.content
|
|
2837
|
+
}
|
|
2838
|
+
),
|
|
2839
|
+
attachments.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2840
|
+
"ul",
|
|
2841
|
+
{
|
|
2842
|
+
"data-boff-explore": "user-attachments",
|
|
2843
|
+
className: "flex max-w-[85%] flex-wrap justify-end gap-1.5",
|
|
2844
|
+
children: attachments.map((attachment) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2845
|
+
"li",
|
|
2846
|
+
{
|
|
2847
|
+
"data-boff-explore": "user-attachment",
|
|
2848
|
+
"data-text-extracted": attachment.textExtracted ? "true" : "false",
|
|
2849
|
+
className: "flex max-w-full items-center gap-1.5 rounded-full border border-border bg-muted/60 px-2.5 py-1 text-xs text-muted-foreground",
|
|
2850
|
+
children: [
|
|
2851
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Paperclip, { className: "h-3 w-3 shrink-0" }),
|
|
2852
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", title: attachment.name, children: attachment.name }),
|
|
2853
|
+
attachment.textExtracted ? null : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "shrink-0", children: [
|
|
2854
|
+
"\xB7 ",
|
|
2855
|
+
T.attachmentNameOnly
|
|
2856
|
+
] })
|
|
2857
|
+
]
|
|
2858
|
+
},
|
|
2859
|
+
`${attachment.name}-${attachment.size}`
|
|
2860
|
+
))
|
|
2861
|
+
}
|
|
2862
|
+
) : null
|
|
2863
|
+
] });
|
|
2586
2864
|
}
|
|
2587
2865
|
function AssistantBubble({
|
|
2588
2866
|
strings: T,
|
|
@@ -3081,7 +3359,8 @@ function ExplorePage({
|
|
|
3081
3359
|
deleteConversation,
|
|
3082
3360
|
clearHistory,
|
|
3083
3361
|
recordClick,
|
|
3084
|
-
createShareLink
|
|
3362
|
+
createShareLink,
|
|
3363
|
+
isSharedView
|
|
3085
3364
|
} = useExploreChat({ productSlug, pageUrl, onSend, examplePrompts });
|
|
3086
3365
|
const [draft, setDraft] = React.useState("");
|
|
3087
3366
|
const textareaRef = React.useRef(null);
|
|
@@ -3107,6 +3386,11 @@ function ExplorePage({
|
|
|
3107
3386
|
const T = React.useMemo(() => exploreStrings(activeLocale), [activeLocale]);
|
|
3108
3387
|
const rtl = isRtlLocale(activeLocale);
|
|
3109
3388
|
const [disclaimerOpen, setDisclaimerOpen] = React.useState(false);
|
|
3389
|
+
const [staged, setStaged] = React.useState([]);
|
|
3390
|
+
const [attachmentNotice, setAttachmentNotice] = React.useState(null);
|
|
3391
|
+
const fileInputRef = React.useRef(null);
|
|
3392
|
+
const stagedRef = React.useRef([]);
|
|
3393
|
+
stagedRef.current = staged;
|
|
3110
3394
|
const [shareLabel, setShareLabel] = React.useState("Share");
|
|
3111
3395
|
const [shareUrl, setShareUrl] = React.useState(null);
|
|
3112
3396
|
const scrollRef = React.useRef(null);
|
|
@@ -3183,13 +3467,40 @@ function ExplorePage({
|
|
|
3183
3467
|
setShareLabel("Share");
|
|
3184
3468
|
}
|
|
3185
3469
|
}, [createShareLink, pageUrl]);
|
|
3470
|
+
const handleFilesPicked = React.useCallback(
|
|
3471
|
+
async (picked) => {
|
|
3472
|
+
if (!picked || picked.length === 0) return;
|
|
3473
|
+
const { accepted, rejected } = await stageFiles(
|
|
3474
|
+
Array.from(picked),
|
|
3475
|
+
stagedRef.current
|
|
3476
|
+
);
|
|
3477
|
+
setStaged((prev) => [...prev, ...accepted]);
|
|
3478
|
+
const first = rejected[0];
|
|
3479
|
+
setAttachmentNotice(
|
|
3480
|
+
first ? first.reason === "too-large" ? fill(T.attachmentTooLarge, {
|
|
3481
|
+
name: first.name,
|
|
3482
|
+
size: String(MAX_ATTACHMENT_BYTES / (1024 * 1024))
|
|
3483
|
+
}) : fill(T.attachmentTooMany, {
|
|
3484
|
+
name: first.name,
|
|
3485
|
+
max: String(MAX_ATTACHMENTS)
|
|
3486
|
+
}) : null
|
|
3487
|
+
);
|
|
3488
|
+
},
|
|
3489
|
+
[T]
|
|
3490
|
+
);
|
|
3491
|
+
const removeAttachment = React.useCallback((id) => {
|
|
3492
|
+
setStaged((prev) => prev.filter((entry) => entry.id !== id));
|
|
3493
|
+
setAttachmentNotice(null);
|
|
3494
|
+
}, []);
|
|
3186
3495
|
const submitDraft = React.useCallback(() => {
|
|
3187
3496
|
const text = draft.trim();
|
|
3188
3497
|
if (!text || overLimit || busy || !canSend) return;
|
|
3189
3498
|
stopDictation();
|
|
3190
3499
|
setDraft("");
|
|
3191
3500
|
stickToBottomRef.current = true;
|
|
3192
|
-
void send(text);
|
|
3501
|
+
void send(text, toPayload(stagedRef.current));
|
|
3502
|
+
setStaged([]);
|
|
3503
|
+
setAttachmentNotice(null);
|
|
3193
3504
|
textareaRef.current?.focus();
|
|
3194
3505
|
}, [busy, canSend, draft, overLimit, send, stopDictation]);
|
|
3195
3506
|
const sendPrompt = React.useCallback(
|
|
@@ -3197,7 +3508,9 @@ function ExplorePage({
|
|
|
3197
3508
|
if (!canSend || busy) return;
|
|
3198
3509
|
setDraft("");
|
|
3199
3510
|
stickToBottomRef.current = true;
|
|
3200
|
-
void send(prompt);
|
|
3511
|
+
void send(prompt, toPayload(stagedRef.current));
|
|
3512
|
+
setStaged([]);
|
|
3513
|
+
setAttachmentNotice(null);
|
|
3201
3514
|
},
|
|
3202
3515
|
[busy, canSend, send]
|
|
3203
3516
|
);
|
|
@@ -3210,7 +3523,9 @@ function ExplorePage({
|
|
|
3210
3523
|
},
|
|
3211
3524
|
[submitDraft]
|
|
3212
3525
|
);
|
|
3213
|
-
const composerDisabled = phase === "limited" || phase === "disabled" || !catalog.enabled
|
|
3526
|
+
const composerDisabled = phase === "limited" || phase === "disabled" || !catalog.enabled || // A share token grants read access only — the server would reject a send anyway, so
|
|
3527
|
+
// disable it here rather than letting the visitor type into a dead composer.
|
|
3528
|
+
isSharedView;
|
|
3214
3529
|
const captchaOn = Boolean(
|
|
3215
3530
|
catalog.captchaRequired && catalog.recaptchaSiteKey
|
|
3216
3531
|
);
|
|
@@ -3404,7 +3719,7 @@ function ExplorePage({
|
|
|
3404
3719
|
disabled: !canSend || busy
|
|
3405
3720
|
}
|
|
3406
3721
|
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto w-full min-w-0 max-w-3xl space-y-6 px-4 py-6", children: messages.map(
|
|
3407
|
-
(message) => message.role === "USER" ? /* @__PURE__ */ jsxRuntime.jsx(UserBubble, { message }, message.id) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3722
|
+
(message) => message.role === "USER" ? /* @__PURE__ */ jsxRuntime.jsx(UserBubble, { strings: T, message }, message.id) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3408
3723
|
AssistantBubble,
|
|
3409
3724
|
{
|
|
3410
3725
|
strings: T,
|
|
@@ -3428,6 +3743,33 @@ function ExplorePage({
|
|
|
3428
3743
|
captchaOn
|
|
3429
3744
|
}
|
|
3430
3745
|
),
|
|
3746
|
+
isSharedView ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3747
|
+
"div",
|
|
3748
|
+
{
|
|
3749
|
+
"data-boff-explore": "shared-banner",
|
|
3750
|
+
className: "mx-auto flex w-full max-w-3xl items-center gap-2 px-4 pb-2 text-xs text-muted-foreground",
|
|
3751
|
+
children: [
|
|
3752
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link2, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
3753
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1", children: "You are viewing a shared conversation. Start your own to ask a question." }),
|
|
3754
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3755
|
+
"button",
|
|
3756
|
+
{
|
|
3757
|
+
type: "button",
|
|
3758
|
+
"data-boff-explore": "shared-start-own",
|
|
3759
|
+
onClick: () => {
|
|
3760
|
+
if (typeof window !== "undefined") {
|
|
3761
|
+
const url = new URL(window.location.href);
|
|
3762
|
+
url.searchParams.delete("c");
|
|
3763
|
+
window.location.href = url.toString();
|
|
3764
|
+
}
|
|
3765
|
+
},
|
|
3766
|
+
className: "shrink-0 underline underline-offset-2 hover:text-foreground",
|
|
3767
|
+
children: "New chat"
|
|
3768
|
+
}
|
|
3769
|
+
)
|
|
3770
|
+
]
|
|
3771
|
+
}
|
|
3772
|
+
) : null,
|
|
3431
3773
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border bg-background/85 px-4 pb-[max(1rem,env(safe-area-inset-bottom))] pt-3 backdrop-blur-md", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3432
3774
|
"form",
|
|
3433
3775
|
{
|
|
@@ -3439,6 +3781,51 @@ function ExplorePage({
|
|
|
3439
3781
|
},
|
|
3440
3782
|
children: [
|
|
3441
3783
|
error ? /* @__PURE__ */ jsxRuntime.jsx(ErrorBanner, { error, onRetry: retry, onReset: reset }) : null,
|
|
3784
|
+
staged.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3785
|
+
"ul",
|
|
3786
|
+
{
|
|
3787
|
+
"data-boff-explore": "attachments",
|
|
3788
|
+
className: "mb-2 flex flex-wrap gap-1.5",
|
|
3789
|
+
"aria-label": T.attach,
|
|
3790
|
+
children: staged.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3791
|
+
"li",
|
|
3792
|
+
{
|
|
3793
|
+
"data-boff-explore": "attachment",
|
|
3794
|
+
"data-text-extracted": entry.textExtracted ? "true" : "false",
|
|
3795
|
+
className: "flex max-w-full items-center gap-1.5 rounded-full border border-border bg-muted/60 py-1 pl-2.5 pr-1 text-xs",
|
|
3796
|
+
children: [
|
|
3797
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Paperclip, { className: "h-3 w-3 shrink-0 text-muted-foreground" }),
|
|
3798
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-medium", title: entry.name, children: entry.name }),
|
|
3799
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "shrink-0 text-muted-foreground", children: [
|
|
3800
|
+
formatBytes(entry.size),
|
|
3801
|
+
entry.textExtracted ? "" : ` \xB7 ${T.attachmentNameOnly}`
|
|
3802
|
+
] }),
|
|
3803
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3804
|
+
"button",
|
|
3805
|
+
{
|
|
3806
|
+
type: "button",
|
|
3807
|
+
"data-boff-explore": "attachment-remove",
|
|
3808
|
+
onClick: () => removeAttachment(entry.id),
|
|
3809
|
+
"aria-label": fill(T.removeAttachment, { name: entry.name }),
|
|
3810
|
+
className: "ml-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-background hover:text-foreground",
|
|
3811
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3 w-3" })
|
|
3812
|
+
}
|
|
3813
|
+
)
|
|
3814
|
+
]
|
|
3815
|
+
},
|
|
3816
|
+
entry.id
|
|
3817
|
+
))
|
|
3818
|
+
}
|
|
3819
|
+
) : null,
|
|
3820
|
+
attachmentNotice !== null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3821
|
+
"p",
|
|
3822
|
+
{
|
|
3823
|
+
"data-boff-explore": "attachment-notice",
|
|
3824
|
+
role: "status",
|
|
3825
|
+
className: "mb-2 text-xs text-destructive",
|
|
3826
|
+
children: attachmentNotice
|
|
3827
|
+
}
|
|
3828
|
+
) : null,
|
|
3442
3829
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3443
3830
|
"div",
|
|
3444
3831
|
{
|
|
@@ -3467,7 +3854,37 @@ function ExplorePage({
|
|
|
3467
3854
|
placeholder: composerDisabled ? phase === "limited" ? "Message limit reached \u2014 please try again later" : "Explore is unavailable right now" : focusedProductName ? fill(T.placeholderProduct, {
|
|
3468
3855
|
product: focusedProductName
|
|
3469
3856
|
}) : T.placeholder,
|
|
3470
|
-
className: "max-h-[200px] min-h-[44px] w-full min-w-0 flex-1 resize-none border-0 bg-transparent px-2 py-2.5 text-
|
|
3857
|
+
className: "max-h-[200px] min-h-[44px] w-full min-w-0 flex-1 resize-none border-0 bg-transparent px-2 py-2.5 text-base shadow-none focus-visible:ring-0 sm:text-sm"
|
|
3858
|
+
}
|
|
3859
|
+
),
|
|
3860
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3861
|
+
"input",
|
|
3862
|
+
{
|
|
3863
|
+
ref: fileInputRef,
|
|
3864
|
+
type: "file",
|
|
3865
|
+
multiple: true,
|
|
3866
|
+
className: "hidden",
|
|
3867
|
+
onChange: (event) => {
|
|
3868
|
+
void handleFilesPicked(event.target.files);
|
|
3869
|
+
event.target.value = "";
|
|
3870
|
+
}
|
|
3871
|
+
}
|
|
3872
|
+
),
|
|
3873
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3874
|
+
Button,
|
|
3875
|
+
{
|
|
3876
|
+
"data-boff-explore": "attach",
|
|
3877
|
+
type: "button",
|
|
3878
|
+
size: "icon",
|
|
3879
|
+
variant: "ghost",
|
|
3880
|
+
disabled: composerDisabled || staged.length >= MAX_ATTACHMENTS,
|
|
3881
|
+
"aria-label": T.attach,
|
|
3882
|
+
title: `${T.attach} \u2014 ${fill(T.attachHint, {
|
|
3883
|
+
max: String(MAX_ATTACHMENTS),
|
|
3884
|
+
size: String(MAX_ATTACHMENT_BYTES / (1024 * 1024))
|
|
3885
|
+
})}`,
|
|
3886
|
+
onClick: () => fileInputRef.current?.click(),
|
|
3887
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Paperclip, { className: "h-4 w-4" })
|
|
3471
3888
|
}
|
|
3472
3889
|
),
|
|
3473
3890
|
speech.supported ? /* @__PURE__ */ jsxRuntime.jsx(
|