feat: add facehash avatars to desktop app#3835
feat: add facehash avatars to desktop app#3835devin-ai-integration[bot] wants to merge 4 commits intomainfrom
Conversation
Co-Authored-By: john@hyprnote.com <john@hyprnote.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
✅ Deploy Preview for hyprnote-storybook canceled.
|
✅ Deploy Preview for hyprnote canceled.
|
- getAvatarUrl returns null when no email (instead of SVG data URI) - Gravatar URL uses ?d=404 so it 404s for unknown emails - img onError handler switches to Facehash when Gravatar fails Co-Authored-By: john@hyprnote.com <john@hyprnote.com>
Co-Authored-By: john@hyprnote.com <john@hyprnote.com>
Co-Authored-By: john@hyprnote.com <john@hyprnote.com>
| }, | ||
| }); | ||
|
|
||
| const facehashName = useMemo( | ||
| () => auth?.session?.user.email || name || "user", | ||
| [auth?.session?.user.email, name], | ||
| ); | ||
|
|
||
| const showFacehash = !profile.data || imgError; |
There was a problem hiding this comment.
🟡 imgError state is never reset, permanently hiding Gravatar after any load failure
Once the Gravatar image fails to load (e.g., transient network error, or 404 from ?d=404), setImgError(true) is called at line 341, and imgError is never reset back to false. The showFacehash flag at line 307 (!profile.data || imgError) will then always be true, meaning the <img> element is never rendered again — so even if React Query refetches the profile URL (e.g., on window refocus), the Gravatar can never recover.
Root Cause and Impact
The imgError state at apps/desktop/src/components/main/sidebar/profile/index.tsx:292 is set to true on image load failure but has no mechanism to reset. Since showFacehash at line 307 short-circuits to true when imgError is set, the <img> tag is conditionally excluded from the DOM, preventing any future load attempt.
Scenario: A user has a valid Gravatar, but the image fails to load due to a transient network issue. After the network recovers, the Facehash avatar is permanently shown instead of the Gravatar for the lifetime of the component.
Fix: Reset imgError to false when profile.data changes, e.g., with a useEffect that watches profile.data.
(Refers to lines 292-307)
Was this helpful? React with 👍 or 👎 to provide feedback.
feat: add facehash avatars to replace initials in desktop app
Summary
Replaces the plain gray circles with text initials throughout the desktop app with facehash — a deterministic avatar generator that creates unique faces from any string. Same input always produces the same face.
What changed:
PersonItem) — 32px avatarsGravatar behavior: The user's own profile avatar still uses Gravatar (SHA-256 hash of email →
gravatar.com/avatar/{hash}?d=404). The?d=404parameter makes Gravatar return a 404 for emails without an account, which triggers theonErrorhandler on the<img>tag to show Facehash instead of Gravatar's default mystery person. When no email is available,getAvatarUrl()returnsnulland Facehash renders immediately.Note: During the profile query's loading state,
showFacehashwill betrue, so users with a valid Gravatar may see a brief flash of the Facehash face before their Gravatar image loads.Review & Testing Checklist for Human
tauri devwas not successfully run. Verify faces render correctly at 32px and 48px, clip properly in rounded containers, and don't cause layout shifts compared to the oldw-8 h-8/w-12 h-12divs.?d=404→onErrorpath works in Tauri's webview and Facehash actually renders (not a broken image icon).bg-linear-to-br from-indigo-400 to-purple-500) and border (border border-t border-neutral-400) were removed from the profile avatar container. Verify this still looks acceptable, especially when Facehash is showing.facehashis at v0.0.7 with 0 dependents on npm. Evaluate whether this is acceptable for production use.Recommended test plan:
ONBOARDING=0 pnpm -F desktop tauri dev)Notes
interactive={false}andshowInitial={false}props disable hover animations and the letter overlay, keeping avatars clean in list contextsgetInitialshelper is still exported fromshared.tsxfor any remaining usagesprofile.data!non-null assertion on the<img>src is guarded by theshowFacehashcheck above itLink to Devin run: https://app.devin.ai/sessions/f69fed2f923742c1a720419dffad67f9
Requested by: @ComputelessComputer