clean up stable projectorelements, if they have an error
This commit is contained in:
parent
c140399fa7
commit
43f084438d
@ -1,5 +1,5 @@
|
|||||||
import { TestBed, inject } from '@angular/core/testing';
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
import { E2EImportsModule } from '../../../../e2e-imports.module';
|
import { E2EImportsModule } from '../../../e2e-imports.module';
|
||||||
import { ProjectorDataService } from './projector-data.service';
|
import { ProjectorDataService } from './projector-data.service';
|
||||||
|
|
||||||
describe('ProjectorDataService', () => {
|
describe('ProjectorDataService', () => {
|
@ -1,9 +1,11 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { WebsocketService } from 'app/core/core-services/websocket.service';
|
|
||||||
import { Observable, BehaviorSubject } from 'rxjs';
|
|
||||||
import { ProjectorElement } from 'app/shared/models/core/projector';
|
|
||||||
|
|
||||||
export interface SlideData<T = object> {
|
import { Observable, BehaviorSubject } from 'rxjs';
|
||||||
|
|
||||||
|
import { WebsocketService } from 'app/core/core-services/websocket.service';
|
||||||
|
import { ProjectorElement, Projector } from 'app/shared/models/core/projector';
|
||||||
|
|
||||||
|
export interface SlideData<T = { error?: string }> {
|
||||||
data: T;
|
data: T;
|
||||||
element: ProjectorElement;
|
element: ProjectorElement;
|
||||||
error?: string;
|
error?: string;
|
||||||
@ -40,21 +42,16 @@ export class ProjectorDataService {
|
|||||||
* @param websocketService
|
* @param websocketService
|
||||||
*/
|
*/
|
||||||
public constructor(private websocketService: WebsocketService) {
|
public constructor(private websocketService: WebsocketService) {
|
||||||
// TODO: On reconnect, we do need to re-inform the server about all needed projectors. This also
|
|
||||||
// updates our projector data, which is great!
|
|
||||||
this.websocketService.getOberservable('projector').subscribe((update: AllProjectorData) => {
|
this.websocketService.getOberservable('projector').subscribe((update: AllProjectorData) => {
|
||||||
Object.keys(update).forEach(_id => {
|
Object.keys(update).forEach(_id => {
|
||||||
const id = parseInt(_id, 10);
|
const id = parseInt(_id, 10);
|
||||||
if ((<{ error: string }>update[id]).error !== undefined) {
|
if (this.currentProjectorData[id]) {
|
||||||
console.log(update, update[_id]);
|
this.currentProjectorData[id].next(update[id] as ProjectorData);
|
||||||
console.log('TODO: Why does the server sends errors on autoupdates?');
|
|
||||||
} else {
|
|
||||||
if (this.currentProjectorData[id]) {
|
|
||||||
this.currentProjectorData[id].next(update[id] as ProjectorData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.websocketService.reconnectEvent.subscribe(() => this.updateProjectorDataSubscription());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -105,4 +102,15 @@ export class ProjectorDataService {
|
|||||||
.filter(id => this.openProjectorInstances[id] > 0);
|
.filter(id => this.openProjectorInstances[id] > 0);
|
||||||
this.websocketService.send('listenToProjectors', { projector_ids: allActiveProjectorIds });
|
this.websocketService.send('listenToProjectors', { projector_ids: allActiveProjectorIds });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns the available projectior data for the given projector. Note that the data
|
||||||
|
* might not be there, if there is no subscribtion for this projector. But the
|
||||||
|
* data, if exist, is always the current data.
|
||||||
|
*/
|
||||||
|
public getAvailableProjectorData(projector: Projector): ProjectorData | null {
|
||||||
|
if (this.currentProjectorData[projector.id]) {
|
||||||
|
return this.currentProjectorData[projector.id].getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Projectable,
|
Projectable,
|
||||||
ProjectorElementBuildDeskriptor,
|
ProjectorElementBuildDeskriptor,
|
||||||
@ -11,15 +13,16 @@ import {
|
|||||||
Projector,
|
Projector,
|
||||||
ProjectorElement,
|
ProjectorElement,
|
||||||
ProjectorElements,
|
ProjectorElements,
|
||||||
IdentifiableProjectorElement
|
IdentifiableProjectorElement,
|
||||||
|
elementIdentifies
|
||||||
} from 'app/shared/models/core/projector';
|
} from 'app/shared/models/core/projector';
|
||||||
import { HttpService } from './http.service';
|
import { HttpService } from './http.service';
|
||||||
import { SlideManager } from 'app/slides/services/slide-manager.service';
|
import { SlideManager } from 'app/slides/services/slide-manager.service';
|
||||||
import { BaseModel } from 'app/shared/models/base/base-model';
|
import { BaseModel } from 'app/shared/models/base/base-model';
|
||||||
import { ViewModelStoreService } from './view-model-store.service';
|
import { ViewModelStoreService } from './view-model-store.service';
|
||||||
import { BaseProjectableViewModel } from 'app/site/base/base-projectable-view-model';
|
import { BaseProjectableViewModel } from 'app/site/base/base-projectable-view-model';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
import { ConfigService } from '../ui-services/config.service';
|
import { ConfigService } from '../ui-services/config.service';
|
||||||
|
import { ProjectorDataService } from './projector-data.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This service cares about Projectables being projected and manage all projection-related
|
* This service cares about Projectables being projected and manage all projection-related
|
||||||
@ -43,7 +46,8 @@ export class ProjectorService {
|
|||||||
private slideManager: SlideManager,
|
private slideManager: SlideManager,
|
||||||
private viewModelStore: ViewModelStoreService,
|
private viewModelStore: ViewModelStoreService,
|
||||||
private translate: TranslateService,
|
private translate: TranslateService,
|
||||||
private configService: ConfigService
|
private configService: ConfigService,
|
||||||
|
private projectorDataService: ProjectorDataService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -201,7 +205,7 @@ export class ProjectorService {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const requestData: any = {};
|
const requestData: any = {};
|
||||||
if (elements) {
|
if (elements) {
|
||||||
requestData.elements = elements;
|
requestData.elements = this.cleanupElements(projector, elements);
|
||||||
}
|
}
|
||||||
if (preview) {
|
if (preview) {
|
||||||
requestData.preview = preview;
|
requestData.preview = preview;
|
||||||
@ -218,6 +222,31 @@ export class ProjectorService {
|
|||||||
await this.http.post(`/rest/core/projector/${projector.id}/project/`, requestData);
|
await this.http.post(`/rest/core/projector/${projector.id}/project/`, requestData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans up stable elements with errors from the projector
|
||||||
|
*
|
||||||
|
* @param projector The projector
|
||||||
|
* @param elements The elements to clean up
|
||||||
|
* @reutns the cleaned up elements.
|
||||||
|
*/
|
||||||
|
private cleanupElements(projector: Projector, elements: ProjectorElements): ProjectorElements {
|
||||||
|
const projectorData = this.projectorDataService.getAvailableProjectorData(projector);
|
||||||
|
|
||||||
|
if (projectorData) {
|
||||||
|
projectorData.forEach(entry => {
|
||||||
|
if (entry.data.error && entry.element.stable) {
|
||||||
|
// Remove this element
|
||||||
|
const idElementToRemove = this.slideManager.getIdentifialbeProjectorElement(entry.element);
|
||||||
|
elements = elements.filter(element => {
|
||||||
|
return !elementIdentifies(idElementToRemove, element);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a projectiondefault, we want to retrieve the projector, that is assigned
|
* Given a projectiondefault, we want to retrieve the projector, that is assigned
|
||||||
* to this default.
|
* to this default.
|
||||||
|
@ -8,7 +8,7 @@ import { BaseComponent } from 'app/base.component';
|
|||||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||||
import { ViewProjector } from 'app/site/projector/models/view-projector';
|
import { ViewProjector } from 'app/site/projector/models/view-projector';
|
||||||
import { Size } from 'app/site/projector/size';
|
import { Size } from 'app/site/projector/size';
|
||||||
import { SlideData, ProjectorDataService } from 'app/site/projector/services/projector-data.service';
|
import { SlideData, ProjectorDataService } from 'app/core/core-services/projector-data.service';
|
||||||
import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service';
|
import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,7 +5,7 @@ import { TranslateService } from '@ngx-translate/core';
|
|||||||
import { BaseComponent } from 'app/base.component';
|
import { BaseComponent } from 'app/base.component';
|
||||||
import { SlideManager } from 'app/slides/services/slide-manager.service';
|
import { SlideManager } from 'app/slides/services/slide-manager.service';
|
||||||
import { BaseSlideComponent } from 'app/slides/base-slide-component';
|
import { BaseSlideComponent } from 'app/slides/base-slide-component';
|
||||||
import { SlideData } from 'app/site/projector/services/projector-data.service';
|
import { SlideData } from 'app/core/core-services/projector-data.service';
|
||||||
import { ProjectorElement } from 'app/shared/models/core/projector';
|
import { ProjectorElement } from 'app/shared/models/core/projector';
|
||||||
import { ViewProjector } from 'app/site/projector/models/view-projector';
|
import { ViewProjector } from 'app/site/projector/models/view-projector';
|
||||||
|
|
||||||
|
@ -29,6 +29,19 @@ export interface IdentifiableProjectorElement extends ProjectorElement {
|
|||||||
getIdentifiers(): (keyof IdentifiableProjectorElement)[];
|
getIdentifiers(): (keyof IdentifiableProjectorElement)[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares an identifiable element to an element. Every identifier of `a` must match, if
|
||||||
|
* the attribute is given in the element `b`.
|
||||||
|
*
|
||||||
|
* @param a The identifiable element
|
||||||
|
* @param b The non-identifiable element
|
||||||
|
*/
|
||||||
|
export function elementIdentifies(a: IdentifiableProjectorElement, b: ProjectorElement): boolean {
|
||||||
|
return a.getIdentifiers().every(identifier => {
|
||||||
|
return !b[identifier] || b[identifier] === a[identifier];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Multiple elements.
|
* Multiple elements.
|
||||||
*/
|
*/
|
||||||
@ -128,14 +141,24 @@ export class Projector extends BaseModel<Projector> {
|
|||||||
let removedElements: ProjectorElements;
|
let removedElements: ProjectorElements;
|
||||||
let nonRemovedElements: ProjectorElements;
|
let nonRemovedElements: ProjectorElements;
|
||||||
[removedElements, nonRemovedElements] = this.partitionArray(this.elements, elementOnProjector => {
|
[removedElements, nonRemovedElements] = this.partitionArray(this.elements, elementOnProjector => {
|
||||||
return element.getIdentifiers().every(identifier => {
|
return elementIdentifies(element, elementOnProjector);
|
||||||
return !elementOnProjector[identifier] || elementOnProjector[identifier] === element[identifier];
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
this.elements = nonRemovedElements;
|
this.elements = nonRemovedElements;
|
||||||
return removedElements;
|
return removedElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces all elements with the given elements, if these elements can identify to the
|
||||||
|
* given one.
|
||||||
|
*
|
||||||
|
* @param element The element to replace
|
||||||
|
*/
|
||||||
|
public replaceElements(element: IdentifiableProjectorElement): void {
|
||||||
|
this.elements = this.elements.map(elementOnProjector =>
|
||||||
|
elementIdentifies(element, elementOnProjector) ? element : elementOnProjector
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splits up the array into two arrays. All elements with a true return value from the callback
|
* Splits up the array into two arrays. All elements with a true return value from the callback
|
||||||
* will be in the fist array, all others in the second one.
|
* will be in the fist array, all others in the second one.
|
||||||
|
@ -5,15 +5,11 @@ import { ProjectorRoutingModule } from './projector-routing.module';
|
|||||||
import { SharedModule } from '../../shared/shared.module';
|
import { SharedModule } from '../../shared/shared.module';
|
||||||
import { ProjectorListComponent } from './components/projector-list/projector-list.component';
|
import { ProjectorListComponent } from './components/projector-list/projector-list.component';
|
||||||
import { ProjectorDetailComponent } from './components/projector-detail/projector-detail.component';
|
import { ProjectorDetailComponent } from './components/projector-detail/projector-detail.component';
|
||||||
import { ClockSlideService } from './services/clock-slide.service';
|
|
||||||
import { ProjectorDataService } from './services/projector-data.service';
|
|
||||||
import { CurrentListOfSpeakersSlideService } from './services/current-list-of-of-speakers-slide.service';
|
|
||||||
import { CountdownListComponent } from './components/countdown-list/countdown-list.component';
|
import { CountdownListComponent } from './components/countdown-list/countdown-list.component';
|
||||||
import { ProjectorMessageListComponent } from './components/projector-message-list/projector-message-list.component';
|
import { ProjectorMessageListComponent } from './components/projector-message-list/projector-message-list.component';
|
||||||
import { CountdownControlsComponent } from './components/countdown-controls/countdown-controls.component';
|
import { CountdownControlsComponent } from './components/countdown-controls/countdown-controls.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
providers: [ClockSlideService, ProjectorDataService, CurrentListOfSpeakersSlideService],
|
|
||||||
imports: [CommonModule, ProjectorRoutingModule, SharedModule],
|
imports: [CommonModule, ProjectorRoutingModule, SharedModule],
|
||||||
declarations: [
|
declarations: [
|
||||||
ProjectorListComponent,
|
ProjectorListComponent,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Input } from '@angular/core';
|
import { Input } from '@angular/core';
|
||||||
import { SlideData } from 'app/site/projector/services/projector-data.service';
|
|
||||||
import { ViewProjector } from 'app/site/projector/models/view-projector';
|
import { ViewProjector } from 'app/site/projector/models/view-projector';
|
||||||
|
import { SlideData } from 'app/core/core-services/projector-data.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every slide has to extends this base class. It forces the slides
|
* Every slide has to extends this base class. It forces the slides
|
||||||
|
@ -8,7 +8,7 @@ import { DiffLinesInParagraph, DiffService, LineRange } from '../../../core/ui-s
|
|||||||
import { LinenumberingService } from '../../../core/ui-services/linenumbering.service';
|
import { LinenumberingService } from '../../../core/ui-services/linenumbering.service';
|
||||||
import { ViewUnifiedChange } from '../../../shared/models/motions/view-unified-change';
|
import { ViewUnifiedChange } from '../../../shared/models/motions/view-unified-change';
|
||||||
import { MotionSlideObjChangeReco } from './motion-slide-obj-change-reco';
|
import { MotionSlideObjChangeReco } from './motion-slide-obj-change-reco';
|
||||||
import { SlideData } from '../../../site/projector/services/projector-data.service';
|
import { SlideData } from '../../../core/core-services/projector-data.service';
|
||||||
import { MotionSlideObjAmendmentParagraph } from './motion-slide-obj-amendment-paragraph';
|
import { MotionSlideObjAmendmentParagraph } from './motion-slide-obj-amendment-paragraph';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
Loading…
Reference in New Issue
Block a user