import { useState, useEffect } from "react"; import { motion } from "framer-motion"; import { TauriService } from "../../services/TauriService"; import type { Edition } from "../../types/edition"; export default function SetUidModal({ isOpen, onClose, playPressSound, playBackSound, instances, installedVersions, targetInstanceId, }: { isOpen: boolean; onClose: () => void; playPressSound: (s?: string) => void; playBackSound: (s?: string) => void; instances: Edition[]; installedVersions: string[]; targetInstanceId: string; }) { const [mode, setMode] = useState<"manual" | "copy">("manual"); const [uid, setUid] = useState("0xFF02F0C87E8AC1F2"); const [selectedInstance, setSelectedInstance] = useState(""); const [isDropdownOpen, setIsDropdownOpen] = useState(false); const [error, setError] = useState(""); const [focusIndex, setFocusIndex] = useState(0); useEffect(() => { if (!isOpen) { setMode("manual"); setUid("0xFF02F0C87E8AC1F2"); setSelectedInstance(""); setError(""); setFocusIndex(0); setIsDropdownOpen(false); } else if (targetInstanceId) { (async () => { try { const targetPath = await TauriService.getInstancePath(targetInstanceId); const data = await TauriService.readBinaryFile(`${targetPath}/uid.dat`); const currentUid = new TextDecoder().decode(data); if (currentUid.trim()) { setUid(currentUid); } else { setUid("0xFF02F0C87E8AC1F2"); } } catch (e) { setUid("0xFF02F0C87E8AC1F2"); } })(); } }, [isOpen, targetInstanceId]); const validInstances = instances.filter((i: Edition) => installedVersions.includes(i.instanceId) && i.instanceId !== targetInstanceId); const handleSave = async () => { playPressSound("save_click.wav"); try { let finalUid = uid; if (mode === "copy") { if (!selectedInstance) { setError("Select an instance to copy from."); return; } const sourcePath = await TauriService.getInstancePath(selectedInstance); try { const sourceData = await TauriService.readBinaryFile(`${sourcePath}/uid.dat`); finalUid = new TextDecoder().decode(sourceData); } catch (e) { setError("Source instance has no uid.dat or it could not be read."); return; } } if (!finalUid) { setError("UID cannot be empty."); return; } const encodedUid = new TextEncoder().encode(finalUid); const targetPath = await TauriService.getInstancePath(targetInstanceId); await TauriService.writeBinaryFile(`${targetPath}/uid.dat`, encodedUid); onClose(); } catch (e: unknown) { setError(e instanceof Error ? e.message : String(e)); } }; useEffect(() => { if (!isOpen) return; const handleKey = (e: KeyboardEvent) => { if (e.key === "Escape") { playBackSound("close_click.wav"); onClose(); } else if (e.key === "ArrowDown" || e.key === "Tab") { e.preventDefault(); setFocusIndex((prev) => (prev + 1) % 5); } else if (e.key === "ArrowUp") { e.preventDefault(); setFocusIndex((prev) => (prev - 1 + 5) % 5); } else if (e.key === "Enter") { if (focusIndex === 0) { playPressSound(); setMode("manual"); } else if (focusIndex === 1) { playPressSound(); setMode("copy"); } else if (focusIndex === 2 && mode === "copy") { playPressSound(); setIsDropdownOpen(!isDropdownOpen); } else if (focusIndex === 3) { playBackSound("close_click.wav"); onClose(); } else if (focusIndex === 4) { handleSave(); } } }; window.addEventListener("keydown", handleKey); return () => window.removeEventListener("keydown", handleKey); }, [isOpen, focusIndex, mode, uid, selectedInstance, isDropdownOpen]); if (!isOpen) return null; return (

Set UID

{mode === "manual" ? (
setUid(e.target.value)} onFocus={() => setFocusIndex(2)} placeholder="0xFF02F0C87E8AC1F2" className={`w-full h-10 px-3 bg-black/40 border-2 ${focusIndex === 2 ? 'border-white' : 'border-[#373737]'} text-white text-base outline-none font-['Mojangles'] text-center`} style={{ imageRendering: "pixelated", filter: focusIndex === 2 ? 'brightness(1.2)' : 'none' }} />
) : (
{ playPressSound(); setIsDropdownOpen(!isDropdownOpen); }} onFocus={() => { setFocusIndex(2); setIsDropdownOpen(false); }} tabIndex={0} className={`w-full h-10 px-3 bg-black/40 border-2 ${focusIndex === 2 ? 'border-white' : 'border-[#373737]'} flex items-center justify-between text-white text-base outline-none font-['Mojangles'] cursor-pointer`} style={{ imageRendering: "pixelated", filter: focusIndex === 2 ? 'brightness(1.2)' : 'none' }} > {selectedInstance ? (() => { const i = validInstances.find((inst: Edition) => inst.instanceId === selectedInstance); return i ? `${i.name} ${i.selectedBranch ? `(${i.selectedBranch})` : ""}` : "-- Select an Instance --"; })() : "-- Select an Instance --"}
{isDropdownOpen && validInstances.length > 0 && (
{validInstances.map((i: Edition) => (
{ playPressSound(); setSelectedInstance(i.instanceId); setIsDropdownOpen(false); }} className="px-3 py-2 text-white text-sm cursor-pointer hover:bg-white/20 transition-colors truncate font-['Mojangles']" > {i.name} {i.selectedBranch ? `(${i.selectedBranch})` : ""}
))}
)} {validInstances.length === 0 && (

No other installed instances available.

)}
)} {error && (
{error}
)}
); }