all files / common/core/pipes/ time-ago.pipe.ts

84.62% Statements 44/52
70% Branches 14/20
75% Functions 9/12
85.11% Lines 40/47
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89                                                                                                 
/*
 *  @license
 *  Copyright Hôpitaux Universitaires de Genève. All Rights Reserved.
 *
 *  Use of this source code is governed by an Apache-2.0 license that can be
 *  found in the LICENSE file at https://github.com/DSI-HUG/dejajs-components/blob/master/LICENSE
 */
 
import { ChangeDetectorRef, NgZone, OnDestroy, Pipe, PipeTransform } from '@angular/core';
import * as moment_ from 'moment';
import { from as observableFrom, Subject, timer as observableTimer } from 'rxjs';
import { debounce, takeWhile } from 'rxjs/operators';
const moment: (value?: any, format?: string) => moment_.Moment = (<any>moment_).default || moment_;
 
@Pipe({ name: 'momentTimeAgo', pure: false })
export class TimeAgoPipe implements PipeTransform, OnDestroy {
    private lastTime: Number;
    private lastValue: Date | moment_.Moment;
    private lastOmitSuffix: boolean;
    private lastText: string;
    private createTimer$ = new Subject();
    private isAlive = true;
 
    constructor(private cdRef: ChangeDetectorRef, private ngZone: NgZone) {
        observableFrom(this.createTimer$).pipe(
            takeWhile(() => this.isAlive),
            debounce(() => {
                const momentInstance = moment(this.lastValue);
                const timeToUpdate = this.getSecondsUntilUpdate(momentInstance) * 1000;
                return observableTimer(timeToUpdate);
            }))
            .subscribe(() => {
                Iif (this.ngZone && this.cdRef) {
                    this.ngZone.runOutsideAngular(() => {
                        this.lastText = moment(this.lastValue).from(moment(), this.lastOmitSuffix);
                        this.ngZone.run(() => this.cdRef.markForCheck());
                    });
                }
            });
    }
 
    public ngOnDestroy() {
        this.isAlive = false;
    }
 
    public transform(value: Date | moment_.Moment, omitSuffix?: boolean): string {
        Eif (this.hasChanged(value, omitSuffix)) {
            this.lastTime = this.getTime(value);
            this.lastValue = value;
            this.lastOmitSuffix = omitSuffix;
            this.createTimer$.next();
            this.lastText = moment(value).from(moment(), omitSuffix);
 
        } else {
            this.createTimer$.next();
        }
 
        return this.lastText;
    }
 
    private getSecondsUntilUpdate(momentInstance: moment_.Moment): number {
        const howOld = Math.abs(moment().diff(momentInstance, 'minute'));
        if (howOld < 1) {
            return 1;
        } else if (howOld < 60) {
            return 30;
        } else Eif (howOld < 180) {
            return 300;
        } else {
            return 3600;
        }
    }
 
    private hasChanged(value: Date | moment_.Moment, omitSuffix?: boolean) {
        return this.getTime(value) !== this.lastTime || omitSuffix !== this.lastOmitSuffix;
    }
 
    private getTime(value: Date | moment_.Moment) {
        if (moment_.isDate(value)) {
            return value.getTime();
        } else Eif (moment_.isMoment(value)) {
            return value.valueOf();
        } else {
            return moment(value).valueOf();
        }
    }
}