Skip to content

Commit

Permalink
Refactor date component
Browse files Browse the repository at this point in the history
  • Loading branch information
jvyden committed Aug 29, 2024
1 parent 96d6de2 commit c33ba56
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 54 deletions.
2 changes: 1 addition & 1 deletion src/app/components/items/level-preview.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {LabelComponent} from "../ui/info/label.component";
<app-level-statistics [level]="level" class="text-sm"></app-level-statistics>
<div class="text-gentle text-sm mt-0.5">
<div class="text-gentle text-sm mt-0.5 flex gap-x-1">
by <app-user-link [user]="level.publisher"></app-user-link>
<app-date [date]="level.publishDate"></app-date>
</div>
Expand Down
128 changes: 75 additions & 53 deletions src/app/components/ui/info/date.component.ts
Original file line number Diff line number Diff line change
@@ -1,61 +1,83 @@
import {Component, Input} from '@angular/core';
import {ChangeDetectorRef, Component, inject, Inject, Input, NgZone, OnDestroy, PLATFORM_ID} from '@angular/core';
import {TooltipComponent} from "../text/tooltip.component";
import {isPlatformBrowser} from "@angular/common";

@Component({
selector: 'app-date',
standalone: true,
imports: [
TooltipComponent
],
template: `
<!--
for some stupid fucking reason we need to defer this,
because otherwise this breaks the layout when SSR renders this component
-->
@defer {
<app-tooltip [text]="getFormattedDate()" class>
{{ getMoment() }}
</app-tooltip>
} @placeholder {
<span>{{ recentText }}</span>
}
`
selector: 'app-date',
standalone: true,
imports: [
TooltipComponent
],
template: `
<app-tooltip [text]="formattedDate">{{ moment }}</app-tooltip>
`
})
export class DateComponent {
private _date: Date = new Date();

protected recentText = "just now";

@Input({required: true, alias: "date"})
set date(value: Date) {
this._date = new Date(value);
}

getMoment(): string {
const now = new Date();
const seconds = Math.floor((now.getTime() - this._date.getTime()) / 1000);

const intervals: { [key: string]: number } = {
year: 31536000,
month: 2592000,
week: 604800,
day: 86400,
hour: 3600,
minute: 60,
second: 1,
};

for (const interval in intervals) {
const time = Math.floor(seconds / intervals[interval]);
if (time >= 1) {
return `${time} ${interval}${time > 1 ? 's' : ''} ago`;
}
export class DateComponent implements OnDestroy {
private _date: Date = new Date();
private intervalId: any;

constructor(@Inject(PLATFORM_ID) private platformId: string, private changeDetector: ChangeDetectorRef) {
if (!this.isBrowser) return;

inject(NgZone).runOutsideAngular(() => {
this.intervalId = setInterval(() => {
// console.log("tick", this.intervalId)
this.changeDetector.detectChanges();
}, 1000);
})
}

get isBrowser(): boolean {
return isPlatformBrowser(this.platformId);
}

protected recentText = "just now";

// this setter is actually required to be here; this is not a hold-over from the old site
// for some reason, javascript's date parser doesn't create a full Date object.
// so we need to do this horse-shit.
@Input({required: true, alias: "date"})
set date(value: Date) {
this._date = new Date(value);
}

return this.recentText;
}
get moment(): string {
const now = new Date();
const totalSeconds = Math.floor((now.getTime() - this._date.getTime()) / 1000);

getFormattedDate(): string {
return `${this._date.toLocaleDateString()} @ ${this._date.toLocaleTimeString()}`;
}
const intervals: { [key: string]: number } = {
year: 31536000,
month: 2592000,
week: 604800,
day: 86400,
hour: 3600,
minute: 60,
second: 1,
};

if (totalSeconds < 20)
return this.recentText;

for (const interval in intervals) {
const time = Math.floor(totalSeconds / intervals[interval]);
if (time > 1) {
return `${time} ${interval}s ago`;
} else if (time == 1) {
return `a${interval == "hour" ? 'n' : ''} ${interval} ago`;
}
}

return this.recentText;
}

get formattedDate(): string {
return `${this._date.toLocaleDateString()} @ ${this._date.toLocaleTimeString()}`;
}

ngOnDestroy() {
if (this.intervalId) {
// console.log("unsubscribe", this.intervalId)
clearInterval(this.intervalId);
}
}
}

0 comments on commit c33ba56

Please sign in to comment.