MOBILE-3585 components: Implement core-chrono component
parent
3c634c4f6e
commit
105430c877
|
@ -0,0 +1,128 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// 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,
|
||||||
|
OnInit,
|
||||||
|
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',
|
||||||
|
templateUrl: 'core-chrono.html',
|
||||||
|
})
|
||||||
|
export class CoreChronoComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
|
@Input() running?: boolean; // Set it to true to start the chrono. Set it to false to stop it.
|
||||||
|
@Input() startTime = 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 = 0;
|
||||||
|
protected interval?: number;
|
||||||
|
|
||||||
|
constructor(protected changeDetectorRef: ChangeDetectorRef) {
|
||||||
|
this.onEnd = new EventEmitter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component being initialized.
|
||||||
|
*/
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.time = this.startTime || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component being changed.
|
||||||
|
*/
|
||||||
|
ngOnChanges(changes: { [name: string]: SimpleChange }): void {
|
||||||
|
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 = window.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.changeDetectorRef.detectChanges();
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the chrono, leaving the same time it has.
|
||||||
|
*/
|
||||||
|
protected stop(): void {
|
||||||
|
clearInterval(this.interval);
|
||||||
|
delete this.interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
<span role="timer">{{ time / 1000 | coreSecondsToHMS }}</span>
|
|
@ -17,6 +17,7 @@ import { CommonModule } from '@angular/common';
|
||||||
import { IonicModule } from '@ionic/angular';
|
import { IonicModule } from '@ionic/angular';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
import { CoreChronoComponent } from './chrono/chrono';
|
||||||
import { CoreDownloadRefreshComponent } from './download-refresh/download-refresh';
|
import { CoreDownloadRefreshComponent } from './download-refresh/download-refresh';
|
||||||
import { CoreFileComponent } from './file/file';
|
import { CoreFileComponent } from './file/file';
|
||||||
import { CoreIconComponent } from './icon/icon';
|
import { CoreIconComponent } from './icon/icon';
|
||||||
|
@ -35,6 +36,7 @@ import { CorePipesModule } from '@app/pipes/pipes.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
|
CoreChronoComponent,
|
||||||
CoreDownloadRefreshComponent,
|
CoreDownloadRefreshComponent,
|
||||||
CoreFileComponent,
|
CoreFileComponent,
|
||||||
CoreIconComponent,
|
CoreIconComponent,
|
||||||
|
@ -56,6 +58,7 @@ import { CorePipesModule } from '@app/pipes/pipes.module';
|
||||||
CorePipesModule,
|
CorePipesModule,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
|
CoreChronoComponent,
|
||||||
CoreDownloadRefreshComponent,
|
CoreDownloadRefreshComponent,
|
||||||
CoreFileComponent,
|
CoreFileComponent,
|
||||||
CoreIconComponent,
|
CoreIconComponent,
|
||||||
|
|
Loading…
Reference in New Issue