mirror of https://github.com/OpenVidu/openvidu.git
openvidu-components: Changed impure pipe to pure to increased efficiency
- Updated the behaviour subject creating a new reference object - Made the streamTypesEnabled pipe to pure - Fixed update bug in participants panelpull/707/head
parent
7af7b96a2d
commit
5a41202935
|
@ -49,14 +49,13 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
|
|
||||||
protected subscribeToParticipants() {
|
protected subscribeToParticipants() {
|
||||||
this.localParticipantSubs = this.participantService.localParticipantObs.subscribe((p) => {
|
this.localParticipantSubs = this.participantService.localParticipantObs.subscribe((p) => {
|
||||||
// We need to update the object reference doing a deep copy for update the view
|
this.localParticipant = p;
|
||||||
this.localParticipant = Object.assign(Object.create(p), p)
|
|
||||||
this.layoutService.update();
|
this.layoutService.update();
|
||||||
this.cd.markForCheck();
|
this.cd.markForCheck();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.remoteParticipantsSubs = this.participantService.remoteParticipantsObs.subscribe((participants) => {
|
this.remoteParticipantsSubs = this.participantService.remoteParticipantsObs.subscribe((participants) => {
|
||||||
this.remoteParticipants = [...participants];
|
this.remoteParticipants = participants;
|
||||||
this.layoutService.update();
|
this.layoutService.update();
|
||||||
this.cd.markForCheck();
|
this.cd.markForCheck();
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
import { Component, Input } from '@angular/core';
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input } from '@angular/core';
|
||||||
import { ParticipantAbstractModel } from '../../../../models/participant.model';
|
import { ParticipantAbstractModel } from '../../../../models/participant.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ov-participant-panel-item',
|
selector: 'ov-participant-panel-item',
|
||||||
templateUrl: './participant-panel-item.component.html',
|
templateUrl: './participant-panel-item.component.html',
|
||||||
styleUrls: ['./participant-panel-item.component.css']
|
styleUrls: ['./participant-panel-item.component.css'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
|
|
||||||
})
|
})
|
||||||
export class ParticipantPanelItemComponent {
|
export class ParticipantPanelItemComponent {
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
set participant( p: ParticipantAbstractModel) {
|
set participant(p: ParticipantAbstractModel) {
|
||||||
this._participant = p;
|
this._participant = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
_participant: ParticipantAbstractModel;
|
_participant: ParticipantAbstractModel;
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.scrollable {
|
.scrollable {
|
||||||
|
height: calc(100% - 60px);
|
||||||
|
max-height: calc(100% - 60px);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,14 @@
|
||||||
|
|
||||||
<div class="scrollable">
|
<div class="scrollable">
|
||||||
|
|
||||||
<div class="local-participant-container">
|
<div class="local-participant-container" *ngIf="localParticipant">
|
||||||
<ng-container *ngTemplateOutlet="participantPanelItemTemplate; context: { $implicit: localParticipant }"></ng-container>
|
<ng-container *ngTemplateOutlet="participantPanelItemTemplate; context: { $implicit: localParticipant }"></ng-container>
|
||||||
<mat-divider *ngIf="true"></mat-divider>
|
<mat-divider *ngIf="true"></mat-divider>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="remote-participants-container" *ngIf="remoteParticipants.length > 0">
|
<div class="remote-participants-container" *ngIf="remoteParticipants.length > 0">
|
||||||
|
|
||||||
<div *ngFor="let participant of remoteParticipants; let lastItem = last">
|
<div *ngFor="let participant of this.remoteParticipants">
|
||||||
<ng-container *ngTemplateOutlet="participantPanelItemTemplate; context: { $implicit: participant }"></ng-container>
|
<ng-container *ngTemplateOutlet="participantPanelItemTemplate; context: { $implicit: participant }"></ng-container>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, OnInit, TemplateRef } from '@angular/core';
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, OnDestroy, OnInit, TemplateRef } from '@angular/core';
|
||||||
import { ParticipantAbstractModel, ParticipantModel } from '../../../../models/participant.model';
|
import { ParticipantAbstractModel } from '../../../../models/participant.model';
|
||||||
import { ParticipantService } from '../../../../services/participant/participant.service';
|
import { ParticipantService } from '../../../../services/participant/participant.service';
|
||||||
import { SidenavMenuService } from '../../../..//services/sidenav-menu/sidenav-menu.service';
|
import { SidenavMenuService } from '../../../..//services/sidenav-menu/sidenav-menu.service';
|
||||||
import { ParticipantPanelItemDirective } from '../../../../directives/openvidu-angular.directive';
|
import { ParticipantPanelItemDirective } from '../../../../directives/openvidu-angular.directive';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ov-participants-panel',
|
selector: 'ov-participants-panel',
|
||||||
|
@ -10,9 +11,12 @@ import { ParticipantPanelItemDirective } from '../../../../directives/openvidu-a
|
||||||
styleUrls: ['./participants-panel.component.css'],
|
styleUrls: ['./participants-panel.component.css'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class ParticipantsPanelComponent implements OnInit {
|
export class ParticipantsPanelComponent implements OnInit, OnDestroy {
|
||||||
localParticipant: any;
|
localParticipant: any;
|
||||||
remoteParticipants: ParticipantAbstractModel[] = [];
|
remoteParticipants: ParticipantAbstractModel[] = [];
|
||||||
|
|
||||||
|
private localParticipantSubs: Subscription;
|
||||||
|
private remoteParticipantsSubs: Subscription;
|
||||||
@ContentChild('participantPanelItem', { read: TemplateRef }) participantPanelItemTemplate: TemplateRef<any>;
|
@ContentChild('participantPanelItem', { read: TemplateRef }) participantPanelItemTemplate: TemplateRef<any>;
|
||||||
|
|
||||||
@ContentChild(ParticipantPanelItemDirective)
|
@ContentChild(ParticipantPanelItemDirective)
|
||||||
|
@ -28,22 +32,34 @@ export class ParticipantsPanelComponent implements OnInit {
|
||||||
protected participantService: ParticipantService,
|
protected participantService: ParticipantService,
|
||||||
protected menuService: SidenavMenuService,
|
protected menuService: SidenavMenuService,
|
||||||
private cd: ChangeDetectorRef
|
private cd: ChangeDetectorRef
|
||||||
) {}
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.participantService.localParticipantObs.subscribe((p: ParticipantModel) => {
|
|
||||||
|
this.localParticipantSubs = this.participantService.localParticipantObs.subscribe((p: ParticipantAbstractModel) => {
|
||||||
this.localParticipant = p;
|
this.localParticipant = p;
|
||||||
// Mark for re-rendering using an impure pipe 'streamsTypesEnabled'
|
// Mark for re-rendering using an impure pipe 'streamsTypesEnabled'
|
||||||
this.cd.markForCheck();
|
this.cd.markForCheck();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.participantService.remoteParticipantsObs.subscribe((p: ParticipantModel[]) => {
|
this.remoteParticipantsSubs = this.participantService.remoteParticipantsObs.subscribe((p: ParticipantAbstractModel[]) => {
|
||||||
this.remoteParticipants = p;
|
// Workaround which forc the objects references update
|
||||||
|
// After one entirely day trying to make it works, this is the only way
|
||||||
|
p.forEach((par, index) => {
|
||||||
|
this.remoteParticipants[index] = Object.create(par);
|
||||||
|
});
|
||||||
// Mark for re-rendering using an impure pipe 'streamsTypesEnabled'
|
// Mark for re-rendering using an impure pipe 'streamsTypesEnabled'
|
||||||
this.cd.markForCheck();
|
this.cd.markForCheck();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
if (this.localParticipantSubs) this.localParticipantSubs.unsubscribe();
|
||||||
|
if (this.remoteParticipantsSubs) this.remoteParticipantsSubs.unsubscribe;
|
||||||
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
this.menuService.closeMenu();
|
this.menuService.closeMenu();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ export abstract class ParticipantAbstractModel {
|
||||||
this.colorProfile = !!props.colorProfile ? props.colorProfile : `hsl(${Math.random()*360}, 100%, 80%)`;
|
this.colorProfile = !!props.colorProfile ? props.colorProfile : `hsl(${Math.random()*360}, 100%, 80%)`;
|
||||||
this.isMutedForcibly = typeof props.isMutedForcibly === 'boolean' ? props.isMutedForcibly : false;
|
this.isMutedForcibly = typeof props.isMutedForcibly === 'boolean' ? props.isMutedForcibly : false;
|
||||||
let streamModel: StreamModel = {
|
let streamModel: StreamModel = {
|
||||||
connected: true,
|
connected: model ? model.connected : true,
|
||||||
type: model ? model.type : VideoType.CAMERA,
|
type: model ? model.type : VideoType.CAMERA,
|
||||||
streamManager: model ? model.streamManager : null,
|
streamManager: model ? model.streamManager : null,
|
||||||
videoEnlarged: model ? model.videoEnlarged : false,
|
videoEnlarged: model ? model.videoEnlarged : false,
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
import { Pipe, PipeTransform } from '@angular/core';
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
import { StreamModel, ParticipantAbstractModel } from '../models/participant.model';
|
import { StreamModel, ParticipantAbstractModel } from '../models/participant.model';
|
||||||
|
|
||||||
@Pipe({ name: 'streams', pure: true })
|
@Pipe({ name: 'streams' })
|
||||||
export class ParticipantStreamsPipe implements PipeTransform {
|
export class ParticipantStreamsPipe implements PipeTransform {
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
transform(participants: ParticipantAbstractModel[] | ParticipantAbstractModel): StreamModel[] {
|
transform(participants: ParticipantAbstractModel[] | ParticipantAbstractModel): StreamModel[] {
|
||||||
let streams: StreamModel[] = [];
|
let streams: StreamModel[] = [];
|
||||||
console.log('STREAM PIPE')
|
if(participants && Object.keys(participants).length > 0){
|
||||||
debugger
|
|
||||||
if(Object.keys(participants).length > 0){
|
|
||||||
if (Array.isArray(participants)) {
|
if (Array.isArray(participants)) {
|
||||||
participants.forEach((p) => {
|
participants.forEach((p) => {
|
||||||
streams = streams.concat(p.getAvailableConnections());
|
streams = streams.concat(p.getAvailableConnections());
|
||||||
|
@ -23,11 +21,12 @@ export class ParticipantStreamsPipe implements PipeTransform {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Pipe({ name: 'streamTypesEnabled', pure: false })
|
@Pipe({ name: 'streamTypesEnabled' })
|
||||||
export class StreamTypesEnabledPipe implements PipeTransform {
|
export class StreamTypesEnabledPipe implements PipeTransform {
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
transform(participant: ParticipantAbstractModel): string {
|
transform(participant: ParticipantAbstractModel): string {
|
||||||
return `(${participant?.getConnectionTypesActive().toString().replace(',', ', ')})`;
|
const activeStreams = participant?.getConnectionTypesActive().toString();
|
||||||
|
return `(${activeStreams.replace(',', ', ')})`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,7 +174,7 @@ export class ParticipantService {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLocalParticipant() {
|
updateLocalParticipant() {
|
||||||
this._localParticipant.next(this.localParticipant);
|
this._localParticipant.next(Object.assign(Object.create(this.localParticipant),this.localParticipant));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -188,7 +188,7 @@ export class ParticipantService {
|
||||||
type,
|
type,
|
||||||
videoEnlarged: type === VideoType.SCREEN,
|
videoEnlarged: type === VideoType.SCREEN,
|
||||||
streamManager: subscriber,
|
streamManager: subscriber,
|
||||||
connected: true,
|
connected: true,
|
||||||
connectionId
|
connectionId
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ export class ParticipantService {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateRemoteParticipants() {
|
updateRemoteParticipants() {
|
||||||
this._remoteParticipants.next(this.remoteParticipants);
|
this._remoteParticipants.next([...this.remoteParticipants]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTypeConnectionData(data: string): VideoType {
|
protected getTypeConnectionData(data: string): VideoType {
|
||||||
|
|
Loading…
Reference in New Issue