24 lines
1.7 KiB
TypeScript
24 lines
1.7 KiB
TypeScript
"use client";
|
|
import { useRef, useState } from "react";
|
|
import { Download, Loader2 } from "lucide-react";
|
|
import { toast } from "sonner";
|
|
|
|
export function VideoArchiveButton({ url, automaticBusy = false, onSaved }: { url: string; automaticBusy?: boolean; onSaved: (url: string) => void }) {
|
|
const running = useRef(false);
|
|
const [busy, setBusy] = useState(false);
|
|
return <button type="button" disabled={busy || automaticBusy} title="当前视频使用临时链接,转存后可长期保留,无需重新生成" className="flex h-10 items-center gap-2 whitespace-nowrap rounded-lg px-3 text-[15px] text-amber-200 hover:bg-white/10 disabled:opacity-50" onClick={async () => {
|
|
if (running.current) return;
|
|
running.current = true;
|
|
setBusy(true);
|
|
try {
|
|
const response = await fetch("/api/canvas/video/archive", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ url }), signal: AbortSignal.timeout(290_000) });
|
|
const result = await response.json();
|
|
if (!response.ok || !result.success || !result.data?.url) throw new Error(result.error || "视频转存失败");
|
|
onSaved(result.data.url);
|
|
toast.success("视频已转存,画布正在保存新地址");
|
|
} catch (error) {
|
|
toast.error(error instanceof Error && error.name === "TimeoutError" ? "视频保存超时,原视频已保留,请稍后重试" : error instanceof Error ? error.message : "视频转存失败");
|
|
} finally { running.current = false; setBusy(false); }
|
|
}}>{busy || automaticBusy ? <Loader2 className="size-4 animate-spin" /> : <Download className="size-4" />}{busy || automaticBusy ? "正在转存" : "转存视频"}</button>;
|
|
}
|