@akropolys/kiku 1.6.2 → 1.6.4
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 +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +406 -93
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +406 -93
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +196 -3
- package/dist/styles.css.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -52,7 +52,7 @@ var SearchIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { wid
|
|
|
52
52
|
function SearchBar({
|
|
53
53
|
placeholder = "Search products\u2026",
|
|
54
54
|
limit = 10,
|
|
55
|
-
debounceMs =
|
|
55
|
+
debounceMs = 150,
|
|
56
56
|
onSelect,
|
|
57
57
|
className,
|
|
58
58
|
inputClassName,
|
|
@@ -63,10 +63,8 @@ function SearchBar({
|
|
|
63
63
|
}) {
|
|
64
64
|
const [query, setQuery] = (0, import_react.useState)("");
|
|
65
65
|
const [open, setOpen] = (0, import_react.useState)(false);
|
|
66
|
-
const
|
|
67
|
-
const { results, loading, search, clear } = (0, import_sdk.useSearch)();
|
|
66
|
+
const { results, loading, search, clear } = (0, import_sdk.useSearch)({ debounceMs });
|
|
68
67
|
const client = (0, import_sdk.useAkropolysContext)();
|
|
69
|
-
const timer = (0, import_react.useRef)();
|
|
70
68
|
const wrap = (0, import_react.useRef)(null);
|
|
71
69
|
const ignoreNextQueryChange = (0, import_react.useRef)(false);
|
|
72
70
|
(0, import_react.useEffect)(() => {
|
|
@@ -74,20 +72,13 @@ function SearchBar({
|
|
|
74
72
|
ignoreNextQueryChange.current = false;
|
|
75
73
|
return;
|
|
76
74
|
}
|
|
77
|
-
clearTimeout(timer.current);
|
|
78
75
|
if (!query.trim()) {
|
|
79
76
|
clear();
|
|
80
77
|
setOpen(false);
|
|
81
|
-
setIsDebouncing(false);
|
|
82
78
|
return;
|
|
83
79
|
}
|
|
84
80
|
setOpen(true);
|
|
85
|
-
|
|
86
|
-
timer.current = setTimeout(() => {
|
|
87
|
-
setIsDebouncing(false);
|
|
88
|
-
search(query, limit);
|
|
89
|
-
}, debounceMs);
|
|
90
|
-
return () => clearTimeout(timer.current);
|
|
81
|
+
search(query, limit);
|
|
91
82
|
}, [query]);
|
|
92
83
|
(0, import_react.useEffect)(() => {
|
|
93
84
|
const h = (e) => {
|
|
@@ -143,8 +134,8 @@ function SearchBar({
|
|
|
143
134
|
}
|
|
144
135
|
),
|
|
145
136
|
showDrop && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: cn("hsk-sb-drop", classNames.dropdown, dropdownClassName), style: { position: "absolute" }, children: [
|
|
146
|
-
|
|
147
|
-
|
|
137
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hsk-sb-loading-bar" }),
|
|
138
|
+
loading && results.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
148
139
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "hsk-sb-skeleton-row", children: [
|
|
149
140
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "hsk-sb-skeleton-icon" }),
|
|
150
141
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "hsk-sb-row-body", children: [
|
|
@@ -160,36 +151,52 @@ function SearchBar({
|
|
|
160
151
|
] })
|
|
161
152
|
] })
|
|
162
153
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
163
|
-
results.length === 0 && !loading &&
|
|
154
|
+
results.length === 0 && !loading && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "hsk-sb-empty", children: [
|
|
164
155
|
"No results for \u201C",
|
|
165
156
|
query,
|
|
166
157
|
"\u201D"
|
|
167
158
|
] }),
|
|
168
|
-
results.map((r, i) =>
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
159
|
+
results.map((r, i) => {
|
|
160
|
+
if (renderResult) {
|
|
161
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
162
|
+
"div",
|
|
163
|
+
{
|
|
164
|
+
onClick: () => handleSelect(r),
|
|
165
|
+
className: "hsk-sb-fade",
|
|
166
|
+
style: { animationDelay: `${i * 18}ms` },
|
|
167
|
+
children: renderResult(r)
|
|
168
|
+
},
|
|
169
|
+
r.id
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
const thumb = r.entity.image ?? r.entity.thumbnail ?? r.entity.images?.[0];
|
|
173
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
174
|
+
"div",
|
|
175
|
+
{
|
|
176
|
+
className: cn("hsk-sb-row hsk-sb-fade", classNames.row),
|
|
177
|
+
style: { animationDelay: `${i * 18}ms` },
|
|
178
|
+
onClick: () => handleSelect(r),
|
|
179
|
+
children: [
|
|
180
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "hsk-sb-row-thumb", children: thumb ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
181
|
+
"img",
|
|
182
|
+
{
|
|
183
|
+
src: thumb,
|
|
184
|
+
alt: "",
|
|
185
|
+
loading: "lazy",
|
|
186
|
+
onError: (e) => {
|
|
187
|
+
e.currentTarget.style.display = "none";
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SearchIcon, {}) }),
|
|
191
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "hsk-sb-row-body", children: [
|
|
192
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hsk-sb-row-title", children: r.entity.title ?? r.entity.name }),
|
|
193
|
+
(r.entity.category || r.entity.brand) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hsk-sb-row-sub", children: r.entity.category ?? r.entity.brand })
|
|
194
|
+
] })
|
|
195
|
+
]
|
|
196
|
+
},
|
|
197
|
+
r.id
|
|
198
|
+
);
|
|
199
|
+
})
|
|
193
200
|
] })
|
|
194
201
|
] })
|
|
195
202
|
] });
|
|
@@ -1199,6 +1206,25 @@ var ShoppingBagIcon = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg",
|
|
|
1199
1206
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
|
|
1200
1207
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M16 10a4 4 0 0 1-8 0" })
|
|
1201
1208
|
] });
|
|
1209
|
+
var SecureShieldIcon = ({ className, size = 18 }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1210
|
+
"svg",
|
|
1211
|
+
{
|
|
1212
|
+
className,
|
|
1213
|
+
width: size,
|
|
1214
|
+
height: size,
|
|
1215
|
+
viewBox: "0 0 24 24",
|
|
1216
|
+
fill: "none",
|
|
1217
|
+
stroke: "currentColor",
|
|
1218
|
+
strokeWidth: "2.5",
|
|
1219
|
+
strokeLinecap: "round",
|
|
1220
|
+
strokeLinejoin: "round",
|
|
1221
|
+
children: [
|
|
1222
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }),
|
|
1223
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 11a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z" }),
|
|
1224
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 11v4" })
|
|
1225
|
+
]
|
|
1226
|
+
}
|
|
1227
|
+
);
|
|
1202
1228
|
var PaperclipIcon = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48" }) });
|
|
1203
1229
|
var MicIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1204
1230
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z" }),
|
|
@@ -1221,6 +1247,173 @@ var DEFAULT_CHIPS = [
|
|
|
1221
1247
|
];
|
|
1222
1248
|
var SESSIONS_KEY = "akropolys_chat_sessions";
|
|
1223
1249
|
var MAX_SESSIONS = 20;
|
|
1250
|
+
function parseAtKiku(raw) {
|
|
1251
|
+
const trimmed = raw.trim();
|
|
1252
|
+
if (!/^@kiku\b/i.test(trimmed)) return null;
|
|
1253
|
+
const rest = trimmed.slice(5).trim();
|
|
1254
|
+
if (rest === "" || /^(capture|save)\b/i.test(rest)) {
|
|
1255
|
+
return {
|
|
1256
|
+
intent: "capture",
|
|
1257
|
+
cleanQuery: rest.replace(/^(capture|save)\s*/i, "").trim() || trimmed
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1260
|
+
if (/^(history|what have you|show my|my items|what did you|saved|captures|recall)\b/i.test(rest)) {
|
|
1261
|
+
return { intent: "view_history", cleanQuery: "show my saved items" };
|
|
1262
|
+
}
|
|
1263
|
+
if (/^(delete|forget|remove|unsave)\b/i.test(rest)) {
|
|
1264
|
+
return {
|
|
1265
|
+
intent: "delete",
|
|
1266
|
+
cleanQuery: rest.replace(/^(delete|forget|remove|unsave)\s*/i, "").trim() || trimmed
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
return { intent: "capture", cleanQuery: rest || trimmed };
|
|
1270
|
+
}
|
|
1271
|
+
function KikuPickerMenu({
|
|
1272
|
+
sources,
|
|
1273
|
+
referencedIds,
|
|
1274
|
+
defaultCurrency,
|
|
1275
|
+
onCapture,
|
|
1276
|
+
onCaptureAll,
|
|
1277
|
+
onViewHistory,
|
|
1278
|
+
onDelete,
|
|
1279
|
+
onDismiss
|
|
1280
|
+
}) {
|
|
1281
|
+
const discussed = sources.filter((s) => s.id && referencedIds.includes(s.id));
|
|
1282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1283
|
+
"div",
|
|
1284
|
+
{
|
|
1285
|
+
className: "hsk-kiku-picker",
|
|
1286
|
+
role: "menu",
|
|
1287
|
+
"aria-label": "@kiku commands",
|
|
1288
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
1289
|
+
children: [
|
|
1290
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-kiku-picker-header", children: [
|
|
1291
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-at", children: "@kiku" }),
|
|
1292
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-hint", children: "What would you like to do?" }),
|
|
1293
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-kiku-picker-close", onClick: onDismiss, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CloseIcon, {}) })
|
|
1294
|
+
] }),
|
|
1295
|
+
discussed.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1296
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-kiku-picker-section", children: "Discussed in this chat" }),
|
|
1297
|
+
discussed.map((src, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1298
|
+
"button",
|
|
1299
|
+
{
|
|
1300
|
+
className: "hsk-kiku-picker-item",
|
|
1301
|
+
role: "menuitem",
|
|
1302
|
+
onClick: () => {
|
|
1303
|
+
onCapture(src);
|
|
1304
|
+
onDismiss();
|
|
1305
|
+
},
|
|
1306
|
+
children: [
|
|
1307
|
+
src.image ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: src.image, alt: src.name, className: "hsk-kiku-picker-img" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-img-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SecureShieldIcon, { size: 14 }) }),
|
|
1308
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "hsk-kiku-picker-item-body", children: [
|
|
1309
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "hsk-kiku-picker-item-name", children: [
|
|
1310
|
+
"\u{1F4CC} ",
|
|
1311
|
+
src.name
|
|
1312
|
+
] }),
|
|
1313
|
+
src.price && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "hsk-kiku-picker-item-price", children: [
|
|
1314
|
+
src.currency ?? defaultCurrency,
|
|
1315
|
+
" ",
|
|
1316
|
+
parseFloat(String(src.price).replace(/[^0-9.]/g, "") || "0").toLocaleString()
|
|
1317
|
+
] })
|
|
1318
|
+
] })
|
|
1319
|
+
]
|
|
1320
|
+
},
|
|
1321
|
+
src.id ?? i
|
|
1322
|
+
)),
|
|
1323
|
+
discussed.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1324
|
+
"button",
|
|
1325
|
+
{
|
|
1326
|
+
className: "hsk-kiku-picker-item hsk-kiku-picker-item--all",
|
|
1327
|
+
role: "menuitem",
|
|
1328
|
+
onClick: () => {
|
|
1329
|
+
onCaptureAll(discussed);
|
|
1330
|
+
onDismiss();
|
|
1331
|
+
},
|
|
1332
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-item-body", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "hsk-kiku-picker-item-name", children: [
|
|
1333
|
+
"\u{1F4CC} Capture all (",
|
|
1334
|
+
discussed.length,
|
|
1335
|
+
" items)"
|
|
1336
|
+
] }) })
|
|
1337
|
+
}
|
|
1338
|
+
),
|
|
1339
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-kiku-picker-divider" })
|
|
1340
|
+
] }),
|
|
1341
|
+
discussed.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1342
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1343
|
+
"button",
|
|
1344
|
+
{
|
|
1345
|
+
className: "hsk-kiku-picker-item",
|
|
1346
|
+
role: "menuitem",
|
|
1347
|
+
onClick: () => {
|
|
1348
|
+
onCapture({ name: "current page", id: void 0 });
|
|
1349
|
+
onDismiss();
|
|
1350
|
+
},
|
|
1351
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-item-body", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-item-name", children: "\u{1F4CC} Capture current page" }) })
|
|
1352
|
+
}
|
|
1353
|
+
),
|
|
1354
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-kiku-picker-divider" })
|
|
1355
|
+
] }),
|
|
1356
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1357
|
+
"button",
|
|
1358
|
+
{
|
|
1359
|
+
className: "hsk-kiku-picker-item",
|
|
1360
|
+
role: "menuitem",
|
|
1361
|
+
onClick: () => {
|
|
1362
|
+
onViewHistory();
|
|
1363
|
+
onDismiss();
|
|
1364
|
+
},
|
|
1365
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-item-body", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-item-name", children: "\u{1F4CB} What have you saved?" }) })
|
|
1366
|
+
}
|
|
1367
|
+
),
|
|
1368
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1369
|
+
"button",
|
|
1370
|
+
{
|
|
1371
|
+
className: "hsk-kiku-picker-item",
|
|
1372
|
+
role: "menuitem",
|
|
1373
|
+
onClick: () => {
|
|
1374
|
+
onDelete();
|
|
1375
|
+
onDismiss();
|
|
1376
|
+
},
|
|
1377
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-item-body", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-item-name", children: "\u{1F5D1}\uFE0F Delete this" }) })
|
|
1378
|
+
}
|
|
1379
|
+
)
|
|
1380
|
+
]
|
|
1381
|
+
}
|
|
1382
|
+
);
|
|
1383
|
+
}
|
|
1384
|
+
function AtPickerMenu({ onSelect, onDismiss }) {
|
|
1385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1386
|
+
"div",
|
|
1387
|
+
{
|
|
1388
|
+
className: "hsk-kiku-picker",
|
|
1389
|
+
role: "menu",
|
|
1390
|
+
"aria-label": "Extensions",
|
|
1391
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
1392
|
+
children: [
|
|
1393
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-kiku-picker-header", children: [
|
|
1394
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-at", children: "@" }),
|
|
1395
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-hint", children: "Use an extension" }),
|
|
1396
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-kiku-picker-close", onClick: onDismiss, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CloseIcon, {}) })
|
|
1397
|
+
] }),
|
|
1398
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1399
|
+
"button",
|
|
1400
|
+
{
|
|
1401
|
+
className: "hsk-kiku-picker-item",
|
|
1402
|
+
role: "menuitem",
|
|
1403
|
+
onClick: () => onSelect("@kiku"),
|
|
1404
|
+
children: [
|
|
1405
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-img-placeholder", style: { background: "color-mix(in srgb, var(--hsk-primary, #7c5cfc) 15%, transparent)", color: "var(--hsk-primary, #7c5cfc)" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparkleIcon2, {}) }),
|
|
1406
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "hsk-kiku-picker-item-body", children: [
|
|
1407
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-item-name", children: "@kiku" }),
|
|
1408
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-picker-item-price", style: { fontSize: "11px", whiteSpace: "normal", lineHeight: "1.3" }, children: "Ask Kiku to capture pages, remember items, or show your history" })
|
|
1409
|
+
] })
|
|
1410
|
+
]
|
|
1411
|
+
}
|
|
1412
|
+
)
|
|
1413
|
+
]
|
|
1414
|
+
}
|
|
1415
|
+
);
|
|
1416
|
+
}
|
|
1224
1417
|
function loadSessions() {
|
|
1225
1418
|
try {
|
|
1226
1419
|
if (typeof window === "undefined") return [];
|
|
@@ -1541,18 +1734,7 @@ var getFriendlyError = (err) => {
|
|
|
1541
1734
|
return str;
|
|
1542
1735
|
}
|
|
1543
1736
|
};
|
|
1544
|
-
var
|
|
1545
|
-
var MK_NOUN = ["thunder", "falcon", "river", "ember", "tiger", "comet", "willow", "onyx"];
|
|
1546
|
-
function generateMagicWord() {
|
|
1547
|
-
return MK_ADJ[Math.floor(Math.random() * MK_ADJ.length)] + MK_NOUN[Math.floor(Math.random() * MK_NOUN.length)];
|
|
1548
|
-
}
|
|
1549
|
-
function parseMemoryKey(raw) {
|
|
1550
|
-
const cleaned = raw.trim().replace(/\s+/g, "");
|
|
1551
|
-
const m = cleaned.match(/^(\d{6,})([a-zA-Z].*)?$/);
|
|
1552
|
-
const phone = m?.[1] || cleaned.replace(/\D/g, "");
|
|
1553
|
-
const word = (m?.[2] || "").toLowerCase() || generateMagicWord();
|
|
1554
|
-
return { phone, word };
|
|
1555
|
-
}
|
|
1737
|
+
var KIKU_KEY_REVEAL_SECONDS = 60;
|
|
1556
1738
|
function parseThinking(text) {
|
|
1557
1739
|
const openMatch = text.match(/<\s*thinking\s*>/i);
|
|
1558
1740
|
if (!openMatch) {
|
|
@@ -1660,6 +1842,7 @@ function ChatModal({
|
|
|
1660
1842
|
theme,
|
|
1661
1843
|
classNames = {},
|
|
1662
1844
|
enableVoice = false,
|
|
1845
|
+
voiceLang,
|
|
1663
1846
|
enableVision = false,
|
|
1664
1847
|
visionCategoryHint
|
|
1665
1848
|
}) {
|
|
@@ -1693,7 +1876,7 @@ function ChatModal({
|
|
|
1693
1876
|
if (!hasSpeechAPI || voiceState !== "idle") return;
|
|
1694
1877
|
const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
1695
1878
|
const recognition = new SR();
|
|
1696
|
-
recognition.lang = "en-US";
|
|
1879
|
+
recognition.lang = voiceLang || document.documentElement.lang || navigator.language || "en-US";
|
|
1697
1880
|
recognition.interimResults = true;
|
|
1698
1881
|
recognition.maxAlternatives = 1;
|
|
1699
1882
|
recognitionRef.current = recognition;
|
|
@@ -1726,7 +1909,7 @@ function ChatModal({
|
|
|
1726
1909
|
setVoiceState((prev) => prev === "listening" ? "idle" : prev);
|
|
1727
1910
|
};
|
|
1728
1911
|
recognition.start();
|
|
1729
|
-
}, [hasSpeechAPI, voiceState]);
|
|
1912
|
+
}, [hasSpeechAPI, voiceState, voiceLang]);
|
|
1730
1913
|
const stopVoice = (0, import_react5.useCallback)(() => {
|
|
1731
1914
|
recognitionRef.current?.stop();
|
|
1732
1915
|
setVoiceState("idle");
|
|
@@ -1741,23 +1924,37 @@ function ChatModal({
|
|
|
1741
1924
|
const [selectedProduct, setSelectedProduct] = (0, import_react5.useState)(null);
|
|
1742
1925
|
const bottomRef = (0, import_react5.useRef)(null);
|
|
1743
1926
|
const textareaRef = (0, import_react5.useRef)(null);
|
|
1744
|
-
const [
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
const [
|
|
1751
|
-
const [memoryKey, setMemoryKey] = (0, import_react5.useState)(null);
|
|
1927
|
+
const [keyInput, setKeyInput] = (0, import_react5.useState)("");
|
|
1928
|
+
const [keyPhase, setKeyPhase] = (0, import_react5.useState)("idle");
|
|
1929
|
+
const [mintedKey, setMintedKey] = (0, import_react5.useState)(null);
|
|
1930
|
+
const [keyCountdown, setKeyCountdown] = (0, import_react5.useState)(KIKU_KEY_REVEAL_SECONDS);
|
|
1931
|
+
const [minting, setMinting] = (0, import_react5.useState)(false);
|
|
1932
|
+
const [showKikuPicker, setShowKikuPicker] = (0, import_react5.useState)(false);
|
|
1933
|
+
const [showAtPicker, setShowAtPicker] = (0, import_react5.useState)(false);
|
|
1752
1934
|
const [sessions, setSessions] = (0, import_react5.useState)(() => loadSessions());
|
|
1753
1935
|
const [sidebarOpen, setSidebarOpen] = (0, import_react5.useState)(false);
|
|
1754
1936
|
const [replayMessages, setReplayMessages] = (0, import_react5.useState)(null);
|
|
1755
1937
|
(0, import_react5.useEffect)(() => {
|
|
1756
1938
|
if (!lastAction) return;
|
|
1757
|
-
if (lastAction.type === "
|
|
1758
|
-
|
|
1939
|
+
if (lastAction.type === "request_kiku_key") {
|
|
1940
|
+
setKeyPhase("prompt_key");
|
|
1759
1941
|
}
|
|
1760
1942
|
}, [lastAction]);
|
|
1943
|
+
(0, import_react5.useEffect)(() => {
|
|
1944
|
+
if (!mintedKey) return;
|
|
1945
|
+
setKeyCountdown(KIKU_KEY_REVEAL_SECONDS);
|
|
1946
|
+
const t = setInterval(() => {
|
|
1947
|
+
setKeyCountdown((s) => {
|
|
1948
|
+
if (s <= 1) {
|
|
1949
|
+
clearInterval(t);
|
|
1950
|
+
setMintedKey(null);
|
|
1951
|
+
return 0;
|
|
1952
|
+
}
|
|
1953
|
+
return s - 1;
|
|
1954
|
+
});
|
|
1955
|
+
}, 1e3);
|
|
1956
|
+
return () => clearInterval(t);
|
|
1957
|
+
}, [mintedKey]);
|
|
1761
1958
|
const isStringTheme = typeof theme === "string";
|
|
1762
1959
|
const hskThemeAttr = isStringTheme ? theme : void 0;
|
|
1763
1960
|
const customStyles = !isStringTheme && theme ? {
|
|
@@ -1767,16 +1964,30 @@ function ChatModal({
|
|
|
1767
1964
|
...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
|
|
1768
1965
|
...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
|
|
1769
1966
|
} : void 0;
|
|
1770
|
-
const
|
|
1771
|
-
if (!phoneInput.trim()) return;
|
|
1772
|
-
const { phone, word } = parseMemoryKey(phoneInput);
|
|
1773
|
-
if (!phone) return;
|
|
1774
|
-
if (typeof window !== "undefined") localStorage.setItem("akropolys_user_phone", phone);
|
|
1775
|
-
client.setShopperIdentity(phone, word);
|
|
1776
|
-
setMemoryKey(phone + word);
|
|
1777
|
-
setPaymentPhase("idle");
|
|
1967
|
+
const retryLastMessage = async () => {
|
|
1778
1968
|
const lastUserMsg = [...messages].reverse().find((m) => m.role === "user");
|
|
1779
|
-
if (lastUserMsg) await
|
|
1969
|
+
if (lastUserMsg) await handleSend(lastUserMsg.content);
|
|
1970
|
+
};
|
|
1971
|
+
const handleUseExistingKey = async () => {
|
|
1972
|
+
const key = keyInput.trim();
|
|
1973
|
+
if (!key) return;
|
|
1974
|
+
client.setKikuKey(key);
|
|
1975
|
+
setKeyInput("");
|
|
1976
|
+
setKeyPhase("idle");
|
|
1977
|
+
await retryLastMessage();
|
|
1978
|
+
};
|
|
1979
|
+
const handleCreateKey = async () => {
|
|
1980
|
+
if (minting) return;
|
|
1981
|
+
setMinting(true);
|
|
1982
|
+
try {
|
|
1983
|
+
const key = await client.mintKikuKey();
|
|
1984
|
+
setMintedKey(key);
|
|
1985
|
+
setKeyPhase("idle");
|
|
1986
|
+
await retryLastMessage();
|
|
1987
|
+
} catch {
|
|
1988
|
+
} finally {
|
|
1989
|
+
setMinting(false);
|
|
1990
|
+
}
|
|
1780
1991
|
};
|
|
1781
1992
|
const msgsContainerRef = (0, import_react5.useRef)(null);
|
|
1782
1993
|
(0, import_react5.useEffect)(() => {
|
|
@@ -1811,7 +2022,7 @@ function ChatModal({
|
|
|
1811
2022
|
saveCurrentSession();
|
|
1812
2023
|
reset();
|
|
1813
2024
|
setReplayMessages(null);
|
|
1814
|
-
|
|
2025
|
+
setKeyPhase("idle");
|
|
1815
2026
|
}, [reset, saveCurrentSession]);
|
|
1816
2027
|
const handleSourceClick = (src) => {
|
|
1817
2028
|
setSelectedProduct(src);
|
|
@@ -1819,27 +2030,97 @@ function ChatModal({
|
|
|
1819
2030
|
const q = `Tell me more about the ${src.name}${src.price ? ` (${src.currency ?? defaultCurrency} ${src.price})` : ""} \u2014 what are its key specs, who is it best for, and is it worth buying?`;
|
|
1820
2031
|
send(q);
|
|
1821
2032
|
};
|
|
1822
|
-
const handleSend = async (text, extraAttachments) => {
|
|
1823
|
-
const
|
|
1824
|
-
if (!
|
|
2033
|
+
const handleSend = async (text, extraAttachments, forcedIntent, captureTargets) => {
|
|
2034
|
+
const raw = (text ?? input).trim();
|
|
2035
|
+
if (!raw || loading) return;
|
|
2036
|
+
const kiku = parseAtKiku(raw);
|
|
2037
|
+
const q = kiku ? kiku.cleanQuery : raw;
|
|
2038
|
+
const resolvedForcedIntent = forcedIntent ?? kiku?.intent;
|
|
1825
2039
|
setReplayMessages(null);
|
|
1826
2040
|
setSelectedProduct(null);
|
|
2041
|
+
setShowKikuPicker(false);
|
|
2042
|
+
setShowAtPicker(false);
|
|
1827
2043
|
setInput("");
|
|
1828
2044
|
if (textareaRef.current) {
|
|
1829
2045
|
textareaRef.current.style.height = "auto";
|
|
1830
2046
|
}
|
|
1831
2047
|
const toSend = extraAttachments ?? attachments;
|
|
1832
2048
|
setAttachments([]);
|
|
1833
|
-
await send(q,
|
|
2049
|
+
await send(q, raw, toSend.length > 0 ? toSend : void 0, resolvedForcedIntent, captureTargets);
|
|
1834
2050
|
};
|
|
2051
|
+
const handleSelectExtension = (ext) => {
|
|
2052
|
+
setInput(ext + " ");
|
|
2053
|
+
setShowAtPicker(false);
|
|
2054
|
+
setShowKikuPicker(true);
|
|
2055
|
+
if (textareaRef.current) {
|
|
2056
|
+
textareaRef.current.focus();
|
|
2057
|
+
}
|
|
2058
|
+
};
|
|
2059
|
+
const handleKikuCapture = (0, import_react5.useCallback)((product) => {
|
|
2060
|
+
const name = product.name || "";
|
|
2061
|
+
const display = `@kiku capture${name ? " " + name : ""}`;
|
|
2062
|
+
const q = name || "capture current page";
|
|
2063
|
+
setInput("");
|
|
2064
|
+
setReplayMessages(null);
|
|
2065
|
+
setSelectedProduct(null);
|
|
2066
|
+
const toSend = attachments;
|
|
2067
|
+
setAttachments([]);
|
|
2068
|
+
send(q, display, toSend.length > 0 ? toSend : void 0, "capture");
|
|
2069
|
+
}, [attachments, send]);
|
|
2070
|
+
const handleKikuCaptureAll = (0, import_react5.useCallback)((products) => {
|
|
2071
|
+
const targets = products.filter((p) => p.id).map((p) => ({
|
|
2072
|
+
name: p.name || "",
|
|
2073
|
+
url: p.url || "",
|
|
2074
|
+
image: p.image || "",
|
|
2075
|
+
price: p.price ? String(p.price) : "",
|
|
2076
|
+
currency: p.currency || defaultCurrency
|
|
2077
|
+
}));
|
|
2078
|
+
const names = products.map((p) => p.name).filter(Boolean).join(", ");
|
|
2079
|
+
const display = `@kiku capture all (${products.length} items)`;
|
|
2080
|
+
setInput("");
|
|
2081
|
+
setReplayMessages(null);
|
|
2082
|
+
setSelectedProduct(null);
|
|
2083
|
+
setAttachments([]);
|
|
2084
|
+
send(names || "capture all", display, void 0, "capture_all", targets);
|
|
2085
|
+
}, [defaultCurrency, send]);
|
|
2086
|
+
const handleKikuViewHistory = (0, import_react5.useCallback)(() => {
|
|
2087
|
+
const display = "@kiku what have you saved?";
|
|
2088
|
+
setInput("");
|
|
2089
|
+
setReplayMessages(null);
|
|
2090
|
+
setSelectedProduct(null);
|
|
2091
|
+
setAttachments([]);
|
|
2092
|
+
send("show my saved items", display, void 0, "view_history");
|
|
2093
|
+
}, [send]);
|
|
2094
|
+
const handleKikuDelete = (0, import_react5.useCallback)(() => {
|
|
2095
|
+
const display = "@kiku delete this";
|
|
2096
|
+
setInput("");
|
|
2097
|
+
setReplayMessages(null);
|
|
2098
|
+
setSelectedProduct(null);
|
|
2099
|
+
setAttachments([]);
|
|
2100
|
+
send("delete this", display, void 0, "delete");
|
|
2101
|
+
}, [send]);
|
|
1835
2102
|
const handleKeyDown = (e) => {
|
|
2103
|
+
if (e.key === "Escape" && showKikuPicker) {
|
|
2104
|
+
e.preventDefault();
|
|
2105
|
+
setShowKikuPicker(false);
|
|
2106
|
+
return;
|
|
2107
|
+
}
|
|
2108
|
+
if (e.key === "Escape" && showAtPicker) {
|
|
2109
|
+
e.preventDefault();
|
|
2110
|
+
setShowAtPicker(false);
|
|
2111
|
+
return;
|
|
2112
|
+
}
|
|
1836
2113
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
1837
2114
|
e.preventDefault();
|
|
1838
2115
|
handleSend();
|
|
1839
2116
|
}
|
|
1840
2117
|
};
|
|
1841
2118
|
const handleInput = (e) => {
|
|
1842
|
-
|
|
2119
|
+
const val = e.target.value;
|
|
2120
|
+
setInput(val);
|
|
2121
|
+
const trimmed = val.trim();
|
|
2122
|
+
setShowAtPicker(trimmed === "@");
|
|
2123
|
+
setShowKikuPicker(/^@kiku\b/i.test(trimmed));
|
|
1843
2124
|
const t = e.target;
|
|
1844
2125
|
t.style.height = "auto";
|
|
1845
2126
|
t.style.height = `${Math.min(t.scrollHeight, 140)}px`;
|
|
@@ -1976,7 +2257,10 @@ function ChatModal({
|
|
|
1976
2257
|
const displayContent = !isUser && isLast && lastIntent === "compare" && sources.length >= 2 && !replayMessages ? stripMarkdownTables(msg.content) : msg.content;
|
|
1977
2258
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-user-msg", children: [
|
|
1978
2259
|
msg.images && msg.images.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-user-imgs", children: msg.images.map((img, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: img, alt: `attachment ${i + 1}`, className: "hsk-cb-user-img-thumb" }, i)) }),
|
|
1979
|
-
msg.content && /* @__PURE__ */ (0, import_jsx_runtime7.
|
|
2260
|
+
msg.content && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-user-bubble", children: [
|
|
2261
|
+
/^@kiku\b/i.test(msg.content) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-kiku-badge", children: "@kiku" }),
|
|
2262
|
+
msg.content
|
|
2263
|
+
] })
|
|
1980
2264
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-ai-msg", children: [
|
|
1981
2265
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparkleIcon2, {}) }),
|
|
1982
2266
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-ai-body", children: [
|
|
@@ -1991,7 +2275,7 @@ function ChatModal({
|
|
|
1991
2275
|
] });
|
|
1992
2276
|
})(),
|
|
1993
2277
|
isLast && lastIntent === "compare" && sources.length >= 2 && !replayMessages && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ComparisonMatrix, { sources, defaultCurrency }),
|
|
1994
|
-
isLast && referencedIds.length > 0 && lastIntent !== "compare" && lastAction?.type !== "
|
|
2278
|
+
isLast && referencedIds.length > 0 && lastIntent !== "compare" && lastAction?.type !== "request_kiku_key" && lastAction?.type !== "awaiting_payment" && lastAction?.type !== "checkout" && lastAction?.type !== "capture" && lastAction?.type !== "delete" && lastAction?.type !== "view_history" && !msg.cartSnapshot && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1995
2279
|
SourcesCarousel,
|
|
1996
2280
|
{
|
|
1997
2281
|
sources,
|
|
@@ -2064,44 +2348,71 @@ function ChatModal({
|
|
|
2064
2348
|
] })
|
|
2065
2349
|
] }),
|
|
2066
2350
|
error && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-error", children: getFriendlyError(error) }),
|
|
2067
|
-
!replayMessages &&
|
|
2351
|
+
!replayMessages && keyPhase === "prompt_key" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-ai-msg", children: [
|
|
2068
2352
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparkleIcon2, {}) }),
|
|
2069
2353
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-ai-body", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-ai-text", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-phone-form", children: [
|
|
2070
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("label", { className: "hsk-cb-phone-label", children: "
|
|
2354
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("label", { className: "hsk-cb-phone-label", children: "Paste your kiku key \u2014 or create one" }),
|
|
2071
2355
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2072
2356
|
"input",
|
|
2073
2357
|
{
|
|
2074
2358
|
type: "text",
|
|
2075
2359
|
className: "hsk-cb-phone-input",
|
|
2076
|
-
placeholder: "
|
|
2077
|
-
value:
|
|
2078
|
-
onChange: (e) =>
|
|
2079
|
-
onKeyDown: (e) => e.key === "Enter" &&
|
|
2360
|
+
placeholder: "kiku_\u2026",
|
|
2361
|
+
value: keyInput,
|
|
2362
|
+
onChange: (e) => setKeyInput(e.target.value),
|
|
2363
|
+
onKeyDown: (e) => e.key === "Enter" && handleUseExistingKey(),
|
|
2080
2364
|
autoFocus: true
|
|
2081
2365
|
}
|
|
2082
2366
|
),
|
|
2083
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.
|
|
2367
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", gap: 8 }, children: [
|
|
2368
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-cb-phone-submit", onClick: handleUseExistingKey, disabled: !keyInput.trim(), children: "Use my key" }),
|
|
2369
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-cb-phone-submit", onClick: handleCreateKey, disabled: minting, children: minting ? "Creating\u2026" : "I'm new \u2014 create my key" })
|
|
2370
|
+
] })
|
|
2084
2371
|
] }) }) })
|
|
2085
2372
|
] }),
|
|
2086
|
-
!replayMessages &&
|
|
2373
|
+
!replayMessages && mintedKey && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-ai-msg", children: [
|
|
2087
2374
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparkleIcon2, {}) }),
|
|
2088
2375
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-ai-body", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-ai-text", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { padding: "10px 12px", border: "1px solid var(--hsk-border, #e5e5e5)", borderRadius: 8 }, children: [
|
|
2089
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontSize: 12, fontWeight: 600, marginBottom: 4 }, children: "\u{1F511} Your
|
|
2090
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { style: { display: "block", fontSize: 14, fontWeight: 700, marginBottom: 6, wordBreak: "break-all" }, children:
|
|
2376
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontSize: 12, fontWeight: 600, marginBottom: 4 }, children: "\u{1F511} Your kiku key \u2014 shown only once" }),
|
|
2377
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { style: { display: "block", fontSize: 14, fontWeight: 700, marginBottom: 6, wordBreak: "break-all" }, children: mintedKey }),
|
|
2091
2378
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
|
|
2092
2379
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-cb-phone-submit", style: { padding: "4px 10px" }, onClick: () => {
|
|
2093
2380
|
try {
|
|
2094
|
-
navigator.clipboard?.writeText(
|
|
2381
|
+
navigator.clipboard?.writeText(mintedKey);
|
|
2095
2382
|
} catch {
|
|
2096
2383
|
}
|
|
2097
2384
|
}, children: "Copy" }),
|
|
2098
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.
|
|
2385
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: { fontSize: 11, opacity: 0.7 }, children: [
|
|
2386
|
+
"Disappears in ",
|
|
2387
|
+
keyCountdown,
|
|
2388
|
+
"s. Save it like a password \u2014 if lost, the memory it opens is lost with it."
|
|
2389
|
+
] })
|
|
2099
2390
|
] })
|
|
2100
2391
|
] }) }) })
|
|
2101
2392
|
] }),
|
|
2102
2393
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref: bottomRef, style: { height: 1 } })
|
|
2103
2394
|
] }),
|
|
2104
2395
|
!replayMessages && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-input-wrap", children: [
|
|
2396
|
+
showAtPicker && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2397
|
+
AtPickerMenu,
|
|
2398
|
+
{
|
|
2399
|
+
onSelect: handleSelectExtension,
|
|
2400
|
+
onDismiss: () => setShowAtPicker(false)
|
|
2401
|
+
}
|
|
2402
|
+
),
|
|
2403
|
+
showKikuPicker && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2404
|
+
KikuPickerMenu,
|
|
2405
|
+
{
|
|
2406
|
+
sources,
|
|
2407
|
+
referencedIds,
|
|
2408
|
+
defaultCurrency,
|
|
2409
|
+
onCapture: handleKikuCapture,
|
|
2410
|
+
onCaptureAll: handleKikuCaptureAll,
|
|
2411
|
+
onViewHistory: handleKikuViewHistory,
|
|
2412
|
+
onDelete: handleKikuDelete,
|
|
2413
|
+
onDismiss: () => setShowKikuPicker(false)
|
|
2414
|
+
}
|
|
2415
|
+
),
|
|
2105
2416
|
attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-img-strip", children: attachments.map((att, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-img-thumb-wrap", children: [
|
|
2106
2417
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: att.data, alt: `attachment ${i + 1}`, className: "hsk-cb-img-thumb" }),
|
|
2107
2418
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
@@ -2200,6 +2511,7 @@ function KikuButton({
|
|
|
2200
2511
|
theme,
|
|
2201
2512
|
classNames = {},
|
|
2202
2513
|
enableVoice = false,
|
|
2514
|
+
voiceLang,
|
|
2203
2515
|
enableVision = false,
|
|
2204
2516
|
visionCategoryHint
|
|
2205
2517
|
}) {
|
|
@@ -2269,6 +2581,7 @@ function KikuButton({
|
|
|
2269
2581
|
theme,
|
|
2270
2582
|
classNames,
|
|
2271
2583
|
enableVoice,
|
|
2584
|
+
voiceLang,
|
|
2272
2585
|
enableVision,
|
|
2273
2586
|
visionCategoryHint
|
|
2274
2587
|
}
|