Skip to content

Add a generic user avatar system with in-app profile picture controls#3549

Draft
adboio wants to merge 4 commits into
mainfrom
posthog-code/bluebird-team-avatars
Draft

Add a generic user avatar system with in-app profile picture controls#3549
adboio wants to merge 4 commits into
mainfrom
posthog-code/bluebird-team-avatars

Conversation

@adboio

@adboio adboio commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Problem

Everywhere a person shows up in the Channels (project-bluebird) space — the channel feed's reply facepile, system rows, the thread panel, the activity page, the @-mention typeahead — they render as bare initials. The app had no user avatar system, and no way for a user to set a profile picture.

Why

Requested in the project-bluebird channel: get real profile pictures showing in the Bluebird UI. The app side is a generic avatar system with no internal-user-specific logic; the photo storage is a UserPersonalization side table in the backend (PostHog/posthog#72086), and populating PostHog staff photos is a backfill command stacked on it (PostHog/posthog#72092).

Changes

  • New UserAvatar component + useUserAvatar hook (packages/ui/src/features/avatars/): resolves a photo from (1) the user record's own avatar_url (present on the full /@me/ response), (2) the org members list — the backend exposes each member's personalization avatar_url there; the hook shares useOrgMembers' query key so this adds no extra fetch, (3) Gravatar keyed by account email (d=404) — PostHog cloud's own convention — and finally the existing initials treatment. Wired into the five Bluebird avatar slots (feed facepile + system rows, thread panel, activity page, mention typeahead).
  • "Profile picture" row in General settings (flag-gated): preview, set/change via an https image URL, and remove. Saves via PATCH /api/users/@me/ (updateCurrentUserAvatar), so the photo follows the user across clients and is visible to teammates.
  • OrganizationMemberBasic.avatar_url optional field in @posthog/shared/domain-types. Until the backend PRs deploy, Gravatar is the effective source and saving from settings will 400.

How did you test this?

  • Unit tests for Gravatar URL construction and the member-avatar index (packages/ui/src/features/avatars/useUserAvatar.test.ts).
  • vitest run src/features/avatars src/features/canvas src/features/settings in packages/ui (183 passed); src/canvas in packages/core (85 passed).
  • pnpm --filter typecheck for shared/core/ui/api-client, plus Biome on all touched files.
  • Not run: end-to-end save against a backend with the new table (depends on the posthog PRs deploying).

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

Created with PostHog Code

Resolve staff profile photos from posthog.com's public team roster and
render them in the Bluebird avatar slots (channel feed facepile, system
rows, thread panel, activity page, mention typeahead), falling back to
the existing initials treatment whenever no confident match exists.

Generated-By: PostHog Code
Task-Id: 66aecb98-c55b-4516-a7aa-42c53cfa8bd2
@trunk-io

trunk-io Bot commented Jul 17, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit c75d3c9.

@adboio adboio left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

posthog agent, if you’re reading this, this is bad

i meant more like a generic profile picture solution, with perhaps a script to import the team photos automatically for internal users

Drop all posthog.com-specific avatar fetching from the app. Avatars now
resolve generically: the account's own avatar_url when the backend
serves one (field added to UserBasic, awaiting backend support),
Gravatar by email otherwise — the same convention PostHog cloud's
ProfilePicture uses — with initials as the fallback. Internal users'
photos become a backend data backfill instead of client logic.

Generated-By: PostHog Code
Task-Id: 66aecb98-c55b-4516-a7aa-42c53cfa8bd2
@adboio adboio changed the title Show posthog.com/people profile photos on Bluebird channel avatars Add a generic user avatar system to the Bluebird UI Jul 17, 2026
New "Profile picture" row in General settings (flag-gated): preview via
UserAvatar, set/change with an https image URL, and remove. Saves to
the PostHog account through PATCH /api/users/@me/ {avatar_url} (new
updateCurrentUserAvatar client method; backend field lands in
PostHog/posthog#72086). UserAvatar/useUserAvatar props widen to a
structural AvatarUser so the full user object works too.

Generated-By: PostHog Code
Task-Id: 66aecb98-c55b-4516-a7aa-42c53cfa8bd2
@adboio adboio changed the title Add a generic user avatar system to the Bluebird UI Add a generic user avatar system with in-app profile picture controls Jul 17, 2026
The backend now stores profile photos on a UserPersonalization side
table exposed via the org members list (and the full /@me/ user), not
on UserBasic. useUserAvatar gains a members-index source (shared query
key with useOrgMembers, so no extra fetch) between the user's own
record and the Gravatar fallback.

Generated-By: PostHog Code
Task-Id: 66aecb98-c55b-4516-a7aa-42c53cfa8bd2
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.

1 participant