Merge pull request #4252 from MaximilianKrambach/speakertime

improve start time and duration display for finished speakers
This commit is contained in:
Emanuel Schütze 2019-02-06 17:52:19 +01:00 committed by GitHub
commit c84f8196fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 9 deletions

View File

@ -69,4 +69,16 @@ export class DurationService {
return ''; return '';
} }
} }
/**
* Converts a duration number (given in seconds)o a string in `MMM:SS` format
*
* @param time value in seconds
* @returns a more human readable time representation
*/
public secondDurationToString(time: number): string {
const minutes = Math.floor(time / 60);
const seconds = Math.floor(time % 60);
return `${minutes}:${`0${seconds}`.slice(-2)}`;
}
} }

View File

@ -19,8 +19,19 @@ export enum SpeakerState {
export class Speaker extends Deserializer { export class Speaker extends Deserializer {
public id: number; public id: number;
public user_id: number; public user_id: number;
public begin_time: string; // TODO this is a time object
public end_time: string; // TODO this is a time object /**
* ISO datetime string to indicate the begin time of the speech. Empty if
* the speaker has not started
*/
public begin_time: string;
/**
* ISO datetime string to indicate the end time of the speech. Empty if the
* speech has not ended
*/
public end_time: string;
public weight: number; public weight: number;
public marked: boolean; public marked: boolean;
public item_id: number; public item_id: number;

View File

@ -37,13 +37,11 @@
<!-- {Number}. {full_name} {time} minutes (Start time: {begin_time}) [close button] --> <!-- {Number}. {full_name} {time} minutes (Start time: {begin_time}) [close button] -->
<mat-list-item *ngFor="let speaker of finishedSpeakers; let number = index"> <mat-list-item *ngFor="let speaker of finishedSpeakers; let number = index">
<div class="finished-prefix"> <div class="finished-prefix">
<span>{{ number + 1 }}</span> <span>.&nbsp;{{ speaker }}</span> <span>{{ number + 1 }}. {{ speaker }}</span>
</div> </div>
<div class="finished-suffix"> <div class="finished-suffix">
<!-- TODO: No Date or time class yet --> &nbsp;&nbsp; {{ durationString(speaker) }}
<!-- <span> calc time here &nbsp;</span> --> ({{ 'Start time' | translate }}: {{ startTimeToString(speaker) }})
<!-- <span translate>minutes</span> -->
<span>&nbsp;(</span> <span translate>Start time</span> <span>:&nbsp;{{ speaker.begin_time }})</span>
</div> </div>
<button <button
mat-stroked-button mat-stroked-button

View File

@ -10,6 +10,7 @@ import { AgendaRepositoryService } from 'app/core/repositories/agenda/agenda-rep
import { BaseViewComponent } from 'app/site/base/base-view'; import { BaseViewComponent } from 'app/site/base/base-view';
import { CurrentListOfSpeakersSlideService } from 'app/site/projector/services/current-list-of-of-speakers-slide.service'; import { CurrentListOfSpeakersSlideService } from 'app/site/projector/services/current-list-of-of-speakers-slide.service';
import { DataStoreService } from 'app/core/core-services/data-store.service'; import { DataStoreService } from 'app/core/core-services/data-store.service';
import { DurationService } from 'app/core/ui-services/duration.service';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService } from 'app/core/core-services/operator.service';
import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service'; import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service';
import { PromptService } from 'app/core/ui-services/prompt.service'; import { PromptService } from 'app/core/ui-services/prompt.service';
@ -91,7 +92,9 @@ export class SpeakerListComponent extends BaseViewComponent implements OnInit {
} }
/** /**
* Constructor for speaker list component * Constructor for speaker list component. Generates the forms and subscribes
* to the {@link currentListOfSpeakers}
*
* @param title * @param title
* @param translate * @param translate
* @param snackBar * @param snackBar
@ -100,6 +103,9 @@ export class SpeakerListComponent extends BaseViewComponent implements OnInit {
* @param DS the DataStore * @param DS the DataStore
* @param itemRepo Repository fpr agenda items * @param itemRepo Repository fpr agenda items
* @param op the current operator * @param op the current operator
* @param promptService
* @param currentListOfSpeakersService
* @param durationService helper for speech duration display
*/ */
public constructor( public constructor(
title: Title, title: Title,
@ -111,7 +117,8 @@ export class SpeakerListComponent extends BaseViewComponent implements OnInit {
private itemRepo: AgendaRepositoryService, private itemRepo: AgendaRepositoryService,
private op: OperatorService, private op: OperatorService,
private promptService: PromptService, private promptService: PromptService,
private currentListOfSpeakersService: CurrentListOfSpeakersSlideService private currentListOfSpeakersService: CurrentListOfSpeakersSlideService,
private durationService: DurationService
) { ) {
super(title, translate, snackBar); super(title, translate, snackBar);
this.isCurrentListOfSpeakers(); this.isCurrentListOfSpeakers();
@ -318,4 +325,27 @@ export class SpeakerListComponent extends BaseViewComponent implements OnInit {
this.itemRepo.deleteAllSpeakers(this.viewItem); this.itemRepo.deleteAllSpeakers(this.viewItem);
} }
} }
/**
* returns a locale-specific version of the starting time for the given speaker item
*
* @param speaker
* @returns a time string using the current language setting of the client
*/
public startTimeToString(speaker: ViewSpeaker): string {
return new Date(speaker.begin_time).toLocaleString(this.translate.currentLang);
}
/**
* get the duration of a speech
*
* @param speaker
* @returns string representation of the duration in `[MM]M:SS minutes` format
*/
public durationString(speaker: ViewSpeaker): string {
const duration = Math.floor(
(new Date(speaker.end_time).valueOf() - new Date(speaker.begin_time).valueOf()) / 1000
);
return `${this.durationService.secondDurationToString(duration)} ${this.translate.instant('minutes')}`;
}
} }

View File

@ -30,10 +30,16 @@ export class ViewSpeaker extends BaseViewModel implements Selectable {
return this.speaker ? this.speaker.marked : null; return this.speaker ? this.speaker.marked : null;
} }
/**
* @returns an ISO datetime string or null
*/
public get begin_time(): string { public get begin_time(): string {
return this.speaker ? this.speaker.begin_time : null; return this.speaker ? this.speaker.begin_time : null;
} }
/**
* @returns an ISO datetime string or null
*/
public get end_time(): string { public get end_time(): string {
return this.speaker ? this.speaker.end_time : null; return this.speaker ? this.speaker.end_time : null;
} }