feat: avatars for humans #273
Reference in New Issue
Block a user
Delete Branch "worktree-refactored-strolling-treasure"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #70
Summary by CodeRabbit
No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID:
73480fa0-39ce-4438-aeef-71baef5ae49d📥 Commits
Reviewing files that changed from the base of the PR and between
6f8349c62fand6ce7cc8651.📒 Files selected for processing (3)
go/internal/handler/handler.gogo/migrations/000017_human_avatar.down.sqljs/desktop/src/features/particles/stream-card.tsx💤 Files with no reviewable changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 Walkthrough
Walkthrough
Implements user-controlled profile avatars: DB migration and model field, repository/service update/delete support, HTTP handlers and routes, desktop API client methods, avatar utilities/hooks/components, settings edit dialog with upload/camera, and avatar rendering across particle and network UIs.
Changes
Avatar Management Feature
go/migrations/000017_human_avatar.up.sql,go/migrations/000017_human_avatar.down.sql,go/internal/human/models.goavatar_object_idcolumn and maps it into the GoHumanmodel asAvatarObjectID.go/internal/human/repository.go,go/internal/human/service.go,go/internal/human/service_test.goavatar_object_id, addsupdateAvatarObjectID; service exposesUpdateAvatar/DeleteAvatar, validates parameters and maps repo errors; tests cover avatar lifecycle.go/internal/handler/handler.go,go/cmd/orion/main.goUpdateAvatarandDeleteAvatarhandlers (5MB request limit, depot uploads, best-effort depot cleanup), maps avatar field into DTO, renamesDownloadParticleMedia→GetObjectDownloadUrl, and wires settings/particles routes.js/desktop/src/api/client.ts,js/desktop/src/api/types.tssendhelper, JSON fetch delegation, and client methodsupdateAvatar,deleteAvatar,getAvatarDownloadUrl;HumanSchemaadds optionalavatar_object_id.js/desktop/src/hooks/use-avatar-url.ts,js/desktop/src/lib/avatar-image.ts,js/desktop/src/lib/humans.ts,js/desktop/src/hooks/use-presence-positions.ts,js/desktop/src/stores/auth-store.tsuseAvatarUrl(React Query) to fetch signed URLs,toAvatarBlobto center-crop and encode images, surfacesavatarObjectIdin human display/presence shapes, and addsrefreshUserto auth store.js/desktop/src/components/human-avatar.tsxuseAvatarUrland rendersAvatarImageorAvatarFallback(initials) as fallback.js/desktop/src/features/settings/avatar-edit-dialog.tsxtoAvatarBlob, API calls for save/remove, preview lifecycle, and CameraCapture subcomponent.js/desktop/src/features/settings-page.tsxHumanAvatarwith camera overlay and opens AvatarEditDialog for editing.js/desktop/src/features/particles/*,js/desktop/src/features/network-settings.tsxHumanAvataracross particle list, cards, reaction bar, presence indicators, members overlay, top bar, and network settings; memoized avatar resolution now includesavatarObjectId.Sequence Diagram(s)
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~45 minutes
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
#70: user-controlled avatar creation via photo snapping or uploading, persistent user-controlled avatars to ensure recognition and consent, and avoids arbitrary video frame usage.✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing Touches
📝 Generate docstrings
🧪 Generate unit tests (beta)
worktree-refactored-strolling-treasureComment
@coderabbitai helpto get the list of available commands and usage tips.Actionable comments posted: 5
🧹 Nitpick comments (1)
🤖 Prompt for all review comments with AI agents
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID:
f1b2fa73-7efe-4b67-abc5-45c5f2ee1d57📥 Commits
Reviewing files that changed from the base of the PR and between
ca3bbf204eandfa9d54aab5.📒 Files selected for processing (25)
go/cmd/orion/main.gogo/internal/handler/handler.gogo/internal/human/models.gogo/internal/human/repository.gogo/internal/human/service.gogo/internal/human/service_test.gogo/migrations/000017_human_avatar.down.sqlgo/migrations/000017_human_avatar.up.sqljs/desktop/src/api/client.tsjs/desktop/src/api/types.tsjs/desktop/src/components/human-avatar.tsxjs/desktop/src/features/network-settings.tsxjs/desktop/src/features/particles/particle-list-view.tsxjs/desktop/src/features/particles/playback-page-indicator.tsxjs/desktop/src/features/particles/reaction-bar.tsxjs/desktop/src/features/particles/stream-card.tsxjs/desktop/src/features/particles/stream-members-overlay.tsxjs/desktop/src/features/particles/stream-top-bar.tsxjs/desktop/src/features/settings-page.tsxjs/desktop/src/features/settings/avatar-edit-dialog.tsxjs/desktop/src/hooks/use-avatar-url.tsjs/desktop/src/hooks/use-presence-positions.tsjs/desktop/src/lib/avatar-image.tsjs/desktop/src/lib/humans.tsjs/desktop/src/stores/auth-store.ts@@ -334,6 +335,83 @@ func (h *Handler) UpdateSettings(w http.ResponseWriter, r *http.Request) {w.WriteHeader(http.StatusNoContent)⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift
Avatar blob lifecycle is inconsistent and leaks objects.
Line 345 clears
avatar_object_idbefore reading prior state, so the old avatar object ID is lost and never deleted.Also, if Line 383 upload succeeds but Line 394 DB update fails, the newly uploaded object is orphaned.
Suggested lifecycle shape
Also applies to: 383-399
🤖 Prompt for AI Agents
@@ -337,0 +400,4 @@flog.Error("failed to update human avatar", "error", err, "humanId", humanId)http.Error(w, "internal server error", http.StatusInternalServerError)// best effort⚠️ Potential issue | 🟡 Minor | ⚡ Quick win
Return 413 for oversized avatar uploads instead of 500.
When
http.MaxBytesReaderlimit is exceeded, the handler currently falls into a generic 500. This should map tohttp.StatusRequestEntityTooLarge.Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents
✅ Addressed in commits
ffac812to6bf2c99@@ -0,0 +1,6 @@BEGIN;⚠️ Potential issue | 🔴 Critical | ⚡ Quick win
Fix invalid SQL in rollback migration.
Line 4 has a trailing comma, which makes the down migration fail to execute.
Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents
✅ Addressed in commits
a45beb9toa25fb83⚠️ Potential issue | 🟡 Minor | ⚡ Quick win
Encode
objectIdbefore building the avatar URL path.Line 161 interpolates
objectIddirectly. Reserved characters can produce a malformed route and wrong request target.Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents
@@ -0,0 +9,4 @@export async function toAvatarBlob(source: ImageBitmap,{ size = 512, mirror = false }: { size?: number; mirror?: boolean } = {},): Promise<Blob> {⚠️ Potential issue | 🟡 Minor | ⚡ Quick win
Validate
sizeas a positive integer before creating the canvas.Line 22 depends on
size; invalid values can yield broken avatar output or throw at runtime.Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents
✅ Addressed in commits
ffac812to6bf2c99Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID:
5eee9ab3-504d-4409-8a31-6fdeca6719b6📥 Commits
Reviewing files that changed from the base of the PR and between
fa9d54aab5and6bf2c9983a.📒 Files selected for processing (2)
go/internal/handler/handler.gojs/desktop/src/lib/avatar-image.ts🚧 Files skipped from review as they are similar to previous changes (1)
@@ -334,6 +335,83 @@ func (h *Handler) UpdateSettings(w http.ResponseWriter, r *http.Request) {w.WriteHeader(http.StatusNoContent)⚠️ Potential issue | 🔴 Critical | ⚡ Quick win
Remove the unmatched
}inUpdateAvatar.Line 398 closes the function early, so Line 400 starts with a bare assignment and the file no longer parses. That matches the CI failure exactly.
Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents
Source: Pipeline failures