frontend: add handling for closed room state with appropriate error messaging and UI updates

This commit is contained in:
juancarmore 2025-08-30 13:35:11 +02:00
parent 089877959a
commit 88e7002cab
6 changed files with 41 additions and 5 deletions

View File

@ -32,6 +32,9 @@ export const validateRoomAccessGuard: CanActivateFn = async (
case 404:
// Room not found
return navigationService.redirectToErrorPage(ErrorReason.INVALID_ROOM);
case 409:
// Room is closed
return navigationService.redirectToErrorPage(ErrorReason.CLOSED_ROOM);
default:
return navigationService.redirectToErrorPage(ErrorReason.INTERNAL_ERROR);
}

View File

@ -1,4 +1,5 @@
export enum ErrorReason {
CLOSED_ROOM = 'closed-room',
MISSING_ROOM_SECRET = 'missing-room-secret',
MISSING_RECORDING_SECRET = 'missing-recording-secret',
INVALID_ROOM_SECRET = 'invalid-room-secret',

View File

@ -50,6 +50,10 @@ export class ErrorComponent implements OnInit {
*/
private mapReasonToNameAndMessage(reason: string): { title: string; message: string } {
const reasonMap: { [key in ErrorReason]: { title: string; message: string } } = {
[ErrorReason.CLOSED_ROOM]: {
title: 'Closed room',
message: 'The room you are trying to access is closed'
},
[ErrorReason.MISSING_ROOM_SECRET]: {
title: 'Missing secret',
message: 'You need to provide a secret to join the room as a moderator or speaker'

View File

@ -215,12 +215,16 @@
<!-- Action Cards Grid -->
<div class="action-cards-grid">
<!-- Join Room Card -->
<mat-card class="action-card primary-card fade-in">
<mat-card class="action-card primary-card fade-in" [ngClass]="{ 'room-closed-card': roomClosed }">
<mat-card-header class="card-header">
<mat-icon class="ov-room-icon card-icon">meeting_room</mat-icon>
<mat-icon class="ov-room-icon card-icon">{{ roomClosed ? 'lock' : 'meeting_room' }}</mat-icon>
<div class="card-title-group">
<mat-card-title>Join Meeting</mat-card-title>
<mat-card-subtitle>Enter the room and start connecting</mat-card-subtitle>
<mat-card-title>{{ roomClosed ? 'Room Closed' : 'Join Meeting' }}</mat-card-title>
<mat-card-subtitle>{{
roomClosed
? 'This room is currently closed and not accepting new participants'
: 'Enter the room and start connecting'
}}</mat-card-subtitle>
</div>
</mat-card-header>
@ -250,7 +254,7 @@
id="participant-name-submit"
type="submit"
class="join-button"
[disabled]="participantForm.invalid"
[disabled]="participantForm.invalid || roomClosed"
>
<span>Join Meeting</span>
</button>

View File

@ -133,6 +133,16 @@
background: linear-gradient(135deg, var(--ov-meet-surface-color) 0%, var(--ov-meet-color-primary-light) 180%);
color: var(--ov-meet-text-on-primary);
}
&.room-closed-card {
.card-header {
background: linear-gradient(135deg, var(--ov-meet-surface-color) 0%, var(--ov-meet-color-warning) 180%);
.mat-icon {
color: var(--ov-meet-color-warning) !important;
}
}
}
}
// Secondary Card - Recordings styling

View File

@ -1,4 +1,5 @@
import { Clipboard } from '@angular/cdk/clipboard';
import { CommonModule } from '@angular/common';
import { Component, OnInit, Signal } from '@angular/core';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatButtonModule, MatIconButton } from '@angular/material/button';
@ -31,6 +32,7 @@ import {
import {
LeftEventReason,
MeetRoom,
MeetRoomStatus,
ParticipantRole,
WebComponentEvent,
WebComponentOutboundEventMessage
@ -65,6 +67,7 @@ import { Subject, takeUntil } from 'rxjs';
imports: [
OpenViduComponentsUiModule,
ApiDirectiveModule,
CommonModule,
MatFormFieldModule,
MatInputModule,
FormsModule,
@ -87,6 +90,7 @@ export class MeetingComponent implements OnInit {
hasRecordings = false;
showRecordingCard = false;
roomClosed = false;
showBackButton = true;
backButtonText = 'Back';
@ -137,6 +141,7 @@ export class MeetingComponent implements OnInit {
this.roomId = this.roomService.getRoomId();
this.roomSecret = this.roomService.getRoomSecret();
this.room = await this.roomService.getRoom(this.roomId);
this.roomClosed = this.room.status === MeetRoomStatus.CLOSED;
await this.setBackButtonText();
await this.checkForRecordings();
@ -218,6 +223,11 @@ export class MeetingComponent implements OnInit {
if (participantName) {
this.participantForm.get('name')?.setValue(participantName);
}
// Disable the form if the room is closed
if (this.roomClosed) {
this.participantForm.disable();
}
}
async goToRecordings() {
@ -309,6 +319,10 @@ export class MeetingComponent implements OnInit {
// Room not found
await this.navigationService.redirectToErrorPage(ErrorReason.INVALID_ROOM, true);
break;
case 409:
// Room is closed
await this.navigationService.redirectToErrorPage(ErrorReason.CLOSED_ROOM, true);
break;
default:
await this.navigationService.redirectToErrorPage(ErrorReason.INTERNAL_ERROR, true);
}