Merge branch 'edit-profile-fixes' into 'develop'
Edit profile fixes Closes #1018 See merge request soapbox-pub/soapbox-fe!1597
This commit is contained in:
commit
d222eb2a0c
7 changed files with 57 additions and 46 deletions
|
@ -6,7 +6,7 @@ import api from '../api';
|
|||
import { loadCredentials } from './auth';
|
||||
import { importFetchedAccount } from './importer';
|
||||
|
||||
import type { AxiosError } from 'axios';
|
||||
import type { AxiosError, AxiosRequestHeaders } from 'axios';
|
||||
import type { AppDispatch, RootState } from 'soapbox/store';
|
||||
import type { APIEntity } from 'soapbox/types/entities';
|
||||
|
||||
|
@ -62,12 +62,16 @@ const persistAuthAccount = (account: APIEntity, params: Record<string, any>) =>
|
|||
}
|
||||
};
|
||||
|
||||
const patchMe = (params: Record<string, any>) =>
|
||||
const patchMe = (params: Record<string, any>, isFormData = false) =>
|
||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||
dispatch(patchMeRequest());
|
||||
|
||||
const headers: AxiosRequestHeaders = isFormData ? {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
} : {};
|
||||
|
||||
return api(getState)
|
||||
.patch('/api/v1/accounts/update_credentials', params)
|
||||
.patch('/api/v1/accounts/update_credentials', params, { headers })
|
||||
.then(response => {
|
||||
persistAuthAccount(response.data, params);
|
||||
dispatch(patchMeSuccess(response.data));
|
||||
|
|
|
@ -4,9 +4,19 @@ import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
|||
import { updateNotificationSettings } from 'soapbox/actions/accounts';
|
||||
import { patchMe } from 'soapbox/actions/me';
|
||||
import snackbar from 'soapbox/actions/snackbar';
|
||||
import BirthdayInput from 'soapbox/components/birthday_input';
|
||||
import List, { ListItem } from 'soapbox/components/list';
|
||||
import { Button, Column, Form, FormActions, FormGroup, Input, Textarea, HStack, Toggle, FileInput } from 'soapbox/components/ui';
|
||||
import {
|
||||
Button,
|
||||
Column,
|
||||
FileInput,
|
||||
Form,
|
||||
FormActions,
|
||||
FormGroup,
|
||||
HStack,
|
||||
Input,
|
||||
Textarea,
|
||||
Toggle,
|
||||
} from 'soapbox/components/ui';
|
||||
import Streamfield, { StreamfieldComponent } from 'soapbox/components/ui/streamfield/streamfield';
|
||||
import { useAppSelector, useAppDispatch, useOwnAccount, useFeatures } from 'soapbox/hooks';
|
||||
import { normalizeAccount } from 'soapbox/normalizers';
|
||||
|
@ -25,25 +35,6 @@ const hidesNetwork = (account: Account): boolean => {
|
|||
return Boolean(hide_followers && hide_follows && hide_followers_count && hide_follows_count);
|
||||
};
|
||||
|
||||
/** Converts JSON objects to FormData. */
|
||||
// https://stackoverflow.com/a/60286175/8811886
|
||||
// @ts-ignore
|
||||
const toFormData = (f => f(f))(h => f => f(x => h(h)(f)(x)))(f => fd => pk => d => {
|
||||
if (d instanceof Object) {
|
||||
// eslint-disable-next-line consistent-return
|
||||
Object.keys(d).forEach(k => {
|
||||
const v = d[k];
|
||||
if (pk) k = `${pk}[${k}]`;
|
||||
if (v instanceof Object && !(v instanceof Date) && !(v instanceof File)) {
|
||||
return f(fd)(k)(v);
|
||||
} else {
|
||||
fd.append(k, v);
|
||||
}
|
||||
});
|
||||
}
|
||||
return fd;
|
||||
})(new FormData())();
|
||||
|
||||
const messages = defineMessages({
|
||||
heading: { id: 'column.edit_profile', defaultMessage: 'Edit profile' },
|
||||
header: { id: 'edit_profile.header', defaultMessage: 'Edit Profile' },
|
||||
|
@ -205,9 +196,8 @@ const EditProfile: React.FC = () => {
|
|||
|
||||
const handleSubmit: React.FormEventHandler = (event) => {
|
||||
const promises = [];
|
||||
const formData = toFormData(data);
|
||||
|
||||
promises.push(dispatch(patchMe(formData)));
|
||||
promises.push(dispatch(patchMe(data, true)));
|
||||
|
||||
if (features.muteStrangers) {
|
||||
promises.push(
|
||||
|
@ -242,10 +232,6 @@ const EditProfile: React.FC = () => {
|
|||
};
|
||||
};
|
||||
|
||||
const handleBirthdayChange = (date: string) => {
|
||||
updateData('birthday', date);
|
||||
};
|
||||
|
||||
const handleHideNetworkChange: React.ChangeEventHandler<HTMLInputElement> = e => {
|
||||
const hide = e.target.checked;
|
||||
|
||||
|
@ -329,9 +315,12 @@ const EditProfile: React.FC = () => {
|
|||
<FormGroup
|
||||
labelText={<FormattedMessage id='edit_profile.fields.birthday_label' defaultMessage='Birthday' />}
|
||||
>
|
||||
<BirthdayInput
|
||||
<Input
|
||||
type='text'
|
||||
value={data.birthday}
|
||||
onChange={handleBirthdayChange}
|
||||
onChange={handleTextChange('birthday')}
|
||||
placeholder='YYYY-MM-DD'
|
||||
pattern='\d{4}-\d{2}-\d{2}'
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
|
|
|
@ -47,6 +47,13 @@ describe('normalizeAccount()', () => {
|
|||
expect(result.birthday).toEqual('1993-07-03');
|
||||
});
|
||||
|
||||
it('normalizes undefined birthday to empty string', () => {
|
||||
const account = require('soapbox/__fixtures__/mastodon-account.json');
|
||||
const result = normalizeAccount(account);
|
||||
|
||||
expect(result.birthday).toEqual('');
|
||||
});
|
||||
|
||||
it('normalizes Pleroma legacy fields', () => {
|
||||
const account = require('soapbox/__fixtures__/pleroma-2.2.2-account.json');
|
||||
const result = normalizeAccount(account);
|
||||
|
|
|
@ -24,7 +24,7 @@ export const AccountRecord = ImmutableRecord({
|
|||
acct: '',
|
||||
avatar: '',
|
||||
avatar_static: '',
|
||||
birthday: undefined as string | undefined,
|
||||
birthday: '',
|
||||
bot: false,
|
||||
created_at: new Date(),
|
||||
discoverable: false,
|
||||
|
@ -261,6 +261,12 @@ const normalizeDiscoverable = (account: ImmutableMap<string, any>) => {
|
|||
return account.set('discoverable', discoverable);
|
||||
};
|
||||
|
||||
/** Normalize undefined/null birthday to empty string. */
|
||||
const fixBirthday = (account: ImmutableMap<string, any>) => {
|
||||
const birthday = account.get('birthday');
|
||||
return account.set('birthday', birthday || '');
|
||||
};
|
||||
|
||||
export const normalizeAccount = (account: Record<string, any>) => {
|
||||
return AccountRecord(
|
||||
ImmutableMap(fromJS(account)).withMutations(account => {
|
||||
|
@ -280,6 +286,7 @@ export const normalizeAccount = (account: Record<string, any>) => {
|
|||
addStaffFields(account);
|
||||
fixUsername(account);
|
||||
fixDisplayName(account);
|
||||
fixBirthday(account);
|
||||
addInternalFields(account);
|
||||
}),
|
||||
);
|
||||
|
|
|
@ -148,9 +148,7 @@ const getInstanceFeatures = (instance: Instance) => {
|
|||
* @see POST /api/v1/accounts
|
||||
* @see PATCH /api/v1/accounts/update_credentials
|
||||
*/
|
||||
// birthdays: v.software === PLEROMA && gte(v.version, '2.4.50'),
|
||||
// FIXME: temporarily disabled until they can be deleted on the backend.
|
||||
birthdays: false,
|
||||
birthdays: v.software === PLEROMA && v.build === SOAPBOX && gte(v.version, '2.4.50'),
|
||||
|
||||
/** Whether people who blocked you are visible through the API. */
|
||||
blockersVisible: features.includes('blockers_visible'),
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
"@types/uuid": "^8.3.4",
|
||||
"array-includes": "^3.1.5",
|
||||
"autoprefixer": "^10.4.2",
|
||||
"axios": "^0.27.2",
|
||||
"axios": "^1.0.0-alpha.1",
|
||||
"axios-mock-adapter": "^1.21.1",
|
||||
"babel-loader": "^8.2.5",
|
||||
"babel-plugin-lodash": "^3.3.4",
|
||||
|
|
24
yarn.lock
24
yarn.lock
|
@ -3506,13 +3506,14 @@ axios-mock-adapter@^1.21.1:
|
|||
fast-deep-equal "^3.1.3"
|
||||
is-buffer "^2.0.5"
|
||||
|
||||
axios@^0.27.2:
|
||||
version "0.27.2"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
|
||||
integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
|
||||
axios@^1.0.0-alpha.1:
|
||||
version "1.0.0-alpha.1"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-1.0.0-alpha.1.tgz#ce69c17ca7605d01787ca754dd906e6fccdf71ee"
|
||||
integrity sha512-p+meG161943WT+K7sJYquHR46xxi/z0tk7vnSmEf/LrfEAyiP+0uTMMYk1OEo1IRF18oGRhnFxN1y8fLcXaTMw==
|
||||
dependencies:
|
||||
follow-redirects "^1.14.9"
|
||||
follow-redirects "^1.15.0"
|
||||
form-data "^4.0.0"
|
||||
proxy-from-env "^1.1.0"
|
||||
|
||||
axobject-query@^2.2.0:
|
||||
version "2.2.0"
|
||||
|
@ -5827,10 +5828,10 @@ follow-redirects@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.4.tgz#838fdf48a8bbdd79e52ee51fb1c94e3ed98b9379"
|
||||
integrity sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==
|
||||
|
||||
follow-redirects@^1.14.9:
|
||||
version "1.14.9"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7"
|
||||
integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==
|
||||
follow-redirects@^1.15.0:
|
||||
version "1.15.1"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5"
|
||||
integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==
|
||||
|
||||
foreach@^2.0.5:
|
||||
version "2.0.5"
|
||||
|
@ -9501,6 +9502,11 @@ proxy-addr@~2.0.7:
|
|||
forwarded "0.2.0"
|
||||
ipaddr.js "1.9.1"
|
||||
|
||||
proxy-from-env@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
||||
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
|
||||
|
||||
psl@^1.1.33:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
|
||||
|
|
Loading…
Reference in a new issue