import { useState, useEffect, memo } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { useUI, useAudio, useGame, useConfig } from "../../context/LauncherContext"; import { ScreenshotService, ScreenshotInfo } from "../../services/ScreenshotService"; const ScreenshotsView = memo(function ScreenshotsView() { const { setActiveView } = useUI(); const { playPressSound, playBackSound } = useAudio(); const { editions } = useGame(); const { animationsEnabled } = useConfig(); const [screenshots, setScreenshots] = useState([]); const [selectedScreenshot, setSelectedScreenshot] = useState(null); const [loading, setLoading] = useState(true); const [gridFocusIndex, setGridFocusIndex] = useState(0); const [modalFocusIndex, setModalFocusIndex] = useState(0); const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); const [deleteConfirmFocusIndex, setDeleteConfirmFocusIndex] = useState(0); useEffect(() => { ScreenshotService.getScreenshots().then((data) => { setScreenshots(data); setLoading(false); }); }, []); const handleBack = () => { playBackSound(); setActiveView("main"); }; const handleOpenFolder = (screenshot: ScreenshotInfo) => { playPressSound(); ScreenshotService.showInFolder(screenshot.path); }; const confirmDelete = async () => { if (!selectedScreenshot) return; playPressSound(); await ScreenshotService.deleteScreenshot(selectedScreenshot.path); setScreenshots((prev) => prev.filter((s) => s.path !== selectedScreenshot.path)); setSelectedScreenshot(null); setShowDeleteConfirm(false); }; useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (loading) return; if (showDeleteConfirm) { if (e.key === "Escape" || e.key === "Backspace") { playBackSound(); setShowDeleteConfirm(false); } else if (e.key === "ArrowLeft" || e.key === "ArrowRight" || e.key === "Tab") { e.preventDefault(); playPressSound(); setDeleteConfirmFocusIndex((prev) => (prev === 0 ? 1 : 0)); } else if (e.key === "Enter") { if (deleteConfirmFocusIndex === 1) confirmDelete(); else { playBackSound(); setShowDeleteConfirm(false); } } return; } if (selectedScreenshot) { if (e.key === "Escape" || e.key === "Backspace") { playBackSound(); setSelectedScreenshot(null); } else if (e.key === "ArrowLeft") { playPressSound(); setModalFocusIndex((prev) => (prev > 0 ? prev - 1 : 2)); } else if (e.key === "ArrowRight" || e.key === "Tab") { e.preventDefault(); playPressSound(); setModalFocusIndex((prev) => (prev < 2 ? prev + 1 : 0)); } else if (e.key === "Enter") { if (modalFocusIndex === 0) handleOpenFolder(selectedScreenshot); else if (modalFocusIndex === 1) { playPressSound(); setDeleteConfirmFocusIndex(0); setShowDeleteConfirm(true); } else if (modalFocusIndex === 2) { playBackSound(); setSelectedScreenshot(null); } } return; } const cols = window.innerWidth >= 1024 ? 4 : window.innerWidth >= 768 ? 3 : 2; if (e.key === "Escape" || e.key === "Backspace") { handleBack(); } else if (e.key === "ArrowLeft") { setGridFocusIndex((prev) => (prev > 0 ? prev - 1 : prev)); } else if (e.key === "ArrowRight") { setGridFocusIndex((prev) => (prev < screenshots.length - 1 ? prev + 1 : prev)); } else if (e.key === "ArrowUp") { setGridFocusIndex((prev) => (prev >= cols ? prev - cols : prev)); } else if (e.key === "ArrowDown") { setGridFocusIndex((prev) => (prev <= screenshots.length - 1 - cols ? prev + cols : prev)); } else if (e.key === "Enter") { if (screenshots[gridFocusIndex]) { playPressSound(); setModalFocusIndex(2); setSelectedScreenshot(screenshots[gridFocusIndex]); } } }; window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); }, [loading, selectedScreenshot, gridFocusIndex, modalFocusIndex, screenshots, showDeleteConfirm, deleteConfirmFocusIndex]); useEffect(() => { if (!selectedScreenshot) { const element = document.getElementById(`ss-${gridFocusIndex}`); element?.scrollIntoView({ block: "nearest", behavior: "smooth" }); } }, [gridFocusIndex, selectedScreenshot]); const getEditionLogo = (instanceId: string) => { const edition = editions.find((e: any) => e.id === instanceId); return edition?.logo || edition?.titleImage; }; return (

Screenshots

{loading ? (
Scanning Archives...
) : screenshots.length === 0 ? (
No screenshots found Take some in-game with F2
) : (
{screenshots.map((ss, index) => (
{ setGridFocusIndex(index); setModalFocusIndex(2); // Close button setSelectedScreenshot(ss); playPressSound(); }} onMouseEnter={() => setGridFocusIndex(index)} className={` relative aspect-video flex flex-col cursor-pointer transition-all border-2 rounded-sm overflow-hidden bg-black/40 ${gridFocusIndex === index ? "border-[#FFFF55] scale-105 z-10" : "border-[#333] hover:border-[#FFFF55]"} `} style={{ backgroundImage: "url('/images/frame_background.png')", backgroundSize: '100% 100%', imageRendering: 'pixelated', boxShadow: gridFocusIndex === index ? '0 0 20px rgba(255, 255, 85, 0.2)' : 'none', }} >
{ss.name} { (e.target as HTMLImageElement).src = "/images/Folder_Icon.png"; }} />
{getEditionLogo(ss.instanceId) && (
)}
{new Date(ss.date * 1000).toLocaleDateString()}
))}
)}
{selectedScreenshot && ( setSelectedScreenshot(null)} > e.stopPropagation()} >
{ (e.target as HTMLImageElement).src = "/images/Pack_Icon.png"; }} />
{selectedScreenshot.name} Captured on {new Date(selectedScreenshot.date * 1000).toLocaleString()}
{getEditionLogo(selectedScreenshot.instanceId) && ( )}
)}
{showDeleteConfirm && ( setShowDeleteConfirm(false)} > e.stopPropagation()} > Are you sure you want to delete this screenshot?
)}
); }); export default ScreenshotsView;