frontend: enhance participant role management with original role tracking
This commit is contained in:
parent
a636ad485f
commit
f1fc2e0ba4
@ -3,22 +3,37 @@ import { ParticipantModel, ParticipantProperties } from 'openvidu-components-ang
|
||||
|
||||
// Represents a participant in the application.
|
||||
export class CustomParticipantModel extends ParticipantModel {
|
||||
// Indicates the role of the participant.
|
||||
// Indicates the original role of the participant.
|
||||
private _meetOriginalRole: ParticipantRole;
|
||||
// Indicates the current role of the participant.
|
||||
private _meetRole: ParticipantRole;
|
||||
|
||||
constructor(props: ParticipantProperties) {
|
||||
super(props);
|
||||
const participant = props.participant;
|
||||
this._meetRole = extractParticipantRole(participant.metadata);
|
||||
this._meetOriginalRole = extractParticipantRole(participant.metadata);
|
||||
this._meetRole = this._meetOriginalRole;
|
||||
}
|
||||
|
||||
set meetRole(role: ParticipantRole) {
|
||||
this._meetRole = role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current role of the participant is moderator.
|
||||
* @returns True if the current role is moderator, false otherwise.
|
||||
*/
|
||||
isModerator(): boolean {
|
||||
return this._meetRole === ParticipantRole.MODERATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the original role of the participant is moderator.
|
||||
* @returns True if the original role is moderator, false otherwise.
|
||||
*/
|
||||
isOriginalModerator(): boolean {
|
||||
return this._meetOriginalRole === ParticipantRole.MODERATOR;
|
||||
}
|
||||
}
|
||||
|
||||
const extractParticipantRole = (metadata: any): ParticipantRole => {
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
@if (showMeeting) {
|
||||
<ov-videoconference
|
||||
[token]="participantToken"
|
||||
|
||||
[prejoin]="true"
|
||||
[prejoinDisplayParticipantName]="false"
|
||||
[videoEnabled]="features().videoEnabled"
|
||||
@ -39,9 +38,9 @@
|
||||
(onRecordingStopRequested)="onRecordingStopRequested($event)"
|
||||
(onViewRecordingsClicked)="onViewRecordingsClicked()"
|
||||
>
|
||||
@if (features().canModerateRoom) {
|
||||
<div *ovToolbarAdditionalButtons>
|
||||
<!-- Copy Link Button -->
|
||||
<ng-container *ovToolbarAdditionalButtons>
|
||||
<!-- Copy Link Button -->
|
||||
@if (features().canModerateRoom) {
|
||||
<button
|
||||
id="copy-speaker-link"
|
||||
mat-icon-button
|
||||
@ -74,32 +73,34 @@
|
||||
<span>End meeting for all</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
}
|
||||
</ng-container>
|
||||
|
||||
<div *ovParticipantPanelAfterLocalParticipant>
|
||||
<ng-container *ovParticipantPanelAfterLocalParticipant>
|
||||
@if (features().canModerateRoom) {
|
||||
<div class="share-meeting-link-container">
|
||||
<ov-share-meeting-link
|
||||
[meetingUrl]="hostname + '/room/' + roomId"
|
||||
(copyClicked)="copySpeakerLink()"
|
||||
></ov-share-meeting-link>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ovLayoutAdditionalElements>
|
||||
@if (remoteParticipants.length === 0) {
|
||||
<div class="main-share-meeting-link-container fade-in-delayed-more">
|
||||
<ov-share-meeting-link
|
||||
[title]="'Start collaborating'"
|
||||
[subtitle]="'Share this link to bring others into the meeting'"
|
||||
[titleSize]="'xl'"
|
||||
[titleWeight]="'bold'"
|
||||
[meetingUrl]="hostname + '/room/' + roomId"
|
||||
(copyClicked)="copySpeakerLink()"
|
||||
></ov-share-meeting-link>
|
||||
</div>
|
||||
}
|
||||
</ng-container>
|
||||
}
|
||||
<ng-container *ovLayoutAdditionalElements>
|
||||
@if (features().canModerateRoom && remoteParticipants.length === 0) {
|
||||
<div class="main-share-meeting-link-container fade-in-delayed-more">
|
||||
<ov-share-meeting-link
|
||||
[title]="'Start collaborating'"
|
||||
[subtitle]="'Share this link to bring others into the meeting'"
|
||||
[titleSize]="'xl'"
|
||||
[titleWeight]="'bold'"
|
||||
[meetingUrl]="hostname + '/room/' + roomId"
|
||||
(copyClicked)="copySpeakerLink()"
|
||||
></ov-share-meeting-link>
|
||||
</div>
|
||||
}
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ovParticipantPanelItem="let participant">
|
||||
<!-- If Meet participant is moderator -->
|
||||
@ -130,25 +131,52 @@
|
||||
}
|
||||
<div *ovParticipantPanelItemElements>
|
||||
<!-- Button to make moderator if not -->
|
||||
@if (!participant.isModerator()) {
|
||||
@if (localParticipant!.isOriginalModerator()) {
|
||||
@if (participant.isModerator() && !participant.isOriginalModerator()) {
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="unmakeModerator(participant)"
|
||||
matTooltip="Remove participant moderator"
|
||||
class="remove-moderator-btn"
|
||||
>
|
||||
<mat-icon class="material-symbols-outlined">remove_moderator</mat-icon>
|
||||
</button>
|
||||
} @else {
|
||||
@if (!participant.isModerator()) {
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="makeModerator(participant)"
|
||||
matTooltip="Make participant moderator"
|
||||
class="make-moderator-btn"
|
||||
>
|
||||
<mat-icon class="material-symbols-outlined">add_moderator</mat-icon>
|
||||
</button>
|
||||
}
|
||||
}
|
||||
} @else {
|
||||
@if (!participant.isModerator()) {
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="makeModerator(participant)"
|
||||
matTooltip="Make participant moderator"
|
||||
class="make-moderator-btn"
|
||||
>
|
||||
<mat-icon class="material-symbols-outlined">add_moderator</mat-icon>
|
||||
</button>
|
||||
}
|
||||
}
|
||||
|
||||
<!-- Button to kick participant -->
|
||||
@if (!participant.isOriginalModerator()) {
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="makeModerator(participant)"
|
||||
matTooltip="Make participant moderator"
|
||||
class="make-moderator-btn"
|
||||
(click)="kickParticipant(participant)"
|
||||
matTooltip="Kick participant"
|
||||
class="force-disconnect-btn"
|
||||
>
|
||||
<mat-icon class="material-symbols-outlined">add_moderator</mat-icon>
|
||||
<mat-icon>call_end</mat-icon>
|
||||
</button>
|
||||
}
|
||||
<!-- Button to kick participant -->
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="kickParticipant(participant)"
|
||||
matTooltip="Kick participant"
|
||||
class="force-disconnect-btn"
|
||||
>
|
||||
<mat-icon>call_end</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</ov-participant-panel-item>
|
||||
}
|
||||
@ -172,7 +200,7 @@
|
||||
</ng-container>
|
||||
</ov-videoconference>
|
||||
} @else {
|
||||
<!-- Move this logic to prejoin meeting page -->
|
||||
<!-- Move this logic to lobby meeting page -->
|
||||
<div class="ov-page-container">
|
||||
<div class="room-access-container fade-in">
|
||||
<!-- Header Section -->
|
||||
|
||||
@ -492,6 +492,10 @@ export class MeetingComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a participant as moderator.
|
||||
* @param participant The participant to make as moderator.
|
||||
*/
|
||||
async makeModerator(participant: CustomParticipantModel) {
|
||||
if (!this.participantService.isModeratorParticipant()) return;
|
||||
|
||||
@ -507,6 +511,25 @@ export class MeetingComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmakes a participant as moderator.
|
||||
* @param participant The participant to unmake as moderator.
|
||||
*/
|
||||
async unmakeModerator(participant: CustomParticipantModel) {
|
||||
if (!this.participantService.isModeratorParticipant()) return;
|
||||
|
||||
try {
|
||||
await this.meetingService.changeParticipantRole(
|
||||
this.roomId,
|
||||
participant.identity,
|
||||
ParticipantRole.SPEAKER
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Error unmaking participant moderator:', error);
|
||||
this.notificationService.showSnackbar('Failed to unmake participant moderator');
|
||||
}
|
||||
}
|
||||
|
||||
async copyModeratorLink() {
|
||||
this.clipboard.copy(this.room!.moderatorRoomUrl);
|
||||
this.notificationService.showSnackbar('Moderator link copied to clipboard');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user