Fix dropped avatar on PNP settings update

This commit is contained in:
Fedor Indutny 2024-02-05 18:29:45 -08:00 committed by GitHub
parent eb82ace2de
commit 330202960c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 42 additions and 23 deletions

View file

@ -11,9 +11,7 @@ import { explodePromise } from '../util/explodePromise';
import { BackOff, FIBONACCI_TIMEOUTS } from '../util/BackOff'; import { BackOff, FIBONACCI_TIMEOUTS } from '../util/BackOff';
import { checkForUsername } from '../util/lookupConversationWithoutServiceId'; import { checkForUsername } from '../util/lookupConversationWithoutServiceId';
import { storageJobQueue } from '../util/JobQueue'; import { storageJobQueue } from '../util/JobQueue';
import { getAbsoluteProfileAvatarPath } from '../util/avatarUtils';
import { getProfile } from '../util/getProfile'; import { getProfile } from '../util/getProfile';
import { imagePathToBytes } from '../util/imagePathToBytes';
import { isSharingPhoneNumberWithEverybody } from '../util/phoneNumberSharingMode'; import { isSharingPhoneNumberWithEverybody } from '../util/phoneNumberSharingMode';
import * as log from '../logging/log'; import * as log from '../logging/log';
import { resolveUsernameByLink } from './username'; import { resolveUsernameByLink } from './username';
@ -169,21 +167,8 @@ class UsernameIntegrityService {
'updating profile' 'updating profile'
); );
const profileAvatarPath = getAbsoluteProfileAvatarPath(me.attributes);
let avatarBuffer: Uint8Array | undefined;
if (profileAvatarPath) {
try {
avatarBuffer = await imagePathToBytes(profileAvatarPath);
} catch (error) {
log.error('usernameIntegrity: local avatar not found, aborting');
return;
}
}
await writeProfile(getConversation(me), { await writeProfile(getConversation(me), {
oldAvatar: avatarBuffer, keepAvatar: true,
newAvatar: avatarBuffer,
}); });
log.warn('usernameIntegrity: updated profile'); log.warn('usernameIntegrity: updated profile');

View file

@ -11,12 +11,24 @@ import { getProfile } from '../util/getProfile';
import { singleProtoJobQueue } from '../jobs/singleProtoJobQueue'; import { singleProtoJobQueue } from '../jobs/singleProtoJobQueue';
import { strictAssert } from '../util/assert'; import { strictAssert } from '../util/assert';
import { isWhitespace } from '../util/whitespaceStringUtil'; import { isWhitespace } from '../util/whitespaceStringUtil';
import { imagePathToBytes } from '../util/imagePathToBytes';
import { getAbsoluteProfileAvatarPath } from '../util/avatarUtils';
import type { AvatarUpdateType } from '../types/Avatar'; import type { AvatarUpdateType } from '../types/Avatar';
import MessageSender from '../textsecure/SendMessage'; import MessageSender from '../textsecure/SendMessage';
export type WriteProfileOptionsType = Readonly<
| {
keepAvatar: true;
}
| {
keepAvatar?: false;
avatarUpdate: AvatarUpdateType;
}
>;
export async function writeProfile( export async function writeProfile(
conversation: ConversationType, conversation: ConversationType,
avatar: AvatarUpdateType options: WriteProfileOptionsType
): Promise<void> { ): Promise<void> {
const { server } = window.textsecure; const { server } = window.textsecure;
if (!server) { if (!server) {
@ -46,16 +58,37 @@ export async function writeProfile(
'writeProfile: Cannot set an empty profile name' 'writeProfile: Cannot set an empty profile name'
); );
let avatarUpdate: AvatarUpdateType;
if (options.keepAvatar) {
const profileAvatarPath = getAbsoluteProfileAvatarPath(model.attributes);
let avatarBuffer: Uint8Array | undefined;
if (profileAvatarPath) {
try {
avatarBuffer = await imagePathToBytes(profileAvatarPath);
} catch (error) {
log.warn('writeProfile: local avatar not found, dropping remote');
}
}
avatarUpdate = {
oldAvatar: avatarBuffer,
newAvatar: avatarBuffer,
};
} else {
avatarUpdate = options.avatarUpdate;
}
const [profileData, encryptedAvatarData] = await encryptProfileData( const [profileData, encryptedAvatarData] = await encryptProfileData(
conversation, conversation,
avatar avatarUpdate
); );
const avatarRequestHeaders = await server.putProfile(profileData); const avatarRequestHeaders = await server.putProfile(profileData);
// Upload the avatar if provided // Upload the avatar if provided
// delete existing files on disk if avatar has been removed // delete existing files on disk if avatar has been removed
// update the account's avatar path and hash if it's a new avatar // update the account's avatar path and hash if it's a new avatar
const { newAvatar } = avatar; const { newAvatar } = avatarUpdate;
let maybeProfileAvatarUpdate: { let maybeProfileAvatarUpdate: {
profileAvatar?: profileAvatar?:
| { | {

View file

@ -2029,7 +2029,7 @@ function saveAvatarToDisk(
function myProfileChanged( function myProfileChanged(
profileData: ProfileDataType, profileData: ProfileDataType,
avatar: AvatarUpdateType avatarUpdate: AvatarUpdateType
): ThunkAction< ): ThunkAction<
void, void,
RootStateType, RootStateType,
@ -2045,7 +2045,9 @@ function myProfileChanged(
...conversation, ...conversation,
...profileData, ...profileData,
}, },
avatar {
avatarUpdate,
}
); );
// writeProfile above updates the backbone model which in turn updates // writeProfile above updates the backbone model which in turn updates

View file

@ -242,8 +242,7 @@ export function createIPCEvents(
// writeProfile fetches the latest profile first so do it before updating // writeProfile fetches the latest profile first so do it before updating
// local data to prevent triggering a conflict. // local data to prevent triggering a conflict.
await writeProfile(getConversation(account), { await writeProfile(getConversation(account), {
oldAvatar: undefined, keepAvatar: true,
newAvatar: undefined,
}); });
const promises = new Array<Promise<void>>(); const promises = new Array<Promise<void>>();