Skip to content

[Due for payment 2025-10-30] [Avatar Customization] Integrate Initial Avatars into list of Custom Avatar Options #71890

@grgia

Description

@grgia

Main Issue

Goal

User can upload either a custom avatar or an initial avatar from the new page. This wraps up the project.

Uses InitialAvatars.ts from #71815

Image

Detailed Background

Existing Pattern for Coloring Workspace SVGs:

Color Options for Initials:

const workspaceColorOptions: SVGAvatarColorStyle[] = [
{backgroundColor: colors.blue200, fill: colors.blue700},
{backgroundColor: colors.blue400, fill: colors.blue800},
{backgroundColor: colors.blue700, fill: colors.blue200},
{backgroundColor: colors.green200, fill: colors.green700},
{backgroundColor: colors.green400, fill: colors.green800},
{backgroundColor: colors.green700, fill: colors.green200},
{backgroundColor: colors.yellow200, fill: colors.yellow700},
{backgroundColor: colors.yellow400, fill: colors.yellow800},
{backgroundColor: colors.yellow700, fill: colors.yellow200},
{backgroundColor: colors.tangerine200, fill: colors.tangerine700},
{backgroundColor: colors.tangerine400, fill: colors.tangerine800},
{backgroundColor: colors.tangerine700, fill: colors.tangerine400},
{backgroundColor: colors.pink200, fill: colors.pink700},
{backgroundColor: colors.pink400, fill: colors.pink800},
{backgroundColor: colors.pink700, fill: colors.pink200},
{backgroundColor: colors.ice200, fill: colors.ice700},
{backgroundColor: colors.ice400, fill: colors.ice800},
{backgroundColor: colors.ice700, fill: colors.ice200},
];

How we color workspace SVGs:

/**
* Helper method to return workspace avatar color styles
*/
function getDefaultWorkspaceAvatarColor(text: string): ViewStyle {
const colorHash = hashText(text.trim(), workspaceColorOptions.length);
return workspaceColorOptions.at(colorHash) ?? {backgroundColor: colors.blue200, fill: colors.blue700};
}

How we fetch workspace SVG

App/src/libs/ReportUtils.ts

Lines 2787 to 2805 in 4f2680e

/**
* Helper method to return the default avatar associated with the given login
*/
function getDefaultWorkspaceAvatar(workspaceName?: string): React.FC<SvgProps> {
if (!workspaceName) {
return defaultWorkspaceAvatars.WorkspaceBuilding;
}
// Remove all chars not A-Z or 0-9 including underscore
const alphaNumeric = workspaceName
.normalize('NFD')
.replace(/[^0-9a-z]/gi, '')
.toUpperCase();
const workspace = `Workspace${alphaNumeric[0]}` as keyof typeof defaultWorkspaceAvatars;
const defaultWorkspaceAvatar = defaultWorkspaceAvatars[workspace];
return !alphaNumeric ? defaultWorkspaceAvatars.WorkspaceBuilding : defaultWorkspaceAvatar;
}

Creating / Uploading an image file

@jmusial Note: we can diverge from this plan if there is a simpler or cleaner solution found:

Option 1
- Create: /src/pages/settings/Profile/Avatar/AvatarGenerator.tsx - dedicated component to render the selected avatar for capturing
- Render the selected SVG: use existingAvatar component/react-native-svg- Pass the user's selected color as a fill prop to the SVG component.
- Capture the view: use exisiting react-native-view-shot - Wrap in <ViewShot> component and capture View as a 400x400 png.
- Generate the image: Expose a capture function via ref that returns the image file URI.
- Upload the image: Use the existing UpdateUserAvatar action. Convert the image URI from the generator into a file object, similar to how it's done in ProfilePage.js for photo library uploads.

Option 2
Instead of generating an image from FE, we call a modified API endpoint (or a new one) and send the identifier for the SVG shape and the selected color value. For example: UpdateUserAvatar({avatar: 'F', color: '#B5853D', fill: '#FFFFF'}) or UpdateUserAvatar({avatar-slug: 'E', color-slug: 'djojd'}) (colors E with some BE allowed color combo under some color ID )

Metadata

Metadata

Labels

Awaiting PaymentAuto-added when associated PR is deployed to productionWeeklyKSv2

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions