Skip to content

Conversation

foodaka
Copy link
Collaborator

@foodaka foodaka commented Oct 2, 2025

General Changes

  • Improves logic for handling which banner is shown(before main net would briefly show and then the intended banner)
  • Adds banner for arb limit orders

Developer Notes

Add any notes here that may be helpful for reviewers.


Reviewer Checklist

Please ensure you, as the reviewer(s), have gone through this checklist to ensure that the code changes are ready to ship safely and to help mitigate any downstream issues that may occur.

  • End-to-end tests are passing without any errors
  • Code changes do not significantly increase the application bundle size
  • If there are new 3rd-party packages, they do not introduce potential security threats
  • If there are new environment variables being added, they have been added to the .env.example file as well as the pertinant .github/actions/* files
  • There are no CI changes, or they have been approved by the DevOps and Engineering team(s)

Copy link

vercel bot commented Oct 2, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
interface Error Error Oct 3, 2025 3:56pm

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR improves the banner display logic to prevent brief flashing of incorrect banners and adds support for Arbitrum limit orders campaigns. The changes ensure that only the intended banner for the user's selected or intended chain is shown, rather than showing all configured campaigns.

  • Modified banner selection logic to show only the intended chain's campaign instead of all available campaigns
  • Added support for Arbitrum limit orders banner campaign
  • Introduced logic to determine the intended chain ID based on localStorage and URL parameters

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/layouts/TopBarNotify.tsx Updated to use campaign-specific chain ID for localStorage operations instead of current chain ID
src/layouts/MainLayout.tsx Added intended chain ID detection logic and filtering to show only relevant campaigns

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 50 to 51
const firstChainId = chainIds[0];
return firstChainId ? campaigns[firstChainId] || null : null;
Copy link

Copilot AI Oct 2, 2025

Choose a reason for hiding this comment

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

The logic assumes the first chain ID from Object.keys() is the intended campaign, but Object.keys() order is not guaranteed to be consistent. This could lead to unpredictable banner selection when multiple campaigns are available.

Suggested change
const firstChainId = chainIds[0];
return firstChainId ? campaigns[firstChainId] || null : null;
if (chainIds.length === 0) return null;
if (currentChainId && campaigns[currentChainId]) {
return campaigns[currentChainId];
}
// fallback: select the campaign with the lowest chainId
const minChainId = Math.min(...chainIds);
return campaigns[minChainId] || null;

Copilot uses AI. Check for mistakes.

Comment on lines 173 to 175
const filteredCampaigns: NetworkCampaigns = isCampaignChainId(intendedChainId)
? { [intendedChainId]: campaignConfigs[intendedChainId]! }
: {};
Copy link

Copilot AI Oct 2, 2025

Choose a reason for hiding this comment

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

Using non-null assertion operator (!) without proper null checking could cause runtime errors if campaignConfigs[intendedChainId] is undefined. Consider using optional chaining or explicit null checking.

Suggested change
const filteredCampaigns: NetworkCampaigns = isCampaignChainId(intendedChainId)
? { [intendedChainId]: campaignConfigs[intendedChainId]! }
: {};
const campaign = campaignConfigs[intendedChainId];
const filteredCampaigns: NetworkCampaigns =
isCampaignChainId(intendedChainId) && campaign !== undefined
? { [intendedChainId]: campaign }
: {};

Copilot uses AI. Check for mistakes.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting

Comment on lines 165 to 175
const campaignConfigs = getCampaignConfigs(openSwitch, openMarket);

const intendedChainId = getIntendedChainId();

const isCampaignChainId = (chainId: ChainId): chainId is CampaignChainId => {
return chainId in campaignConfigs;
};

const filteredCampaigns: NetworkCampaigns = isCampaignChainId(intendedChainId)
? { [intendedChainId]: campaignConfigs[intendedChainId]! }
: {};

Choose a reason for hiding this comment

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

P1 Badge Keep banner campaigns in sync with market changes

The new filteredCampaigns is derived from getIntendedChainId() using only localStorage/URL and is computed once in MainLayout. Because this component subscribes only to setCurrentMarket, it never re-renders when the user switches markets or when a marketName query param overrides a stale localStorage value. Meanwhile TopBarNotify now shows the first entry it receives, so after the initial render the banner stays locked to whatever chain was chosen at load time (e.g. start on mainnet, switch to Base, but the mainnet campaign continues to display). The banner logic therefore regresses compared to before. Consider deriving the campaign from the store’s currentChainId or recomputing filteredCampaigns when the selected market changes.

Useful? React with 👍 / 👎.

Copy link

github-actions bot commented Oct 2, 2025

Copy link

github-actions bot commented Oct 2, 2025

📦 Next.js Bundle Analysis for aave-ui

This analysis was generated by the Next.js Bundle Analysis action. 🤖

This PR introduced no changes to the JavaScript bundle! 🙌

Copy link

github-actions bot commented Oct 2, 2025

Copy link

github-actions bot commented Oct 2, 2025

📦 Next.js Bundle Analysis for aave-ui

This analysis was generated by the Next.js Bundle Analysis action. 🤖

This PR introduced no changes to the JavaScript bundle! 🙌

Copy link

github-actions bot commented Oct 2, 2025

Copy link

github-actions bot commented Oct 2, 2025

📦 Next.js Bundle Analysis for aave-ui

This analysis was generated by the Next.js Bundle Analysis action. 🤖

This PR introduced no changes to the JavaScript bundle! 🙌

@foodaka foodaka requested a review from Copilot October 2, 2025 14:42
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

};

const currentCampaign = getCurrentCampaign();
const campaignChainId = currentChainId;
Copy link

Copilot AI Oct 2, 2025

Choose a reason for hiding this comment

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

The variable campaignChainId is redundant as it simply aliases currentChainId. Consider removing this variable and using currentChainId directly throughout the component to reduce unnecessary indirection.

Copilot uses AI. Check for mistakes.

// Use stored preference for this chain
setShowWarning(warningBarOpen !== 'false');
}
}, [currentCampaign, campaignChainId, currentChainId]);
Copy link

Copilot AI Oct 2, 2025

Choose a reason for hiding this comment

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

The dependency array includes both campaignChainId and currentChainId which are the same value. Since campaignChainId is just an alias for currentChainId, only currentChainId should be included in the dependency array.

Suggested change
}, [currentCampaign, campaignChainId, currentChainId]);
}, [currentCampaign, currentChainId]);

Copilot uses AI. Check for mistakes.

Copy link

github-actions bot commented Oct 2, 2025

Copy link

github-actions bot commented Oct 2, 2025

📦 Next.js Bundle Analysis for aave-ui

This analysis was generated by the Next.js Bundle Analysis action. 🤖

This PR introduced no changes to the JavaScript bundle! 🙌

};

const campaignConfigs = getCampaignConfigs(openMarket);
const campaignConfigs = getCampaignConfigs(openSwitch, openMarket);
Copy link
Contributor

Choose a reason for hiding this comment

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

would move getCampaignConfigs to a hook useBannerCampaigns so we can get openSwitch (or others in the future) right in there and just pass the chain id

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done in 33af445

icon: string;
}

type CampaignChainId = ChainId.base | ChainId.mainnet | ChainId.arbitrum_one;
Copy link
Contributor

Choose a reason for hiding this comment

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

why not just use generic ChainId if down here we use Partial of chains ids

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah good point 33af445

buttonText: string;
buttonAction: ButtonAction;
bannerVersion: string;
icon: string;
Copy link
Contributor

Choose a reason for hiding this comment

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

does it make sense to make the icon optional for future solo-text campaings

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yes 33af445

Comment on lines 45 to 49
// Priority 3: URL params marketName
const urlMarket = getQueryParameter('marketName');
if (urlMarket && marketsData[urlMarket as CustomMarket]) {
return marketsData[urlMarket as CustomMarket].chainId;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't this be prioritized e.g. someone opens a shared link but been using other network

// icon: '/icons/networks/arbitrum.svg',
// },
[ChainId.arbitrum_one]: {
notifyText: 'Limit orders are now live on Arbitrum',
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure how translations work but can we ensure banner messages will be translated this way? otherwise we can set notifyText type as react node and just use

Copy link
Contributor

Choose a reason for hiding this comment

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

i see
` {currentCampaign.notifyText}

`
just checking if it's enough

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah we dont really use translations much but added b2f5f50

openMarket: (market: CustomMarket) => void
) => ({
): CampaignConfigs => ({
[ChainId.base]: {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit/v2: we can leverage vercel configs or amplitude feature flags to automatically change campaings without commiting new code

Comment on lines 81 to 91
useEffect(() => {
if (showWarning) {
const timer = setTimeout(() => {
setSlideIn(true);
}, 100);

return () => clearTimeout(timer);
} else {
setSlideIn(false);
}
}, [currentCampaign, currentChainId]);
}, [showWarning]);
Copy link
Contributor

Choose a reason for hiding this comment

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

cant this be replaced by a showWarning fn that has the timeout inside?

Copy link
Contributor

Choose a reason for hiding this comment

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

ui ideas

Image

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.

2 participants