Conversation
|
Warning Review limit reached
Next review available in: 57 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThis PR adds side-panel support across the extension: new hooks and manifest entries register the side panel, a new button opens it, and many popup and staking screens now switch layout and sizing when rendered in side-panel mode. ChangesSide Panel Mode
Estimated code review effort: 4 (Complex) | ~75 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant SidePanelModeButton
participant chrome.sidePanel.open
participant CurrentWindow
User->>SidePanelModeButton: click
SidePanelModeButton->>chrome.sidePanel.open: open({ windowId })
chrome.sidePanel.open-->>SidePanelModeButton: success
SidePanelModeButton->>CurrentWindow: window.close()
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
PR Summary by QodoAdd Chrome side panel mode for extension UI
AI Description
Diagram
High-Level Assessment
Files changed (54)
|
Code Review by Qodo
Context used✅ Compliance rules (platform):
14 rules 1.
|
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
packages/extension-polkagate/src/popup/staking/pool-new/joinPool/ChoosePool.tsx (1)
105-135: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd a flex-column wrapper for
ChoosePoolThe currentMotionwrapper is a plainmotion.div, soflex: '1 1 auto'/minHeight: 0on the innerStackwon’t take effect unless an ancestor setsdisplay: flex; flexDirection: column.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/popup/staking/pool-new/joinPool/ChoosePool.tsx` around lines 105 - 135, The inner Stack in ChoosePool relies on flex sizing, but its current Motion wrapper is a plain motion.div so the column flex rules do not apply. Update the ChoosePool wrapper around the Stack to be a flex column container (or ensure the Motion component applies display flex with column direction) so the Stack’s flex: '1 1 auto' and minHeight: 0 behavior works as intended.packages/extension-polkagate/src/popup/accountsLists/NewProfile.tsx (1)
50-73: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winSame missing-
.catchpattern asEditProfile.onEdit.
Promise.all(...).finally(...)here has no.catch, so a rejectedupdateMetacall surfaces as an unhandled promise rejection while the popup still closes via.finallyas though the add succeeded.🔧 Proposed fix
}) || []).finally(() => { + }) || []).catch(console.error).finally(() => { setIsBusy(false); handleClose(); });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/popup/accountsLists/NewProfile.tsx` around lines 50 - 73, The onAdd flow in NewProfile is missing the same rejection handling used in EditProfile.onEdit: Promise.all(...).finally(...) will still close the popup even if updateMeta fails, and the rejection becomes unhandled. Update onAdd to explicitly catch errors around the Promise.all/updateMeta work, keep setIsBusy(false) in a shared cleanup path, and only call handleClose after a successful add so failures are surfaced instead of looking successful.packages/extension-polkagate/src/popup/accountsLists/EditProfile.tsx (2)
47-83: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winMissing error handling on the second persistence phase.
The first
Promise.all(Lines 52-63) has.catch(console.error), but the secondPromise.all(Lines 65-82) only has.finally, no.catch. If anyupdateMetacall in phase 2 rejects, it becomes an unhandled promise rejection — silently swallowed while the popup still closes as if the update succeeded (via.finally), giving the user no signal of a partial failure.🔧 Proposed fix
}) || []).finally(() => { + }) || []).catch(console.error).finally(() => { setIsBusy(false); handleClose(); });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/popup/accountsLists/EditProfile.tsx` around lines 47 - 83, The second persistence phase in onEdit is missing error handling, so failures from updateMeta in the allAccounts Promise.all can become unhandled while the popup still closes. Add a .catch handler to that Promise.all (alongside the existing .finally) and surface/log the rejection before closing, so the EditProfile flow only completes cleanly when all metadata updates succeed. Keep the cleanup in .finally, but ensure any phase-2 failure is observed and reported.
47-63: 🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick winSkip the cleanup pass for retained accounts. In this editable-profile path,
useProfileAccounts(allAccounts, profileLabel)falls through to tag-based filtering, soaccount.profile?.includes(profileLabel)doesn’t narrow the loop. As a result, accounts that stay selected get stripped in phase 1 and written again in phase 2, adding an unnecessary update and briefly clearing the tag. Gate the first pass on!selectedAddresses.has(account.address)instead.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/popup/accountsLists/EditProfile.tsx` around lines 47 - 63, The first cleanup pass in onEdit is affecting retained accounts because the current account.profile?.includes(profileLabel) check does not exclude still-selected accounts from useProfileAccounts(allAccounts, profileLabel). Update the Promise.all loop in EditProfile.tsx to skip any account whose address is in selectedAddresses by gating the cleanup on !selectedAddresses.has(account.address), so retained accounts are not stripped and rewritten during phase 1.packages/extension-polkagate/src/popup/notification/partials/SelectChain.tsx (1)
61-74: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
ExtensionPopupneeds a side-panel height override here. In side-panel mode the content grows tocalc(100vh - 250px), but the popup shell still falls back to its 440px default because neithermaxHeightnorcompactInSidePanelis passed. That can leave this screen with extra scrolling or clipped content.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/popup/notification/partials/SelectChain.tsx` around lines 61 - 74, The SelectChain popup is not applying the side-panel height override to ExtensionPopup, so the shell still uses its default 440px sizing in side-panel mode. Update the ExtensionPopup usage in SelectChain to pass the side-panel-specific height behavior, using the existing isSidePanel check and the relevant props such as maxHeight and/or compactInSidePanel so the shell matches the inner content sizing.
🧹 Nitpick comments (12)
packages/extension-polkagate/src/partials/ConnectedAccounts.tsx (1)
32-40: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueStale comment now describes the wrong variable.
// Sort only on the first render, store result in a refwas moved abovelistRefbut actually documentssortedAccountsRef(declared on the next line). Consider moving the comment back next tosortedAccountsRef.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/partials/ConnectedAccounts.tsx` around lines 32 - 40, The inline comment is attached to the wrong variable and now describes `sortedAccountsRef` instead of `listRef`. Move or reattach the “Sort only on the first render, store result in a ref” comment so it sits directly above `sortedAccountsRef` in `ConnectedAccounts`, keeping `listRef` documented separately and ensuring the comment matches the symbol it describes.packages/extension-polkagate/src/partials/BiometricUnlockSetting.tsx (1)
41-49: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUnreachable side-panel branch in the enable-password
SharePopup.
isEnableBlockedInSidePanel(isSidePanel && !status.enabled) blocks the switch andonTogglewhenever the user tries to enable biometrics from the side panel, andsetShowPasswordForm(true)is only reached after that check passes. That meansshowPasswordFormcan never betruewhileisSidePanelistrue, so theisSidePanelbranches inpopupProps(Line 204compactInSidePanel: isSidePanel, Line 205maxHeight: isSidePanel ? 'calc(100vh - 190px)' : ...) never actually execute for this popup.Consider simplifying to reflect that this modal only ever opens outside the side panel, or reconsider if the enable-block gate was meant to be narrower (e.g., only block after the password form step) so this branch becomes reachable.
♻️ Possible simplification if the enable-blocked gate is intentional as-is
popupProps={{ - compactInSidePanel: isSidePanel, - maxHeight: isSidePanel ? 'calc(100vh - 190px)' : isExtension ? '100%' : '360px', + maxHeight: isExtension ? '100%' : '360px', pt: 90, withGradientBorder: true }}As per coding guidelines, "Write minimum code that solves the problem without speculative features" — this branch is speculative/unreachable given the current gating logic.
Also applies to: 107-120, 204-211
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/partials/BiometricUnlockSetting.tsx` around lines 41 - 49, The `BiometricUnlockSetting` flow has an unreachable side-panel path because `isEnableBlockedInSidePanel` prevents entering `setShowPasswordForm(true)` when `isSidePanel` is true. Update the gating around `onToggle`/password-form entry so the `popupProps` side-panel branches (`compactInSidePanel`, `maxHeight`) are either removed as dead code or made reachable by narrowing the block to the intended step in `BiometricUnlockSetting`/`SharePopup` rather than blocking the entire enable flow.Source: Coding guidelines
packages/extension-polkagate/src/hooks/useUiMode.ts (1)
12-28: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSimplify the redundant branches.
Both branches return the same
isExtension/isSidePanelfields and only differ inisFullscreen, which is simply the negation of theifcondition. This can be collapsed into a single return.♻️ Proposed simplification
export default function useUiMode(): { isExtension: boolean, isSidePanel: boolean, isFullscreen: boolean } { const isExtension = useIsExtensionPopup(); const isSidePanel = useIsSidePanel(); - if (isExtension || isSidePanel) { - return { - isExtension, - isFullscreen: false, - isSidePanel - }; - } - - return { - isExtension, - isFullscreen: true, - isSidePanel - }; + return { + isExtension, + isFullscreen: !(isExtension || isSidePanel), + isSidePanel + }; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/hooks/useUiMode.ts` around lines 12 - 28, Simplify the redundant branching in useUiMode by collapsing the two return paths into a single return statement. The function useUiMode currently returns the same isExtension and isSidePanel values in both branches, so replace the if/else structure with one object that sets isFullscreen based on the negation of the existing extension/side-panel condition. Keep the useIsExtensionPopup and useIsSidePanel calls unchanged.packages/extension-polkagate/src/hooks/useIsExtensionPopup.ts (2)
12-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReuse
useIsSidePanelinstead of re-deriving the pathname check.This inlines the same
/sidepanel.htmlpathname check already implemented inuseIsSidePanel.ts. Reusing the hook avoids duplicated logic that could drift if the detection rule changes.♻️ Proposed fix
+import useIsSidePanel from './useIsSidePanel'; + export default function useIsExtensionPopup(): boolean { - const isSidePanel = window.location.pathname.endsWith('/sidepanel.html'); + const isSidePanel = useIsSidePanel(); if (isSidePanel) { return true; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/hooks/useIsExtensionPopup.ts` around lines 12 - 17, The pathname check for detecting the extension popup is duplicated in useIsExtensionPopup and should reuse the existing useIsSidePanel hook instead of re-deriving /sidepanel.html logic. Update useIsExtensionPopup to call useIsSidePanel and base its return value on that shared hook so the detection logic stays centralized and consistent.
4-10: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate chrome-access boilerplate across files.
ChromeWithExtensionViews/getChromehere mirrors the near-identicalChromeWithSidePanel/getChromepattern inSidePanelModeButton.tsx. Consider extracting a shared typedchromeaccessor (or a single unified interface) to avoid maintaining duplicateglobalThis.chrometypings in multiple places.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/hooks/useIsExtensionPopup.ts` around lines 4 - 10, The chrome access typing is duplicated here and in the SidePanelModeButton code path, so extract a shared typed chrome accessor or unified chrome interface instead of keeping separate ChromeWithExtensionViews/getChrome boilerplate in useIsExtensionPopup. Move the reusable chrome typing/access helper to a common module, then update both useIsExtensionPopup and SidePanelModeButton to consume that shared symbol so globalThis.chrome is defined in one place.packages/extension-polkagate/src/partials/SidePanelModeButton.tsx (2)
74-89: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueClickable
Boxlacks keyboard accessibility.No
role,tabIndex, oronKeyDownhandler, so keyboard-only users can't activate this button. If this matches an existing pattern (e.g.FullscreenModeButton), consider addressing both together.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/partials/SidePanelModeButton.tsx` around lines 74 - 89, The clickable Box in SidePanelModeButton is mouse-only and lacks keyboard access. Update the Box used as the button container to match the existing accessible button pattern (for example, the one in FullscreenModeButton) by adding the appropriate role, tabIndex, and an onKeyDown handler that activates on keyboard input. Keep the existing onClick behavior and ensure the interactive semantics are applied to the same buttonContainer element.
11-20: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueCentralize the typed
chromeaccessor Consider sharing thechromewrapper/type instead of duplicatingChromeWith*+getChromeinuseIsExtensionPopup.ts,ConnectedDapp.tsx, and this file; keeping them local makes thechromeshape easy to drift over time.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/partials/SidePanelModeButton.tsx` around lines 11 - 20, Centralize the typed chrome accessor instead of keeping separate ChromeWith* interfaces and getChrome helpers in SidePanelModeButton, useIsExtensionPopup, and ConnectedDapp. Move the shared chrome shape/wrapper into a common utility or type definition, then update SidePanelModeButton to import and use that shared accessor so the chrome API contract stays consistent across all call sites.packages/extension-polkagate/src/popup/staking/easyStake/SelectPool.tsx (1)
118-118: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winStack
sxlayout object is duplicated inChoosePool.tsx.The exact same object (
flex/height/maxHeight/minHeight/overflowY) is repeated inpackages/extension-polkagate/src/popup/staking/pool-new/joinPool/ChoosePool.tsx(line 105). Given both components already share nearly identical pool-filtering logic, consider extracting a sharedusePoolListStackStyle()helper (or a small shared style constant) to avoid the two copies drifting apart.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/popup/staking/easyStake/SelectPool.tsx` at line 118, The Stack sx layout object used in SelectPool and ChoosePool is duplicated and should be centralized. Extract the shared flex/height/maxHeight/minHeight/overflowY/px/width styling into a common helper or shared constant such as a usePoolListStackStyle() hook, then use it from both SelectPool and ChoosePool to keep the pool list container styling in sync.packages/extension-polkagate/src/popup/staking/EarningOptions.tsx (1)
74-87: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftExtract the repeated side-panel layout styles into a shared helper.
The Grid
sx(flexDirection/flexWrap/height/overflow/pb) and theMotionstyleobject are duplicated verbatim inReward.tsx(lines 207, 209) andStakingPositions.tsx(lines 183, 191). A shared hook/constant (e.g.useSidePanelPageStyle()returning{ gridSx, motionStyle }) would remove this triplication and prevent future drift when one page's layout needs tweaking but the others are missed.♻️ Example extraction
// hooks/useSidePanelPageStyle.ts export default function useSidePanelPageStyle(bottomPad = '86px') { const isSidePanel = useIsSidePanel(); return { isSidePanel, gridSx: { flexDirection: isSidePanel ? 'column' : undefined, flexWrap: isSidePanel ? 'nowrap' : undefined, height: isSidePanel ? '100vh' : undefined, overflow: isSidePanel ? 'hidden' : undefined, pb: isSidePanel ? bottomPad : undefined, position: 'relative' }, motionStyle: isSidePanel ? { display: 'flex', flex: '1 1 auto', flexDirection: 'column', minHeight: 0, overflow: 'hidden' } : undefined } as const; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/popup/staking/EarningOptions.tsx` around lines 74 - 87, The side-panel layout styles in the EarningOptions page are duplicated in other staking pages, so extract them into a shared helper to keep them consistent. Move the repeated Grid sx values and Motion style object into a reusable hook/constant such as useSidePanelPageStyle, and use that shared source from EarningOptions, Reward, and StakingPositions. Keep the helper centered around the existing isSidePanel logic so the page components only consume gridSx and motionStyle instead of redefining the same objects.packages/extension-polkagate/src/popup/staking/solo-new/nominations/NominationsSetting.tsx (1)
91-93: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate side-panel height formula across files.
Math.max(viewportHeight - 165, 300)is repeated verbatim inSelectValidator.tsx(line 140). Consider extracting a shared hook (e.g.,useSidePanelTableHeight) to avoid the magic numbers drifting out of sync.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/popup/staking/solo-new/nominations/NominationsSetting.tsx` around lines 91 - 93, The side-panel table height calculation is duplicated with the same magic numbers, so extract it into a shared helper/hook such as useSidePanelTableHeight and use that from NominationsSetting and SelectValidator. Keep the shared logic in one place using the viewportHeight-based Math.max(...) formula so both components stay in sync and the constants are defined only once.packages/extension-polkagate/src/popup/accountsLists/EditProfile.tsx (1)
99-106: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtract the shared viewport offsets These side-panel
calc(100vh - …)values are duplicated acrosspackages/extension-polkagate/src/popup/accountsLists/EditProfile.tsx,packages/extension-polkagate/src/popup/accountsLists/NewProfile.tsx, andpackages/extension-polkagate/src/popup/accountsLists/BodySection.tsx. Pull them into a shared constant/helper so the layout spacing stays consistent.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/popup/accountsLists/EditProfile.tsx` around lines 99 - 106, The side-panel viewport offset values are duplicated across EditProfile, NewProfile, and BodySection, so extract the repeated `calc(100vh - …)` spacing into a shared constant or helper and use it from the relevant layout styles. Update the `EditProfile` layout block (and the matching side-panel sizing in `NewProfile` and `BodySection`) to reference the shared symbol so the spacing stays consistent in one place.packages/extension-polkagate/src/popup/nft/index.tsx (1)
74-80: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate
sxobject shared verbatim withnotification/index.tsx.The outer
Gridsx here (flexDirection,flexWrap,height: '100vh',overflow: 'hidden',pb: '86px',position: 'relative', all gated onisSidePanel) is byte-for-byte identical to the one inpackages/extension-polkagate/src/popup/notification/index.tsx(line 43), and per the PR description this "page shell" pattern likely repeats across several more files in this cohort (home, tokens, etc.). Consider extracting a shared hook/helper (e.g.useSidePanelPageSx()) returning this sx object to avoid maintaining N copies of the same conditional styling.♻️ Example extraction
// hooks/useSidePanelPageSx.ts export default function useSidePanelPageSx() { const isSidePanel = useIsSidePanel(); return { flexDirection: isSidePanel ? 'column' : undefined, flexWrap: isSidePanel ? 'nowrap' : undefined, height: isSidePanel ? '100vh' : undefined, overflow: isSidePanel ? 'hidden' : undefined, pb: isSidePanel ? '86px' : undefined, position: 'relative' } as const; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-polkagate/src/popup/nft/index.tsx` around lines 74 - 80, The outer Grid styling in this NFT popup is duplicated verbatim across the side-panel page shell, so extract the shared conditional sx into a reusable helper or hook (for example, a page-shell sx builder) and use it here and in the matching notification/page components. Update the Grid in nft/index.tsx to consume that shared source of truth so the same isSidePanel-dependent layout is maintained in one place instead of repeating the object in multiple files.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/extension-polkagate/src/partials/SidePanelModeButton.tsx`:
- Line 30: The SidePanelModeButton component is duplicating the side panel URL
check instead of using the shared hook. Update SidePanelModeButton to import and
use useIsSidePanel from the hooks barrel, and replace the inline useMemo
pathname comparison with that hook so the logic stays centralized and
consistent.
In `@packages/extension-polkagate/src/popup/settings/extensionSettings/index.tsx`:
- Line 27: The `location` variable in `ExtensionSettings` is being cast to the
DOM `Location` type, which hides the router-specific shape returned by
`useLocation()`. Update the typing in `index.tsx` to use the router location
type (or narrow only `state` on the `useLocation` result) so `location`
correctly reflects the values from React Router without pretending to be a DOM
`Location`.
---
Outside diff comments:
In `@packages/extension-polkagate/src/popup/accountsLists/EditProfile.tsx`:
- Around line 47-83: The second persistence phase in onEdit is missing error
handling, so failures from updateMeta in the allAccounts Promise.all can become
unhandled while the popup still closes. Add a .catch handler to that Promise.all
(alongside the existing .finally) and surface/log the rejection before closing,
so the EditProfile flow only completes cleanly when all metadata updates
succeed. Keep the cleanup in .finally, but ensure any phase-2 failure is
observed and reported.
- Around line 47-63: The first cleanup pass in onEdit is affecting retained
accounts because the current account.profile?.includes(profileLabel) check does
not exclude still-selected accounts from useProfileAccounts(allAccounts,
profileLabel). Update the Promise.all loop in EditProfile.tsx to skip any
account whose address is in selectedAddresses by gating the cleanup on
!selectedAddresses.has(account.address), so retained accounts are not stripped
and rewritten during phase 1.
In `@packages/extension-polkagate/src/popup/accountsLists/NewProfile.tsx`:
- Around line 50-73: The onAdd flow in NewProfile is missing the same rejection
handling used in EditProfile.onEdit: Promise.all(...).finally(...) will still
close the popup even if updateMeta fails, and the rejection becomes unhandled.
Update onAdd to explicitly catch errors around the Promise.all/updateMeta work,
keep setIsBusy(false) in a shared cleanup path, and only call handleClose after
a successful add so failures are surfaced instead of looking successful.
In
`@packages/extension-polkagate/src/popup/notification/partials/SelectChain.tsx`:
- Around line 61-74: The SelectChain popup is not applying the side-panel height
override to ExtensionPopup, so the shell still uses its default 440px sizing in
side-panel mode. Update the ExtensionPopup usage in SelectChain to pass the
side-panel-specific height behavior, using the existing isSidePanel check and
the relevant props such as maxHeight and/or compactInSidePanel so the shell
matches the inner content sizing.
In
`@packages/extension-polkagate/src/popup/staking/pool-new/joinPool/ChoosePool.tsx`:
- Around line 105-135: The inner Stack in ChoosePool relies on flex sizing, but
its current Motion wrapper is a plain motion.div so the column flex rules do not
apply. Update the ChoosePool wrapper around the Stack to be a flex column
container (or ensure the Motion component applies display flex with column
direction) so the Stack’s flex: '1 1 auto' and minHeight: 0 behavior works as
intended.
---
Nitpick comments:
In `@packages/extension-polkagate/src/hooks/useIsExtensionPopup.ts`:
- Around line 12-17: The pathname check for detecting the extension popup is
duplicated in useIsExtensionPopup and should reuse the existing useIsSidePanel
hook instead of re-deriving /sidepanel.html logic. Update useIsExtensionPopup to
call useIsSidePanel and base its return value on that shared hook so the
detection logic stays centralized and consistent.
- Around line 4-10: The chrome access typing is duplicated here and in the
SidePanelModeButton code path, so extract a shared typed chrome accessor or
unified chrome interface instead of keeping separate
ChromeWithExtensionViews/getChrome boilerplate in useIsExtensionPopup. Move the
reusable chrome typing/access helper to a common module, then update both
useIsExtensionPopup and SidePanelModeButton to consume that shared symbol so
globalThis.chrome is defined in one place.
In `@packages/extension-polkagate/src/hooks/useUiMode.ts`:
- Around line 12-28: Simplify the redundant branching in useUiMode by collapsing
the two return paths into a single return statement. The function useUiMode
currently returns the same isExtension and isSidePanel values in both branches,
so replace the if/else structure with one object that sets isFullscreen based on
the negation of the existing extension/side-panel condition. Keep the
useIsExtensionPopup and useIsSidePanel calls unchanged.
In `@packages/extension-polkagate/src/partials/BiometricUnlockSetting.tsx`:
- Around line 41-49: The `BiometricUnlockSetting` flow has an unreachable
side-panel path because `isEnableBlockedInSidePanel` prevents entering
`setShowPasswordForm(true)` when `isSidePanel` is true. Update the gating around
`onToggle`/password-form entry so the `popupProps` side-panel branches
(`compactInSidePanel`, `maxHeight`) are either removed as dead code or made
reachable by narrowing the block to the intended step in
`BiometricUnlockSetting`/`SharePopup` rather than blocking the entire enable
flow.
In `@packages/extension-polkagate/src/partials/ConnectedAccounts.tsx`:
- Around line 32-40: The inline comment is attached to the wrong variable and
now describes `sortedAccountsRef` instead of `listRef`. Move or reattach the
“Sort only on the first render, store result in a ref” comment so it sits
directly above `sortedAccountsRef` in `ConnectedAccounts`, keeping `listRef`
documented separately and ensuring the comment matches the symbol it describes.
In `@packages/extension-polkagate/src/partials/SidePanelModeButton.tsx`:
- Around line 74-89: The clickable Box in SidePanelModeButton is mouse-only and
lacks keyboard access. Update the Box used as the button container to match the
existing accessible button pattern (for example, the one in
FullscreenModeButton) by adding the appropriate role, tabIndex, and an onKeyDown
handler that activates on keyboard input. Keep the existing onClick behavior and
ensure the interactive semantics are applied to the same buttonContainer
element.
- Around line 11-20: Centralize the typed chrome accessor instead of keeping
separate ChromeWith* interfaces and getChrome helpers in SidePanelModeButton,
useIsExtensionPopup, and ConnectedDapp. Move the shared chrome shape/wrapper
into a common utility or type definition, then update SidePanelModeButton to
import and use that shared accessor so the chrome API contract stays consistent
across all call sites.
In `@packages/extension-polkagate/src/popup/accountsLists/EditProfile.tsx`:
- Around line 99-106: The side-panel viewport offset values are duplicated
across EditProfile, NewProfile, and BodySection, so extract the repeated
`calc(100vh - …)` spacing into a shared constant or helper and use it from the
relevant layout styles. Update the `EditProfile` layout block (and the matching
side-panel sizing in `NewProfile` and `BodySection`) to reference the shared
symbol so the spacing stays consistent in one place.
In `@packages/extension-polkagate/src/popup/nft/index.tsx`:
- Around line 74-80: The outer Grid styling in this NFT popup is duplicated
verbatim across the side-panel page shell, so extract the shared conditional sx
into a reusable helper or hook (for example, a page-shell sx builder) and use it
here and in the matching notification/page components. Update the Grid in
nft/index.tsx to consume that shared source of truth so the same
isSidePanel-dependent layout is maintained in one place instead of repeating the
object in multiple files.
In `@packages/extension-polkagate/src/popup/staking/EarningOptions.tsx`:
- Around line 74-87: The side-panel layout styles in the EarningOptions page are
duplicated in other staking pages, so extract them into a shared helper to keep
them consistent. Move the repeated Grid sx values and Motion style object into a
reusable hook/constant such as useSidePanelPageStyle, and use that shared source
from EarningOptions, Reward, and StakingPositions. Keep the helper centered
around the existing isSidePanel logic so the page components only consume gridSx
and motionStyle instead of redefining the same objects.
In `@packages/extension-polkagate/src/popup/staking/easyStake/SelectPool.tsx`:
- Line 118: The Stack sx layout object used in SelectPool and ChoosePool is
duplicated and should be centralized. Extract the shared
flex/height/maxHeight/minHeight/overflowY/px/width styling into a common helper
or shared constant such as a usePoolListStackStyle() hook, then use it from both
SelectPool and ChoosePool to keep the pool list container styling in sync.
In
`@packages/extension-polkagate/src/popup/staking/solo-new/nominations/NominationsSetting.tsx`:
- Around line 91-93: The side-panel table height calculation is duplicated with
the same magic numbers, so extract it into a shared helper/hook such as
useSidePanelTableHeight and use that from NominationsSetting and
SelectValidator. Keep the shared logic in one place using the
viewportHeight-based Math.max(...) formula so both components stay in sync and
the constants are defined only once.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: bd9bfc52-21cf-486e-b7fb-9f2d6c666feb
📒 Files selected for processing (54)
packages/extension-polkagate/src/components/ExtensionPopup.tsxpackages/extension-polkagate/src/fullscreen/components/GovernanceModal.tsxpackages/extension-polkagate/src/hooks/index.tspackages/extension-polkagate/src/hooks/useIsExtensionPopup.tspackages/extension-polkagate/src/hooks/useIsSidePanel.tspackages/extension-polkagate/src/hooks/useUiMode.tspackages/extension-polkagate/src/hooks/useViewportHeight.tspackages/extension-polkagate/src/partials/BiometricUnlockSetting.tsxpackages/extension-polkagate/src/partials/ConnectedAccounts.tsxpackages/extension-polkagate/src/partials/ConnectedDapp.tsxpackages/extension-polkagate/src/partials/RemoveAccount.tsxpackages/extension-polkagate/src/partials/RenameAccount.tsxpackages/extension-polkagate/src/partials/SelectLanguage.tsxpackages/extension-polkagate/src/partials/SidePanelModeButton.tsxpackages/extension-polkagate/src/partials/UserDashboardHeader.tsxpackages/extension-polkagate/src/partials/WebsitesAccess.tsxpackages/extension-polkagate/src/popup/accountsLists/BodySection.tsxpackages/extension-polkagate/src/popup/accountsLists/EditProfile.tsxpackages/extension-polkagate/src/popup/accountsLists/NewProfile.tsxpackages/extension-polkagate/src/popup/accountsLists/index.tsxpackages/extension-polkagate/src/popup/history/newDesign/HistoryBox.tsxpackages/extension-polkagate/src/popup/history/newDesign/HistoryDetail.tsxpackages/extension-polkagate/src/popup/history/newDesign/index.tsxpackages/extension-polkagate/src/popup/home/ChangeLog.tsxpackages/extension-polkagate/src/popup/home/index.tsxpackages/extension-polkagate/src/popup/home/partial/AssetsBox.tsxpackages/extension-polkagate/src/popup/home/partial/SelectCurrency.tsxpackages/extension-polkagate/src/popup/nft/index.tsxpackages/extension-polkagate/src/popup/notification/index.tsxpackages/extension-polkagate/src/popup/notification/partials/SelectChain.tsxpackages/extension-polkagate/src/popup/notification/partials/SelectNotificationAccountsBody.tsxpackages/extension-polkagate/src/popup/receive/Receive.tsxpackages/extension-polkagate/src/popup/settings/extensionSettings/Chains.tsxpackages/extension-polkagate/src/popup/settings/extensionSettings/Endpoints.tsxpackages/extension-polkagate/src/popup/settings/extensionSettings/index.tsxpackages/extension-polkagate/src/popup/settings/partials/ActionRow.tsxpackages/extension-polkagate/src/popup/settings/partials/actions/ThemeChange.tsxpackages/extension-polkagate/src/popup/staking/EarningOptions.tsxpackages/extension-polkagate/src/popup/staking/Reward.tsxpackages/extension-polkagate/src/popup/staking/StakingPositions.tsxpackages/extension-polkagate/src/popup/staking/easyStake/SelectPool.tsxpackages/extension-polkagate/src/popup/staking/easyStake/SelectValidator.tsxpackages/extension-polkagate/src/popup/staking/partial/PoolDetail.tsxpackages/extension-polkagate/src/popup/staking/partial/StakingInfoTile.tsxpackages/extension-polkagate/src/popup/staking/pool-new/joinPool/ChoosePool.tsxpackages/extension-polkagate/src/popup/staking/solo-new/nominations/NominationsSetting.tsxpackages/extension-polkagate/src/popup/staking/solo-new/settings/ChooseAccount.tsxpackages/extension-polkagate/src/popup/tokens/index.tsxpackages/extension-polkagate/src/popup/tokens/partial/TokenHistory.tsxpackages/extension/manifest.dev.jsonpackages/extension/manifest.jsonpackages/extension/manifest.prod.jsonpackages/extension/public/locales/en/translation.jsonpackages/extension/public/sidepanel.html
# [2.14.0](v2.13.0...v2.14.0) (2026-07-16) ### Features * add side panel view for the extension ([#2185](#2185)) ([1b32f33](1b32f33))
Summary by CodeRabbit
New Features
Bug Fixes