import { AutoFocus } from '@/mainview/components/AutoFocus'; import DotsLoading from '@/mainview/components/backgrounds/dots'; import { ContextList, DialogEntry } from '@/mainview/components/ContextDialog'; import { StickyHeaderUI } from '@/mainview/components/Header'; import { Button } from '@/mainview/components/options/Button'; import Screenshots from '@/mainview/components/Screenshots'; import SelectMenu from '@/mainview/components/SelectMenu'; import { FloatingShortcuts } from '@/mainview/components/Shortcuts'; import { GlobalDialogContext } from '@/mainview/scripts/contexts'; import { downloadLookupQuery } from '@/mainview/scripts/queries/romm'; import { GamePadButtonCode, useShortcuts } from '@/mainview/scripts/shortcuts'; import { HandleGoBack } from '@/mainview/scripts/utils'; import { FocusContext, useFocusable } from '@noriginmedia/norigin-spatial-navigation'; import { createFileRoute, useNavigate, useRouter } from '@tanstack/react-router'; import { Download } from 'lucide-react'; import prettyBytes from 'pretty-bytes'; import { useContext } from 'react'; export const Route = createFileRoute('/store/details/download/$source/$id')({ component: RouteComponent, pendingComponent: Loading, async loader (ctx) { const data = await ctx.context.queryClient.fetchQuery(downloadLookupQuery(decodeURIComponent(ctx.params.source), decodeURIComponent(ctx.params.id))); return { data }; } }); function Loading () { const { ref, focusSelf } = useFocusable({ focusKey: 'download-details' }); return <> ; } const imagesMap = new Set(['JPEG', 'PNG', 'Motion JPEG', 'Item Image']); const videoFormat = new Set(['h.264']); const downloadsBlacklist = new Set(['JPEG Thumb', 'Metadata', 'Thumbnail', 'Item Tile', 'Archive BitTorrent', ...videoFormat, ...imagesMap]); function Details (data: { onDownload: (focusKey: string) => void; }) { const { data: download } = Route.useLoaderData(); const screenshots = download.files.filter(f => f.format && imagesMap.has(f.format)).map(f => f.download_url); if (screenshots.length <= 0 && download.cover_url) screenshots.push(download.cover_url); return
{!!download.cover_url && }
{download.name}
{download.date?.toDateString()}
{download.source}
{!!download.summary &&
}
Downloads
    {download.files.filter(f => f.format && !downloadsBlacklist.has(f.format)).map(f =>
  • {f.id} {!!f.size && prettyBytes(f.size)}
  • )}
; } function RouteComponent () { const navigate = useNavigate(); const router = useRouter(); const { ref, focusKey, focusSelf } = useFocusable({ focusKey: 'download-details', preferredChildFocusKey: 'download-btn' }); const { data } = Route.useLoaderData(); const globalDialog = useContext(GlobalDialogContext); useShortcuts(focusKey, () => [{ label: "Return", action: (e) => HandleGoBack(router, e), button: GamePadButtonCode.B }], [router]); return
globalDialog.openContext({ content: f.format && !downloadsBlacklist.has(f.format)).map(f => { const option: DialogEntry = { id: f.id, content: f.id, type: 'primary', action (ctx) { navigate({ to: '/game/add', search: { gameLocation: f.download_url, search: data.name, step: 1 } }); }, }; return option; })} /> }, focusKey)} />
; }