perf: Add ram metric
This commit is contained in:
@@ -335,9 +335,7 @@
|
||||
></textarea>
|
||||
|
||||
@if (dragActive()) {
|
||||
<div
|
||||
class="pointer-events-none absolute inset-0 flex items-center justify-center border-2 border-dashed border-primary bg-primary/5"
|
||||
>
|
||||
<div class="pointer-events-none absolute inset-0 flex items-center justify-center border-2 border-dashed border-primary bg-primary/5">
|
||||
<div class="text-sm text-muted-foreground">Drop files to attach</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -198,7 +198,9 @@
|
||||
name="lucideImage"
|
||||
class="h-5 w-5 text-primary"
|
||||
/>
|
||||
<span class="chat-image-grid-loading-label">{{ ((gridImage.receivedBytes || 0) * 100) / gridImage.size | number: '1.0-0' }}%</span>
|
||||
<span class="chat-image-grid-loading-label"
|
||||
>{{ ((gridImage.receivedBytes || 0) * 100) / gridImage.size | number: '1.0-0' }}%</span
|
||||
>
|
||||
</div>
|
||||
} @else {
|
||||
<div class="chat-image-grid-cell chat-image-grid-loading">
|
||||
@@ -231,216 +233,249 @@
|
||||
}
|
||||
@for (att of attachmentsList; track att.id) {
|
||||
@if (shouldShowAttachmentInList(att)) {
|
||||
@if (isImageLikeAttachment(att) && !imageGridLayout().useGrid) {
|
||||
@if (att.available && att.objectUrl) {
|
||||
<div
|
||||
class="group/img relative inline-block"
|
||||
(contextmenu)="openImageContextMenu($event, att)"
|
||||
>
|
||||
<img
|
||||
[src]="att.objectUrl"
|
||||
[alt]="att.filename"
|
||||
class="max-h-80 w-auto cursor-pointer rounded-md"
|
||||
(click)="openLightbox(att)"
|
||||
/>
|
||||
<div class="pointer-events-none absolute inset-0 rounded-md bg-black/0 transition-colors group-hover/img:bg-black/20"></div>
|
||||
<div class="absolute right-2 top-2 flex gap-1 opacity-0 transition-opacity group-hover/img:opacity-100">
|
||||
<button
|
||||
(click)="openLightbox(att); $event.stopPropagation()"
|
||||
class="grid h-7 w-7 place-items-center rounded-md bg-black/60 text-white backdrop-blur-sm transition-colors hover:bg-black/80"
|
||||
title="View full size"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideExpand"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
(click)="downloadAttachment(att); $event.stopPropagation()"
|
||||
class="grid h-7 w-7 place-items-center rounded-md bg-black/60 text-white backdrop-blur-sm transition-colors hover:bg-black/80"
|
||||
title="Download"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideDownload"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
} @else if ((att.receivedBytes || 0) > 0) {
|
||||
<div
|
||||
appThemeNode="chatAttachmentCard"
|
||||
class="max-w-xs rounded-md border border-border bg-secondary/40 p-3"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-md bg-primary/10">
|
||||
<ng-icon
|
||||
name="lucideImage"
|
||||
class="h-5 w-5 text-primary"
|
||||
/>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="truncate text-sm font-medium">{{ att.filename }}</div>
|
||||
<div class="text-xs text-muted-foreground">{{ formatBytes(att.receivedBytes || 0) }} / {{ formatBytes(att.size) }}</div>
|
||||
</div>
|
||||
<div class="text-xs font-medium text-primary">{{ ((att.receivedBytes || 0) * 100) / att.size | number: '1.0-0' }}%</div>
|
||||
</div>
|
||||
<div class="mt-2 h-1.5 overflow-hidden rounded-full bg-muted">
|
||||
<div
|
||||
class="h-full rounded-full bg-primary transition-all duration-300"
|
||||
[style.width.%]="((att.receivedBytes || 0) * 100) / att.size"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
} @else {
|
||||
<div
|
||||
appThemeNode="chatAttachmentCard"
|
||||
class="max-w-xs rounded-md border border-dashed border-border bg-secondary/20 p-4"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-md bg-muted">
|
||||
<ng-icon
|
||||
name="lucideImage"
|
||||
class="h-5 w-5 text-muted-foreground"
|
||||
/>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="truncate text-sm font-medium text-foreground">{{ att.filename }}</div>
|
||||
<div class="text-xs text-muted-foreground">{{ formatBytes(att.size) }}</div>
|
||||
<div
|
||||
class="mt-0.5 text-xs"
|
||||
[class.italic]="!att.requestError"
|
||||
[class.opacity-70]="!att.requestError"
|
||||
[class.text-destructive]="!!att.requestError"
|
||||
[class.text-muted-foreground]="!att.requestError"
|
||||
>
|
||||
{{ att.requestError || 'Waiting for image source...' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
(click)="retryImageRequest(att)"
|
||||
class="mt-2 w-full rounded-md bg-secondary px-3 py-1.5 text-xs text-foreground transition-colors hover:bg-secondary/80"
|
||||
@if (isImageLikeAttachment(att) && !imageGridLayout().useGrid) {
|
||||
@if (att.available && att.objectUrl) {
|
||||
<div
|
||||
class="group/img relative inline-block"
|
||||
(contextmenu)="openImageContextMenu($event, att)"
|
||||
>
|
||||
Retry
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
} @else if (att.isVideo || att.isAudio) {
|
||||
@if (att.available && att.objectUrl) {
|
||||
@if (att.isVideo) {
|
||||
<app-chat-video-player
|
||||
[src]="att.objectUrl"
|
||||
[filename]="att.filename"
|
||||
[sizeLabel]="formatBytes(att.size)"
|
||||
(downloadRequested)="downloadAttachment(att)"
|
||||
/>
|
||||
} @else {
|
||||
<app-chat-audio-player
|
||||
[src]="att.objectUrl"
|
||||
[filename]="att.filename"
|
||||
[sizeLabel]="formatBytes(att.size)"
|
||||
(downloadRequested)="downloadAttachment(att)"
|
||||
/>
|
||||
}
|
||||
} @else if ((att.receivedBytes || 0) > 0) {
|
||||
<div
|
||||
appThemeNode="chatAttachmentCard"
|
||||
class="max-w-xl rounded-md border border-border bg-secondary/40 p-3"
|
||||
>
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="truncate text-sm font-medium">{{ att.filename }}</div>
|
||||
<div class="text-xs text-muted-foreground">{{ formatBytes(att.receivedBytes || 0) }} / {{ formatBytes(att.size) }}</div>
|
||||
</div>
|
||||
<button
|
||||
class="rounded bg-destructive px-2 py-1 text-xs text-destructive-foreground"
|
||||
(click)="cancelAttachment(att)"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-2 h-1.5 overflow-hidden rounded-full bg-muted">
|
||||
<div
|
||||
class="h-full rounded-full bg-primary transition-all duration-300"
|
||||
[style.width.%]="att.progressPercent"
|
||||
></div>
|
||||
</div>
|
||||
<div class="mt-2 flex items-center justify-between text-xs text-muted-foreground">
|
||||
<span>{{ att.progressPercent | number: '1.0-0' }}%</span>
|
||||
@if (att.speedBps) {
|
||||
<span>{{ formatSpeed(att.speedBps) }}</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
} @else {
|
||||
<div
|
||||
appThemeNode="chatAttachmentCard"
|
||||
class="max-w-xl rounded-md border border-dashed border-border bg-secondary/20 p-4"
|
||||
>
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="truncate text-sm font-medium text-foreground">{{ att.filename }}</div>
|
||||
<div class="text-xs text-muted-foreground">{{ formatBytes(att.size) }}</div>
|
||||
<div
|
||||
class="mt-1 text-xs leading-relaxed"
|
||||
[class.opacity-80]="!att.requestError"
|
||||
[class.text-destructive]="!!att.requestError"
|
||||
[class.text-muted-foreground]="!att.requestError"
|
||||
<img
|
||||
[src]="att.objectUrl"
|
||||
[alt]="att.filename"
|
||||
class="max-h-80 w-auto cursor-pointer rounded-md"
|
||||
(click)="openLightbox(att)"
|
||||
/>
|
||||
<div class="pointer-events-none absolute inset-0 rounded-md bg-black/0 transition-colors group-hover/img:bg-black/20"></div>
|
||||
<div class="absolute right-2 top-2 flex gap-1 opacity-0 transition-opacity group-hover/img:opacity-100">
|
||||
<button
|
||||
(click)="openLightbox(att); $event.stopPropagation()"
|
||||
class="grid h-7 w-7 place-items-center rounded-md bg-black/60 text-white backdrop-blur-sm transition-colors hover:bg-black/80"
|
||||
title="View full size"
|
||||
>
|
||||
{{ att.mediaStatusText }}
|
||||
<ng-icon
|
||||
name="lucideExpand"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
(click)="downloadAttachment(att); $event.stopPropagation()"
|
||||
class="grid h-7 w-7 place-items-center rounded-md bg-black/60 text-white backdrop-blur-sm transition-colors hover:bg-black/80"
|
||||
title="Download"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideDownload"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
} @else if ((att.receivedBytes || 0) > 0) {
|
||||
<div
|
||||
appThemeNode="chatAttachmentCard"
|
||||
class="max-w-xs rounded-md border border-border bg-secondary/40 p-3"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-md bg-primary/10">
|
||||
<ng-icon
|
||||
name="lucideImage"
|
||||
class="h-5 w-5 text-primary"
|
||||
/>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="truncate text-sm font-medium">{{ att.filename }}</div>
|
||||
<div class="text-xs text-muted-foreground">{{ formatBytes(att.receivedBytes || 0) }} / {{ formatBytes(att.size) }}</div>
|
||||
</div>
|
||||
<div class="text-xs font-medium text-primary">{{ ((att.receivedBytes || 0) * 100) / att.size | number: '1.0-0' }}%</div>
|
||||
</div>
|
||||
<div class="mt-2 h-1.5 overflow-hidden rounded-full bg-muted">
|
||||
<div
|
||||
class="h-full rounded-full bg-primary transition-all duration-300"
|
||||
[style.width.%]="((att.receivedBytes || 0) * 100) / att.size"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
} @else {
|
||||
<div
|
||||
appThemeNode="chatAttachmentCard"
|
||||
class="max-w-xs rounded-md border border-dashed border-border bg-secondary/20 p-4"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-md bg-muted">
|
||||
<ng-icon
|
||||
name="lucideImage"
|
||||
class="h-5 w-5 text-muted-foreground"
|
||||
/>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="truncate text-sm font-medium text-foreground">{{ att.filename }}</div>
|
||||
<div class="text-xs text-muted-foreground">{{ formatBytes(att.size) }}</div>
|
||||
<div
|
||||
class="mt-0.5 text-xs"
|
||||
[class.italic]="!att.requestError"
|
||||
[class.opacity-70]="!att.requestError"
|
||||
[class.text-destructive]="!!att.requestError"
|
||||
[class.text-muted-foreground]="!att.requestError"
|
||||
>
|
||||
{{ att.requestError || 'Waiting for image source...' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
(click)="requestAttachment(att)"
|
||||
class="shrink-0 rounded-md bg-secondary px-3 py-1.5 text-xs text-foreground transition-colors hover:bg-secondary/80"
|
||||
(click)="retryImageRequest(att)"
|
||||
class="mt-2 w-full rounded-md bg-secondary px-3 py-1.5 text-xs text-foreground transition-colors hover:bg-secondary/80"
|
||||
>
|
||||
{{ att.mediaActionLabel }}
|
||||
Retry
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
} @else {
|
||||
<div
|
||||
appThemeNode="chatAttachmentCard"
|
||||
class="rounded-md border border-border bg-secondary/40 p-2"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="min-w-0">
|
||||
<div class="truncate text-sm font-medium">{{ att.filename }}</div>
|
||||
<div class="text-xs text-muted-foreground">{{ formatBytes(att.size) }}</div>
|
||||
}
|
||||
} @else if (att.isVideo || att.isAudio) {
|
||||
@if (att.available && att.objectUrl) {
|
||||
@if (att.isVideo) {
|
||||
<app-chat-video-player
|
||||
[src]="att.objectUrl"
|
||||
[filename]="att.filename"
|
||||
[sizeLabel]="formatBytes(att.size)"
|
||||
(downloadRequested)="downloadAttachment(att)"
|
||||
/>
|
||||
} @else {
|
||||
<app-chat-audio-player
|
||||
[src]="att.objectUrl"
|
||||
[filename]="att.filename"
|
||||
[sizeLabel]="formatBytes(att.size)"
|
||||
(downloadRequested)="downloadAttachment(att)"
|
||||
/>
|
||||
}
|
||||
} @else if ((att.receivedBytes || 0) > 0) {
|
||||
<div
|
||||
appThemeNode="chatAttachmentCard"
|
||||
class="max-w-xl rounded-md border border-border bg-secondary/40 p-3"
|
||||
>
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="truncate text-sm font-medium">{{ att.filename }}</div>
|
||||
<div class="text-xs text-muted-foreground">{{ formatBytes(att.receivedBytes || 0) }} / {{ formatBytes(att.size) }}</div>
|
||||
</div>
|
||||
<button
|
||||
class="rounded bg-destructive px-2 py-1 text-xs text-destructive-foreground"
|
||||
(click)="cancelAttachment(att)"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-2 h-1.5 overflow-hidden rounded-full bg-muted">
|
||||
<div
|
||||
class="h-full rounded-full bg-primary transition-all duration-300"
|
||||
[style.width.%]="att.progressPercent"
|
||||
></div>
|
||||
</div>
|
||||
<div class="mt-2 flex items-center justify-between text-xs text-muted-foreground">
|
||||
<span>{{ att.progressPercent | number: '1.0-0' }}%</span>
|
||||
@if (att.speedBps) {
|
||||
<span>{{ formatSpeed(att.speedBps) }}</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
@if (!att.isUploader) {
|
||||
@if (!att.available) {
|
||||
<div class="h-1.5 w-24 rounded bg-muted">
|
||||
<div
|
||||
class="h-1.5 rounded bg-primary"
|
||||
[style.width.%]="att.progressPercent"
|
||||
></div>
|
||||
} @else {
|
||||
<div
|
||||
appThemeNode="chatAttachmentCard"
|
||||
class="max-w-xl rounded-md border border-dashed border-border bg-secondary/20 p-4"
|
||||
>
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="truncate text-sm font-medium text-foreground">{{ att.filename }}</div>
|
||||
<div class="text-xs text-muted-foreground">{{ formatBytes(att.size) }}</div>
|
||||
<div
|
||||
class="mt-1 text-xs leading-relaxed"
|
||||
[class.opacity-80]="!att.requestError"
|
||||
[class.text-destructive]="!!att.requestError"
|
||||
[class.text-muted-foreground]="!att.requestError"
|
||||
>
|
||||
{{ att.mediaStatusText }}
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-xs text-muted-foreground">
|
||||
<span>{{ att.progressPercent | number: '1.0-0' }}%</span>
|
||||
@if (att.speedBps) {
|
||||
<span>• {{ formatSpeed(att.speedBps) }}</span>
|
||||
</div>
|
||||
<button
|
||||
(click)="requestAttachment(att)"
|
||||
class="shrink-0 rounded-md bg-secondary px-3 py-1.5 text-xs text-foreground transition-colors hover:bg-secondary/80"
|
||||
>
|
||||
{{ att.mediaActionLabel }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
} @else {
|
||||
<div
|
||||
appThemeNode="chatAttachmentCard"
|
||||
class="rounded-md border border-border bg-secondary/40 p-2"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="min-w-0">
|
||||
<div class="truncate text-sm font-medium">{{ att.filename }}</div>
|
||||
<div class="text-xs text-muted-foreground">{{ formatBytes(att.size) }}</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
@if (!att.isUploader) {
|
||||
@if (!att.available) {
|
||||
<div class="h-1.5 w-24 rounded bg-muted">
|
||||
<div
|
||||
class="h-1.5 rounded bg-primary"
|
||||
[style.width.%]="att.progressPercent"
|
||||
></div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-xs text-muted-foreground">
|
||||
<span>{{ att.progressPercent | number: '1.0-0' }}%</span>
|
||||
@if (att.speedBps) {
|
||||
<span>• {{ formatSpeed(att.speedBps) }}</span>
|
||||
}
|
||||
</div>
|
||||
@if (!(att.receivedBytes || 0)) {
|
||||
<button
|
||||
class="rounded bg-secondary px-2 py-1 text-xs text-foreground"
|
||||
(click)="requestAttachment(att)"
|
||||
>
|
||||
{{ att.requestError ? 'Retry' : 'Request' }}
|
||||
</button>
|
||||
} @else {
|
||||
<button
|
||||
class="rounded bg-destructive px-2 py-1 text-xs text-destructive-foreground"
|
||||
(click)="cancelAttachment(att)"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
@if (!(att.receivedBytes || 0)) {
|
||||
<button
|
||||
class="rounded bg-secondary px-2 py-1 text-xs text-foreground"
|
||||
(click)="requestAttachment(att)"
|
||||
>
|
||||
{{ att.requestError ? 'Retry' : 'Request' }}
|
||||
</button>
|
||||
} @else {
|
||||
@if (att.canOpenExternally) {
|
||||
<button
|
||||
class="inline-flex items-center gap-1.5 rounded bg-secondary px-2 py-1 text-xs text-foreground transition-colors hover:bg-secondary/80"
|
||||
(click)="openAttachmentExternally(att)"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideExternalLink"
|
||||
class="h-3.5 w-3.5"
|
||||
/>
|
||||
Open
|
||||
</button>
|
||||
}
|
||||
@if (att.canUseExperimentalPlayer) {
|
||||
<button
|
||||
class="inline-flex items-center gap-1.5 rounded bg-secondary px-2 py-1 text-xs text-foreground transition-colors hover:bg-secondary/80"
|
||||
(click)="openExperimentalPlayer(att)"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucidePlay"
|
||||
class="h-3.5 w-3.5"
|
||||
/>
|
||||
Play
|
||||
</button>
|
||||
}
|
||||
<button
|
||||
class="rounded bg-destructive px-2 py-1 text-xs text-destructive-foreground"
|
||||
(click)="cancelAttachment(att)"
|
||||
class="rounded bg-primary px-2 py-1 text-xs text-primary-foreground"
|
||||
(click)="downloadAttachment(att)"
|
||||
>
|
||||
Cancel
|
||||
Download
|
||||
</button>
|
||||
}
|
||||
} @else {
|
||||
<div class="text-xs text-muted-foreground">Shared from your device</div>
|
||||
@if (att.canOpenExternally) {
|
||||
<button
|
||||
class="inline-flex items-center gap-1.5 rounded bg-secondary px-2 py-1 text-xs text-foreground transition-colors hover:bg-secondary/80"
|
||||
@@ -465,68 +500,35 @@
|
||||
Play
|
||||
</button>
|
||||
}
|
||||
<button
|
||||
class="rounded bg-primary px-2 py-1 text-xs text-primary-foreground"
|
||||
(click)="downloadAttachment(att)"
|
||||
>
|
||||
Download
|
||||
</button>
|
||||
}
|
||||
} @else {
|
||||
<div class="text-xs text-muted-foreground">Shared from your device</div>
|
||||
@if (att.canOpenExternally) {
|
||||
<button
|
||||
class="inline-flex items-center gap-1.5 rounded bg-secondary px-2 py-1 text-xs text-foreground transition-colors hover:bg-secondary/80"
|
||||
(click)="openAttachmentExternally(att)"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideExternalLink"
|
||||
class="h-3.5 w-3.5"
|
||||
/>
|
||||
Open
|
||||
</button>
|
||||
}
|
||||
@if (att.canUseExperimentalPlayer) {
|
||||
<button
|
||||
class="inline-flex items-center gap-1.5 rounded bg-secondary px-2 py-1 text-xs text-foreground transition-colors hover:bg-secondary/80"
|
||||
(click)="openExperimentalPlayer(att)"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucidePlay"
|
||||
class="h-3.5 w-3.5"
|
||||
/>
|
||||
Play
|
||||
</button>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@if (!att.available && att.requestError) {
|
||||
<div
|
||||
class="mt-2 w-full rounded-md border border-destructive/20 bg-destructive/5 px-2.5 py-1.5 text-xs leading-relaxed text-destructive"
|
||||
>
|
||||
{{ att.requestError }}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@if (!att.available && att.requestError) {
|
||||
<div
|
||||
class="mt-2 w-full rounded-md border border-destructive/20 bg-destructive/5 px-2.5 py-1.5 text-xs leading-relaxed text-destructive"
|
||||
>
|
||||
{{ att.requestError }}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@if (att.experimentalPlayerActive && att.objectUrl) {
|
||||
@defer {
|
||||
<app-experimental-vlc-player
|
||||
[src]="att.objectUrl"
|
||||
[filename]="att.filename"
|
||||
[mime]="att.mime"
|
||||
[sizeLabel]="formatBytes(att.size)"
|
||||
(closed)="closeExperimentalPlayer()"
|
||||
(downloadRequested)="downloadAttachment(att)"
|
||||
/>
|
||||
} @loading {
|
||||
<div class="mt-2 max-w-xl rounded-md border border-border bg-secondary/20 p-3 text-xs text-muted-foreground">
|
||||
Loading experimental player...
|
||||
</div>
|
||||
@if (att.experimentalPlayerActive && att.objectUrl) {
|
||||
@defer {
|
||||
<app-experimental-vlc-player
|
||||
[src]="att.objectUrl"
|
||||
[filename]="att.filename"
|
||||
[mime]="att.mime"
|
||||
[sizeLabel]="formatBytes(att.size)"
|
||||
(closed)="closeExperimentalPlayer()"
|
||||
(downloadRequested)="downloadAttachment(att)"
|
||||
/>
|
||||
} @loading {
|
||||
<div class="mt-2 max-w-xl rounded-md border border-border bg-secondary/20 p-3 text-xs text-muted-foreground">
|
||||
Loading experimental player...
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user