MOBILE-2312 core: Implement CoreChrono component
parent
527993dfe8
commit
57d4d9d8ff
|
@ -0,0 +1,116 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, Input, OnChanges, OnDestroy, Output, EventEmitter, SimpleChange, ChangeDetectorRef } from '@angular/core';
|
||||
|
||||
/**
|
||||
* This component shows a chronometer in format HH:MM:SS.
|
||||
*
|
||||
* If no startTime is provided, it will start at 00:00:00.
|
||||
* If an endTime is provided, the chrono will stop and emit an event in the onEnd output when that number of milliseconds is
|
||||
* reached. E.g. if startTime=60000 and endTime=120000, the chrono will start at 00:01:00 and end when it reaches 00:02:00.
|
||||
*
|
||||
* This component has 2 boolean inputs to control the timer: running (to start and stop it) and reset.
|
||||
*
|
||||
* Example usage:
|
||||
* <core-chrono [running]="running" [reset]="reset" [endTime]="maxTime" (onEnd)="stopCapturing()"></core-chrono>
|
||||
*/
|
||||
@Component({
|
||||
selector: 'core-chrono',
|
||||
template: '<span>{{ time / 1000 | coreSecondsToHMS }}</span>'
|
||||
})
|
||||
export class CoreChronoComponent implements OnChanges, OnDestroy {
|
||||
@Input() running: boolean; // Set it to true to start the chrono. Set it to false to stop it.
|
||||
@Input() startTime?: number = 0; // Number of milliseconds to put in the chrono before starting.
|
||||
@Input() endTime?: number; // Number of milliseconds to stop the chrono.
|
||||
@Input() reset?: boolean; // Set it to true to reset the chrono.
|
||||
@Output() onEnd?: EventEmitter<void>; // Will emit an event when the endTime is reached.
|
||||
|
||||
time: number = 0;
|
||||
protected interval;
|
||||
|
||||
constructor(private cdr: ChangeDetectorRef) {
|
||||
this.onEnd = new EventEmitter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit() {
|
||||
this.time = this.startTime || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnChanges(changes: {[name: string]: SimpleChange}) {
|
||||
if (changes && changes.running) {
|
||||
if (changes.running.currentValue) {
|
||||
this.start();
|
||||
} else {
|
||||
this.stop();
|
||||
}
|
||||
}
|
||||
if (changes && changes.reset && changes.reset.currentValue) {
|
||||
this.resetChrono();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the chrono, stopping it and setting it to startTime.
|
||||
*/
|
||||
protected resetChrono() : void {
|
||||
this.stop();
|
||||
this.time = this.startTime || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the chrono if it isn't running.
|
||||
*/
|
||||
protected start() : void {
|
||||
if (this.interval) {
|
||||
// Already setup.
|
||||
return;
|
||||
}
|
||||
|
||||
let lastExecTime = Date.now();
|
||||
|
||||
this.interval = setInterval(() => {
|
||||
// Increase the chrono.
|
||||
this.time += Date.now() - lastExecTime;
|
||||
lastExecTime = Date.now();
|
||||
|
||||
if (typeof this.endTime != 'undefined' && this.time > this.endTime) {
|
||||
// End time reached, stop the timer and call the end function.
|
||||
this.stop();
|
||||
this.onEnd.emit();
|
||||
}
|
||||
|
||||
// Force change detection. Angular doesn't detect these async operations.
|
||||
this.cdr.detectChanges();
|
||||
}, 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the chrono, leaving the same time it has.
|
||||
*/
|
||||
protected stop() : void {
|
||||
clearInterval(this.interval);
|
||||
delete this.interval;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.stop();
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ import { NgModule } from '@angular/core';
|
|||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CoreDirectivesModule } from '../directives/directives.module';
|
||||
import { CorePipesModule } from '../pipes/pipes.module';
|
||||
import { CoreLoadingComponent } from './loading/loading';
|
||||
import { CoreMarkRequiredComponent } from './mark-required/mark-required';
|
||||
import { CoreInputErrorsComponent } from './input-errors/input-errors';
|
||||
|
@ -28,6 +29,7 @@ import { CoreFileComponent } from './file/file';
|
|||
import { CoreContextMenuComponent } from './context-menu/context-menu';
|
||||
import { CoreContextMenuItemComponent } from './context-menu/context-menu-item';
|
||||
import { CoreContextMenuPopoverComponent } from './context-menu/context-menu-popover';
|
||||
import { CoreChronoComponent } from './chrono/chrono';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -42,7 +44,8 @@ import { CoreContextMenuPopoverComponent } from './context-menu/context-menu-pop
|
|||
CoreFileComponent,
|
||||
CoreContextMenuComponent,
|
||||
CoreContextMenuItemComponent,
|
||||
CoreContextMenuPopoverComponent
|
||||
CoreContextMenuPopoverComponent,
|
||||
CoreChronoComponent
|
||||
],
|
||||
entryComponents: [
|
||||
CoreContextMenuPopoverComponent
|
||||
|
@ -50,7 +53,8 @@ import { CoreContextMenuPopoverComponent } from './context-menu/context-menu-pop
|
|||
imports: [
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreDirectivesModule
|
||||
CoreDirectivesModule,
|
||||
CorePipesModule
|
||||
],
|
||||
exports: [
|
||||
CoreLoadingComponent,
|
||||
|
@ -63,7 +67,8 @@ import { CoreContextMenuPopoverComponent } from './context-menu/context-menu-pop
|
|||
CoreSearchBoxComponent,
|
||||
CoreFileComponent,
|
||||
CoreContextMenuComponent,
|
||||
CoreContextMenuItemComponent
|
||||
CoreContextMenuItemComponent,
|
||||
CoreChronoComponent
|
||||
]
|
||||
})
|
||||
export class CoreComponentsModule {}
|
||||
|
|
|
@ -54,6 +54,9 @@ export class CoreSecondsToHMSPipe implements PipeTransform {
|
|||
seconds = numberSeconds;
|
||||
}
|
||||
|
||||
// Don't allow decimals.
|
||||
seconds = Math.floor(seconds);
|
||||
|
||||
hours = Math.floor(seconds / CoreConstants.secondsHour);
|
||||
seconds -= hours * CoreConstants.secondsHour;
|
||||
minutes = Math.floor(seconds / CoreConstants.secondsMinute);
|
||||
|
|
Loading…
Reference in New Issue