@adatechnology/conversations-ui 0.9.0 → 0.11.0

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.
Files changed (91) hide show
  1. package/README.md +107 -0
  2. package/dist/{ConversationSimulatorPanel-q-wVgBCN.d.ts → ConversationSimulatorPanel-P6eqTSAO.d.ts} +1 -16
  3. package/dist/{chunk-O6457XHK.js → chunk-WCZNIJ3M.js} +16 -1
  4. package/dist/{chunk-L3OFAQPS.js → chunk-Y326LLEP.js} +4 -14
  5. package/dist/index.d.ts +10 -3
  6. package/dist/index.js +3 -3
  7. package/dist/participant/index.d.ts +55 -3
  8. package/dist/participant/index.js +1369 -319
  9. package/dist/preview/index.d.ts +2 -2
  10. package/dist/preview/index.js +2 -2
  11. package/dist/styles.css +187 -0
  12. package/package.json +2 -2
  13. package/src/AudioRecorderButton.tsx +4 -28
  14. package/src/audioRecorderFormat.ts +27 -0
  15. package/src/participant/ConversationThread.tsx +7 -0
  16. package/src/participant/ParticipantAttachmentItem.tsx +7 -10
  17. package/src/participant/ParticipantAudioAttachment.tsx +34 -0
  18. package/src/participant/ParticipantAudioPlayer.tsx +68 -0
  19. package/src/participant/ParticipantAudioPlayerControls.tsx +68 -0
  20. package/src/participant/ParticipantAudioRecorderView.tsx +55 -0
  21. package/src/participant/ParticipantAudioTranscription.tsx +90 -0
  22. package/src/participant/ParticipantComposer.tsx +50 -15
  23. package/src/participant/ParticipantComposerAudio.tsx +95 -0
  24. package/src/participant/ParticipantConversations.tsx +5 -0
  25. package/src/participant/ParticipantRecorderParts.tsx +118 -0
  26. package/src/participant/ParticipantThread.test.tsx +46 -0
  27. package/src/participant/ParticipantThread.tsx +17 -0
  28. package/src/participant/ParticipantThreadScreen.tsx +2 -0
  29. package/src/participant/index.ts +3 -0
  30. package/src/participant/participantAudio.types.ts +10 -0
  31. package/src/participant/participantAudioCapture.test.ts +15 -0
  32. package/src/participant/participantAudioCapture.ts +85 -0
  33. package/src/participant/participantAudioCoordinator.ts +13 -0
  34. package/src/participant/participantAudioFormat.test.ts +93 -0
  35. package/src/participant/participantAudioFormat.ts +72 -0
  36. package/src/participant/participantAudioGolden.test.tsx +168 -0
  37. package/src/participant/participantAudioLabels.test.ts +22 -0
  38. package/src/participant/participantAudioLabels.ts +76 -0
  39. package/src/participant/participantAudioPlayerControlsDom.test.tsx +123 -0
  40. package/src/participant/participantAudioPlayerCss.test.ts +63 -0
  41. package/src/participant/participantAudioPlayerDom.test.tsx +154 -0
  42. package/src/participant/participantAudioPlayerDomKit.test-helper.tsx +84 -0
  43. package/src/participant/participantAudioPlayerState.ts +35 -0
  44. package/src/participant/participantAudioRecorderDom.test.tsx +127 -0
  45. package/src/participant/participantAudioRecorderInterruptionDom.test.tsx +135 -0
  46. package/src/participant/participantAudioRecorderSpecDom.test.tsx +110 -0
  47. package/src/participant/participantAudioRecorderState.test.ts +144 -0
  48. package/src/participant/participantAudioRecorderState.ts +93 -0
  49. package/src/participant/participantAudioRecorderView.test.tsx +98 -0
  50. package/src/participant/participantAudioSupport.ts +36 -0
  51. package/src/participant/participantAudioTranscriptionDom.test.tsx +198 -0
  52. package/src/participant/participantComposerAudioDom.test.tsx +185 -0
  53. package/src/participant/participantComposerAudioGolden.test.tsx +68 -0
  54. package/src/participant/participantComposerAudioSsr.test.tsx +74 -0
  55. package/src/participant/participantFileValidation.ts +1 -1
  56. package/src/participant/participantGolden.test.tsx +2 -0
  57. package/src/participant/participantGoldenScenarios.test-helper.tsx +14 -1
  58. package/src/participant/participantLabels.ts +4 -1
  59. package/src/participant/participantMediaFakes.test-helper.ts +82 -0
  60. package/src/participant/participantNoMicrophoneDom.test.tsx +44 -0
  61. package/src/participant/participantPublicTypes.test.ts +11 -0
  62. package/src/participant/participantRecorderDomKit.test-helper.tsx +131 -0
  63. package/src/participant/participantRecorderFakes.test-helper.ts +47 -0
  64. package/src/participant/participantSpecRecorderFake.test-helper.ts +52 -0
  65. package/src/participant/participantThemeContrast.test.ts +9 -0
  66. package/src/participant/test-fixtures/composer-audio-denied.golden.html +1 -0
  67. package/src/participant/test-fixtures/composer-audio-idle.golden.html +1 -0
  68. package/src/participant/test-fixtures/composer-audio-recording.golden.html +1 -0
  69. package/src/participant/test-fixtures/composer-audio-review.golden.html +1 -0
  70. package/src/participant/test-fixtures/thread-audio-native.golden.html +1 -0
  71. package/src/participant/test-fixtures/thread-audio-player.golden.html +1 -0
  72. package/src/participant/test-fixtures/thread-audio-transcription-empty.golden.html +1 -0
  73. package/src/participant/test-fixtures/thread-audio-transcription-pending.golden.html +1 -0
  74. package/src/participant/test-fixtures/thread-audio-transcription-ready.golden.html +1 -0
  75. package/src/participant/test-fixtures/thread-audio-transcription-too_long.golden.html +1 -0
  76. package/src/participant/test-fixtures/thread-composer-microphone-idle.golden.html +1 -0
  77. package/src/participant/test-fixtures/thread-empty-draft.golden.html +1 -0
  78. package/src/participant/useParticipantAudioMediaEvents.ts +46 -0
  79. package/src/participant/useParticipantAudioPlayer.ts +52 -0
  80. package/src/participant/useParticipantAudioPlayerActions.ts +47 -0
  81. package/src/participant/useParticipantAudioRecorder.ts +153 -0
  82. package/src/participant/useParticipantAudioRecorderCore.ts +55 -0
  83. package/src/participant/useParticipantAudioRecorderEffects.ts +70 -0
  84. package/src/participant/useParticipantAudioSourceRetry.ts +42 -0
  85. package/src/participant/useParticipantSendAudio.test.tsx +85 -0
  86. package/src/participant/useParticipantSendAudio.ts +28 -0
  87. package/src/participant/useParticipantThreadController.ts +20 -7
  88. package/src/participant/useStableAttachmentUrl.ts +71 -0
  89. package/src/participant/useTranscriptionOverflow.ts +25 -0
  90. package/src/participant/useTranscriptionReadyAnnouncement.ts +24 -0
  91. package/src/styles.css +30 -0
package/README.md CHANGED
@@ -334,6 +334,7 @@ import { ConversationThread } from '@adatechnology/conversations-ui/participant'
334
334
  | `status?` | `'open' \| 'closed'` | `closed` tira o compositor e mostra `labels.closedNotice` |
335
335
  | `counterpartLabel?` | `string` | linha curta sob o título, montada pelo host |
336
336
  | `headerActions?` | `ReactNode` | slot à direita do cabeçalho; ausente não desenha nada. Espera botões curtos ou só ícone, cada um com `aria-label`: com ações, a barra quebra de linha e o título mantém no mínimo `6rem` |
337
+ | `renderComposerLock?` | `(conversation) => ReactNode \| undefined` | devolver um nó troca o compositor por ele (aviso + ações do host), dentro de `cv-p-thread__lock`; `undefined` mantém o compositor. `closed` continua tendo prioridade. Avaliado a cada render; o rascunho fica no controlador e volta ao destravar. Também existe em `ParticipantConversations` |
337
338
  | `onBack?` | `() => void` | ausente = sem seta (o diálogo do host já tem o próprio fechar) |
338
339
  | `quickReplies?` | `QuickReply[]` | chips acima do campo; tocar **preenche**, nunca envia |
339
340
  | `renderSubjectIcon?`, `subjectGroups?` | | ícone do assunto no cabeçalho, como na lista |
@@ -392,6 +393,112 @@ superfície) e nenhum texto depende dele (o erro de carga ganha painel sólido).
392
393
  decorativa (cerca de 1,4:1): quem a distingue da página é o preenchimento, e o texto passa de 4,5:1. Ao mapear o
393
394
  acento, mantenha-o a 4,5:1 contra `--cv-p-highlight`, que é onde ficam os links da bolha própria. Os contrastes só valem com `--cv-p-highlight` **opaco**: o padrão do tema escuro do pacote é translúcido (`rgb(213 138 71 / 10%)`), então o host que mapeia o token deve fornecer um valor opaco.
394
395
 
396
+ ### Gravação de áudio e transcrição (`audioRecording`)
397
+
398
+ Capacidade **opt-in**: sem a prop `audioRecording`, não há microfone, e o compositor e a bolha mantêm o markup de
399
+ antes, byte a byte. A prop existe em `ParticipantConversations` e em `ConversationThread`.
400
+
401
+ ```tsx
402
+ import { ParticipantConversations } from '@adatechnology/conversations-ui/participant'
403
+
404
+ ;<ParticipantConversations
405
+ api={participantApi}
406
+ audioRecording={{
407
+ maxDurationMs: 120_000,
408
+ maxSizeBytes: 8 * 1024 * 1024,
409
+ onCaptureChange: (isCapturing) => captureRegistry.set('audio', isCapturing),
410
+ }}
411
+ />
412
+ ```
413
+
414
+ Tipo `ParticipantAudioRecordingOptions`, exportado por `@adatechnology/conversations-ui/participant`:
415
+
416
+ | Campo | Efeito |
417
+ | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
418
+ | `maxDurationMs?` | teto da gravação. Só baixa: acima de 5 min (padrão) é cortado para 5 min |
419
+ | `maxSizeBytes?` | teto do arquivo. Só baixa: fica no menor valor entre `DEFAULT_MAX_RECORDING_BYTES` (16 MiB, a política de áudio da API) e o teto do canal |
420
+ | `onCaptureChange?(isCapturing)` | `true` de `requesting` até sair de `review`; `false` ao sair. Nunca recebe o áudio |
421
+
422
+ Regras de exibição e envio:
423
+
424
+ - O microfone só aparece com a prop **e** com o campo de texto vazio. Com texto ou anexo, o lugar dele é do botão de enviar.
425
+ - O canal só desliga a gravação. `portal` e `webchat` não gravam; `app`, `email` e `whatsapp` gravam.
426
+ - Sem `MediaRecorder` ou `getUserMedia` no navegador, o microfone não aparece.
427
+ - O áudio gravado vai como mensagem própria, pelo mesmo caminho do anexo (`send({ files: [file] })` por dentro). O rascunho de texto e os anexos do rascunho não são alterados. Dois toques seguidos enviam uma mensagem só.
428
+ - `onSendAudio` é fiação interna do controlador da thread, não prop do host. O host só passa `audioRecording`.
429
+
430
+ **Estados do gravador:** `idle` → `requesting` → `recording` → `review` (ouvir, enviar ou descartar). Os caminhos de erro
431
+ são `denied`, `unsupported`, `empty` e `tooLarge`, com mensagem no compositor. Durante a gravação, uma interrupção
432
+ (aba oculta, `pagehide`, trilha do microfone encerrada ou muda por mais de 3 s) para a captura e vai para `review`; em
433
+ `review`, pausa e mantém. Desmontar o componente descarta. O microfone é liberado em toda saída.
434
+
435
+ **Player.** Cada anexo `audio/*` mostra o player `.cv-p-audio` (tocar e pausar, posição, velocidade 1×, 1,5× e 2×) e
436
+ depois o nome do arquivo. Nada é baixado antes do primeiro toque (`preload="none"`); a URL é resolvida ao montar, por
437
+ `id` do anexo. A duração aparece depois do toque quando o servidor não manda `durationMs`. Tocar um áudio pausa o que
438
+ estava tocando em qualquer player da visão do participante na página (o player do operador e uma segunda cópia do
439
+ pacote não são coordenados).
440
+
441
+ **Bloco de transcrição** (por `transcription.status` do anexo):
442
+
443
+ - `pending`: linha "Transcribing…" (default em inglês).
444
+ - `ready`: aviso "gerada por máquina" e o texto, com expandir e recolher quando passa do espaço. Texto vazio mostra
445
+ "Nothing was said in the audio" (é resultado, não falha).
446
+ - `failed` com `reason: 'too_long'` e `maxDurationMs`: aviso com o limite aplicado.
447
+ - Qualquer outro `failed`, `disabled` ou ausência do campo: só o player.
448
+
449
+ **Rótulos novos.** Todos opcionais em `ParticipantConversationsLabels`; os defaults também entraram em `DEFAULT_PARTICIPANT_CONVERSATIONS_LABELS`. `{minutes}` é **calculado** pela UI a partir de `maxDurationMs` (piso em minutos inteiros; abaixo de 1 minuto nada é desenhado), não vem do servidor. Os defaults em inglês estão em
450
+ `DEFAULT_PARTICIPANT_AUDIO_LABELS` (tipo `ParticipantAudioLabels`). Placeholders entre chaves são preenchidos pela
451
+ própria UI.
452
+
453
+ | Chave | Default | Onde aparece |
454
+ | ----------------------- | ------------------------------------------------------------ | -------------------------------------------- |
455
+ | `recordAudio` | Record audio | botão do microfone |
456
+ | `recordingInProgress` | Recording | grupo em `recording` |
457
+ | `stopRecording` | Stop recording | parar |
458
+ | `recordingElapsed` | {elapsed} of {limit} | relógio da gravação |
459
+ | `reviewAudio` | Listen before sending | dica em `review` |
460
+ | `sendAudio` | Send audio | enviar |
461
+ | `discardAudio` | Discard audio | descartar |
462
+ | `microphoneDenied` | No permission to use the microphone. | `denied` |
463
+ | `recordingUnsupported` | This device cannot record audio. | `unsupported` |
464
+ | `audioEmpty` | Nothing was captured by the microphone. | `empty` |
465
+ | `audioTooLarge` | Audio too large to send. | `tooLarge` |
466
+ | `audioPlayer` | Audio | grupo do player |
467
+ | `playAudio` | Play audio | tocar |
468
+ | `pauseAudio` | Pause audio | pausar |
469
+ | `audioPosition` | Audio position | nome do controle de posição |
470
+ | `audioPositionValue` | {position} of {duration} | `aria-valuetext` (sem duração, só a posição) |
471
+ | `playbackRate` | Playback speed {rate} | velocidade |
472
+ | `audioUnavailable` | Audio unavailable | falha do player |
473
+ | `transcribing` | Transcribing… | `pending` |
474
+ | `transcriptionReady` | Transcription ready | região viva ao terminar |
475
+ | `machineTranscription` | Transcription generated by machine | aviso de `ready` |
476
+ | `emptyTranscription` | Nothing was said in the audio | `ready` vazio |
477
+ | `transcriptionTooLong` | Transcription only for audios shorter than {minutes} minutes | `too_long` (`{minutes}` vem do servidor) |
478
+ | `showFullTranscription` | Show all | expandir |
479
+ | `collapseTranscription` | Show less | recolher |
480
+
481
+ **Classes novas** (todas `.cv-p-*`, em `styles.css`): `.cv-p-audio`, `.cv-p-audio__toggle`, `.cv-p-audio__seek`,
482
+ `.cv-p-audio__time`, `.cv-p-audio__rate`, `.cv-p-audio__media`, `.cv-p-audio__error`, `.cv-p-composer__record`,
483
+ `.cv-p-recorder` (com `--review`), `.cv-p-recorder__dot`, `.cv-p-recorder__elapsed`, `.cv-p-recorder__hint`,
484
+ `.cv-p-recorder__stop`, `.cv-p-recorder__send`, `.cv-p-recorder__discard`, `.cv-p-transcription` (com `--pending` e
485
+ `--too-long`), `.cv-p-transcription__notice`, `.cv-p-transcription__text`, `.cv-p-transcription__empty` e
486
+ `.cv-p-transcription__toggle`. Não há variável `--cv-p-*` nova: o áudio usa as que já existem (`--cv-p-accent`,
487
+ `--cv-p-text-muted`, `--cv-p-danger` e as demais da tabela acima).
488
+
489
+ **Limites conhecidos desta versão**
490
+
491
+ - **WhatsApp:** **não ative o microfone com `channel="whatsapp"` antes da validação**: o Chromium grava WebM, que o
492
+ WhatsApp não aceita. A capacidade do canal `whatsapp` declara gravação, mas o envio de áudio de volta ao WhatsApp não foi
493
+ validado ponta a ponta nesta branch. Não trate a gravação nessa conversa como pronta até a validação da spec 264.
494
+ - **Safari e iPhone:** o formato e a gravação no Safari/iPhone (`audio/mp4`) e o pedido de permissão no toque ficam a
495
+ conferir em aparelho real na T7.1 do consumidor.
496
+ - **Evento `stop` ausente:** se o `stop` do `MediaRecorder` nunca chegar (a especificação o garante), a UI permanece em
497
+ `recording` até o usuário descartar a gravação. Um vigia opcional fica para uma versão futura.
498
+
499
+ **Validação do anexo.** `transcription` e `durationMs` inválidos reprovam o anexo inteiro (só chaves desconhecidas são
500
+ descartadas): valide por anexo com `participantTranscriptionSchema.safeParse` e descarte o campo que falhar.
501
+
395
502
  ### Limitações conhecidas
396
503
 
397
504
  - O avatar alinha pelo topo da bolha, não pelo rabinho no canto inferior.
@@ -20,15 +20,6 @@ interface MediaRendererProps {
20
20
  }
21
21
  declare function MediaRenderer({ message, onLightbox, onResolveUrl, onTranscribeAudio, className, }: MediaRendererProps): react.JSX.Element | null;
22
22
 
23
- /**
24
- * Gravação de áudio no simulador, pelo microfone do próprio navegador.
25
- *
26
- * Existe porque áudio é o formato que mais chega de cliente real e o que mais quebra fluxo: sem
27
- * poder gravar aqui, testar o caminho de transcrição exigia mandar mensagem do celular de alguém.
28
- *
29
- * O arquivo gravado sai daqui como `File` e segue exatamente o mesmo caminho de um anexo — quem
30
- * hospeda e devolve o `mediaId` é o host, via `uploadMedia`.
31
- */
32
23
  interface AudioRecorderButtonLabels {
33
24
  start: string;
34
25
  stop: string;
@@ -69,12 +60,6 @@ interface AudioRecorderButtonProps {
69
60
  */
70
61
  disabledHint?: string;
71
62
  }
72
- /**
73
- * Cinco minutos: com o codec de voz do WhatsApp isso dá menos de 3MB, folgado dentro do teto de
74
- * 16MB que a Meta impõe a áudio, e é mais do que qualquer recado de cliente. O corte automático
75
- * existe porque gravação esquecida aberta só se descobre no envio, com o arquivo inteiro perdido.
76
- */
77
- declare const DEFAULT_MAX_RECORDING_MILLISECONDS: number;
78
63
  declare function AudioRecorderButton({ onRecorded, onFailure, onRecordingChange, reviewBeforeSend, maxDurationMilliseconds, labels, disabled, disabledHint, }: AudioRecorderButtonProps): react.JSX.Element;
79
64
 
80
65
  interface ListConversationsParams {
@@ -651,4 +636,4 @@ type ConversationSimulatorPanelProps = Omit<ConversationPreviewProps, 'placehold
651
636
  };
652
637
  declare function ConversationSimulatorPanel({ onClose, channel, displayHandle, displayNumber, labels, headerActions, ...previewProps }: ConversationSimulatorPanelProps): react.JSX.Element;
653
638
 
654
- export { AudioRecorderButton as A, acceptsMediaKind as B, type ConversationSummary as C, DEFAULT_AUDIO_RECORDER_BUTTON_LABELS as D, assertPreviewEnvironment as E, createPreviewMediaPoster as F, createPreviewMediaUploader as G, createPreviewWebhookClient as H, isConversationSimulatorClient as I, mediaKindOf as J, mediaTypeOf as K, type ListConversationsParams as L, signPreviewPayload as M, simulatorPanelLabelsOf as N, toConversationSimulatorClient as O, type PreviewUploadedMedia$1 as P, type ListDocumentsParams as Q, type ResolveMediaUrl as R, type SSEProvider as S, type ToSimulatorClientParams as T, type ConversationTemplate as U, type CompanyDocument as V, type CompanyDocumentPage as W, type ConversationDocumentPage as X, DEFAULT_MAX_RECORDING_MILLISECONDS as Y, MediaRenderer as Z, type MediaRendererProps as _, type ConversationEventSource as a, type ConversationsApi as b, type ConversationPage as c, type ConversationDocument as d, type SendPreviewMediaParams as e, type PreviewWebhookClient as f, type AudioRecorderButtonLabels as g, type AudioRecorderButtonProps as h, ConversationPreview as i, type ConversationPreviewProps as j, type ConversationSimulatorClient as k, ConversationSimulatorPanel as l, type ConversationSimulatorPanelLabels as m, type ConversationSimulatorPanelProps as n, type CreatePreviewMediaUploaderParams as o, type CreatePreviewWebhookClientParams as p, DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS as q, DEFAULT_MEDIA_UPLOAD_PATH as r, PreviewInProductionError as s, PreviewMediaUploadRejectedError as t, type PreviewMediaUploadRequest as u, type PreviewUploadedMedia as v, PreviewWebhookRejectedError as w, SIMULATOR_FILE_MEDIA_KINDS as x, type SendSimulatorMediaParams as y, type SimulatorMediaKind as z };
639
+ export { AudioRecorderButton as A, acceptsMediaKind as B, type ConversationSummary as C, DEFAULT_AUDIO_RECORDER_BUTTON_LABELS as D, assertPreviewEnvironment as E, createPreviewMediaPoster as F, createPreviewMediaUploader as G, createPreviewWebhookClient as H, isConversationSimulatorClient as I, mediaKindOf as J, mediaTypeOf as K, type ListConversationsParams as L, signPreviewPayload as M, simulatorPanelLabelsOf as N, toConversationSimulatorClient as O, type PreviewUploadedMedia$1 as P, type ListDocumentsParams as Q, type ResolveMediaUrl as R, type SSEProvider as S, type ToSimulatorClientParams as T, type ConversationTemplate as U, type CompanyDocument as V, type CompanyDocumentPage as W, type ConversationDocumentPage as X, MediaRenderer as Y, type MediaRendererProps as Z, type ConversationEventSource as a, type ConversationsApi as b, type ConversationPage as c, type ConversationDocument as d, type SendPreviewMediaParams as e, type PreviewWebhookClient as f, type AudioRecorderButtonLabels as g, type AudioRecorderButtonProps as h, ConversationPreview as i, type ConversationPreviewProps as j, type ConversationSimulatorClient as k, ConversationSimulatorPanel as l, type ConversationSimulatorPanelLabels as m, type ConversationSimulatorPanelProps as n, type CreatePreviewMediaUploaderParams as o, type CreatePreviewWebhookClientParams as p, DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS as q, DEFAULT_MEDIA_UPLOAD_PATH as r, PreviewInProductionError as s, PreviewMediaUploadRejectedError as t, type PreviewMediaUploadRequest as u, type PreviewUploadedMedia as v, PreviewWebhookRejectedError as w, SIMULATOR_FILE_MEDIA_KINDS as x, type SendSimulatorMediaParams as y, type SimulatorMediaKind as z };
@@ -233,6 +233,19 @@ function formatFileSize(bytes) {
233
233
  return `${formatted} ${FILE_SIZE_UNITS[exponent]}`;
234
234
  }
235
235
 
236
+ // src/audioRecorderFormat.ts
237
+ var DEFAULT_MAX_RECORDING_MILLISECONDS = 5 * 60 * 1e3;
238
+ var RECORDING_FORMATS = [
239
+ { mimeType: "audio/ogg;codecs=opus", uploadMimeType: "audio/ogg", extension: "ogg" },
240
+ { mimeType: "audio/mp4", uploadMimeType: "audio/mp4", extension: "m4a" },
241
+ { mimeType: "audio/webm", uploadMimeType: "audio/webm", extension: "webm" }
242
+ ];
243
+ function resolveRecordingFormat() {
244
+ if (typeof MediaRecorder === "undefined") return void 0;
245
+ if (typeof MediaRecorder.isTypeSupported !== "function") return RECORDING_FORMATS[0];
246
+ return RECORDING_FORMATS.find((format) => MediaRecorder.isTypeSupported(format.mimeType));
247
+ }
248
+
236
249
  export {
237
250
  formatPhone,
238
251
  phoneInitials,
@@ -251,5 +264,7 @@ export {
251
264
  formatTimestamp,
252
265
  formatDateTime,
253
266
  isSameDay,
254
- formatFileSize
267
+ formatFileSize,
268
+ DEFAULT_MAX_RECORDING_MILLISECONDS,
269
+ resolveRecordingFormat
255
270
  };
@@ -6,14 +6,16 @@ import {
6
6
  import {
7
7
  CONVERSATION_CHANNEL,
8
8
  DEFAULT_CONVERSATION_CHANNEL,
9
+ DEFAULT_MAX_RECORDING_MILLISECONDS,
9
10
  StatusTicks,
10
11
  channelCapabilityFor,
11
12
  formatDateTime,
12
13
  formatFileSize,
13
14
  formatPhone,
14
15
  formatTimestamp,
15
- isSameDay
16
- } from "./chunk-O6457XHK.js";
16
+ isSameDay,
17
+ resolveRecordingFormat
18
+ } from "./chunk-WCZNIJ3M.js";
17
19
 
18
20
  // src/ConversationLocalesProvider.tsx
19
21
  import { createContext, useContext } from "react";
@@ -1098,17 +1100,6 @@ var DEFAULT_AUDIO_RECORDER_BUTTON_LABELS = {
1098
1100
  discard: "Descartar \xE1udio",
1099
1101
  empty: "Nada foi captado pelo microfone."
1100
1102
  };
1101
- var DEFAULT_MAX_RECORDING_MILLISECONDS = 5 * 60 * 1e3;
1102
- var RECORDING_FORMATS = [
1103
- { mimeType: "audio/ogg;codecs=opus", uploadMimeType: "audio/ogg", extension: "ogg" },
1104
- { mimeType: "audio/mp4", uploadMimeType: "audio/mp4", extension: "m4a" },
1105
- { mimeType: "audio/webm", uploadMimeType: "audio/webm", extension: "webm" }
1106
- ];
1107
- function resolveRecordingFormat() {
1108
- if (typeof MediaRecorder === "undefined") return void 0;
1109
- if (typeof MediaRecorder.isTypeSupported !== "function") return RECORDING_FORMATS[0];
1110
- return RECORDING_FORMATS.find((format) => MediaRecorder.isTypeSupported(format.mimeType));
1111
- }
1112
1103
  function AudioRecorderButton({
1113
1104
  onRecorded,
1114
1105
  onFailure,
@@ -3047,7 +3038,6 @@ export {
3047
3038
  DEFAULT_EMOJI_PICKER_LABELS,
3048
3039
  EmojiPicker,
3049
3040
  DEFAULT_AUDIO_RECORDER_BUTTON_LABELS,
3050
- DEFAULT_MAX_RECORDING_MILLISECONDS,
3051
3041
  AudioRecorderButton,
3052
3042
  COMPOSER_BAR_CLASS,
3053
3043
  COMPOSER_TOOL_BUTTON_CLASS,
package/dist/index.d.ts CHANGED
@@ -2,8 +2,8 @@ import * as react from 'react';
2
2
  import react__default, { ReactNode, CSSProperties, UIEvent, FormEvent, RefObject, KeyboardEvent } from 'react';
3
3
  import { M as MessagePayload, I as InteractiveSelection, a as MessageTranscription, C as ConversationChannel, e as InteractivePayload, f as ConversationsFeatures, Q as QuickReply$1, T as TranscriptionMode, g as QueuedAttachment, b as QuickReplyInput, c as QuickReplyAttachment, h as ConversationVariable, i as ChannelFilter, j as ChannelFilterOption } from './quickReply.types-DzWH3NYV.js';
4
4
  export { k as CHANNEL_CAPABILITIES, l as CHANNEL_FILTER_ALL, m as CONVERSATION_CHANNEL, n as ChannelCapabilities, d as ConversationsTheme, o as ConversationsUIConfig, D as DEFAULT_CONVERSATION_CHANNEL, F as FormatContactHandleParams, H as HANDLE_KIND, p as HandleKind, q as InteractiveOption, r as InteractiveSection, s as QUICK_REPLY_ATTACHMENT_LIMIT, R as REOPEN_MECHANISM, t as ReopenMechanism, S as StoredAttachmentSendResult, u as TranscriptionStatus, v as capabilitiesOf, w as channelFiltersFor, x as contactFlag, y as formatContactHandle } from './quickReply.types-DzWH3NYV.js';
5
- import { R as ResolveMediaUrl, C as ConversationSummary, L as ListConversationsParams, b as ConversationsApi, S as SSEProvider, Q as ListDocumentsParams, d as ConversationDocument, U as ConversationTemplate, k as ConversationSimulatorClient, m as ConversationSimulatorPanelLabels, P as PreviewUploadedMedia } from './ConversationSimulatorPanel-q-wVgBCN.js';
6
- export { A as AudioRecorderButton, g as AudioRecorderButtonLabels, h as AudioRecorderButtonProps, V as CompanyDocument, W as CompanyDocumentPage, X as ConversationDocumentPage, a as ConversationEventSource, c as ConversationPage, D as DEFAULT_AUDIO_RECORDER_BUTTON_LABELS, Y as DEFAULT_MAX_RECORDING_MILLISECONDS, Z as MediaRenderer, _ as MediaRendererProps, y as SendSimulatorMediaParams, z as SimulatorMediaKind } from './ConversationSimulatorPanel-q-wVgBCN.js';
5
+ import { R as ResolveMediaUrl, C as ConversationSummary, L as ListConversationsParams, b as ConversationsApi, S as SSEProvider, Q as ListDocumentsParams, d as ConversationDocument, U as ConversationTemplate, k as ConversationSimulatorClient, m as ConversationSimulatorPanelLabels, P as PreviewUploadedMedia } from './ConversationSimulatorPanel-P6eqTSAO.js';
6
+ export { A as AudioRecorderButton, g as AudioRecorderButtonLabels, h as AudioRecorderButtonProps, V as CompanyDocument, W as CompanyDocumentPage, X as ConversationDocumentPage, a as ConversationEventSource, c as ConversationPage, D as DEFAULT_AUDIO_RECORDER_BUTTON_LABELS, Y as MediaRenderer, Z as MediaRendererProps, y as SendSimulatorMediaParams, z as SimulatorMediaKind } from './ConversationSimulatorPanel-P6eqTSAO.js';
7
7
  import { ChannelCapability } from '@adatechnology/conversation-contracts';
8
8
  export { ChannelCapability } from '@adatechnology/conversation-contracts';
9
9
  import '@adatechnology/meta-whatsapp-contracts/testing';
@@ -487,6 +487,13 @@ interface RichMessageComposerProps {
487
487
  }
488
488
  declare const RichMessageComposer: react.ForwardRefExoticComponent<RichMessageComposerProps & react.RefAttributes<RichMessageComposerHandle>>;
489
489
 
490
+ /**
491
+ * Cinco minutos: com o codec de voz do WhatsApp isso dá menos de 3MB, folgado dentro do teto de
492
+ * 16MB que a Meta impõe a áudio, e é mais do que qualquer recado de cliente. O corte automático
493
+ * existe porque gravação esquecida aberta só se descobre no envio, com o arquivo inteiro perdido.
494
+ */
495
+ declare const DEFAULT_MAX_RECORDING_MILLISECONDS: number;
496
+
490
497
  interface WhatsAppMessageEditorLabels {
491
498
  bold: string;
492
499
  /** Tooltip da negrito — traz a sintaxe do WhatsApp junto, por isso é separado do `aria-label`. */
@@ -2314,4 +2321,4 @@ type QueuedAttachmentsListProps = {
2314
2321
  };
2315
2322
  declare function QueuedAttachmentsList({ items, statusOf, onRemove, onRetry, retryingKeys, getThumbnailUrl, labels, busy, }: QueuedAttachmentsListProps): react.JSX.Element | null;
2316
2323
 
2317
- export { type AsyncResourceState, type AttachmentFileRejection, AudioPlayer, type AudioPlayerProps, AudioTranscription, type AudioTranscriptionProps, Avatar, type AvatarLabels, type AvatarProps, type BotMessages, type BuildTranscriptTextParams, BulkActionBar, type BulkActionBarProps, CHANNEL_BRAND_COLOR, CONVERSATIONS_PER_PAGE, CONVERSATION_WINDOW, ChannelFilter, ChannelFilterOption, ChannelIcon, type ChannelIconProps, ConversationChannel, type ConversationContextEntry, ConversationContextPanel, type ConversationContextPanelClassNames, type ConversationContextPanelLabels, type ConversationContextPanelProps, type ConversationContextStatus, ConversationDocument, ConversationDocumentsPanel, type ConversationDocumentsPanelClassNames, type ConversationDocumentsPanelLabels, type ConversationDocumentsPanelProps, ConversationHeader, type ConversationHeaderClassNames, type ConversationHeaderLabels, type ConversationHeaderProps, type ConversationHeaderUtility, ConversationListItem, type ConversationListItemLabels, type ConversationListItemProps, type ConversationLocales, ConversationLocalesProvider, type ConversationLocalesProviderProps, ConversationPane, type ConversationPaneProps, type ConversationRealtimeHandler, ConversationRow, type ConversationRowClassNames, type ConversationRowProps, ConversationSimulatorClient, ConversationSummary, ConversationTemplate, ConversationVariable, ConversationWallpaper, type ConversationWallpaperProps, type ConversationWindow, ConversationsApi, ConversationsFeatures, ConversationsInboxList, type ConversationsInboxListProps, ConversationsProvider, ConversationsWorkspace, type ConversationsWorkspaceLabels, type ConversationsWorkspaceProps, type ConversationsWorkspaceSimulator, DEFAULT_ACCEPTED_FILE_TYPES, DEFAULT_AVATAR_LABELS, DEFAULT_CONVERSATIONS_WORKSPACE_LABELS, DEFAULT_CONVERSATION_CONTEXT_LABELS, DEFAULT_CONVERSATION_DOCUMENTS_LABELS, DEFAULT_CONVERSATION_HEADER_LABELS, DEFAULT_CONVERSATION_LIST_ITEM_LABELS, DEFAULT_DARK_MODE_TOGGLE_LABELS, DEFAULT_DOCUMENTS_LIBRARY_LABELS, DEFAULT_DOCUMENTS_WORKSPACE_LABELS, DEFAULT_EMOJI_PICKER_LABELS, DEFAULT_INTERACTIVE_MESSAGE_LABELS, DEFAULT_LIGHTBOX_LABELS, DEFAULT_MAX_ATTACHMENT_SIZE_BYTES, DEFAULT_MESSAGE_COMPOSER_LABELS, DEFAULT_QUICK_REPLIES_PICKER_LABELS, DEFAULT_QUICK_REPLIES_WORKSPACE_LABELS, DEFAULT_RICH_COMPOSER_TOOLTIPS, DEFAULT_TEMPLATES_SETTINGS_LABELS, DEFAULT_WHATSAPP_MESSAGE_EDITOR_LABELS, DEFAULT_WINDOW_EXPIRED_LABELS, DOCUMENT_SOURCE_FILTER, DarkModeToggle, type DarkModeToggleLabels, type DarkModeToggleProps, DateDivider, type DateDividerClassNames, type DateDividerProps, type DocumentSourceFilter, type DocumentsFiltersContext, DocumentsLibrary, type DocumentsLibraryClassNames, type DocumentsLibraryLabels, type DocumentsLibraryProps, DocumentsWorkspace, type DocumentsWorkspaceClassNames, type DocumentsWorkspaceLabels, type DocumentsWorkspaceProps, EMOJI_CATEGORIES, type EmojiCategory, type EmojiEntry, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, FileIcon, type FileIconProps, type FilterOption, type FilterQuickRepliesParams, InteractiveMessage, type InteractiveMessageLabels, type InteractiveMessageProps, InteractivePayload, InteractiveSelection, Lightbox, type LightboxLabels, type LightboxProps, ListConversationsParams, ListDocumentsParams, ListingPagination, type ListingPaginationProps, type MatchSegment, type MaxAttachmentSizeBytes, MessageBubble, type MessageBubbleProps, MessageComposer, type MessageComposerClassNames, type MessageComposerLabels, type MessageComposerProps, MessagePayload, MessageTail, MessageText, type MessageTextProps, MessageTimestamp, MessageTranscription, MessagesWorkspace, type MessagesWorkspaceApi, type MessagesWorkspaceLabels, type MessagesWorkspaceProps, type MessagesWorkspaceTemplateRole, MultiSelectFilter, type MultiSelectFilterProps, NARROW_MAX_WIDTH_PX, type OutgoingItems, QueuedAttachment, QueuedAttachmentsList, QuickRepliesPicker, type QuickRepliesPickerLabels, type QuickRepliesPickerProps, QuickRepliesWorkspace, type QuickRepliesWorkspaceLabels, type QuickRepliesWorkspaceProps, type QuickReply, QuickReplyAttachment, QuickReplyInput, REPLY_LATENCY, REPLY_LATENCY_CRITICAL_HOURS, REPLY_LATENCY_LATE_HOURS, RICH_COMPOSER_ACTION, type ReplyLatency, type ReplyLatencyParams, ResolveMediaUrl, type RichComposerAction, type RichComposerQuickReply, type RichComposerTooltips, type RichComposerVariable, RichMessageComposer, type RichMessageComposerHandle, type RichMessageComposerProps, SSEProvider, QuickReply$1 as SavedQuickReply, SimpleEmojiPicker, type SimpleEmojiPickerProps, type SimulatorTransportFactory, type SimulatorTransportParams, type SortDirection, SortableHead, type SortableHeadProps, StatusTicks, type StatusTicksProps, TEMPLATE_SETTINGS_TAB, TOOLTIP_ATTRIBUTE, type TemplateSettings, type TemplateSettingsTab, ToastProvider, TooltipLayer, type TopicItem, TopicsForm, type TopicsFormLabels, type TopicsFormProps, TranscriptionMode, type TranscriptionSettings, TranscriptionSettingsForm, type TranscriptionSettingsFormLabels, type TranscriptionSettingsFormProps, type UrlStateOptions, type UseConversationActionsResult, type UseConversationContextResult, type UseConversationDocumentsParams, type UseConversationDocumentsResult, type UseConversationListParams, type UseConversationListResult, type UseConversationMessagesResult, type UseConversationsInboxParams, type UseConversationsInboxResult, type UseInboxActionsResult, type UseScrollToLatestMessageParams, type UseScrollToLatestMessageResult, type UseWaitingNotificationsLabels, type UseWaitingNotificationsParams, type UseWaitingNotificationsResult, type ValidateAttachmentFilesResult, WHATSAPP_MARKER_BY_ACTION, WINDOW_FILTERS, WelcomeFarewellForm, type WelcomeFarewellFormLabels, type WelcomeFarewellFormProps, WhatsAppCreateTemplateForm, type WhatsAppCreateTemplateFormLabels, type WhatsAppCreateTemplateFormProps, type WhatsAppCreateTemplateResult, type WhatsAppCreateTemplateState, WhatsAppMessageEditor, type WhatsAppMessageEditorLabels, type WhatsAppMessageEditorProps, WhatsAppMessagePreview, type WhatsAppMessagePreviewProps, type WhatsAppTemplateHeaderType, WhatsAppTemplateSettingsForm, type WhatsAppTemplateSettingsFormLabels, type WhatsAppTemplateSettingsFormProps, type WhatsAppTemplateSummary, type WhatsAppTemplateVariableSuggestion, WhatsAppTemplatesSettings, type WhatsAppTemplatesSettingsLabels, type WhatsAppTemplatesSettingsProps, WindowExpiredNotice, type WindowExpiredNoticeLabels, type WindowExpiredNoticeProps, type WindowOfParams, applyQuickReplyVariables, buildTranscriptFilename, buildTranscriptText, channelCapabilityFor, createMediaUrlResolver, downloadTextFile, filterQuickReplies, formatDateTime, formatFileSize, formatPhone, formatStalledFor, formatTimestamp, highlightMatch, htmlToWA, isReplyOverdue, isSameDay, isWindowBlocking, normalizeForSearch, parseWhatsAppFormatting, phoneInitials, queuedAttachmentsFromQuickReply, replyLatencyOf, resolveMaxAttachmentSizeBytes, resolveQuickReply, searchEmojis, toast, useConversationActions, useConversationContext, useConversationDocuments, useConversationList, useConversationLocales, useConversationMessages, useConversationRealtime, useConversations, useConversationsInbox, useDarkMode, useDebouncedValue, useGlobalRealtime, useInboxActions, useIsDarkTheme, useIsNarrow, useScrollToLatestMessage, useToast, useUrlArrayState, useUrlNumberState, useUrlStringState, useWaitingNotifications, waToHTML, waToHTMLInline, windowOf };
2324
+ export { type AsyncResourceState, type AttachmentFileRejection, AudioPlayer, type AudioPlayerProps, AudioTranscription, type AudioTranscriptionProps, Avatar, type AvatarLabels, type AvatarProps, type BotMessages, type BuildTranscriptTextParams, BulkActionBar, type BulkActionBarProps, CHANNEL_BRAND_COLOR, CONVERSATIONS_PER_PAGE, CONVERSATION_WINDOW, ChannelFilter, ChannelFilterOption, ChannelIcon, type ChannelIconProps, ConversationChannel, type ConversationContextEntry, ConversationContextPanel, type ConversationContextPanelClassNames, type ConversationContextPanelLabels, type ConversationContextPanelProps, type ConversationContextStatus, ConversationDocument, ConversationDocumentsPanel, type ConversationDocumentsPanelClassNames, type ConversationDocumentsPanelLabels, type ConversationDocumentsPanelProps, ConversationHeader, type ConversationHeaderClassNames, type ConversationHeaderLabels, type ConversationHeaderProps, type ConversationHeaderUtility, ConversationListItem, type ConversationListItemLabels, type ConversationListItemProps, type ConversationLocales, ConversationLocalesProvider, type ConversationLocalesProviderProps, ConversationPane, type ConversationPaneProps, type ConversationRealtimeHandler, ConversationRow, type ConversationRowClassNames, type ConversationRowProps, ConversationSimulatorClient, ConversationSummary, ConversationTemplate, ConversationVariable, ConversationWallpaper, type ConversationWallpaperProps, type ConversationWindow, ConversationsApi, ConversationsFeatures, ConversationsInboxList, type ConversationsInboxListProps, ConversationsProvider, ConversationsWorkspace, type ConversationsWorkspaceLabels, type ConversationsWorkspaceProps, type ConversationsWorkspaceSimulator, DEFAULT_ACCEPTED_FILE_TYPES, DEFAULT_AVATAR_LABELS, DEFAULT_CONVERSATIONS_WORKSPACE_LABELS, DEFAULT_CONVERSATION_CONTEXT_LABELS, DEFAULT_CONVERSATION_DOCUMENTS_LABELS, DEFAULT_CONVERSATION_HEADER_LABELS, DEFAULT_CONVERSATION_LIST_ITEM_LABELS, DEFAULT_DARK_MODE_TOGGLE_LABELS, DEFAULT_DOCUMENTS_LIBRARY_LABELS, DEFAULT_DOCUMENTS_WORKSPACE_LABELS, DEFAULT_EMOJI_PICKER_LABELS, DEFAULT_INTERACTIVE_MESSAGE_LABELS, DEFAULT_LIGHTBOX_LABELS, DEFAULT_MAX_ATTACHMENT_SIZE_BYTES, DEFAULT_MAX_RECORDING_MILLISECONDS, DEFAULT_MESSAGE_COMPOSER_LABELS, DEFAULT_QUICK_REPLIES_PICKER_LABELS, DEFAULT_QUICK_REPLIES_WORKSPACE_LABELS, DEFAULT_RICH_COMPOSER_TOOLTIPS, DEFAULT_TEMPLATES_SETTINGS_LABELS, DEFAULT_WHATSAPP_MESSAGE_EDITOR_LABELS, DEFAULT_WINDOW_EXPIRED_LABELS, DOCUMENT_SOURCE_FILTER, DarkModeToggle, type DarkModeToggleLabels, type DarkModeToggleProps, DateDivider, type DateDividerClassNames, type DateDividerProps, type DocumentSourceFilter, type DocumentsFiltersContext, DocumentsLibrary, type DocumentsLibraryClassNames, type DocumentsLibraryLabels, type DocumentsLibraryProps, DocumentsWorkspace, type DocumentsWorkspaceClassNames, type DocumentsWorkspaceLabels, type DocumentsWorkspaceProps, EMOJI_CATEGORIES, type EmojiCategory, type EmojiEntry, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, FileIcon, type FileIconProps, type FilterOption, type FilterQuickRepliesParams, InteractiveMessage, type InteractiveMessageLabels, type InteractiveMessageProps, InteractivePayload, InteractiveSelection, Lightbox, type LightboxLabels, type LightboxProps, ListConversationsParams, ListDocumentsParams, ListingPagination, type ListingPaginationProps, type MatchSegment, type MaxAttachmentSizeBytes, MessageBubble, type MessageBubbleProps, MessageComposer, type MessageComposerClassNames, type MessageComposerLabels, type MessageComposerProps, MessagePayload, MessageTail, MessageText, type MessageTextProps, MessageTimestamp, MessageTranscription, MessagesWorkspace, type MessagesWorkspaceApi, type MessagesWorkspaceLabels, type MessagesWorkspaceProps, type MessagesWorkspaceTemplateRole, MultiSelectFilter, type MultiSelectFilterProps, NARROW_MAX_WIDTH_PX, type OutgoingItems, QueuedAttachment, QueuedAttachmentsList, QuickRepliesPicker, type QuickRepliesPickerLabels, type QuickRepliesPickerProps, QuickRepliesWorkspace, type QuickRepliesWorkspaceLabels, type QuickRepliesWorkspaceProps, type QuickReply, QuickReplyAttachment, QuickReplyInput, REPLY_LATENCY, REPLY_LATENCY_CRITICAL_HOURS, REPLY_LATENCY_LATE_HOURS, RICH_COMPOSER_ACTION, type ReplyLatency, type ReplyLatencyParams, ResolveMediaUrl, type RichComposerAction, type RichComposerQuickReply, type RichComposerTooltips, type RichComposerVariable, RichMessageComposer, type RichMessageComposerHandle, type RichMessageComposerProps, SSEProvider, QuickReply$1 as SavedQuickReply, SimpleEmojiPicker, type SimpleEmojiPickerProps, type SimulatorTransportFactory, type SimulatorTransportParams, type SortDirection, SortableHead, type SortableHeadProps, StatusTicks, type StatusTicksProps, TEMPLATE_SETTINGS_TAB, TOOLTIP_ATTRIBUTE, type TemplateSettings, type TemplateSettingsTab, ToastProvider, TooltipLayer, type TopicItem, TopicsForm, type TopicsFormLabels, type TopicsFormProps, TranscriptionMode, type TranscriptionSettings, TranscriptionSettingsForm, type TranscriptionSettingsFormLabels, type TranscriptionSettingsFormProps, type UrlStateOptions, type UseConversationActionsResult, type UseConversationContextResult, type UseConversationDocumentsParams, type UseConversationDocumentsResult, type UseConversationListParams, type UseConversationListResult, type UseConversationMessagesResult, type UseConversationsInboxParams, type UseConversationsInboxResult, type UseInboxActionsResult, type UseScrollToLatestMessageParams, type UseScrollToLatestMessageResult, type UseWaitingNotificationsLabels, type UseWaitingNotificationsParams, type UseWaitingNotificationsResult, type ValidateAttachmentFilesResult, WHATSAPP_MARKER_BY_ACTION, WINDOW_FILTERS, WelcomeFarewellForm, type WelcomeFarewellFormLabels, type WelcomeFarewellFormProps, WhatsAppCreateTemplateForm, type WhatsAppCreateTemplateFormLabels, type WhatsAppCreateTemplateFormProps, type WhatsAppCreateTemplateResult, type WhatsAppCreateTemplateState, WhatsAppMessageEditor, type WhatsAppMessageEditorLabels, type WhatsAppMessageEditorProps, WhatsAppMessagePreview, type WhatsAppMessagePreviewProps, type WhatsAppTemplateHeaderType, WhatsAppTemplateSettingsForm, type WhatsAppTemplateSettingsFormLabels, type WhatsAppTemplateSettingsFormProps, type WhatsAppTemplateSummary, type WhatsAppTemplateVariableSuggestion, WhatsAppTemplatesSettings, type WhatsAppTemplatesSettingsLabels, type WhatsAppTemplatesSettingsProps, WindowExpiredNotice, type WindowExpiredNoticeLabels, type WindowExpiredNoticeProps, type WindowOfParams, applyQuickReplyVariables, buildTranscriptFilename, buildTranscriptText, channelCapabilityFor, createMediaUrlResolver, downloadTextFile, filterQuickReplies, formatDateTime, formatFileSize, formatPhone, formatStalledFor, formatTimestamp, highlightMatch, htmlToWA, isReplyOverdue, isSameDay, isWindowBlocking, normalizeForSearch, parseWhatsAppFormatting, phoneInitials, queuedAttachmentsFromQuickReply, replyLatencyOf, resolveMaxAttachmentSizeBytes, resolveQuickReply, searchEmojis, toast, useConversationActions, useConversationContext, useConversationDocuments, useConversationList, useConversationLocales, useConversationMessages, useConversationRealtime, useConversations, useConversationsInbox, useDarkMode, useDebouncedValue, useGlobalRealtime, useInboxActions, useIsDarkTheme, useIsNarrow, useScrollToLatestMessage, useToast, useUrlArrayState, useUrlNumberState, useUrlStringState, useWaitingNotifications, waToHTML, waToHTMLInline, windowOf };
package/dist/index.js CHANGED
@@ -27,7 +27,6 @@ import {
27
27
  DEFAULT_EMOJI_PICKER_LABELS,
28
28
  DEFAULT_INTERACTIVE_MESSAGE_LABELS,
29
29
  DEFAULT_LIGHTBOX_LABELS,
30
- DEFAULT_MAX_RECORDING_MILLISECONDS,
31
30
  DEFAULT_MESSAGE_COMPOSER_LABELS,
32
31
  DEFAULT_QUICK_REPLIES_PICKER_LABELS,
33
32
  DEFAULT_QUICK_REPLIES_WORKSPACE_LABELS,
@@ -61,7 +60,7 @@ import {
61
60
  useConversationLocales,
62
61
  useConversations,
63
62
  useQuickRepliesPicker
64
- } from "./chunk-L3OFAQPS.js";
63
+ } from "./chunk-Y326LLEP.js";
65
64
  import {
66
65
  ZERO_WIDTH_SPACE,
67
66
  cn,
@@ -77,6 +76,7 @@ import {
77
76
  CHANNEL_FILTER_ALL,
78
77
  CONVERSATION_CHANNEL,
79
78
  DEFAULT_CONVERSATION_CHANNEL,
79
+ DEFAULT_MAX_RECORDING_MILLISECONDS,
80
80
  HANDLE_KIND,
81
81
  REOPEN_MECHANISM,
82
82
  StatusTicks,
@@ -91,7 +91,7 @@ import {
91
91
  formatTimestamp,
92
92
  isSameDay,
93
93
  phoneInitials
94
- } from "./chunk-O6457XHK.js";
94
+ } from "./chunk-WCZNIJ3M.js";
95
95
 
96
96
  // src/RichMessageComposer.tsx
97
97
  import {
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { ParticipantConversationSummary, ParticipantConversationPage, ParticipantSubjectRef, ParticipantMessage, ParticipantAttachment } from '@adatechnology/conversation-contracts';
4
- export { ParticipantAttachment, ParticipantConversationPage, ParticipantConversationSummary, ParticipantMessage, ParticipantSubjectRef } from '@adatechnology/conversation-contracts';
4
+ export { ParticipantAttachment, ParticipantConversationPage, ParticipantConversationSummary, ParticipantMessage, ParticipantSubjectRef, ParticipantTranscription } from '@adatechnology/conversation-contracts';
5
5
  import { C as ConversationChannel, d as ConversationsTheme, Q as QuickReply } from '../quickReply.types-DzWH3NYV.js';
6
6
 
7
7
  type ParticipantAuthorAvatarRenderer = (author: {
@@ -105,6 +105,50 @@ type ParticipantLocalPendingMessage = Omit<ParticipantPendingMessage, 'state'> &
105
105
  readonly state: 'sending' | 'queued' | 'failed' | 'sent';
106
106
  };
107
107
 
108
+ type ParticipantAudioRecordingOptions = {
109
+ /** Only lowers the default: a larger value is cut to DEFAULT_MAX_RECORDING_MILLISECONDS (5 min). */
110
+ readonly maxDurationMs?: number;
111
+ /** Only lowers the default: a larger value is cut to DEFAULT_MAX_RECORDING_BYTES (16 MiB, the app audio policy). */
112
+ readonly maxSizeBytes?: number;
113
+ /** True from `requesting` until it leaves `review`; the host feeds its capture registry. Never receives the audio. */
114
+ readonly onCaptureChange?: (isCapturing: boolean) => void;
115
+ };
116
+ declare const DEFAULT_MAX_RECORDING_BYTES: number;
117
+
118
+ type ParticipantAudioLabels = {
119
+ readonly recordAudio: string;
120
+ readonly recordingInProgress: string;
121
+ readonly stopRecording: string;
122
+ /** Uses the `{elapsed}` and `{limit}` placeholders. */
123
+ readonly recordingElapsed: string;
124
+ readonly reviewAudio: string;
125
+ readonly sendAudio: string;
126
+ readonly discardAudio: string;
127
+ readonly microphoneDenied: string;
128
+ readonly recordingUnsupported: string;
129
+ readonly audioEmpty: string;
130
+ readonly audioTooLarge: string;
131
+ readonly audioPlayer: string;
132
+ readonly playAudio: string;
133
+ readonly pauseAudio: string;
134
+ readonly audioPosition: string;
135
+ /** Uses the `{position}` and `{duration}` placeholders; without a duration only the position is spoken. */
136
+ readonly audioPositionValue: string;
137
+ /** Uses the `{rate}` placeholder. */
138
+ readonly playbackRate: string;
139
+ readonly audioUnavailable: string;
140
+ readonly transcribing: string;
141
+ /** Spoken by the thread's live region when a transcription finishes. */
142
+ readonly transcriptionReady: string;
143
+ readonly machineTranscription: string;
144
+ readonly emptyTranscription: string;
145
+ /** Uses the `{minutes}` placeholder, filled from the limit the server applied. */
146
+ readonly transcriptionTooLong: string;
147
+ readonly showFullTranscription: string;
148
+ readonly collapseTranscription: string;
149
+ };
150
+ declare const DEFAULT_PARTICIPANT_AUDIO_LABELS: ParticipantAudioLabels;
151
+
108
152
  type ParticipantConversationsLabels = {
109
153
  readonly inboxTitle: string;
110
154
  readonly sectionAwaiting: string;
@@ -170,7 +214,7 @@ type ParticipantConversationsLabels = {
170
214
  /** Prefix of the accessible name of the copy buttons: "Copy 529.982.247-25". */
171
215
  readonly copyValue: string;
172
216
  readonly valueCopied: string;
173
- };
217
+ } & Readonly<Partial<ParticipantAudioLabels>>;
174
218
  declare const DEFAULT_PARTICIPANT_CONVERSATIONS_LABELS: ParticipantConversationsLabels;
175
219
 
176
220
  type ParticipantConversationsProps = {
@@ -198,6 +242,10 @@ type ParticipantConversationsProps = {
198
242
  renderAuthorAvatar?: ParticipantAuthorAvatarRenderer;
199
243
  /** Speech-bubble tail on the bottom corner; false removes it. Default true. */
200
244
  tail?: boolean;
245
+ /** Absent draws no microphone. Present lets the user record and send an audio as a message of its own. */
246
+ audioRecording?: ParticipantAudioRecordingOptions;
247
+ /** Return a node to replace the composer for this conversation (notice + host actions); undefined keeps the composer. `closed` still wins. Evaluated every render. */
248
+ renderComposerLock?: (conversation: ParticipantConversationSummary) => ReactNode | undefined;
201
249
  };
202
250
  declare function ParticipantConversations(props: ParticipantConversationsProps): react.JSX.Element;
203
251
 
@@ -239,10 +287,14 @@ type ConversationThreadProps = {
239
287
  readonly tail?: boolean;
240
288
  readonly avatars?: 'initials';
241
289
  readonly renderAuthorAvatar?: ParticipantAuthorAvatarRenderer;
290
+ /** Absent draws no microphone. Present lets the user record and send an audio as a message of its own. */
291
+ readonly audioRecording?: ParticipantAudioRecordingOptions;
292
+ /** Return a node to replace the composer (notice + host actions); undefined keeps the composer. `closed` still wins. Evaluated every render. */
293
+ readonly renderComposerLock?: (conversation: ParticipantConversationSummary) => ReactNode | undefined;
242
294
  };
243
295
  /** One conversation about one subject, drawn like the participant app and seen from either side. */
244
296
  declare function ConversationThread(props: ConversationThreadProps): react.JSX.Element;
245
297
 
246
298
  declare function groupParticipantConversations(params: GroupParticipantConversationsParams): ParticipantInboxView;
247
299
 
248
- export { ConversationThread, type ConversationThreadApi, type ConversationThreadProps, DEFAULT_PARTICIPANT_CONVERSATIONS_LABELS, type GroupParticipantConversationsParams, type ParticipantAuthorAvatarRenderer, type ParticipantConversationEvent, ParticipantConversations, type ParticipantConversationsApi, type ParticipantConversationsClassNames, type ParticipantConversationsLabels, type ParticipantConversationsProps, type ParticipantInboxSection, type ParticipantInboxView, type ParticipantLocalPendingMessage, type ParticipantPendingMessage, type ParticipantPerspective, type ParticipantSendInput, type ParticipantSendResult, type ParticipantSubjectGroup, type ParticipantSubjectIconRenderer, groupParticipantConversations };
300
+ export { ConversationThread, type ConversationThreadApi, type ConversationThreadProps, DEFAULT_MAX_RECORDING_BYTES, DEFAULT_PARTICIPANT_AUDIO_LABELS, DEFAULT_PARTICIPANT_CONVERSATIONS_LABELS, type GroupParticipantConversationsParams, type ParticipantAudioLabels, type ParticipantAudioRecordingOptions, type ParticipantAuthorAvatarRenderer, type ParticipantConversationEvent, ParticipantConversations, type ParticipantConversationsApi, type ParticipantConversationsClassNames, type ParticipantConversationsLabels, type ParticipantConversationsProps, type ParticipantInboxSection, type ParticipantInboxView, type ParticipantLocalPendingMessage, type ParticipantPendingMessage, type ParticipantPerspective, type ParticipantSendInput, type ParticipantSendResult, type ParticipantSubjectGroup, type ParticipantSubjectIconRenderer, groupParticipantConversations };