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 gong sound + cta for settling realm and joining battle #2149

Merged
merged 12 commits into from
Nov 28, 2024

Conversation

edisontim
Copy link
Collaborator

@edisontim edisontim commented Nov 26, 2024

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new gong sound effect for user interface interactions.
    • Enhanced TwitterShareButton with customizable properties for improved user engagement.
    • Added BattleTwitterShareButton for sharing battle information on Twitter.
    • Integrated social sharing capabilities into the onboarding process.
  • Improvements

    • Simplified logic in the SettleRealmComponent for better interaction with settled realm IDs.
    • Enhanced PillageHistory for a more dynamic display and sharing of pillage details.
    • Improved sound feedback in the TopLeftNavigation component based on progress changes.
    • Enhanced sorting functionality in the useEntities hook for better organization of realm and structure lists.
  • Bug Fixes

    • Retained consistent error handling across various components, ensuring users receive appropriate feedback.
  • Chores

    • Updated .prettierignore to exclude the eliza folder from formatting.

Copy link

vercel bot commented Nov 26, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
eternum ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 27, 2024 10:05pm
eternum-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 27, 2024 10:05pm
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
eternum-landing ⬜️ Ignored (Inspect) Visit Preview Nov 27, 2024 10:05pm

Copy link
Contributor

coderabbitai bot commented Nov 26, 2024

Walkthrough

This pull request includes several modifications across multiple components and hooks in the codebase. Key changes involve the simplification of the useSettleRealm hook, the addition of a new sound effect in the useUISound hook, and enhancements to the SettleRealmComponent for better interaction with parent components. The TwitterShareButton component has been updated to accept new props for improved configurability. Additionally, new functionalities for sharing battle information on Twitter have been introduced in the Battle component and a new BattleTwitterShareButton component. The onboarding experience has also been enhanced with social sharing capabilities.

Changes

File Path Change Summary
client/src/hooks/helpers/use-settle-realm.tsx Removed getNextRealmIdForOrder and getRealmIdForOrderAfter from useRealm(). Simplified calldata initialization and added return of id in settleRealm.
client/src/hooks/useUISound.tsx Added new sound entry: gong: "events/gong.mp3" in soundSelector.
client/src/ui/components/cityview/realm/SettleRealmComponent.tsx Updated component to accept setSettledRealmId prop and modified settleRealm invocation to capture and use realmId.
client/src/ui/elements/TwitterShareButton.tsx Updated Props interface to include callToActionText, buttonSize, and variant. Modified function signature to destructure new props.
client/src/ui/modules/navigation/TopLeftNavigation.tsx Integrated useUiSounds and added sound effect for progress decrease. Introduced lastProgressRef to track progress.
client/src/ui/modules/onboarding/Steps.tsx Added TwitterShareButton and modified StepTwo to track settledRealmId. Updated layout to include social sharing capabilities.
client/src/ui/components/military/PillageHistory.tsx Enhanced pillage history with new imports and logic for social sharing. Updated rendering to conditionally display player's name.
client/src/ui/modules/military/battle-view/Battle.tsx Added BattleTwitterShareButton to share battle-related information on Twitter.
client/src/ui/modules/military/battle-view/battle-twitter-share-button.tsx Introduced BattleTwitterShareButton component for sharing battle details on Twitter.
client/src/ui/socials.ts Added TemplateVariables type, formatSocialText function, and twitterTemplates object for dynamic text generation in social media sharing.
.prettierignore Added rule to ignore the eliza folder.

Possibly related PRs

Suggested reviewers

  • bob0005
  • aymericdelab

Poem

🐰 In the realm where bunnies play,
New sounds and buttons come to stay.
With tweets to share, our battles bright,
We hop with joy, oh what a sight!
So settle realms and share the cheer,
For every bunny holds their dear! 🌟


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?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

Failed to generate code suggestions for PR

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (8)
client/src/ui/elements/TwitterShareButton.tsx (2)

11-11: Consider adding a default prop value

While the implementation works, providing a default value for callToActionText could improve developer experience and make the component more maintainable.

-const TwitterShareButton: React.FC<Props> = ({ text, className, callToActionText }) => {
+const TwitterShareButton: React.FC<Props> = ({ 
+  text, 
+  className, 
+  callToActionText = 'Share to Twitter' 
+}) => {

20-20: Extract default text to a constant

The default text "Share to Twitter" is hardcoded and could be duplicated if implementing default props. Consider extracting it to a constant for better maintainability.

+const DEFAULT_SHARE_TEXT = 'Share to Twitter';
+
 const TwitterShareButton: React.FC<Props> = ({ 
   text, 
   className, 
-  callToActionText 
+  callToActionText = DEFAULT_SHARE_TEXT
 }) => {
   // ...
-  {callToActionText ? callToActionText : `Share to Twitter`}
+  {callToActionText}
client/src/hooks/helpers/use-settle-realm.tsx (3)

32-36: Simplify array handling in create_multiple_realms call.

While the calldata construction has been simplified, we can further improve it by removing the redundant spread operator.

-      const calldata = [Number(id)];
-
-      await create_multiple_realms({
-        signer: account,
-        realm_ids: [...calldata],
-      });
+      await create_multiple_realms({
+        signer: account,
+        realm_ids: [Number(id)],
+      });

Line range hint 40-46: Improve error handling and type safety for settleRealm return value.

The function returns id only in the success case but implicitly returns undefined in the error case. This could lead to type safety issues in consuming components.

-      return id;
+      return { success: true as const, id };
     } catch (error) {
       setErrorMessage("Realm already settled. Please try a different Realm.");
       console.error("Error during minting:", error);
+      return { success: false as const, error: String(error) };
     } finally {
       setIsLoading(false);
     }

Then update the return type:

type SettleRealmResult = 
  | { success: true; id: number }
  | { success: false; error: string };

Line range hint 7-11: Consider optimizing state management.

The hook maintains several pieces of state (isLoading, selectedOrder, tokenId, errorMessage). Since selectedOrder and tokenId might no longer be needed after removing order-based selection, consider simplifying the state management.

-  const [selectedOrder, setSelectedOrder] = useState(1);
-  const [tokenId, setTokenId] = useState<number>(0);

Then update the return value:

-  return { settleRealm, isLoading, selectedOrder, setSelectedOrder, tokenId, setTokenId, errorMessage };
+  return { settleRealm, isLoading, errorMessage };
client/src/ui/modules/onboarding/Steps.tsx (2)

326-330: Add error handling for realm name retrieval

The getRealmNameById function could potentially return undefined if the realm ID is invalid. Consider adding a fallback.

-    const realmName = getRealmNameById(settledRealmId);
+    const realmName = getRealmNameById(settledRealmId) ?? 'My realm';
     return (
       <TwitterShareButton
         text={`I've joined the Eternum battle for glory.\nWars will be fought, tears will be shed.\n${realmName} has been settled. ⚔️`}
       />

337-343: Consider improving mobile responsiveness

The current grid layout might not provide the best experience on mobile devices. Consider adding responsive classes.

-      <div className="grid grid-cols-3 gap-4 justify-center items-center">
-        <div className="col-start-2 flex justify-center">
+      <div className="grid grid-cols-1 md:grid-cols-3 gap-4 justify-center items-center">
+        <div className="col-start-1 md:col-start-2 flex justify-center">
           <Button size="md" className="mt-4" variant="primary" onClick={onNext}>
             Continue <ArrowRight className="w-2 fill-current ml-3" />
           </Button>
         </div>
-        <div className="col-start-3 flex justify-start">
+        <div className="col-start-1 md:col-start-3 flex justify-center md:justify-start">
           {settledComponent && settledComponent}
         </div>
client/src/ui/modules/navigation/TopLeftNavigation.tsx (1)

345-345: Consider debouncing the gong sound effect

The current implementation might trigger the sound effect too frequently if progress updates rapidly. Consider adding debounce to prevent sound overlap and improve user experience.

Here's a suggested implementation using debounce:

+ import { debounce } from 'lodash';
  const TickProgress = () => {
    const { play } = useUiSounds(soundSelector.gong);
+   const debouncedPlay = useMemo(
+     () => debounce(play, 1000, { leading: true, trailing: false }),
+     [play]
+   );

    useEffect(() => {
      if (lastProgressRef.current > progress) {
-       play();
+       debouncedPlay();
      }
      lastProgressRef.current = progress;
-   }, [progress]);
+   }, [progress, debouncedPlay]);

Also applies to: 359-365

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between cc68e67 and fea2e59.

⛔ Files ignored due to path filters (1)
  • client/public/sound/events/gong.mp3 is excluded by !**/*.mp3
📒 Files selected for processing (7)
  • client/src/hooks/helpers/use-settle-realm.tsx (2 hunks)
  • client/src/hooks/useUISound.tsx (1 hunks)
  • client/src/ui/components/cityview/realm/SettleRealmComponent.tsx (2 hunks)
  • client/src/ui/elements/TwitterShareButton.tsx (2 hunks)
  • client/src/ui/modules/military/battle-view/BattleSideView.tsx (2 hunks)
  • client/src/ui/modules/navigation/TopLeftNavigation.tsx (5 hunks)
  • client/src/ui/modules/onboarding/Steps.tsx (2 hunks)
🔇 Additional comments (13)
client/src/ui/elements/TwitterShareButton.tsx (2)

8-8: LGTM! Props interface is well-defined

The new optional prop is properly typed and follows TypeScript best practices.


12-12: Verify text sanitization

While encodeURIComponent provides URL encoding, ensure that the text prop is properly sanitized before being used in the Twitter URL to prevent potential XSS attacks.

client/src/hooks/helpers/use-settle-realm.tsx (1)

13-13: Verify removal of order-based realm selection.

The removal of getNextRealmIdForOrder and getRealmIdForOrderAfter functions suggests a shift to random-only realm selection. However, selectedOrder state is still maintained but might be unused.

client/src/ui/components/cityview/realm/SettleRealmComponent.tsx (1)

11-11: LGTM! Verify parent component updates.

The new prop follows TypeScript best practices with clear typing.

Let's verify that all parent components have been updated to handle this breaking change:

✅ Verification successful

All parent components correctly handle the breaking change

The verification shows that SettleRealmComponent is only used in Steps.tsx and it correctly passes the required setSettledRealmId prop, matching the new component signature.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for components rendering SettleRealmComponent
rg -l "SettleRealmComponent" | xargs rg -A 5 "<SettleRealmComponent"

Length of output: 699

client/src/ui/modules/military/battle-view/BattleSideView.tsx (2)

9-9: LGTM!

The TwitterShareButton import follows the project's import organization pattern.


115-120: Verify component visibility in scrollable container

The TwitterShareButton is placed inside a div with max-h-24 overflow-y-auto. Ensure the button remains visible and accessible when the army list is long.

✅ Verification successful

Based on the search results, I can now generate the final response:

TwitterShareButton placement is safe in scrollable container

The TwitterShareButton is placed at the end of the army list, after all army entries, which is a good practice. The max-h-24 (96px) height constraint provides sufficient space for both the army list and the button, and the button will remain fixed at the bottom of the list. This is consistent with other scroll container patterns in the codebase where interactive elements are properly positioned.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other instances of TwitterShareButton to see common placement patterns
ast-grep --pattern 'TwitterShareButton'

# Look for scroll container patterns in the codebase
rg 'overflow-y-auto' -A 2 -B 2

Length of output: 13068

client/src/hooks/useUISound.tsx (1)

73-73: Verify the gong sound file existence and integration.

The addition of the gong sound follows the established pattern for event sounds. However, let's ensure proper integration:

Consider adding a comment above the soundSelector object to document the purpose and usage context of different sound categories (ui, buildings, resources, events).

✅ Verification successful

Sound file exists and is properly integrated

The verification shows that:

  • The gong sound file exists at the correct location: client/public/sound/events/gong.mp3
  • It follows the established directory structure for event sounds
  • It's being used in TopLeftNavigation.tsx with proper sound hook integration (useUiSounds)
  • The implementation uses the standard pattern for sound playback in the application
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the gong sound file existence and its usage in the codebase

# Check if the sound file exists in the public directory
fd "gong.mp3" public/sound/events

# Find components using the new gong sound
rg -l "soundSelector.gong" --type tsx

Length of output: 206


Script:

#!/bin/bash
# Let's try different approaches to verify the sound file and its usage

# 1. Find the sound file in any directory
fd "gong.mp3"

# 2. Find all sound files to understand the correct directory structure
fd ".mp3$"

# 3. Search for gong sound usage with ripgrep (without file type restriction)
rg -l "soundSelector.gong"

# 4. Search for any gong-related code
rg -l "gong"

Length of output: 3830


Script:

#!/bin/bash
# Let's check how the gong sound is being used in TopLeftNavigation.tsx

# Check the implementation details
rg -A 5 -B 5 "soundSelector.gong" client/src/ui/modules/navigation/TopLeftNavigation.tsx

# Also check if there are any volume controls being applied
ast-grep --pattern 'useUISound($$$)'  client/src/ui/modules/navigation/TopLeftNavigation.tsx

Length of output: 631

client/src/ui/modules/onboarding/Steps.tsx (2)

21-21: LGTM!

The TwitterShareButton import is correctly placed and properly utilized in the code.


319-332: LGTM! Well-structured component with proper state management

The implementation is clean with:

  • Proper state management using TypeScript types
  • Efficient memoization of the Twitter share component
  • Good separation of concerns
client/src/ui/modules/navigation/TopLeftNavigation.tsx (4)

8-8: LGTM: Sound-related imports are properly organized

The new imports for sound functionality are correctly placed with other hook imports.


350-351: LGTM: Progress tracking implementation is solid

The progress tracking using useRef is implemented correctly, with proper initialization and calculation logic.

Also applies to: 354-356


Line range hint 341-411: LGTM: Sound feature is well-integrated

The new sound functionality is cleanly integrated into the TickProgress component without disrupting existing features such as progress display and tooltips.


Line range hint 1-411: Verify the implementation of CTA functionality

While the gong sound is implemented, the CTA for settling realm and joining battle mentioned in the PR title is not visible in this file.

Copy link
Contributor

@mentatbot mentatbot bot left a comment

Choose a reason for hiding this comment

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

The PR adds nice quality of life improvements with sound feedback and social sharing capabilities. The gong sound for day cycles and Twitter sharing for key moments like settling realms and battles are good additions. The code is generally well structured with good separation of concerns. A few suggestions around error handling and user control over sounds, but overall this is a solid improvement to the user experience.

Thanks for using MentatBot. Give comments a 👍 or 👎 to help me improve!

@aymericdelab
Copy link
Collaborator

@edisontim i decided to change the share button to something that blends more with the app style
image

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (13)
client/src/ui/socials.ts (1)

1-12: Enhance type documentation for consistency and clarity

While the type definition is well-structured, the documentation could be improved for consistency and clarity.

Consider applying this documentation update:

 type TemplateVariables = {
+  // name of the opposing player/realm
   enemyName: string;
+  // number of attacking troops (formatted)
   attackerTroops: string;
+  // number of defending troops (formatted)
   defenderTroops: string;
-  // game url
+  // full game URL (e.g., https://eternum.io/realm/123)
   url: string;
+  // name of the player's realm
   realmName: string;
   // player name
   addressName: string;
   // 300 diamonds, 100 donkeys, 2000 gold
   resources: string;
 };
client/src/ui/modules/military/battle-view/Battle.tsx (2)

63-66: Consider responsive design for button container

The layout improvements with space-x-1 and items-center are good. Consider adding responsive classes for better mobile experience.

-<div className="flex justify-center mb-2 space-x-1 items-center">
+<div className="flex justify-center mb-2 space-x-1 md:space-x-2 items-center flex-wrap gap-y-2">

67-74: Enhance type safety for battle sharing props

The BattleTwitterShareButton integration looks good, but consider creating a dedicated type for the props to improve maintainability and type safety.

type BattleShareProps = {
  userArmiesInBattle: ArmyInfo[]
  attackerArmies: ArmyInfo[]
  defenderArmies: (ArmyInfo | undefined)[]
  ownArmySide: string
  battleAdjusted: ComponentValue<ClientComponents["Battle"]["schema"]> | undefined
  structure: Structure | undefined
}
client/src/ui/modules/onboarding/Steps.tsx (2)

320-327: Consider memoizing socialsText calculation.

The implementation looks good, but the socialsText calculation could be optimized using useMemo since it only needs to be recalculated when realmName changes.

Consider this optimization:

-  const socialsText = formatSocialText(twitterTemplates.settle, {
-    realmName: realmName || "",
-    url: window.location.origin,
-  });
+  const socialsText = useMemo(() => 
+    formatSocialText(twitterTemplates.settle, {
+      realmName: realmName || "",
+      url: window.location.origin,
+    }),
+    [realmName]
+  );

323-326: Consider making the URL configurable.

The URL is currently hardcoded to window.location.origin. Consider making it configurable through environment variables for better flexibility across different environments.

Consider using an environment variable:

-    url: window.location.origin,
+    url: env.VITE_PUBLIC_APP_URL || window.location.origin,
client/src/ui/elements/TwitterShareButton.tsx (4)

20-20: Consider using CSS hover states instead of managing hover state

Managing the hover effect via the hover state variable increases complexity. You could achieve the same effect using CSS hover pseudo-classes or Tailwind CSS's hover utilities, which are more performant and simplify the code.

Apply this refactor to remove the hover state:

- const [hover, setHover] = React.useState(false);

...

- <Button
-   ...
-   onPointerEnter={() => setHover(true)}
-   onPointerLeave={() => setHover(false)}
- >
+ <Button
+   ...
+ >
      <div className={`flex items-center justify-center mr-2 ${iconSizeClasses[buttonSize]}`}>
-       <TwitterIcon className={`${hover ? "text-brown" : "text-gold"} transition-all duration-300`} />
+       <TwitterIcon className="text-gold hover:text-brown transition-all duration-300" />
      </div>

24-28: Handle default icon size and unexpected buttonSize values

Currently, the iconSizeClasses object only includes mappings for "xs" and "md". If buttonSize receives an unexpected value, it may result in undefined. Consider providing a default size or validating the buttonSize prop.

You can modify the className assignment to include a default size:

<div className={`flex items-center justify-center mr-2 ${iconSizeClasses[buttonSize] || "h-4 w-4"}`}>

Alternatively, ensure that buttonSize only accepts the specified values.


39-39: Consider clarity in call-to-action text

The default callToActionText is "Share on X", which might be unclear to users familiar with "Twitter". Since the icon is the Twitter logo, consider whether using "Share on Twitter" might provide better clarity.

If desired, update the default text:

- <span>{callToActionText ? callToActionText : "Share on X"}</span>
+ <span>{callToActionText ? callToActionText : "Share on Twitter"}</span>

39-39: Improve accessibility with aria-labels

Adding aria-label or title attributes to the TwitterIcon can improve accessibility for users relying on screen readers.

Example:

<TwitterIcon
  className={`${hover ? "text-brown" : "text-gold"} transition-all duration-300`}
  aria-label="Twitter icon"
/>
client/src/ui/modules/military/battle-view/battle-twitter-share-button.tsx (4)

60-63: Include getAddressNameFromEntity in useMemo dependencies.

The enemyName computation uses getAddressNameFromEntity, which might change if the entities data updates. To ensure consistency, include it in the dependencies array.

Update the useMemo dependencies:

}, [defenderArmies, attackerArmies, ownArmySide
+ , getAddressNameFromEntity
]);

65-74: Add missing dependencies to useMemo hooks.

The totalAttackerTroops and totalDefenderTroops computations depend on properties of battleAdjusted. If these properties change, the memoized values should update accordingly.

Include the specific battleAdjusted properties in the dependencies:

[attackerArmies, battleAdjusted
+ ?.attack_army_health.current],
[defenderArmies, battleAdjusted
+ ?.defence_army_health.current],

77-80: Clarify conditional logic for choosing Twitter templates.

The nested ternary operators in generateTwitterText can be hard to read and maintain.

Consider simplifying the conditional logic for better readability:

const text = structure
  ? structure.isMine
    ? twitterTemplates.underSiege
    : twitterTemplates.attacking
  : twitterTemplates.battling;

Optionally, refactor using a function or clearer conditional statements.


89-89: Optimize useMemo dependencies for twitterText.

The generateTwitterText function depends on more than the specified dependencies. Ensure all variables used within the function are included.

Verify that structure and any other variables referenced in generateTwitterText are appropriately included in the dependencies.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between fea2e59 and 7110242.

⛔ Files ignored due to path filters (1)
  • client/src/assets/icons/twitter.svg is excluded by !**/*.svg
📒 Files selected for processing (6)
  • client/src/ui/components/military/PillageHistory.tsx (2 hunks)
  • client/src/ui/elements/TwitterShareButton.tsx (1 hunks)
  • client/src/ui/modules/military/battle-view/Battle.tsx (2 hunks)
  • client/src/ui/modules/military/battle-view/battle-twitter-share-button.tsx (1 hunks)
  • client/src/ui/modules/onboarding/Steps.tsx (2 hunks)
  • client/src/ui/socials.ts (1 hunks)
🔇 Additional comments (14)
client/src/ui/socials.ts (1)

21-27: 🛠️ Refactor suggestion

Consider Twitter's constraints and template consistency

The templates need to account for Twitter's character limits and maintain consistent styling.

Let's verify the template lengths with maximum-length values:

Consider these improvements:

  1. Extract the Twitter handle to a constant for maintainability
  2. Add character limit validation in formatSocialText
  3. Standardize emoji usage across templates
  4. Consider shorter alternatives for long templates
+const TWITTER_HANDLE = '@RealmsEternum';
+const MAX_TWEET_LENGTH = 280;
+
 export const twitterTemplates = {
   battling: `⚔️ My army is battling another army in Eternum! ⚔️\n\nI am battling against {enemyName} with {attackerTroops} troops on my side against {defenderTroops} troops on their side.\n\nJoin the battle at {url} 🛡️`,
   underSiege: `🏰 My realm is under siege in Eternum! 🏰\n\n{enemyName} is attacking with {attackerTroops} troops ⚔️ while I'm defending with {defenderTroops} troops 🛡️.\n\nHelp me keep my realm at {url} 👑`,
   attacking: `🔥 I'm attacking {enemyName}'s realm in Eternum! 🔥\n\nI have {attackerTroops} troops 🗡️ against their {defenderTroops} troops.\n\nHelp me conquer their realm at {url} 🏰`,
   settle: `I've joined the Eternum battle for glory.\nWars will be fought, tears will be shed.\n\n{realmName} has been settled. ⚔️\n\nSettle your realm at {url} and compete for 100K $LORDS`,
-  pillage: `I, Ser {addressName}, have just raided {enemyName} from {resources} in @RealmsEternum.💰💰💰\n\nJoin the battle for victory at {url}`,
+  pillage: `I, Ser {addressName}, have just raided {enemyName} from {resources} in ${TWITTER_HANDLE} 💰\n\nJoin the battle at {url}`,
 };
client/src/ui/modules/military/battle-view/Battle.tsx (1)

18-18: LGTM: Clean import addition

The import statement follows React conventions and maintains good code organization.

client/src/ui/components/military/PillageHistory.tsx (5)

6-8: LGTM! Import changes align with social sharing feature addition.

The new imports support the Twitter sharing functionality and resource formatting improvements.


16-20: LGTM! Proper account context usage.

The account context is correctly destructured from useDojo for player identification.


27-30: LGTM! Well-implemented player identification logic.

The useMemo hook efficiently caches the player check result with proper dependencies.


55-55: LGTM! Clean Twitter share button integration.

The button is properly conditionally rendered and sized appropriately.


56-58: LGTM! Clear player identification in UI.

The conditional rendering and styling effectively distinguish between the current player and others.

client/src/ui/modules/onboarding/Steps.tsx (2)

21-23: LGTM: Clean import organization for social sharing feature.

The new imports are well-organized and properly scoped for the social sharing functionality.


331-335: LGTM: Clean layout implementation.

The button layout is well-structured with proper spacing and conditional rendering of the TwitterShareButton.

client/src/ui/elements/TwitterShareButton.tsx (3)

8-10: Enhance component flexibility with new optional props

Great job adding callToActionText, buttonSize, and variant props to make the TwitterShareButton more configurable and reusable in different contexts.


13-19: Set default prop values in the component

Setting default values for buttonSize and variant directly in the destructuring assignment ensures that the component behaves predictably even if these props are not provided.


31-37: Verify that the Button component supports all passed props

Ensure that the Button component accepts and correctly handles the size, variant, onPointerEnter, and onPointerLeave props. If these are not supported, they may have no effect or cause unexpected behavior.

Run the following script to check the Button component's prop types:

✅ Verification successful

Let me gather more information about the Button component's props.


All props are properly supported by the Button component

The Button component fully supports all the props being passed:

  • size: Supported with values "xs" | "md"
  • variant: Supported with values "primary" | "secondary" | "success" | "red" | "danger" | "default" | "outline" | "opaque"
  • onPointerEnter and onPointerLeave: These are automatically supported as the component extends React.ComponentPropsWithRef<"button">, which includes all native button props
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the Button component supports the specified props.

# Search for the Button component's prop definitions and check for the props.
fd 'Button.tsx' --exec cat {} \; | rg -A 10 'interface Props' | rg 'size|variant|onPointerEnter|onPointerLeave'

Length of output: 162


Script:

#!/bin/bash
# Search for the complete Button component interface and implementation
fd 'Button.tsx' --exec cat {} \;

Length of output: 15247

client/src/ui/modules/military/battle-view/battle-twitter-share-button.tsx (2)

35-37: Ensure troops counts are accurately calculated.

When summing up the troops counts, ensure that all troop types are included and that the properties exist. The use of army?.troops?.<troop_type> prevents potential undefined errors if troops is not defined.


46-58: Consistent handling of adjusted health in calculateTotalTroops.

In calculateTotalTroops, when adjustedHealth is provided, it's returned directly. When it's not, the total troops are calculated from the armies. Verify that this logic aligns with the intended behavior and that adjustedHealth accurately represents the total health.

Please confirm that adjustedHealth corresponds to the entire army's total health and that bypassing the individual troop counts is appropriate in this context.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (1)
client/src/ui/components/bank/LiquidityTable.tsx (1)

31-35: Consider optimizing the filtering performance

The current implementation performs multiple array operations on every render. Consider memoizing the filtered results using useMemo and creating a lookup map for resources to avoid repeated find operations.

Here's a suggested optimization:

const resourceMap = useMemo(
  () => Object.fromEntries(resources.map(r => [r.id, r])),
  []
);

const filteredResources = useMemo(() => {
  const searchLower = searchTerm.toLowerCase();
  return Object.entries(RESOURCE_TIERS).flatMap(([tier, resourceIds]) => {
    if (tier === "lords") return [];
    return resourceIds.filter((resourceId) => {
      const resource = resourceMap[resourceId];
      return resource?.trait?.toLowerCase().includes(searchLower) ?? false;
    });
  });
}, [searchTerm, resourceMap]);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7110242 and 97d36bb.

📒 Files selected for processing (3)
  • client/src/three/sound/utils.ts (1 hunks)
  • client/src/ui/components/bank/LiquidityTable.tsx (1 hunks)
  • landing/schema.graphql (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • client/src/three/sound/utils.ts
  • landing/schema.graphql

client/src/ui/components/bank/LiquidityTable.tsx Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 97d36bb and ff378f4.

📒 Files selected for processing (1)
  • package.json (1 hunks)

package.json Outdated Show resolved Hide resolved
@aymericdelab
Copy link
Collaborator

@edisontim i've tried fixing the linter but for some reason it's bugged

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (2)
client/src/ui/elements/TwitterShareButton.tsx (1)

13-27: Consider moving static objects outside the component

The iconSizeClasses object is static and doesn't depend on props or state. Moving it outside the component would prevent unnecessary recreation on each render.

+const iconSizeClasses = {
+  xs: "h-3 w-3",
+  md: "h-4 w-4",
+};

const TwitterShareButton: React.FC<Props> = ({
  text,
  className,
  callToActionText,
  buttonSize = "md",
  variant = "primary",
}) => {
  const [hover, setHover] = React.useState(false);

  const tweetUrl = `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}`;

-  const iconSizeClasses = {
-    xs: "h-3 w-3",
-    md: "h-4 w-4",
-  };
client/src/ui/modules/onboarding/Steps.tsx (1)

318-324: Consider optimizing social text generation

The social text is generated even when realmName is undefined. Consider moving this logic inside a useEffect or memoizing it to avoid unnecessary computations.

-  const realmName = settledRealmId ? getRealmNameById(settledRealmId) : undefined;
-  const socialsText = formatSocialText(twitterTemplates.settle, {
-    realmName: realmName || "",
-    url: window.location.origin,
-  });
+  const realmName = useMemo(() => 
+    settledRealmId ? getRealmNameById(settledRealmId) : undefined,
+    [settledRealmId]
+  );
+  
+  const socialsText = useMemo(() => 
+    realmName ? formatSocialText(twitterTemplates.settle, {
+      realmName,
+      url: window.location.origin,
+    }) : undefined,
+    [realmName]
+  );
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3a8e3ed and 1c6e332.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • client/src/ui/elements/TwitterShareButton.tsx (1 hunks)
  • client/src/ui/modules/onboarding/Steps.tsx (2 hunks)
🔇 Additional comments (4)
client/src/ui/elements/TwitterShareButton.tsx (3)

8-10: LGTM! Well-structured type definitions

The new optional props are well-typed using TypeScript's union types, maintaining backward compatibility while adding flexibility for button customization.


31-41: LGTM! Well-implemented button with proper security and accessibility

The button implementation:

  • Correctly uses the new customization props
  • Implements smooth hover animations
  • Uses proper security attributes for external links
  • Maintains good accessibility with clear text labels

Line range hint 1-46: Verify component usage across the codebase

Since this component's interface has been significantly enhanced, let's ensure all existing usages are compatible with these changes.

✅ Verification successful

Let me gather more information about the actual usage of the component to verify the props being passed.


Based on the analysis of the component usage across the codebase, I can now provide the final response:

All usages of TwitterShareButton are compatible with the interface changes

The component is used in three locations, and all usages are passing valid props that match the updated interface:

  1. battle-twitter-share-button.tsx:
<TwitterShareButton
  className="h-10"
  variant="opaque"
  callToActionText="Call to Arms!"
  text={twitterText}
  buttonSize="md"
/>
  1. Steps.tsx:
<TwitterShareButton
  buttonSize="md"
  variant="default"
  className="mt-4 col-start-3 justify-self-start hover:text-gold"
  text={socialsText}
/>
  1. PillageHistory.tsx:
<TwitterShareButton text={twitterText} buttonSize={"xs"} />

All instances use the proper prop types and provide valid values for the optional props. The changes to the component interface have been properly integrated across the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all usages of TwitterShareButton to verify proper integration

# Search for TwitterShareButton imports and usage
rg -A 5 "TwitterShareButton" --type tsx --type jsx

# Search for potential test files
fd -e test.tsx -e test.jsx -e spec.tsx -e spec.jsx | xargs rg "TwitterShareButton"

Length of output: 1355


Script:

#!/bin/bash
# Get the implementation details of files using TwitterShareButton
cat client/src/ui/modules/military/battle-view/battle-twitter-share-button.tsx
cat client/src/ui/modules/onboarding/Steps.tsx
cat client/src/ui/components/military/PillageHistory.tsx

Length of output: 26998

client/src/ui/modules/onboarding/Steps.tsx (1)

21-23: LGTM: Clean import organization

The new imports are well-organized and properly scoped for the social sharing functionality.

Comment on lines +329 to +340
<div className="grid grid-cols-3 w-full justify-center items-center">
<Button size="md" className="mt-4 col-start-2 justify-self-center" variant="primary" onClick={onNext}>
Continue <ArrowRight className="w-2 fill-current ml-3" />
</Button>
{true && (
<TwitterShareButton
buttonSize="md"
variant="default"
className="mt-4 col-start-3 justify-self-start hover:text-gold"
text={socialsText}
/>
)}
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 layout structure and conditional rendering

Several improvements can be made to the layout and rendering logic:

  1. The hardcoded true condition makes the conditional rendering redundant
  2. The grid layout using magic numbers might not be responsive
  3. The button placement could be more maintainable using flex layout
-      <div className="grid grid-cols-3 w-full justify-center items-center">
-        <Button size="md" className="mt-4 col-start-2 justify-self-center" variant="primary" onClick={onNext}>
+      <div className="flex w-full justify-center items-center gap-4">
+        <Button size="md" className="mt-4" variant="primary" onClick={onNext}>
           Continue <ArrowRight className="w-2 fill-current ml-3" />
         </Button>
-        {true && (
+        {socialsText && (
           <TwitterShareButton
             buttonSize="md"
             variant="default"
-            className="mt-4 col-start-3 justify-self-start hover:text-gold"
+            className="mt-4 hover:text-gold"
             text={socialsText}
           />
-        )}
       </div>
📝 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
<div className="grid grid-cols-3 w-full justify-center items-center">
<Button size="md" className="mt-4 col-start-2 justify-self-center" variant="primary" onClick={onNext}>
Continue <ArrowRight className="w-2 fill-current ml-3" />
</Button>
{true && (
<TwitterShareButton
buttonSize="md"
variant="default"
className="mt-4 col-start-3 justify-self-start hover:text-gold"
text={socialsText}
/>
)}
<div className="flex w-full justify-center items-center gap-4">
<Button size="md" className="mt-4" variant="primary" onClick={onNext}>
Continue <ArrowRight className="w-2 fill-current ml-3" />
</Button>
{socialsText && (
<TwitterShareButton
buttonSize="md"
variant="default"
className="mt-4 hover:text-gold"
text={socialsText}
/>
)}
</div>

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
client/src/hooks/helpers/useEntities.tsx (1)

148-149: LGTM! Consider extending sorting to otherRealms for consistency.

The addition of name-based sorting for player realms improves the user experience by providing a consistent ordering. The implementation correctly uses localeCompare and maintains proper order of operations (filter then sort).

Consider applying the same sorting to getOtherRealms for complete consistency:

  const getOtherRealms = (filterFn?: (realm: RealmWithPosition) => boolean) => {
    return useMemo(() => {
-     return filterFn ? otherRealms.filter(filterFn) : otherRealms;
+     const realms = filterFn ? otherRealms.filter(filterFn) : otherRealms;
+     return realms.sort((a, b) => a.name.localeCompare(b.name));
    }, [otherRealms, filterFn]);
  };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 1c6e332 and 37e0b8e.

📒 Files selected for processing (2)
  • client/src/hooks/helpers/useEntities.tsx (1 hunks)
  • client/src/ui/components/cityview/realm/SettleRealmComponent.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • client/src/ui/components/cityview/realm/SettleRealmComponent.tsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants