ngx-simple-countdown
Version:
The most simple way to display a countdown in angular 20 (standalone and ngModule)
419 lines (410 loc) • 15.2 kB
JavaScript
import * as i0 from '@angular/core';
import { EventEmitter, Output, Input, Directive, NgModule } from '@angular/core';
import { interval, ReplaySubject } from 'rxjs';
import { takeUntil, filter, tap } from 'rxjs/operators';
const getDateNow = () => {
return Math.floor(Date.now() / 1000);
};
const getCountdownResult = (secondes) => {
return {
seconds: Math.floor((secondes / 1) % 60),
minutes: Math.floor((secondes / 1 / 60) % 60),
hours: Math.floor((secondes / (1 * 60 * 60)) % 24),
day: Math.floor(secondes / (1 * 60 * 60 * 24))
};
};
const getLanguage = (language) => {
if (language === 'fr') {
return {
timeago: 'il y a',
now: "à l'instant",
seconds: 's',
minutes: 'm',
hours: 'h',
day: 'j'
};
}
else if (language === 'de') {
return {
timeago: 'vor',
now: 'gerade jetzt',
seconds: 'z',
minutes: 'm',
hours: 's',
day: 't'
};
}
else if (language === 'pt') {
return {
timeago: 'há',
now: 'agora mesmo',
seconds: 's',
minutes: 'm',
hours: 's',
day: 'd'
};
}
else if (language === 'es') {
return {
timeago: 'hace',
now: 'en este momento',
seconds: 's',
minutes: 'm',
hours: 's',
day: 'd'
};
}
else if (language === 'cs') {
return {
timeago: 'před',
now: 'právě teď',
seconds: 's',
minutes: 'm',
hours: 'h',
day: 'd'
};
}
else if (language === 'pl') {
return {
timeago: 'jest',
now: 'właśnie',
seconds: 's',
minutes: 'm',
hours: 'g',
day: 'd'
};
}
else if (language === 'ge') {
return {
timeago: 'დასრულდა',
now: 'დროა',
seconds: 'წმ',
minutes: 'წთ',
hours: 'სთ',
day: 'დღე'
};
}
else {
return {
timeago: 'there is',
now: 'just now',
seconds: 's',
minutes: 'm',
hours: 'h',
day: 'd'
};
}
};
class NgxSimpleCountdownDirective {
elementRef;
dateTo;
endMessage = 'countdown finish';
language = 'en';
reactive = true;
styles = 'font-size:20px;color:#FFF;background-color:#000;padding:10px 5px;font-weight:bold;min-width:40px;text-align:center;';
finish = new EventEmitter();
countdownResult;
dateNow;
interval$;
keywords;
totalSecondes;
constructor(elementRef) {
this.elementRef = elementRef;
}
ngOnInit() {
this.dateNow = getDateNow();
this.keywords = getLanguage(this.language);
this.initSimpleCountdown();
}
ngOnDestroy() { }
initSimpleCountdown() {
this.totalSecondes = this.dateTo - this.dateNow;
this.updateSimpleCountdown(this.totalSecondes);
this.interval$ = interval(1000).pipe(takeUntil(this.componentDestroyed(this)), filter((_) => this.reactive && this.totalSecondes > 0), tap((_) => {
this.totalSecondes--;
this.updateSimpleCountdown(this.totalSecondes);
}));
if (this.reactive) {
this.interval$.subscribe();
}
}
createHTML(data) {
const { day, hours, minutes, seconds } = data;
let o = '';
if (this.totalSecondes > 0) {
o = '<div style="display:flex;">';
if (day > 0) {
o += `<div style="${this.styles}">
${day}${this.keywords.day}
</div>`;
}
if (hours > 0 || day > 0) {
o += `<div style="${this.styles}">
${hours}${this.keywords.hours}
</div>`;
}
if ((minutes > 0 || hours > 0 || day > 0) && this.reactive) {
o += `<div style="${this.styles}">
${minutes}${this.keywords.minutes}
</div>`;
}
if ((seconds > 0 || minutes > 0 || hours > 0 || day > 0) &&
this.reactive) {
o += `<div style="${this.styles}">
${seconds}${this.keywords.seconds}
</div>`;
}
o += '</div>';
}
else {
this.finish.emit();
if (this.endMessage !== '') {
o += `<div style="${this.styles}">${this.endMessage}</div>`;
}
}
this.elementRef.nativeElement.innerHTML = o;
}
updateSimpleCountdown(secondes) {
const countdownResult = getCountdownResult(secondes);
this.createHTML(countdownResult);
}
componentDestroyed(component) {
const oldNgOnDestroy = component.ngOnDestroy;
const destroyed$ = new ReplaySubject(1);
component.ngOnDestroy = () => {
oldNgOnDestroy.apply(component);
destroyed$.next(undefined);
destroyed$.complete();
};
return destroyed$;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: NgxSimpleCountdownDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.15", type: NgxSimpleCountdownDirective, isStandalone: false, selector: "[simpleCountdown]", inputs: { dateTo: "dateTo", endMessage: "endMessage", language: "language", reactive: "reactive", styles: "styles" }, outputs: { finish: "finish" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: NgxSimpleCountdownDirective, decorators: [{
type: Directive,
args: [{
selector: '[simpleCountdown]',
standalone: false
}]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { dateTo: [{
type: Input
}], endMessage: [{
type: Input
}], language: [{
type: Input
}], reactive: [{
type: Input
}], styles: [{
type: Input
}], finish: [{
type: Output
}] } });
class NgxSimpleTimeagoDirective {
elementRef;
date;
language = 'en';
reactive = true;
dateNow;
interval$;
keywords;
totalSecondes;
constructor(elementRef) {
this.elementRef = elementRef;
}
ngOnInit() {
this.dateNow = getDateNow();
this.keywords = getLanguage(this.language);
this.initSimpleCountdown();
}
ngOnDestroy() { }
initSimpleCountdown() {
this.totalSecondes = this.dateNow - this.date;
this.updateSimpleCountdown(this.totalSecondes);
this.interval$ = interval(20000).pipe(takeUntil(this.componentDestroyed(this)), filter(() => this.reactive && this.totalSecondes > 0), tap(() => {
this.totalSecondes += 20;
this.updateSimpleCountdown(this.totalSecondes);
}));
if (this.reactive) {
this.interval$.subscribe();
}
}
createHTML(data) {
const { day, hours, minutes } = data;
let o = '';
if (this.totalSecondes > 0) {
if (this.totalSecondes <= 60) {
o += this.keywords.now;
}
else {
o += `${this.keywords.timeago} `;
if (data.day > 0) {
o += `${data.day}${this.keywords.day} `;
}
if (hours > 0 || day > 0) {
o += `${hours}${this.keywords.hours} `;
}
if (minutes > 0 || hours > 0 || day > 0) {
o += `${minutes}${this.keywords.minutes} `;
}
}
}
this.elementRef.nativeElement.innerHTML = o;
}
updateSimpleCountdown(secondes) {
const countdownResult = getCountdownResult(secondes);
this.createHTML(countdownResult);
}
componentDestroyed(component) {
const oldNgOnDestroy = component.ngOnDestroy;
const destroyed$ = new ReplaySubject(1);
component.ngOnDestroy = () => {
oldNgOnDestroy.apply(component);
destroyed$.next(undefined);
destroyed$.complete();
};
return destroyed$;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: NgxSimpleTimeagoDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.15", type: NgxSimpleTimeagoDirective, isStandalone: false, selector: "[simpleTimeago]", inputs: { date: "date", language: "language", reactive: "reactive" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: NgxSimpleTimeagoDirective, decorators: [{
type: Directive,
args: [{
selector: '[simpleTimeago]',
standalone: false
}]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { date: [{
type: Input
}], language: [{
type: Input
}], reactive: [{
type: Input
}] } });
class NgxSimpleCountdownModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: NgxSimpleCountdownModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.15", ngImport: i0, type: NgxSimpleCountdownModule, declarations: [NgxSimpleCountdownDirective, NgxSimpleTimeagoDirective], exports: [NgxSimpleCountdownDirective, NgxSimpleTimeagoDirective] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: NgxSimpleCountdownModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: NgxSimpleCountdownModule, decorators: [{
type: NgModule,
args: [{
declarations: [NgxSimpleCountdownDirective, NgxSimpleTimeagoDirective],
imports: [],
exports: [NgxSimpleCountdownDirective, NgxSimpleTimeagoDirective]
}]
}] });
class NgxSimpleCountdownStandaloneDirective {
elementRef;
dateTo;
endMessage = 'countdown finish';
language = 'en';
reactive = true;
styles = 'font-size:20px;color:#FFF;background-color:#000;padding:10px 5px;font-weight:bold;min-width:40px;text-align:center;';
finish = new EventEmitter();
countdownResult;
dateNow;
interval$;
keywords;
totalSecondes;
constructor(elementRef) {
this.elementRef = elementRef;
}
ngOnInit() {
this.dateNow = getDateNow();
this.keywords = getLanguage(this.language);
this.initSimpleCountdown();
}
ngOnDestroy() { }
initSimpleCountdown() {
this.totalSecondes = this.dateTo - this.dateNow;
this.updateSimpleCountdown(this.totalSecondes);
this.interval$ = interval(1000).pipe(takeUntil(this.componentDestroyed(this)), filter((_) => this.reactive && this.totalSecondes > 0), tap((_) => {
this.totalSecondes--;
this.updateSimpleCountdown(this.totalSecondes);
}));
if (this.reactive) {
this.interval$.subscribe();
}
}
createHTML(data) {
const { day, hours, minutes, seconds } = data;
let o = '';
if (this.totalSecondes > 0) {
o = '<div style="display:flex;">';
if (day > 0) {
o += `<div style="${this.styles}">
${day}${this.keywords.day}
</div>`;
}
if (hours > 0 || day > 0) {
o += `<div style="${this.styles}">
${hours}${this.keywords.hours}
</div>`;
}
if ((minutes > 0 || hours > 0 || day > 0) && this.reactive) {
o += `<div style="${this.styles}">
${minutes}${this.keywords.minutes}
</div>`;
}
if ((seconds > 0 || minutes > 0 || hours > 0 || day > 0) &&
this.reactive) {
o += `<div style="${this.styles}">
${seconds}${this.keywords.seconds}
</div>`;
}
o += '</div>';
}
else {
this.finish.emit();
if (this.endMessage !== '') {
o += `<div style="${this.styles}">${this.endMessage}</div>`;
}
}
this.elementRef.nativeElement.innerHTML = o;
}
updateSimpleCountdown(secondes) {
const countdownResult = getCountdownResult(secondes);
this.createHTML(countdownResult);
}
componentDestroyed(component) {
const oldNgOnDestroy = component.ngOnDestroy;
const destroyed$ = new ReplaySubject(1);
component.ngOnDestroy = () => {
oldNgOnDestroy.apply(component);
destroyed$.next(undefined);
destroyed$.complete();
};
return destroyed$;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: NgxSimpleCountdownStandaloneDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.15", type: NgxSimpleCountdownStandaloneDirective, isStandalone: true, selector: "[simpleCountdown]", inputs: { dateTo: "dateTo", endMessage: "endMessage", language: "language", reactive: "reactive", styles: "styles" }, outputs: { finish: "finish" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: NgxSimpleCountdownStandaloneDirective, decorators: [{
type: Directive,
args: [{
selector: '[simpleCountdown]',
standalone: true
}]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { dateTo: [{
type: Input
}], endMessage: [{
type: Input
}], language: [{
type: Input
}], reactive: [{
type: Input
}], styles: [{
type: Input
}], finish: [{
type: Output
}] } });
/*
* Public API Surface of ngx-simple-countdown
*/
// ngModule
/**
* Generated bundle index. Do not edit.
*/
export { NgxSimpleCountdownDirective, NgxSimpleCountdownModule, NgxSimpleCountdownStandaloneDirective, NgxSimpleTimeagoDirective };
//# sourceMappingURL=ngx-simple-countdown.mjs.map