import { animate, style, transition, trigger } from '@angular/animations'; import { HttpClient } from '@angular/common/http'; import { Component } from '@angular/core'; import { lastValueFrom } from 'rxjs'; import { DataPacket_Kind, DataPublishOptions, ParticipantService, RemoteParticipant, Room, RoomEvent, OpenViduAngularModule, ApiDirectiveModule, OpenViduAngularDirectiveModule } from 'openvidu-angular'; import { ParticipantAppModel } from './models/participant-app.model'; import { environment } from 'src/environments/environment'; import { MatIcon } from '@angular/material/icon'; import { MatIconButton } from '@angular/material/button'; enum DataTopicApp { HAND_TOGGLE = 'handToggle' } @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], animations: [ trigger('inOutHandAnimation', [ transition(':enter', [ style({ opacity: 0, transform: 'translateY(-100%)' }), animate('300ms ease-in-out', style({ opacity: 1, transform: 'translateY(0)' })) ]), transition(':leave', [ style({ opacity: 1, transform: 'translateY(0)' }), animate('300ms ease-in-out', style({ opacity: 0, transform: 'translateY(-100%)' })) ]) ]) ], standalone: true, imports: [OpenViduAngularModule, ApiDirectiveModule, OpenViduAngularDirectiveModule, MatIconButton, MatIcon] }) export class AppComponent { // The URL of the application server. APPLICATION_SERVER_URL = ''; LIVEKIT_URL = environment.livekitUrl; // The token used to connect to the OpenVidu session. token!: string; // Whether the local participant has raised their hand. hasHandRaised: boolean = false; // The name of the OpenVidu room. private roomName = 'openvidu-toggle-hand'; constructor(private httpClient: HttpClient, private participantService: ParticipantService) {} // Requests a token from the application server for the given participant name. async onTokenRequested(participantName: string) { const { token } = await this.getToken(this.roomName, participantName); this.token = token; } // Handles the reception of a remote hand-raising event. handleRemoteHand(room: Room) { // Subscribe to hand toggling events from other participants room.on(RoomEvent.DataReceived, (payload: Uint8Array, participant?: RemoteParticipant, _?: DataPacket_Kind, topic?: string) => { if (topic === DataTopicApp.HAND_TOGGLE) { const p = this.participantService.getRemoteParticipantBySid(participant.sid); if (p) { (p).toggleHandRaised(); } this.participantService.updateRemoteParticipants(); } }); } // Handles the local hand-raising event. async handleLocalHand() { // Get local participant with ParticipantService const participant = this.participantService.getLocalParticipant(); // Toggle the participant hand with the method we wil add in our ParticipantAppModel participant.toggleHandRaised(); // Refresh the local participant object for others component and services this.participantService.updateLocalParticipant(); // Send a signal with the new value to others participant using the openvidu-browser signal const strData = JSON.stringify({}); const data: Uint8Array = new TextEncoder().encode(strData); const options: DataPublishOptions = { topic: DataTopicApp.HAND_TOGGLE }; await this.participantService.publishData(data, options); } // Requests a token from the application server for the given room and participant names. getToken(roomName: string, participantName: string): Promise { try { return lastValueFrom(this.httpClient.post(this.APPLICATION_SERVER_URL + 'token', { roomName, participantName })); } catch (error: any) { if (error.status === 404) { throw { status: error.status, message: 'Cannot connect with backend. ' + error.url + ' not found' }; } throw error; } } }