Skip to content

fix(shadcn): UI improvements and favicon service refactoring - #3908

Merged
amitsingh-007 merged 12 commits into
mainfrom
f-shadcn-fixes-and-improvements
Feb 23, 2026
Merged

amitsingh-007 merged 12 commits into
mainfrom
f-shadcn-fixes-and-improvements

Conversation

@amitsingh-007

@amitsingh-007 amitsingh-007 commented Feb 22, 2026 •

Copy link
Copy Markdown
Owner

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 AuthProvider by removing the async initialization wrapper and directly calling onAuthStateChange. Consolidated test utilities into a shared test-helpers.ts file and improved test fixtures for better isolation.

Confidence Score: 4/5

  • This PR is mostly safe to merge with minor concerns around error handling and browser compatibility
  • The refactoring is well-structured with the favicon service properly threaded through components. However, there are existing issues from previous threads (error handling in sign-out flow, button state management) that remain unaddressed. The new CSS Color Level 5 syntax may have limited browser support. The core favicon refactoring is solid.
  • Pay attention to apps/web/src/app/web-ext/page.tsx for the error handling and button state issues mentioned in previous reviews, and packages/ui/src/styles/globals.css for browser compatibility of the rgba(from ...) syntax

Last reviewed commit: 5d348f9

- 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>
greptile-apps[bot]

This comment was marked as resolved.

gemini-code-assist[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@coderabbitai

coderabbitai Bot commented Feb 22, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Renames favicon helper from getFaviconProxyUrl to getGoogleFaviconUrl, adds getYandexFaviconUrl, and exposes favicon resolution via a new getFaviconUrl prop on Bookmark/Favicon/BookmarksList/Persons; updates call sites. Removes turbopack SVG rule and the @svgr/webpack devDependency. Moves global ::selection styling into packages/ui. Refactors AuthProvider to use onAuthStateChange with unsubscribe. Simplifies AppHeader markup and adjusts PageHeader button weight. Adds isSigningOut UI state on web-ext page. Introduces shared Playwright test helpers and refactors many tests, fixtures, and utilities.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The PR description is missing. The author provided only a Greptile AI summary with confidence score, but no actual pull request description following the required template. Add a proper pull request description that addresses the template requirement: explicitly state whether the extension requires a version change (checkbox). The provided Greptile comment is not a substitute for a human-authored PR description.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main changes: shadcn-related UI improvements and favicon service refactoring, accurately reflecting the primary objectives of this PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch f-shadcn-fixes-and-improvements

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot]

This comment was marked as resolved.

- 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>
greptile-apps[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
apps/extension/src/entrypoints/popup/panels/BookmarksPanel/components/BookmarkRow.tsx (1)

15-18: Consider wrapping onOpenLink in useCallback to preserve referential stability.

onOpenLink is recreated on every BookmarkRow render. Since Bookmark is also memo'd, each new reference defeats memoization and causes an unnecessary re-render of Bookmark. startHistoryMonitor from 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>
devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@amitsingh-007

Copy link
Copy Markdown
Owner Author

/gemini review

Memoize isRestrictedPath to only re-run effect when path restriction status changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
gemini-code-assist[bot]

This comment was marked as resolved.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
apps/web/src/app/provider/AuthProvider.tsx (1)

36-49: Previous auth-listener churn issue resolved — LGTM.

isRestrictedPath as the dep correctly scopes listener lifecycle to restricted ↔ non-restricted transitions, and return unsubscribe is now properly wired. The const (vs. useMemo) is fine here since RESTRICTED_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

📥 Commits

Reviewing files that changed from the base of the PR and between 2813db5 and 425d8d9.

📒 Files selected for processing (1)
  • apps/web/src/app/provider/AuthProvider.tsx

greptile-apps[bot]

This comment was marked as resolved.

amitsingh-007 and others added 5 commits February 23, 2026 12:24
- 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>
@amitsingh-007

Copy link
Copy Markdown
Owner Author

/gemini review

devin-ai-integration[bot]

This comment was marked as resolved.

gemini-code-assist[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

- 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>
greptile-apps[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

- 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>
greptile-apps[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@webext-bot

webext-bot Bot commented Feb 23, 2026

Copy link
Copy Markdown

Extension version is updated from 24.0.0 to 24.1.0

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

48 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment thread apps/web/src/app/provider/AuthProvider.tsx
@amitsingh-007
amitsingh-007 merged commit 2c9fcaa into main Feb 23, 2026
4 checks passed
@amitsingh-007
amitsingh-007 deleted the f-shadcn-fixes-and-improvements branch February 23, 2026 18:34
@amitsingh-007 amitsingh-007 linked an issue Feb 23, 2026 that may be closed by this pull request
@coderabbitai coderabbitai Bot mentioned this pull request Jul 11, 2026
1 task done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant