Skip to content

Conversation

@MaheshtheDev
Copy link
Member

@MaheshtheDev MaheshtheDev commented Oct 3, 2025

ui: update the chrome extension visibilty

fix the ui for the chrome extension icon

remove bun lock

image.png

image.png

Copy link
Member Author


How to use the Graphite Merge Queue

Add the label Main to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@cloudflare-workers-and-pages
Copy link

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
🔵 In progress
View logs
supermemory-app 353a6fb Oct 03 2025, 12:34 AM

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Oct 3, 2025

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
supermemory-app 050b241 Oct 03 2025, 08:02 AM

@MaheshtheDev MaheshtheDev marked this pull request as ready for review October 3, 2025 00:35
@graphite-app graphite-app bot requested a review from Dhravya October 3, 2025 00:35
@graphite-app
Copy link

graphite-app bot commented Oct 3, 2025

Merge activity

@graphite-app
Copy link

graphite-app bot commented Oct 3, 2025

Sesame Street gif. Ernie looks at us, smiling widely and giving a big thumbs up. (Added via Giphy)

@graphite-app graphite-app bot force-pushed the 10-01-ui_update_the_chrome_extension_visibilty branch from 353a6fb to 050b241 Compare October 3, 2025 07:55
@graphite-app graphite-app bot merged commit 050b241 into main Oct 3, 2025
3 of 4 checks passed
@claude
Copy link

claude bot commented Oct 3, 2025

PR Review: Chrome Extension Visibility Update

Thanks for working on improving the Chrome extension visibility! Here's my review:

✅ Positive Aspects

  1. Good UX patterns: The progressive disclosure (minimization after 3s) and localStorage persistence are user-friendly
  2. Analytics integration: Properly tracking extension install clicks via PostHog
  3. Visual polish: Nice use of animations and gradient backgrounds
  4. Consistent patterns: Follows similar pattern to InstallPrompt component

🐛 Potential Issues

1. Import Inconsistency (Critical)

Location: apps/web/components/chrome-extension-button.tsx:62

import { motion } from "framer-motion"

But InstallPrompt.tsx uses:

import { motion } from "motion/react"

The package.json shows both framer-motion (v12.23.12) and motion (v12.19.2) are installed. You should standardize on one import style across the codebase for consistency.

Recommendation: Use motion/react to match the existing InstallPrompt component.


2. Race Condition in Extension Detection

Location: apps/web/components/chrome-extension-button.tsx:31-58

The current implementation has potential timing issues:

  • 1-second timeout for extension detection is arbitrary
  • No cleanup of message listener if component unmounts during detection
  • The handleMessage function is created inside useEffect but could be called after unmount

Recommendation:

useEffect(() => {
  let mounted = true;
  
  const checkExtension = () => {
    // ... existing code ...
    
    const handleMessage = (event: MessageEvent) => {
      if (mounted && event.data?.action === "extension-detected") {
        clearTimeout(timeout)
        setIsExtensionInstalled(true)
        setIsChecking(false)
        window.removeEventListener("message", handleMessage)
      }
    }
    // ... rest of code
  }
  
  checkExtension()
  
  return () => {
    mounted = false
    // ... existing cleanup
  }
}, [])

3. Auto-Minimize Logic Issue

Location: apps/web/components/chrome-extension-button.tsx:35-39

The auto-minimize logic is nested inside the timeout callback, which means it only triggers when the extension is NOT installed. However, the logic seems correct for the use case. Just worth noting that if a user dismisses quickly, the minimize timer still runs.

Recommendation: Clear the minimize timeout on dismiss:

const [minimizeTimeout, setMinimizeTimeout] = useState<NodeJS.Timeout | null>(null)

// In timeout callback
const timeout = setTimeout(() => {
  // ... existing code ...
  if (!dismissed) {
    const minTimeout = setTimeout(() => setIsMinimized(true), 3000)
    setMinimizeTimeout(minTimeout)
  }
}, 1000)

// In handleDismiss
const handleDismiss = () => {
  if (minimizeTimeout) clearTimeout(minimizeTimeout)
  localStorage.setItem("chrome-extension-dismissed", "true")
  setIsDismissed(true)
}

4. Missing Image Optimization

Location: apps/web/components/chrome-extension-button.tsx:178-183

Using Image from next/image but the binary images (extension-bg.png, extension-logo.png) aren't shown in the diff (marked as additions:0, deletions:0).

Concerns:

  • No dimensions specified for extension-logo.png - could cause layout shift
  • Background images should use Next.js static imports for optimization
  • Consider if these images are optimized for web (compressed, correct format)

Recommendation:

import extensionLogo from "@/public/images/extension-logo.png"
import extensionBg from "@/public/images/extension-bg.png"

// Then use:
<Image
  src={extensionLogo}
  alt="Extension Logo"
  width={24}
  height={24}
/>

// For background:
style={{
  backgroundImage: `url(${extensionBg.src})`,
  // ... rest
}}

5. Accessibility Issues

Location: Multiple locations in component

  • Close button (CircleX) has no aria-label
  • No role or ARIA attributes for the popup
  • The minimized button hover effect with opacity change isn't keyboard-accessible

Recommendation:

<Button
  variant="ghost"
  size="sm"
  onClick={handleDismiss}
  aria-label="Dismiss extension prompt"
  className="..."
>
  <CircleX className="w-4 h-4" />
</Button>

<motion.div
  role="dialog"
  aria-label="Chrome extension installation prompt"
  className="fixed bottom-4 right-4 z-50"
  // ...
>

6. Header Icons Without Context

Location: apps/web/components/header.tsx:103-196

Adding icons to dropdown menu items is great, but importing several icons that aren't used elsewhere in the file:

import { User, CreditCard, Chrome, LogOut } from "lucide-react"

These are only used for the dropdown menu. Consider if this adds unnecessary bundle size. However, with tree-shaking this is likely fine.


🎨 Style & Best Practices

  1. Magic strings: Extension URL is hardcoded in multiple places (lines 70, 116). Consider extracting to a constant:
const EXTENSION_URL = "https://chromewebstore.google.com/detail/supermemory/afpgkkipfdpeaflnpoaffkcankadgjfc"
  1. Inline styles: The backgroundImage style is repeated. Consider using a CSS class or extracting to a styled component.

  2. Type safety: event.data?.action should have proper typing. Consider creating an interface:

interface ExtensionMessage {
  action: 'check-extension' | 'extension-detected'
}

🧪 Testing Concerns

Missing test coverage for:

  • Extension detection logic
  • LocalStorage persistence
  • Auto-minimize behavior
  • Message event handling
  • Analytics tracking

🔒 Security

Low risk, but worth noting:

  • window.postMessage(message, "*") uses wildcard origin - this is fine for feature detection but be cautious with sensitive data
  • Consider checking event.origin in message handler for production environments

⚡ Performance

  1. Animation performance: Using framer-motion for a component that renders on every page load. Consider:

    • Lazy loading this component
    • Using CSS animations instead for simpler transitions
  2. LocalStorage access: Synchronous localStorage reads in useEffect on every mount. Consider:

const [isDismissed, setIsDismissed] = useState(() => 
  typeof window !== 'undefined' 
    ? localStorage.getItem("chrome-extension-dismissed") === "true"
    : false
)

📝 Summary

Overall: Good implementation with nice UX touches! The main issues are:

  1. Must fix: Import inconsistency (framer-motion vs motion/react)
  2. Should fix: Race condition cleanup, accessibility, image optimization
  3. Nice to have: Extract constants, improve type safety, add tests

The functionality looks solid, but addressing the race condition and accessibility issues would make this production-ready.

Recommendation: Request changes for items #1, #2, #4, and #5 before merging.

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.

3 participants