frontend: update participant management methods and improve code clarity

This commit is contained in:
juancarmore 2025-08-13 20:55:29 +02:00
parent 02339b50b4
commit 29019f82ff
3 changed files with 55 additions and 38 deletions

View File

@ -42,7 +42,7 @@
>
@if (features().canModerateRoom) {
<div *ovToolbarAdditionalButtons>
<!-- Copy Links Button -->
<!-- Copy Link Button -->
<button
id="copy-speaker-link"
mat-icon-button
@ -80,7 +80,7 @@
<div *ovParticipantPanelAfterLocalParticipant>
<div class="share-meeting-link-container">
<ov-share-meeting-link
[meetingUrl]="hostname + '/' + roomId"
[meetingUrl]="hostname + '/room/' + roomId"
(copyClicked)="copySpeakerLink()"
></ov-share-meeting-link>
</div>
@ -94,7 +94,7 @@
[subtitle]="'Share this link to bring others into the meeting'"
[titleSize]="'xl'"
[titleWeight]="'bold'"
[meetingUrl]="hostname + '/' + roomId"
[meetingUrl]="hostname + '/room/' + roomId"
(copyClicked)="copySpeakerLink()"
></ov-share-meeting-link>
</div>
@ -119,7 +119,6 @@
</ov-participant-panel-item>
} @else {
<!-- Remote participant -->
<ov-participant-panel-item [participant]="participant">
@if (participant.isModerator()) {
<ng-container *ovParticipantPanelParticipantBadge>
@ -145,7 +144,7 @@
<!-- Button to kick participant -->
<button
mat-icon-button
(click)="forceDisconnectParticipant(participant)"
(click)="kickParticipant(participant)"
matTooltip="Kick participant"
class="force-disconnect-btn"
>
@ -155,9 +154,8 @@
</ov-participant-panel-item>
}
</div>
}
<!-- If I can't moderate the room -->
@else {
} @else {
<!-- If I can't moderate the room -->
<div class="participant-item-container">
<ov-participant-panel-item [participant]="participant">
@if (participant.isModerator()) {
@ -274,7 +272,7 @@
<!-- Room URL Badge -->
@if (features().canModerateRoom) {
<ov-share-meeting-link
[meetingUrl]="hostname + '/' + roomId"
[meetingUrl]="hostname + '/room/' + roomId"
(copyClicked)="copySpeakerLink()"
></ov-share-meeting-link>
}

View File

@ -105,20 +105,20 @@ export class MeetingComponent implements OnInit {
constructor(
protected route: ActivatedRoute,
protected navigationService: NavigationService,
protected recordingService: RecordingService,
protected authService: AuthService,
protected roomService: RoomService,
protected meetingService: MeetingService,
protected openviduService: OpenViduService,
protected participantService: ParticipantService,
protected componentParticipantService: ComponentParticipantService,
protected appDataService: AppDataService,
protected wcManagerService: WebComponentManagerService,
protected sessionStorageService: SessionStorageService,
protected recordingService: RecordingService,
protected featureConfService: FeatureConfigurationService,
protected clipboard: Clipboard,
protected notificationService: NotificationService
protected authService: AuthService,
protected appDataService: AppDataService,
protected sessionStorageService: SessionStorageService,
protected wcManagerService: WebComponentManagerService,
protected openviduService: OpenViduService,
protected componentParticipantService: ComponentParticipantService,
protected navigationService: NavigationService,
protected notificationService: NotificationService,
protected clipboard: Clipboard
) {
this.features = this.featureConfService.features;
}
@ -256,7 +256,8 @@ export class MeetingComponent implements OnInit {
await this.addParticipantNameToUrl();
await this.roomService.loadRoomPreferences(this.roomId);
this.showMeeting = true;
// Subscribe to remote participants updates for showing/hiding the share meeting link component
// Subscribe to remote participants updates
this.componentParticipantService.remoteParticipants$
.pipe(takeUntil(this.destroy$))
.subscribe((participants) => {
@ -349,7 +350,7 @@ export class MeetingComponent implements OnInit {
});
this.localParticipant!.meetRole = newRole;
this.notificationService.showSnackbar(`You have been assigned the role of ${newRole}.`);
this.notificationService.showSnackbar(`You have been assigned the role of ${newRole}`);
} catch (error) {
console.error('Error refreshing participant token to update role:', error);
}
@ -431,23 +432,41 @@ export class MeetingComponent implements OnInit {
}
async endMeeting() {
if (this.participantService.isModeratorParticipant()) {
const roomId = this.roomService.getRoomId();
this.meetingEndedByMe = true;
await this.meetingService.endMeeting(roomId);
if (!this.participantService.isModeratorParticipant()) return;
this.meetingEndedByMe = true;
try {
await this.meetingService.endMeeting(this.roomId);
} catch (error) {
console.error('Error ending meeting:', error);
this.notificationService.showSnackbar('Failed to end meeting');
}
}
async forceDisconnectParticipant(participant: CustomParticipantModel) {
if (this.participantService.isModeratorParticipant()) {
async kickParticipant(participant: CustomParticipantModel) {
if (!this.participantService.isModeratorParticipant()) return;
try {
await this.meetingService.kickParticipant(this.roomId, participant.identity);
} catch (error) {
console.error('Error kicking participant:', error);
this.notificationService.showSnackbar('Failed to kick participant');
}
}
async makeModerator(participant: CustomParticipantModel) {
if (this.participantService.isModeratorParticipant()) {
const newRole = ParticipantRole.MODERATOR;
await this.meetingService.changeParticipantRole(this.roomId, participant.identity, newRole);
if (!this.participantService.isModeratorParticipant()) return;
try {
await this.meetingService.changeParticipantRole(
this.roomId,
participant.identity,
ParticipantRole.MODERATOR
);
} catch (error) {
console.error('Error making participant moderator:', error);
this.notificationService.showSnackbar('Failed to make participant moderator');
}
}

View File

@ -34,28 +34,28 @@ export class MeetingService {
* Kicks a participant from a meeting.
*
* @param roomId - The unique identifier of the meeting room
* @param participantId - The unique identifier of the participant to be kicked
* @param participantIdentity - The identity of the participant to be kicked
* @returns A promise that resolves when the participant has been kicked
*/
async kickParticipant(roomId: string, participantId: string): Promise<void> {
const path = `${this.MEETINGS_API}/${roomId}/participants/${participantId}`;
async kickParticipant(roomId: string, participantIdentity: string): Promise<void> {
const path = `${this.MEETINGS_API}/${roomId}/participants/${participantIdentity}`;
const headers = this.participantService.getParticipantRoleHeader();
await this.httpService.deleteRequest(path, headers);
this.log.d(`Participant '${participantId}' kicked from room ${roomId}`);
this.log.d(`Participant '${participantIdentity}' kicked from room ${roomId}`);
}
/**
* Changes the role of a participant in a meeting.
*
* @param roomId - The unique identifier of the meeting room
* @param participantId - The unique identifier of the participant whose role is to be changed
* @param participantIdentity - The identity of the participant whose role is to be changed
* @param newRole - The new role to be assigned to the participant
*/
async changeParticipantRole(roomId: string, participantId: string, newRole: string): Promise<void> {
const path = `${this.MEETINGS_API}/${roomId}/participants/${participantId}`;
async changeParticipantRole(roomId: string, participantIdentity: string, newRole: string): Promise<void> {
const path = `${this.MEETINGS_API}/${roomId}/participants/${participantIdentity}`;
const headers = this.participantService.getParticipantRoleHeader();
const body = { role: newRole };
await this.httpService.patchRequest(path, body, headers);
this.log.d(`Changed role of participant '${participantId}' to '${newRole}' in room ${roomId}`);
this.log.d(`Changed role of participant '${participantIdentity}' to '${newRole}' in room '${roomId}'`);
}
}