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

View File

@ -105,20 +105,20 @@ export class MeetingComponent implements OnInit {
constructor( constructor(
protected route: ActivatedRoute, protected route: ActivatedRoute,
protected navigationService: NavigationService,
protected recordingService: RecordingService,
protected authService: AuthService,
protected roomService: RoomService, protected roomService: RoomService,
protected meetingService: MeetingService, protected meetingService: MeetingService,
protected openviduService: OpenViduService,
protected participantService: ParticipantService, protected participantService: ParticipantService,
protected componentParticipantService: ComponentParticipantService, protected recordingService: RecordingService,
protected appDataService: AppDataService,
protected wcManagerService: WebComponentManagerService,
protected sessionStorageService: SessionStorageService,
protected featureConfService: FeatureConfigurationService, protected featureConfService: FeatureConfigurationService,
protected clipboard: Clipboard, protected authService: AuthService,
protected notificationService: NotificationService 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; this.features = this.featureConfService.features;
} }
@ -256,7 +256,8 @@ export class MeetingComponent implements OnInit {
await this.addParticipantNameToUrl(); await this.addParticipantNameToUrl();
await this.roomService.loadRoomPreferences(this.roomId); await this.roomService.loadRoomPreferences(this.roomId);
this.showMeeting = true; this.showMeeting = true;
// Subscribe to remote participants updates for showing/hiding the share meeting link component
// Subscribe to remote participants updates
this.componentParticipantService.remoteParticipants$ this.componentParticipantService.remoteParticipants$
.pipe(takeUntil(this.destroy$)) .pipe(takeUntil(this.destroy$))
.subscribe((participants) => { .subscribe((participants) => {
@ -349,7 +350,7 @@ export class MeetingComponent implements OnInit {
}); });
this.localParticipant!.meetRole = newRole; 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) { } catch (error) {
console.error('Error refreshing participant token to update role:', error); console.error('Error refreshing participant token to update role:', error);
} }
@ -431,23 +432,41 @@ export class MeetingComponent implements OnInit {
} }
async endMeeting() { async endMeeting() {
if (this.participantService.isModeratorParticipant()) { if (!this.participantService.isModeratorParticipant()) return;
const roomId = this.roomService.getRoomId();
this.meetingEndedByMe = true; this.meetingEndedByMe = true;
await this.meetingService.endMeeting(roomId);
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) { async kickParticipant(participant: CustomParticipantModel) {
if (this.participantService.isModeratorParticipant()) { if (!this.participantService.isModeratorParticipant()) return;
try {
await this.meetingService.kickParticipant(this.roomId, participant.identity); 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) { async makeModerator(participant: CustomParticipantModel) {
if (this.participantService.isModeratorParticipant()) { if (!this.participantService.isModeratorParticipant()) return;
const newRole = ParticipantRole.MODERATOR;
await this.meetingService.changeParticipantRole(this.roomId, participant.identity, newRole); 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. * Kicks a participant from a meeting.
* *
* @param roomId - The unique identifier of the meeting room * @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 * @returns A promise that resolves when the participant has been kicked
*/ */
async kickParticipant(roomId: string, participantId: string): Promise<void> { async kickParticipant(roomId: string, participantIdentity: string): Promise<void> {
const path = `${this.MEETINGS_API}/${roomId}/participants/${participantId}`; const path = `${this.MEETINGS_API}/${roomId}/participants/${participantIdentity}`;
const headers = this.participantService.getParticipantRoleHeader(); const headers = this.participantService.getParticipantRoleHeader();
await this.httpService.deleteRequest(path, headers); 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. * Changes the role of a participant in a meeting.
* *
* @param roomId - The unique identifier of the meeting room * @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 * @param newRole - The new role to be assigned to the participant
*/ */
async changeParticipantRole(roomId: string, participantId: string, newRole: string): Promise<void> { async changeParticipantRole(roomId: string, participantIdentity: string, newRole: string): Promise<void> {
const path = `${this.MEETINGS_API}/${roomId}/participants/${participantId}`; const path = `${this.MEETINGS_API}/${roomId}/participants/${participantIdentity}`;
const headers = this.participantService.getParticipantRoleHeader(); const headers = this.participantService.getParticipantRoleHeader();
const body = { role: newRole }; const body = { role: newRole };
await this.httpService.patchRequest(path, body, headers); 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}'`);
} }
} }