Merge pull request #4221 from FinnStutzenstein/client-projector
projector cleanup
This commit is contained in:
commit
c00b1a8325
@ -39,41 +39,11 @@ export class ProjectorService extends OpenSlidesComponent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, if a given object is projected.
|
||||
* Retusn the identifiable projector element from the given types of slides/elements/descriptors
|
||||
*
|
||||
* @param obj The object in question
|
||||
* @returns true, if the object is projected on one projector.
|
||||
* @param obj Something related to IdentifiableProjectorElement
|
||||
* @returns the identifiable projector element from obj.
|
||||
*/
|
||||
public isProjected(obj: Projectable | ProjectorElementBuildDeskriptor): boolean {
|
||||
if (isProjectable(obj)) {
|
||||
return this.DS.getAll<Projector>('core/projector').some(projector => {
|
||||
return projector.isElementShown(obj.getSlide().getBasicProjectorElement());
|
||||
});
|
||||
} else {
|
||||
return this.DS.getAll<Projector>('core/projector').some(projector => {
|
||||
return projector.isElementShown(obj.getBasicProjectorElement());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all projectors where the object is prejected on.
|
||||
*
|
||||
* @param obj The object in question
|
||||
* @return All projectors, where this Object is projected on
|
||||
*/
|
||||
public getProjectorsWhichAreProjecting(obj: Projectable | ProjectorElementBuildDeskriptor): Projector[] {
|
||||
if (isProjectable(obj)) {
|
||||
return this.DS.getAll<Projector>('core/projector').filter(projector => {
|
||||
return projector.isElementShown(obj.getSlide().getBasicProjectorElement());
|
||||
});
|
||||
} else {
|
||||
return this.DS.getAll<Projector>('core/projector').filter(projector => {
|
||||
return projector.isElementShown(obj.getBasicProjectorElement());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private getProjectorElement(
|
||||
obj: Projectable | ProjectorElementBuildDeskriptor | IdentifiableProjectorElement
|
||||
): IdentifiableProjectorElement {
|
||||
@ -86,6 +56,34 @@ export class ProjectorService extends OpenSlidesComponent {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, if a given object is projected.
|
||||
*
|
||||
* @param obj The object in question
|
||||
* @returns true, if the object is projected on one projector.
|
||||
*/
|
||||
public isProjected(obj: Projectable | ProjectorElementBuildDeskriptor | IdentifiableProjectorElement): boolean {
|
||||
const element = this.getProjectorElement(obj);
|
||||
return this.DS.getAll<Projector>('core/projector').some(projector => {
|
||||
return projector.isElementShown(element);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all projectors where the object is prejected on.
|
||||
*
|
||||
* @param obj The object in question
|
||||
* @return All projectors, where this Object is projected on
|
||||
*/
|
||||
public getProjectorsWhichAreProjecting(
|
||||
obj: Projectable | ProjectorElementBuildDeskriptor | IdentifiableProjectorElement
|
||||
): Projector[] {
|
||||
const element = this.getProjectorElement(obj);
|
||||
return this.DS.getAll<Projector>('core/projector').filter(projector => {
|
||||
return projector.isElementShown(element);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, if the object is projected on the given projector.
|
||||
*
|
||||
@ -101,12 +99,8 @@ export class ProjectorService extends OpenSlidesComponent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects the given ProjectorElement on the given projectors.
|
||||
*
|
||||
* TODO: this does not care about the element being stable. Some more logic must be added later.
|
||||
*
|
||||
* On the given projectors: Delete all non-stable elements and add the given element.
|
||||
* On all other projectors: If the element (compared with name and id) is there, it will be deleted.
|
||||
* Projects the given ProjectorElement on the given projectors. Removes the element
|
||||
* from all non-given projectors
|
||||
*
|
||||
* @param projectors All projectors where to add the element.
|
||||
* @param element The element in question.
|
||||
@ -121,6 +115,13 @@ export class ProjectorService extends OpenSlidesComponent {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Projcets the given object on the projector. If the object is non-stable, all other non-stable
|
||||
* elements will be removed and added to the history.
|
||||
*
|
||||
* @param projector The projector to add the object to.
|
||||
* @param obj The object to project
|
||||
*/
|
||||
public async projectOn(
|
||||
projector: Projector,
|
||||
obj: Projectable | ProjectorElementBuildDeskriptor | IdentifiableProjectorElement
|
||||
@ -147,26 +148,40 @@ export class ProjectorService extends OpenSlidesComponent {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given object from the projector. Non stable elements will be added to the history.
|
||||
*
|
||||
* @param projector The projector
|
||||
* @param obj the object to unproject
|
||||
*/
|
||||
public async removeFrom(
|
||||
projector: Projector,
|
||||
obj: Projectable | ProjectorElementBuildDeskriptor | IdentifiableProjectorElement
|
||||
): Promise<void> {
|
||||
const element = this.getProjectorElement(obj);
|
||||
|
||||
if (element.stable) {
|
||||
// Just remove this stable element
|
||||
projector.removeElements(element);
|
||||
await this.projectRequest(projector, projector.elements);
|
||||
} else {
|
||||
// For non-stable elements remove all current non-stable elements and add them to the history
|
||||
const removedElements = projector.removeElements(element);
|
||||
if (removedElements.length > 0) {
|
||||
console.log(projector.elements, removedElements);
|
||||
const removedElements = projector.removeElements(element);
|
||||
if (removedElements.length > 0) {
|
||||
if (element.stable) {
|
||||
await this.projectRequest(projector, projector.elements);
|
||||
} else {
|
||||
// For non-stable elements: Add removed elements to the history.
|
||||
await this.projectRequest(projector, projector.elements, null, removedElements);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the request to change projector elements.
|
||||
*
|
||||
* Note: Just one of `appendToHistory` and `deleteLastHistoryElement` can be given.
|
||||
*
|
||||
* @param projector The affected projector
|
||||
* @param elements (optional) Elements to set.
|
||||
* @param preview (optional) preview to set
|
||||
* @param appendToHistory (optional) Elements to be appended to the history
|
||||
* @param deleteLastHistroyElement (optional) If given, the last history element will be removed.
|
||||
*/
|
||||
private async projectRequest(
|
||||
projector: Projector,
|
||||
elements?: ProjectorElements,
|
||||
@ -206,21 +221,41 @@ export class ProjectorService extends OpenSlidesComponent {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a model associated with the identifiable projector element. Throws an error,
|
||||
* if the element is not mappable.
|
||||
*
|
||||
* @param element The projector element
|
||||
* @returns the model from the projector element
|
||||
*/
|
||||
public getModelFromProjectorElement<T extends BaseModel>(element: IdentifiableProjectorElement): T {
|
||||
if (!this.slideManager.canSlideBeMappedToModel(element.name)) {
|
||||
throw new Error('THis projectorelement cannot be mapped to a model');
|
||||
throw new Error('This projector element cannot be mapped to a model');
|
||||
}
|
||||
const identifiers = element.getIdentifiers();
|
||||
if (!identifiers.includes('name') || !identifiers.includes('name')) {
|
||||
if (!identifiers.includes('name') || !identifiers.includes('id')) {
|
||||
throw new Error('To map this element to a model, a name and id is needed.');
|
||||
}
|
||||
return this.DS.get<T>(element.name, element.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects the next slide in the queue. Moves all currently projected
|
||||
* non-stable slides to the history.
|
||||
*
|
||||
* @param projector The projector
|
||||
*/
|
||||
public async projectNextSlide(projector: Projector): Promise<void> {
|
||||
await this.projectPreviewSlide(projector, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects one slide (given by the index of the preview) on the given projector. Moves
|
||||
* all current projected non-stable elements to the history.
|
||||
*
|
||||
* @param projector The projector
|
||||
* @param previewIndex The index in the `elements_preview` array.
|
||||
*/
|
||||
public async projectPreviewSlide(projector: Projector, previewIndex: number): Promise<void> {
|
||||
if (projector.elements_preview.length === 0 || previewIndex >= projector.elements_preview.length) {
|
||||
return;
|
||||
@ -231,6 +266,11 @@ export class ProjectorService extends OpenSlidesComponent {
|
||||
await this.projectRequest(projector, projector.elements, projector.elements_preview, removedElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects the last slide of the history. This slide will be removed from the history.
|
||||
*
|
||||
* @param projector The projector
|
||||
*/
|
||||
public async projectPreviousSlide(projector: Projector): Promise<void> {
|
||||
if (projector.elements_history.length === 0) {
|
||||
return;
|
||||
@ -253,10 +293,21 @@ export class ProjectorService extends OpenSlidesComponent {
|
||||
await this.projectRequest(projector, projector.elements, projector.elements_preview, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the preview of the projector
|
||||
*
|
||||
* @param projector The projector to save the preview.
|
||||
*/
|
||||
public async savePreview(projector: Projector): Promise<void> {
|
||||
await this.projectRequest(projector, null, projector.elements_preview);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the given element to the preview.
|
||||
*
|
||||
* @param projector The projector
|
||||
* @param element The element to add to the preview.
|
||||
*/
|
||||
public async addElementToPreview(projector: Projector, element: ProjectorElement): Promise<void> {
|
||||
projector.elements_preview.push(element);
|
||||
await this.projectRequest(projector, null, projector.elements_preview);
|
||||
|
@ -5,6 +5,13 @@ import { HttpService } from './http.service';
|
||||
import { environment } from 'environments/environment.prod';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
|
||||
/**
|
||||
* This service provides the timeoffset to the server and a user of this service
|
||||
* can query the servertime.
|
||||
*
|
||||
* This service needs to be started with `startScheduler` which will update
|
||||
* the servertime frequently.
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
@ -13,7 +20,7 @@ export class ServertimeService extends OpenSlidesComponent {
|
||||
private static NORMAL_TIMEOUT = 60 * 5;
|
||||
|
||||
/**
|
||||
* In milliseconds
|
||||
* The server offset in milliseconds
|
||||
*/
|
||||
private serverOffsetSubject = new BehaviorSubject<number>(0);
|
||||
|
||||
@ -21,27 +28,40 @@ export class ServertimeService extends OpenSlidesComponent {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the scheduler to sync with the server.
|
||||
*/
|
||||
public startScheduler(): void {
|
||||
this.scheduleNextRefresh(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an observable for the server offset.
|
||||
*/
|
||||
public getServerOffsetObservable(): Observable<number> {
|
||||
return this.serverOffsetSubject.asObservable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules the next sync with the server.
|
||||
*
|
||||
* @param seconds The timeout in seconds to the refresh.
|
||||
*/
|
||||
private scheduleNextRefresh(seconds: number): void {
|
||||
setTimeout(async () => {
|
||||
let timeout = ServertimeService.NORMAL_TIMEOUT;
|
||||
try {
|
||||
await this.refreshServertime();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
timeout = ServertimeService.FAILURE_TIMEOUT;
|
||||
}
|
||||
this.scheduleNextRefresh(timeout);
|
||||
}, 1000 * seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the servertime and calculates the offset.
|
||||
*/
|
||||
private async refreshServertime(): Promise<void> {
|
||||
// servertime is the time in seconds.
|
||||
const servertime = await this.http.get<number>(environment.urlPrefix + '/core/servertime/');
|
||||
@ -52,6 +72,9 @@ export class ServertimeService extends OpenSlidesComponent {
|
||||
this.serverOffsetSubject.next(Math.floor(Date.now() - servertime * 1000));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the time of the server.
|
||||
*/
|
||||
public getServertime(): number {
|
||||
return Date.now() - this.serverOffsetSubject.getValue();
|
||||
}
|
||||
|
@ -1,10 +1,19 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
|
||||
import { Projectable, ProjectorElementBuildDeskriptor } from 'app/site/base/projectable';
|
||||
import {
|
||||
Projectable,
|
||||
ProjectorElementBuildDeskriptor,
|
||||
isProjectable,
|
||||
isProjectorElementBuildDeskriptor
|
||||
} from 'app/site/base/projectable';
|
||||
import { ProjectionDialogService } from 'app/core/services/projection-dialog.service';
|
||||
import { ProjectorService } from '../../../core/services/projector.service';
|
||||
|
||||
/**
|
||||
* The projector button to project something on the projector.
|
||||
*
|
||||
* Use the input [object] to specify the object to project. It can either be
|
||||
* a Projectable or a ProjectorElementBuildDeskriptor
|
||||
*/
|
||||
@Component({
|
||||
selector: 'os-projector-button',
|
||||
@ -12,11 +21,29 @@ import { ProjectorService } from '../../../core/services/projector.service';
|
||||
styleUrls: ['./projector-button.component.scss']
|
||||
})
|
||||
export class ProjectorButtonComponent implements OnInit {
|
||||
/**
|
||||
* The object to project.
|
||||
*/
|
||||
private _object: Projectable | ProjectorElementBuildDeskriptor;
|
||||
|
||||
public get object(): Projectable | ProjectorElementBuildDeskriptor {
|
||||
return this._object;
|
||||
}
|
||||
|
||||
@Input()
|
||||
public object: Projectable | ProjectorElementBuildDeskriptor;
|
||||
public set object(obj: Projectable | ProjectorElementBuildDeskriptor) {
|
||||
if (isProjectable(obj) || isProjectorElementBuildDeskriptor(obj)) {
|
||||
this._object = obj;
|
||||
} else {
|
||||
console.error(
|
||||
'Your model for the projectorbutton is not projectable and not' + 'a projectorElementBuildDescriptor!',
|
||||
obj
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The consotructor
|
||||
* The constructor
|
||||
*/
|
||||
public constructor(
|
||||
private projectionDialogService: ProjectionDialogService,
|
||||
@ -28,6 +55,11 @@ export class ProjectorButtonComponent implements OnInit {
|
||||
*/
|
||||
public ngOnInit(): void {}
|
||||
|
||||
/**
|
||||
* Click on the projector button
|
||||
*
|
||||
* @param event the click event
|
||||
*/
|
||||
public onClick(event: Event): void {
|
||||
event.stopPropagation();
|
||||
this.projectionDialogService.openProjectDialogFor(this.object);
|
||||
@ -39,10 +71,9 @@ export class ProjectorButtonComponent implements OnInit {
|
||||
* @returns true, if the object is projected on one projector.
|
||||
*/
|
||||
public isProjected(): boolean {
|
||||
if (this.object) {
|
||||
return this.projectorService.isProjected(this.object);
|
||||
} else {
|
||||
if (!this.object) {
|
||||
return false;
|
||||
}
|
||||
return this.projectorService.isProjected(this.object);
|
||||
}
|
||||
}
|
||||
|
@ -84,8 +84,12 @@ export class Projector extends BaseModel<Projector> {
|
||||
* @returns all removed unstable elements
|
||||
*/
|
||||
public removeAllNonStableElements(): ProjectorElements {
|
||||
const unstableElements = this.elements.filter(element => !element.stable);
|
||||
this.elements = this.elements.filter(element => element.stable);
|
||||
let unstableElements: ProjectorElements;
|
||||
let stableElements: ProjectorElements;
|
||||
|
||||
[unstableElements, stableElements] = this.partitionArray(this.elements, element => !element.stable);
|
||||
|
||||
this.elements = stableElements;
|
||||
return unstableElements;
|
||||
}
|
||||
|
||||
@ -99,8 +103,11 @@ export class Projector extends BaseModel<Projector> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Must match everything. If a projectorelement does not have all keys
|
||||
* to identify, it will be removed, if all existing keys match
|
||||
* Removes and returns all projector elements, witch can be identified with the
|
||||
* given element.
|
||||
*
|
||||
* @param element The element to remove
|
||||
* @returns all removed projector elements
|
||||
*/
|
||||
public removeElements(element: IdentifiableProjectorElement): ProjectorElements {
|
||||
let removedElements: ProjectorElements;
|
||||
@ -114,6 +121,14 @@ export class Projector extends BaseModel<Projector> {
|
||||
return removedElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param array The array to split
|
||||
* @param callback To evaluate every entry
|
||||
* @returns the splitted array
|
||||
*/
|
||||
private partitionArray<T>(array: T[], callback: (element: T) => boolean): [T[], T[]] {
|
||||
return array.reduce(
|
||||
(result, element) => {
|
||||
|
@ -69,7 +69,7 @@ export class CountdownListComponent extends BaseViewComponent implements OnInit
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new Section.
|
||||
* Add a new countdown.
|
||||
*/
|
||||
public onPlusButton(): void {
|
||||
if (!this.countdownToCreate) {
|
||||
|
@ -7,7 +7,7 @@ import { BaseViewComponent } from '../../../base/base-view';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
|
||||
/**
|
||||
* List view for the statute paragraphs.
|
||||
* List view for the projector messages.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'os-projectormessage-list',
|
||||
@ -22,7 +22,7 @@ export class ProjectorMessageListComponent extends BaseViewComponent implements
|
||||
/**
|
||||
* Init function.
|
||||
*
|
||||
* Sets the title and gets/observes countdowns from DataStore
|
||||
* Sets the title and gets/observes messages from DataStore
|
||||
*/
|
||||
public ngOnInit(): void {
|
||||
super.setTitle('Messages');
|
||||
|
@ -15,7 +15,7 @@ export class CurrentListOfSpeakersSlideService {
|
||||
return {
|
||||
name: overlay ? 'agenda/current-list-of-speakers-overlay' : 'agenda/current-list-of-speakers',
|
||||
stable: overlay,
|
||||
getIdentifiers: () => ['name', 'stable']
|
||||
getIdentifiers: () => ['name']
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ export class ProjectorDataService {
|
||||
Object.keys(update).forEach(_id => {
|
||||
const id = parseInt(_id, 10);
|
||||
if ((<{ error: string }>update[id]).error !== undefined) {
|
||||
console.log('TODO: Why does the server sends errors on autpupdates?');
|
||||
console.log('TODO: Why does the server sends errors on autoupdates?');
|
||||
} else {
|
||||
if (this.currentProjectorData[id]) {
|
||||
this.currentProjectorData[id].next(update[id] as ProjectorData);
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { BaseSlideComponent } from 'app/slides/base-slide-component';
|
||||
import { HttpService } from 'app/core/services/http.service';
|
||||
import { AgendaCurrentListOfSpeakersSlideData } from '../base/agenda-current-list-of-speakers-slide-data';
|
||||
import { SlideData } from 'app/site/projector/services/projector-data.service';
|
||||
|
||||
@Component({
|
||||
selector: 'os-agenda-current-list-of-speakers-slide',
|
||||
@ -12,23 +10,8 @@ import { SlideData } from 'app/site/projector/services/projector-data.service';
|
||||
})
|
||||
export class AgendaCurrentListOfSpeakersSlideComponent extends BaseSlideComponent<AgendaCurrentListOfSpeakersSlideData>
|
||||
implements OnInit {
|
||||
private _data: SlideData<AgendaCurrentListOfSpeakersSlideData>;
|
||||
|
||||
public isOverlay: boolean;
|
||||
|
||||
public get data(): SlideData<AgendaCurrentListOfSpeakersSlideData> {
|
||||
return this._data;
|
||||
}
|
||||
|
||||
@Input()
|
||||
public set data(value: SlideData<AgendaCurrentListOfSpeakersSlideData>) {
|
||||
this.isOverlay = !value || value.element.stable;
|
||||
this._data = value;
|
||||
}
|
||||
|
||||
public constructor(private http: HttpService) {
|
||||
public constructor() {
|
||||
super();
|
||||
console.log(this.http);
|
||||
}
|
||||
|
||||
public ngOnInit(): void {
|
||||
|
@ -32,7 +32,7 @@ export class CoreClockSlideComponent extends BaseSlideComponent<{}> implements O
|
||||
const hours = '0' + time.getHours();
|
||||
const minutes = '0' + time.getMinutes();
|
||||
|
||||
// Will display time in 10:30:23 format
|
||||
// Will display time in hh:mm format
|
||||
this.time = hours.slice(-2) + ':' + minutes.slice(-2);
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,8 @@
|
||||
<div *ngIf="!data.data.is_child" [innerHTML]="data.data.text"></div>
|
||||
|
||||
<!-- Amendment text -->
|
||||
<div *ngIf="data.data.is_child" [innerHTML]="data.data.amendment_paragraphs[0]"></div>
|
||||
<div *ngIf="data.data.is_child && data.data.amendment_paragraphs"
|
||||
[innerHTML]="data.data.amendment_paragraphs[0]"></div>
|
||||
|
||||
<!-- Reason -->
|
||||
<div *ngIf="data.data.reason">
|
||||
|
@ -23,15 +23,14 @@ def user_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
|
||||
user_id = element.get("id")
|
||||
|
||||
if user_id is None:
|
||||
return {"error": "id is required for user slide"}
|
||||
raise ProjectorElementException("id is required for user slide")
|
||||
|
||||
try:
|
||||
user = all_data["users/user"][user_id]
|
||||
except KeyError:
|
||||
raise ProjectorElementException(f"user with id {user_id} does not exist")
|
||||
|
||||
return_value = {"user": get_user_name(all_data, user["id"])}
|
||||
return return_value
|
||||
return {"user": get_user_name(all_data, user["id"])}
|
||||
|
||||
|
||||
def get_user_name(all_data: AllData, user_id: int) -> str:
|
||||
|
Loading…
Reference in New Issue
Block a user