Merge branch 'fix-profile-update' into 'main'

Fix updating profile avatar/banner

See merge request soapbox-pub/soapbox!3304
This commit is contained in:
Alex Gleason 2024-12-19 19:43:48 +00:00
commit c737d7cb5c
2 changed files with 36 additions and 17 deletions

View File

@ -53,16 +53,12 @@ const fetchMe = () =>
.catch(error => dispatch(fetchMeFail(error))); .catch(error => dispatch(fetchMeFail(error)));
}; };
const patchMe = (params: Record<string, any>, isFormData = false) => const patchMe = (params: Record<string, any> | FormData) =>
(dispatch: AppDispatch, getState: () => RootState) => { (dispatch: AppDispatch, getState: () => RootState) => {
dispatch(patchMeRequest()); dispatch(patchMeRequest());
const headers = isFormData ? {
'Content-Type': 'multipart/form-data',
} : undefined;
return api(getState) return api(getState)
.patch('/api/v1/accounts/update_credentials', params, { headers }) .patch('/api/v1/accounts/update_credentials', params)
.then((response) => response.json()).then((data) => { .then((response) => response.json()).then((data) => {
dispatch(patchMeSuccess(data)); dispatch(patchMeSuccess(data));
}).catch(error => { }).catch(error => {

View File

@ -79,11 +79,6 @@ interface AccountCredentialsSource {
sensitive?: boolean; sensitive?: boolean;
/** Default language to use for authored statuses. (ISO 6391) */ /** Default language to use for authored statuses. (ISO 6391) */
language?: string; language?: string;
/** Nostr metadata. */
nostr?: {
/** Nostr NIP-05 identifier. */
nip05?: string;
};
} }
/** /**
@ -214,6 +209,10 @@ const EditProfile: React.FC = () => {
const avatar = useImageField({ maxPixels: 400 * 400, preview: nonDefaultAvatar(account?.avatar) }); const avatar = useImageField({ maxPixels: 400 * 400, preview: nonDefaultAvatar(account?.avatar) });
const header = useImageField({ maxPixels: 1920 * 1080, preview: nonDefaultHeader(account?.header) }); const header = useImageField({ maxPixels: 1920 * 1080, preview: nonDefaultHeader(account?.header) });
// `null` means the file was explicitly cleared. `undefined` means unchanged.
useEffect(() => updateData('avatar', avatar.file === null ? '' : avatar.file), [avatar.file]);
useEffect(() => updateData('header', header.file === null ? '' : header.file), [header.file]);
useEffect(() => { useEffect(() => {
if (account) { if (account) {
const credentials = accountToCredentials(account); const credentials = accountToCredentials(account);
@ -231,14 +230,38 @@ const EditProfile: React.FC = () => {
}; };
const handleSubmit: React.FormEventHandler = (event) => { const handleSubmit: React.FormEventHandler = (event) => {
const promises = []; const formdata = new FormData();
const params = { ...data }; for (const [key, value] of Object.entries(data) as [string, unknown][]) {
if (params.fields_attributes?.length === 0) params.fields_attributes = [{ name: '', value: '' }]; if (key === 'fields_attributes') {
if (header.file !== undefined) params.header = header.file || ''; const fields = data.fields_attributes || [];
if (avatar.file !== undefined) params.avatar = avatar.file || ''; fields.forEach((field, i) => {
formdata.set(`fields_attributes[${i}][name]`, field.name);
formdata.set(`fields_attributes[${i}][value]`, field.value);
});
} else if (key === 'source') {
for (const [k, v] of Object.entries(data.source || {})) {
formdata.set(`source[${k}]`, String(v));
}
} else if (value instanceof Blob) {
formdata.set(key, value);
} else if (['string', 'number', 'boolean'].includes(typeof value)) {
formdata.set(key, String(value));
} else if (value) {
throw new Error('Could not encode profile data into a FormData object.');
}
}
promises.push(dispatch(patchMe(params, true))); // Having zero profile fields should remove them from the account.
// On Mastodon, it's only possible to do this by sending one field with empty values.
if (data.fields_attributes?.length === 0) {
formdata.set('fields_attributes[0][name]', '');
formdata.set('fields_attributes[0][value]', '');
}
const promises = [
dispatch(patchMe(formdata)),
];
if (features.muteStrangers) { if (features.muteStrangers) {
promises.push( promises.push(