import { FocusContext, useFocusable, } from "@noriginmedia/norigin-spatial-navigation"; import CardElement, { GameCardParams } from "./CardElement"; import { JSX } from "react"; import { twMerge } from "tailwind-merge"; import { GamePadButtonCode, Shortcut, useShortcuts } from "../scripts/shortcuts"; import { oneShot } from "../scripts/audio/audio"; export interface GameMetaExtra extends GameMeta { preview?: GameCardParams['preview']; badges?: JSX.Element[]; focusKey: string; } function LocalCardElement (data: { game: GameMetaExtra, i: number; onQuickAction?: (ctx: InteractParamsArgs) => void; } & FocusParams & InteractParams) { let preview: GameCardParams['preview'] = data.game.preview; if (!preview && data.game.previewUrls) { preview = data.game.previewUrls; } const handleAction = (ctx: InteractParamsArgs) => { data.game.onSelect?.(); data.onAction?.({ event, focusKey: data.game.focusKey }); oneShot('click'); }; const handleAltAction = (ctx: InteractParamsArgs) => { data.game.onQuickAction?.(); data.onQuickAction?.({ event, focusKey: data.game.focusKey }); oneShot('click'); }; useShortcuts(data.game.focusKey, () => { const options: Shortcut[] = [{ label: "Details", button: GamePadButtonCode.A, action: event => handleAction({ event, focusKey: data.game.focusKey }) }]; if (data.onQuickAction || data.game.onQuickAction) { options.push({ label: "Play", button: GamePadButtonCode.X, action: event => handleAltAction({ event, focusKey: data.game.focusKey }) }); } return options; }, [data.onQuickAction, data.game.onQuickAction, data.game.focusKey]); return ( { data.game.onFocus?.(focusKey, node, details); data.onFocus?.(focusKey, node, { ...details, id: data.game.id }); }} onAction={handleAction} preview={preview} badges={data.game.badges} id={data.game.id} /> ); } export function CardList (data: { id: string; type?: string; games: GameMetaExtra[]; grid?: boolean; onSelectGame?: (id: string) => void; focus?: string; className?: string; finalElement?: JSX.Element | JSX.Element[]; saveChildFocus?: 'session' | 'local'; } & FocusParams) { const { ref, focusKey } = useFocusable({ focusKey: data.id, focusable: data.games.length > 0 || (!!data.finalElement && (Array.isArray(data.finalElement) ? data.finalElement.length > 0 : !!data.finalElement)), preferredChildFocusKey: data.focus }); return ( ); }