Files
Toju/toju-app/src/app/domains/profile-avatar
myxeliumandCursor 31962aeb1a fix: restore build and stabilize E2E cross-signal behavior
Revert the automated member-ordering pass that broke Angular field init
(TS2729) and disable that rule until a safe reorder strategy exists.
Fix modal/confirm dialog i18n defaults via template fallbacks, search all
active endpoints (including offline), register foreign rooms with actor
owner IDs, sync profile display names from avatar summaries, and guard
dm-chat when a private call converts to a group conversation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-11 12:16:40 +02:00
..
2026-04-17 03:06:44 +02:00

Profile Avatar Domain

Owns local profile picture workflow plus peer-synced profile-card metadata: source validation, crop/zoom editor state, static 256x256 WebP rendering, animated avatar preservation, desktop file persistence, and P2P avatar/profile sync metadata.

Responsibilities

  • Accept .webp, .gif, .jpg, .jpeg profile image sources.
  • Let user drag and zoom source inside fixed preview frame before saving.
  • Render static avatars to 256x256 WebP with client-side compression.
  • Preserve animated .gif and animated .webp uploads without flattening frames.
  • Persist desktop copy at user/<username>/profile/profile.<ext> under app data.
  • Let the local user edit their profile-card display name and description.
  • Expose helpers used by store effects to keep avatar metadata (avatarHash, avatarMime, avatarUpdatedAt) consistent.
  • Reuse the avatar summary/request/full handshake to sync profile text (displayName, description, profileUpdatedAt) alongside avatar state.

Module map

graph TD
    PC[ProfileCardComponent] --> PAE[ProfileAvatarEditorComponent]
    PAE --> PAF[ProfileAvatarFacade]
    PAF --> PAI[ProfileAvatarImageService]
    PAF --> PAS[ProfileAvatarStorageService]
    PAF --> Store[UsersActions.updateCurrentUserAvatar]
    Store --> UAV[UserAvatarEffects]
    UAV --> RTC[WebRTC data channel]
    UAV --> DB[DatabaseService]

    click PAE "feature/profile-avatar-editor/" "Crop and zoom editor UI" _blank
    click PAF "application/services/profile-avatar.facade.ts" "Facade used by UI and effects" _blank
    click PAI "infrastructure/services/profile-avatar-image.service.ts" "Canvas render and compression" _blank
    click PAS "infrastructure/services/profile-avatar-storage.service.ts" "Electron file persistence" _blank

Flow

  1. ProfileCardComponent opens file picker from editable avatar button.
  2. ProfileCardComponent saves display-name and description edits through the users store.
  3. ProfileAvatarEditorComponent previews exact crop using drag + zoom.
  4. ProfileAvatarImageService renders static uploads to 256x256 WebP, but keeps animated GIF and WebP sources intact.
  5. ProfileAvatarStorageService writes desktop copy when Electron is available.
  6. UserAvatarEffects broadcasts avatar/profile summaries, answers requests, streams chunks when needed, and persists received profile state locally.

Notes

  • Static uploads are normalized to WebP. Animated GIF and animated WebP uploads keep their original animation, mime type, and full-frame presentation.
  • avatarUrl stays local display data. Version conflict resolution uses avatarUpdatedAt and avatarHash.
  • Profile text uses its own profileUpdatedAt version so display-name and description changes can sync without replacing a newer avatar.