Merge branch 'fix-profile-update' into 'main'
Fix updating profile avatar/banner See merge request soapbox-pub/soapbox!3304
This commit is contained in:
commit
c737d7cb5c
|
@ -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 => {
|
||||||
|
|
|
@ -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(
|
||||||
|
|
Loading…
Reference in New Issue