-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Staging #228
base: develop
Are you sure you want to change the base?
Staging #228
Conversation
…pdated position data to include player and opponent states with native and non-native coordinates. Simplified position retrieval logic based on pit number and player type. Improved animation handling for seed positioning.
* opponents position update * isNative confirmations * pit 7 ops * pit 7 plays * pit 7 plays * prettier * update dojo config
* feat: fixed the trophy icon set * feat: arcade progression wip * feat: trophy element changes & controller client config * feat: torii config * feat: wip header
* fixed burner issue * fixed burner issue * fixed burner issue * loading screen upgrade * loading screen upgrade * up update * optimize tables * update ui * changed text color in game board * added error boundary ui * optimized user section * optimized user section * default url * auto connect * Merge into staging-ui-upgrade * add eliza * ui update * ui update * fixed build issue * eliza starter * eliza starter * animate-spin --------- Co-authored-by: kelvin_joshua <[email protected]>
* fix: patch first attempt * fix: path2 achievements
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThis pull request introduces significant updates to the Mancala game project, focusing on transitioning from a development environment to an alpha stage. The changes span across multiple components, including client-side configuration, game mechanics, profile management, and contract systems. Key modifications include updating namespaces, introducing trophy and task systems, enhancing game interactions, and refactoring the overall project structure. Changes
Sequence DiagramsequenceDiagram
participant Player
participant GameSystem
participant ProfileSystem
participant AchievementSystem
Player->>GameSystem: Create Game
GameSystem->>ProfileSystem: Initialize Player Profile
ProfileSystem-->>GameSystem: Profile Created
GameSystem->>AchievementSystem: Register Initial Tasks
Player->>GameSystem: Make Move
GameSystem->>AchievementSystem: Update Player Progress
AchievementSystem->>GameSystem: Progress Tracked
GameSystem->>AchievementSystem: Check Trophy Conditions
AchievementSystem-->>Player: Trophy Awarded
Possibly related PRs
Suggested reviewers
Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 35
🔭 Outside diff range comments (2)
contracts/src/tests/test_world.cairo (1)
Line range hint
46-46
: Useset_caller_address
instead ofset_contract_address
for changing the callerYou are using
set_contract_address(ANYONE);
to change the caller in the test. However,set_contract_address
sets the address of the current contract, not the caller's address. To simulate calls from different accounts, you should useset_caller_address(ANYONE);
.Apply this diff to fix the issue:
- set_contract_address(ANYONE); + set_caller_address(ANYONE);contracts/dojo_dev.toml (1)
Line range hint
27-31
: Security: IPFS credentials should not be in version controlThe configuration file contains hardcoded IPFS credentials, which poses a security risk.
Consider:
- Moving credentials to environment variables
- Using a secure secrets management solution
- Rotating the exposed credentials immediately
-ipfs_config.username = "2EBrzr7ZASQZKH32sl2xWauXPSA" -ipfs_config.password = "12290b883db9138a8ae3363b6739d220" +ipfs_config.username = "${IPFS_USERNAME}" +ipfs_config.password = "${IPFS_PASSWORD}"
🧹 Nitpick comments (48)
client/src/AppWrapper.tsx (2)
27-34
: Consider enhancing edge case handlingWhile the current implementation is good, consider handling the case where
currentStep
exists but isn't a key inSETUP_STATUS_MESSAGES
.return currentStep - ? SETUP_STATUS_MESSAGES[currentStep as keyof typeof SETUP_STATUS_MESSAGES] + ? SETUP_STATUS_MESSAGES[currentStep as keyof typeof SETUP_STATUS_MESSAGES] ?? "Setting up game..." : "Loading...";
48-53
: Consider optimizing logo animation performanceThe animated logo looks good, but continuous animation might impact performance on lower-end devices. Consider:
- Using CSS
animation-duration
with a slower speed- Implementing
will-change: transform
for better performance- Adding
@media (prefers-reduced-motion: reduce)
support- <img src={logo} width={126} height={126} alt="logo" className="animate-spin" /> + <img + src={logo} + width={126} + height={126} + alt="logo" + className="animate-spin motion-safe:animate-spin will-change-transform" + style={{ animationDuration: '3s' }} + />client/src/components/lobby/leaderboard.tsx (3)
10-11
: Consider using responsive design patterns.The current implementation uses fixed dimensions which may cause layout issues on different screen sizes. Consider:
- Using relative units (e.g., vh, vw) or responsive classes for container heights
- Implementing responsive width classes instead of fixed pixel values
- Ensuring the scrollable div's height (500px) aligns with its container (437px)
- <div className="bg-[#0F1116] bg-contain bg-center bg-no-repeat border-2 border-[#272A32] rounded-2xl w-[928px] h-[437px] flex flex-col items-center justify-center px-8"> - <div className="w-[928px] rounded-t-xl rounded-b-xl fixed h-[500px] overflow-y-scroll hide-scrollbar pb-4"> + <div className="bg-[#0F1116] bg-contain bg-center bg-no-repeat border-2 border-[#272A32] rounded-2xl w-full max-w-[928px] h-[437px] flex flex-col items-center justify-center px-8"> + <div className="w-full rounded-t-xl rounded-b-xl fixed h-[437px] overflow-y-scroll hide-scrollbar pb-4">
20-26
: Review sticky header positioning.The negative top value in sticky positioning might cause inconsistent behavior across browsers. Consider using a positive offset and adjusting the container padding instead.
- <thead className="sticky -top-3.5 bg-[#0F1116] z-10"> + <thead className="sticky top-0 bg-[#0F1116] z-10">
35-105
: Consider performance optimizations for large datasets.The current implementation might face performance issues with large datasets. Consider:
- Implementing virtualization for the table rows
- Adding pagination or infinite scroll
- Memoizing the player row component
Would you like me to provide an example implementation using react-window or react-virtualized?
client/src/components/profile/game-history.tsx (2)
69-71
: Consider adding error handling for the empty state check.The empty state check could be more robust by handling undefined/null cases.
- } else if (data?.length === 0) { + } else if (!data || data.length === 0) {
105-111
: Improve date handling and memoize color calculations.The color and date calculations could be optimized:
- Date parsing on every render
- Color calculations could be memoized
+ const memoizedColors = useMemo(() => { + return data?.map((_, index) => ({ + challenger: colors[index % colors.length], + challenged: colors[(index + 3) % colors.length] + })); + }, [data?.length]); return ( // ... in the map function: - const challengerColor = colors[index % colors.length]; - const challengedColor = colors[(index + 3) % colors.length]; - const date = new Date(item.date); + const { challenger: challengerColor, challenged: challengedColor } = memoizedColors[index]; + const date = useMemo(() => new Date(item.date), [item.date]);contracts/src/components/initializable.cairo (1)
34-34
: Consider defining error messages in anerrors
module for consistency.For better maintainability and consistency across components, define the error message
'Counter already initialized'
in anerrors
module, similar to other components.Apply this diff to refactor:
+// Errors +mod errors { + const COUNTER_ALREADY_INITIALIZED: felt252 = 'Counter already initialized'; +} ... -assert(current_game_counter.count == 0, 'Counter already initialized'); +assert(current_game_counter.count == 0, errors::COUNTER_ALREADY_INITIALIZED);contracts/src/systems/profile.cairo (1)
38-46
: Add input validation forname
andnew_uri
parameters.Currently, there is no validation on the
name
andnew_uri
parameters in thecreate_player_profile
andupdate_player_profile
functions. Consider adding input validation to ensure these parameters meet expected criteria (e.g., length limits, acceptable character sets) to enhance security and prevent potential issues.contracts/src/components/profile.cairo (2)
27-39
: Add input validation forname
parameter innew_profile
function.To ensure data integrity and prevent potential issues, consider adding validation for the
name
parameter in thenew_profile
function.
41-55
: Add input validation forname
andnew_uri
parameters inupdate_player_profile
function.Adding input validation for the
name
andnew_uri
parameters in theupdate_player_profile
function will enhance security and prevent potential issues.client/src/components/header.tsx (1)
103-137
: Simplify conditional rendering for better readability.The current conditional rendering logic within the JSX is a bit complex and can be refactored for clarity. Consider creating separate components or helper functions for the different button states to make the code more maintainable and easier to read.
contracts/src/systems/mancala.cairo (1)
62-88
: Add error handling for the initialization process.In the
dojo_init
function, there is no error handling for the initialization processes ofinitializable
andachievable
components. Consider adding error handling or logging to capture any issues that may arise during initialization.Apply this diff to add error handling:
fn dojo_init(self: @ContractState) { - self.initializable.initialize(self.world_storage()); + let init_result = self.initializable.initialize(self.world_storage()); + if init_result.is_err() { + // Handle the error accordingly + } // [Event] Emit all Trophy events let world = self.world(@NAMESPACE()); let mut trophy_id: u8 = TROPHY_COUNT; while trophy_id > 0 { let trophy: Trophy = trophy_id.into(); let create_result = self .achievable .create( world, id: trophy.identifier(), hidden: trophy.hidden(), index: trophy.index(), points: trophy.points(), start: trophy.start(), end: trophy.end(), group: trophy.group(), icon: trophy.icon(), title: trophy.title(), description: trophy.description(), tasks: trophy.tasks(), data: trophy.data(), ); + if create_result.is_err() { + // Handle the error accordingly + } trophy_id -= 1; } }client/src/components/gameplay/game-board.tsx (2)
58-96
: Consider refactoring duplicateuseEffect
hooks for better maintainabilityThe
useEffect
hooks for handling captures (lines 58~ to 76~) and extra turns (lines 78~ to 96~) have similar structures. Refactoring this logic into a reusable function or a custom hook can reduce code duplication and improve code maintainability.Here's how you might abstract the common logic:
+const useGameEventNotification = (data, dataKey, titleMap, descriptionMap) => { + const { toast } = useToast(); + useEffect(() => { + const events = data?.[dataKey]?.edges; + if (events && events.length > 0) { + const latestEvent = events[events.length - 1]?.node; + + if (latestEvent) { + const isPlayerEvent = latestEvent.player === account.account?.address; + + toast({ + title: isPlayerEvent ? titleMap.player : titleMap.opponent, + description: isPlayerEvent + ? descriptionMap.player(latestEvent) + : descriptionMap.opponent(latestEvent), + duration: 3000, + }); + } + } + }, [data, account.account?.address, toast]); +}; + useEffect(() => { - const captures = captureData?.mancalaAlphaCaptureModels?.edges; - if (captures && captures.length > 0) { - const latestCapture = captures[captures.length - 1]?.node; - - if (latestCapture) { - const isPlayerCapture = - latestCapture.player === account.account?.address; - - toast({ - title: isPlayerCapture ? "Seeds Captured!" : "Seeds Lost!", - description: isPlayerCapture - ? `You captured ${latestCapture.seed_count} seeds from pit ${latestCapture.pit_number}` - : `Opponent captured ${latestCapture.seed_count} seeds from pit ${latestCapture.pit_number}`, - duration: 3000, - }); - } - } + useGameEventNotification( + captureData, + 'mancalaAlphaCaptureModels', + { player: 'Seeds Captured!', opponent: 'Seeds Lost!' }, + { + player: (event) => `You captured ${event.seed_count} seeds from pit ${event.pit_number}`, + opponent: (event) => `Opponent captured ${event.seed_count} seeds from pit ${event.pit_number}`, + } + ); }, [captureData, account.account?.address, toast]); useEffect(() => { - const extraTurns = extraTurnData?.mancalaAlphaPlayerExtraTurnModels?.edges; - if (extraTurns && extraTurns.length > 0) { - const latestExtraTurn = extraTurns[extraTurns.length - 1]?.node; - - if (latestExtraTurn) { - const isPlayerExtraTurn = - latestExtraTurn.player === account.account?.address; - - toast({ - title: isPlayerExtraTurn ? "Extra Turn!" : "Opponent Extra Turn", - description: isPlayerExtraTurn - ? "You get another turn!" - : "Opponent gets another turn", - duration: 3000, - }); - } - } + useGameEventNotification( + extraTurnData, + 'mancalaAlphaPlayerExtraTurnModels', + { player: 'Extra Turn!', opponent: 'Opponent Extra Turn' }, + { + player: () => 'You get another turn!', + opponent: () => 'Opponent gets another turn', + } + ); }, [extraTurnData, account.account?.address, toast]);
151-161
: Simplify seed count retrieval using.find
When calculating
player_pot_seed_count
andopponent_pot_seed_count
, you can replace the chained.filter()
calls with a single.find()
to improve efficiency and readability.Here's the suggested change:
-player_pot_seed_count = game_players?.mancalaAlphaPitModels.edges .filter( (item: any) => item?.node.player === game_players?.mancalaAlphaPlayerModels.edges[player_position]?.node.address, ) .filter((item: any) => item?.node.pit_number === 7)[0]?.node ?.seed_count || 0; +player_pot_seed_count = + game_players?.mancalaAlphaPitModels.edges + .find( + (item: any) => + item?.node.player === + game_players?.mancalaAlphaPlayerModels.edges[player_position]?.node.address && + item?.node.pit_number === 7, + )?.node + ?.seed_count || 0;Apply the same logic to
opponent_pot_seed_count
.client/src/components/gameplay/game-message.tsx (2)
205-285
: Avoid logging sensitive game data in productionThe
console.log
statements inconstructElizaMessage
(lines 207~ and 241~) can expose sensitive game data in the browser's console. Consider removing or conditioning these logs to prevent potential information leakage.[security_issue]
Remove or conditionally disable debug logs:
- console.log({ game_node }); ... - console.log({ - message - })
281-287
: Optimize address normalization functionThe
normalizeAddress
function can lead to inconsistent results if addresses are not in the expected format. Consider using a standardized library or method for address normalization to ensure consistency across different parts of the application.Alternatively, adjust the function to handle different possible address formats robustly.
contracts/src/types/trophy.cairo (2)
28-40
: Simplifylevel
method implementationThe
level
method contains repeated patterns that can be simplified. As all trophies exceptTrophy::None
have an associated level, consider refactoring to eliminate redundancy.Example:
fn level(self: Trophy) -> u8 { match self { Trophy::None => 0, _ => { // Define a mapping from Trophy variant to level, if possible. }, } }
267-272
: Implement a more informativeThe
Example:
fn print(self: Trophy) { self.title().print(); }contracts/src/tests/test_world.cairo (1)
389-389
: Consider removing commented-out codeThe code at line 389~ is commented out. If this code is no longer needed, consider removing it to keep the codebase clean. If you plan to use it later, add a comment explaining its purpose.
client/src/components/profile/user-section.tsx (1)
113-113
: Simplify null checks using optional chainingYou can simplify the null checks by using optional chaining when accessing
event.target.files[0]
.Apply this diff to simplify the code:
- if (event.target.files && event.target.files[0]) { + if (event.target.files?.[0]) {🧰 Tools
🪛 Biome (1.9.4)
[error] 113-113: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
contracts/src/components/playable.cairo (1)
243-264
: Duplicate code when updating task progressThe code for updating task progress after capturing seeds is duplicated. Consider refactoring this into a helper function to improve maintainability.
Extract the repeated code into a function, for example:
fn update_task_progress(player_address: ContractAddress, captured_seeds: u8, world: WorldStorage) { let arcade_store: ArcadeStore = ArcadeStoreTrait::new(world); let task_id = Task::Collecting.identifier(0); let extractor_task_id = Task::Clearing.identifier(0); let time = get_block_timestamp(); arcade_store.progress(player_address.into(), task_id, captured_seeds.into(), time); arcade_store.progress(player_address.into(), extractor_task_id, captured_seeds.into(), time); }Then call
update_task_progress
where needed.client/src/lib/constants.ts (2)
783-812
: Handle Possible Empty Results in New QueriesThe new
MancalaCaptureQuery
andMancalaExtraTurnQuery
have been added. Ensure that the application gracefully handles scenarios where these queries return empty results or errors to prevent runtime exceptions.Consider adding default values or checks when processing the data returned by these queries.
813-1100
: Optimize thepositions
Function for MaintainabilityThe
positions
function contains extensive hard-coded coordinate arrays, which can be difficult to maintain and prone to errors. Refactor the function to generate coordinates programmatically if possible.Consider the following suggestions:
Mathematical Generation: Use mathematical formulas to calculate positions based on indices.
Data Structures: Store patterns or offsets in a data structure that can be looped over.
Helper Functions: Break down the coordinate generation into smaller helper functions for clarity.
Example refactor:
export const positions = (type: "player" | "opponent" | undefined) => Array.from({ length: 7 }, (_, playerIndex) => { const xBase = type === "player" ? playerIndex * 120 : 600 - playerIndex * 120; const yBase = type === "player" ? 0 : -110; const generateCoords = () => { let coords = []; for (let i = 0; i < NUM_SEEDS; i++) { coords.push({ x: xBase + calculateXOffset(i), y: yBase + calculateYOffset(i), }); } return coords; }; return { player: { native: generateCoords(), non_native: generateCoords(), }, opponent: { native: generateCoords(), non_native: generateCoords(), }, }; });Where
calculateXOffset
andcalculateYOffset
are functions that compute offsets.contracts/src/elements/tasks/mastering.cairo (1)
11-11
: Improve description grammar.The current message "Get {} games win streak" could be clearer. Consider these alternatives:
- "Get a {} game win streak"
- "Win {} games in a row"
- format!("Get {} games win streak", count) + format!("Get a {} game win streak", count)contracts/src/elements/tasks/collecting.cairo (1)
11-11
: Improve description clarity and grammar.The current message has grammar issues and could be more concise:
- "seed" should be plural when count > 1
- "in game lifetime history" is verbose
- format!("Collect {} seed in game lifetime history", count) + format!("Collect {} seeds throughout your games", count)contracts/src/elements/trophies/interface.cairo (1)
4-15
: Well-structured trophy system interface.The TrophyTrait provides a comprehensive interface for trophy management with:
- Clear separation between trophy attributes and tasks
- Type-safe level parameters
- Flexible task integration via BushidoTask
Consider adding documentation comments for each method to improve maintainability.
client/src/components/controller-trophy.tsx (1)
16-20
: Add loading state to prevent multiple clicks.The button should show a loading state while the profile is being opened.
+ const [isLoading, setIsLoading] = useState(false); + + const handleTrophyClick = useCallback(async () => { + setIsLoading(true); if (!connector?.controller) { // error handling + setIsLoading(false); return; } - connector?.controller.openProfile("achievements"); + try { + await connector.controller.openProfile("achievements"); + } finally { + setIsLoading(false); + } }, [connector]); return ( - <Button variant="outline" onClick={() => handleTrophyClick()}> + <Button variant="outline" onClick={handleTrophyClick} disabled={isLoading}> <Trophy /> </Button> );client/src/components/lobby/empty-duels.tsx (1)
3-3
: Props interface should be extracted.For better maintainability and reuse, define a separate props interface.
+interface EmptyDuelsProps { + message: string; + onCreateGame?: () => void; +} -export default function EmptyDuels({ message }: { message: string }) +export default function EmptyDuels({ message, onCreateGame }: EmptyDuelsProps)contracts/src/lib.cairo (1)
21-51
: Well-structured module organization!The new module structure effectively separates concerns and provides a clear hierarchy for the game's components:
- Components layer for core functionalities
- Elements layer for task and trophy management
- Systems layer for game mechanics
- Types layer for shared enums
This organization promotes maintainability and follows good architectural practices.
Consider documenting the responsibility of each module layer in the README to help future contributors understand the codebase structure.
contracts/src/elements/trophies/victor.cairo (1)
3-54
: Well-structured trophy implementation!The implementation follows a clear pattern and provides all necessary properties for the trophy system.
Consider documenting magic numbers.
The implementation uses magic numbers for points (100) and count (100). Consider extracting these to named constants with documentation explaining their significance.
+/// Points awarded for achieving the Victor trophy +const VICTOR_POINTS: u16 = 100; +/// Number of tasks required to earn the Victor trophy +const VICTOR_TASK_COUNT: u32 = 100; + impl Victor of TrophyTrait { #[inline] fn points(level: u8) -> u16 { - 100 + VICTOR_POINTS } #[inline] fn count(level: u8) -> u32 { - 100 + VICTOR_TASK_COUNT } }contracts/src/elements/trophies/dominator.cairo (1)
3-54
: Consistent trophy implementation!The implementation follows the same pattern as other trophies, maintaining consistency across the codebase.
Consider extracting common patterns and documenting magic numbers.
- The implementation uses magic numbers for points (50) and count (500). Consider extracting these to named constants.
- There's potential for code duplication across trophy implementations. Consider extracting common patterns into a base implementation.
+/// Points awarded for achieving the Dominator trophy +const DOMINATOR_POINTS: u16 = 50; +/// Number of tasks required to earn the Dominator trophy +const DOMINATOR_TASK_COUNT: u32 = 500; + impl Dominator of TrophyTrait { #[inline] fn points(level: u8) -> u16 { - 50 + DOMINATOR_POINTS } #[inline] fn count(level: u8) -> u32 { - 500 + DOMINATOR_TASK_COUNT } }Consider creating a macro to reduce boilerplate across trophy implementations:
// Example macro (syntax may need adjustment) macro_rules! implement_trophy { ($name:ident, $id:expr, $points:expr, $count:expr) => { impl $name of TrophyTrait { // Common implementation details... } } }client/src/components/boundaries/error-boundary.tsx (1)
16-29
: Enhanced error UI with better visual hierarchy!The updated error boundary provides a more polished and user-friendly experience.
Consider accessibility improvements.
While the UI looks good, consider enhancing accessibility:
- Add aria-label to the error container
- Ensure sufficient color contrast for text visibility
- Add aria-live region for screen readers
<div role="alert" + aria-label="Error occurred" className="grid w-full h-screen place-items-center bg-[#0F1116] bg-[url('./assets/bg.png')] bg-cover bg-center" > <div className="flex flex-col items-center justify-center space-y-4"> - <div className="flex flex-col items-center justify-center space-y-1.5 w-[400px] h-[275px] rounded-lg bg-[#4920003D] backdrop-blur-md"> + <div + className="flex flex-col items-center justify-center space-y-1.5 w-[400px] h-[275px] rounded-lg bg-[#4920003D] backdrop-blur-md" + aria-live="polite" + > <img src={logo} width={126} height={126} alt="logo" /> <h2 className="text-white font-semibold">Ouch, an error occurred</h2> - <div className="text-white/80 text-center px-4">{error.message}</div> + <div className="text-white/90 text-center px-4">{error.message}</div>client/src/pages/Home.tsx (1)
24-27
: Consider adding loading state to the button.The connection process might take time, and the button should reflect this state to improve user experience.
<button className="bg-[#1A1D25] text-[#F58229] py-2.5 px-7 rounded-full flex flex-row items-center justify-center space-x-1"> <Bubble /> - <p>Go to lobby</p> + <p>{account ? 'Go to lobby' : 'Connecting...'}</p> </button>contracts/src/elements/trophies/strategist.cairo (1)
80-83
: Document the task type choice.The use of
Task::Mastering
instead ofTask::Collecting
should be documented to explain the different requirements.Add a comment explaining why Mastering tasks are used for the Strategist trophy:
fn tasks(level: u8) -> Span<BushidoTask> { + // Using Mastering tasks as they represent strategic gameplay achievements let total: u32 = Self::count(level); Task::Mastering.tasks(level, total, total) }
client/src/components/pits.tsx (1)
56-56
: Consider adding error handling for audio playback.While the sound effect integration is good, consider wrapping the
playEmptyPitSound()
call in a try-catch block to handle potential audio playback failures gracefully.- playEmptyPitSound(); + try { + playEmptyPitSound(); + } catch (error) { + console.warn('Failed to play sound effect:', error); + }client/src/components/seed.tsx (1)
24-34
: Consider memoizing position calculations more efficiently.The current implementation recalculates positions on every render. Consider simplifying the condition chain.
const position = useMemo(() => { - return isNative && type === "player" - ? _positions[pit_number - 1]?.player?.native[seed_number - 1] - : isNative && type === "opponent" - ? _positions[pit_number - 1]?.opponent?.native[seed_number - 1] - : !isNative && type === "player" - ? _positions[pit_number - 1]?.player?.non_native[seed_number - 1] - : !isNative && type === "opponent" - ? _positions[pit_number - 1]?.opponent?.non_native[seed_number - 1] - : { x: 0, y: 0 }; + if (!type || pit_number < 1 || seed_number < 1) { + return { x: 0, y: 0 }; + } + const positionType = isNative ? 'native' : 'non_native'; + return _positions[pit_number - 1]?.[type]?.[positionType]?.[seed_number - 1] || { x: 0, y: 0 }; }, [isNative, type, _positions, pit_number, seed_number]);client/src/pages/Profile.tsx (1)
39-44
: Consider adding error handling for auto-connect.While auto-connect improves UX, it should handle potential connection failures gracefully.
useEffect(() => { if (!account?.account?.address) { - connect({ connector: connectors[0] }); + try { + connect({ connector: connectors[0] }); + } catch (error) { + console.error('Failed to auto-connect:', error); + // Consider showing a user-friendly error message + } } }, [account, connect, connectors]);client/src/components/lobby/duels-skeleton.tsx (1)
43-43
: Consider making the number of skeleton rows configurable.The hardcoded value of 5 rows could be made configurable to better match different view states.
+const SKELETON_ROWS = 5; export function DuelsSkeleton() { return ( // ... - {Array.from({ length: 5 }).map((_, index) => { + {Array.from({ length: SKELETON_ROWS }).map((_, index) => {client/src/pages/games/Gameplay.tsx (1)
55-60
: Consider user consent for automatic wallet connection.While automatic connection enhances UX, it's best practice to request user consent before connecting to their wallet. Consider adding a connection prompt or button for better user control.
- useEffect(() => { - if (!account?.account?.address) { - connect({ connector: connectors[0] }); - } - }, [account, connect, connectors]); + useEffect(() => { + const autoConnect = localStorage.getItem('autoConnect') === 'true'; + if (!account?.account?.address && autoConnect) { + connect({ connector: connectors[0] }); + } + }, [account, connect, connectors]);client/src/components/lobby/live-duels.tsx (1)
12-30
: Consider making the filter condition more explicit.While filtering out "0x0" addresses is correct, consider making the validation more explicit for better maintainability.
- const data = games - ?.filter( - (game: any) => - game.node.player_one !== "0x0" && game.node.player_two !== "0x0", - ) + const isValidAddress = (address: string) => address !== "0x0"; + const data = games + ?.filter( + (game: any) => + isValidAddress(game.node.player_one) && isValidAddress(game.node.player_two), + )contracts/src/utils/board.cairo (1)
Line range hint
214-243
: LGTM! Consider documenting the return value.The modification to return the total number of captured seeds is a good addition that could be useful for tracking game statistics or achievements. The implementation correctly calculates the total before modifying the game state.
Consider adding a comment to document that the function returns the total number of seeds captured, which could help other developers understand the purpose of this return value.
client/src/components/lobby/duels.tsx (2)
102-136
: Consider extracting table components for better maintainability.The table structure is well-organized but quite complex. Consider extracting the table header and row components to improve code maintainability and reusability.
291-330
: Enhance accessibility for sharing buttons.The sharing functionality is well-implemented, but consider adding ARIA labels and keyboard navigation support for better accessibility.
Example improvements:
-<div className="flex flex-row items-center justify-center space-x-1 pr-10 cursor-pointer" +<button + aria-label={copied ? "Game link copied" : "Copy game link"} + className="flex flex-row items-center justify-center space-x-1 pr-10 cursor-pointer"client/src/pages/Lobby.tsx (2)
373-397
: Consider using radio group for player type selection.The player type selection using buttons could be improved by using a radio group component for better accessibility and state management.
Example improvement:
-<div className="flex flex-row items-center justify-center space-x-3.5"> +<RadioGroup + value={playWith} + onValueChange={setPlayWith} + className="flex flex-row items-center justify-center space-x-3.5" +> <button>Human Player</button> <button>Play with Eliza AI</button> -</div> +</RadioGroup>
400-408
: Remove unnecessary fragment.The fragment wrapper is redundant as it contains only one child element.
Apply this diff to fix the issue:
-{playWith === "Human" && ( - <> - <input - className="p-2.5 w-72 rounded-xl border border-[#1D212B] bg-transparent outline-none placeholder:text-[#4F5666] placeholder:font-medium text-[#4F5666] font-medium" - placeholder="0x..." - onChange={(e) => setPlayer2(e.target.value)} - /> - </> -)} +{playWith === "Human" && ( + <input + className="p-2.5 w-72 rounded-xl border border-[#1D212B] bg-transparent outline-none placeholder:text-[#4F5666] placeholder:font-medium text-[#4F5666] font-medium" + placeholder="0x..." + onChange={(e) => setPlayer2(e.target.value)} + /> +)}🧰 Tools
🪛 Biome (1.9.4)
[error] 401-407: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
contracts/src/elements/trophies/extractor.cairo (1)
20-22
: Consider extracting magic numbers as constantsThe
points()
andcount()
methods use magic numbers (100 and 10000). Consider extracting these as named constants for better maintainability.+const EXTRACTOR_POINTS: u16 = 100; +const EXTRACTOR_COUNT: u32 = 10000; + impl Extractor of TrophyTrait { #[inline] fn points(level: u8) -> u16 { - 100 + EXTRACTOR_POINTS } #[inline] fn count(level: u8) -> u32 { - 10000 + EXTRACTOR_COUNT }Also applies to: 45-47
contracts/manifest_dev.json (1)
1611-1616
: New achievement system implementation detected.The addition of AchievableComponent and trophy-related events (TrophyCreation, TrophyProgression) suggests a new achievement system. This enhances the game's engagement mechanics.
Consider implementing the following for the achievement system:
- Achievement progress persistence
- Achievement notification system
- Achievement unlock conditions validation
Also applies to: 1961-1968
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (39)
.github/workflows/test.yml
is excluded by none and included by none.gitignore
is excluded by none and included by noneclient/pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
,!client/pnpm-lock.yaml
and included byclient/**
client/src/assets/bg.png
is excluded by!**/*.png
and included byclient/**
client/src/assets/home-box.png
is excluded by!**/*.png
and included byclient/**
client/src/assets/small-logo.png
is excluded by!**/*.png
and included byclient/**
client/src/assets/square-avatar.png
is excluded by!**/*.png
and included byclient/**
client/src/dojo/generated/generated.ts
is excluded by!**/generated/**
and included byclient/**
client/src/dojo/generated/setup.ts
is excluded by!**/generated/**
and included byclient/**
client/src/music/empty-pit.mp3
is excluded by!**/*.mp3
and included byclient/**
client/src/music/seed-drop.mp3
is excluded by!**/*.mp3
and included byclient/**
contracts/Scarb.lock
is excluded by!**/*.lock
and included bycontracts/**
eliza-starter/.env.example
is excluded by none and included by noneeliza-starter/.gitignore
is excluded by none and included by noneeliza-starter/LICENSE
is excluded by none and included by noneeliza-starter/README.md
is excluded by none and included by noneeliza-starter/actions/join_game_action.ts
is excluded by none and included by noneeliza-starter/actions/move_game_action.ts
is excluded by none and included by noneeliza-starter/actions/new_game_action.ts
is excluded by none and included by noneeliza-starter/characters/eliza.character.json
is excluded by none and included by noneeliza-starter/characters/tate.character.json
is excluded by none and included by noneeliza-starter/characters/trump.character.json
is excluded by none and included by noneeliza-starter/dist/actions/join_game_action.d.ts
is excluded by!**/dist/**
and included by noneeliza-starter/dist/actions/move_game_action.d.ts
is excluded by!**/dist/**
and included by noneeliza-starter/dist/actions/new_game_action.d.ts
is excluded by!**/dist/**
and included by noneeliza-starter/dist/environment.d.ts
is excluded by!**/dist/**
and included by noneeliza-starter/dist/src/character.d.ts
is excluded by!**/dist/**
and included by noneeliza-starter/dist/src/index.d.ts
is excluded by!**/dist/**
and included by noneeliza-starter/dist/utils/index.d.ts
is excluded by!**/dist/**
and included by noneeliza-starter/environment.ts
is excluded by none and included by noneeliza-starter/message-templates.json
is excluded by none and included by noneeliza-starter/package.json
is excluded by none and included by noneeliza-starter/pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
and included by noneeliza-starter/src/character.ts
is excluded by none and included by noneeliza-starter/src/index.ts
is excluded by none and included by noneeliza-starter/tsconfig.json
is excluded by none and included by noneeliza-starter/utils/index.ts
is excluded by none and included by nonepackage.json
is excluded by none and included by nonepnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
and included by none
📒 Files selected for processing (74)
client/.gitignore
(1 hunks)client/dev.sh
(1 hunks)client/dojoConfig.ts
(1 hunks)client/package.json
(3 hunks)client/src/App.tsx
(2 hunks)client/src/AppWrapper.tsx
(2 hunks)client/src/components/boundaries/error-boundary.tsx
(2 hunks)client/src/components/controller-trophy.tsx
(1 hunks)client/src/components/gameplay/end-game-button.tsx
(1 hunks)client/src/components/gameplay/game-board.tsx
(7 hunks)client/src/components/gameplay/game-message.tsx
(6 hunks)client/src/components/gameplay/game-navigation.tsx
(1 hunks)client/src/components/gameplay/restart-button.tsx
(1 hunks)client/src/components/gameplay/timeout-button.tsx
(1 hunks)client/src/components/header.tsx
(3 hunks)client/src/components/lobby/duels-skeleton.tsx
(1 hunks)client/src/components/lobby/duels.tsx
(2 hunks)client/src/components/lobby/empty-duels.tsx
(1 hunks)client/src/components/lobby/leaderboard.tsx
(2 hunks)client/src/components/lobby/live-duels.tsx
(5 hunks)client/src/components/message-area.tsx
(2 hunks)client/src/components/pits.tsx
(3 hunks)client/src/components/profile/empty-game-history.tsx
(1 hunks)client/src/components/profile/game-history-skeleton.tsx
(1 hunks)client/src/components/profile/game-history.tsx
(1 hunks)client/src/components/profile/user-section.tsx
(5 hunks)client/src/components/seed.tsx
(2 hunks)client/src/components/ui/dialog.tsx
(1 hunks)client/src/components/ui/svgs/bubble.tsx
(1 hunks)client/src/components/ui/svgs/users-plus.tsx
(1 hunks)client/src/dojo/DojoContext.tsx
(2 hunks)client/src/dojo/createSystemCalls.ts
(1 hunks)client/src/hooks/useAudioControl.ts
(4 hunks)client/src/hooks/useControllerData.ts
(0 hunks)client/src/lib/config.ts
(1 hunks)client/src/lib/constants.ts
(9 hunks)client/src/pages/Home.tsx
(2 hunks)client/src/pages/Leaderboard.tsx
(0 hunks)client/src/pages/Lobby.tsx
(19 hunks)client/src/pages/Profile.tsx
(4 hunks)client/src/pages/games/Gameplay.tsx
(2 hunks)contracts/.tool-versions
(1 hunks)contracts/Scarb.toml
(2 hunks)contracts/dojo_dev.toml
(2 hunks)contracts/dojo_sepolia.toml
(2 hunks)contracts/dojo_slot.toml
(1 hunks)contracts/manifest_dev.json
(18 hunks)contracts/manifest_sepolia.json
(18 hunks)contracts/src/components/initializable.cairo
(1 hunks)contracts/src/components/playable.cairo
(14 hunks)contracts/src/components/profile.cairo
(1 hunks)contracts/src/constants.cairo
(1 hunks)contracts/src/elements/tasks/clearing.cairo
(1 hunks)contracts/src/elements/tasks/collecting.cairo
(1 hunks)contracts/src/elements/tasks/dominating.cairo
(1 hunks)contracts/src/elements/tasks/interface.cairo
(1 hunks)contracts/src/elements/tasks/mastering.cairo
(1 hunks)contracts/src/elements/tasks/reigning.cairo
(1 hunks)contracts/src/elements/trophies/collector.cairo
(1 hunks)contracts/src/elements/trophies/dominator.cairo
(1 hunks)contracts/src/elements/trophies/extractor.cairo
(1 hunks)contracts/src/elements/trophies/interface.cairo
(1 hunks)contracts/src/elements/trophies/strategist.cairo
(1 hunks)contracts/src/elements/trophies/victor.cairo
(1 hunks)contracts/src/lib.cairo
(1 hunks)contracts/src/systems/actions.cairo
(0 hunks)contracts/src/systems/mancala.cairo
(1 hunks)contracts/src/systems/profile.cairo
(1 hunks)contracts/src/tests/setup.cairo
(4 hunks)contracts/src/tests/test_world.cairo
(15 hunks)contracts/src/types/task.cairo
(1 hunks)contracts/src/types/trophy.cairo
(1 hunks)contracts/src/utils/board.cairo
(2 hunks)contracts/torii_dev.toml
(1 hunks)
💤 Files with no reviewable changes (3)
- contracts/src/systems/actions.cairo
- client/src/pages/Leaderboard.tsx
- client/src/hooks/useControllerData.ts
✅ Files skipped from review due to trivial changes (9)
- contracts/.tool-versions
- client/src/components/gameplay/timeout-button.tsx
- contracts/src/constants.cairo
- client/src/components/gameplay/restart-button.tsx
- client/src/components/gameplay/end-game-button.tsx
- client/src/components/ui/svgs/users-plus.tsx
- client/src/lib/config.ts
- client/.gitignore
- client/src/components/ui/svgs/bubble.tsx
🧰 Additional context used
🪛 Shellcheck (0.10.0)
client/dev.sh
[warning] 2-2: ShellCheck can't follow non-constant source. Use a directive to specify location.
(SC1090)
🪛 Biome (1.9.4)
client/src/pages/Lobby.tsx
[error] 401-407: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
client/src/components/profile/user-section.tsx
[error] 113-113: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
client/src/pages/games/Gameplay.tsx
[error] 39-43: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with
(lint/complexity/noUselessTernary)
🪛 Gitleaks (8.21.2)
contracts/dojo_slot.toml
27-27: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
contracts/dojo_sepolia.toml
27-27: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: test
🔇 Additional comments (58)
client/src/dojo/DojoContext.tsx (3)
27-27
: LGTM: Client extraction from setup resultThe addition of the
client
property aligns with theSetupResult
type and maintains consistency with the context interface.
36-36
: Good refactoring: Simplified burner manager data handlingThe change to store the complete burner manager data improves maintainability by eliminating the need to manually update destructured properties when the burner manager interface changes.
43-46
: LGTM: Robust context value constructionThe changes provide:
- Complete burner manager functionality through spreading
- Proper fallback to masterAccount
- Type-safe inclusion of the client property
client/src/AppWrapper.tsx (2)
3-3
: Well-structured setup status messagesGood addition of user-friendly status messages with proper typing. The messages are clear and informative for users during the loading process.
Also applies to: 7-7, 10-19
22-25
: LGTM: Type-safe state managementGood use of TypeScript's Partial type for setup status state management.
contracts/src/components/initializable.cairo (1)
1-45
: Initialization logic is correctly implemented.The
initialize
function properly sets up the game counter with appropriate checks and updates.contracts/src/types/task.cairo (1)
1-81
: LGTM!The implementation of the
Task
enum and its associated traits is clean and well-structured. The conversion implementations betweenTask
andu8
are correctly defined, and the match statements cover all task variants with appropriate default cases.contracts/src/systems/mancala.cairo (1)
67-87
: Verify the trophy initialization logic to prevent off-by-one errors.In the loop initializing trophies, the loop decrements
trophy_id
until it reaches zero. Ensure that all intended trophies are initialized and that you're not missing the trophy withtrophy_id
zero if it's valid.Run the following script to check the range of initialized trophies:
If trophy ID
0
is a valid trophy, consider adjusting the loop condition to include it.✅ Verification successful
Trophy initialization logic is correct
The current implementation correctly initializes all valid trophies. Trophy ID 0 represents
Trophy::None
, which is a special case used to represent invalid or no trophy, and should not be initialized. The loop correctly processes all valid trophies from 9 down to 1, matching theTROPHY_COUNT
of 9.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that trophies with IDs from 1 to TROPHY_COUNT are initialized. # Test: Check for usage of trophy_id == 0 ast-grep --pattern $'let mut trophy_id: u8 = TROPHY_COUNT;\nwhile trophy_id > 0 {\n $$$\n trophy_id -= 1;\n}'Length of output: 108
Script:
#!/bin/bash # Find Trophy type definition and TROPHY_COUNT ast-grep --pattern 'enum Trophy {' # Find TROPHY_COUNT constant rg "const TROPHY_COUNT" -A 2 # Look for any trophy with ID 0 references rg "Trophy::(\w+) = 0" --type cairoLength of output: 276
Script:
#!/bin/bash # View trophy type definition cat contracts/src/types/trophy.cairo # Search for any zero references in trophy definitions without file type restriction rg "Trophy::\w+ = 0"Length of output: 11443
client/src/components/gameplay/game-board.tsx (1)
206-215
: Verify logic for determiningisPlayerSeed
In the function determining
isPlayerSeed
(lines 206~ to 215~), ensure that the logic correctly handles cases whereaccount.account?.address
may beundefined
or when the user is not logged in. This could lead to unexpected behavior when determining seed ownership.client/src/components/gameplay/game-message.tsx (1)
132-154
: Handle Eliza's states consistently inmoveMessageOnTimer
In the
moveMessageOnTimer
function, the conditions for displaying Eliza's messages are nested within the check forgame_node?.winner === "0x0"
. Ensure that the logic correctly handles scenarios where the game has a winner or the game status changes, to prevent inconsistent UI messages.contracts/src/components/playable.cairo (2)
46-46
: Validate state mutation withref self
The change to use
ref self: ComponentState<TState>
indicates intentional state mutation. Ensure that this aligns with the component's design and that all state mutations are managed correctly.
228-234
: Handle potential integer overflows when updating tasksWhen updating task progress with
arcade_store.progress
, ensure that thecaptured_seeds
value is within the expected range to prevent integer overflows.client/src/lib/constants.ts (3)
619-655
: Confirm Policy Targets and Methods AlignmentIn the
POLICIES
array, thetarget
for each policy has been updated to useMANCALA_ADDRESS
andPROFILE_ADDRESS
. Ensure that each method corresponds to the correct contract address and that the smart contracts expose these methods.
Line range hint
661-771
: Update GraphQL Queries to Reflect New Backend ModelsThe GraphQL queries have been updated to use the
mancalaAlpha
namespace (e.g.,mancalaAlphaMancalaBoardModels
). Verify that the backend service has these models and that the queries will function as expected.
608-615
: Verify the Accuracy of Contract AddressesNew constants
MANCALA_ADDRESS
,PROFILE_ADDRESS
, andELIZA_ADDRESS
have been added. Please ensure that these addresses are correct and correspond to the intended smart contracts on the specified network.Run the following script to verify the addresses:
✅ Verification successful
Contract Addresses Verified Successfully
The addresses are consistently used throughout the codebase and their usage patterns align with their intended purposes. MANCALA_ADDRESS is used for game operations, PROFILE_ADDRESS for profile management, and ELIZA_ADDRESS for AI opponent functionality.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that the contract addresses are correctly defined. # Expected addresses (update these with the correct values if known) EXPECTED_MANCALA_ADDRESS="0x470f026bf97f0781492a95ebb9031da1c524601e8c2a285534545d33ca44797" EXPECTED_PROFILE_ADDRESS="0x4a992660cbd6a91cda1e1697e43c52641f3818aeabcf96658a986322603ef85" EXPECTED_ELIZA_ADDRESS="0x076795eb2cdc3e799364f661a409edbe0f204b67625b179a6880733893f7004d" # Actual addresses from the code ACTUAL_MANCALA_ADDRESS="0x470f026bf97f0781492a95ebb9031da1c524601e8c2a285534545d33ca44797" ACTUAL_PROFILE_ADDRESS="0x4a992660cbd6a91cda1e1697e43c52641f3818aeabcf96658a986322603ef85" ACTUAL_ELIZA_ADDRESS="0x076795eb2cdc3e799364f661a409edbe0f204b67625b179a6880733893f7004d" # Verify addresses if [ "$ACTUAL_MANCALA_ADDRESS" != "$EXPECTED_MANCALA_ADDRESS" ]; then echo "MANCALA_ADDRESS does not match the expected address." fi if [ "$ACTUAL_PROFILE_ADDRESS" != "$EXPECTED_PROFILE_ADDRESS" ]; then echo "PROFILE_ADDRESS does not match the expected address." fi if [ "$ACTUAL_ELIZA_ADDRESS" != "$EXPECTED_ELIZA_ADDRESS" ]; then echo "ELIZA_ADDRESS does not match the expected address." fiLength of output: 992
Script:
#!/bin/bash # Search for occurrences of these addresses and related contract references echo "=== Searching for MANCALA_ADDRESS ===" rg -i "0x470f026bf97f0781492a95ebb9031da1c524601e8c2a285534545d33ca44797" --type ts --type js rg -i "mancala.*address" --type ts --type js echo -e "\n=== Searching for PROFILE_ADDRESS ===" rg -i "0x4a992660cbd6a91cda1e1697e43c52641f3818aeabcf96658a986322603ef85" --type ts --type js rg -i "profile.*address" --type ts --type js echo -e "\n=== Searching for ELIZA_ADDRESS ===" rg -i "0x076795eb2CDc3E799364F661A409EDBE0f204b67625B179a6880733893f7004d" --type ts --type js rg -i "eliza.*address" --type ts --type js echo -e "\n=== Looking for contract deployment files ===" fd -e ts -e js -e json "deploy|contract" --type fLength of output: 4188
contracts/src/elements/tasks/interface.cairo (1)
1-4
: IntroduceTaskTrait
Interface CorrectlyThe
TaskTrait
is defined with two methods:identifier
anddescription
. Ensure that the return types and parameters match the intended use and that any implementing structures conform to this trait.contracts/src/elements/tasks/clearing.cairo (1)
10-12
:⚠️ Potential issueEnsure Proper String Handling in
description
MethodThe
description
method usesformat!
to create a string. Verify that theformat!
macro is supported and that it returns aByteArray
as intended. In Cairo, string manipulation is limited, and you may need to construct theByteArray
manually.Consider constructing the
ByteArray
explicitly:fn description(count: u32) -> ByteArray { - format!("Collect {} seed", count) + ByteArray::new("Collect ") + ByteArray::from_u32(count) + ByteArray::new(" seed") }Ensure that the
ByteArray
operations are valid and that the necessary imports or helper functions are included.Likely invalid or redundant comment.
contracts/src/elements/tasks/dominating.cairo (1)
1-13
: LGTM! Clean and well-structured implementation.The implementation correctly follows the TaskTrait interface with appropriate use of #[inline] attributes and clear description formatting.
contracts/src/elements/tasks/reigning.cairo (1)
1-13
: LGTM! Clear and precise implementation.The implementation correctly follows the TaskTrait interface with good description clarity by using "total" in the message.
client/dojoConfig.ts (2)
7-7
: Environment change from test to staging confirmed.The toriiUrl endpoint change from
mancala-t
tomancala-e
aligns with the staging transition.
9-9
: Verify the masterAddress case change.The masterAddress has a case change from 'E' to 'e'. While Starknet addresses are case-insensitive for hex characters, let's verify this doesn't impact any existing integrations.
✅ Verification successful
Case difference in masterAddress is safe to proceed
The case change from 'E' to 'e' in the masterAddress is safe as:
- Starknet addresses are case-insensitive for hex characters
- The address appears in only two isolated contexts (contract config and client config)
- No other variations or dependent code found that could be impacted
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for any hardcoded references to the old address format rg -i "0x02A54eFf65D55a2E7D2fC7E23eF0F0e6030dB0313b16c8F0eaD0b4a83807f6d6"Length of output: 284
Script:
#!/bin/bash # Search for imports of dojoConfig.ts and dojo_sepolia.toml echo "=== Searching for dojoConfig.ts imports ===" rg -l "dojoConfig" echo -e "\n=== Searching for dojo_sepolia.toml usage ===" rg -l "dojo_sepolia" echo -e "\n=== Searching for any other variations of the address with different casing ===" # Using parts of the address to catch any variations rg -i "2[aA]54[eE][fF][fF].*2[eE]7[dD]2[fF][cC]7[eE]23"Length of output: 754
client/src/pages/Home.tsx (1)
13-17
: 🛠️ Refactor suggestionAdd error handling for connection logic.
The auto-connection logic should handle cases where no connectors are available to prevent potential runtime errors.
Consider adding error handling:
useEffect(() => { if (!account?.address) { + if (connectors.length === 0) { + console.warn("No connectors available"); + return; + } connect({ connector: connectors[0] }); } }, [account, connect, connectors]);contracts/src/elements/trophies/collector.cairo (1)
80-83
: Verify task generation logic.The task generation uses the same value for both parameters of
tasks()
, which might not be intentional.✅ Verification successful
Task generation logic is correct
The consistent pattern of using the same value for both
count
andtotal
parameters is intentional and correct. All trophy implementations follow this pattern, and theTask::tasks
method uses these parameters for different purposes:count
for description generation andtotal
for task creation.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check task generation patterns across trophies rg "Task::\w+\.tasks\(level, total, total\)" --type cairoLength of output: 89
Script:
#!/bin/bash # Search for task generation patterns without file type restriction echo "=== Task generation patterns ===" rg "Task::\w+\.tasks\(.*\)" echo -e "\n=== Task enum definition ===" rg "enum Task" echo -e "\n=== All task method implementations ===" rg "fn tasks.*->.*BushidoTask"Length of output: 1425
Script:
#!/bin/bash # Look for Task enum implementation and its tasks method echo "=== Task implementation ===" rg -A 10 "enum Task \{" contracts/src/types/task.cairo echo -e "\n=== Task::tasks method implementation ===" rg -A 5 "fn tasks\(" contracts/src/types/task.cairoLength of output: 691
contracts/src/elements/trophies/strategist.cairo (1)
25-32
: Points progression is well-balanced.The doubling of points per level (20 → 40 → 80) provides a good balance between reward and challenge.
client/src/App.tsx (2)
18-23
: Verify the configuration values for alpha deployment.The namespace and slot values have been updated for alpha stage. Ensure these values match the deployment configuration.
65-72
: 🛠️ Refactor suggestionClean up leaderboard-related code.
The leaderboard route has been removed, but there might be leftover references or components.
Ensure all leaderboard-related code is removed to maintain a clean codebase.
client/src/components/pits.tsx (1)
3-3
: LGTM! Audio feedback integration looks good.The addition of the
useAudioControl
hook and its integration enhances the user experience by providing audio feedback.Also applies to: 47-47
contracts/src/tests/setup.cairo (3)
12-14
: LGTM! System dispatcher transition looks good.The transition from actions to a dedicated Mancala system dispatcher improves the code organization by making it more domain-specific.
74-77
: LGTM! Systems struct initialization is correct.The initialization of the Mancala system dispatcher is properly implemented.
49-53
: Verify trophy system integration.The addition of trophy-related events suggests a new achievement system. Please ensure that:
- Trophy creation and progression events are properly handled
- Achievement triggers are correctly implemented in the Mancala system
client/src/pages/Profile.tsx (1)
18-18
: Verify data model transition to alpha environment.The transition from dev to alpha environment (
mancalaDevMancalaBoardModels
→mancalaAlphaMancalaBoardModels
) needs verification:
- Ensure all queries are updated consistently
- Verify data schema compatibility
Also applies to: 36-36
client/src/components/profile/game-history-skeleton.tsx (1)
8-77
: LGTM! Skeleton UI improvements enhance user experience.The restructured skeleton loading state using Material Tailwind components provides:
- Better visual hierarchy with Card component
- Improved layout organization
- Consistent styling with the actual content
client/src/components/lobby/duels-skeleton.tsx (1)
7-81
: LGTM! Consistent skeleton UI implementation.The skeleton UI implementation maintains consistency with the game history component while providing:
- Clean table layout
- Proper spacing and alignment
- Responsive design considerations
client/src/pages/games/Gameplay.tsx (2)
62-62
: Clean component structure with proper styling.The main component's structure is well-organized with appropriate styling and background implementation.
1-1
: Environment transition looks good, but verify data model compatibility.The transition from dev to alpha environment (
mancalaDevMancalaBoardModels
→mancalaAlphaMancalaBoardModels
) is implemented correctly. The addition of connection management enhances user experience.Run this script to verify the data model compatibility:
Also applies to: 5-5, 34-34, 39-40
client/src/components/ui/dialog.tsx (1)
1-120
: Well-implemented dialog components with proper accessibility.The dialog implementation follows best practices:
- Uses Radix UI for robust accessibility
- Proper TypeScript typing with forwardRef
- Includes screen reader support
- Clean component composition
client/src/dojo/createSystemCalls.ts (1)
62-64
: Verify contract event emission order change.The change from
events[1]
toevents[0]
suggests a modification in contract event emission order. While the optional chaining is a good addition, we should verify this change.client/src/components/lobby/live-duels.tsx (1)
38-40
: Good empty state handling.The implementation of empty state with a customizable message is clean and user-friendly.
client/src/components/lobby/duels.tsx (1)
4-17
: LGTM! Clean implementation of clipboard functionality.The addition of clipboard-related icons and state management is well-structured and follows React best practices.
Also applies to: 94-95
contracts/torii_dev.toml (1)
17-20
: Verify historical events configurationThe configuration tracks trophy-related events. Ensure these event names match the exact event names emitted by the contracts.
Let's verify the event names in the contracts:
✅ Verification successful
Event names in historical configuration are correct
The event names
mancala_alpha-TrophyCreation
andmancala_alpha-TrophyProgression
match exactly with the events defined in the contracts and are consistently used across all configuration files.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for trophy-related event definitions rg -A 2 "event\s+(TrophyCreation|TrophyProgression)" --type cairoLength of output: 97
Script:
#!/bin/bash # First find cairo files echo "=== Finding Cairo files ===" fd -e cairo # Then search for trophy events (both with and without prefix) echo -e "\n=== Searching for trophy events ===" rg -i "event.*trophy(creation|progression)" # Also search with exact names from config echo -e "\n=== Searching for exact event names ===" rg "mancala_alpha-TrophyCreation|mancala_alpha-TrophyProgression"Length of output: 3208
contracts/Scarb.toml (1)
4-4
: Version bump and dependency updates look goodThe version bump to 0.3.0 is appropriate given the significant changes. Dependencies are correctly pinned to specific versions.
Also applies to: 13-14
contracts/dojo_slot.toml (2)
29-31
: Security: Same IPFS credential exposure issueSimilar to dojo_dev.toml, this file also contains hardcoded IPFS credentials.
33-34
: Verify raw event processing configurationThe configuration enables raw event processing and tracks trophy progression events. Ensure this aligns with the event processing capabilities of your infrastructure.
Let's verify the event processing setup:
✅ Verification successful
Raw event processing configuration is properly integrated
The configuration aligns with the project's infrastructure as evidenced by consistent raw event processing setup across development and Sepolia environments, proper manifest integration, and test coverage.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for raw event processing implementations rg -l "TrophyProgression.*event" --type cairoLength of output: 77
Script:
#!/bin/bash # Search for TrophyProgression without file type restriction rg -l "TrophyProgression" # Search for event processing related configurations rg -l "raw.*=.*true" --type toml # Find all dojo_slot.toml files fd "dojo_slot.toml"Length of output: 398
contracts/dojo_sepolia.toml (3)
19-21
: LGTM! Writers configuration updated for the new namespace.The writers configuration has been properly updated to reflect the new namespace structure, including trophy-related components.
33-34
: LGTM! Additional configuration flags for trophy system.The raw flag and historical tracking for trophy progression have been properly configured.
7-8
: Verify the configuration changes for the staging environment.The changes in world configuration indicate a transition from development to alpha stage:
- Seed updated to "mancala-achievement"
- Namespace changed to "mancala_alpha"
These changes align with the staging objectives.
Run the following script to verify the configuration consistency across files:
Also applies to: 16-16
✅ Verification successful
Configuration changes for staging environment are properly implemented
The configuration changes show correct environment separation:
- Staging environment (dojo_sepolia.toml) uses unique seed "mancala-achievement"
- Development environments maintain original "mancala" seed
- Namespace "mancala_alpha" is consistently set across all environments
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for any inconsistencies in namespace and seed configuration # across different environment files. echo "Checking namespace and seed configuration..." rg -l "mancala_dev|mancala_alpha|mancala-achievement" --type tomlLength of output: 268
Script:
#!/bin/bash # Check actual content of configuration files for seed and namespace values echo "Checking seed configurations..." rg -A 1 -B 1 "^seed\s*=" --type toml echo -e "\nChecking namespace configurations..." rg -A 1 -B 1 "namespace" --type tomlLength of output: 1047
client/src/components/message-area.tsx (1)
60-60
: Verify the useEffect dependencies are exhaustive.The restart_game function has been added to the dependency array, but ensure all other dependencies used within the effect are also included.
Run the following script to check for potential missing dependencies:
client/package.json (3)
29-29
: LGTM! New dependencies added.The following dependencies have been added:
- @headlessui/react for UI components
- @radix-ui/react-dialog for dialog components
- concurrently for running multiple commands
Also applies to: 36-36, 49-49
8-8
: Verify the dev script changes.The development script has been updated to use a shell script. Ensure that
dev.sh
exists and has proper execute permissions.Run the following script to verify the dev script setup:
✅ Verification successful
Dev script exists but doesn't require execute permissions
The
client/dev.sh
file exists and is properly referenced in package.json. Since the script is executed usingbash dev.sh
rather than direct execution, it doesn't require execute permissions to work correctly.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify dev script existence and permissions echo "Checking dev script..." if [ -f "dev.sh" ]; then ls -l dev.sh else echo "dev.sh not found" fiLength of output: 117
Script:
#!/bin/bash # Description: Verify dev script in client directory echo "Checking dev script in client directory..." if [ -f "client/dev.sh" ]; then ls -l client/dev.sh else echo "dev.sh not found in client directory" fiLength of output: 205
17-25
: Review package version changes for compatibility.Several package versions have been modified:
- @cartridge/connector downgraded to ^0.5.5
- @cartridge/controller upgraded to ^0.5.8
- @dojoengine/* packages upgraded to 1.0.8
Run the following script to check for potential version conflicts:
✅ Verification successful
Package versions are compatible and well-structured
The version changes are safe because:
- All @dojoengine packages (except recs) are consistently set to 1.0.8
- @dojoengine/recs at ^2.0.13 is an intended different major version
- @Cartridge packages use compatible version ranges
- Required peer dependencies (e.g., starknet) are satisfied
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for potential version conflicts and security advisories # Check npm for version compatibility echo "Checking version compatibility..." npm info "@cartridge/connector@^0.5.5" peerDependencies npm info "@cartridge/controller@^0.5.8" peerDependencies npm info "@dojoengine/[email protected]" peerDependencies # Check for known vulnerabilities echo "Checking for vulnerabilities..." npm auditLength of output: 703
Script:
#!/bin/bash # Find all package.json files and their content echo "=== Package.json files ===" fd package.json --type f --exec cat {} # Search for import statements of these packages echo -e "\n=== Package imports ===" rg -A 1 "from ['\"]@(cartridge|dojoengine)/" --type ts --type tsx --type js --type jsx # Look for version-specific patterns or constraints echo -e "\n=== Version constraints ===" rg "(@cartridge|@dojoengine)" --type jsonLength of output: 6713
contracts/manifest_sepolia.json (3)
1308-1314
: Review state mutability changes in contract functions.Several functions have had their state mutability changed from "view" to "external". This change affects how the functions can modify contract state.
Ensure that:
- All state-modifying functions are properly marked as "external"
- Pure view functions remain as "view"
- Access control is properly implemented for external functions
Also applies to: 1365-1505
1958-1968
: LGTM! New trophy system events added.Trophy-related events have been properly configured:
- TrophyCreation
- TrophyProgression
These align with the achievement system implementation.
4-5
: Verify contract addresses and seed configuration.The world configuration has been updated with new addresses and seed values. Ensure these values are correct for the respective environments.
Run the following script to verify contract addresses:
✅ Verification successful
Contract addresses and seed configurations verified successfully
The contract addresses and seed values are correctly configured and consistent across all environment files (manifest and dojo configuration files):
- Sepolia environment with seed "mancala-achievement"
- Dev environment with seed "mancala"
- Slot environment with seed "mancala"
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify contract addresses across environments echo "Checking contract addresses..." rg -A 1 '"address":\s*"0x[a-fA-F0-9]+"' --type jsonLength of output: 1829
Script:
#!/bin/bash # Search for any references to these addresses in other files # and check for any documentation about contract configurations echo "Checking for address references and documentation..." rg -l "0x2570a4240bf789d09bdbc2cb8f870ad7879b0737d453ee1d70f5dfaedd9f3f6|0x7e6333cfb9768d94ffa94daf40d8261b27a245a154e180e8ed052781a2e1779|0x4068272626b01237de6009110492f508fb9de4d9358b6ecf15ffb02a1c7e0a3" echo -e "\nChecking for configuration documentation..." fd -t f "README|CONTRIBUTING|DEPLOY|CONFIG" -e md -e txtLength of output: 762
Script:
#!/bin/bash # Check contracts README and verify configuration consistency echo "Checking contracts README..." cat contracts/README.md echo -e "\nVerifying configuration consistency..." echo "Sepolia configs:" cat contracts/dojo_sepolia.toml echo -e "\nDev configs:" cat contracts/dojo_dev.toml echo -e "\nSlot configs:" cat contracts/dojo_slot.tomlLength of output: 6400
contracts/manifest_dev.json (5)
1255-1256
: Contract deployment changes detected.The contract address and class hash have been updated, indicating a new deployment. This is consistent with the transition to alpha stage.
Line range hint
1358-1506
: Well-structured game system interface.The IMancalaSystem interface provides a comprehensive set of functions for managing the Mancala game, including:
- Game lifecycle (new_game, join_game, create_private_game)
- Game mechanics (move, get_score, is_game_over)
- Player management (timeout, forfeited)
- Game state management (request_restart_game, restart_current_game)
All functions are correctly marked as external for proper access control.
Line range hint
1728-1750
: Profile system implementation looks good.The IPlayerProfile interface provides essential functionality for player profile management:
- Profile creation with name
- Profile updates with URI support
- View-only functions for data safety
The implementation follows best practices for player data management.
1899-1930
: Complete set of game models with proper alpha stage tagging.The models cover all essential aspects of the game:
- Game state (GameCounter, MancalaBoard)
- Player data (Player, Profile)
- Game mechanics (Pit, Seed)
All models are correctly tagged with
mancala_alpha
prefix.
1937-1968
: Comprehensive event system for game actions and achievements.The event system includes:
- Game mechanics events (Capture, EndTurn, PlayerMove)
- Special events (PlayerExtraTurn)
- Achievement events (TrophyCreation, TrophyProgression)
All events are properly tagged with
mancala_alpha
prefix and have unique selectors.
{players[index]?.name | ||
? players[index]?.name | ||
: truncateString(address)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve type safety in name rendering.
The optional chaining usage suggests potential type safety issues. Consider using proper TypeScript types and null coalescing.
- {players[index]?.name
- ? players[index]?.name
- : truncateString(address)}
+ {players[index]?.name ?? truncateString(address)}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
{players[index]?.name | |
? players[index]?.name | |
: truncateString(address)} | |
{players[index]?.name ?? truncateString(address)} |
</td> | ||
<td> | ||
<p className="font-normal text-[#BDC2CC] text-center"> | ||
Lvl {wins < 4 ? 1 : Math.floor(wins / 4) + 1} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Extract level calculation logic.
The level calculation logic should be moved to a utility function for better maintainability and reusability.
+// In utils.ts
+export const calculatePlayerLevel = (wins: number): number =>
+ wins < 4 ? 1 : Math.floor(wins / 4) + 1;
+// In component
- Lvl {wins < 4 ? 1 : Math.floor(wins / 4) + 1}
+ Lvl {calculatePlayerLevel(wins)}
Committable suggestion skipped: line range outside the PR's diff.
@@ -2,7 +2,7 @@ import mancala_duels_logo from "../../assets/mancala_duels.png"; | |||
|
|||
export default function EmptyGameHistory({ id }: { id: string }) { | |||
return ( | |||
<div className="w-[874px] h-[874px] bg-[url('./assets/lobby-box-long.png')] bg-contain bg-no-repeat p-8"> | |||
<div className="bg-[#0F1116] bg-contain bg-center bg-no-repeat border-2 border-[#272A32] rounded-2xl w-[full h-[437px] flex flex-col items-center justify-center"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix CSS class syntax error and improve accessibility.
The className has syntax errors and accessibility can be improved:
w-[full
is missing a closing bracket- Missing ARIA attributes for better screen reader support
Apply this diff to fix the issues:
- <div className="bg-[#0F1116] bg-contain bg-center bg-no-repeat border-2 border-[#272A32] rounded-2xl w-[full h-[437px] flex flex-col items-center justify-center">
+ <div
+ className="bg-[#0F1116] bg-contain bg-center bg-no-repeat border-2 border-[#272A32] rounded-2xl w-full h-[437px] flex flex-col items-center justify-center"
+ role="region"
+ aria-label="Empty game history">
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
<div className="bg-[#0F1116] bg-contain bg-center bg-no-repeat border-2 border-[#272A32] rounded-2xl w-[full h-[437px] flex flex-col items-center justify-center"> | |
<div | |
className="bg-[#0F1116] bg-contain bg-center bg-no-repeat border-2 border-[#272A32] rounded-2xl w-full h-[437px] flex flex-col items-center justify-center" | |
role="region" | |
aria-label="Empty game history"> |
> | ||
<UserIcon | ||
color="#F58229" | ||
className="w-5 h-5 text-white" | ||
/> | ||
</div> | ||
</div> | ||
<p className="font-normal text-white"> | ||
{item.challenger.name | ||
? item.challenger.name | ||
: truncateString( | ||
games[index].node.player_one, | ||
)} | ||
</p> | ||
</div> | ||
</td> | ||
<td className="flex flex-row px-4 h-16 space-x-5 w-[200px] text-center border-y-2 border-[#1A1E25] bg-[#111419]"> | ||
{item.challenged !== "0x0" ? ( | ||
<div className="flex flex-row items-center space-x-2.5 w-fit"> | ||
<div | ||
className="w-8 h-8 flex items-center justify-center rounded-full" | ||
style={{ backgroundColor: challengedColor }} | ||
> | ||
<UserIcon color="#F58229" className="w-5 h-5 text-white" /> | ||
</div> | ||
</td> | ||
<td className="flex flex-row items-center p-4 space-x-5 w-[200px] justify-center"> | ||
{games[index].node.player_two !== "0x0" ? ( | ||
<div className="flex flex-row items-center space-x-2.5 w-fit"> | ||
{/* <img src={item.challenged.profilePicture} width={35} height={35} alt={`${item.challenged.name} profile picture`} className="rounded-full" /> */} | ||
<div className="p-1 rounded-full bg-gradient-to-r bg-[#15181E] from-[#2E323A] via-[#4B505C] to-[#1D2026] relative"> | ||
<div | ||
className="bg-[#FFE600] w-8 h-8 flex items-center justify-center rounded-full" | ||
style={{ backgroundColor: challengedColor }} | ||
> | ||
<UserIcon | ||
color="#F58229" | ||
className="w-5 h-5 text-white" | ||
/> | ||
</div> | ||
</div> | ||
<p className="font-normal text-white"> | ||
{item.challenged.name | ||
? item.challenged.name | ||
: truncateString( | ||
games[index].node.player_two, | ||
)} | ||
</p> | ||
</div> | ||
) : ( | ||
<p className="text-white">Matchmaking</p> | ||
)} | ||
</td> | ||
<td className="w-[200px] text-center ml-8"> | ||
<p className="font-normal text-[#FAB580]"> | ||
{item.winner.name | ||
? item.winner.name | ||
: truncateString(games[index].node.winner)} | ||
<Typography variant="paragraph" className="font-medium leading-none text-white"> | ||
{truncateString(item.challenged)} | ||
</Typography> | ||
</div> | ||
) : ( | ||
<div className="flex flex-row items-center justify-center w-full h-16"> | ||
<p className="text-[#646976] font-semibold text-center w-full"> | ||
Matchmaking... | ||
</p> | ||
</td> | ||
<td className="w-[200px] text-end pr-12"> | ||
<p className="font-normal text-[#F97E22]"> | ||
{date.toLocaleDateString()} | ||
</p> | ||
</td> | ||
</tr> | ||
); | ||
})} | ||
</tbody> | ||
</table> | ||
</div> | ||
</div> | ||
</Card> | ||
</div> | ||
)} | ||
</td> | ||
<td className="w-[125px] px-4 text-center h-16 flex flex-col justify-center bg-[#111419] border-y-2 border-[#1A1E25]"> | ||
<p className="font-normal text-[#FAB580]"> | ||
{truncateString(item.winner)} | ||
</p> | ||
</td> | ||
<td className="w-[200px] px-4 text-end h-16 flex flex-col items-start justify-center bg-[#111419] border-y-2 border-r-2 border-[#1A1E25] rounded-r-xl"> | ||
<p className="font-normal text-[#F97E22] ml-2.5"> | ||
{date.toLocaleDateString().replace(/\//g, "-")} | ||
</p> | ||
</td> | ||
</tr> | ||
); | ||
})} | ||
</tbody> | ||
</table> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Optimize performance and improve type safety.
The table body implementation has several areas for improvement:
- Fixed positioning with absolute dimensions could cause layout issues
- Missing TypeScript interfaces for data structure
- Potential performance issues with large datasets
Consider creating an interface for the game data:
interface GameHistoryItem {
challenger: string;
challenged: string;
winner: string;
date: string;
}
And optimize the table body:
- <tbody className="h-[450px] w-[800px] rounded-b-xl fixed overflow-y-scroll overflow-x-clip space-y-2 bg-[#0F1116]">
+ <tbody className="max-h-[450px] w-full rounded-b-xl overflow-y-auto space-y-2 bg-[#0F1116]">
Also, consider implementing virtualization for better performance with large datasets using a library like react-window
or react-virtualized
.
return ( | ||
<div className="w-full"> | ||
<Card className="w-full h-full bg-transparent"> | ||
<div className="w-full text-left bg-transparent table-auto"> | ||
<div className="flex flex-row items-center justify-between w-full bg-[#0F1116] pt-2 rounded-t-xl px-2.5"> | ||
<div className="flex flex-row items-center justify-between w-full"> | ||
{duels_header.map((head) => ( | ||
<div | ||
key={head.id} | ||
className={clsx( | ||
head.id === 2 | ||
? "text-center ml-20" | ||
: head.id === 3 | ||
? "text-center -ml-6" | ||
: head.id === 4 && "-ml-16", | ||
head.id === 5 && "hidden", | ||
"w-[175px] p-4 text-start" | ||
)} | ||
> | ||
<Typography | ||
variant="small" | ||
className="font-semibold leading-none text-[#BDC2CC]" | ||
> | ||
{head.name === "Winner" ? "Result" : head.name} | ||
</Typography> | ||
</div> | ||
</div> | ||
<div className="absolute h-[275px] w-[814px] overflow-y-scroll scrollbar-hidden"> | ||
<table className="w-full text-left table-auto"> | ||
<thead className="border-b border-[#313640] hidden"> | ||
<tr className="w-full bg-[#0F1116] flex flex-row items-center justify-between"> | ||
{duels_header.map((head) => ( | ||
<th key={head.id} className="p-4"> | ||
<Typography | ||
variant="small" | ||
className="font-medium leading-none text-[#BDC2CC]" | ||
))} | ||
</div> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve table header accessibility and responsiveness.
The table header structure needs accessibility improvements and better responsive design handling:
- Missing proper table semantics
- Hard-coded pixel values could break on different screen sizes
- Missing ARIA attributes
- <div className="w-full">
- <Card className="w-full h-full bg-transparent">
- <div className="w-full text-left bg-transparent table-auto">
+ <div className="w-full" role="region" aria-label="Game history">
+ <Card className="w-full h-full bg-transparent">
+ <div className="w-full text-left bg-transparent">
+ <table className="w-full table-auto">
+ <thead>
Committable suggestion skipped: line range outside the PR's diff.
@@ -0,0 +1,20 @@ | |||
rpc = "https://api.cartridge.gg/x/starknet/sepolia" | |||
|
|||
allowed_origins = ["*"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Security: Restrict CORS allowed origins
The configuration allows all origins ("*"
) for CORS, which is overly permissive. Additionally, there's a duplicate CORS setting in the [indexing]
section.
Consider:
- Restricting allowed origins to specific domains
- Removing the duplicate CORS setting from the
[indexing]
section
-allowed_origins = ["*"]
+allowed_origins = ["https://your-domain.com", "https://staging.your-domain.com"]
[indexing]
-allowed_origins = ["*"]
Also applies to: 9-9
ipfs_config.url = "https://ipfs.infura.io:5001" | ||
ipfs_config.username = "2EBrzr7ZASQZKH32sl2xWauXPSA" | ||
ipfs_config.password = "12290b883db9138a8ae3363b6739d220" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Security Issue: IPFS credentials exposed in configuration file.
The IPFS configuration contains sensitive credentials that should not be committed to the repository.
Recommendations:
- Remove the credentials from the configuration file
- Use environment variables or a secure secrets management system
- Update the
.gitignore
file to prevent accidental commits of sensitive data
Apply this diff to use environment variables instead:
-ipfs_config.username = "2EBrzr7ZASQZKH32sl2xWauXPSA"
-ipfs_config.password = "12290b883db9138a8ae3363b6739d220"
+ipfs_config.username = "${IPFS_USERNAME}"
+ipfs_config.password = "${IPFS_PASSWORD}"
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
ipfs_config.url = "https://ipfs.infura.io:5001" | |
ipfs_config.username = "2EBrzr7ZASQZKH32sl2xWauXPSA" | |
ipfs_config.password = "12290b883db9138a8ae3363b6739d220" | |
ipfs_config.url = "https://ipfs.infura.io:5001" | |
ipfs_config.username = "${IPFS_USERNAME}" | |
ipfs_config.password = "${IPFS_PASSWORD}" |
@@ -28,6 +28,7 @@ export default function MessageArea({ | |||
const { system } = useDojo(); | |||
const [_, setRestarted] = useState(false); | |||
const { gameId } = useParams(); | |||
// eslint-disable-next-line react-hooks/exhaustive-deps |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid disabling ESLint rules without justification.
The ESLint rule for exhaustive dependencies is being disabled without explanation. This rule helps prevent bugs related to stale closures in React hooks.
Instead of disabling the rule:
- Add all required dependencies to the useEffect dependency array
- If certain dependencies need to be omitted, add a comment explaining why
- Consider using useCallback for the restart_game function if it needs to be stable across renders
@@ -3,7 +3,7 @@ | |||
"class_hash": "0x45575a88cc5cef1e444c77ce60b7b4c9e73a01cbbe20926d5a4c72a94011410", | |||
"address": "0x7e6333cfb9768d94ffa94daf40d8261b27a245a154e180e8ed052781a2e1779", | |||
"seed": "mancala", | |||
"name": "Mancala", | |||
"name": "RealmOfRa: Mancala", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Update project name in all manifest files
The project name has been updated to "RealmOfRa: Mancala" in manifest_dev.json
, but it's still set as "Mancala" in:
manifest_sepolia.json
manifest_slot.json
Please synchronize the name across all manifest files to maintain consistency between environments.
🔗 Analysis chain
Verify name consistency across the codebase.
The project has been rebranded from "Mancala" to "RealmOfRa: Mancala". This change might require updates in related documentation, UI components, and other references.
Run this script to check for inconsistencies:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for inconsistent naming across the codebase
# Search for old name references
echo "Searching for old 'Mancala' references that might need updating..."
rg --type md --type txt --type yaml --type json "\"name\":\s*\"Mancala\"" || true
# Search for inconsistent new name references
echo "Checking for inconsistent 'RealmOfRa: Mancala' references..."
rg --type md --type txt --type yaml --type json "\"name\":\s*\"RealmOfRa:\s*Mancala\"" || true
Length of output: 611
{ | ||
"type": "function", | ||
"name": "dojo_init", | ||
"inputs": [], | ||
"outputs": [], | ||
"state_mutability": "view" | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
State mutability mismatch in dojo_init function
The dojo_init
implementation in contracts/src/systems/mancala.cairo
performs state modifications (initializes world storage and emits events), but it's declared as a view
function in the manifest files. This mismatch could lead to runtime issues.
- Change
state_mutability
from"view"
to an appropriate value in:- contracts/manifest_dev.json
- contracts/manifest_sepolia.json
- contracts/manifest_slot.json
🔗 Analysis chain
Verify dojo_init implementation.
The dojo_init
function is marked as view-only, which is appropriate for initialization. However, ensure that any state modifications required during initialization are handled correctly.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for state modifications in dojo_init implementations
# Search for state modifications in dojo_init
echo "Checking dojo_init implementations for state modifications..."
ast-grep --pattern 'fn dojo_init($$$) { $$$ }'
Length of output: 181
Script:
#!/bin/bash
# Search for dojo_init across all files with context
echo "Searching for dojo_init definitions and usage..."
rg "dojo_init" -A 5 -B 5
# Also check for any files containing dojo_init in their name
echo -e "\nChecking for files containing dojo_init..."
fd "dojo.*init"
Length of output: 4377
Summary by CodeRabbit
Release Notes
New Features
Improvements
Performance
UI/UX
Chores