Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5917c32
feat(arcade): update components for arcade native
Larkooo Nov 11, 2025
a7e4b83
rounded top & bottom tokens
Larkooo Nov 11, 2025
2f03d9c
view all tokens
Larkooo Nov 11, 2025
1118855
collection page with dynamic loading of tokens
Larkooo Nov 11, 2025
2cef01d
collections new look for cards & tokens
Larkooo Nov 12, 2025
f5eba16
refactor: components for common usage
Larkooo Nov 13, 2025
e3039c2
chore: image loading
Larkooo Nov 27, 2025
b739d1c
fix: image sanitization for beast cards
Larkooo Nov 28, 2025
045d66d
correctly patch svg
Larkooo Nov 28, 2025
239e00a
blur radius
Larkooo Nov 28, 2025
2e6703e
feat: drawer for token filtering
Larkooo Dec 1, 2025
e5636e8
user avatar, aracade brands side draver and game pages
Larkooo Dec 3, 2025
6afc678
thumbnail fix& items and games
Larkooo Dec 3, 2025
58104bc
arcade icon game size
Larkooo Dec 3, 2025
648dd74
feat: collection page & side drawer pretty
Larkooo Dec 4, 2025
598d07f
feat: loading for trait filters
Larkooo Dec 5, 2025
b6ce62b
feat(drawer): chevron up animation trait
Larkooo Dec 5, 2025
602fd6b
feat(drawer): arcade logo in filter mode
Larkooo Dec 5, 2025
45a4c12
feat(drawer): use global search for owners lookup in filtering
Larkooo Dec 5, 2025
bac7189
feat: list for activity
Larkooo Dec 5, 2025
c574d66
animate tab bar
Larkooo Dec 5, 2025
954379b
feat(filter): add Status filter UI (All/Buy Now)
Larkooo Dec 10, 2025
e9c7fc4
feat: use useTokens hook for inventory NFTs with proper metadata
Larkooo Dec 16, 2025
a3e28c2
feat: lords color icon for token inventory
Larkooo Dec 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 87 additions & 7 deletions src/clone/arcade/context/arcade.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { createContext, type PropsWithChildren } from "react";
import arcadeMock from "./arcade.mock.json";
/**
* Arcade Context - REAL DATA from Torii
* Provides games and editions data
*/
import { createContext, type PropsWithChildren, useMemo, useRef, useEffect, useState } from "react";
import { useGames, type Game as BaseGame } from "../../../../../../hooks/useGames";

const CHAIN_ID = "SN_MAIN";

Expand All @@ -8,22 +12,98 @@ export interface ProjectProps {
project: string;
}

const initialState = {
export type Game = BaseGame & { id: number };

export interface Edition {
id: string;
gameId: number;
config?: {
project?: string;
};
}

const emptyState = {
chainId: CHAIN_ID,
provider: {},
pins: {},
follows: {},
accesses: [],
games: arcadeMock.games,
editions: arcadeMock.editions,
games: [],
gamesList: [], // Lightweight list for UI
editions: [],
chains: [],
clients: {},
player: undefined,
setPlayer: () => {},
version: 0,
};

export const ArcadeContext = createContext(initialState);
export const ArcadeContext = createContext(emptyState);

export function ArcadeProvider(props: PropsWithChildren) {
return <ArcadeContext.Provider value={initialState} {...props} />;
let baseGames: BaseGame[] = [];

try {
const result = useGames();
baseGames = result.games;
} catch (err) {
console.error('❌ ArcadeProvider: Failed to load games', err);
baseGames = [];
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: React hook called inside try-catch block

The useGames() hook is called inside a try-catch block, which violates React's rules of hooks. Hooks must be called unconditionally at the top level of a component - they cannot be wrapped in try-catch, conditionals, or loops. While this code will execute, the try-catch won't actually catch errors thrown by the hook during React's render cycle. If useGames() throws, it will propagate up and cause rendering issues. The error handling approach here gives a false sense of safety without actually providing it.

Fix in Cursor Fix in Web


// Use refs for stable data + version counter for updates
const gamesRef = useRef<Game[]>([]);
const editionsRef = useRef<Edition[]>([]);
// Create a lightweight games list with only simple values for UI
const gamesListRef = useRef<Array<{id: number, name: string, icon?: string, color?: string}>>([]);
const [version, setVersion] = useState(0);

// Update refs and version when games count changes
useEffect(() => {
if (baseGames.length !== gamesRef.current.length) {
console.log('🎮 ArcadeProvider: Updating games -', baseGames.length, 'games');

// Convert games
const newGames = baseGames.map((game, index) => ({
...game,
id: parseInt(game.id) || index,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Game ID zero incorrectly replaced by array index

The expression parseInt(game.id) || index uses the logical OR operator with a falsy check. If a game has id: "0", parseInt("0") returns 0, which is falsy in JavaScript, causing the expression to fall back to index. This incorrectly assigns the array position as the ID instead of preserving the valid ID of zero.

Fix in Cursor Fix in Web

}));

// Create lightweight list for UI (only simple values!)
const newGamesList = newGames.map(g => ({
id: g.id,
name: g.name,
icon: g.properties?.icon || undefined,
color: g.color || undefined,
}));

// Create editions
const newEditions = newGames.map((game) => ({
id: game.id.toString(),
gameId: game.id,
config: {
project: `arcade-${game.name.toLowerCase().replace(/\s+/g, '-')}`,
},
}));

gamesRef.current = newGames;
gamesListRef.current = newGamesList;
editionsRef.current = newEditions;

// Increment version to trigger re-renders
setVersion(v => v + 1);
}
}, [baseGames.length]);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: useEffect only updates games when count changes

The useEffect has [baseGames.length] as its dependency and the condition checks baseGames.length !== gamesRef.current.length. This means if game properties change (names, icons, covers, etc.) but the total game count remains the same, the refs won't update and consumers will see stale game data.

Fix in Cursor Fix in Web


const value = useMemo(() => ({
...emptyState,
games: gamesRef.current,
gamesList: gamesListRef.current, // Expose lightweight list
editions: editionsRef.current,
version, // Include version so consumers can depend on it
}), [version]); // Only depend on version number!

console.log('🎮 ArcadeProvider: Providing', gamesRef.current.length, 'real games (v', version, ')');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Debug console.log statements left in code

Multiple debug console.log statements with emoji prefixes (🎮, 💰) have been left in the production code. These statements in ArcadeProvider and MarketplaceProvider will log on every render and component update, cluttering the console output in production builds.

Additional Locations (1)

Fix in Cursor Fix in Web


return <ArcadeContext.Provider value={value} {...props} />;
}
Loading
Loading