-
Notifications
You must be signed in to change notification settings - Fork 37
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
[client] spectator mode #2075
[client] spectator mode #2075
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Skipped Deployment
|
You are out of MentatBot reviews. Your usage will refresh November 11 at 08:00 AM. |
WalkthroughThis pull request introduces several updates across multiple components and hooks to incorporate a spectator mode feature. Key changes include the addition of an Changes
Possibly related PRs
Suggested reviewers
Poem
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 (
|
Failed to generate code suggestions for PR |
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: 3
🧹 Outside diff range and nitpick comments (10)
client/src/ui/components/resources/EntityResourceTable.tsx (2)
40-44
: Consider memoizing the resources array for performance.While the rendering structure is cleaner, the resources array is recreated on every render. For better performance, especially with many resources, consider memoizing this transformation.
return Object.entries(RESOURCE_TIERS).map(([tier, resourceIds]) => { - const resources = resourceIds.map((resourceId: any) => ( + const resources = useMemo(() => resourceIds.map((resourceId: any) => ( <ResourceChip key={resourceId} resourceId={resourceId} entityId={entityId} maxStorehouseCapacityKg={maxStorehouseCapacityKg} tick={tick} /> - )); + )), [resourceIds, entityId, maxStorehouseCapacityKg, tick]); return ( <div key={tier}> <div className="grid grid-cols-1 flex-wrap">{resources}</div> </div> ); });
Line range hint
1-44
: Type safety improvement needed.The component uses
any
type for resourceId which could lead to type-safety issues. Consider defining proper types for the resources.- resourceIds.map((resourceId: any) => + resourceIds.map((resourceId: number) =>client/src/hooks/helpers/useStructureEntityId.tsx (2)
Line range hint
44-44
: Consider safer address comparison.The direct BigInt conversion of the address might be unsafe. Consider using a utility function for address comparison that handles potential edge cases.
Consider implementing a safer comparison:
-const isOwner = structureOwner?.address === BigInt(address); +const isOwner = structureOwner?.address ? compareAddresses(structureOwner.address, address) : false;Add this utility function:
function compareAddresses(a: bigint, b: string): boolean { try { return a === BigInt(b); } catch { return false; } }
Line range hint
35-55
: Add documentation for complex logic.The effect contains complex logic for determining structure ownership and entity IDs. Consider adding JSDoc comments to explain:
- The purpose of the effect
- The different cases handled (map view vs. non-map view)
- The ownership determination logic
Add documentation like this:
/** * Effect to manage structure entity ID based on: * - Current position (x, y) * - Map view state * - Structure ownership * - Spectator mode * * In map view, prioritizes owned structures. * In non-map view, uses structure at current position. */ useEffect(() => { // ... existing code }, [defaultPlayerStructure, isMapView, hexPosition, address]);client/src/hooks/store/useUIStore.tsx (1)
59-60
: Consider persisting spectator mode preference.Similar to other UI preferences in this store (sound, music level), the spectator mode state could benefit from localStorage persistence to maintain user preference across sessions.
Example implementation:
- isSpectatorMode: boolean; + isSpectatorMode: boolean; // Initialize from localStorage setSpectatorMode: (enabled: boolean) => void;- isSpectatorMode: false, + isSpectatorMode: localStorage.getItem("spectatorMode") === "true" || false, - setSpectatorMode: (enabled: boolean) => set({ isSpectatorMode: enabled }), + setSpectatorMode: (enabled: boolean) => { + localStorage.setItem("spectatorMode", String(enabled)); + set({ isSpectatorMode: enabled }); + },client/src/hooks/helpers/useEntities.tsx (2)
Line range hint
156-171
: Fix incorrect dependency arrays in structure getter functionsThere appears to be a bug in the dependency arrays of
getPlayerStructures
andgetOtherStructures
. They currently depend onotherRealms
instead of their respective structure arrays.Apply these fixes:
const getPlayerStructures = (filterFn?: (structure: PlayerStructure) => boolean) => { return useMemo(() => { return filterFn ? playerStructures.filter(filterFn) : playerStructures; - }, [otherRealms, filterFn]); + }, [playerStructures, filterFn]); }; const getOtherStructures = (filterFn?: (structure: PlayerStructure) => boolean) => { return useMemo(() => { return filterFn ? otherStructures.filter(filterFn) : otherStructures; - }, [otherRealms, filterFn]); + }, [otherStructures, filterFn]); };
40-42
: Consider extracting address logic into a custom hookThe spectator mode address logic could be extracted into a custom hook for better reusability and testability:
// usePlayerAddress.ts export const usePlayerAddress = () => { const isSpectatorMode = useUIStore((state) => state.isSpectatorMode); const { account } = useDojo(); return useMemo(() => isSpectatorMode ? ContractAddress("0x0") : ContractAddress(account.address), [isSpectatorMode, account.address] ); };This would simplify the
useEntities
hook and make the address logic reusable across other components.client/src/ui/modules/onboarding/Steps.tsx (1)
76-89
: Enhance accessibility and user experience.The spectator mode button section needs accessibility improvements:
- Add aria-label to the "or" separator
- Make button text more descriptive for screen readers
<div className="relative"> <div className="absolute -top-2 left-1/2 transform -translate-x-1/2"> - <div className="text-sm text-gold/60">or</div> + <div className="text-sm text-gold/60" aria-label="or choose alternative option">or</div> </div> <Button size="md" variant="secondary" className="mx-auto mt-4 w-48 border border-gold/30 hover:border-gold/50 transition-colors" onClick={onSpectatorModeClick} + aria-label="Enter game in spectator mode to observe without participating" > - Enter as Spectator + Enter as Observer <ArrowRight className="w-2 ml-2 fill-current" /> </Button> </div>client/src/ui/modules/navigation/TopLeftNavigation.tsx (2)
200-213
: Consider extracting structure name rendering logicThe conditional rendering logic could be simplified by extracting the repeated structure name pattern into a separate component.
Consider refactoring to:
+ const StructureNameDisplay = ({ + isSpectatorMode, + structureIcon, + structureName + }: { + isSpectatorMode: boolean; + structureIcon: JSX.Element; + structureName: string; + }) => ( + <h5 className="flex items-center gap-4"> + {isSpectatorMode ? ( + <> + {structureIcons.SpectatorMode} + <span>Spectator Mode</span> + </> + ) : ( + <> + {structureIcon} + <span>{structureName}</span> + </> + )} + </h5> + ); <div className="w-full px-4 py-2"> - <h5 className="flex items-center gap-4"> - {isSpectatorMode ? ( - <> - {structureIcons.SpectatorMode} - <span>Spectator Mode</span> - </> - ) : ( - <> - {structure.structureCategory ? structureIcons[structure.structureCategory] : structureIcons.None} - <span>{structure.name}</span> - </> - )} - </h5> + <StructureNameDisplay + isSpectatorMode={isSpectatorMode} + structureIcon={structure.structureCategory ? structureIcons[structure.structureCategory] : structureIcons.None} + structureName={structure.name} + /> </div>
Line range hint
349-386
: Remove commented out codeThere are several blocks of commented out code and duplicate dependency array comments that should be removed to maintain code cleanliness.
Remove the following:
- Duplicate useEffect dependency array comments
- Commented out progress calculation
- Commented out updateTooltip implementation
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (7)
client/src/hooks/helpers/useEntities.tsx
(3 hunks)client/src/hooks/helpers/useStructureEntityId.tsx
(2 hunks)client/src/hooks/store/useUIStore.tsx
(2 hunks)client/src/ui/components/resources/EntityResourceTable.tsx
(1 hunks)client/src/ui/modules/navigation/RightNavigationModule.tsx
(1 hunks)client/src/ui/modules/navigation/TopLeftNavigation.tsx
(4 hunks)client/src/ui/modules/onboarding/Steps.tsx
(1 hunks)
🔇 Additional comments (11)
client/src/ui/components/resources/EntityResourceTable.tsx (2)
26-28
: LGTM: Early return pattern improves code clarity.
The addition of an early return with a clear message for invalid entityId values follows React best practices and improves error handling.
35-35
: Verify entityId prop usage across the application.
The direct usage of entityId (without the previous nullish coalescing to 0) aligns with the new validation check. However, we should verify this change doesn't affect other components.
✅ Verification successful
The entityId prop change is safe to proceed
Based on the codebase analysis, the ResourceChip
component is only used in EntityResourceTable.tsx
and the removal of nullish coalescing for entityId
is safe because:
ResourceChip
is only imported and used in this single file- All other components using
entityId
props have their own validation or handling mechanisms - No other instances of
ResourceChip
usage were found that could be affected by this change
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for other instances of ResourceChip usage to ensure consistent entityId handling
# Search for ResourceChip usage patterns
rg -A 3 '<ResourceChip' --type tsx
Length of output: 64
Script:
#!/bin/bash
# Search for ResourceChip usage patterns with TypeScript/React extensions
rg -A 3 '<ResourceChip' --type ts --type tsx --type jsx
# Also search for entityId prop pattern specifically
rg -A 3 'entityId=' --type ts --type tsx --type jsx
# Search for ResourceChip imports to ensure we find all relevant files
rg "import.*ResourceChip" --type ts --type tsx --type jsx
Length of output: 253
Script:
#!/bin/bash
# Search for ResourceChip usage patterns without specifying file types
rg -A 3 '<ResourceChip'
# Search for entityId prop pattern
rg -A 3 'entityId='
# Search for ResourceChip imports
rg "import.*ResourceChip"
Length of output: 14730
client/src/hooks/helpers/useStructureEntityId.tsx (2)
3-3
: LGTM: ContractAddress import is appropriate.
The import is necessary for the new address handling in spectator mode.
16-24
: Verify edge cases in address calculation.
While the spectator mode implementation looks good, there are some edge cases to consider:
- The code assumes
account.address
is always defined - Using
"0x0"
as the spectator address needs verification
Let's verify the contract's behavior with these addresses:
✅ Verification successful
Based on the search results, I can now generate the final response:
The address handling implementation is safe and consistent
The codebase shows consistent handling of addresses:
account.address
is always used within aContractAddress
wrapper- The
"0x0"
address in spectator mode aligns with the pattern used across the codebase for representing null/empty addresses - The code has proper null checks with fallbacks (e.g.,
owner?.address || 0n
)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any special handling of address "0x0" in the contract
# and verify account.address usage across the codebase
# Check for "0x0" address handling in contract files
echo "Checking for '0x0' address handling:"
rg -l "0x0" --type rust
# Check how account.address is used elsewhere
echo "\nChecking account.address usage:"
ast-grep --pattern 'account.address'
Length of output: 11321
client/src/ui/modules/navigation/RightNavigationModule.tsx (2)
70-70
: LGTM! Explicit boolean conversion is more type-safe.
The change to use !!
for explicit boolean conversion is a good practice as it makes the type conversion more explicit and handles edge cases better.
Line range hint 70-74
: Verify entityId handling in spectator mode.
Since this component is part of the spectator mode implementation, ensure that structureEntityId
is properly handled when in spectator mode.
Let's verify the integration:
✅ Verification successful
Let me gather more information about the spectator mode implementation to verify how structureEntityId is handled.
Based on the gathered information, I can now provide the final response:
structureEntityId
is properly handled in spectator mode
The implementation correctly handles spectator mode through:
- The
useStructureEntityId
hook checksisSpectatorMode
and adjusts the address accordingly (0x0
for spectator mode) - Structure entity selection logic properly considers the spectator state when setting IDs
- The
EntityResourceTable
component safely handles undefined entity IDs with a fallback UI
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check how structureEntityId is handled in spectator mode
# across the codebase
# Check for spectator mode handling in related files
echo "Checking for spectator mode handling in useStructureEntityId hook..."
rg -A 5 "useStructureEntityId|structureEntityId.*spectator"
# Check EntityResourceTable component for spectator mode handling
echo "Checking EntityResourceTable component..."
ast-grep --pattern 'const EntityResourceTable = $_ => {
$$$
}'
Length of output: 5206
Script:
#!/bin/bash
# Check for spectator mode related code and its interaction with structure entities
echo "Checking spectator mode implementation..."
rg -A 5 "isSpectator|spectator.*mode"
# Check how structure entity selection works
echo "Checking structure entity selection..."
rg -A 10 "setStructureEntityId|selectStructure"
# Check the store implementation for structure entities
echo "Checking store implementation..."
ast-grep --pattern 'const useUIStore = $_ => {
$$$
}'
Length of output: 8395
client/src/hooks/store/useUIStore.tsx (1)
118-119
: Implementation looks good, verify usage in dependent components.
The store implementation follows established patterns and integrates well with the existing structure.
Let's verify the usage of these new properties across the codebase:
✅ Verification successful
Spectator mode implementation is properly integrated and used across components
The store properties are correctly used in several components and hooks:
- Used in navigation UI (
TopLeftNavigation.tsx
) for display logic - Integrated in entity-related hooks (
useEntities.tsx
,useStructureEntityId.tsx
) for address handling - Connected to onboarding flow (
Steps.tsx
) for mode activation - Consistently follows the selector pattern with
useUIStore((state) => state.isSpectatorMode)
Note: There's a minor typo in Steps.tsx
where setSpactatorMode
should be setSpectatorMode
, but it doesn't affect functionality.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check usage of spectator mode properties across the codebase
# Test: Find direct references to isSpectatorMode
echo "=== Direct isSpectatorMode usage ==="
rg "isSpectatorMode" --type tsx --type ts
# Test: Find store selector usage patterns
echo -e "\n=== Store selector patterns ==="
rg "useUIStore\(\s*\)\s*\.\s*(isSpectatorMode|setSpectatorMode)" --type tsx --type ts
Length of output: 347
Script:
#!/bin/bash
# Let's try without file type filters since tsx/ts extensions aren't recognized
# Search for spectator mode references
echo "=== Direct isSpectatorMode usage ==="
rg "isSpectatorMode"
echo -e "\n=== Store selector patterns ==="
rg "useUIStore.*\.(isSpectatorMode|setSpectatorMode)"
# Also search for potential UI components that might use spectator mode
echo -e "\n=== Potential spectator-related components ==="
rg -i "spectator"
Length of output: 3559
client/src/hooks/helpers/useEntities.tsx (3)
16-16
: LGTM: Clean import addition
The import of useUIStore
is properly placed and follows the project's import organization pattern.
51-51
: LGTM: Consistent address comparison updates
The owner address comparisons have been consistently updated across all filter functions to use the new address
variable, maintaining type safety with ContractAddress
wrapper.
Also applies to: 58-58, 68-68, 75-75
40-42
: Verify the choice of 0x0 as the default spectator address
While the implementation looks correct, let's verify that using 0x0
as the default address in spectator mode won't cause any issues with other parts of the system.
✅ Verification successful
Based on the search results, I can now generate the final response:
Using 0x0 as spectator address is a safe choice
The codebase shows consistent handling of address 0x0:
- It's already used as a default/zero address in multiple places including chat, banks, and other UI components
- The
ContractAddress("0x0")
pattern is used in similar spectator/default scenarios - No special validation or restrictions were found that would reject 0x0 addresses
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for any special handling of address 0x0 in the codebase
rg -i "0x0|address.*zero|zero.*address" --type ts --type tsx
# Search for ContractAddress usage patterns
rg "ContractAddress\(" --type ts --type tsx
Length of output: 164
Script:
#!/bin/bash
# Search for any special handling of address 0x0 in the codebase without file type restrictions
rg -i "0x0|address.*zero|zero.*address"
# Search for ContractAddress usage patterns without file type restrictions
rg "ContractAddress\("
# Look for files that might contain address-related constants or utilities
fd -e ts -e tsx -e js -e jsx "address|contract" -t f
Length of output: 15844
client/src/ui/modules/navigation/TopLeftNavigation.tsx (1)
23-23
: LGTM: Icon changes for spectator mode
The addition of EyeIcon and its mapping in structureIcons is appropriate for the spectator mode feature.
Also applies to: 39-39
@@ -45,18 +45,48 @@ const StepContainer = ({ children }: { children: React.ReactNode }) => { | |||
}; | |||
|
|||
export const StepOne = ({ onNext }: { onNext: () => void }) => { | |||
const setSpactatorMode = useUIStore((state) => state.setSpectatorMode); |
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 typo in variable name.
The variable name setSpactatorMode
contains a typo and should be setSpectatorMode
.
- const setSpactatorMode = useUIStore((state) => state.setSpectatorMode);
+ const setSpectatorMode = useUIStore((state) => state.setSpectatorMode);
📝 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.
const setSpactatorMode = useUIStore((state) => state.setSpectatorMode); | |
const setSpectatorMode = useUIStore((state) => state.setSpectatorMode); |
const onSpectatorModeClick = () => { | ||
setIsLoadingScreenEnabled(true); | ||
setSpactatorMode(true); | ||
setTimeout(() => { | ||
showBlankOverlay(false); | ||
handleUrlChange(new Position({ x: 0, y: 0 }).toMapLocationUrl()); | ||
window.dispatchEvent(new Event(ACCOUNT_CHANGE_EVENT)); | ||
}, 250); | ||
}; |
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 robustness of spectator mode transition.
Several improvements can be made to the spectator mode transition:
- Extract magic number 250 to a named constant
- Add error handling for URL change
- Consider using Promise.all or async/await for better synchronization
+const SPECTATOR_MODE_TRANSITION_DELAY = 250; // ms
+
const onSpectatorModeClick = () => {
setIsLoadingScreenEnabled(true);
- setSpactatorMode(true);
- setTimeout(() => {
- showBlankOverlay(false);
- handleUrlChange(new Position({ x: 0, y: 0 }).toMapLocationUrl());
- window.dispatchEvent(new Event(ACCOUNT_CHANGE_EVENT));
- }, 250);
+ setSpectatorMode(true);
+
+ setTimeout(async () => {
+ try {
+ showBlankOverlay(false);
+ await handleUrlChange(new Position({ x: 0, y: 0 }).toMapLocationUrl());
+ window.dispatchEvent(new Event(ACCOUNT_CHANGE_EVENT));
+ } catch (error) {
+ console.error('Failed to transition to spectator mode:', error);
+ // Consider adding error recovery logic here
+ }
+ }, SPECTATOR_MODE_TRANSITION_DELAY);
};
📝 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.
const onSpectatorModeClick = () => { | |
setIsLoadingScreenEnabled(true); | |
setSpactatorMode(true); | |
setTimeout(() => { | |
showBlankOverlay(false); | |
handleUrlChange(new Position({ x: 0, y: 0 }).toMapLocationUrl()); | |
window.dispatchEvent(new Event(ACCOUNT_CHANGE_EVENT)); | |
}, 250); | |
}; | |
const SPECTATOR_MODE_TRANSITION_DELAY = 250; // ms | |
const onSpectatorModeClick = () => { | |
setIsLoadingScreenEnabled(true); | |
setSpectatorMode(true); | |
setTimeout(async () => { | |
try { | |
showBlankOverlay(false); | |
await handleUrlChange(new Position({ x: 0, y: 0 }).toMapLocationUrl()); | |
window.dispatchEvent(new Event(ACCOUNT_CHANGE_EVENT)); | |
} catch (error) { | |
console.error('Failed to transition to spectator mode:', error); | |
// Consider adding error recovery logic here | |
} | |
}, SPECTATOR_MODE_TRANSITION_DELAY); | |
}; |
const setSpactatorMode = useUIStore((state) => state.setSpectatorMode); | ||
const showBlankOverlay = useUIStore((state) => state.setShowBlankOverlay); | ||
const setIsLoadingScreenEnabled = useUIStore((state) => state.setIsLoadingScreenEnabled); | ||
const { handleUrlChange } = useQuery(); | ||
|
||
const onSpectatorModeClick = () => { | ||
setIsLoadingScreenEnabled(true); | ||
setSpactatorMode(true); | ||
setTimeout(() => { | ||
showBlankOverlay(false); | ||
handleUrlChange(new Position({ x: 0, y: 0 }).toMapLocationUrl()); | ||
window.dispatchEvent(new Event(ACCOUNT_CHANGE_EVENT)); | ||
}, 250); | ||
}; | ||
|
||
return ( | ||
<StepContainer> | ||
<div className="w-full text-center pt-6"> | ||
<div className="mx-auto flex mb-8"> | ||
<img src="/images/eternum_with_snake.png" className="w-72 mx-auto" alt="Eternum Logo" /> | ||
</div> | ||
</div> | ||
<div className="flex space-x-2 mt-8 justify-center"> | ||
<Button size="md" className="mx-auto" variant="primary" onClick={onNext}> | ||
<div className="flex flex-col space-y-4 mt-8 items-center"> | ||
<Button size="md" className="mx-auto w-48" variant="primary" onClick={onNext}> | ||
Choose your Leader | ||
<ArrowRight className="w-2 ml-2 fill-current" /> | ||
</Button> | ||
|
||
<div className="relative"> | ||
<div className="absolute -top-2 left-1/2 transform -translate-x-1/2"> | ||
<div className="text-sm text-gold/60">or</div> | ||
</div> | ||
<Button | ||
size="md" | ||
variant="secondary" | ||
className="mx-auto mt-4 w-48 border border-gold/30 hover:border-gold/50 transition-colors" | ||
onClick={onSpectatorModeClick} | ||
> | ||
Enter as Spectator | ||
<ArrowRight className="w-2 ml-2 fill-current" /> | ||
</Button> | ||
</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.
💡 Codebase verification
Spectator mode integration appears incomplete in the UI store
The verification reveals a potential issue with the spectator mode implementation:
- The
UIStore
interface inclient/src/hooks/store/useUIStore.tsx
doesn't expose the requiredsetSpectatorMode
,isSpectatorMode
, andsetIsLoadingScreenEnabled
methods that are being used inSteps.tsx
- However, these methods are being consumed correctly across multiple components:
TopLeftNavigation.tsx
usesisSpectatorMode
useEntities.tsx
anduseStructureEntityId.tsx
properly handle spectator mode state- The URL generation via
Position.toMapLocationUrl()
is implemented correctly
🔗 Analysis chain
Verify spectator mode integration with other components.
Let's ensure the spectator mode changes are properly integrated with other components.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify spectator mode integration points
# Test 1: Check for proper useUIStore integration
echo "Checking useUIStore integration..."
rg -l "setSpectatorMode|isSpectatorMode" --type tsx --type ts
# Test 2: Check for proper URL handling in spectator mode
echo "Checking URL handling..."
rg -l "toMapLocationUrl.*Position.*0.*0" --type tsx --type ts
# Test 3: Check for proper event handling
echo "Checking address change event handling..."
rg -l "ACCOUNT_CHANGE_EVENT.*addressChanged" --type tsx --type ts
Length of output: 510
Script:
#!/bin/bash
# Let's try without file type restrictions since tsx/ts extensions aren't recognized
echo "Checking useUIStore integration..."
rg -l "setSpectatorMode|isSpectatorMode"
echo -e "\nChecking URL handling and Position usage..."
rg -l "toMapLocationUrl"
echo -e "\nChecking account change event handling..."
rg -l "ACCOUNT_CHANGE_EVENT"
# Let's also check the store implementation
echo -e "\nChecking UI store implementation..."
rg -A 5 "spectatorMode"
Length of output: 942
Script:
#!/bin/bash
# Let's examine the actual implementations to verify integration
echo "Checking useUIStore implementation..."
rg -A 10 "interface UIStore" client/src/hooks/store/useUIStore.tsx
echo -e "\nChecking TopLeftNavigation usage..."
rg -B 5 -A 10 "setSpectatorMode|isSpectatorMode" client/src/ui/modules/navigation/TopLeftNavigation.tsx
echo -e "\nChecking useEntities spectator mode handling..."
rg -B 5 -A 10 "setSpectatorMode|isSpectatorMode" client/src/hooks/helpers/useEntities.tsx
echo -e "\nChecking useStructureEntityId spectator mode handling..."
rg -B 5 -A 10 "setSpectatorMode|isSpectatorMode" client/src/hooks/helpers/useStructureEntityId.tsx
echo -e "\nChecking Position class implementation..."
rg -A 10 "toMapLocationUrl" client/src/types/Position.ts
Length of output: 4101
Fixes #2074
Summary by CodeRabbit
Release Notes
New Features
EntityResourceTable
andTopLeftNavigation
to accommodate spectator mode.Bug Fixes
EntityResourceTable
.Refactor
Documentation