@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { createContext, useMemo, useState, useRef, useCallback, useEffect, useContext } from 'react';
|
|
3
|
-
import { Sparkles, RotateCcw, Link2, History, Trash2, Mic, Square, ArrowUp, BookOpenText, Layers, TriangleAlert, ChevronLeft, ChevronRight, ExternalLink } from 'lucide-react';
|
|
3
|
+
import { Sparkles, RotateCcw, Link2, History, Trash2, Paperclip, X, Mic, Square, ArrowUp, BookOpenText, Layers, TriangleAlert, ChevronLeft, ChevronRight, ExternalLink } from 'lucide-react';
|
|
4
4
|
import ReactMarkdown from 'react-markdown';
|
|
5
5
|
import rehypeSanitize from 'rehype-sanitize';
|
|
6
6
|
import remarkGfm from 'remark-gfm';
|
|
@@ -47,6 +47,12 @@ var EN = {
|
|
|
47
47
|
disclaimerShort: "Grounded in our docs \u2014 check anything important.",
|
|
48
48
|
dictate: "Dictate your question",
|
|
49
49
|
stopDictating: "Stop dictating",
|
|
50
|
+
attach: "Attach files",
|
|
51
|
+
attachHint: "Up to {{max}} files, {{size}} MB each",
|
|
52
|
+
removeAttachment: "Remove {{name}}",
|
|
53
|
+
attachmentNameOnly: "name and type only",
|
|
54
|
+
attachmentTooLarge: "{{name}} is larger than {{size}} MB and was not attached.",
|
|
55
|
+
attachmentTooMany: "Only {{max}} files can be attached, so {{name}} was skipped.",
|
|
50
56
|
noAnswer: "I couldn't find this in our documentation, so the answer below is not grounded in a source. Try rephrasing, or",
|
|
51
57
|
askHuman: "ask a human",
|
|
52
58
|
prevSuggestion: "Previous suggestion",
|
|
@@ -89,6 +95,12 @@ var ZH = {
|
|
|
89
95
|
disclaimerShort: "\u5185\u5BB9\u57FA\u4E8E\u6211\u4EEC\u7684\u6587\u6863\uFF0C\u91CD\u8981\u4FE1\u606F\u8BF7\u81EA\u884C\u6838\u5BF9\u3002",
|
|
90
96
|
dictate: "\u8BED\u97F3\u8F93\u5165",
|
|
91
97
|
stopDictating: "\u505C\u6B62\u8BED\u97F3\u8F93\u5165",
|
|
98
|
+
attach: "\u6DFB\u52A0\u6587\u4EF6",
|
|
99
|
+
attachHint: "\u6700\u591A {{max}} \u4E2A\u6587\u4EF6\uFF0C\u6BCF\u4E2A\u4E0D\u8D85\u8FC7 {{size}} MB",
|
|
100
|
+
removeAttachment: "\u79FB\u9664 {{name}}",
|
|
101
|
+
attachmentNameOnly: "\u4EC5\u6587\u4EF6\u540D\u548C\u7C7B\u578B",
|
|
102
|
+
attachmentTooLarge: "{{name}} \u8D85\u8FC7 {{size}} MB\uFF0C\u672A\u80FD\u6DFB\u52A0\u3002",
|
|
103
|
+
attachmentTooMany: "\u6700\u591A\u53EA\u80FD\u6DFB\u52A0 {{max}} \u4E2A\u6587\u4EF6\uFF0C\u5DF2\u8DF3\u8FC7 {{name}}\u3002",
|
|
92
104
|
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",
|
|
93
105
|
askHuman: "\u8054\u7CFB\u6211\u4EEC",
|
|
94
106
|
prevSuggestion: "\u4E0A\u4E00\u4E2A\u5EFA\u8BAE",
|
|
@@ -127,6 +139,12 @@ var HI = {
|
|
|
127
139
|
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",
|
|
128
140
|
dictate: "\u092C\u094B\u0932\u0915\u0930 \u092A\u0942\u091B\u0947\u0902",
|
|
129
141
|
stopDictating: "\u092C\u094B\u0932\u0928\u093E \u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
|
|
142
|
+
attach: "\u092B\u093C\u093E\u0907\u0932\u0947\u0902 \u091C\u094B\u0921\u093C\u0947\u0902",
|
|
143
|
+
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",
|
|
144
|
+
removeAttachment: "{{name}} \u0939\u091F\u093E\u090F\u0901",
|
|
145
|
+
attachmentNameOnly: "\u0915\u0947\u0935\u0932 \u0928\u093E\u092E \u0914\u0930 \u092A\u094D\u0930\u0915\u093E\u0930",
|
|
146
|
+
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",
|
|
147
|
+
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",
|
|
130
148
|
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",
|
|
131
149
|
askHuman: "\u0939\u092E\u0938\u0947 \u0938\u0902\u092A\u0930\u094D\u0915 \u0915\u0930\u0947\u0902",
|
|
132
150
|
prevSuggestion: "\u092A\u093F\u091B\u0932\u093E \u0938\u0941\u091D\u093E\u0935",
|
|
@@ -169,6 +187,12 @@ var ES = {
|
|
|
169
187
|
disclaimerShort: "Basado en nuestra documentaci\xF3n: comprueba cualquier dato importante.",
|
|
170
188
|
dictate: "Dictar tu pregunta",
|
|
171
189
|
stopDictating: "Dejar de dictar",
|
|
190
|
+
attach: "Adjuntar archivos",
|
|
191
|
+
attachHint: "Hasta {{max}} archivos, {{size}} MB cada uno",
|
|
192
|
+
removeAttachment: "Quitar {{name}}",
|
|
193
|
+
attachmentNameOnly: "solo nombre y tipo",
|
|
194
|
+
attachmentTooLarge: "{{name}} supera los {{size}} MB y no se adjunt\xF3.",
|
|
195
|
+
attachmentTooMany: "Solo se pueden adjuntar {{max}} archivos, as\xED que se omiti\xF3 {{name}}.",
|
|
172
196
|
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",
|
|
173
197
|
askHuman: "habla con una persona",
|
|
174
198
|
prevSuggestion: "Sugerencia anterior",
|
|
@@ -211,6 +235,12 @@ var AR = {
|
|
|
211
235
|
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.",
|
|
212
236
|
dictate: "\u0623\u0645\u0644\u0650 \u0633\u0624\u0627\u0644\u0643",
|
|
213
237
|
stopDictating: "\u0625\u064A\u0642\u0627\u0641 \u0627\u0644\u0625\u0645\u0644\u0627\u0621",
|
|
238
|
+
attach: "\u0625\u0631\u0641\u0627\u0642 \u0645\u0644\u0641\u0627\u062A",
|
|
239
|
+
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",
|
|
240
|
+
removeAttachment: "\u0625\u0632\u0627\u0644\u0629 {{name}}",
|
|
241
|
+
attachmentNameOnly: "\u0627\u0644\u0627\u0633\u0645 \u0648\u0627\u0644\u0646\u0648\u0639 \u0641\u0642\u0637",
|
|
242
|
+
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.",
|
|
243
|
+
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}}.",
|
|
214
244
|
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",
|
|
215
245
|
askHuman: "\u062A\u062D\u062F\u0651\u062B \u0625\u0644\u0649 \u0634\u062E\u0635",
|
|
216
246
|
prevSuggestion: "\u0627\u0644\u0627\u0642\u062A\u0631\u0627\u062D \u0627\u0644\u0633\u0627\u0628\u0642",
|
|
@@ -253,6 +283,12 @@ var TA = {
|
|
|
253
283
|
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.",
|
|
254
284
|
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",
|
|
255
285
|
stopDictating: "\u0BAA\u0BC7\u0B9A\u0BC1\u0BB5\u0BA4\u0BC8 \u0BA8\u0BBF\u0BB1\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1",
|
|
286
|
+
attach: "\u0B95\u0BCB\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BC8 \u0B87\u0BA3\u0BC8\u0B95\u0BCD\u0B95",
|
|
287
|
+
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",
|
|
288
|
+
removeAttachment: "{{name}} \u0B85\u0B95\u0BB1\u0BCD\u0BB1\u0BC1",
|
|
289
|
+
attachmentNameOnly: "\u0BAA\u0BC6\u0BAF\u0BB0\u0BC1\u0BAE\u0BCD \u0BB5\u0B95\u0BC8\u0BAF\u0BC1\u0BAE\u0BCD \u0BAE\u0B9F\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD",
|
|
290
|
+
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.",
|
|
291
|
+
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.",
|
|
256
292
|
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",
|
|
257
293
|
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",
|
|
258
294
|
prevSuggestion: "\u0BAE\u0BC1\u0BA8\u0BCD\u0BA4\u0BC8\u0BAF \u0BAA\u0BB0\u0BBF\u0BA8\u0BCD\u0BA4\u0BC1\u0BB0\u0BC8",
|
|
@@ -756,6 +792,12 @@ var EXPLORE_MESSAGE_FIELDS = (
|
|
|
756
792
|
}
|
|
757
793
|
followUps
|
|
758
794
|
answered
|
|
795
|
+
attachments {
|
|
796
|
+
name
|
|
797
|
+
mimeType
|
|
798
|
+
size
|
|
799
|
+
textExtracted
|
|
800
|
+
}
|
|
759
801
|
errorCode
|
|
760
802
|
createdAt
|
|
761
803
|
completedAt
|
|
@@ -841,6 +883,16 @@ var CREATE_EXPLORE_SHARE_LINK_MUTATION = (
|
|
|
841
883
|
}
|
|
842
884
|
`
|
|
843
885
|
);
|
|
886
|
+
var EXPLORE_SHARED_CONVERSATION_QUERY = (
|
|
887
|
+
/* GraphQL */
|
|
888
|
+
`
|
|
889
|
+
query ExploreSharedConversation($shareToken: String!) {
|
|
890
|
+
exploreSharedConversation(shareToken: $shareToken) {
|
|
891
|
+
${EXPLORE_MESSAGE_FIELDS}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
`
|
|
895
|
+
);
|
|
844
896
|
|
|
845
897
|
// src/data/products.ts
|
|
846
898
|
var ECOSYSTEM_PRODUCTS = [
|
|
@@ -1291,6 +1343,14 @@ function readPersisted(key) {
|
|
|
1291
1343
|
return null;
|
|
1292
1344
|
}
|
|
1293
1345
|
}
|
|
1346
|
+
function readShareToken() {
|
|
1347
|
+
if (typeof window === "undefined") return null;
|
|
1348
|
+
try {
|
|
1349
|
+
return new URL(window.location.href).searchParams.get("c");
|
|
1350
|
+
} catch {
|
|
1351
|
+
return null;
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1294
1354
|
function visibleText(message) {
|
|
1295
1355
|
return message.content || message.partialContent || "";
|
|
1296
1356
|
}
|
|
@@ -1329,10 +1389,18 @@ function useExploreChat(options = {}) {
|
|
|
1329
1389
|
const pollGenerationRef = useRef(0);
|
|
1330
1390
|
const pollTimerRef = useRef(null);
|
|
1331
1391
|
const conversationTokenRef = useRef(null);
|
|
1392
|
+
const shareTokenRef = useRef(void 0);
|
|
1393
|
+
if (shareTokenRef.current === void 0) {
|
|
1394
|
+
shareTokenRef.current = readShareToken();
|
|
1395
|
+
}
|
|
1396
|
+
const isSharedView = shareTokenRef.current !== null;
|
|
1332
1397
|
const catalogRef = useRef(fallbackCatalog);
|
|
1333
1398
|
const turnCountRef = useRef(0);
|
|
1334
1399
|
const focusProductRef = useRef(null);
|
|
1335
1400
|
const lastSentTextRef = useRef(null);
|
|
1401
|
+
const lastSentAttachmentsRef = useRef(
|
|
1402
|
+
[]
|
|
1403
|
+
);
|
|
1336
1404
|
const inFlightRef = useRef(false);
|
|
1337
1405
|
catalogRef.current = catalog;
|
|
1338
1406
|
const clearPollTimer = useCallback(() => {
|
|
@@ -1357,6 +1425,43 @@ function useExploreChat(options = {}) {
|
|
|
1357
1425
|
};
|
|
1358
1426
|
}, []);
|
|
1359
1427
|
useEffect(() => {
|
|
1428
|
+
const shareToken = shareTokenRef.current;
|
|
1429
|
+
if (!shareToken) return;
|
|
1430
|
+
let cancelled = false;
|
|
1431
|
+
setHydrated(true);
|
|
1432
|
+
void client.query(
|
|
1433
|
+
EXPLORE_SHARED_CONVERSATION_QUERY,
|
|
1434
|
+
{ shareToken },
|
|
1435
|
+
{ cache: false }
|
|
1436
|
+
).then((res) => {
|
|
1437
|
+
if (cancelled || !mountedRef.current) return;
|
|
1438
|
+
const shared = res?.data?.exploreSharedConversation;
|
|
1439
|
+
if (shared && shared.length > 0) {
|
|
1440
|
+
setMessages(shared);
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
setError({
|
|
1444
|
+
kind: "unknown",
|
|
1445
|
+
code: "SHARE_NOT_FOUND",
|
|
1446
|
+
message: "That shared conversation could not be found. The link may have expired.",
|
|
1447
|
+
// Nothing to retry: a bad token will stay bad.
|
|
1448
|
+
retryable: false
|
|
1449
|
+
});
|
|
1450
|
+
}).catch(() => {
|
|
1451
|
+
if (cancelled || !mountedRef.current) return;
|
|
1452
|
+
setError({
|
|
1453
|
+
kind: "unknown",
|
|
1454
|
+
code: "SHARE_NOT_FOUND",
|
|
1455
|
+
message: "That shared conversation could not be loaded.",
|
|
1456
|
+
retryable: true
|
|
1457
|
+
});
|
|
1458
|
+
});
|
|
1459
|
+
return () => {
|
|
1460
|
+
cancelled = true;
|
|
1461
|
+
};
|
|
1462
|
+
}, [client]);
|
|
1463
|
+
useEffect(() => {
|
|
1464
|
+
if (shareTokenRef.current !== null) return;
|
|
1360
1465
|
if (!persist) {
|
|
1361
1466
|
setHydrated(true);
|
|
1362
1467
|
return;
|
|
@@ -1524,7 +1629,7 @@ function useExploreChat(options = {}) {
|
|
|
1524
1629
|
[client, pollIntervalMs, pollTimeoutMs]
|
|
1525
1630
|
);
|
|
1526
1631
|
const submit = useCallback(
|
|
1527
|
-
async (text, optimisticId, captchaAttempt) => {
|
|
1632
|
+
async (text, optimisticId, captchaAttempt, attachments) => {
|
|
1528
1633
|
const activeCatalog = catalogRef.current;
|
|
1529
1634
|
let recaptchaToken;
|
|
1530
1635
|
if (activeCatalog.captchaRequired && activeCatalog.recaptchaSiteKey) {
|
|
@@ -1542,7 +1647,8 @@ function useExploreChat(options = {}) {
|
|
|
1542
1647
|
...focusProductRef.current || productSlug ? { productSlug: focusProductRef.current ?? productSlug } : {},
|
|
1543
1648
|
...recaptchaToken ? { recaptchaToken } : {},
|
|
1544
1649
|
...locale ? { locale } : {},
|
|
1545
|
-
...pageUrl ? { pageUrl } : {}
|
|
1650
|
+
...pageUrl ? { pageUrl } : {},
|
|
1651
|
+
...attachments.length > 0 ? { attachments: [...attachments] } : {}
|
|
1546
1652
|
};
|
|
1547
1653
|
const res = await client.mutate(
|
|
1548
1654
|
SEND_EXPLORE_MESSAGE_MUTATION,
|
|
@@ -1556,7 +1662,7 @@ function useExploreChat(options = {}) {
|
|
|
1556
1662
|
const code = typeof first?.extensions?.code === "string" ? first.extensions.code : void 0;
|
|
1557
1663
|
const classified = classifyExploreError(code, first?.message);
|
|
1558
1664
|
if (classified.kind === "captcha" && captchaAttempt === 0) {
|
|
1559
|
-
await submit(text, optimisticId, 1);
|
|
1665
|
+
await submit(text, optimisticId, 1, attachments);
|
|
1560
1666
|
return;
|
|
1561
1667
|
}
|
|
1562
1668
|
inFlightRef.current = false;
|
|
@@ -1593,7 +1699,7 @@ function useExploreChat(options = {}) {
|
|
|
1593
1699
|
[client, locale, pageUrl, productSlug, startPolling]
|
|
1594
1700
|
);
|
|
1595
1701
|
const send = useCallback(
|
|
1596
|
-
async (message) => {
|
|
1702
|
+
async (message, attachments = []) => {
|
|
1597
1703
|
const text = message.trim();
|
|
1598
1704
|
if (!text) return;
|
|
1599
1705
|
if (inFlightRef.current) return;
|
|
@@ -1623,6 +1729,7 @@ function useExploreChat(options = {}) {
|
|
|
1623
1729
|
}
|
|
1624
1730
|
inFlightRef.current = true;
|
|
1625
1731
|
lastSentTextRef.current = text;
|
|
1732
|
+
lastSentAttachmentsRef.current = attachments;
|
|
1626
1733
|
setError(null);
|
|
1627
1734
|
setPhase("sending");
|
|
1628
1735
|
cancelPolling();
|
|
@@ -1645,7 +1752,7 @@ function useExploreChat(options = {}) {
|
|
|
1645
1752
|
setTurnCount(turnCountRef.current);
|
|
1646
1753
|
onSend?.(text);
|
|
1647
1754
|
try {
|
|
1648
|
-
await submit(text, optimistic.id, 0);
|
|
1755
|
+
await submit(text, optimistic.id, 0, attachments);
|
|
1649
1756
|
} catch (err) {
|
|
1650
1757
|
if (!mountedRef.current) return;
|
|
1651
1758
|
console.error("[WebSDK] Explore send failed", err);
|
|
@@ -1694,7 +1801,7 @@ function useExploreChat(options = {}) {
|
|
|
1694
1801
|
});
|
|
1695
1802
|
turnCountRef.current = Math.max(0, turnCountRef.current - 1);
|
|
1696
1803
|
setTurnCount(turnCountRef.current);
|
|
1697
|
-
void send(text);
|
|
1804
|
+
void send(text, lastSentAttachmentsRef.current);
|
|
1698
1805
|
}, [cancelPolling, send]);
|
|
1699
1806
|
const reset = useCallback(() => {
|
|
1700
1807
|
setArchive(
|
|
@@ -1708,6 +1815,7 @@ function useExploreChat(options = {}) {
|
|
|
1708
1815
|
inFlightRef.current = false;
|
|
1709
1816
|
conversationTokenRef.current = null;
|
|
1710
1817
|
lastSentTextRef.current = null;
|
|
1818
|
+
lastSentAttachmentsRef.current = [];
|
|
1711
1819
|
turnCountRef.current = 0;
|
|
1712
1820
|
setTurnCount(0);
|
|
1713
1821
|
setMessages([]);
|
|
@@ -1816,7 +1924,8 @@ function useExploreChat(options = {}) {
|
|
|
1816
1924
|
deleteConversation,
|
|
1817
1925
|
clearHistory,
|
|
1818
1926
|
recordClick,
|
|
1819
|
-
createShareLink
|
|
1927
|
+
createShareLink,
|
|
1928
|
+
isSharedView
|
|
1820
1929
|
};
|
|
1821
1930
|
}
|
|
1822
1931
|
var optimisticCounter = 0;
|
|
@@ -2200,6 +2309,145 @@ var Textarea = React.forwardRef(({ className, ...props }, ref) => {
|
|
|
2200
2309
|
);
|
|
2201
2310
|
});
|
|
2202
2311
|
Textarea.displayName = "Textarea";
|
|
2312
|
+
|
|
2313
|
+
// src/utils/explore-attachments.ts
|
|
2314
|
+
var MAX_ATTACHMENTS = 5;
|
|
2315
|
+
var MAX_ATTACHMENT_BYTES = 10 * 1024 * 1024;
|
|
2316
|
+
var MAX_TEXT_PER_ATTACHMENT = 2e4;
|
|
2317
|
+
var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
2318
|
+
"txt",
|
|
2319
|
+
"md",
|
|
2320
|
+
"markdown",
|
|
2321
|
+
"csv",
|
|
2322
|
+
"tsv",
|
|
2323
|
+
"json",
|
|
2324
|
+
"jsonl",
|
|
2325
|
+
"yaml",
|
|
2326
|
+
"yml",
|
|
2327
|
+
"toml",
|
|
2328
|
+
"ini",
|
|
2329
|
+
"cfg",
|
|
2330
|
+
"conf",
|
|
2331
|
+
"env",
|
|
2332
|
+
"log",
|
|
2333
|
+
"sql",
|
|
2334
|
+
"graphql",
|
|
2335
|
+
"gql",
|
|
2336
|
+
"html",
|
|
2337
|
+
"htm",
|
|
2338
|
+
"xml",
|
|
2339
|
+
"svg",
|
|
2340
|
+
"css",
|
|
2341
|
+
"scss",
|
|
2342
|
+
"js",
|
|
2343
|
+
"jsx",
|
|
2344
|
+
"mjs",
|
|
2345
|
+
"cjs",
|
|
2346
|
+
"ts",
|
|
2347
|
+
"tsx",
|
|
2348
|
+
"py",
|
|
2349
|
+
"rb",
|
|
2350
|
+
"go",
|
|
2351
|
+
"rs",
|
|
2352
|
+
"java",
|
|
2353
|
+
"kt",
|
|
2354
|
+
"c",
|
|
2355
|
+
"h",
|
|
2356
|
+
"cpp",
|
|
2357
|
+
"cs",
|
|
2358
|
+
"php",
|
|
2359
|
+
"sh",
|
|
2360
|
+
"bash",
|
|
2361
|
+
"zsh",
|
|
2362
|
+
"ps1",
|
|
2363
|
+
"dockerfile",
|
|
2364
|
+
"tf",
|
|
2365
|
+
"tfvars"
|
|
2366
|
+
]);
|
|
2367
|
+
function isTextualMimeType(mimeType) {
|
|
2368
|
+
if (mimeType.startsWith("text/")) return true;
|
|
2369
|
+
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");
|
|
2370
|
+
}
|
|
2371
|
+
function extensionOf(name) {
|
|
2372
|
+
const dot = name.lastIndexOf(".");
|
|
2373
|
+
if (dot <= 0 || dot === name.length - 1) return "";
|
|
2374
|
+
return name.slice(dot + 1).toLowerCase();
|
|
2375
|
+
}
|
|
2376
|
+
function looksTextual(name, mimeType) {
|
|
2377
|
+
if (isTextualMimeType(mimeType)) return true;
|
|
2378
|
+
return TEXT_EXTENSIONS.has(extensionOf(name));
|
|
2379
|
+
}
|
|
2380
|
+
function isDecodedTextUsable(decoded) {
|
|
2381
|
+
if (decoded.length === 0) return false;
|
|
2382
|
+
if (decoded.includes("\0")) return false;
|
|
2383
|
+
let replacements = 0;
|
|
2384
|
+
for (const char of decoded) if (char === "\uFFFD") replacements += 1;
|
|
2385
|
+
return replacements / decoded.length < 0.1;
|
|
2386
|
+
}
|
|
2387
|
+
function formatBytes(bytes) {
|
|
2388
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
2389
|
+
if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
|
|
2390
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
2391
|
+
}
|
|
2392
|
+
var counter = 0;
|
|
2393
|
+
function nextId() {
|
|
2394
|
+
counter += 1;
|
|
2395
|
+
return `att-${counter}`;
|
|
2396
|
+
}
|
|
2397
|
+
async function readArrayBuffer(blob) {
|
|
2398
|
+
if (typeof blob.arrayBuffer === "function") return blob.arrayBuffer();
|
|
2399
|
+
return new Promise((resolve, reject) => {
|
|
2400
|
+
const reader = new FileReader();
|
|
2401
|
+
reader.onload = () => resolve(reader.result);
|
|
2402
|
+
reader.onerror = () => reject(reader.error ?? new Error("file read failed"));
|
|
2403
|
+
reader.readAsArrayBuffer(blob);
|
|
2404
|
+
});
|
|
2405
|
+
}
|
|
2406
|
+
async function readTextPrefix(file) {
|
|
2407
|
+
try {
|
|
2408
|
+
const slice = file.slice(0, MAX_TEXT_PER_ATTACHMENT);
|
|
2409
|
+
const buffer = await readArrayBuffer(slice);
|
|
2410
|
+
const decoded = new TextDecoder("utf-8").decode(buffer);
|
|
2411
|
+
return isDecodedTextUsable(decoded) ? decoded : null;
|
|
2412
|
+
} catch {
|
|
2413
|
+
return null;
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
async function stageFiles(files, alreadyStaged) {
|
|
2417
|
+
const accepted = [];
|
|
2418
|
+
const rejected = [];
|
|
2419
|
+
let slots = MAX_ATTACHMENTS - alreadyStaged.length;
|
|
2420
|
+
for (const file of files) {
|
|
2421
|
+
if (slots <= 0) {
|
|
2422
|
+
rejected.push({ name: file.name, reason: "too-many" });
|
|
2423
|
+
continue;
|
|
2424
|
+
}
|
|
2425
|
+
if (file.size > MAX_ATTACHMENT_BYTES) {
|
|
2426
|
+
rejected.push({ name: file.name, reason: "too-large" });
|
|
2427
|
+
continue;
|
|
2428
|
+
}
|
|
2429
|
+
const mimeType = file.type || "application/octet-stream";
|
|
2430
|
+
const textContent = looksTextual(file.name, mimeType) ? await readTextPrefix(file) : null;
|
|
2431
|
+
accepted.push({
|
|
2432
|
+
id: nextId(),
|
|
2433
|
+
name: file.name,
|
|
2434
|
+
mimeType,
|
|
2435
|
+
size: file.size,
|
|
2436
|
+
textContent,
|
|
2437
|
+
textExtracted: textContent !== null
|
|
2438
|
+
});
|
|
2439
|
+
slots -= 1;
|
|
2440
|
+
}
|
|
2441
|
+
return { accepted, rejected };
|
|
2442
|
+
}
|
|
2443
|
+
function toPayload(staged) {
|
|
2444
|
+
return staged.map(({ name, mimeType, size, textContent }) => ({
|
|
2445
|
+
name,
|
|
2446
|
+
mimeType,
|
|
2447
|
+
size,
|
|
2448
|
+
textContent
|
|
2449
|
+
}));
|
|
2450
|
+
}
|
|
2203
2451
|
var EXPLORE_CSS = `
|
|
2204
2452
|
@keyframes boff-explore-pulse {
|
|
2205
2453
|
0%, 80%, 100% { opacity: 0.25; transform: translateY(0); }
|
|
@@ -2548,15 +2796,45 @@ function ThinkingIndicator({ activity }) {
|
|
|
2548
2796
|
}
|
|
2549
2797
|
);
|
|
2550
2798
|
}
|
|
2551
|
-
function UserBubble({
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2799
|
+
function UserBubble({
|
|
2800
|
+
strings: T,
|
|
2801
|
+
message
|
|
2802
|
+
}) {
|
|
2803
|
+
const attachments = message.attachments ?? [];
|
|
2804
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-end gap-1.5", children: [
|
|
2805
|
+
/* @__PURE__ */ jsx(
|
|
2806
|
+
"div",
|
|
2807
|
+
{
|
|
2808
|
+
"data-boff-explore": "user",
|
|
2809
|
+
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",
|
|
2810
|
+
children: message.content
|
|
2811
|
+
}
|
|
2812
|
+
),
|
|
2813
|
+
attachments.length > 0 ? /* @__PURE__ */ jsx(
|
|
2814
|
+
"ul",
|
|
2815
|
+
{
|
|
2816
|
+
"data-boff-explore": "user-attachments",
|
|
2817
|
+
className: "flex max-w-[85%] flex-wrap justify-end gap-1.5",
|
|
2818
|
+
children: attachments.map((attachment) => /* @__PURE__ */ jsxs(
|
|
2819
|
+
"li",
|
|
2820
|
+
{
|
|
2821
|
+
"data-boff-explore": "user-attachment",
|
|
2822
|
+
"data-text-extracted": attachment.textExtracted ? "true" : "false",
|
|
2823
|
+
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",
|
|
2824
|
+
children: [
|
|
2825
|
+
/* @__PURE__ */ jsx(Paperclip, { className: "h-3 w-3 shrink-0" }),
|
|
2826
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", title: attachment.name, children: attachment.name }),
|
|
2827
|
+
attachment.textExtracted ? null : /* @__PURE__ */ jsxs("span", { className: "shrink-0", children: [
|
|
2828
|
+
"\xB7 ",
|
|
2829
|
+
T.attachmentNameOnly
|
|
2830
|
+
] })
|
|
2831
|
+
]
|
|
2832
|
+
},
|
|
2833
|
+
`${attachment.name}-${attachment.size}`
|
|
2834
|
+
))
|
|
2835
|
+
}
|
|
2836
|
+
) : null
|
|
2837
|
+
] });
|
|
2560
2838
|
}
|
|
2561
2839
|
function AssistantBubble({
|
|
2562
2840
|
strings: T,
|
|
@@ -3055,7 +3333,8 @@ function ExplorePage({
|
|
|
3055
3333
|
deleteConversation,
|
|
3056
3334
|
clearHistory,
|
|
3057
3335
|
recordClick,
|
|
3058
|
-
createShareLink
|
|
3336
|
+
createShareLink,
|
|
3337
|
+
isSharedView
|
|
3059
3338
|
} = useExploreChat({ productSlug, pageUrl, onSend, examplePrompts });
|
|
3060
3339
|
const [draft, setDraft] = useState("");
|
|
3061
3340
|
const textareaRef = useRef(null);
|
|
@@ -3081,6 +3360,11 @@ function ExplorePage({
|
|
|
3081
3360
|
const T = useMemo(() => exploreStrings(activeLocale), [activeLocale]);
|
|
3082
3361
|
const rtl = isRtlLocale(activeLocale);
|
|
3083
3362
|
const [disclaimerOpen, setDisclaimerOpen] = useState(false);
|
|
3363
|
+
const [staged, setStaged] = useState([]);
|
|
3364
|
+
const [attachmentNotice, setAttachmentNotice] = useState(null);
|
|
3365
|
+
const fileInputRef = useRef(null);
|
|
3366
|
+
const stagedRef = useRef([]);
|
|
3367
|
+
stagedRef.current = staged;
|
|
3084
3368
|
const [shareLabel, setShareLabel] = useState("Share");
|
|
3085
3369
|
const [shareUrl, setShareUrl] = useState(null);
|
|
3086
3370
|
const scrollRef = useRef(null);
|
|
@@ -3157,13 +3441,40 @@ function ExplorePage({
|
|
|
3157
3441
|
setShareLabel("Share");
|
|
3158
3442
|
}
|
|
3159
3443
|
}, [createShareLink, pageUrl]);
|
|
3444
|
+
const handleFilesPicked = useCallback(
|
|
3445
|
+
async (picked) => {
|
|
3446
|
+
if (!picked || picked.length === 0) return;
|
|
3447
|
+
const { accepted, rejected } = await stageFiles(
|
|
3448
|
+
Array.from(picked),
|
|
3449
|
+
stagedRef.current
|
|
3450
|
+
);
|
|
3451
|
+
setStaged((prev) => [...prev, ...accepted]);
|
|
3452
|
+
const first = rejected[0];
|
|
3453
|
+
setAttachmentNotice(
|
|
3454
|
+
first ? first.reason === "too-large" ? fill(T.attachmentTooLarge, {
|
|
3455
|
+
name: first.name,
|
|
3456
|
+
size: String(MAX_ATTACHMENT_BYTES / (1024 * 1024))
|
|
3457
|
+
}) : fill(T.attachmentTooMany, {
|
|
3458
|
+
name: first.name,
|
|
3459
|
+
max: String(MAX_ATTACHMENTS)
|
|
3460
|
+
}) : null
|
|
3461
|
+
);
|
|
3462
|
+
},
|
|
3463
|
+
[T]
|
|
3464
|
+
);
|
|
3465
|
+
const removeAttachment = useCallback((id) => {
|
|
3466
|
+
setStaged((prev) => prev.filter((entry) => entry.id !== id));
|
|
3467
|
+
setAttachmentNotice(null);
|
|
3468
|
+
}, []);
|
|
3160
3469
|
const submitDraft = useCallback(() => {
|
|
3161
3470
|
const text = draft.trim();
|
|
3162
3471
|
if (!text || overLimit || busy || !canSend) return;
|
|
3163
3472
|
stopDictation();
|
|
3164
3473
|
setDraft("");
|
|
3165
3474
|
stickToBottomRef.current = true;
|
|
3166
|
-
void send(text);
|
|
3475
|
+
void send(text, toPayload(stagedRef.current));
|
|
3476
|
+
setStaged([]);
|
|
3477
|
+
setAttachmentNotice(null);
|
|
3167
3478
|
textareaRef.current?.focus();
|
|
3168
3479
|
}, [busy, canSend, draft, overLimit, send, stopDictation]);
|
|
3169
3480
|
const sendPrompt = useCallback(
|
|
@@ -3171,7 +3482,9 @@ function ExplorePage({
|
|
|
3171
3482
|
if (!canSend || busy) return;
|
|
3172
3483
|
setDraft("");
|
|
3173
3484
|
stickToBottomRef.current = true;
|
|
3174
|
-
void send(prompt);
|
|
3485
|
+
void send(prompt, toPayload(stagedRef.current));
|
|
3486
|
+
setStaged([]);
|
|
3487
|
+
setAttachmentNotice(null);
|
|
3175
3488
|
},
|
|
3176
3489
|
[busy, canSend, send]
|
|
3177
3490
|
);
|
|
@@ -3184,7 +3497,9 @@ function ExplorePage({
|
|
|
3184
3497
|
},
|
|
3185
3498
|
[submitDraft]
|
|
3186
3499
|
);
|
|
3187
|
-
const composerDisabled = phase === "limited" || phase === "disabled" || !catalog.enabled
|
|
3500
|
+
const composerDisabled = phase === "limited" || phase === "disabled" || !catalog.enabled || // A share token grants read access only — the server would reject a send anyway, so
|
|
3501
|
+
// disable it here rather than letting the visitor type into a dead composer.
|
|
3502
|
+
isSharedView;
|
|
3188
3503
|
const captchaOn = Boolean(
|
|
3189
3504
|
catalog.captchaRequired && catalog.recaptchaSiteKey
|
|
3190
3505
|
);
|
|
@@ -3378,7 +3693,7 @@ function ExplorePage({
|
|
|
3378
3693
|
disabled: !canSend || busy
|
|
3379
3694
|
}
|
|
3380
3695
|
) : /* @__PURE__ */ jsx("div", { className: "mx-auto w-full min-w-0 max-w-3xl space-y-6 px-4 py-6", children: messages.map(
|
|
3381
|
-
(message) => message.role === "USER" ? /* @__PURE__ */ jsx(UserBubble, { message }, message.id) : /* @__PURE__ */ jsx(
|
|
3696
|
+
(message) => message.role === "USER" ? /* @__PURE__ */ jsx(UserBubble, { strings: T, message }, message.id) : /* @__PURE__ */ jsx(
|
|
3382
3697
|
AssistantBubble,
|
|
3383
3698
|
{
|
|
3384
3699
|
strings: T,
|
|
@@ -3402,6 +3717,33 @@ function ExplorePage({
|
|
|
3402
3717
|
captchaOn
|
|
3403
3718
|
}
|
|
3404
3719
|
),
|
|
3720
|
+
isSharedView ? /* @__PURE__ */ jsxs(
|
|
3721
|
+
"div",
|
|
3722
|
+
{
|
|
3723
|
+
"data-boff-explore": "shared-banner",
|
|
3724
|
+
className: "mx-auto flex w-full max-w-3xl items-center gap-2 px-4 pb-2 text-xs text-muted-foreground",
|
|
3725
|
+
children: [
|
|
3726
|
+
/* @__PURE__ */ jsx(Link2, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
3727
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1", children: "You are viewing a shared conversation. Start your own to ask a question." }),
|
|
3728
|
+
/* @__PURE__ */ jsx(
|
|
3729
|
+
"button",
|
|
3730
|
+
{
|
|
3731
|
+
type: "button",
|
|
3732
|
+
"data-boff-explore": "shared-start-own",
|
|
3733
|
+
onClick: () => {
|
|
3734
|
+
if (typeof window !== "undefined") {
|
|
3735
|
+
const url = new URL(window.location.href);
|
|
3736
|
+
url.searchParams.delete("c");
|
|
3737
|
+
window.location.href = url.toString();
|
|
3738
|
+
}
|
|
3739
|
+
},
|
|
3740
|
+
className: "shrink-0 underline underline-offset-2 hover:text-foreground",
|
|
3741
|
+
children: "New chat"
|
|
3742
|
+
}
|
|
3743
|
+
)
|
|
3744
|
+
]
|
|
3745
|
+
}
|
|
3746
|
+
) : null,
|
|
3405
3747
|
/* @__PURE__ */ 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__ */ jsxs(
|
|
3406
3748
|
"form",
|
|
3407
3749
|
{
|
|
@@ -3413,6 +3755,51 @@ function ExplorePage({
|
|
|
3413
3755
|
},
|
|
3414
3756
|
children: [
|
|
3415
3757
|
error ? /* @__PURE__ */ jsx(ErrorBanner, { error, onRetry: retry, onReset: reset }) : null,
|
|
3758
|
+
staged.length > 0 ? /* @__PURE__ */ jsx(
|
|
3759
|
+
"ul",
|
|
3760
|
+
{
|
|
3761
|
+
"data-boff-explore": "attachments",
|
|
3762
|
+
className: "mb-2 flex flex-wrap gap-1.5",
|
|
3763
|
+
"aria-label": T.attach,
|
|
3764
|
+
children: staged.map((entry) => /* @__PURE__ */ jsxs(
|
|
3765
|
+
"li",
|
|
3766
|
+
{
|
|
3767
|
+
"data-boff-explore": "attachment",
|
|
3768
|
+
"data-text-extracted": entry.textExtracted ? "true" : "false",
|
|
3769
|
+
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",
|
|
3770
|
+
children: [
|
|
3771
|
+
/* @__PURE__ */ jsx(Paperclip, { className: "h-3 w-3 shrink-0 text-muted-foreground" }),
|
|
3772
|
+
/* @__PURE__ */ jsx("span", { className: "truncate font-medium", title: entry.name, children: entry.name }),
|
|
3773
|
+
/* @__PURE__ */ jsxs("span", { className: "shrink-0 text-muted-foreground", children: [
|
|
3774
|
+
formatBytes(entry.size),
|
|
3775
|
+
entry.textExtracted ? "" : ` \xB7 ${T.attachmentNameOnly}`
|
|
3776
|
+
] }),
|
|
3777
|
+
/* @__PURE__ */ jsx(
|
|
3778
|
+
"button",
|
|
3779
|
+
{
|
|
3780
|
+
type: "button",
|
|
3781
|
+
"data-boff-explore": "attachment-remove",
|
|
3782
|
+
onClick: () => removeAttachment(entry.id),
|
|
3783
|
+
"aria-label": fill(T.removeAttachment, { name: entry.name }),
|
|
3784
|
+
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",
|
|
3785
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
|
|
3786
|
+
}
|
|
3787
|
+
)
|
|
3788
|
+
]
|
|
3789
|
+
},
|
|
3790
|
+
entry.id
|
|
3791
|
+
))
|
|
3792
|
+
}
|
|
3793
|
+
) : null,
|
|
3794
|
+
attachmentNotice !== null ? /* @__PURE__ */ jsx(
|
|
3795
|
+
"p",
|
|
3796
|
+
{
|
|
3797
|
+
"data-boff-explore": "attachment-notice",
|
|
3798
|
+
role: "status",
|
|
3799
|
+
className: "mb-2 text-xs text-destructive",
|
|
3800
|
+
children: attachmentNotice
|
|
3801
|
+
}
|
|
3802
|
+
) : null,
|
|
3416
3803
|
/* @__PURE__ */ jsxs(
|
|
3417
3804
|
"div",
|
|
3418
3805
|
{
|
|
@@ -3441,7 +3828,37 @@ function ExplorePage({
|
|
|
3441
3828
|
placeholder: composerDisabled ? phase === "limited" ? "Message limit reached \u2014 please try again later" : "Explore is unavailable right now" : focusedProductName ? fill(T.placeholderProduct, {
|
|
3442
3829
|
product: focusedProductName
|
|
3443
3830
|
}) : T.placeholder,
|
|
3444
|
-
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-
|
|
3831
|
+
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"
|
|
3832
|
+
}
|
|
3833
|
+
),
|
|
3834
|
+
/* @__PURE__ */ jsx(
|
|
3835
|
+
"input",
|
|
3836
|
+
{
|
|
3837
|
+
ref: fileInputRef,
|
|
3838
|
+
type: "file",
|
|
3839
|
+
multiple: true,
|
|
3840
|
+
className: "hidden",
|
|
3841
|
+
onChange: (event) => {
|
|
3842
|
+
void handleFilesPicked(event.target.files);
|
|
3843
|
+
event.target.value = "";
|
|
3844
|
+
}
|
|
3845
|
+
}
|
|
3846
|
+
),
|
|
3847
|
+
/* @__PURE__ */ jsx(
|
|
3848
|
+
Button,
|
|
3849
|
+
{
|
|
3850
|
+
"data-boff-explore": "attach",
|
|
3851
|
+
type: "button",
|
|
3852
|
+
size: "icon",
|
|
3853
|
+
variant: "ghost",
|
|
3854
|
+
disabled: composerDisabled || staged.length >= MAX_ATTACHMENTS,
|
|
3855
|
+
"aria-label": T.attach,
|
|
3856
|
+
title: `${T.attach} \u2014 ${fill(T.attachHint, {
|
|
3857
|
+
max: String(MAX_ATTACHMENTS),
|
|
3858
|
+
size: String(MAX_ATTACHMENT_BYTES / (1024 * 1024))
|
|
3859
|
+
})}`,
|
|
3860
|
+
onClick: () => fileInputRef.current?.click(),
|
|
3861
|
+
children: /* @__PURE__ */ jsx(Paperclip, { className: "h-4 w-4" })
|
|
3445
3862
|
}
|
|
3446
3863
|
),
|
|
3447
3864
|
speech.supported ? /* @__PURE__ */ jsx(
|