"use client"; import React from "react"; import { platformAccept } from "@/utils/idb"; import type { Platform } from "@/data/baseRoms"; export default function StickyActionBar({ title, version, author, baseRomName, baseRomPlatform, onPatch, status, error, isLinked, romReady, onClickLink, supported, onUploadChange }: { title: string; version?: string; author: string; baseRomName?: string | null; baseRomPlatform?: Platform; onPatch: () => void; status: "idle" | "ready" | "patching" | "done" | "downloading"; error: string | null; isLinked: boolean; romReady: boolean; onClickLink: () => void; supported: boolean; onUploadChange: (e: React.ChangeEvent) => void; }) { const [mounted, setMounted] = React.useState(false); React.useEffect(() => setMounted(true), []); const uploadInputRef = React.useRef(null); const [errorMessage, setErrorMessage] = React.useState(null); const [showError, setShowError] = React.useState(false); const [patchAgainReady, setPatchAgainReady] = React.useState(true); // Keep error mounted to allow fade-out when error becomes null React.useEffect(() => { let timeoutId: number | undefined; if (error) { setErrorMessage(error); // next frame to ensure transition runs requestAnimationFrame(() => setShowError(true)); } else if (errorMessage !== null) { setShowError(false); timeoutId = window.setTimeout(() => setErrorMessage(null), 300); } else { setShowError(false); } return () => { if (timeoutId) window.clearTimeout(timeoutId); }; }, [error, errorMessage]); React.useEffect(() => { if (status === "done") { setPatchAgainReady(false); setTimeout(() => { setPatchAgainReady(true); }, 3000); } else { setPatchAgainReady(true); } }, [status]); return (
{title}
{version && ( {version} )}
By @{author}
{status === "downloading" ? "Downloading..." : romReady ? "Ready" : isLinked ? "Permission needed" : "Base ROM needed"} {!romReady && !isLinked && ( )} {!romReady && isLinked && ( )}
{errorMessage !== null && (
{errorMessage}
)}
); }