diff --git a/frontend/projects/shared-meet-components/src/lib/models/custom-participant.model.ts b/frontend/projects/shared-meet-components/src/lib/models/custom-participant.model.ts index 1912ba8..4d7e49f 100644 --- a/frontend/projects/shared-meet-components/src/lib/models/custom-participant.model.ts +++ b/frontend/projects/shared-meet-components/src/lib/models/custom-participant.model.ts @@ -6,32 +6,29 @@ export class CustomParticipantModel extends ParticipantModel { // Indicates the role of the participant. private _meetRole: ParticipantRole; - // Creates a new instance of CustomParticipantModel. constructor(props: ParticipantProperties) { super(props); const participant = props.participant; this._meetRole = extractParticipantRole(participant.metadata); } - // Sets the role of the participant. set meetRole(role: ParticipantRole) { this._meetRole = role; } - // Checks if the participant is a moderator. - // Returns true if the participant's role is MODERATOR, otherwise false. isModerator(): boolean { return this._meetRole === ParticipantRole.MODERATOR; } } const extractParticipantRole = (metadata: any): ParticipantRole => { - let parsedMetadata: MeetTokenMetadata = metadata; + let parsedMetadata: MeetTokenMetadata | undefined; try { parsedMetadata = JSON.parse(metadata || '{}'); } catch (e) { console.warn('Failed to parse participant metadata:', e); } + if (!parsedMetadata || typeof parsedMetadata !== 'object') { return ParticipantRole.SPEAKER; } diff --git a/frontend/projects/shared-meet-components/src/lib/models/index.ts b/frontend/projects/shared-meet-components/src/lib/models/index.ts index e91df19..aca8052 100644 --- a/frontend/projects/shared-meet-components/src/lib/models/index.ts +++ b/frontend/projects/shared-meet-components/src/lib/models/index.ts @@ -1,6 +1,7 @@ export * from './app.model'; -export * from './auth.model'; +export * from './custom-participant.model'; export * from './navigation.model'; export * from './notification.model'; export * from './sidenav.model'; +export * from './token.model'; export * from './wizard.model'; diff --git a/frontend/projects/shared-meet-components/src/lib/models/auth.model.ts b/frontend/projects/shared-meet-components/src/lib/models/token.model.ts similarity index 100% rename from frontend/projects/shared-meet-components/src/lib/models/auth.model.ts rename to frontend/projects/shared-meet-components/src/lib/models/token.model.ts diff --git a/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts b/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts index 30d09ef..0c18674 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts +++ b/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts @@ -36,7 +36,11 @@ import { WebComponentEvent, WebComponentOutboundEventMessage } from '@lib/typings/ce'; -import { MeetParticipantRoleUpdatedPayload, MeetSignalType } from '@lib/typings/ce/event.model'; +import { + MeetParticipantRoleUpdatedPayload, + MeetRoomPreferencesUpdatedPayload, + MeetSignalType +} from '@lib/typings/ce/event.model'; import { ApiDirectiveModule, DataPacket_Kind, @@ -325,33 +329,34 @@ export class MeetingComponent implements OnInit { RoomEvent.DataReceived, (payload: Uint8Array, _participant?: RemoteParticipant, _kind?: DataPacket_Kind, topic?: string) => { const event = JSON.parse(new TextDecoder().decode(payload)); - if (topic === MeetSignalType.MEET_ROOM_PREFERENCES_UPDATED) { - const roomPreferences: MeetRoomPreferences = event.preferences; - this.featureConfService.setRoomPreferences(roomPreferences); - } else if (topic === MeetSignalType.MEET_PARTICIPANT_ROLE_UPDATED) { - const { participantName, newRole, secret } = event as MeetParticipantRoleUpdatedPayload; - if (participantName === this.localParticipant!.name) { + if (topic === MeetSignalType.MEET_ROOM_PREFERENCES_UPDATED) { + const { preferences } = event as MeetRoomPreferencesUpdatedPayload; + this.featureConfService.setRoomPreferences(preferences); + // TODO: Update local state with new room preferences + } else if (topic === MeetSignalType.MEET_PARTICIPANT_ROLE_UPDATED) { + const { participantIdentity, newRole, secret } = event as MeetParticipantRoleUpdatedPayload; + + if (participantIdentity === this.localParticipant!.name) { this.localParticipant!.meetRole = newRole; + // TODO: Request for new token with the new role } else { - const participant = this.remoteParticipants.find((p) => p.name === participantName); + const participant = this.remoteParticipants.find((p) => p.identity === participantIdentity); if (participant) { participant.meetRole = newRole; } } - - // !Request for new token with the new role } } ); } onParticipantConnected(event: ParticipantModel) { - const message: WebComponentOutboundEventMessage = { + const message: WebComponentOutboundEventMessage = { event: WebComponentEvent.JOINED, payload: { roomId: event.getProperties().room?.name || '', - participantName: event.name! + participantIdentity: event.identity } }; this.wcManagerService.sendMessageToParent(message); @@ -368,7 +373,7 @@ export class MeetingComponent implements OnInit { event: WebComponentEvent.LEFT, payload: { roomId: event.roomName, - participantName: event.participantName, + participantIdentity: event.participantName, reason: leftReason } }; diff --git a/frontend/projects/shared-meet-components/src/lib/services/participant-token.service.ts b/frontend/projects/shared-meet-components/src/lib/services/participant-token.service.ts index dfaced0..94eeb89 100644 --- a/frontend/projects/shared-meet-components/src/lib/services/participant-token.service.ts +++ b/frontend/projects/shared-meet-components/src/lib/services/participant-token.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { ParticipantTokenInfo } from '@lib/models'; import { FeatureConfigurationService, HttpService } from '@lib/services'; -import { ParticipantOptions, ParticipantPermissions, ParticipantRole } from '@lib/typings/ce'; +import { MeetTokenMetadata, ParticipantOptions, ParticipantPermissions, ParticipantRole } from '@lib/typings/ce'; import { getValidDecodedToken } from '@lib/utils'; import { LoggerService } from 'openvidu-components-angular'; @@ -70,15 +70,15 @@ export class ParticipantTokenService { protected updateParticipantTokenInfo(token: string): void { try { const decodedToken = getValidDecodedToken(token); - const roleAndPermissions = decodedToken.metadata.roles?.find( - (r: { role: ParticipantRole; permissions: ParticipantPermissions }) => r.role === this.participantRole - ); + const metadata = decodedToken.metadata as MeetTokenMetadata; + const role = metadata.selectedRole; + const permissions = metadata.roles.find((r) => r.role === role)!.permissions; this.currentTokenInfo = { token: token, - role: roleAndPermissions.role, + role: role, permissions: { livekit: decodedToken.video, - openvidu: roleAndPermissions.permissions + openvidu: permissions } }; this.participantRole = this.currentTokenInfo.role; diff --git a/frontend/src/app/app.config.ts b/frontend/src/app/app.config.ts index 3633583..ce9a8bf 100644 --- a/frontend/src/app/app.config.ts +++ b/frontend/src/app/app.config.ts @@ -5,9 +5,9 @@ import { provideAnimationsAsync } from '@angular/platform-browser/animations/asy import { provideRouter } from '@angular/router'; import { routes } from '@app/app.routes'; import { environment } from '@environment/environment'; -import { httpInterceptor } from '@lib/interceptors/index'; -import { CustomParticipantModel } from '@lib/models/custom-participant.model'; -import { ThemeService } from '@lib/services/theme.service'; +import { httpInterceptor } from '@lib/interceptors'; +import { CustomParticipantModel } from '@lib/models'; +import { ThemeService } from '@lib/services'; import { OpenViduComponentsConfig, OpenViduComponentsModule, ParticipantProperties } from 'openvidu-components-angular'; const ovComponentsconfig: OpenViduComponentsConfig = {