ffmpeg only accepts -version (single dash); it exits 8 on --version and writes to stderr, so the status panel reported it missing even when installed. Version flags are now per-tool and both streams are read. The player used max-h-full inside a grid, which a 1080x1920 Short overflowed. Switched to absolute fill with object-contain so portrait and landscape both letterbox correctly. Also sized the window to 1180x780 centered, which fits a laptop display.
55 lines
2.0 KiB
TypeScript
55 lines
2.0 KiB
TypeScript
import { fileUrl } from "../api";
|
|
import type { FeedItem } from "../types";
|
|
import { compactViews, relativeTime } from "./format";
|
|
|
|
interface Props {
|
|
item: FeedItem;
|
|
path: string;
|
|
onClose: () => void;
|
|
onDelete: () => void;
|
|
}
|
|
|
|
/**
|
|
* Plays the local file through Tauri's asset protocol. Every download is
|
|
* H.264/AAC in MP4 precisely so WKWebView can decode it natively.
|
|
*/
|
|
export default function Player({ item, path, onClose, onDelete }: Props) {
|
|
return (
|
|
<div className="fixed inset-0 z-50 bg-ink/97 flex flex-col">
|
|
<div className="flex items-center gap-3 px-5 py-3 border-b border-edge">
|
|
<button onClick={onClose}
|
|
className="rounded-full px-3 py-1.5 text-xs font-medium bg-surface hover:bg-raised cursor-pointer">
|
|
← Back
|
|
</button>
|
|
<span className="text-sm text-muted truncate flex-1">{item.channel_title}</span>
|
|
<button onClick={onDelete}
|
|
className="rounded-full px-3 py-1.5 text-xs font-medium bg-surface text-muted
|
|
hover:bg-red-500/20 hover:text-red-300 cursor-pointer">
|
|
Delete download
|
|
</button>
|
|
</div>
|
|
|
|
{/* Absolute fill + object-contain, so portrait Shorts and landscape
|
|
videos are both letterboxed to the pane instead of overflowing it. */}
|
|
<div className="flex-1 min-h-0 bg-black relative">
|
|
<video key={path} src={fileUrl(path)} controls autoPlay
|
|
className="absolute inset-0 h-full w-full object-contain" />
|
|
</div>
|
|
|
|
<div className="px-5 py-4 max-h-56 overflow-y-auto border-t border-edge">
|
|
<h2 className="font-semibold text-lg leading-snug">{item.title}</h2>
|
|
<div className="mt-1 text-xs text-muted">
|
|
{[compactViews(item.views), relativeTime(item.published)]
|
|
.filter(Boolean)
|
|
.join(" · ")}
|
|
</div>
|
|
{item.description && (
|
|
<p className="mt-3 text-sm text-muted whitespace-pre-wrap leading-relaxed">
|
|
{item.description}
|
|
</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|