@adatechnology/conversations-ui 0.1.0-rc.12 → 0.1.0-rc.13
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/{chunk-3RKFU46R.js → chunk-QFEESERN.js} +198 -107
- package/dist/index.d.ts +2 -2
- package/dist/index.js +7 -1
- package/dist/preview/index.d.ts +3 -37
- package/dist/preview/index.js +36 -124
- package/dist/{types-B5C1DLu1.d.ts → types-C_dqJ83O.d.ts} +42 -1
- package/package.json +1 -1
- package/src/{preview/audioRecorderFormat.test.ts → audioRecorderFormat.test.ts} +1 -1
- package/src/index.ts +6 -0
- package/src/preview/ConversationPreview.tsx +1 -1
- package/src/preview/index.ts +2 -2
- /package/src/{preview/AudioRecorderButton.tsx → AudioRecorderButton.tsx} +0 -0
|
@@ -1081,11 +1081,99 @@ var MessageComposer = ({
|
|
|
1081
1081
|
);
|
|
1082
1082
|
};
|
|
1083
1083
|
|
|
1084
|
+
// src/AudioRecorderButton.tsx
|
|
1085
|
+
import { useCallback as useCallback3, useRef as useRef3, useState as useState7 } from "react";
|
|
1086
|
+
import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1087
|
+
var DEFAULT_AUDIO_RECORDER_BUTTON_LABELS = {
|
|
1088
|
+
start: "Gravar \xE1udio",
|
|
1089
|
+
stop: "Parar grava\xE7\xE3o",
|
|
1090
|
+
unsupported: "Este navegador n\xE3o grava \xE1udio.",
|
|
1091
|
+
denied: "Sem permiss\xE3o para usar o microfone."
|
|
1092
|
+
};
|
|
1093
|
+
var DEFAULT_MAX_RECORDING_MILLISECONDS = 5 * 60 * 1e3;
|
|
1094
|
+
var RECORDING_FORMATS = [
|
|
1095
|
+
{ mimeType: "audio/ogg;codecs=opus", uploadMimeType: "audio/ogg", extension: "ogg" },
|
|
1096
|
+
{ mimeType: "audio/mp4", uploadMimeType: "audio/mp4", extension: "m4a" },
|
|
1097
|
+
{ mimeType: "audio/webm", uploadMimeType: "audio/webm", extension: "webm" }
|
|
1098
|
+
];
|
|
1099
|
+
function resolveRecordingFormat() {
|
|
1100
|
+
if (typeof MediaRecorder === "undefined") return void 0;
|
|
1101
|
+
if (typeof MediaRecorder.isTypeSupported !== "function") return RECORDING_FORMATS[0];
|
|
1102
|
+
return RECORDING_FORMATS.find((format) => MediaRecorder.isTypeSupported(format.mimeType));
|
|
1103
|
+
}
|
|
1104
|
+
function AudioRecorderButton({
|
|
1105
|
+
onRecorded,
|
|
1106
|
+
onFailure,
|
|
1107
|
+
onRecordingChange,
|
|
1108
|
+
maxDurationMilliseconds = DEFAULT_MAX_RECORDING_MILLISECONDS,
|
|
1109
|
+
labels,
|
|
1110
|
+
disabled
|
|
1111
|
+
}) {
|
|
1112
|
+
const startLabel = labels?.start ?? DEFAULT_AUDIO_RECORDER_BUTTON_LABELS.start;
|
|
1113
|
+
const stopLabel = labels?.stop ?? DEFAULT_AUDIO_RECORDER_BUTTON_LABELS.stop;
|
|
1114
|
+
const [isRecording, setIsRecording] = useState7(false);
|
|
1115
|
+
const recorderRef = useRef3(null);
|
|
1116
|
+
const autoStopRef = useRef3(void 0);
|
|
1117
|
+
const stop = useCallback3(() => {
|
|
1118
|
+
recorderRef.current?.stop();
|
|
1119
|
+
}, []);
|
|
1120
|
+
const start = useCallback3(async () => {
|
|
1121
|
+
const format = resolveRecordingFormat();
|
|
1122
|
+
if (!format || !navigator.mediaDevices?.getUserMedia) {
|
|
1123
|
+
onFailure?.(labels?.unsupported ?? DEFAULT_AUDIO_RECORDER_BUTTON_LABELS.unsupported);
|
|
1124
|
+
return;
|
|
1125
|
+
}
|
|
1126
|
+
try {
|
|
1127
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
1128
|
+
const recorder = new MediaRecorder(stream, { mimeType: format.mimeType });
|
|
1129
|
+
const chunks = [];
|
|
1130
|
+
recorder.addEventListener("dataavailable", (event) => {
|
|
1131
|
+
if (event.data.size > 0) chunks.push(event.data);
|
|
1132
|
+
});
|
|
1133
|
+
recorder.addEventListener("stop", () => {
|
|
1134
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
1135
|
+
clearTimeout(autoStopRef.current);
|
|
1136
|
+
setIsRecording(false);
|
|
1137
|
+
onRecordingChange?.(false);
|
|
1138
|
+
recorderRef.current = null;
|
|
1139
|
+
const blob = new Blob(chunks, { type: format.uploadMimeType });
|
|
1140
|
+
void onRecorded(
|
|
1141
|
+
new File([blob], `audio-${Date.now()}.${format.extension}`, { type: format.uploadMimeType })
|
|
1142
|
+
);
|
|
1143
|
+
});
|
|
1144
|
+
recorderRef.current = recorder;
|
|
1145
|
+
recorder.start();
|
|
1146
|
+
autoStopRef.current = setTimeout(() => recorder.stop(), maxDurationMilliseconds);
|
|
1147
|
+
setIsRecording(true);
|
|
1148
|
+
onRecordingChange?.(true);
|
|
1149
|
+
} catch {
|
|
1150
|
+
onFailure?.(labels?.denied ?? DEFAULT_AUDIO_RECORDER_BUTTON_LABELS.denied);
|
|
1151
|
+
}
|
|
1152
|
+
}, [labels?.denied, labels?.unsupported, maxDurationMilliseconds, onFailure, onRecorded, onRecordingChange]);
|
|
1153
|
+
return /* @__PURE__ */ jsx13(
|
|
1154
|
+
"button",
|
|
1155
|
+
{
|
|
1156
|
+
type: "button",
|
|
1157
|
+
disabled,
|
|
1158
|
+
onClick: () => isRecording ? stop() : void start(),
|
|
1159
|
+
title: isRecording ? stopLabel : startLabel,
|
|
1160
|
+
"aria-label": isRecording ? stopLabel : startLabel,
|
|
1161
|
+
"aria-pressed": isRecording,
|
|
1162
|
+
className: `flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-full transition-colors ${isRecording ? "animate-pulse bg-red-500 text-white ring-4 ring-red-500/30 hover:bg-red-600" : "text-gray-500 hover:bg-gray-200 dark:hover:bg-gray-700"}`,
|
|
1163
|
+
children: isRecording ? /* @__PURE__ */ jsx13("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx13("rect", { x: "6", y: "6", width: "12", height: "12", rx: "2" }) }) : /* @__PURE__ */ jsxs9("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [
|
|
1164
|
+
/* @__PURE__ */ jsx13("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z" }),
|
|
1165
|
+
/* @__PURE__ */ jsx13("path", { d: "M19 11a7 7 0 0 1-14 0" }),
|
|
1166
|
+
/* @__PURE__ */ jsx13("line", { x1: "12", y1: "18", x2: "12", y2: "22" })
|
|
1167
|
+
] })
|
|
1168
|
+
}
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1084
1172
|
// src/DateDivider.tsx
|
|
1085
|
-
import { jsx as
|
|
1173
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1086
1174
|
function DateDivider({ iso, className, classNames }) {
|
|
1087
1175
|
const { dateDivider } = useConversationLocales();
|
|
1088
|
-
return /* @__PURE__ */
|
|
1176
|
+
return /* @__PURE__ */ jsx14("div", { className: cn("flex justify-center sticky top-0 z-10 my-2 pointer-events-none", classNames?.root, className), children: /* @__PURE__ */ jsx14(
|
|
1089
1177
|
"span",
|
|
1090
1178
|
{
|
|
1091
1179
|
className: cn(
|
|
@@ -1152,13 +1240,13 @@ function phoneInitials(number) {
|
|
|
1152
1240
|
}
|
|
1153
1241
|
|
|
1154
1242
|
// src/hooks/useAsyncResource.ts
|
|
1155
|
-
import { useCallback as
|
|
1243
|
+
import { useCallback as useCallback4, useEffect as useEffect2, useRef as useRef4, useState as useState8 } from "react";
|
|
1156
1244
|
function useAsyncResource(fetcher, deps) {
|
|
1157
|
-
const [data, setData] =
|
|
1158
|
-
const [loading, setLoading] =
|
|
1159
|
-
const [error, setError] =
|
|
1160
|
-
const requestIdRef =
|
|
1161
|
-
const load =
|
|
1245
|
+
const [data, setData] = useState8(void 0);
|
|
1246
|
+
const [loading, setLoading] = useState8(false);
|
|
1247
|
+
const [error, setError] = useState8(void 0);
|
|
1248
|
+
const requestIdRef = useRef4(0);
|
|
1249
|
+
const load = useCallback4(async () => {
|
|
1162
1250
|
const requestId = ++requestIdRef.current;
|
|
1163
1251
|
setLoading(true);
|
|
1164
1252
|
setError(void 0);
|
|
@@ -1206,9 +1294,9 @@ function useConversationDocuments(conversationId, params) {
|
|
|
1206
1294
|
}
|
|
1207
1295
|
|
|
1208
1296
|
// src/ConversationDocumentsPanel.tsx
|
|
1209
|
-
import { useState as
|
|
1297
|
+
import { useState as useState9 } from "react";
|
|
1210
1298
|
import { ArrowUpDown, Bot, Download, Eye, Users } from "lucide-react";
|
|
1211
|
-
import { jsx as
|
|
1299
|
+
import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1212
1300
|
var DOCUMENT_SOURCE_FILTER = {
|
|
1213
1301
|
ALL: "all",
|
|
1214
1302
|
CUSTOMER: "customer",
|
|
@@ -1248,12 +1336,12 @@ function ConversationDocumentsPanel({
|
|
|
1248
1336
|
}) {
|
|
1249
1337
|
const labels = { ...DEFAULT_CONVERSATION_DOCUMENTS_LABELS, ...labelsOverride };
|
|
1250
1338
|
const context = useConversations();
|
|
1251
|
-
const [search, setSearch] =
|
|
1252
|
-
const [sourceFilter, setSourceFilter] =
|
|
1253
|
-
const [sortDirection, setSortDirection] =
|
|
1254
|
-
const [page, setPage] =
|
|
1255
|
-
const [selectedIds, setSelectedIds] =
|
|
1256
|
-
const [archiveError, setArchiveError] =
|
|
1339
|
+
const [search, setSearch] = useState9("");
|
|
1340
|
+
const [sourceFilter, setSourceFilter] = useState9(DOCUMENT_SOURCE_FILTER.ALL);
|
|
1341
|
+
const [sortDirection, setSortDirection] = useState9("desc");
|
|
1342
|
+
const [page, setPage] = useState9(1);
|
|
1343
|
+
const [selectedIds, setSelectedIds] = useState9([]);
|
|
1344
|
+
const [archiveError, setArchiveError] = useState9(false);
|
|
1257
1345
|
const hasFilters = search !== "" || sourceFilter !== DOCUMENT_SOURCE_FILTER.ALL || sortDirection !== "desc";
|
|
1258
1346
|
const { documents, total, loading, error } = useConversationDocuments(open ? conversationId : void 0, {
|
|
1259
1347
|
search,
|
|
@@ -1304,10 +1392,10 @@ function ConversationDocumentsPanel({
|
|
|
1304
1392
|
}
|
|
1305
1393
|
}
|
|
1306
1394
|
if (!open) return null;
|
|
1307
|
-
return /* @__PURE__ */
|
|
1308
|
-
/* @__PURE__ */
|
|
1309
|
-
/* @__PURE__ */
|
|
1310
|
-
/* @__PURE__ */
|
|
1395
|
+
return /* @__PURE__ */ jsx15("div", { className: cn("border-b", classNames?.root, className), children: /* @__PURE__ */ jsxs10("section", { className: cn("px-4 py-3", classNames?.body), children: [
|
|
1396
|
+
/* @__PURE__ */ jsx15("p", { className: cn("mb-2 text-sm font-medium", classNames?.title), children: labels.title }),
|
|
1397
|
+
/* @__PURE__ */ jsxs10("div", { className: cn("mb-2 flex flex-wrap items-center gap-2 border-b pb-2", classNames?.filters), children: [
|
|
1398
|
+
/* @__PURE__ */ jsx15(
|
|
1311
1399
|
"input",
|
|
1312
1400
|
{
|
|
1313
1401
|
type: "search",
|
|
@@ -1318,7 +1406,7 @@ function ConversationDocumentsPanel({
|
|
|
1318
1406
|
className: cn("w-full rounded-md border px-3 py-2 text-sm sm:w-52", classNames?.search)
|
|
1319
1407
|
}
|
|
1320
1408
|
),
|
|
1321
|
-
/* @__PURE__ */
|
|
1409
|
+
/* @__PURE__ */ jsxs10(
|
|
1322
1410
|
"select",
|
|
1323
1411
|
{
|
|
1324
1412
|
value: sourceFilter,
|
|
@@ -1326,25 +1414,25 @@ function ConversationDocumentsPanel({
|
|
|
1326
1414
|
"aria-label": labels.sourceFilterAll,
|
|
1327
1415
|
className: cn("w-full rounded-md border px-2 py-2 text-sm sm:w-36", classNames?.sourceSelect),
|
|
1328
1416
|
children: [
|
|
1329
|
-
/* @__PURE__ */
|
|
1330
|
-
/* @__PURE__ */
|
|
1331
|
-
/* @__PURE__ */
|
|
1417
|
+
/* @__PURE__ */ jsx15("option", { value: DOCUMENT_SOURCE_FILTER.ALL, children: labels.sourceFilterAll }),
|
|
1418
|
+
/* @__PURE__ */ jsx15("option", { value: DOCUMENT_SOURCE_FILTER.CUSTOMER, children: labels.sourceFilterCustomer }),
|
|
1419
|
+
/* @__PURE__ */ jsx15("option", { value: DOCUMENT_SOURCE_FILTER.TEAM, children: labels.sourceFilterTeam })
|
|
1332
1420
|
]
|
|
1333
1421
|
}
|
|
1334
1422
|
),
|
|
1335
|
-
/* @__PURE__ */
|
|
1423
|
+
/* @__PURE__ */ jsxs10(
|
|
1336
1424
|
"button",
|
|
1337
1425
|
{
|
|
1338
1426
|
type: "button",
|
|
1339
1427
|
onClick: () => applyFilter(() => setSortDirection(sortDirection === "desc" ? "asc" : "desc")),
|
|
1340
1428
|
className: cn("cv-header-action inline-flex items-center gap-1", classNames?.sortButton),
|
|
1341
1429
|
children: [
|
|
1342
|
-
/* @__PURE__ */
|
|
1430
|
+
/* @__PURE__ */ jsx15(ArrowUpDown, { size: 14 }),
|
|
1343
1431
|
sortDirection === "desc" ? labels.sortMostRecent : labels.sortOldest
|
|
1344
1432
|
]
|
|
1345
1433
|
}
|
|
1346
1434
|
),
|
|
1347
|
-
hasFilters ? /* @__PURE__ */
|
|
1435
|
+
hasFilters ? /* @__PURE__ */ jsx15(
|
|
1348
1436
|
"button",
|
|
1349
1437
|
{
|
|
1350
1438
|
type: "button",
|
|
@@ -1358,12 +1446,12 @@ function ConversationDocumentsPanel({
|
|
|
1358
1446
|
}
|
|
1359
1447
|
) : null
|
|
1360
1448
|
] }),
|
|
1361
|
-
loading ? /* @__PURE__ */
|
|
1362
|
-
error ? /* @__PURE__ */
|
|
1363
|
-
!loading && !error && documents.length === 0 ? /* @__PURE__ */
|
|
1364
|
-
canArchive && documents.length > 0 ? /* @__PURE__ */
|
|
1365
|
-
/* @__PURE__ */
|
|
1366
|
-
/* @__PURE__ */
|
|
1449
|
+
loading ? /* @__PURE__ */ jsx15("p", { className: cn("text-xs text-gray-500", classNames?.status), children: labels.loading }) : null,
|
|
1450
|
+
error ? /* @__PURE__ */ jsx15("p", { role: "alert", className: cn("text-xs text-red-600 dark:text-red-400", classNames?.status), children: labels.failure }) : null,
|
|
1451
|
+
!loading && !error && documents.length === 0 ? /* @__PURE__ */ jsx15("p", { className: cn("text-xs text-gray-500", classNames?.status), children: hasFilters ? labels.noResults : labels.empty }) : null,
|
|
1452
|
+
canArchive && documents.length > 0 ? /* @__PURE__ */ jsxs10("div", { className: cn("mb-2 flex flex-wrap items-center gap-3 text-xs", classNames?.selectionBar), children: [
|
|
1453
|
+
/* @__PURE__ */ jsxs10("label", { className: "inline-flex items-center gap-1.5", children: [
|
|
1454
|
+
/* @__PURE__ */ jsx15(
|
|
1367
1455
|
"input",
|
|
1368
1456
|
{
|
|
1369
1457
|
type: "checkbox",
|
|
@@ -1374,13 +1462,13 @@ function ConversationDocumentsPanel({
|
|
|
1374
1462
|
),
|
|
1375
1463
|
labels.selectAll
|
|
1376
1464
|
] }),
|
|
1377
|
-
selectedIds.length > 0 ? /* @__PURE__ */
|
|
1378
|
-
archiveError ? /* @__PURE__ */
|
|
1465
|
+
selectedIds.length > 0 ? /* @__PURE__ */ jsx15("button", { type: "button", onClick: () => void handleDownloadSelected(), className: "cv-header-action", children: labels.downloadSelected(selectedIds.length) }) : null,
|
|
1466
|
+
archiveError ? /* @__PURE__ */ jsx15("span", { role: "alert", className: "text-red-600 dark:text-red-400", children: labels.archiveFailed }) : null
|
|
1379
1467
|
] }) : null,
|
|
1380
|
-
/* @__PURE__ */
|
|
1468
|
+
/* @__PURE__ */ jsx15("ul", { className: cn("space-y-2", classNames?.list), children: documents.map((document2) => {
|
|
1381
1469
|
const isFromCustomer = !TEAM_SOURCES.has(document2.source);
|
|
1382
1470
|
const SourceIcon = isFromCustomer ? Users : Bot;
|
|
1383
|
-
return /* @__PURE__ */
|
|
1471
|
+
return /* @__PURE__ */ jsxs10(
|
|
1384
1472
|
"li",
|
|
1385
1473
|
{
|
|
1386
1474
|
className: cn(
|
|
@@ -1388,8 +1476,8 @@ function ConversationDocumentsPanel({
|
|
|
1388
1476
|
classNames?.item
|
|
1389
1477
|
),
|
|
1390
1478
|
children: [
|
|
1391
|
-
/* @__PURE__ */
|
|
1392
|
-
canArchive ? /* @__PURE__ */
|
|
1479
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
1480
|
+
canArchive ? /* @__PURE__ */ jsx15(
|
|
1393
1481
|
"input",
|
|
1394
1482
|
{
|
|
1395
1483
|
type: "checkbox",
|
|
@@ -1399,9 +1487,9 @@ function ConversationDocumentsPanel({
|
|
|
1399
1487
|
className: cn("shrink-0", classNames?.checkbox)
|
|
1400
1488
|
}
|
|
1401
1489
|
) : null,
|
|
1402
|
-
/* @__PURE__ */
|
|
1403
|
-
/* @__PURE__ */
|
|
1404
|
-
/* @__PURE__ */
|
|
1490
|
+
/* @__PURE__ */ jsx15(FileIcon, { filename: document2.filename, mimeType: document2.mimeType }),
|
|
1491
|
+
/* @__PURE__ */ jsxs10("div", { className: "min-w-0 flex-1", children: [
|
|
1492
|
+
/* @__PURE__ */ jsxs10(
|
|
1405
1493
|
"div",
|
|
1406
1494
|
{
|
|
1407
1495
|
className: cn(
|
|
@@ -1410,12 +1498,12 @@ function ConversationDocumentsPanel({
|
|
|
1410
1498
|
classNames?.sourceBadge
|
|
1411
1499
|
),
|
|
1412
1500
|
children: [
|
|
1413
|
-
/* @__PURE__ */
|
|
1501
|
+
/* @__PURE__ */ jsx15(SourceIcon, { size: 11 }),
|
|
1414
1502
|
isFromCustomer ? labels.sourceFilterCustomer : labels.sourceFilterTeam
|
|
1415
1503
|
]
|
|
1416
1504
|
}
|
|
1417
1505
|
),
|
|
1418
|
-
/* @__PURE__ */
|
|
1506
|
+
/* @__PURE__ */ jsx15(
|
|
1419
1507
|
"div",
|
|
1420
1508
|
{
|
|
1421
1509
|
className: cn("truncate text-sm font-medium", classNames?.filename),
|
|
@@ -1423,15 +1511,15 @@ function ConversationDocumentsPanel({
|
|
|
1423
1511
|
children: document2.filename
|
|
1424
1512
|
}
|
|
1425
1513
|
),
|
|
1426
|
-
/* @__PURE__ */
|
|
1514
|
+
/* @__PURE__ */ jsxs10("div", { className: cn("text-xs text-gray-500 dark:text-gray-400", classNames?.meta), children: [
|
|
1427
1515
|
formatDateTime(document2.linkedAt),
|
|
1428
1516
|
" \xB7 ",
|
|
1429
1517
|
formatFileSize(document2.sizeBytes)
|
|
1430
1518
|
] })
|
|
1431
1519
|
] })
|
|
1432
1520
|
] }),
|
|
1433
|
-
/* @__PURE__ */
|
|
1434
|
-
/* @__PURE__ */
|
|
1521
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex shrink-0 gap-1", children: [
|
|
1522
|
+
/* @__PURE__ */ jsx15(
|
|
1435
1523
|
"button",
|
|
1436
1524
|
{
|
|
1437
1525
|
type: "button",
|
|
@@ -1439,10 +1527,10 @@ function ConversationDocumentsPanel({
|
|
|
1439
1527
|
title: labels.view,
|
|
1440
1528
|
"aria-label": `${labels.view}: ${document2.filename}`,
|
|
1441
1529
|
className: cn("cv-header-icon", classNames?.viewButton),
|
|
1442
|
-
children: /* @__PURE__ */
|
|
1530
|
+
children: /* @__PURE__ */ jsx15(Eye, { size: 14 })
|
|
1443
1531
|
}
|
|
1444
1532
|
),
|
|
1445
|
-
/* @__PURE__ */
|
|
1533
|
+
/* @__PURE__ */ jsx15(
|
|
1446
1534
|
"button",
|
|
1447
1535
|
{
|
|
1448
1536
|
type: "button",
|
|
@@ -1450,7 +1538,7 @@ function ConversationDocumentsPanel({
|
|
|
1450
1538
|
title: labels.download,
|
|
1451
1539
|
"aria-label": `${labels.download}: ${document2.filename}`,
|
|
1452
1540
|
className: cn("cv-header-icon", classNames?.downloadButton),
|
|
1453
|
-
children: /* @__PURE__ */
|
|
1541
|
+
children: /* @__PURE__ */ jsx15(Download, { size: 14 })
|
|
1454
1542
|
}
|
|
1455
1543
|
)
|
|
1456
1544
|
] })
|
|
@@ -1459,7 +1547,7 @@ function ConversationDocumentsPanel({
|
|
|
1459
1547
|
document2.id
|
|
1460
1548
|
);
|
|
1461
1549
|
}) }),
|
|
1462
|
-
total > perPage ? /* @__PURE__ */
|
|
1550
|
+
total > perPage ? /* @__PURE__ */ jsxs10(
|
|
1463
1551
|
"div",
|
|
1464
1552
|
{
|
|
1465
1553
|
className: cn(
|
|
@@ -1467,9 +1555,9 @@ function ConversationDocumentsPanel({
|
|
|
1467
1555
|
classNames?.pagination
|
|
1468
1556
|
),
|
|
1469
1557
|
children: [
|
|
1470
|
-
/* @__PURE__ */
|
|
1471
|
-
/* @__PURE__ */
|
|
1472
|
-
/* @__PURE__ */
|
|
1558
|
+
/* @__PURE__ */ jsx15("span", { className: "text-gray-400", children: labels.total(total) }),
|
|
1559
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
|
|
1560
|
+
/* @__PURE__ */ jsx15(
|
|
1473
1561
|
"button",
|
|
1474
1562
|
{
|
|
1475
1563
|
type: "button",
|
|
@@ -1480,8 +1568,8 @@ function ConversationDocumentsPanel({
|
|
|
1480
1568
|
children: "\u2039"
|
|
1481
1569
|
}
|
|
1482
1570
|
),
|
|
1483
|
-
/* @__PURE__ */
|
|
1484
|
-
/* @__PURE__ */
|
|
1571
|
+
/* @__PURE__ */ jsx15("span", { className: "text-gray-500", children: labels.page(page, lastPage) }),
|
|
1572
|
+
/* @__PURE__ */ jsx15(
|
|
1485
1573
|
"button",
|
|
1486
1574
|
{
|
|
1487
1575
|
type: "button",
|
|
@@ -1500,9 +1588,9 @@ function ConversationDocumentsPanel({
|
|
|
1500
1588
|
}
|
|
1501
1589
|
|
|
1502
1590
|
// src/DocumentsLibrary.tsx
|
|
1503
|
-
import { useEffect as useEffect3, useState as
|
|
1591
|
+
import { useEffect as useEffect3, useState as useState10 } from "react";
|
|
1504
1592
|
import { ArrowUpDown as ArrowUpDown2, Bot as Bot2, Download as Download2, Eye as Eye2, MessageSquare, Users as Users2 } from "lucide-react";
|
|
1505
|
-
import { jsx as
|
|
1593
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1506
1594
|
var DEFAULT_DOCUMENTS_LIBRARY_LABELS = {
|
|
1507
1595
|
title: "Documentos",
|
|
1508
1596
|
searchPlaceholder: "Buscar por nome do arquivo ou telefone",
|
|
@@ -1533,14 +1621,14 @@ function DocumentsLibrary({
|
|
|
1533
1621
|
}) {
|
|
1534
1622
|
const labels = { ...DEFAULT_DOCUMENTS_LIBRARY_LABELS, ...labelsOverride };
|
|
1535
1623
|
const context = useConversations();
|
|
1536
|
-
const [search, setSearch] =
|
|
1537
|
-
const [sourceFilter, setSourceFilter] =
|
|
1538
|
-
const [sortDirection, setSortDirection] =
|
|
1539
|
-
const [page, setPage] =
|
|
1540
|
-
const [documents, setDocuments] =
|
|
1541
|
-
const [total, setTotal] =
|
|
1542
|
-
const [loading, setLoading] =
|
|
1543
|
-
const [failed, setFailed] =
|
|
1624
|
+
const [search, setSearch] = useState10("");
|
|
1625
|
+
const [sourceFilter, setSourceFilter] = useState10(DOCUMENT_SOURCE_FILTER.ALL);
|
|
1626
|
+
const [sortDirection, setSortDirection] = useState10("desc");
|
|
1627
|
+
const [page, setPage] = useState10(1);
|
|
1628
|
+
const [documents, setDocuments] = useState10([]);
|
|
1629
|
+
const [total, setTotal] = useState10(0);
|
|
1630
|
+
const [loading, setLoading] = useState10(false);
|
|
1631
|
+
const [failed, setFailed] = useState10(false);
|
|
1544
1632
|
const hasFilters = search !== "" || sourceFilter !== DOCUMENT_SOURCE_FILTER.ALL || sortDirection !== "desc";
|
|
1545
1633
|
const lastPage = Math.max(1, Math.ceil(total / perPage));
|
|
1546
1634
|
const fetchAll = context?.api.getAllDocuments;
|
|
@@ -1577,10 +1665,10 @@ function DocumentsLibrary({
|
|
|
1577
1665
|
if (url) window.open(url, "_blank", "noopener,noreferrer");
|
|
1578
1666
|
}
|
|
1579
1667
|
if (!fetchAll) return null;
|
|
1580
|
-
return /* @__PURE__ */
|
|
1581
|
-
/* @__PURE__ */
|
|
1582
|
-
/* @__PURE__ */
|
|
1583
|
-
/* @__PURE__ */
|
|
1668
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn("space-y-3", classNames?.root, className), children: [
|
|
1669
|
+
/* @__PURE__ */ jsx16("h2", { className: cn("text-lg font-semibold", classNames?.title), children: labels.title }),
|
|
1670
|
+
/* @__PURE__ */ jsxs11("div", { className: cn("flex flex-wrap items-center gap-2", classNames?.filters), children: [
|
|
1671
|
+
/* @__PURE__ */ jsx16(
|
|
1584
1672
|
"input",
|
|
1585
1673
|
{
|
|
1586
1674
|
type: "search",
|
|
@@ -1591,7 +1679,7 @@ function DocumentsLibrary({
|
|
|
1591
1679
|
className: cn("w-full rounded-md border px-3 py-2 text-sm sm:w-64", classNames?.search)
|
|
1592
1680
|
}
|
|
1593
1681
|
),
|
|
1594
|
-
/* @__PURE__ */
|
|
1682
|
+
/* @__PURE__ */ jsxs11(
|
|
1595
1683
|
"select",
|
|
1596
1684
|
{
|
|
1597
1685
|
value: sourceFilter,
|
|
@@ -1599,25 +1687,25 @@ function DocumentsLibrary({
|
|
|
1599
1687
|
"aria-label": labels.sourceFilterAll,
|
|
1600
1688
|
className: cn("w-full rounded-md border px-2 py-2 text-sm sm:w-40", classNames?.sourceSelect),
|
|
1601
1689
|
children: [
|
|
1602
|
-
/* @__PURE__ */
|
|
1603
|
-
/* @__PURE__ */
|
|
1604
|
-
/* @__PURE__ */
|
|
1690
|
+
/* @__PURE__ */ jsx16("option", { value: DOCUMENT_SOURCE_FILTER.ALL, children: labels.sourceFilterAll }),
|
|
1691
|
+
/* @__PURE__ */ jsx16("option", { value: DOCUMENT_SOURCE_FILTER.CUSTOMER, children: labels.sourceFilterCustomer }),
|
|
1692
|
+
/* @__PURE__ */ jsx16("option", { value: DOCUMENT_SOURCE_FILTER.TEAM, children: labels.sourceFilterTeam })
|
|
1605
1693
|
]
|
|
1606
1694
|
}
|
|
1607
1695
|
),
|
|
1608
|
-
/* @__PURE__ */
|
|
1696
|
+
/* @__PURE__ */ jsxs11(
|
|
1609
1697
|
"button",
|
|
1610
1698
|
{
|
|
1611
1699
|
type: "button",
|
|
1612
1700
|
onClick: () => applyFilter(() => setSortDirection(sortDirection === "desc" ? "asc" : "desc")),
|
|
1613
1701
|
className: cn("cv-header-action inline-flex items-center gap-1", classNames?.sortButton),
|
|
1614
1702
|
children: [
|
|
1615
|
-
/* @__PURE__ */
|
|
1703
|
+
/* @__PURE__ */ jsx16(ArrowUpDown2, { size: 14 }),
|
|
1616
1704
|
sortDirection === "desc" ? labels.sortMostRecent : labels.sortOldest
|
|
1617
1705
|
]
|
|
1618
1706
|
}
|
|
1619
1707
|
),
|
|
1620
|
-
hasFilters ? /* @__PURE__ */
|
|
1708
|
+
hasFilters ? /* @__PURE__ */ jsx16(
|
|
1621
1709
|
"button",
|
|
1622
1710
|
{
|
|
1623
1711
|
type: "button",
|
|
@@ -1631,13 +1719,13 @@ function DocumentsLibrary({
|
|
|
1631
1719
|
}
|
|
1632
1720
|
) : null
|
|
1633
1721
|
] }),
|
|
1634
|
-
loading ? /* @__PURE__ */
|
|
1635
|
-
failed ? /* @__PURE__ */
|
|
1636
|
-
!loading && !failed && documents.length === 0 ? /* @__PURE__ */
|
|
1637
|
-
/* @__PURE__ */
|
|
1722
|
+
loading ? /* @__PURE__ */ jsx16("p", { className: cn("text-sm text-gray-500", classNames?.status), children: labels.loading }) : null,
|
|
1723
|
+
failed ? /* @__PURE__ */ jsx16("p", { role: "alert", className: cn("text-sm text-red-600 dark:text-red-400", classNames?.status), children: labels.failure }) : null,
|
|
1724
|
+
!loading && !failed && documents.length === 0 ? /* @__PURE__ */ jsx16("p", { className: cn("text-sm text-gray-500", classNames?.status), children: hasFilters ? labels.noResults : labels.empty }) : null,
|
|
1725
|
+
/* @__PURE__ */ jsx16("ul", { className: cn("space-y-2", classNames?.list), children: documents.map((document2) => {
|
|
1638
1726
|
const isFromCustomer = !TEAM_SOURCES2.has(document2.source);
|
|
1639
1727
|
const SourceIcon = isFromCustomer ? Users2 : Bot2;
|
|
1640
|
-
return /* @__PURE__ */
|
|
1728
|
+
return /* @__PURE__ */ jsxs11(
|
|
1641
1729
|
"li",
|
|
1642
1730
|
{
|
|
1643
1731
|
className: cn(
|
|
@@ -1645,23 +1733,23 @@ function DocumentsLibrary({
|
|
|
1645
1733
|
classNames?.item
|
|
1646
1734
|
),
|
|
1647
1735
|
children: [
|
|
1648
|
-
/* @__PURE__ */
|
|
1649
|
-
/* @__PURE__ */
|
|
1650
|
-
/* @__PURE__ */
|
|
1651
|
-
/* @__PURE__ */
|
|
1652
|
-
/* @__PURE__ */
|
|
1653
|
-
/* @__PURE__ */
|
|
1654
|
-
/* @__PURE__ */
|
|
1736
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
|
|
1737
|
+
/* @__PURE__ */ jsx16(FileIcon, { filename: document2.filename, mimeType: document2.mimeType }),
|
|
1738
|
+
/* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1", children: [
|
|
1739
|
+
/* @__PURE__ */ jsx16("div", { className: cn("truncate text-sm font-medium", classNames?.filename), title: document2.filename, children: document2.filename }),
|
|
1740
|
+
/* @__PURE__ */ jsxs11("div", { className: cn("flex flex-wrap items-center gap-x-2 text-xs text-gray-500", classNames?.meta), children: [
|
|
1741
|
+
/* @__PURE__ */ jsxs11("span", { className: "inline-flex items-center gap-1", children: [
|
|
1742
|
+
/* @__PURE__ */ jsx16(SourceIcon, { size: 11 }),
|
|
1655
1743
|
isFromCustomer ? labels.sourceFilterCustomer : labels.sourceFilterTeam
|
|
1656
1744
|
] }),
|
|
1657
|
-
/* @__PURE__ */
|
|
1658
|
-
/* @__PURE__ */
|
|
1659
|
-
/* @__PURE__ */
|
|
1660
|
-
/* @__PURE__ */
|
|
1745
|
+
/* @__PURE__ */ jsx16("span", { children: "\xB7" }),
|
|
1746
|
+
/* @__PURE__ */ jsx16("span", { children: formatDateTime(document2.linkedAt) }),
|
|
1747
|
+
/* @__PURE__ */ jsx16("span", { children: "\xB7" }),
|
|
1748
|
+
/* @__PURE__ */ jsx16("span", { children: formatFileSize(document2.sizeBytes) })
|
|
1661
1749
|
] })
|
|
1662
1750
|
] })
|
|
1663
1751
|
] }),
|
|
1664
|
-
onOpenConversation ? /* @__PURE__ */
|
|
1752
|
+
onOpenConversation ? /* @__PURE__ */ jsxs11(
|
|
1665
1753
|
"button",
|
|
1666
1754
|
{
|
|
1667
1755
|
type: "button",
|
|
@@ -1669,13 +1757,13 @@ function DocumentsLibrary({
|
|
|
1669
1757
|
title: labels.openConversation,
|
|
1670
1758
|
className: cn("cv-header-action inline-flex shrink-0 items-center gap-1", classNames?.conversationLink),
|
|
1671
1759
|
children: [
|
|
1672
|
-
/* @__PURE__ */
|
|
1760
|
+
/* @__PURE__ */ jsx16(MessageSquare, { size: 12 }),
|
|
1673
1761
|
formatPhone(document2.conversationId)
|
|
1674
1762
|
]
|
|
1675
1763
|
}
|
|
1676
|
-
) : /* @__PURE__ */
|
|
1677
|
-
/* @__PURE__ */
|
|
1678
|
-
/* @__PURE__ */
|
|
1764
|
+
) : /* @__PURE__ */ jsx16("span", { className: cn("shrink-0 text-xs text-gray-500", classNames?.conversationLink), children: formatPhone(document2.conversationId) }),
|
|
1765
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex shrink-0 gap-1", children: [
|
|
1766
|
+
/* @__PURE__ */ jsx16(
|
|
1679
1767
|
"button",
|
|
1680
1768
|
{
|
|
1681
1769
|
type: "button",
|
|
@@ -1683,10 +1771,10 @@ function DocumentsLibrary({
|
|
|
1683
1771
|
title: labels.view,
|
|
1684
1772
|
"aria-label": `${labels.view}: ${document2.filename}`,
|
|
1685
1773
|
className: "cv-header-icon",
|
|
1686
|
-
children: /* @__PURE__ */
|
|
1774
|
+
children: /* @__PURE__ */ jsx16(Eye2, { size: 14 })
|
|
1687
1775
|
}
|
|
1688
1776
|
),
|
|
1689
|
-
/* @__PURE__ */
|
|
1777
|
+
/* @__PURE__ */ jsx16(
|
|
1690
1778
|
"button",
|
|
1691
1779
|
{
|
|
1692
1780
|
type: "button",
|
|
@@ -1694,7 +1782,7 @@ function DocumentsLibrary({
|
|
|
1694
1782
|
title: labels.download,
|
|
1695
1783
|
"aria-label": `${labels.download}: ${document2.filename}`,
|
|
1696
1784
|
className: "cv-header-icon",
|
|
1697
|
-
children: /* @__PURE__ */
|
|
1785
|
+
children: /* @__PURE__ */ jsx16(Download2, { size: 14 })
|
|
1698
1786
|
}
|
|
1699
1787
|
)
|
|
1700
1788
|
] })
|
|
@@ -1703,10 +1791,10 @@ function DocumentsLibrary({
|
|
|
1703
1791
|
`${document2.conversationId}:${document2.id}`
|
|
1704
1792
|
);
|
|
1705
1793
|
}) }),
|
|
1706
|
-
total > perPage ? /* @__PURE__ */
|
|
1707
|
-
/* @__PURE__ */
|
|
1708
|
-
/* @__PURE__ */
|
|
1709
|
-
/* @__PURE__ */
|
|
1794
|
+
total > perPage ? /* @__PURE__ */ jsxs11("div", { className: cn("flex items-center justify-between border-t pt-2 text-xs dark:border-gray-700", classNames?.pagination), children: [
|
|
1795
|
+
/* @__PURE__ */ jsx16("span", { className: "text-gray-400", children: labels.total(total) }),
|
|
1796
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
|
|
1797
|
+
/* @__PURE__ */ jsx16(
|
|
1710
1798
|
"button",
|
|
1711
1799
|
{
|
|
1712
1800
|
type: "button",
|
|
@@ -1716,8 +1804,8 @@ function DocumentsLibrary({
|
|
|
1716
1804
|
children: "\u2039"
|
|
1717
1805
|
}
|
|
1718
1806
|
),
|
|
1719
|
-
/* @__PURE__ */
|
|
1720
|
-
/* @__PURE__ */
|
|
1807
|
+
/* @__PURE__ */ jsx16("span", { className: "text-gray-500", children: labels.page(page, lastPage) }),
|
|
1808
|
+
/* @__PURE__ */ jsx16(
|
|
1721
1809
|
"button",
|
|
1722
1810
|
{
|
|
1723
1811
|
type: "button",
|
|
@@ -1762,6 +1850,9 @@ export {
|
|
|
1762
1850
|
DEFAULT_MESSAGE_COMPOSER_LABELS,
|
|
1763
1851
|
DEFAULT_ACCEPTED_FILE_TYPES,
|
|
1764
1852
|
MessageComposer,
|
|
1853
|
+
DEFAULT_AUDIO_RECORDER_BUTTON_LABELS,
|
|
1854
|
+
DEFAULT_MAX_RECORDING_MILLISECONDS,
|
|
1855
|
+
AudioRecorderButton,
|
|
1765
1856
|
DateDivider,
|
|
1766
1857
|
formatPhone,
|
|
1767
1858
|
phoneCountryFlag,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import react__default, { ReactNode, CSSProperties, FormEvent } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
export { C as CHANNEL_CAPABILITIES,
|
|
3
|
+
import { G as MessagePayload, K as ResolveMediaUrl, z as InteractiveSelection, x as InteractivePayload, r as ConversationsFeatures, o as ConversationSummary, j as ConversationChannel, L as ListConversationsParams, q as ConversationsApi, S as SSEProvider, B as ListDocumentsParams, k as ConversationDocument, p as ConversationTemplate } from './types-C_dqJ83O.js';
|
|
4
|
+
export { A as AudioRecorderButton, a as AudioRecorderButtonLabels, b as AudioRecorderButtonProps, C as CHANNEL_CAPABILITIES, c as CHANNEL_FILTER_ALL, d as CONVERSATION_CHANNEL, e as ChannelCapabilities, f as ChannelFilter, g as ChannelFilterOption, h as CompanyDocument, i as CompanyDocumentPage, l as ConversationDocumentPage, m as ConversationEventSource, n as ConversationPage, s as ConversationsTheme, t as ConversationsUIConfig, D as DEFAULT_AUDIO_RECORDER_BUTTON_LABELS, u as DEFAULT_CONVERSATION_CHANNEL, v as DEFAULT_MAX_RECORDING_MILLISECONDS, F as FormatContactHandleParams, H as HANDLE_KIND, w as HandleKind, I as InteractiveOption, y as InteractiveSection, M as MediaRenderer, E as MediaRendererProps, R as REOPEN_MECHANISM, J as ReopenMechanism, N as capabilitiesOf, O as channelFiltersFor, P as contactFlag, Q as formatContactHandle } from './types-C_dqJ83O.js';
|
|
5
5
|
|
|
6
6
|
interface MessageBubbleProps {
|
|
7
7
|
message: MessagePayload;
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AudioPlayer,
|
|
3
|
+
AudioRecorderButton,
|
|
3
4
|
ConversationDocumentsPanel,
|
|
4
5
|
ConversationLocalesProvider,
|
|
5
6
|
ConversationWallpaper,
|
|
6
7
|
ConversationsProvider,
|
|
7
8
|
DEFAULT_ACCEPTED_FILE_TYPES,
|
|
9
|
+
DEFAULT_AUDIO_RECORDER_BUTTON_LABELS,
|
|
8
10
|
DEFAULT_CONVERSATION_DOCUMENTS_LABELS,
|
|
9
11
|
DEFAULT_DOCUMENTS_LIBRARY_LABELS,
|
|
10
12
|
DEFAULT_EMOJI_PICKER_LABELS,
|
|
11
13
|
DEFAULT_INTERACTIVE_MESSAGE_LABELS,
|
|
12
14
|
DEFAULT_LIGHTBOX_LABELS,
|
|
15
|
+
DEFAULT_MAX_RECORDING_MILLISECONDS,
|
|
13
16
|
DEFAULT_MESSAGE_COMPOSER_LABELS,
|
|
14
17
|
DOCUMENT_SOURCE_FILTER,
|
|
15
18
|
DateDivider,
|
|
@@ -41,7 +44,7 @@ import {
|
|
|
41
44
|
useConversationDocuments,
|
|
42
45
|
useConversationLocales,
|
|
43
46
|
useConversations
|
|
44
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-QFEESERN.js";
|
|
45
48
|
import {
|
|
46
49
|
htmlToWA,
|
|
47
50
|
parseWhatsAppFormatting,
|
|
@@ -2271,6 +2274,7 @@ function useInboxActions() {
|
|
|
2271
2274
|
}
|
|
2272
2275
|
export {
|
|
2273
2276
|
AudioPlayer,
|
|
2277
|
+
AudioRecorderButton,
|
|
2274
2278
|
Avatar,
|
|
2275
2279
|
CHANNEL_BRAND_COLOR,
|
|
2276
2280
|
CHANNEL_CAPABILITIES,
|
|
@@ -2287,6 +2291,7 @@ export {
|
|
|
2287
2291
|
ConversationWallpaper,
|
|
2288
2292
|
ConversationsProvider,
|
|
2289
2293
|
DEFAULT_ACCEPTED_FILE_TYPES,
|
|
2294
|
+
DEFAULT_AUDIO_RECORDER_BUTTON_LABELS,
|
|
2290
2295
|
DEFAULT_AVATAR_LABELS,
|
|
2291
2296
|
DEFAULT_CONVERSATION_CHANNEL,
|
|
2292
2297
|
DEFAULT_CONVERSATION_CONTEXT_LABELS,
|
|
@@ -2297,6 +2302,7 @@ export {
|
|
|
2297
2302
|
DEFAULT_EMOJI_PICKER_LABELS,
|
|
2298
2303
|
DEFAULT_INTERACTIVE_MESSAGE_LABELS,
|
|
2299
2304
|
DEFAULT_LIGHTBOX_LABELS,
|
|
2305
|
+
DEFAULT_MAX_RECORDING_MILLISECONDS,
|
|
2300
2306
|
DEFAULT_MESSAGE_COMPOSER_LABELS,
|
|
2301
2307
|
DEFAULT_RICH_COMPOSER_TOOLTIPS,
|
|
2302
2308
|
DEFAULT_TEMPLATES_SETTINGS_LABELS,
|
package/dist/preview/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { G as MessagePayload, o as ConversationSummary, m as ConversationEventSource, q as ConversationsApi, L as ListConversationsParams, n as ConversationPage, S as SSEProvider, k as ConversationDocument, K as ResolveMediaUrl } from '../types-C_dqJ83O.js';
|
|
2
|
+
export { A as AudioRecorderButton, a as AudioRecorderButtonLabels, b as AudioRecorderButtonProps, D as DEFAULT_AUDIO_RECORDER_BUTTON_LABELS } from '../types-C_dqJ83O.js';
|
|
2
3
|
import * as react from 'react';
|
|
3
4
|
import { InteractiveReplyOption, InboundMediaType } from '@adatechnology/meta-whatsapp-contracts/testing';
|
|
4
5
|
|
|
@@ -205,41 +206,6 @@ type PreviewUploadedMedia = {
|
|
|
205
206
|
declare function mediaTypeOf(mimeType: string): SendPreviewMediaParams['mediaType'];
|
|
206
207
|
declare function ConversationPreview({ client, sse, conversationId, loadMessages, placeholder, pollIntervalMs, uploadMedia, }: ConversationPreviewProps): react.JSX.Element;
|
|
207
208
|
|
|
208
|
-
/**
|
|
209
|
-
* Gravação de áudio no simulador, pelo microfone do próprio navegador.
|
|
210
|
-
*
|
|
211
|
-
* Existe porque áudio é o formato que mais chega de cliente real e o que mais quebra fluxo: sem
|
|
212
|
-
* poder gravar aqui, testar o caminho de transcrição exigia mandar mensagem do celular de alguém.
|
|
213
|
-
*
|
|
214
|
-
* O arquivo gravado sai daqui como `File` e segue exatamente o mesmo caminho de um anexo — quem
|
|
215
|
-
* hospeda e devolve o `mediaId` é o host, via `uploadMedia`.
|
|
216
|
-
*/
|
|
217
|
-
interface AudioRecorderButtonLabels {
|
|
218
|
-
start: string;
|
|
219
|
-
stop: string;
|
|
220
|
-
unsupported: string;
|
|
221
|
-
denied: string;
|
|
222
|
-
}
|
|
223
|
-
declare const DEFAULT_AUDIO_RECORDER_BUTTON_LABELS: AudioRecorderButtonLabels;
|
|
224
|
-
interface AudioRecorderButtonProps {
|
|
225
|
-
onRecorded: (file: File) => void | Promise<void>;
|
|
226
|
-
onFailure?: (message: string) => void;
|
|
227
|
-
/**
|
|
228
|
-
* Avisa quando a gravação começa e termina. O botão é um interruptor — o segundo toque é que
|
|
229
|
-
* envia — e sem um aviso fora dele o operador grava, não vê nada acontecer e desiste achando
|
|
230
|
-
* que o microfone está quebrado.
|
|
231
|
-
*/
|
|
232
|
-
onRecordingChange?: (isRecording: boolean) => void;
|
|
233
|
-
/**
|
|
234
|
-
* Teto de duração da gravação, em milissegundos. Passado o tempo, o gravador para e envia o que
|
|
235
|
-
* tem. Produto com limite próprio sobrescreve.
|
|
236
|
-
*/
|
|
237
|
-
maxDurationMilliseconds?: number;
|
|
238
|
-
labels?: Partial<AudioRecorderButtonLabels>;
|
|
239
|
-
disabled?: boolean;
|
|
240
|
-
}
|
|
241
|
-
declare function AudioRecorderButton({ onRecorded, onFailure, onRecordingChange, maxDurationMilliseconds, labels, disabled, }: AudioRecorderButtonProps): react.JSX.Element;
|
|
242
|
-
|
|
243
209
|
/**
|
|
244
210
|
* Roteiro que mantém o preview vivo: sem tráfego chegando, a inbox é uma tela estática e as
|
|
245
211
|
* transições que o atendente precisa testar (fila de espera enchendo, handoff, devolução ao bot)
|
|
@@ -338,4 +304,4 @@ type MediaTypesPreviewProps = {
|
|
|
338
304
|
};
|
|
339
305
|
declare function MediaTypesPreview({ conversationId, className, }: MediaTypesPreviewProps): react.JSX.Element;
|
|
340
306
|
|
|
341
|
-
export { type AppendMessageParams,
|
|
307
|
+
export { type AppendMessageParams, ConversationPreview, type ConversationPreviewProps, type CreateMockConversationsApiParams, type CreateMockSSEProviderParams, type CreatePreviewStoreParams, type CreatePreviewWebhookClientParams, DEFAULT_PREVIEW_SCRIPT, GLOBAL_CHANNEL, type ListConversationsFilters, MEDIA_TYPES_CONVERSATION_ID, MediaTypesPreview, type MediaTypesPreviewProps, type MockEventSource, PREVIEW_CONVERSATIONS, PREVIEW_DOCUMENTS, PREVIEW_FILE_SAMPLES, PREVIEW_MESSAGES, type PreviewEmission, PreviewInProductionError, type PreviewScriptStep, type PreviewStore, type PreviewStoreListener, type PreviewUploadedMedia, type PreviewWebhookClient, PreviewWebhookRejectedError, type SendPreviewMediaParams, type SetModeParams, type StartPreviewScriptParams, assertPreviewEnvironment, conversationChannel, createMockConversationsApi, createMockEventSource, createMockSSEProvider, createPreviewMediaResolver, createPreviewStore, createPreviewWebhookClient, mediaTypeOf, previewFileBase64, previewFileUrl, resolvePreviewFileSample, signPreviewPayload, startPreviewScript };
|
package/dist/preview/index.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AudioRecorderButton,
|
|
2
3
|
ConversationDocumentsPanel,
|
|
3
4
|
ConversationWallpaper,
|
|
4
5
|
ConversationsProvider,
|
|
6
|
+
DEFAULT_AUDIO_RECORDER_BUTTON_LABELS,
|
|
5
7
|
DateDivider,
|
|
6
8
|
DocumentsLibrary,
|
|
7
9
|
MessageBubble,
|
|
8
10
|
MessageComposer
|
|
9
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-QFEESERN.js";
|
|
10
12
|
import "../chunk-2AYDBWNE.js";
|
|
11
13
|
|
|
12
14
|
// src/preview/previewStore.ts
|
|
@@ -845,98 +847,8 @@ function createMockSSEProvider(params) {
|
|
|
845
847
|
}
|
|
846
848
|
|
|
847
849
|
// src/preview/ConversationPreview.tsx
|
|
848
|
-
import { useCallback
|
|
849
|
-
|
|
850
|
-
// src/preview/AudioRecorderButton.tsx
|
|
851
|
-
import { useCallback, useRef, useState } from "react";
|
|
850
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
852
851
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
853
|
-
var DEFAULT_AUDIO_RECORDER_BUTTON_LABELS = {
|
|
854
|
-
start: "Gravar \xE1udio",
|
|
855
|
-
stop: "Parar grava\xE7\xE3o",
|
|
856
|
-
unsupported: "Este navegador n\xE3o grava \xE1udio.",
|
|
857
|
-
denied: "Sem permiss\xE3o para usar o microfone."
|
|
858
|
-
};
|
|
859
|
-
var DEFAULT_MAX_RECORDING_MILLISECONDS = 5 * 60 * 1e3;
|
|
860
|
-
var RECORDING_FORMATS = [
|
|
861
|
-
{ mimeType: "audio/ogg;codecs=opus", uploadMimeType: "audio/ogg", extension: "ogg" },
|
|
862
|
-
{ mimeType: "audio/mp4", uploadMimeType: "audio/mp4", extension: "m4a" },
|
|
863
|
-
{ mimeType: "audio/webm", uploadMimeType: "audio/webm", extension: "webm" }
|
|
864
|
-
];
|
|
865
|
-
function resolveRecordingFormat() {
|
|
866
|
-
if (typeof MediaRecorder === "undefined") return void 0;
|
|
867
|
-
if (typeof MediaRecorder.isTypeSupported !== "function") return RECORDING_FORMATS[0];
|
|
868
|
-
return RECORDING_FORMATS.find((format) => MediaRecorder.isTypeSupported(format.mimeType));
|
|
869
|
-
}
|
|
870
|
-
function AudioRecorderButton({
|
|
871
|
-
onRecorded,
|
|
872
|
-
onFailure,
|
|
873
|
-
onRecordingChange,
|
|
874
|
-
maxDurationMilliseconds = DEFAULT_MAX_RECORDING_MILLISECONDS,
|
|
875
|
-
labels,
|
|
876
|
-
disabled
|
|
877
|
-
}) {
|
|
878
|
-
const startLabel = labels?.start ?? DEFAULT_AUDIO_RECORDER_BUTTON_LABELS.start;
|
|
879
|
-
const stopLabel = labels?.stop ?? DEFAULT_AUDIO_RECORDER_BUTTON_LABELS.stop;
|
|
880
|
-
const [isRecording, setIsRecording] = useState(false);
|
|
881
|
-
const recorderRef = useRef(null);
|
|
882
|
-
const autoStopRef = useRef(void 0);
|
|
883
|
-
const stop = useCallback(() => {
|
|
884
|
-
recorderRef.current?.stop();
|
|
885
|
-
}, []);
|
|
886
|
-
const start = useCallback(async () => {
|
|
887
|
-
const format = resolveRecordingFormat();
|
|
888
|
-
if (!format || !navigator.mediaDevices?.getUserMedia) {
|
|
889
|
-
onFailure?.(labels?.unsupported ?? DEFAULT_AUDIO_RECORDER_BUTTON_LABELS.unsupported);
|
|
890
|
-
return;
|
|
891
|
-
}
|
|
892
|
-
try {
|
|
893
|
-
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
894
|
-
const recorder = new MediaRecorder(stream, { mimeType: format.mimeType });
|
|
895
|
-
const chunks = [];
|
|
896
|
-
recorder.addEventListener("dataavailable", (event) => {
|
|
897
|
-
if (event.data.size > 0) chunks.push(event.data);
|
|
898
|
-
});
|
|
899
|
-
recorder.addEventListener("stop", () => {
|
|
900
|
-
stream.getTracks().forEach((track) => track.stop());
|
|
901
|
-
clearTimeout(autoStopRef.current);
|
|
902
|
-
setIsRecording(false);
|
|
903
|
-
onRecordingChange?.(false);
|
|
904
|
-
recorderRef.current = null;
|
|
905
|
-
const blob = new Blob(chunks, { type: format.uploadMimeType });
|
|
906
|
-
void onRecorded(
|
|
907
|
-
new File([blob], `audio-${Date.now()}.${format.extension}`, { type: format.uploadMimeType })
|
|
908
|
-
);
|
|
909
|
-
});
|
|
910
|
-
recorderRef.current = recorder;
|
|
911
|
-
recorder.start();
|
|
912
|
-
autoStopRef.current = setTimeout(() => recorder.stop(), maxDurationMilliseconds);
|
|
913
|
-
setIsRecording(true);
|
|
914
|
-
onRecordingChange?.(true);
|
|
915
|
-
} catch {
|
|
916
|
-
onFailure?.(labels?.denied ?? DEFAULT_AUDIO_RECORDER_BUTTON_LABELS.denied);
|
|
917
|
-
}
|
|
918
|
-
}, [labels?.denied, labels?.unsupported, maxDurationMilliseconds, onFailure, onRecorded, onRecordingChange]);
|
|
919
|
-
return /* @__PURE__ */ jsx(
|
|
920
|
-
"button",
|
|
921
|
-
{
|
|
922
|
-
type: "button",
|
|
923
|
-
disabled,
|
|
924
|
-
onClick: () => isRecording ? stop() : void start(),
|
|
925
|
-
title: isRecording ? stopLabel : startLabel,
|
|
926
|
-
"aria-label": isRecording ? stopLabel : startLabel,
|
|
927
|
-
"aria-pressed": isRecording,
|
|
928
|
-
className: `flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-full transition-colors ${isRecording ? "animate-pulse bg-red-500 text-white ring-4 ring-red-500/30 hover:bg-red-600" : "text-gray-500 hover:bg-gray-200 dark:hover:bg-gray-700"}`,
|
|
929
|
-
children: isRecording ? /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("rect", { x: "6", y: "6", width: "12", height: "12", rx: "2" }) }) : /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [
|
|
930
|
-
/* @__PURE__ */ jsx("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z" }),
|
|
931
|
-
/* @__PURE__ */ jsx("path", { d: "M19 11a7 7 0 0 1-14 0" }),
|
|
932
|
-
/* @__PURE__ */ jsx("line", { x1: "12", y1: "18", x2: "12", y2: "22" })
|
|
933
|
-
] })
|
|
934
|
-
}
|
|
935
|
-
);
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
// src/preview/ConversationPreview.tsx
|
|
939
|
-
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
940
852
|
function mediaTypeOf(mimeType) {
|
|
941
853
|
if (mimeType.startsWith("image/")) return "image";
|
|
942
854
|
if (mimeType.startsWith("video/")) return "video";
|
|
@@ -983,15 +895,15 @@ function ConversationPreview({
|
|
|
983
895
|
pollIntervalMs,
|
|
984
896
|
uploadMedia
|
|
985
897
|
}) {
|
|
986
|
-
const [messages, setMessages] =
|
|
987
|
-
const [failure, setFailure] =
|
|
988
|
-
const [loadFailure, setLoadFailure] =
|
|
989
|
-
const [isRecording, setIsRecording] =
|
|
990
|
-
const [pendingLocal, setPendingLocal] =
|
|
991
|
-
const loadMessagesRef =
|
|
992
|
-
const bottomRef =
|
|
898
|
+
const [messages, setMessages] = useState([]);
|
|
899
|
+
const [failure, setFailure] = useState(void 0);
|
|
900
|
+
const [loadFailure, setLoadFailure] = useState(void 0);
|
|
901
|
+
const [isRecording, setIsRecording] = useState(false);
|
|
902
|
+
const [pendingLocal, setPendingLocal] = useState([]);
|
|
903
|
+
const loadMessagesRef = useRef(loadMessages);
|
|
904
|
+
const bottomRef = useRef(null);
|
|
993
905
|
loadMessagesRef.current = loadMessages;
|
|
994
|
-
const refresh =
|
|
906
|
+
const refresh = useCallback(async () => {
|
|
995
907
|
try {
|
|
996
908
|
const loaded = await loadMessagesRef.current(conversationId);
|
|
997
909
|
setMessages(loaded);
|
|
@@ -1084,11 +996,11 @@ function ConversationPreview({
|
|
|
1084
996
|
setFailure(error instanceof Error ? error.message : "Falha ao enviar o arquivo.");
|
|
1085
997
|
}
|
|
1086
998
|
}
|
|
1087
|
-
return /* @__PURE__ */
|
|
1088
|
-
/* @__PURE__ */
|
|
1089
|
-
rendered.map(({ message, isFirstInGroup, showDateDivider }) => /* @__PURE__ */
|
|
1090
|
-
showDateDivider ? /* @__PURE__ */
|
|
1091
|
-
/* @__PURE__ */
|
|
999
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [
|
|
1000
|
+
/* @__PURE__ */ jsxs(ConversationWallpaper, { className: "flex-1 min-h-0 overflow-y-auto px-4 py-3", children: [
|
|
1001
|
+
rendered.map(({ message, isFirstInGroup, showDateDivider }) => /* @__PURE__ */ jsxs("div", { children: [
|
|
1002
|
+
showDateDivider ? /* @__PURE__ */ jsx(DateDivider, { iso: message.timestamp }) : null,
|
|
1003
|
+
/* @__PURE__ */ jsx(
|
|
1092
1004
|
MessageBubble,
|
|
1093
1005
|
{
|
|
1094
1006
|
message,
|
|
@@ -1098,17 +1010,17 @@ function ConversationPreview({
|
|
|
1098
1010
|
}
|
|
1099
1011
|
)
|
|
1100
1012
|
] }, message.id)),
|
|
1101
|
-
/* @__PURE__ */
|
|
1013
|
+
/* @__PURE__ */ jsx("div", { ref: bottomRef })
|
|
1102
1014
|
] }),
|
|
1103
|
-
failure ? /* @__PURE__ */
|
|
1104
|
-
loadFailure ? /* @__PURE__ */
|
|
1105
|
-
/* @__PURE__ */
|
|
1015
|
+
failure ? /* @__PURE__ */ jsx("p", { role: "alert", className: "px-4 py-2 text-sm text-red-600 dark:text-red-400", children: failure }) : null,
|
|
1016
|
+
loadFailure ? /* @__PURE__ */ jsx("p", { role: "status", className: "px-4 py-2 text-sm text-amber-700 dark:text-amber-400", children: loadFailure }) : null,
|
|
1017
|
+
/* @__PURE__ */ jsx(
|
|
1106
1018
|
MessageComposer,
|
|
1107
1019
|
{
|
|
1108
1020
|
onSend: (text) => void handleSend(text),
|
|
1109
1021
|
onAttach: uploadMedia ? (file) => void handleAttach(file) : void 0,
|
|
1110
1022
|
placeholder: isRecording ? "Gravando\u2026 toque no quadrado para enviar" : placeholder ?? "Escreva como o cliente\u2026",
|
|
1111
|
-
idleAction: uploadMedia ? /* @__PURE__ */
|
|
1023
|
+
idleAction: uploadMedia ? /* @__PURE__ */ jsx(
|
|
1112
1024
|
AudioRecorderButton,
|
|
1113
1025
|
{
|
|
1114
1026
|
onRecorded: (file) => void handleAttach(file),
|
|
@@ -1218,7 +1130,7 @@ function startPreviewScript(params) {
|
|
|
1218
1130
|
|
|
1219
1131
|
// src/preview/MediaTypesPreview.tsx
|
|
1220
1132
|
import { useMemo as useMemo2 } from "react";
|
|
1221
|
-
import { jsx as
|
|
1133
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1222
1134
|
var MEDIA_TYPES_CONVERSATION_ID = "5511944443333";
|
|
1223
1135
|
function MediaTypesPreview({
|
|
1224
1136
|
conversationId = MEDIA_TYPES_CONVERSATION_ID,
|
|
@@ -1233,26 +1145,26 @@ function MediaTypesPreview({
|
|
|
1233
1145
|
const messages = PREVIEW_MESSAGES[conversationId] ?? [];
|
|
1234
1146
|
const documents = PREVIEW_DOCUMENTS[conversationId] ?? [];
|
|
1235
1147
|
const mimeTypes = [...new Set(documents.map((document) => document.mimeType))];
|
|
1236
|
-
return /* @__PURE__ */
|
|
1237
|
-
/* @__PURE__ */
|
|
1238
|
-
/* @__PURE__ */
|
|
1239
|
-
/* @__PURE__ */
|
|
1148
|
+
return /* @__PURE__ */ jsx2(ConversationsProvider, { api, sse, children: /* @__PURE__ */ jsxs2("div", { className, children: [
|
|
1149
|
+
/* @__PURE__ */ jsxs2("header", { className: "border-b px-4 py-3 dark:border-gray-700", children: [
|
|
1150
|
+
/* @__PURE__ */ jsx2("h1", { className: "text-lg font-semibold", children: "Teste manual de m\xEDdia" }),
|
|
1151
|
+
/* @__PURE__ */ jsxs2("p", { className: "text-sm text-gray-500", children: [
|
|
1240
1152
|
documents.length,
|
|
1241
1153
|
" arquivos, ",
|
|
1242
1154
|
mimeTypes.length,
|
|
1243
1155
|
" tipos. Clique no olho para abrir em aba nova e no bot\xE3o da bolha para carregar a m\xEDdia na thread \u2014 \xE9 o que teste automatizado n\xE3o v\xEA."
|
|
1244
1156
|
] })
|
|
1245
1157
|
] }),
|
|
1246
|
-
/* @__PURE__ */
|
|
1247
|
-
/* @__PURE__ */
|
|
1248
|
-
/* @__PURE__ */
|
|
1249
|
-
/* @__PURE__ */
|
|
1158
|
+
/* @__PURE__ */ jsxs2("div", { className: "grid gap-4 p-4 lg:grid-cols-2", children: [
|
|
1159
|
+
/* @__PURE__ */ jsxs2("section", { className: "space-y-3", children: [
|
|
1160
|
+
/* @__PURE__ */ jsx2("h2", { className: "text-sm font-semibold uppercase tracking-wide text-gray-500", children: "Biblioteca da empresa" }),
|
|
1161
|
+
/* @__PURE__ */ jsx2(DocumentsLibrary, { perPage: documents.length || 20 })
|
|
1250
1162
|
] }),
|
|
1251
|
-
/* @__PURE__ */
|
|
1252
|
-
/* @__PURE__ */
|
|
1253
|
-
/* @__PURE__ */
|
|
1254
|
-
/* @__PURE__ */
|
|
1255
|
-
/* @__PURE__ */
|
|
1163
|
+
/* @__PURE__ */ jsxs2("section", { className: "space-y-3", children: [
|
|
1164
|
+
/* @__PURE__ */ jsx2("h2", { className: "text-sm font-semibold uppercase tracking-wide text-gray-500", children: "Painel da conversa" }),
|
|
1165
|
+
/* @__PURE__ */ jsx2(ConversationDocumentsPanel, { conversationId, open: true, perPage: documents.length || 20 }),
|
|
1166
|
+
/* @__PURE__ */ jsx2("h2", { className: "text-sm font-semibold uppercase tracking-wide text-gray-500", children: "Bolhas na thread" }),
|
|
1167
|
+
/* @__PURE__ */ jsx2(ConversationWallpaper, { className: "max-h-[70vh] overflow-y-auto rounded-lg px-3 py-2", children: messages.map((message, index) => /* @__PURE__ */ jsx2(
|
|
1256
1168
|
MessageBubble,
|
|
1257
1169
|
{
|
|
1258
1170
|
message,
|
|
@@ -104,6 +104,47 @@ interface MediaRendererProps {
|
|
|
104
104
|
}
|
|
105
105
|
declare function MediaRenderer({ message, onLightbox, onResolveUrl, className }: MediaRendererProps): react.JSX.Element | null;
|
|
106
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Gravação de áudio no simulador, pelo microfone do próprio navegador.
|
|
109
|
+
*
|
|
110
|
+
* Existe porque áudio é o formato que mais chega de cliente real e o que mais quebra fluxo: sem
|
|
111
|
+
* poder gravar aqui, testar o caminho de transcrição exigia mandar mensagem do celular de alguém.
|
|
112
|
+
*
|
|
113
|
+
* O arquivo gravado sai daqui como `File` e segue exatamente o mesmo caminho de um anexo — quem
|
|
114
|
+
* hospeda e devolve o `mediaId` é o host, via `uploadMedia`.
|
|
115
|
+
*/
|
|
116
|
+
interface AudioRecorderButtonLabels {
|
|
117
|
+
start: string;
|
|
118
|
+
stop: string;
|
|
119
|
+
unsupported: string;
|
|
120
|
+
denied: string;
|
|
121
|
+
}
|
|
122
|
+
declare const DEFAULT_AUDIO_RECORDER_BUTTON_LABELS: AudioRecorderButtonLabels;
|
|
123
|
+
interface AudioRecorderButtonProps {
|
|
124
|
+
onRecorded: (file: File) => void | Promise<void>;
|
|
125
|
+
onFailure?: (message: string) => void;
|
|
126
|
+
/**
|
|
127
|
+
* Avisa quando a gravação começa e termina. O botão é um interruptor — o segundo toque é que
|
|
128
|
+
* envia — e sem um aviso fora dele o operador grava, não vê nada acontecer e desiste achando
|
|
129
|
+
* que o microfone está quebrado.
|
|
130
|
+
*/
|
|
131
|
+
onRecordingChange?: (isRecording: boolean) => void;
|
|
132
|
+
/**
|
|
133
|
+
* Teto de duração da gravação, em milissegundos. Passado o tempo, o gravador para e envia o que
|
|
134
|
+
* tem. Produto com limite próprio sobrescreve.
|
|
135
|
+
*/
|
|
136
|
+
maxDurationMilliseconds?: number;
|
|
137
|
+
labels?: Partial<AudioRecorderButtonLabels>;
|
|
138
|
+
disabled?: boolean;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Cinco minutos: com o codec de voz do WhatsApp isso dá menos de 3MB, folgado dentro do teto de
|
|
142
|
+
* 16MB que a Meta impõe a áudio, e é mais do que qualquer recado de cliente. O corte automático
|
|
143
|
+
* existe porque gravação esquecida aberta só se descobre no envio, com o arquivo inteiro perdido.
|
|
144
|
+
*/
|
|
145
|
+
declare const DEFAULT_MAX_RECORDING_MILLISECONDS: number;
|
|
146
|
+
declare function AudioRecorderButton({ onRecorded, onFailure, onRecordingChange, maxDurationMilliseconds, labels, disabled, }: AudioRecorderButtonProps): react.JSX.Element;
|
|
147
|
+
|
|
107
148
|
/**
|
|
108
149
|
* Canal de origem da conversa e o que cada um permite.
|
|
109
150
|
*
|
|
@@ -362,4 +403,4 @@ interface ConversationDocument {
|
|
|
362
403
|
linkedAt: string;
|
|
363
404
|
}
|
|
364
405
|
|
|
365
|
-
export {
|
|
406
|
+
export { AudioRecorderButton as A, type ListDocumentsParams as B, CHANNEL_CAPABILITIES as C, DEFAULT_AUDIO_RECORDER_BUTTON_LABELS as D, type MediaRendererProps as E, type FormatContactHandleParams as F, type MessagePayload as G, HANDLE_KIND as H, type InteractiveOption as I, type ReopenMechanism as J, type ResolveMediaUrl as K, type ListConversationsParams as L, MediaRenderer as M, capabilitiesOf as N, channelFiltersFor as O, contactFlag as P, formatContactHandle as Q, REOPEN_MECHANISM as R, type SSEProvider as S, type AudioRecorderButtonLabels as a, type AudioRecorderButtonProps as b, CHANNEL_FILTER_ALL as c, CONVERSATION_CHANNEL as d, type ChannelCapabilities as e, type ChannelFilter as f, type ChannelFilterOption as g, type CompanyDocument as h, type CompanyDocumentPage as i, type ConversationChannel as j, type ConversationDocument as k, type ConversationDocumentPage as l, type ConversationEventSource as m, type ConversationPage as n, type ConversationSummary as o, type ConversationTemplate as p, type ConversationsApi as q, type ConversationsFeatures as r, type ConversationsTheme as s, type ConversationsUIConfig as t, DEFAULT_CONVERSATION_CHANNEL as u, DEFAULT_MAX_RECORDING_MILLISECONDS as v, type HandleKind as w, type InteractivePayload as x, type InteractiveSection as y, type InteractiveSelection as z };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { afterEach, describe, expect, it } from 'bun:test'
|
|
2
2
|
|
|
3
3
|
import { resolveRecordingFormat } from './AudioRecorderButton'
|
|
4
|
-
import { DEFAULT_ACCEPTED_FILE_TYPES } from '
|
|
4
|
+
import { DEFAULT_ACCEPTED_FILE_TYPES } from './MessageComposer'
|
|
5
5
|
|
|
6
6
|
const originalMediaRecorder = (globalThis as Record<string, unknown>).MediaRecorder
|
|
7
7
|
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,12 @@ export type {
|
|
|
15
15
|
RichComposerVariable,
|
|
16
16
|
RichMessageComposerHandle,
|
|
17
17
|
} from './RichMessageComposer'
|
|
18
|
+
export {
|
|
19
|
+
AudioRecorderButton,
|
|
20
|
+
DEFAULT_AUDIO_RECORDER_BUTTON_LABELS,
|
|
21
|
+
DEFAULT_MAX_RECORDING_MILLISECONDS,
|
|
22
|
+
} from './AudioRecorderButton'
|
|
23
|
+
export type { AudioRecorderButtonProps, AudioRecorderButtonLabels } from './AudioRecorderButton'
|
|
18
24
|
export { WhatsAppMessageEditor, DEFAULT_WHATSAPP_MESSAGE_EDITOR_LABELS } from './WhatsAppMessageEditor'
|
|
19
25
|
export { SimpleEmojiPicker } from './SimpleEmojiPicker'
|
|
20
26
|
export { DateDivider } from './DateDivider'
|
|
@@ -20,7 +20,7 @@ import { MessageComposer } from '../MessageComposer'
|
|
|
20
20
|
import { DateDivider } from '../DateDivider'
|
|
21
21
|
import { ConversationWallpaper } from '../Wallpaper'
|
|
22
22
|
import type { PreviewWebhookClient, SendPreviewMediaParams } from './createPreviewWebhookClient'
|
|
23
|
-
import { AudioRecorderButton } from '
|
|
23
|
+
import { AudioRecorderButton } from '../AudioRecorderButton'
|
|
24
24
|
|
|
25
25
|
export type ConversationPreviewProps = {
|
|
26
26
|
client: PreviewWebhookClient
|
package/src/preview/index.ts
CHANGED
|
@@ -29,8 +29,8 @@ export { ConversationPreview } from './ConversationPreview'
|
|
|
29
29
|
export { mediaTypeOf } from './ConversationPreview'
|
|
30
30
|
export type { ConversationPreviewProps, PreviewUploadedMedia } from './ConversationPreview'
|
|
31
31
|
|
|
32
|
-
export { AudioRecorderButton, DEFAULT_AUDIO_RECORDER_BUTTON_LABELS } from '
|
|
33
|
-
export type { AudioRecorderButtonProps, AudioRecorderButtonLabels } from '
|
|
32
|
+
export { AudioRecorderButton, DEFAULT_AUDIO_RECORDER_BUTTON_LABELS } from '../AudioRecorderButton'
|
|
33
|
+
export type { AudioRecorderButtonProps, AudioRecorderButtonLabels } from '../AudioRecorderButton'
|
|
34
34
|
|
|
35
35
|
export {
|
|
36
36
|
createPreviewWebhookClient,
|
|
File without changes
|