chore: update Angular cache and TypeScript build info

This commit is contained in:
2025-09-23 21:45:57 -04:00
parent d372b7d509
commit 9a3983a253
18 changed files with 664 additions and 169 deletions
@@ -1,8 +1,8 @@
<a [routerLink]="['/watch', video.id]" [queryParams]="buildQueryParams(video)" [state]="{ video }" class="group flex flex-col gap-2">
<div class="relative aspect-video w-full overflow-hidden rounded-lg bg-zinc-800">
<img [src]="video.thumbnailUrl" [alt]="video.title" class="h-full w-full object-cover transition-transform group-hover:scale-105" />
<span *ngIf="video.durationSec" class="absolute bottom-1 right-1 rounded bg-black/80 px-1.5 py-0.5 text-xs text-white">
{{ video.durationSec | date:'mm:ss' }}
<span *ngIf="video.durationSec !== undefined" class="absolute bottom-1 right-1 rounded bg-black/80 px-1.5 py-0.5 text-xs text-white">
{{ video.durationSec | duration }}
</span>
</div>
@@ -2,13 +2,14 @@ import { Component, Input } from '@angular/core';
import { VideoItem } from '../../models/video-item.model';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
import { DurationPipe } from '../../pipes/duration.pipe';
@Component({
selector: 'app-video-card',
templateUrl: './video-card.component.html',
styleUrls: ['./video-card.component.scss'],
standalone: true,
imports: [CommonModule, RouterLink],
imports: [CommonModule, RouterLink, DurationPipe],
})
export class VideoCardComponent {
@Input() video!: VideoItem;
+58
View File
@@ -0,0 +1,58 @@
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'duration',
standalone: true,
})
export class DurationPipe implements PipeTransform {
transform(value: number | string | null | undefined): string {
if (value == null) {
return '0:00';
}
let totalSeconds: number;
if (typeof value === 'number') {
totalSeconds = value;
} else if (typeof value === 'string' && value.trim() !== '') {
const numeric = Number(value);
totalSeconds = Number.isFinite(numeric) ? numeric : this.parseColonDuration(value);
} else {
totalSeconds = 0;
}
if (!Number.isFinite(totalSeconds) || totalSeconds <= 0) {
return '0:00';
}
totalSeconds = Math.round(totalSeconds);
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
if (hours > 0) {
return `${hours}:${this.pad(minutes)}:${this.pad(seconds)}`;
}
return `${minutes}:${this.pad(seconds)}`;
}
private pad(value: number): string {
return value.toString().padStart(2, '0');
}
private parseColonDuration(raw: string): number {
const clean = raw.replace(/[^0-9:]/g, '');
if (!clean.includes(':')) {
return 0;
}
const parts = clean.split(':').filter(Boolean).map(part => Number(part));
if (parts.some(part => !Number.isFinite(part))) {
return 0;
}
while (parts.length < 3) {
parts.unshift(0);
}
const [hours, minutes, seconds] = parts.slice(-3);
return (hours * 3600) + (minutes * 60) + seconds;
}
}