added time left display #93
This commit is contained in:
parent
b8311371f9
commit
6cb2132bf9
|
@ -61,6 +61,7 @@ import { CardComponent } from './components/stream/status/card/card.component';
|
|||
import { ListEditorComponent } from './components/floating-column/manage-account/my-account/list-editor/list-editor.component';
|
||||
import { ListAccountComponent } from './components/floating-column/manage-account/my-account/list-editor/list-account/list-account.component';
|
||||
import { PollComponent } from './components/stream/status/poll/poll.component';
|
||||
import { TimeLeftPipe } from './pipes/time-left.pipe';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: "", redirectTo: "home", pathMatch: "full" },
|
||||
|
@ -110,7 +111,8 @@ const routes: Routes = [
|
|||
CardComponent,
|
||||
ListEditorComponent,
|
||||
ListAccountComponent,
|
||||
PollComponent
|
||||
PollComponent,
|
||||
TimeLeftPipe
|
||||
],
|
||||
imports: [
|
||||
FontAwesomeModule,
|
||||
|
|
|
@ -23,6 +23,6 @@
|
|||
<button href *ngIf="!poll.voted && !poll.expired" class="btn btn-sm btn-custom-primary poll__btn-vote"
|
||||
title="don't boo, vote!" (click)="vote()">Vote</button>
|
||||
<a href class="poll__refresh" *ngIf="poll.voted || poll.expired" title="refresh poll">refresh</a>
|
||||
<div class="poll__statistics"><span *ngIf="poll.voted || poll.expired" class="poll__separator">·</span>{{poll.votes_count}} votes<span *ngIf="!poll.expired" class="poll__separator">· X days left</span></div>
|
||||
<div class="poll__statistics"><span *ngIf="poll.voted || poll.expired" class="poll__separator">·</span>{{poll.votes_count}} votes<span *ngIf="!poll.expired" class="poll__separator" title="{{ poll.expires_at | timeLeft | async }}">· {{ poll.expires_at | timeLeft | async }}</span></div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,8 @@
|
|||
import { TimeLeftPipe } from './time-left.pipe';
|
||||
|
||||
xdescribe('TimeLeftPipe', () => {
|
||||
it('create an instance', () => {
|
||||
const pipe = new TimeLeftPipe(null);
|
||||
expect(pipe).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,106 @@
|
|||
import { Pipe, PipeTransform, NgZone } from '@angular/core';
|
||||
import { Observable, Observer } from 'rxjs';
|
||||
|
||||
interface processOutput {
|
||||
text: string; // Convert timestamp to string
|
||||
timeToUpdate: number; // Time until update in milliseconds
|
||||
}
|
||||
|
||||
@Pipe({
|
||||
name: 'timeLeft'
|
||||
})
|
||||
export class TimeLeftPipe implements PipeTransform {
|
||||
|
||||
constructor(private ngZone: NgZone) { }
|
||||
|
||||
private process = (timestamp: number): processOutput => {
|
||||
let text: string;
|
||||
let timeToUpdate: number;
|
||||
|
||||
const now = new Date();
|
||||
|
||||
// Time ago in milliseconds
|
||||
const timeLeft: number = timestamp - now.getTime();
|
||||
|
||||
const seconds = timeLeft / 1000;
|
||||
const minutes = seconds / 60;
|
||||
const hours = minutes / 60;
|
||||
const days = hours / 24;
|
||||
// const months = days / 30.416;
|
||||
// const years = days / 365;
|
||||
|
||||
if (seconds < 0) {
|
||||
text = '0 seconds left';
|
||||
} else if (seconds <= 60) {
|
||||
text = Math.round(seconds) + ' seconds left';
|
||||
} else if (minutes <= 90) {
|
||||
text = Math.round(minutes) + ' minutes left';
|
||||
} else if (hours <= 24) {
|
||||
text = Math.round(hours) + ' hours left';
|
||||
} else {
|
||||
text = Math.round(days) + ' days left';
|
||||
}
|
||||
|
||||
if (seconds < -10) {
|
||||
// update every week
|
||||
timeToUpdate = 7 * 24 * 3600 * 1000;
|
||||
} else if (minutes < 1) {
|
||||
// update every 2 secs
|
||||
timeToUpdate = 2 * 1000;
|
||||
} else if (hours < 1) {
|
||||
// update every 30 secs
|
||||
timeToUpdate = 30 * 1000;
|
||||
} else if (days < 1) {
|
||||
// update every 5 mins
|
||||
timeToUpdate = 300 * 1000;
|
||||
} else {
|
||||
// update every hour
|
||||
timeToUpdate = 3600 * 1000;
|
||||
}
|
||||
|
||||
return {
|
||||
text,
|
||||
timeToUpdate
|
||||
};
|
||||
}
|
||||
|
||||
public transform = (value: string | Date): Observable<string> => {
|
||||
let d: Date;
|
||||
if (value instanceof Date) {
|
||||
d = value;
|
||||
}
|
||||
else {
|
||||
d = new Date(value);
|
||||
}
|
||||
// time value in milliseconds
|
||||
const timestamp = d.getTime();
|
||||
|
||||
let timeoutID: any;
|
||||
|
||||
return Observable.create((observer: Observer<string>) => {
|
||||
let latestText = '';
|
||||
|
||||
// Repeatedly set new timeouts for new update checks.
|
||||
const registerUpdate = () => {
|
||||
const processOutput = this.process(timestamp);
|
||||
if (processOutput.text !== latestText) {
|
||||
latestText = processOutput.text;
|
||||
this.ngZone.run(() => {
|
||||
observer.next(latestText);
|
||||
});
|
||||
}
|
||||
timeoutID = setTimeout(registerUpdate, processOutput.timeToUpdate);
|
||||
};
|
||||
|
||||
this.ngZone.runOutsideAngular(registerUpdate);
|
||||
|
||||
// Return teardown function
|
||||
const teardownFunction = () => {
|
||||
if (timeoutID) {
|
||||
clearTimeout(timeoutID);
|
||||
}
|
||||
};
|
||||
return teardownFunction;
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue