diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 1cb8f4ab..0995eaa6 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -41,6 +41,7 @@ import { HashtagComponent } from './components/stream/hashtag/hashtag.component'
import { StreamOverlayComponent } from './components/stream/stream-overlay/stream-overlay.component';
import { DatabindedTextComponent } from './components/stream/status/databinded-text/databinded-text.component';
import { MastodonTimePipe } from './pipes/mastodon-time.pipe';
+import { TimeAgoPipe } from './pipes/time-ago.pipe';
const routes: Routes = [
{ path: "", redirectTo: "home", pathMatch: "full" },
@@ -74,7 +75,8 @@ const routes: Routes = [
HashtagComponent,
StreamOverlayComponent,
DatabindedTextComponent,
- MastodonTimePipe
+ MastodonTimePipe,
+ TimeAgoPipe
],
imports: [
BrowserModule,
diff --git a/src/app/components/stream/status/status.component.html b/src/app/components/stream/status/status.component.html
index c3a9e341..9161e98c 100644
--- a/src/app/components/stream/status/status.component.html
+++ b/src/app/components/stream/status/status.component.html
@@ -13,7 +13,7 @@
{{
- status.created_at | mastodontime }}
+ status.created_at | timeAgo | async }}
diff --git a/src/app/pipes/time-ago.pipe.spec.ts b/src/app/pipes/time-ago.pipe.spec.ts
new file mode 100644
index 00000000..c3d7df28
--- /dev/null
+++ b/src/app/pipes/time-ago.pipe.spec.ts
@@ -0,0 +1,8 @@
+import { TimeAgoPipe } from './time-ago.pipe';
+
+describe('TimeAgoPipe', () => {
+ it('create an instance', () => {
+ const pipe = new TimeAgoPipe();
+ expect(pipe).toBeTruthy();
+ });
+});
diff --git a/src/app/pipes/time-ago.pipe.ts b/src/app/pipes/time-ago.pipe.ts
new file mode 100644
index 00000000..bb7f0a9d
--- /dev/null
+++ b/src/app/pipes/time-ago.pipe.ts
@@ -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 => {
+ 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) => {
+ 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;
+ });
+ }
+}
\ No newline at end of file