114 lines
3.8 KiB
TypeScript
114 lines
3.8 KiB
TypeScript
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) {
|
|
(<ParticipantAppModel>p).toggleHandRaised();
|
|
}
|
|
this.participantService.updateRemoteParticipants();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Handles the local hand-raising event.
|
|
async handleLocalHand() {
|
|
// Get local participant with ParticipantService
|
|
const participant = <ParticipantAppModel>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<any> {
|
|
try {
|
|
return lastValueFrom(this.httpClient.post<any>(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;
|
|
}
|
|
}
|
|
}
|