Repository navigation
fix(shadcn): UI improvements and favicon service refactoring - #3908
Conversation
- Refactor favicon service: rename getFaviconProxyUrl to getGoogleFaviconUrl and add getYandexFaviconUrl - Add custom text selection styling using primary theme color - Simplify AppHeader component by removing duplicate download button - Fix AuthProvider initialization to properly set user state on mount - Improve web-ext page button styling and add loading state for sign out - Minor layout.css and component styling improvements Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughRenames favicon helper from 🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
- Add proper cleanup for AuthProvider's auth state change unsubscribe - Fix BookmarkRow type exclusions and pass getFaviconUrl prop - Add getFaviconUrl prop to BookmarksList and pass through to Bookmark - Use Yandex favicon service for persons panel on web Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
apps/extension/src/entrypoints/popup/panels/BookmarksPanel/components/BookmarkRow.tsx (1)
15-18: Consider wrappingonOpenLinkinuseCallbackto preserve referential stability.
onOpenLinkis recreated on everyBookmarkRowrender. SinceBookmarkis alsomemo'd, each new reference defeats memoization and causes an unnecessary re-render ofBookmark.startHistoryMonitorfrom Zustand is a stable selector, so the dependency array is effectively static.♻️ Proposed refactor
-import { memo } from 'react'; +import { memo, useCallback } from 'react'; const BookmarkRow = memo<Omit<BookmarkProps, 'onOpenLink' | 'getFaviconUrl'>>( (props) => { const startHistoryMonitor = useHistoryStore( (state) => state.startHistoryMonitor ); - const onOpenLink = (url: string) => { + const onOpenLink = useCallback((url: string) => { startHistoryMonitor(); browser.tabs.create({ url, active: false }); - }; + }, [startHistoryMonitor]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/extension/src/entrypoints/popup/panels/BookmarksPanel/components/BookmarkRow.tsx` around lines 15 - 18, onOpenLink in BookmarkRow is recreated on every render which breaks memoization of the memo'd Bookmark component; wrap onOpenLink in React.useCallback to preserve referential stability (e.g., memoize the handler that calls startHistoryMonitor() and browser.tabs.create({...})) and list appropriate dependencies (startHistoryMonitor is a stable selector so the dependency array can be empty or include only truly dynamic values), ensuring the memo'd Bookmark benefits from a stable prop reference.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@packages/shared/src/components/Bookmarks/components/Favicon.tsx`:
- Around line 30-36: The async initFavicon inside the useEffect can throw
unhandled rejections because getFaviconUrl(url) uses new URL(...) and will throw
for empty/malformed URLs; wrap the logic in initFavicon with a try/catch,
validate that url is non-empty (or guard with a safe URL parse) before calling
getFaviconUrl and getBlobUrl, and on error catch and handle it (e.g., call
setFaviconUrl(null) and/or log the error) so the promise rejection is handled;
update the initFavicon function referenced in the useEffect (initFavicon,
getFaviconUrl, getBlobUrl, setFaviconUrl) accordingly.
---
Nitpick comments:
In
`@apps/extension/src/entrypoints/popup/panels/BookmarksPanel/components/BookmarkRow.tsx`:
- Around line 15-18: onOpenLink in BookmarkRow is recreated on every render
which breaks memoization of the memo'd Bookmark component; wrap onOpenLink in
React.useCallback to preserve referential stability (e.g., memoize the handler
that calls startHistoryMonitor() and browser.tabs.create({...})) and list
appropriate dependencies (startHistoryMonitor is a stable selector so the
dependency array can be empty or include only truly dynamic values), ensuring
the memo'd Bookmark benefits from a stable prop reference.
Remove dynamic import pattern and unnecessary isInitialized state for cleaner auth state management. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
/gemini review |
Memoize isRestrictedPath to only re-run effect when path restriction status changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
apps/web/src/app/provider/AuthProvider.tsx (1)
36-49: Previous auth-listener churn issue resolved — LGTM.
isRestrictedPathas the dep correctly scopes listener lifecycle to restricted ↔ non-restricted transitions, andreturn unsubscribeis now properly wired. Theconst(vs.useMemo) is fine here sinceRESTRICTED_PATHS.has(pathname)returns a primitive boolean that the deps array compares by value.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/app/provider/AuthProvider.tsx` around lines 36 - 49, No code change required: the useEffect correctly scopes the auth listener lifecycle using the boolean isRestrictedPath (computed from RESTRICTED_PATHS.has(pathname)), returns the unsubscribe function, and updates state via onAuthStateChange -> setUser and setIsInitialized; keep the current const isRestrictedPath and dependency [isRestrictedPath] so the listener is only created/removed on restricted ↔ non-restricted transitions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@apps/web/src/app/provider/AuthProvider.tsx`:
- Around line 36-49: No code change required: the useEffect correctly scopes the
auth listener lifecycle using the boolean isRestrictedPath (computed from
RESTRICTED_PATHS.has(pathname)), returns the unsubscribe function, and updates
state via onAuthStateChange -> setUser and setIsInitialized; keep the current
const isRestrictedPath and dependency [isRestrictedPath] so the listener is only
created/removed on restricted ↔ non-restricted transitions.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
📒 Files selected for processing (1)
apps/web/src/app/provider/AuthProvider.tsx
- Add test-helpers.ts to packages/shared with common utilities - Move closeDialog, fillSearchInput, clearSearchInput, parseBadgeCount to shared - Remove duplicate utility code from extension and web test files - Add @playwright/test as devDependency to packages/shared Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…h-variance E2E paths Replace hardcoded timeout delays with proper state-based waiting using waitForSelector and retry assertions. This improves test reliability and reduces flakiness by waiting for actual UI state rather than arbitrary time intervals. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add TEST_TIMEOUTS.AUTH to all waitFor and expect calls in auth setup files to ensure consistent timeout handling and improve test reliability. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace toTruthy() with more specific toBeTruthy() assertions - Add explicit timeout to auth setup - Import shared test utilities across test files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Simplify e2e tests
|
/gemini review |
- Add openExtensionPanelPage utility for cleaner panel navigation - Refactor fixtures to use new utility instead of authenticateAndNavigate - Remove .serial from test suites to enable parallel execution - Add unique test data (folder names, person names) for isolation - Add state reset/cleanup in shortcuts and history tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add explicit timeouts to poll assertions to prevent flaky tests - Improve page leak detection and cleanup in bookmarks tests - Add toBeEnabled() assertion for context menu items - Add toBeVisible() before text assertions to ensure stability - Refactor getNumericBadgeValue to simplify logic - Improve timeout values for history tracking tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Extension version is updated from |
Greptile Summary
Refactored favicon service to be configurable instead of hardcoded, allowing the extension to use Google's favicon API and the web app to use Yandex's API. Added UI improvements including updated button styling, text selection colors using CSS Color Level 5 syntax, and removed the Chrome extension download button from the header. Simplified the
AuthProviderby removing the async initialization wrapper and directly callingonAuthStateChange. Consolidated test utilities into a sharedtest-helpers.tsfile and improved test fixtures for better isolation.Confidence Score: 4/5
apps/web/src/app/web-ext/page.tsxfor the error handling and button state issues mentioned in previous reviews, andpackages/ui/src/styles/globals.cssfor browser compatibility of thergba(from ...)syntaxLast reviewed commit: 5d348f9