valtech-components 4.0.241 → 4.0.242
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/esm2022/lib/components/molecules/chat-composer/chat-composer.component.mjs +63 -3
- package/esm2022/lib/components/molecules/message-bubble/message-bubble.component.mjs +28 -3
- package/esm2022/lib/version.mjs +2 -2
- package/fesm2022/valtech-components.mjs +90 -5
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/molecules/chat-composer/chat-composer.component.d.ts +5 -0
- package/lib/components/molecules/message-bubble/message-bubble.component.d.ts +5 -0
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -56,7 +56,7 @@ import { BrowserMultiFormatReader } from '@zxing/browser';
|
|
|
56
56
|
* Current version of valtech-components.
|
|
57
57
|
* This is automatically updated during the publish process.
|
|
58
58
|
*/
|
|
59
|
-
const VERSION = '4.0.
|
|
59
|
+
const VERSION = '4.0.242';
|
|
60
60
|
|
|
61
61
|
// Control de estado de refresco (singleton a nivel de módulo)
|
|
62
62
|
let isRefreshing = false;
|
|
@@ -72621,6 +72621,19 @@ class MessageBubbleComponent {
|
|
|
72621
72621
|
this.actionsOpen.set(false);
|
|
72622
72622
|
this.action.emit({ type, msgId: this.msg().msgId, token });
|
|
72623
72623
|
}
|
|
72624
|
+
/** Diagnóstico: el navegador no pudo reproducir el audio recibido. */
|
|
72625
|
+
onAudioError(att, event) {
|
|
72626
|
+
const el = event.target;
|
|
72627
|
+
const codes = { 1: 'ABORTED', 2: 'NETWORK', 3: 'DECODE', 4: 'SRC_NOT_SUPPORTED' };
|
|
72628
|
+
const canPlay = att.mimeType ? document.createElement('audio').canPlayType(att.mimeType) : '';
|
|
72629
|
+
console.error('[MessageBubble] audio play error', {
|
|
72630
|
+
mimeType: att.mimeType,
|
|
72631
|
+
url: att.url.slice(0, 80),
|
|
72632
|
+
code: el.error?.code,
|
|
72633
|
+
reason: el.error ? codes[el.error.code] : 'unknown',
|
|
72634
|
+
canPlayThisType: canPlay,
|
|
72635
|
+
});
|
|
72636
|
+
}
|
|
72624
72637
|
t(key) {
|
|
72625
72638
|
return this.i18n.t(key, 'MessageBubble');
|
|
72626
72639
|
}
|
|
@@ -72669,7 +72682,13 @@ class MessageBubbleComponent {
|
|
|
72669
72682
|
@if (audioAttachments().length > 0) {
|
|
72670
72683
|
<div class="audios">
|
|
72671
72684
|
@for (att of audioAttachments(); track att.url) {
|
|
72672
|
-
<audio
|
|
72685
|
+
<audio
|
|
72686
|
+
class="att-audio"
|
|
72687
|
+
controls
|
|
72688
|
+
preload="metadata"
|
|
72689
|
+
[src]="att.url"
|
|
72690
|
+
(error)="onAudioError(att, $event)"
|
|
72691
|
+
></audio>
|
|
72673
72692
|
}
|
|
72674
72693
|
</div>
|
|
72675
72694
|
}
|
|
@@ -72784,7 +72803,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
72784
72803
|
@if (audioAttachments().length > 0) {
|
|
72785
72804
|
<div class="audios">
|
|
72786
72805
|
@for (att of audioAttachments(); track att.url) {
|
|
72787
|
-
<audio
|
|
72806
|
+
<audio
|
|
72807
|
+
class="att-audio"
|
|
72808
|
+
controls
|
|
72809
|
+
preload="metadata"
|
|
72810
|
+
[src]="att.url"
|
|
72811
|
+
(error)="onAudioError(att, $event)"
|
|
72812
|
+
></audio>
|
|
72788
72813
|
}
|
|
72789
72814
|
</div>
|
|
72790
72815
|
}
|
|
@@ -73184,6 +73209,10 @@ class ChatComposerComponent {
|
|
|
73184
73209
|
this.recStream = stream;
|
|
73185
73210
|
const mimeType = this.pickAudioMime();
|
|
73186
73211
|
this.recorder = new MediaRecorder(stream, mimeType ? { mimeType } : undefined);
|
|
73212
|
+
console.log('[ChatComposer] recording start', {
|
|
73213
|
+
picked: mimeType || '(default)',
|
|
73214
|
+
recorderMimeType: this.recorder.mimeType,
|
|
73215
|
+
});
|
|
73187
73216
|
this.recChunks = [];
|
|
73188
73217
|
this.recorder.ondataavailable = e => {
|
|
73189
73218
|
if (e.data.size > 0)
|
|
@@ -73210,6 +73239,13 @@ class ChatComposerComponent {
|
|
|
73210
73239
|
const blob = new Blob(this.recChunks, { type });
|
|
73211
73240
|
const ext = type.includes('mp4') ? 'm4a' : 'webm';
|
|
73212
73241
|
const file = new File([blob], `audio-${this.recSeconds()}s.${ext}`, { type });
|
|
73242
|
+
console.log('[ChatComposer] audio recorded', {
|
|
73243
|
+
type,
|
|
73244
|
+
size: blob.size,
|
|
73245
|
+
chunks: this.recChunks.length,
|
|
73246
|
+
canPlayWebm: this.canPlay('audio/webm'),
|
|
73247
|
+
canPlayMp4: this.canPlay('audio/mp4'),
|
|
73248
|
+
});
|
|
73213
73249
|
if (blob.size > 0)
|
|
73214
73250
|
this.addPending(file);
|
|
73215
73251
|
this.cleanupRecording();
|
|
@@ -73240,6 +73276,43 @@ class ChatComposerComponent {
|
|
|
73240
73276
|
this.recording.set(false);
|
|
73241
73277
|
this.recSeconds.set(0);
|
|
73242
73278
|
}
|
|
73279
|
+
/** Diagnóstico: el navegador no pudo reproducir el adjunto de audio. */
|
|
73280
|
+
onAudioError(where, file, event) {
|
|
73281
|
+
const el = event.target;
|
|
73282
|
+
const err = el.error;
|
|
73283
|
+
const codes = {
|
|
73284
|
+
1: 'ABORTED',
|
|
73285
|
+
2: 'NETWORK',
|
|
73286
|
+
3: 'DECODE',
|
|
73287
|
+
4: 'SRC_NOT_SUPPORTED',
|
|
73288
|
+
};
|
|
73289
|
+
console.error('[ChatComposer] audio play error', {
|
|
73290
|
+
where,
|
|
73291
|
+
fileType: file.type,
|
|
73292
|
+
fileName: file.name,
|
|
73293
|
+
code: err?.code,
|
|
73294
|
+
reason: err ? codes[err.code] : 'unknown',
|
|
73295
|
+
message: err?.message,
|
|
73296
|
+
canPlayThisType: this.canPlay(file.type),
|
|
73297
|
+
});
|
|
73298
|
+
}
|
|
73299
|
+
onAudioLoaded(where, file, event) {
|
|
73300
|
+
const el = event.target;
|
|
73301
|
+
console.log('[ChatComposer] audio loadedmetadata', {
|
|
73302
|
+
where,
|
|
73303
|
+
fileType: file.type,
|
|
73304
|
+
duration: el.duration,
|
|
73305
|
+
});
|
|
73306
|
+
}
|
|
73307
|
+
/** ¿El navegador declara que puede reproducir este tipo? '' / 'maybe' / 'probably'. */
|
|
73308
|
+
canPlay(type) {
|
|
73309
|
+
try {
|
|
73310
|
+
return document.createElement('audio').canPlayType(type);
|
|
73311
|
+
}
|
|
73312
|
+
catch {
|
|
73313
|
+
return 'error';
|
|
73314
|
+
}
|
|
73315
|
+
}
|
|
73243
73316
|
ngOnDestroy() {
|
|
73244
73317
|
this.cleanupRecording();
|
|
73245
73318
|
for (const att of this.pending()) {
|
|
@@ -73270,7 +73343,13 @@ class ChatComposerComponent {
|
|
|
73270
73343
|
@for (att of pending(); track att.id) {
|
|
73271
73344
|
@if (att.kind === 'audio') {
|
|
73272
73345
|
<div class="audio-chip">
|
|
73273
|
-
<audio
|
|
73346
|
+
<audio
|
|
73347
|
+
controls
|
|
73348
|
+
preload="metadata"
|
|
73349
|
+
[src]="att.url"
|
|
73350
|
+
(error)="onAudioError('preview', att.file, $event)"
|
|
73351
|
+
(loadedmetadata)="onAudioLoaded('preview', att.file, $event)"
|
|
73352
|
+
></audio>
|
|
73274
73353
|
<button class="thumb-remove inline" [attr.aria-label]="t('remove')" (click)="removePending(att.id)">
|
|
73275
73354
|
<ion-icon name="close-outline" aria-hidden="true" />
|
|
73276
73355
|
</button>
|
|
@@ -73365,7 +73444,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
73365
73444
|
@for (att of pending(); track att.id) {
|
|
73366
73445
|
@if (att.kind === 'audio') {
|
|
73367
73446
|
<div class="audio-chip">
|
|
73368
|
-
<audio
|
|
73447
|
+
<audio
|
|
73448
|
+
controls
|
|
73449
|
+
preload="metadata"
|
|
73450
|
+
[src]="att.url"
|
|
73451
|
+
(error)="onAudioError('preview', att.file, $event)"
|
|
73452
|
+
(loadedmetadata)="onAudioLoaded('preview', att.file, $event)"
|
|
73453
|
+
></audio>
|
|
73369
73454
|
<button class="thumb-remove inline" [attr.aria-label]="t('remove')" (click)="removePending(att.id)">
|
|
73370
73455
|
<ion-icon name="close-outline" aria-hidden="true" />
|
|
73371
73456
|
</button>
|