From 86ee13c00c2cbf78a35aa712090ae2be0d38ec12 Mon Sep 17 00:00:00 2001 From: dmkt9 Date: Fri, 15 Aug 2025 11:07:08 +0700 Subject: [PATCH 1/2] =?UTF-8?q?Fix=20-=20The=20avatar=20in=20the=20QR=20co?= =?UTF-8?q?de=20does=20not=20match=20the=20account=E2=80=99s=20set=20avata?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/UserUtils.ts | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/libs/UserUtils.ts b/src/libs/UserUtils.ts index 0c5b4c840210..cad9a8fb3b3e 100644 --- a/src/libs/UserUtils.ts +++ b/src/libs/UserUtils.ts @@ -111,17 +111,7 @@ function generateAccountID(searchValue: string): number { return hashText(searchValue, 2 ** 32); } -/** - * Helper method to return the default avatar associated with the given accountID - */ -function getDefaultAvatar(accountID = -1, avatarURL?: string): IconAsset | undefined { - if (accountID === CONST.ACCOUNT_ID.CONCIERGE) { - return ConciergeAvatar; - } - if (accountID === CONST.ACCOUNT_ID.NOTIFICATIONS) { - return NotificationsAvatar; - } - +function getAccountIDHashBucket(accountID = -1, avatarURL?: string) { // There are 24 possible default avatars, so we choose which one this user has based // on a simple modulo operation of their login number. Note that Avatar count starts at 1. @@ -135,7 +125,21 @@ function getDefaultAvatar(accountID = -1, avatarURL?: string): IconAsset | undef } else if (accountID > 0) { accountIDHashBucket = ((accountID % CONST.DEFAULT_AVATAR_COUNT) + 1) as AvatarRange; } + return accountIDHashBucket; +} + +/** + * Helper method to return the default avatar associated with the given accountID + */ +function getDefaultAvatar(accountID = -1, avatarURL?: string): IconAsset | undefined { + if (accountID === CONST.ACCOUNT_ID.CONCIERGE) { + return ConciergeAvatar; + } + if (accountID === CONST.ACCOUNT_ID.NOTIFICATIONS) { + return NotificationsAvatar; + } + const accountIDHashBucket = getAccountIDHashBucket(accountID, avatarURL); if (!accountIDHashBucket) { return; } @@ -146,13 +150,12 @@ function getDefaultAvatar(accountID = -1, avatarURL?: string): IconAsset | undef /** * Helper method to return default avatar URL associated with the accountID */ -function getDefaultAvatarURL(accountID: string | number = ''): string { +function getDefaultAvatarURL(accountID: string | number = '', avatarURL?: string): string { if (Number(accountID) === CONST.ACCOUNT_ID.CONCIERGE) { return CONST.CONCIERGE_ICON_URL; } - // Note that Avatar count starts at 1 which is why 1 has to be added to the result (or else 0 would result in a broken avatar link) - const accountIDHashBucket = (Number(accountID) % CONST.DEFAULT_AVATAR_COUNT) + 1; + const accountIDHashBucket = getAccountIDHashBucket(Number(accountID) || -1, avatarURL); const avatarPrefix = `default-avatar`; return `${CONST.CLOUDFRONT_URL}/images/avatars/${avatarPrefix}_${accountIDHashBucket}.png`; @@ -196,7 +199,7 @@ function getAvatar(avatarSource?: AvatarSource, accountID?: number): AvatarSourc * @param accountID - the accountID of the user */ function getAvatarUrl(avatarSource: AvatarSource | undefined, accountID: number): AvatarSource { - return isDefaultAvatar(avatarSource) ? getDefaultAvatarURL(accountID) : avatarSource; + return isDefaultAvatar(avatarSource) ? getDefaultAvatarURL(accountID, avatarSource) : avatarSource; } /** From 227ec590d363b61e45bafbacfdb35699a7e8dc36 Mon Sep 17 00:00:00 2001 From: dmkt9 Date: Mon, 18 Aug 2025 21:05:48 +0700 Subject: [PATCH 2/2] add unit tests --- tests/unit/UserUtilsTest.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/unit/UserUtilsTest.ts b/tests/unit/UserUtilsTest.ts index e5378c756751..193b1ebb8767 100644 --- a/tests/unit/UserUtilsTest.ts +++ b/tests/unit/UserUtilsTest.ts @@ -1,3 +1,4 @@ +import * as defaultAvatars from '@components/Icon/DefaultAvatars'; import * as UserUtils from '@src/libs/UserUtils'; describe('UserUtils', () => { @@ -6,6 +7,12 @@ describe('UserUtils', () => { const defaultAvatar = UserUtils.getAvatar(avatarURL, 1); expect(typeof defaultAvatar).toBe('function'); + + const defaultAvatarUrl = UserUtils.getAvatarUrl(avatarURL, 1); + + expect(defaultAvatarUrl).toBe('https://d2k5nsl2zxldvw.cloudfront.net/images/avatars/default-avatar_7.png'); + // Both defaultAvatar and defaultAvatarUrl must be `defaultAvatars.Avatar7` + expect(defaultAvatar === defaultAvatars.Avatar7).toBeTruthy(); }); it('should return the same url if url is not for default avatar', () => { @@ -13,5 +20,9 @@ describe('UserUtils', () => { const avatar = UserUtils.getAvatar(avatarURL, 1); expect(avatar).toEqual('https://test.com/images/some_avatar.png'); + + const avatarUrl = UserUtils.getAvatarUrl(avatarURL, 1); + + expect(avatarUrl).toEqual('https://test.com/images/some_avatar.png'); }); });