Skip to content
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

feat: add state loading component #2117

Draft
wants to merge 1 commit into
base: next
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 13 additions & 2 deletions client/src/dojo/setup.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import useUIStore from "@/hooks/store/useUIStore";
import { DojoConfig } from "@dojoengine/core";
import { getSyncEntities, getSyncEvents } from "@dojoengine/state";
import { createClientComponents } from "./createClientComponents";
Expand All @@ -14,9 +15,19 @@ export async function setup({ ...config }: DojoConfig) {
const components = createClientComponents(network);
const systemCalls = createSystemCalls(network);

const setLoadingState = useUIStore.getState().setEventsLoadingState;

// fetch all existing entities from torii
const sync = await getSyncEntities(network.toriiClient, network.contractComponents as any, undefined, [], 10_000);
const eventSync = getSyncEvents(network.toriiClient, network.contractComponents.events as any, undefined, [], 10_000);
const sync = await getSyncEntities(network.toriiClient, network.contractComponents as any, undefined, [], 20_000);
const eventSync = getSyncEvents(
network.toriiClient,
network.contractComponents.events as any,
undefined,
[],
20_000,
false,
() => setLoadingState(false),
);
Comment on lines +22 to +30
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Improve event sync error handling and loading state management

Several concerns with the current implementation:

  1. Loading state is only set to false but never explicitly set to true
  2. Missing error handling could leave the UI stuck in a loading state
  3. The purpose of the false parameter is unclear and should be documented

Consider implementing this more robust approach:

+  // Set initial loading state
+  setLoadingState(true);
+
   const eventSync = getSyncEvents(
     network.toriiClient,
     network.contractComponents.events as any,
     undefined,
     [],
     20_000,
     false, // Add comment explaining this parameter
-    () => setLoadingState(false),
+    () => setLoadingState(false)
+  ).catch(error => {
+    console.error('Event sync failed:', error);
+    setLoadingState(false);
+    throw error;
   });
📝 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.

Suggested change
const eventSync = getSyncEvents(
network.toriiClient,
network.contractComponents.events as any,
undefined,
[],
20_000,
false,
() => setLoadingState(false),
);
// Set initial loading state
setLoadingState(true);
const eventSync = getSyncEvents(
network.toriiClient,
network.contractComponents.events as any,
undefined,
[],
20_000,
false, // Add comment explaining this parameter
() => setLoadingState(false)
).catch(error => {
console.error('Event sync failed:', error);
setLoadingState(false);
throw error;
});


configManager.setDojo(components);

Expand Down
4 changes: 4 additions & 0 deletions client/src/hooks/store/useUIStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ interface UIStore {
setSelectedPlayer: (player: ContractAddress | null) => void;
isSpectatorMode: boolean;
setSpectatorMode: (enabled: boolean) => void;
eventsLoadingState: boolean;
setEventsLoadingState: (enabled: boolean) => void;
}

export type AppStore = UIStore & PopupsStore & ThreeStore & BuildModeStore & RealmStore & BlockchainStore;
Expand Down Expand Up @@ -117,6 +119,8 @@ const useUIStore = create(
setSelectedPlayer: (player: ContractAddress | null) => set({ selectedPlayer: player }),
isSpectatorMode: false,
setSpectatorMode: (enabled: boolean) => set({ isSpectatorMode: enabled }),
eventsLoadingState: true,
setEventsLoadingState: (enabled: boolean) => set({ eventsLoadingState: enabled }),
...createPopupsSlice(set, get),
...createThreeStoreSlice(set, get),
...createBuildModeStoreSlice(set),
Expand Down
5 changes: 5 additions & 0 deletions client/src/ui/containers/BottomLeftContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const BottomLeftContainer = ({ children }: { children: React.ReactNode }) => {
return <div className="absolute bottom-0 left-0">{children}</div>;
};

export default BottomLeftContainer;
8 changes: 8 additions & 0 deletions client/src/ui/layouts/World.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ const BottomRightContainer = lazy(() =>
const LeftMiddleContainer = lazy(() => import("../containers/LeftMiddleContainer"));
const RightMiddleContainer = lazy(() => import("../containers/RightMiddleContainer"));
const TopLeftContainer = lazy(() => import("../containers/TopLeftContainer"));
const BottomLeftContainer = lazy(() => import("../containers/BottomLeftContainer"));
const BottomLeftNavigation = lazy(() =>
import("../modules/navigation/BottomLeftNavigation").then((module) => ({ default: module.BottomLeftNavigation })),
);
const Tooltip = lazy(() => import("../elements/Tooltip").then((module) => ({ default: module.Tooltip })));
const BattleView = lazy(() =>
import("../modules/military/battle-view/BattleView").then((module) => ({ default: module.BattleView })),
Expand Down Expand Up @@ -147,6 +151,10 @@ export const World = () => {
<TopLeftContainer>
<TopLeftNavigation />
</TopLeftContainer>

<BottomLeftContainer>
<BottomLeftNavigation />
</BottomLeftContainer>
Comment on lines +154 to +157
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Mobile handling is appropriate, but layout needs adjustment

The BottomLeftNavigation component already has appropriate mobile handling through its conditional rendering based on eventsLoadingState. However, there are two layout considerations:

  1. The absolute positioning (absolute bottom-0 left-0) in BottomLeftContainer could conflict with other UI elements since it's placed at the exact corner.
  2. The component includes proper mobile-friendly padding (mb-4 ml-4) and styling, but the background might need z-index handling to prevent overlaps.

Recommendations:

  • Add a z-index to the BottomLeftContainer to ensure proper layering
  • Consider adding some base padding/margin to the container to prevent edge-touching on mobile devices
🔗 Analysis chain

Verify mobile device handling and layout positioning

The new bottom-left components are added without mobile-specific handling, unlike other containers in the layout (e.g., BottomRightContainer). Please verify:

  1. If these components should be hidden on mobile devices
  2. If the positioning conflicts with other mobile UI elements

Let's check for any mobile-specific handling in the new components:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for mobile-specific handling in the new components

# Check BottomLeftContainer for mobile handling
echo "Checking BottomLeftContainer for mobile handling..."
rg -A 5 "IS_MOBILE" $(fd -t f "BottomLeftContainer.tsx$")

# Check BottomLeftNavigation for mobile handling
echo "Checking BottomLeftNavigation for mobile handling..."
rg -A 5 "IS_MOBILE" $(fd -t f "BottomLeftNavigation.tsx$")

# Check for potential layout conflicts
echo "Checking for other components with 'bottom-left' positioning..."
rg -i "bottom.?left" $(fd -t f -e tsx -e css)

Length of output: 766


Script:

#!/bin/bash
# Let's check for mobile-specific styling and layout handling

# Check BottomLeftContainer styling and mobile handling
echo "Checking BottomLeftContainer styling..."
fd -t f "BottomLeftContainer" -x cat {}

# Check BottomLeftNavigation styling and mobile handling
echo "Checking BottomLeftNavigation styling..."
fd -t f "BottomLeftNavigation.tsx$" -x cat {}

# Check for any mobile-specific utilities or constants
echo "Checking for mobile utilities usage..."
rg "IS_MOBILE|isMobile|mobile" client/src/ui/layouts/World.tsx

# Check for any z-index or positioning conflicts
echo "Checking for positioning styles..."
rg "position:|z-index:|bottom:|left:" client/src/ui/layouts/World.tsx

Length of output: 1454

</div>

<Redirect to="/" />
Expand Down
12 changes: 12 additions & 0 deletions client/src/ui/modules/navigation/BottomLeftNavigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import useUIStore from "@/hooks/store/useUIStore";

export const BottomLeftNavigation = () => {
const eventsLoadingState = useUIStore((state) => state.eventsLoadingState);

return eventsLoadingState ? (
<div className="flex flex-row mb-4 ml-4 items-center bg-hex bg-black/50 rounded-lg p-2">
<img src="/images/eternum-logo_animated.png" className="invert w-10 h-10" />
<div className="text-xs text-white/90 ml-2 animate-pulse">Game state is loading...</div>
</div>
) : null;
Comment on lines +6 to +11
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve accessibility and performance

Several improvements can be made to enhance the component:

  1. Add alt text to the image for screen readers
  2. Consider reducing animation impact on performance
  3. Externalize text for internationalization
  4. Ensure sufficient contrast ratio for text visibility
 return eventsLoadingState ? (
   <div className="flex flex-row mb-4 ml-4 items-center bg-hex bg-black/50 rounded-lg p-2">
-    <img src="/images/eternum-logo_animated.png" className="invert w-10 h-10" />
-    <div className="text-xs text-white/90 ml-2 animate-pulse">Game state is loading...</div>
+    <img 
+      src="/images/eternum-logo_animated.png" 
+      alt="Loading indicator" 
+      className="invert w-10 h-10" 
+      loading="lazy"
+    />
+    <div className="text-xs text-white ml-2 animate-pulse" role="status">
+      {t('loading.gameState')}
+    </div>
   </div>
 ) : null;

Committable suggestion skipped: line range outside the PR's diff.

};
Loading