ov-components: Implement error handling for recording start failures and enhance UI interactions

master
Carlos Santos 2025-07-29 18:19:16 +02:00
parent 5f6b404576
commit fe3f90d266
14 changed files with 78 additions and 33 deletions

View File

@ -103,7 +103,7 @@
<mat-icon class="error-icon" aria-hidden="true">error_outline</mat-icon> <mat-icon class="error-icon" aria-hidden="true">error_outline</mat-icon>
</div> </div>
<div class="error-content"> <div class="error-content">
<span class="error-title">Error starting recording</span> <span class="error-title">{{ 'PANEL.RECORDING.ERROR_STARTING' | translate }}</span>
<span class="error-message">{{ recordingError }}</span> <span class="error-message">{{ recordingError }}</span>
</div> </div>
</div> </div>

View File

@ -11,15 +11,21 @@
id="activities-tag" id="activities-tag"
*ngIf="recordingStatus === _recordingStatus.STARTED || broadcastingStatus === _broadcastingStatus.STARTED" *ngIf="recordingStatus === _recordingStatus.STARTED || broadcastingStatus === _broadcastingStatus.STARTED"
> >
<div *ngIf="recordingStatus === _recordingStatus.STARTED" id="recording-tag" class="recording-tag"> @if (recordingStatus === _recordingStatus.STARTED) {
<mat-icon class="blink">radio_button_checked</mat-icon> <div id="recording-tag" class="recording-tag" (click)="openRecordingActivityPanel()">
<span class="blink">REC</span> <mat-icon class="blink">radio_button_checked</mat-icon>
<span *ngIf="recordingTime"> | {{ recordingTime | date: 'H:mm:ss' }}</span> <span class="blink">REC</span>
</div> <span *ngIf="recordingTime"> | {{ recordingTime | date: 'H:mm:ss' }}</span>
<div *ngIf="broadcastingStatus === _broadcastingStatus.STARTED" id="broadcasting-tag" class="broadcasting-tag"> </div>
<mat-icon class="blink">sensors</mat-icon> }
<span class="blink">LIVE</span>
</div> @if (broadcastingStatus === _broadcastingStatus.STARTED) {
<!-- Broadcasting tag -->
<div id="broadcasting-tag" class="broadcasting-tag">
<mat-icon class="blink">sensors</mat-icon>
<span class="blink">LIVE</span>
</div>
}
</div> </div>
</div> </div>
</div> </div>
@ -129,12 +135,17 @@
(click)="toggleRecording()" (click)="toggleRecording()"
> >
<mat-icon color="warn">radio_button_checked</mat-icon> <mat-icon color="warn">radio_button_checked</mat-icon>
<span *ngIf="recordingStatus === _recordingStatus.STOPPED || recordingStatus === _recordingStatus.STOPPING"> @if (
{{ 'TOOLBAR.START_RECORDING' | translate }} recordingStatus === _recordingStatus.STOPPED ||
</span> recordingStatus === _recordingStatus.STOPPING ||
<span *ngIf="recordingStatus === _recordingStatus.STARTED || recordingStatus === _recordingStatus.STARTING"> recordingStatus === _recordingStatus.FAILED
{{ 'TOOLBAR.STOP_RECORDING' | translate }} ) {
</span> <span class="blink">
{{ 'TOOLBAR.START_RECORDING' | translate }}
</span>
} @else if (recordingStatus === _recordingStatus.STARTED || recordingStatus === _recordingStatus.STARTING) {
<span>{{ 'TOOLBAR.RECORDING' | translate }}</span>
}
</button> </button>
<!-- View recordings button --> <!-- View recordings button -->

View File

@ -126,6 +126,7 @@ $ov-recording-blinking-color: #eb5144;
text-align: center; text-align: center;
line-height: 20px; line-height: 20px;
margin: auto; margin: auto;
cursor: pointer;
} }
.recording-tag { .recording-tag {

View File

@ -563,10 +563,33 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
} }
} }
/**
* @ignore
*/
openRecordingActivityPanel() {
if (this.showActivitiesPanelButton && !this.isActivitiesOpened) {
this.panelService.togglePanel(PanelType.ACTIVITIES, 'recording');
}
}
/**
* @ignore
*/
openBroadcastingActivityPanel() {
if (this.showActivitiesPanelButton && !this.isActivitiesOpened) {
this.panelService.togglePanel(PanelType.ACTIVITIES, 'broadcasting');
}
}
/** /**
* @ignore * @ignore
*/ */
toggleRecording() { toggleRecording() {
if (this.recordingStatus === RecordingStatus.FAILED) {
this.openRecordingActivityPanel();
return;
}
const payload: RecordingStartRequestedEvent = { const payload: RecordingStartRequestedEvent = {
roomName: this.openviduService.getRoomName() roomName: this.openviduService.getRoomName()
}; };
@ -576,9 +599,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
this.onRecordingStopRequested.emit(payload); this.onRecordingStopRequested.emit(payload);
} else if (this.recordingStatus === RecordingStatus.STOPPED) { } else if (this.recordingStatus === RecordingStatus.STOPPED) {
this.onRecordingStartRequested.emit(payload); this.onRecordingStartRequested.emit(payload);
if (this.showActivitiesPanelButton && !this.isActivitiesOpened) { this.openRecordingActivityPanel();
this.toggleActivitiesPanel('recording');
}
} }
} }
@ -595,9 +616,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
this.onBroadcastingStopRequested.emit(payload); this.onBroadcastingStopRequested.emit(payload);
this.broadcastingService.setBroadcastingStopped(); this.broadcastingService.setBroadcastingStopped();
} else if (this.broadcastingStatus === BroadcastingStatus.STOPPED) { } else if (this.broadcastingStatus === BroadcastingStatus.STOPPED) {
if (this.showActivitiesPanelButton && !this.isActivitiesOpened) { this.openBroadcastingActivityPanel();
this.toggleActivitiesPanel('broadcasting');
}
} }
} }
@ -650,7 +669,11 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
this.documentService.toggleFullscreen('session-container'); this.documentService.toggleFullscreen('session-container');
} }
private toggleActivitiesPanel(expandPanel: string) { /**
* @internal
* @param expandPanel
*/
toggleActivitiesPanel(expandPanel: string) {
this.panelService.togglePanel(PanelType.ACTIVITIES, expandPanel); this.panelService.togglePanel(PanelType.ACTIVITIES, expandPanel);
} }

View File

@ -132,7 +132,8 @@
"RECORDINGS": "录制", "RECORDINGS": "录制",
"NO_MODERATOR": "只有主持人可以开始录音", "NO_MODERATOR": "只有主持人可以开始录音",
"NO_TRACKS_PUBLISHED": "请分享音频或视频以开始录制。", "NO_TRACKS_PUBLISHED": "请分享音频或视频以开始录制。",
"NO_RECORDINGS_AVAILABLE": "目前没有可用的录音" "NO_RECORDINGS_AVAILABLE": "目前没有可用的录音",
"ERROR_STARTING": "开始录音时出错"
}, },
"STREAMING": { "STREAMING": {
"TITLE": "直播", "TITLE": "直播",

View File

@ -126,7 +126,8 @@
"DOWNLOAD": "Download", "DOWNLOAD": "Download",
"RECORDINGS": "AUFZEICHNUNGEN", "RECORDINGS": "AUFZEICHNUNGEN",
"NO_MODERATOR": "Nur der MODERATOR kann die Aufzeichnung starten", "NO_MODERATOR": "Nur der MODERATOR kann die Aufzeichnung starten",
"NO_TRACKS_PUBLISHED": "Teile Audio oder Video, um mit der Aufnahme zu beginnen." "NO_TRACKS_PUBLISHED": "Teile Audio oder Video, um mit der Aufnahme zu beginnen.",
"ERROR_STARTING": "Fehler beim Starten der Aufnahme"
}, },
"STREAMING": { "STREAMING": {
"TITLE": "Streaming", "TITLE": "Streaming",

View File

@ -136,7 +136,8 @@
"NO_MODERATOR": "Only the MODERATOR can start the recording", "NO_MODERATOR": "Only the MODERATOR can start the recording",
"NO_TRACKS_PUBLISHED": "Share audio or video to start recording.", "NO_TRACKS_PUBLISHED": "Share audio or video to start recording.",
"NO_RECORDINGS_AVAILABLE": "No recordings available at this time", "NO_RECORDINGS_AVAILABLE": "No recordings available at this time",
"BROWSE_RECORDINGS": "Browse saved recordings" "BROWSE_RECORDINGS": "Browse saved recordings",
"ERROR_STARTING": "Error starting recording"
}, },
"STREAMING": { "STREAMING": {
"TITLE": "Streaming", "TITLE": "Streaming",

View File

@ -132,7 +132,8 @@
"RECORDINGS": "GRABACIONES", "RECORDINGS": "GRABACIONES",
"NO_MODERATOR": "Sólo el MODERADOR puede iniciar la grabación", "NO_MODERATOR": "Sólo el MODERADOR puede iniciar la grabación",
"NO_TRACKS_PUBLISHED": "Comparte audio o video para poder empezar a grabar.", "NO_TRACKS_PUBLISHED": "Comparte audio o video para poder empezar a grabar.",
"NO_RECORDINGS_AVAILABLE": "No hay grabaciones disponibles en este momento" "NO_RECORDINGS_AVAILABLE": "No hay grabaciones disponibles en este momento",
"ERROR_STARTING": "Error iniciando la grabación"
}, },
"STREAMING": { "STREAMING": {
"TITLE": "Streaming", "TITLE": "Streaming",

View File

@ -132,7 +132,8 @@
"RECORDINGS": "ENREGISTREMENTS", "RECORDINGS": "ENREGISTREMENTS",
"NO_MODERATOR": "Seul le MODERATEUR peut lancer l'enregistrement", "NO_MODERATOR": "Seul le MODERATEUR peut lancer l'enregistrement",
"NO_TRACKS_PUBLISHED": "Partagez de laudio ou de la vidéo pour commencer lenregistrement.", "NO_TRACKS_PUBLISHED": "Partagez de laudio ou de la vidéo pour commencer lenregistrement.",
"NO_RECORDINGS_AVAILABLE": "Aucun enregistrement disponible pour le moment" "NO_RECORDINGS_AVAILABLE": "Aucun enregistrement disponible pour le moment",
"ERROR_STARTING": "Erreur de démarrage"
}, },
"STREAMING": { "STREAMING": {
"TITLE": "Streaming", "TITLE": "Streaming",

View File

@ -132,7 +132,8 @@
"RECORDINGS": "रिकॉर्डिंग", "RECORDINGS": "रिकॉर्डिंग",
"NO_MODERATOR": "केवल मॉडरेटर ही रिकॉर्डिंग शुरू कर सकता है", "NO_MODERATOR": "केवल मॉडरेटर ही रिकॉर्डिंग शुरू कर सकता है",
"NO_TRACKS_PUBLISHED": "रिकॉर्डिंग शुरू करने के लिए ऑडियो या वीडियो साझा करें।", "NO_TRACKS_PUBLISHED": "रिकॉर्डिंग शुरू करने के लिए ऑडियो या वीडियो साझा करें।",
"NO_RECORDINGS_AVAILABLE": "इस समय कोई रिकॉर्डिंग उपलब्ध नहीं है" "NO_RECORDINGS_AVAILABLE": "इस समय कोई रिकॉर्डिंग उपलब्ध नहीं है",
"ERROR_STARTING": "रिकॉर्डिंग शुरू करने में त्रुटि"
}, },
"STREAMING": { "STREAMING": {
"TITLE": "स्ट्रीमिंग", "TITLE": "स्ट्रीमिंग",

View File

@ -132,7 +132,8 @@
"RECORDINGS": "REGISTRAZIONI", "RECORDINGS": "REGISTRAZIONI",
"NO_MODERATOR": "Solo il MODERATORE può avviare la registrazione", "NO_MODERATOR": "Solo il MODERATORE può avviare la registrazione",
"NO_TRACKS_PUBLISHED": "Condividi audio o video per iniziare la registrazione.", "NO_TRACKS_PUBLISHED": "Condividi audio o video per iniziare la registrazione.",
"NO_RECORDINGS_AVAILABLE": "Nessuna registrazione disponibile al momento" "NO_RECORDINGS_AVAILABLE": "Nessuna registrazione disponibile al momento",
"ERROR_STARTING": "Errore di avvio"
}, },
"STREAMING": { "STREAMING": {
"TITLE": "Streaming", "TITLE": "Streaming",

View File

@ -132,7 +132,8 @@
"RECORDINGS": "録画", "RECORDINGS": "録画",
"NO_MODERATOR": "録画を開始できるのは、モデレーターのみです", "NO_MODERATOR": "録画を開始できるのは、モデレーターのみです",
"NO_TRACKS_PUBLISHED": "録音を開始するには、音声または動画を共有してください。", "NO_TRACKS_PUBLISHED": "録音を開始するには、音声または動画を共有してください。",
"NO_RECORDINGS_AVAILABLE": "現在利用可能な録画はありません" "NO_RECORDINGS_AVAILABLE": "現在利用可能な録画はありません",
"ERROR_STARTING": "録画開始エラー"
}, },
"STREAMING": { "STREAMING": {
"TITLE": "ストリーミング", "TITLE": "ストリーミング",

View File

@ -132,7 +132,8 @@
"RECORDINGS": "OPNAME", "RECORDINGS": "OPNAME",
"NO_MODERATOR": "Alleen de MOEDERATOR kan de opname starten", "NO_MODERATOR": "Alleen de MOEDERATOR kan de opname starten",
"NO_TRACKS_PUBLISHED": "Deel audio of video om met opnemen te beginnen.", "NO_TRACKS_PUBLISHED": "Deel audio of video om met opnemen te beginnen.",
"NO_RECORDINGS_AVAILABLE": "Momenteel zijn er geen opnames beschikbaar" "NO_RECORDINGS_AVAILABLE": "Momenteel zijn er geen opnames beschikbaar",
"ERROR_STARTING": "Fout bij starten opname"
}, },
"STREAMING": { "STREAMING": {
"TITLE": "Streaming", "TITLE": "Streaming",

View File

@ -132,7 +132,8 @@
"RECORDINGS": "GRAVAÇÕES", "RECORDINGS": "GRAVAÇÕES",
"NO_MODERATOR": "Só o MODERADOR pode iniciar a gravação", "NO_MODERATOR": "Só o MODERADOR pode iniciar a gravação",
"NO_TRACKS_PUBLISHED": "Compartilhe áudio ou vídeo para começar a gravar.", "NO_TRACKS_PUBLISHED": "Compartilhe áudio ou vídeo para começar a gravar.",
"NO_RECORDINGS_AVAILABLE": "Nenhuma gravação disponível no momento" "NO_RECORDINGS_AVAILABLE": "Nenhuma gravação disponível no momento",
"ERROR_STARTING": "Erro ao iniciar gravação"
}, },
"STREAMING": { "STREAMING": {
"TITLE": "Streaming", "TITLE": "Streaming",