fix: clean file info cards for non-native video/media formats on tool page

Instead of showing a broken video player error for formats like AVI,
MKV, WMV that browsers can't play, show a clean file info card with
icon, filename, format, and size. Message says "Preview will be
available after processing" which is accurate -- the processed output
is typically in a browser-friendly format.

Also cleaned up the post-processing non-previewable card to match
the same visual style.
This commit is contained in:
SnapOtter
2026-06-15 11:57:27 +08:00
parent ed458d4bbd
commit 511e941da0
22 changed files with 65 additions and 25 deletions
+44 -25
View File
@@ -10,6 +10,7 @@ import {
FileImage,
Loader2,
Upload,
Video,
XCircle,
} from "lucide-react";
import { lazy, Suspense, useCallback, useEffect, useMemo, useRef, useState } from "react";
@@ -659,6 +660,31 @@ export function ToolPage() {
);
}
}
// Check if the current file is browser-playable
const currentFileName = hasProcessed
? (currentEntry?.processedFilename ?? "")
: (currentEntry?.file?.name ?? "");
const currentExt = currentFileName.split(".").pop()?.toLowerCase() ?? "";
const nativeVideoExts = new Set(["mp4", "webm", "ogg", "ogv", "m4v", "mov"]);
const isNativeVideo = nativeVideoExts.has(currentExt);
if (!isNativeVideo && currentExt) {
return (
<div className="flex-1 flex items-center justify-center">
<div className="text-center p-8 max-w-xs">
<div className="mx-auto w-16 h-16 rounded-2xl bg-muted flex items-center justify-center mb-4">
<Video className="h-8 w-8 text-muted-foreground" />
</div>
<p className="font-medium text-foreground mb-1">{currentFileName}</p>
<p className="text-sm text-muted-foreground mb-1">
{currentExt.toUpperCase()} &middot;{" "}
{currentEntry?.file ? formatFileSize(currentEntry.file.size) : ""}
</p>
<p className="text-xs text-muted-foreground/60">{t.toolPage.previewUnavailable}</p>
</div>
</div>
);
}
return (
<Suspense fallback={<div className="text-sm text-muted-foreground">Loading...</div>}>
<MediaPlayerView />
@@ -790,23 +816,19 @@ export function ToolPage() {
// Non-previewable format with no fallback at all - show success card
if (hasProcessed && !isProcessedPreviewable && !processedPreviewUrl && !originalBlobUrl) {
return (
<div className="flex flex-col items-center justify-center h-full gap-4 text-center p-8">
<div className="w-16 h-16 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center">
<CheckCircle2 className="h-8 w-8 text-green-600 dark:text-green-400" />
</div>
<div>
<p className="text-sm font-medium">{t.toolPage.conversionComplete}</p>
<p className="text-xs text-muted-foreground mt-1">{processedFileName}</p>
<div className="flex-1 flex items-center justify-center">
<div className="text-center p-8 max-w-xs">
<div className="mx-auto w-16 h-16 rounded-2xl bg-emerald-50 dark:bg-emerald-950/30 flex items-center justify-center mb-4">
<CheckCircle2 className="h-8 w-8 text-emerald-600 dark:text-emerald-400" />
</div>
<p className="font-medium text-foreground mb-1">{t.toolPage.conversionComplete}</p>
<p className="text-sm text-muted-foreground mb-1">{processedFileName}</p>
{processedSize != null && (
<p className="text-xs text-muted-foreground">
{formatFileSize(processedSize)} · {processedFileType}
<p className="text-xs text-muted-foreground/60">
{processedFileType} &middot; {formatFileSize(processedSize)}
</p>
)}
</div>
<p className="text-xs text-muted-foreground max-w-xs">
{processedFileType} files cannot be previewed in the browser. Use the download button to
save your file.
</p>
</div>
);
}
@@ -880,20 +902,17 @@ export function ToolPage() {
if (!canBrowserPreview(originalBlobUrl, fname)) {
const ext = fname.split(".").pop()?.toUpperCase() ?? "";
return (
<div className="flex flex-col items-center justify-center h-full gap-4 text-center p-8">
<div className="w-16 h-16 rounded-full bg-muted flex items-center justify-center">
<FileImage className="h-8 w-8 text-muted-foreground" />
</div>
<div>
<p className="text-sm font-medium truncate max-w-xs">{fname}</p>
<p className="text-xs text-muted-foreground mt-1">
{ext} · {formatFileSize(fsize)}
<div className="flex-1 flex items-center justify-center">
<div className="text-center p-8 max-w-xs">
<div className="mx-auto w-16 h-16 rounded-2xl bg-muted flex items-center justify-center mb-4">
<FileImage className="h-8 w-8 text-muted-foreground" />
</div>
<p className="font-medium text-foreground mb-1">{fname}</p>
<p className="text-sm text-muted-foreground mb-1">
{ext} &middot; {formatFileSize(fsize)}
</p>
<p className="text-xs text-muted-foreground/60">{t.toolPage.previewUnavailable}</p>
</div>
<p className="text-xs text-muted-foreground max-w-xs">
{ext} files cannot be previewed in the browser. The tool will still process this file
normally.
</p>
</div>
);
}
+1
View File
@@ -2453,6 +2453,7 @@ export const ar: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2467,6 +2467,7 @@ export const de: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2417,6 +2417,7 @@ export const en = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2449,6 +2449,7 @@ export const es: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2468,6 +2468,7 @@ export const fr: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2450,6 +2450,7 @@ export const hi: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2462,6 +2462,7 @@ export const id: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2461,6 +2461,7 @@ export const it: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2420,6 +2420,7 @@ export const ja: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2405,6 +2405,7 @@ export const ko: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2464,6 +2464,7 @@ export const nl: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2465,6 +2465,7 @@ export const pl: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2461,6 +2461,7 @@ export const ptBR: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2463,6 +2463,7 @@ export const ru: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2460,6 +2460,7 @@ export const sv: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2442,6 +2442,7 @@ export const th: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2465,6 +2465,7 @@ export const tr: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2463,6 +2463,7 @@ export const uk: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2462,6 +2462,7 @@ export const vi: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2395,6 +2395,7 @@ export const zhCN: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",
+1
View File
@@ -2393,6 +2393,7 @@ export const zhTW: TranslationKeys = {
adjustSettings: "Adjust settings",
startOver: "Start over with a new file",
newFile: "New file",
previewUnavailable: "Preview will be available after processing",
backToTools: "Back to Tools",
original: "Original",
processed: "Processed",