Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: User default avatar preview not respecting Use Full Name Initials settings #34187

Merged
merged 10 commits into from
Dec 20, 2024
5 changes: 5 additions & 0 deletions .changeset/five-peaches-approve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

Adds support for `Use Full Name Initials to Generate Default Avatar` setting for the generated avatar preview button when editing an User's avatar
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ type UserAvatarEditorProps = {
setAvatarObj: (obj: AvatarObject) => void;
disabled?: boolean;
etag: IUser['avatarETag'];
name: IUser['name'];
};

function UserAvatarEditor({ currentUsername, username, setAvatarObj, disabled, etag }: UserAvatarEditorProps): ReactElement {
function UserAvatarEditor({ currentUsername, username, setAvatarObj, name, disabled, etag }: UserAvatarEditorProps): ReactElement {
const { t } = useTranslation();
const useFullNameForDefaultAvatar = useSetting('UI_Use_Name_Avatar');
const rotateImages = useSetting('FileUpload_RotateImages');
const [avatarFromUrl, setAvatarFromUrl] = useState('');
const [newAvatarSource, setNewAvatarSource] = useState<string>();
Expand Down Expand Up @@ -53,7 +55,7 @@ function UserAvatarEditor({ currentUsername, username, setAvatarObj, disabled, e
};

const clickReset = (): void => {
setNewAvatarSource(`/avatar/%40${username}`);
setNewAvatarSource(`/avatar/%40${useFullNameForDefaultAvatar ? name : username}`);
setAvatarObj('reset');
};

Expand Down Expand Up @@ -91,7 +93,7 @@ function UserAvatarEditor({ currentUsername, username, setAvatarObj, disabled, e
<Box display='flex' flexDirection='column' flexGrow='1' justifyContent='space-between' mis={4}>
<Box display='flex' flexDirection='row' mbs='none'>
<Button square disabled={disabled} mi={4} title={t('Accounts_SetDefaultAvatar')} onClick={clickReset}>
<Avatar url={`/avatar/%40${username}`} />
<Avatar url={`/avatar/%40${useFullNameForDefaultAvatar ? name : username}`} />
</Button>
<IconButton icon='upload' secondary disabled={disabled} title={t('Upload')} mi={4} onClick={clickUpload} />
<IconButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const AccountProfileForm = (props: AllHTMLAttributes<HTMLFormElement>): ReactEle
formState: { errors },
} = useFormContext<AccountProfileFormValues>();

const { email, avatar, username } = watch();
const { email, avatar, username, name: userFullName } = watch();

const previousEmail = user ? getUserEmailAddress(user) : '';
const previousUsername = user?.username || '';
Expand Down Expand Up @@ -150,6 +150,7 @@ const AccountProfileForm = (props: AllHTMLAttributes<HTMLFormElement>): ReactEle
<UserAvatarEditor
etag={user?.avatarETag}
currentUsername={user?.username}
name={userFullName}
username={username}
setAvatarObj={onChange}
disabled={!allowUserAvatarChange}
Expand Down
3 changes: 2 additions & 1 deletion apps/meteor/client/views/admin/users/AdminUserForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ const AdminUserForm = ({ userData, onReload, context, refetchUserFormData, roleD
mode: 'onBlur',
});

const { avatar, username, setRandomPassword, password } = watch();
const { avatar, username, setRandomPassword, password, name: userFullName } = watch();

const eventStats = useEndpointAction('POST', '/v1/statistics.telemetry');
const updateUserAction = useEndpoint('POST', '/v1/users.update');
Expand Down Expand Up @@ -208,6 +208,7 @@ const AdminUserForm = ({ userData, onReload, context, refetchUserFormData, roleD
username={username}
etag={userData?.avatarETag}
setAvatarObj={onChange}
name={userFullName}
/>
)}
/>
Expand Down
39 changes: 34 additions & 5 deletions apps/meteor/server/routes/avatar/user.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,13 +236,42 @@ describe('#userAvatarByUsername()', () => {
expect(pipe.calledWith(response)).to.be.true;
});

it(`should serve svg if requestUsername starts with @`, async () => {
const request = { url: '/@jon' };
describe('should serve svg if requestUsername starts with @', () => {
it('should serve SVG and useAllInitials should be false', async () => {
const request = { url: '/@jon' };

mocks.settingsGet.returns(false);

await userAvatarByUsername(request, response, next);

expect(mocks.utils.setCacheAndDispositionHeaders.calledWith(request, response)).to.be.true;
expect(
mocks.utils.serveSvgAvatarInRequestedFormat.calledWith({
nameOrUsername: 'jon',
req: request,
res: response,
useAllInitials: false,
}),
).to.be.true;
});

await userAvatarByUsername(request, response, next);
it('should serve SVG and useAllInitials should be true', async () => {
const request = { url: '/@baba yaga' };

expect(mocks.utils.setCacheAndDispositionHeaders.calledWith(request, response)).to.be.true;
expect(mocks.utils.serveSvgAvatarInRequestedFormat.calledWith({ nameOrUsername: 'jon', req: request, res: response })).to.be.true;
mocks.settingsGet.withArgs('UI_Use_Name_Avatar').returns(true);

await userAvatarByUsername(request, response, next);

expect(mocks.utils.setCacheAndDispositionHeaders.calledWith(request, response)).to.be.true;
expect(
mocks.utils.serveSvgAvatarInRequestedFormat.calledWith({
nameOrUsername: 'baba yaga',
req: request,
res: response,
useAllInitials: true,
}),
).to.be.true;
});
});

it(`should serve avatar file if found`, async () => {
Expand Down
7 changes: 6 additions & 1 deletion apps/meteor/server/routes/avatar/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ export const userAvatarByUsername = async function (request: IncomingMessage, re

// if request starts with @ always return the svg letters
if (requestUsername[0] === '@') {
serveSvgAvatarInRequestedFormat({ nameOrUsername: requestUsername.slice(1), req, res });
serveSvgAvatarInRequestedFormat({
nameOrUsername: requestUsername.slice(1),
req,
res,
useAllInitials: settings.get('UI_Use_Name_Avatar'),
});
return;
}

Expand Down
Loading