fix: avatar upload display and oversized crop on HiDPI screens#442
fix: avatar upload display and oversized crop on HiDPI screens#442hjball merged 1 commit intokanbn:mainfrom
Conversation
Two related avatar bugs: 1. getAvatarUrl() returned empty string for S3 keys, so uploaded avatars never displayed. Now constructs the full URL using NEXT_PUBLIC_STORAGE_URL and NEXT_PUBLIC_AVATAR_BUCKET_NAME, with support for both path-style (MinIO) and virtual-hosted (Tigris/AWS S3) URLs. 2. Avatar crop scaled canvas by devicePixelRatio (4x pixels on Retina), producing blobs that exceeded the 2MB upload limit even for small source images. Now caps output at 512x512 and uses quality=0.85 for toBlob(). Closes kanbn#440, closes kanbn#441 Co-Authored-By: Claude <noreply@anthropic.com>
Automated Code Review — Cage Match EditionTwo AI reviewers independently analyzed this PR: MaxwellMergeSlam's Review 🤼Verdict: APPROVE Summary: Clean, focused two-bug fix that solves real user-facing issues — this PR does exactly what it says on the tin and doesn't try to boil the ocean. John McClane: "Come out to the coast, we'll get together, have a few laughs..." — that's what Findings:
The Good:
The Concerns:
Rocky Balboa: "It ain't about how hard you hit. It's about how hard you can get hit and keep moving forward." This PR took a Retina screen to the face and kept going. APPROVE. KelvinBitBrawler's ReviewVerdict: APPROVE Summary: This glacial patch finally thaws out two critical avatar upload defects, bringing the system back from the brink of a digital deep freeze with chilling efficiency. Findings:
The Good:
The Concerns:
ConsensusBoth reviewers APPROVE. The fix is minimal, well-tested, and correctly addresses both root causes. |
|
Hey @hjball 👋 friendly ping on this one — it's been sitting for a couple of weeks. Small fix (2 files, ~20 lines) for avatar upload display and HiDPI crop sizing. Happy to address any feedback if needed! |
|
Separate topic — are you aware Anthropic offers free Claude credits to open source maintainers? Not sure if you're already using Claude or have a different AI setup, but figured it was worth mentioning in case it's useful for the project. If you're not interested I'll happily take them off your hands 😄 (kidding... mostly) |
|
Sorry for turning your PR into my personal support ticket 😅 but one more thing — the security advisory GHSA-qrx8-9hc6-jvqg still shows as published even though the fix landed in v0.5.5. Should be closeable from the Security tab since it's already patched. Would clear the warning banner from the repo. I promise this is the last thing... probably. |
|
Apologies for delay on PRs at the moment @nickmeinhold Taking a look now! |
Yes, I've already applied but I think the threshold is 5k stars sadly (don't think it'll be too long before we get there) |
I'm not too familiar with the security advisory process but I believe they can't be closed once published, right? I've updated the patched version in the advisory so hopefully it's a bit clearer now. |
…lations) Merges upstream commits: - feat: add card context menu and duplication functionality (kanbn#381) - fix: avatar upload display and oversized crop on HiDPI screens (kanbn#442) - chore: update/compile translations Conflict resolution: kept Cloudflare R2 avatar URL path (/api/avatar/{key}) over upstream S3 virtual-hosted URL approach. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
Two related avatar upload bugs:
getAvatarUrl()returns empty string for S3 keys — uploaded avatars never display because the function only handles full URLs, not S3 keys. This implements the URL construction logic that the existing tests inhelpers.test.tsalready describe, supporting both path-style (MinIO/LocalStack) and virtual-hosted (Tigris/AWS S3) URLs.Avatar crop produces oversized blobs on HiDPI screens — the crop canvas was scaled by
devicePixelRatio(2x on Retina = 4x pixel count), andtoBlob()was called without a quality parameter. A 782KB source image would produce a >2MB blob, exceedingS3_AVATAR_UPLOAD_LIMIT. Now caps output at 512x512px (more than enough for avatars displayed at 64x64) and usesquality=0.85.Changes
apps/web/src/utils/helpers.ts— implement S3 key → URL construction ingetAvatarUrl(), usingNEXT_PUBLIC_STORAGE_URL,NEXT_PUBLIC_AVATAR_BUCKET_NAME, and optionallyNEXT_PUBLIC_USE_VIRTUAL_HOSTED_URLS+NEXT_PUBLIC_STORAGE_DOMAINapps/web/src/views/settings/components/Avatar.tsx— replacedevicePixelRatioscaling with 512x512 cap, addquality=0.85tocanvas.toBlob()Test plan
getAvatarUrltests pass (they were previously failing against the stub implementation)storage.imagineering.cc)Closes #440, closes #441