Conversation
WalkthroughAdds a survey popup feature to the app menu with state persistence. Introduces a new banners-state flag and API to control popup visibility, integrates timed display and close handling in the UI, adjusts a Solana banner metric event, and bumps the extension package version. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User
participant AM as AppMenu (index.vue)
participant BS as BannersState
participant SB as SolanaBanner
participant SP as SurveyPopup
participant BR as Browser (openLink)
rect rgb(241,248,255)
note over AM: onMounted
AM->>BS: showSolanaStakingBanner()
alt Solana banner visible
AM-->>SB: Render Solana banner
else Not visible
AM->>BS: showSurveyPopup()
BS-->>AM: boolean (can show?)
alt can show
AM->>AM: wait 4s
AM-->>SP: Render Survey popup
end
end
end
rect rgb(245,255,245)
note over SB: User clicks banner
U->>SB: Click
SB->>BR: openLink(staking URL)
end
rect rgb(255,246,240)
note over SP: User interacts
U->>SP: Click CTA
SP->>BR: openLink(survey URL)
SP-->>AM: emit close
AM->>BS: hideSurveyPopup()
end
rect rgb(255,246,240)
note over SP: User closes popup (X)
U->>SP: Close
SP-->>AM: emit close
AM->>BS: hideSurveyPopup()
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
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 |
|
💼 Build Files |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (4)
packages/extension/src/ui/action/components/app-menu/components/survey-popup.vue (1)
6-13: Use button elements for clickable UI (a11y, semantics).Replace
a href="javascript:void(0);"with<button>for both CTA and close controls.Apply:
- <a href="javascript:void(0);" @click="openSurveyLink" class="button" - ><span>Click here</span></a - > + <button type="button" @click="openSurveyLink" class="button"> + <span>Click here</span> + </button> - <a class="survey-popup__close" @click="close"> + <button type="button" class="survey-popup__close" @click="close" aria-label="Close survey popup"> <close-icon /> - </a> + </button>packages/extension/src/libs/banners-state/index.ts (1)
16-26: Backfill new state keys when reading old stored objects.Merge with defaults on read to persist newly added keys (avoids repeated “show” until first hide).
Apply:
- if (state) { - return state; - } - const newState: IState = { + const defaultState: IState = { isHideSolanStakingBanner: false, isHideNetworkAssetSolanStakingBanner: false, isHideSurveyPopup: false, }; - await this.storage.set(StorageKeys.bannersInfo, newState); - return newState; + if (state) { + const merged: IState = { ...defaultState, ...state }; + // Persist once if we added new keys + if ( + (state as Partial<IState>).isHideSurveyPopup === undefined || + Object.keys(state).length !== Object.keys(merged).length + ) { + await this.storage.set(StorageKeys.bannersInfo, merged); + } + return merged; + } + await this.storage.set(StorageKeys.bannersInfo, defaultState); + return defaultState;packages/extension/src/ui/action/components/app-menu/index.vue (2)
560-566: Debounce and cancel the survey timer to avoid duplicates and leaks.Multiple calls to
openSurveyPopup()can schedule multiple timers; also cancel on unmount.Apply:
-const openSurveyPopup = async () => { - if (await bannersState.showSurveyPopup()) { - setTimeout(() => { - isSurveyPopup.value = true; - }, 4000); - } -}; +const openSurveyPopup = async () => { + if (await bannersState.showSurveyPopup()) { + if (surveyTimeout.value) clearTimeout(surveyTimeout.value); + surveyTimeout.value = setTimeout(() => { + isSurveyPopup.value = true; + surveyTimeout.value = null; + }, 4000); + } +};Additions outside this hunk:
// imports import { PropType, ref, computed, onMounted, onBeforeUnmount } from 'vue'; // near other refs const surveyTimeout = ref<ReturnType<typeof setTimeout> | null>(null); // lifecycle onBeforeUnmount(() => { if (surveyTimeout.value) clearTimeout(surveyTimeout.value); });
568-572: Clear pending timer on close for consistency.const closeSurveyPopup = () => { isSurveyPopup.value = false; + if (surveyTimeout.value) { + clearTimeout(surveyTimeout.value); + surveyTimeout.value = null; + } bannersState.hideSurveyPopup(); };
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
packages/extension/package.json(1 hunks)packages/extension/src/libs/banners-state/index.ts(3 hunks)packages/extension/src/libs/banners-state/types.ts(1 hunks)packages/extension/src/ui/action/components/app-menu/components/solana-staking-banner.vue(1 hunks)packages/extension/src/ui/action/components/app-menu/components/survey-popup.vue(1 hunks)packages/extension/src/ui/action/components/app-menu/index.vue(4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: buildAll
🔇 Additional comments (6)
packages/extension/src/libs/banners-state/types.ts (1)
8-9: State shape extension — LGTM.New
isHideSurveyPopupkey is consistent with existing “hide” flags.packages/extension/src/ui/action/components/app-menu/components/solana-staking-banner.vue (1)
34-34: Metric event rename: confirm downstream dashboards.Switching to
NetworkListClickedlooks intentional; confirm it exists inSolanaStakingBannerEventsand is wired in analytics dashboards.packages/extension/src/libs/banners-state/index.ts (1)
58-67: Survey popup APIs — LGTM.API shape mirrors existing banner show/hide; no issues.
packages/extension/src/ui/action/components/app-menu/index.vue (2)
161-173: Transition + keyed branches — LGTM.Clean exclusivity between banners with proper keys for animations.
583-596: Slide-fade animation — LGTM.Durations feel reasonable; no jank risks spotted.
packages/extension/package.json (1)
3-3: Version bump only — LGTM. Verify extension manifest alignment.
packages/extension/package.json = 2.12.0; no manifest*.json found under packages/extension — if manifests are generated or located elsewhere, ensure they reflect 2.12.0.
Merge pull request #757 from enkryptcom/develop
Summary by CodeRabbit
New Features
Improvements
Chores