openvidu-components: Refactored the video enlarged logic

pull/707/head
csantosm 2022-02-25 13:53:49 +01:00
parent 3318dfd207
commit 6057d1c11e
9 changed files with 69 additions and 70 deletions

View File

@ -2,7 +2,7 @@
<div <div
class="OT_root OT_publisher" class="OT_root OT_publisher"
*ngFor="let stream of localParticipant | streams" *ngFor="let stream of localParticipant | streams"
[ngClass]="{ OV_small: !stream.streamManager?.stream?.videoActive }" [ngClass]="{ OV_big: stream.videoEnlarged }"
> >
<ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: stream }"></ng-container> <ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: stream }"></ng-container>
</div> </div>
@ -11,7 +11,7 @@
*ngFor="let stream of remoteParticipants | streams" *ngFor="let stream of remoteParticipants | streams"
class="OT_root OT_publisher" class="OT_root OT_publisher"
id="remote-participant" id="remote-participant"
[ngClass]="{ OV_small: !stream.streamManager?.stream?.videoActive }" [ngClass]="{ OV_big: stream.videoEnlarged }"
> >
<ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: stream }"></ng-container> <ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: stream }"></ng-container>
</div> </div>

View File

@ -236,15 +236,13 @@ export class SessionComponent implements OnInit {
} }
private subscribeToStreamPropertyChange() { private subscribeToStreamPropertyChange() {
// this.session.on('streamPropertyChanged', (event: StreamPropertyChangedEvent) => { this.session.on('streamPropertyChanged', (event: StreamPropertyChangedEvent) => {
// const connectionId = event.stream.connection.connectionId; const connectionId = event.stream.connection.connectionId;
// const isRemoteConnection: boolean = !this.openviduService.isMyOwnConnection(connectionId); const isRemoteConnection: boolean = !this.openviduService.isMyOwnConnection(connectionId);
// if (isRemoteConnection) { if (isRemoteConnection) {
// if (event.changedProperty === 'videoActive') { this.participantService.updateRemoteParticipants();
// // this.participantService.updateUsers(); }
// } });
// }
// });
} }
private subscribeToNicknameChanged() { private subscribeToNicknameChanged() {

View File

@ -51,12 +51,8 @@ export class StreamComponent implements OnInit {
setTimeout(() => { setTimeout(() => {
if (streamContainer) { if (streamContainer) {
this._streamContainer = streamContainer; this._streamContainer = streamContainer;
if (this._stream.type === VideoType.SCREEN) {
this.toggleVideoEnlarged(true);
}
// Remove 'no-size' css class for showing the element in the view. // Remove 'no-size' css class for showing the element in the view.
// This is a workaround for fixing a layout bug which provide a bad UX with each new elements created. // This is a workaround for fixing a layout bug which provide a bad UX with each new elements created.
//
this.documentService.removeNoSizeElementClass(this._streamContainer.nativeElement); this.documentService.removeNoSizeElementClass(this._streamContainer.nativeElement);
} }
}, 0); }, 0);
@ -84,16 +80,7 @@ export class StreamComponent implements OnInit {
this.cdkSrv.setSelector('body'); this.cdkSrv.setSelector('body');
} }
toggleVideoEnlarged(resetAll?) { toggleVideoEnlarged() {
const element = this.documentService.getHTMLElementByClassName(this._streamContainer.nativeElement, LayoutClass.ROOT_ELEMENT);
if (!!resetAll) {
this.documentService.removeAllBigElementClass();
this.participantService.resetMyVideoEnlarged();
this.participantService.resetRemotesVideoEnlarged();
}
this.documentService.toggleBigElementClass(element);
if (!!this._stream.streamManager?.stream?.connection?.connectionId) { if (!!this._stream.streamManager?.stream?.connection?.connectionId) {
if (this.openviduService.isMyOwnConnection(this._stream.streamManager?.stream?.connection?.connectionId)) { if (this.openviduService.isMyOwnConnection(this._stream.streamManager?.stream?.connection?.connectionId)) {
this.participantService.toggleMyVideoEnlarged(this._stream.streamManager?.stream?.connection?.connectionId); this.participantService.toggleMyVideoEnlarged(this._stream.streamManager?.stream?.connection?.connectionId);

View File

@ -201,7 +201,7 @@ export class ToolbarComponent implements OnInit, OnDestroy {
this.toggleScreenShare(); this.toggleScreenShare();
}); });
this.log.d('ACCESS ALOWED screenPublisher'); this.log.d('ACCESS ALOWED screenPublisher');
this.participantService.enableScreenUser(screenPublisher); this.participantService.activeMyScreenShare(screenPublisher);
if (!this.openviduService.isScreenSessionConnected()) { if (!this.openviduService.isScreenSessionConnected()) {
await this.openviduService.connectSession( await this.openviduService.connectSession(

View File

@ -173,7 +173,7 @@ export class UserSettingsComponent implements OnInit, OnDestroy {
this.log.d('Clicked native stop button. Stopping screen sharing'); this.log.d('Clicked native stop button. Stopping screen sharing');
this.toggleScreenShare(); this.toggleScreenShare();
}); });
this.participantService.enableScreenUser(screenPublisher); this.participantService.activeMyScreenShare(screenPublisher);
if (!this.participantService.hasCameraVideoActive()) { if (!this.participantService.hasCameraVideoActive()) {
this.participantService.disableWebcamUser(); this.participantService.disableWebcamUser();
} }

View File

@ -1,4 +1,3 @@
import { THIS_EXPR } from '@angular/compiler/src/output/output_ast';
import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular/core'; import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular/core';
import { StreamManager } from 'openvidu-browser'; import { StreamManager } from 'openvidu-browser';
import { VideoType } from '../../models/video-type.model'; import { VideoType } from '../../models/video-type.model';

View File

@ -82,8 +82,10 @@ export abstract class ParticipantAbstractModel {
this.getScreenConnection().connectionId = connectionId; this.getScreenConnection().connectionId = connectionId;
} }
removeConnection(connectionId: string) { removeConnection(connectionId: string): StreamModel {
this.streams.delete(this.getConnectionById(connectionId).type); const removeStream = this.getConnectionById(connectionId);
this.streams.delete(removeStream.type);
return removeStream;
} }
hasConnectionId(connectionId: string): boolean { hasConnectionId(connectionId: string): boolean {
@ -164,10 +166,19 @@ export abstract class ParticipantAbstractModel {
const screenConnection = this.getScreenConnection(); const screenConnection = this.getScreenConnection();
if (screenConnection) screenConnection.connected = false; if (screenConnection) screenConnection.connected = false;
} }
setAllVideoEnlarged(enlarged: boolean) { setAllVideoEnlarged(enlarged: boolean) {
this.streams.forEach((conn) => (conn.videoEnlarged = enlarged)); this.streams.forEach((conn) => (conn.videoEnlarged = enlarged));
} }
setCameraEnlarged(enlarged: boolean) {
this.streams.get(VideoType.CAMERA).videoEnlarged = enlarged;
}
setScreenEnlarged(enlarged: boolean) {
this.streams.get(VideoType.SCREEN).videoEnlarged = enlarged;
}
toggleVideoEnlarged(connectionId: string) { toggleVideoEnlarged(connectionId: string) {
this.streams.forEach((conn) => { this.streams.forEach((conn) => {
if (conn.connectionId === connectionId) { if (conn.connectionId === connectionId) {

View File

@ -48,30 +48,10 @@ export class DocumentService {
} }
} }
removeAllBigElementClass() {
const elements: HTMLCollectionOf<Element> = document.getElementsByClassName(LayoutClass.BIG_ELEMENT);
while (elements.length > 0) {
this.removeBigElementClass(elements[0]);
}
}
removeNoSizeElementClass(element: HTMLElement | Element) { removeNoSizeElementClass(element: HTMLElement | Element) {
element?.classList.remove(LayoutClass.NO_SIZE_ELEMENT); element?.classList.remove(LayoutClass.NO_SIZE_ELEMENT);
} }
removeBigElementClass(element: HTMLElement | Element) {
element?.classList.remove(LayoutClass.BIG_ELEMENT);
}
toggleBigElementClass(element: HTMLElement | Element) {
if (element?.className.includes(LayoutClass.BIG_ELEMENT)) {
this.removeBigElementClass(element);
} else {
element.classList.add(LayoutClass.BIG_ELEMENT);
}
}
isSmallElement(element: HTMLElement | Element): boolean { isSmallElement(element: HTMLElement | Element): boolean {
return element?.className.includes(LayoutClass.SMALL_ELEMENT); return element?.className.includes(LayoutClass.SMALL_ELEMENT);
} }

View File

@ -78,7 +78,7 @@ export class ParticipantService {
this.updateLocalParticipant(); this.updateLocalParticipant();
} }
enableScreenUser(screenPublisher: Publisher) { activeMyScreenShare(screenPublisher: Publisher) {
this.log.d('Enabling screen publisher'); this.log.d('Enabling screen publisher');
const steramModel: StreamModel = { const steramModel: StreamModel = {
@ -91,6 +91,8 @@ export class ParticipantService {
connectionId: null connectionId: null
}; };
this.resetRemoteStreamsToNormalSize();
this.resetMyStreamsToNormalSize();
this.localParticipant.addConnection(steramModel); this.localParticipant.addConnection(steramModel);
this.updateLocalParticipant(); this.updateLocalParticipant();
} }
@ -121,14 +123,19 @@ export class ParticipantService {
return this.localParticipant.getScreenNickname(); return this.localParticipant.getScreenNickname();
} }
resetMyVideoEnlarged() {
this.localParticipant?.setAllVideoEnlarged(false);
}
toggleMyVideoEnlarged(connectionId: string) { toggleMyVideoEnlarged(connectionId: string) {
this.localParticipant.toggleVideoEnlarged(connectionId); this.localParticipant.toggleVideoEnlarged(connectionId);
} }
resetMyStreamsToNormalSize() {
if(this.localParticipant.someHasVideoEnlarged()){
this.localParticipant.setAllVideoEnlarged(false);
this.updateLocalParticipant();
}
}
clear() { clear() {
this.disableScreenUser(); this.disableScreenUser();
this.localParticipant = this.newParticipant(); this.localParticipant = this.newParticipant();
@ -186,10 +193,11 @@ export class ParticipantService {
addRemoteConnection(connectionId:string, data: string, subscriber: Subscriber) { addRemoteConnection(connectionId:string, data: string, subscriber: Subscriber) {
const steramModel: StreamModel = { const type: VideoType = this.getTypeConnectionData(data);
const streamModel: StreamModel = {
local: false, local: false,
type: this.getTypeConnectionData(data), type,
videoEnlarged: false, videoEnlarged: type === VideoType.SCREEN,
streamManager: subscriber, streamManager: subscriber,
nickname: this.getNicknameFromConnectionData(data), nickname: this.getNicknameFromConnectionData(data),
connected: true, connected: true,
@ -200,21 +208,28 @@ export class ParticipantService {
const participantAdded = this.getRemoteParticipantById(participantId); const participantAdded = this.getRemoteParticipantById(participantId);
if (!!participantAdded) { if (!!participantAdded) {
this.log.d('Adding connection to existing participant: ', participantId); this.log.d('Adding connection to existing participant: ', participantId);
if(participantAdded.hasConnectionType(steramModel.type)) { if(participantAdded.hasConnectionType(streamModel.type)) {
this.log.d('Participant has publisher, updating it'); this.log.d('Participant has publisher, updating it');
participantAdded.setPublisher(steramModel.type, subscriber); participantAdded.setPublisher(streamModel.type, subscriber);
} else { } else {
this.log.d('Participant has not publisher, adding it'); this.log.d('Participant has not publisher, adding it');
participantAdded.addConnection(steramModel); this.resetRemoteStreamsToNormalSize();
this.resetMyStreamsToNormalSize();
participantAdded.addConnection(streamModel);
} }
} else { } else {
this.log.d('Creating new participant with id: ', participantId); this.log.w('Creating new participant with id: ', participantId);
const remoteParticipant = this.newParticipant(steramModel, participantId); const remoteParticipant = this.newParticipant(streamModel, participantId);
this.remoteParticipants.push(remoteParticipant); this.remoteParticipants.push(remoteParticipant);
} }
this.updateRemoteParticipants(); this.updateRemoteParticipants();
} }
resetRemoteStreamsToNormalSize() {
this.remoteParticipants.forEach(participant => participant.setAllVideoEnlarged(false));
this.updateRemoteParticipants();
}
removeConnectionByConnectionId(connectionId: string) { removeConnectionByConnectionId(connectionId: string) {
this.log.w('Deleting connection: ', connectionId); this.log.w('Deleting connection: ', connectionId);
let participant = null; let participant = null;
@ -225,12 +240,24 @@ export class ParticipantService {
} }
if (participant) { if (participant) {
participant.removeConnection(connectionId); const removeStream: StreamModel = participant.removeConnection(connectionId);
//TODO: Timeout of X seconds?? Its possible sometimes the connections map was empty but must not be deleted //TODO: Timeout of X seconds?? Its possible sometimes the connections map was empty but must not be deleted
if (participant.streams.size === 0) { if (participant.streams.size === 0) {
// Remove participants without connections // Remove participants without connections
this.remoteParticipants = this.remoteParticipants.filter((p) => p !== participant); this.remoteParticipants = this.remoteParticipants.filter((p) => p !== participant);
} }
if(removeStream.type === VideoType.SCREEN){
const remoteScreens = this.remoteParticipants.filter(p => p.isScreenActive());
if(remoteScreens.length > 0){
// Enlarging the last screen connection active
const lastScreenActive = remoteScreens[remoteScreens.length -1];
lastScreenActive.setScreenEnlarged(true);
} else if(this.localParticipant.isScreenActive()) {
// Enlarging my screen if thereare not any remote screen active
this.localParticipant.setScreenEnlarged(true);
}
}
this.updateRemoteParticipants(); this.updateRemoteParticipants();
} }
} }
@ -250,10 +277,6 @@ export class ParticipantService {
p.toggleVideoEnlarged(connectionId); p.toggleVideoEnlarged(connectionId);
} }
resetRemotesVideoEnlarged() {
this.remoteParticipants.forEach((u) => u.setAllVideoEnlarged(false));
}
getNicknameFromConnectionData(data: string): string { getNicknameFromConnectionData(data: string): string {
try { try {
return JSON.parse(data).clientData; return JSON.parse(data).clientData;
@ -262,6 +285,10 @@ export class ParticipantService {
} }
} }
updateRemoteParticipants() {
this._remoteParticipants.next(this.remoteParticipants);
}
protected getTypeConnectionData(data: string): VideoType { protected getTypeConnectionData(data: string): VideoType {
try { try {
return JSON.parse(data).type; return JSON.parse(data).type;
@ -278,9 +305,6 @@ export class ParticipantService {
} }
} }
updateRemoteParticipants() {
this._remoteParticipants.next(this.remoteParticipants);
}
protected newParticipant(streamModel?: StreamModel, participantId?: string) { protected newParticipant(streamModel?: StreamModel, participantId?: string) {
if(this.openviduAngularConfigSrv.hasParticipantFactory()){ if(this.openviduAngularConfigSrv.hasParticipantFactory()){