better time pipe
This commit is contained in:
parent
b876728dbe
commit
7cb5b3f226
|
@ -41,6 +41,7 @@ import { HashtagComponent } from './components/stream/hashtag/hashtag.component'
|
||||||
import { StreamOverlayComponent } from './components/stream/stream-overlay/stream-overlay.component';
|
import { StreamOverlayComponent } from './components/stream/stream-overlay/stream-overlay.component';
|
||||||
import { DatabindedTextComponent } from './components/stream/status/databinded-text/databinded-text.component';
|
import { DatabindedTextComponent } from './components/stream/status/databinded-text/databinded-text.component';
|
||||||
import { MastodonTimePipe } from './pipes/mastodon-time.pipe';
|
import { MastodonTimePipe } from './pipes/mastodon-time.pipe';
|
||||||
|
import { TimeAgoPipe } from './pipes/time-ago.pipe';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: "", redirectTo: "home", pathMatch: "full" },
|
{ path: "", redirectTo: "home", pathMatch: "full" },
|
||||||
|
@ -74,7 +75,8 @@ const routes: Routes = [
|
||||||
HashtagComponent,
|
HashtagComponent,
|
||||||
StreamOverlayComponent,
|
StreamOverlayComponent,
|
||||||
DatabindedTextComponent,
|
DatabindedTextComponent,
|
||||||
MastodonTimePipe
|
MastodonTimePipe,
|
||||||
|
TimeAgoPipe
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<div class="status__created-at" title="{{ displayedStatus.created_at | date: 'full' }}">{{
|
<div class="status__created-at" title="{{ displayedStatus.created_at | date: 'full' }}">{{
|
||||||
status.created_at | mastodontime }}</div>
|
status.created_at | timeAgo | async }}</div>
|
||||||
<!-- <div #content class="status__content" innerHTML="{{displayedStatus.content}}"></div> -->
|
<!-- <div #content class="status__content" innerHTML="{{displayedStatus.content}}"></div> -->
|
||||||
|
|
||||||
<app-databinded-text class="status__content" [text]="displayedStatus.content" (accountSelected)="accountSelected($event)" (hashtagSelected)="hashtagSelected($event)" (textSelected)="textSelected()"></app-databinded-text>
|
<app-databinded-text class="status__content" [text]="displayedStatus.content" (accountSelected)="accountSelected($event)" (hashtagSelected)="hashtagSelected($event)" (textSelected)="textSelected()"></app-databinded-text>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { TimeAgoPipe } from './time-ago.pipe';
|
||||||
|
|
||||||
|
describe('TimeAgoPipe', () => {
|
||||||
|
it('create an instance', () => {
|
||||||
|
const pipe = new TimeAgoPipe();
|
||||||
|
expect(pipe).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,104 @@
|
||||||
|
//https://github.com/AndrewPoyntz/time-ago-pipe/issues/6#issuecomment-313726956
|
||||||
|
|
||||||
|
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: 'timeAgo',
|
||||||
|
pure: true
|
||||||
|
})
|
||||||
|
export class TimeAgoPipe 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 timeAgo: number = now.getTime() - timestamp;
|
||||||
|
|
||||||
|
const seconds = timeAgo / 1000;
|
||||||
|
const minutes = seconds / 60;
|
||||||
|
const hours = minutes / 60;
|
||||||
|
const days = hours / 24;
|
||||||
|
// const months = days / 30.416;
|
||||||
|
// const years = days / 365;
|
||||||
|
|
||||||
|
if (seconds <= 60) {
|
||||||
|
text = Math.round(seconds) + 's';
|
||||||
|
} else if (minutes <= 90) {
|
||||||
|
text = Math.round(minutes) + 'm';
|
||||||
|
} else if (hours <= 24) {
|
||||||
|
text = Math.round(hours) + 'h';
|
||||||
|
} else {
|
||||||
|
text = Math.round(days) + 'd';
|
||||||
|
}
|
||||||
|
|
||||||
|
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