Avoid inline message definitions
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
7c3d0c821b
commit
682d2a3647
|
@ -83,7 +83,7 @@ export const COMPOSE_SET_STATUS = 'COMPOSE_SET_STATUS';
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
exceededImageSizeLimit: { id: 'upload_error.image_size_limit', defaultMessage: 'Image exceeds the current file size limit ({limit})' },
|
exceededImageSizeLimit: { id: 'upload_error.image_size_limit', defaultMessage: 'Image exceeds the current file size limit ({limit})' },
|
||||||
exceededVideoSizeLimit: { id: 'upload_error.video_size_limit', defaultMessage: 'Video exceeds the current file size limit ({limit})' },
|
exceededVideoSizeLimit: { id: 'upload_error.video_size_limit', defaultMessage: 'Video exceeds the current file size limit ({limit})' },
|
||||||
scheduleError: { id: 'compose.invalid_schedule', defaultMessage: 'You must schedule a post at least 5 minutes out.' },
|
scheduleError: { id: 'compose.invalid_schedule', defaultMessage: 'You must schedule a post at least 5 minutes out.' },
|
||||||
success: { id: 'compose.submit_success', defaultMessage: 'Your post was sent' },
|
success: { id: 'compose.submit_success', defaultMessage: 'Your post was sent' },
|
||||||
uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' },
|
uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' },
|
||||||
uploadErrorPoll: { id: 'upload_error.poll', defaultMessage: 'File upload not allowed with polls.' },
|
uploadErrorPoll: { id: 'upload_error.poll', defaultMessage: 'File upload not allowed with polls.' },
|
||||||
|
|
|
@ -2,7 +2,7 @@ import classNames from 'classnames';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
interface IBadge {
|
interface IBadge {
|
||||||
title: string,
|
title: string | React.ReactNode,
|
||||||
slug: 'patron' | 'donor' | 'admin' | 'moderator' | 'bot' | 'opaque',
|
slug: 'patron' | 'donor' | 'admin' | 'moderator' | 'bot' | 'opaque',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -614,12 +614,12 @@ class MediaGallery extends React.PureComponent {
|
||||||
<div className='space-y-1'>
|
<div className='space-y-1'>
|
||||||
<Text weight='semibold'>{warning}</Text>
|
<Text weight='semibold'>{warning}</Text>
|
||||||
<Text size='sm'>
|
<Text size='sm'>
|
||||||
{intl.formatMessage({ id: 'status.sensitive_warning.subtitle', defaultMessage: 'This content may not be suitable for all audiences.' })}
|
<FormattedMessage id='status.sensitive_warning.subtitle' defaultMessage='This content may not be suitable for all audiences.' />
|
||||||
</Text>
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button type='button' theme='primary' size='sm' icon={require('@tabler/icons/icons/eye.svg')}>
|
<Button type='button' theme='primary' size='sm' icon={require('@tabler/icons/icons/eye.svg')}>
|
||||||
{intl.formatMessage({ id: 'status.sensitive_warning.action', defaultMessage: 'Show content' })}
|
<FormattedMessage id='status.sensitive_warning.action' defaultMessage='Show content' />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useIntl } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { usePopper } from 'react-popper';
|
import { usePopper } from 'react-popper';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
|
@ -64,7 +64,6 @@ interface IProfileHoverCard {
|
||||||
export const ProfileHoverCard: React.FC<IProfileHoverCard> = ({ visible = true }) => {
|
export const ProfileHoverCard: React.FC<IProfileHoverCard> = ({ visible = true }) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const intl = useIntl();
|
|
||||||
|
|
||||||
const [popperElement, setPopperElement] = useState<HTMLElement | null>(null);
|
const [popperElement, setPopperElement] = useState<HTMLElement | null>(null);
|
||||||
|
|
||||||
|
@ -130,7 +129,7 @@ export const ProfileHoverCard: React.FC<IProfileHoverCard> = ({ visible = true }
|
||||||
<div className='absolute top-2 left-2'>
|
<div className='absolute top-2 left-2'>
|
||||||
<Badge
|
<Badge
|
||||||
slug='opaque'
|
slug='opaque'
|
||||||
title={intl.formatMessage({ id: 'account.follows_you', defaultMessage: 'Follows you' })}
|
title={<FormattedMessage id='account.follows_you' defaultMessage='Follows you' />}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import classNames from 'classnames';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { HotKeys } from 'react-hotkeys';
|
import { HotKeys } from 'react-hotkeys';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import { injectIntl, FormattedMessage, IntlShape } from 'react-intl';
|
import { injectIntl, FormattedMessage, IntlShape, defineMessages } from 'react-intl';
|
||||||
import { NavLink, withRouter, RouteComponentProps } from 'react-router-dom';
|
import { NavLink, withRouter, RouteComponentProps } from 'react-router-dom';
|
||||||
|
|
||||||
import Icon from 'soapbox/components/icon';
|
import Icon from 'soapbox/components/icon';
|
||||||
|
@ -31,6 +31,10 @@ import type {
|
||||||
// Defined in components/scrollable_list
|
// Defined in components/scrollable_list
|
||||||
export type ScrollPosition = { height: number, top: number };
|
export type ScrollPosition = { height: number, top: number };
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
reblogged_by: { id: 'status.reblogged_by', defaultMessage: '{name} reposted' },
|
||||||
|
});
|
||||||
|
|
||||||
export const textForScreenReader = (intl: IntlShape, status: StatusEntity, rebloggedByText?: string): string => {
|
export const textForScreenReader = (intl: IntlShape, status: StatusEntity, rebloggedByText?: string): string => {
|
||||||
const { account } = status;
|
const { account } = status;
|
||||||
if (!account || typeof account !== 'object') return '';
|
if (!account || typeof account !== 'object') return '';
|
||||||
|
@ -437,12 +441,10 @@ class Status extends ImmutablePureComponent<IStatus, IStatusState> {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
rebloggedByText = intl.formatMessage({
|
rebloggedByText = intl.formatMessage(
|
||||||
id: 'status.reblogged_by',
|
messages.reblogged_by,
|
||||||
defaultMessage: '{name} reposted',
|
{ name: String(status.getIn(['account', 'acct'])) },
|
||||||
}, {
|
);
|
||||||
name: String(status.getIn(['account', 'acct'])),
|
|
||||||
});
|
|
||||||
|
|
||||||
// @ts-ignore what the FUCK
|
// @ts-ignore what the FUCK
|
||||||
account = status.account;
|
account = status.account;
|
||||||
|
|
|
@ -102,7 +102,7 @@ export default class StatusList extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLoadGap(index) {
|
renderLoadGap(index) {
|
||||||
const { statusIds, onLoadMore, isLoading } = this.props;
|
const { statusIds, onLoadMore, isLoading } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LoadGap
|
<LoadGap
|
||||||
|
@ -115,7 +115,7 @@ export default class StatusList extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderStatus(statusId) {
|
renderStatus(statusId) {
|
||||||
const { timelineId, withGroupAdmin, group } = this.props;
|
const { timelineId, withGroupAdmin, group } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StatusContainer
|
<StatusContainer
|
||||||
|
@ -148,7 +148,7 @@ export default class StatusList extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderFeaturedStatuses() {
|
renderFeaturedStatuses() {
|
||||||
const { featuredStatusIds, timelineId } = this.props;
|
const { featuredStatusIds, timelineId } = this.props;
|
||||||
if (!featuredStatusIds) return null;
|
if (!featuredStatusIds) return null;
|
||||||
|
|
||||||
return featuredStatusIds.map(statusId => (
|
return featuredStatusIds.map(statusId => (
|
||||||
|
@ -164,7 +164,7 @@ export default class StatusList extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderStatuses() {
|
renderStatuses() {
|
||||||
const { statusIds, isLoading } = this.props;
|
const { statusIds, isLoading } = this.props;
|
||||||
|
|
||||||
if (isLoading || statusIds.size > 0) {
|
if (isLoading || statusIds.size > 0) {
|
||||||
return statusIds.map((statusId, index) => {
|
return statusIds.map((statusId, index) => {
|
||||||
|
@ -193,7 +193,7 @@ export default class StatusList extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { statusIds, divideType, featuredStatusIds, onLoadMore, timelineId, totalQueuedItemsCount, isLoading, isPartial, withGroupAdmin, group, ...other } = this.props;
|
const { statusIds, divideType, featuredStatusIds, onLoadMore, timelineId, totalQueuedItemsCount, isLoading, isPartial, withGroupAdmin, group, ...other } = this.props;
|
||||||
|
|
||||||
if (isPartial) {
|
if (isPartial) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
@ -457,7 +457,7 @@ class Header extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
makeInfo() {
|
makeInfo() {
|
||||||
const { account, intl, me } = this.props;
|
const { account, me } = this.props;
|
||||||
|
|
||||||
const info = [];
|
const info = [];
|
||||||
|
|
||||||
|
@ -468,7 +468,7 @@ class Header extends ImmutablePureComponent {
|
||||||
<Badge
|
<Badge
|
||||||
key='followed_by'
|
key='followed_by'
|
||||||
slug='opaque'
|
slug='opaque'
|
||||||
title={intl.formatMessage({ id: 'account.follows_you', defaultMessage: 'Follows you' })}
|
title={<FormattedMessage id='account.follows_you' defaultMessage='Follows you' />}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
} else if (me !== account.get('id') && account.getIn(['relationship', 'blocking'])) {
|
} else if (me !== account.get('id') && account.getIn(['relationship', 'blocking'])) {
|
||||||
|
@ -476,7 +476,7 @@ class Header extends ImmutablePureComponent {
|
||||||
<Badge
|
<Badge
|
||||||
key='blocked'
|
key='blocked'
|
||||||
slug='opaque'
|
slug='opaque'
|
||||||
title={intl.formatMessage({ id: 'account.blocked', defaultMessage: 'Blocked' })}
|
title={<FormattedMessage id='account.blocked' defaultMessage='Blocked' />}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -486,7 +486,7 @@ class Header extends ImmutablePureComponent {
|
||||||
<Badge
|
<Badge
|
||||||
key='muted'
|
key='muted'
|
||||||
slug='opaque'
|
slug='opaque'
|
||||||
title={intl.formatMessage({ id: 'account.muted', defaultMessage: 'Muted' })}
|
title={<FormattedMessage id='account.muted' defaultMessage='Muted' />}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
} else if (me !== account.get('id') && account.getIn(['relationship', 'domain_blocking'])) {
|
} else if (me !== account.get('id') && account.getIn(['relationship', 'domain_blocking'])) {
|
||||||
|
@ -494,7 +494,7 @@ class Header extends ImmutablePureComponent {
|
||||||
<Badge
|
<Badge
|
||||||
key='domain_blocked'
|
key='domain_blocked'
|
||||||
slug='opaque'
|
slug='opaque'
|
||||||
title={intl.formatMessage({ id: 'account.domain_blocked', defaultMessage: 'Domain hidden' })}
|
title={<FormattedMessage id='account.domain_blocked' defaultMessage='Domain hidden' />}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,12 @@ import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { approveUsers } from 'soapbox/actions/admin';
|
import { approveUsers } from 'soapbox/actions/admin';
|
||||||
|
import { rejectUserModal } from 'soapbox/actions/moderation';
|
||||||
import snackbar from 'soapbox/actions/snackbar';
|
import snackbar from 'soapbox/actions/snackbar';
|
||||||
import IconButton from 'soapbox/components/icon_button';
|
import IconButton from 'soapbox/components/icon_button';
|
||||||
import { useAppSelector, useAppDispatch } from 'soapbox/hooks';
|
import { useAppSelector, useAppDispatch } from 'soapbox/hooks';
|
||||||
import { makeGetAccount } from 'soapbox/selectors';
|
import { makeGetAccount } from 'soapbox/selectors';
|
||||||
|
|
||||||
import { rejectUserModal } from '../../../actions/moderation';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
approved: { id: 'admin.awaiting_approval.approved_message', defaultMessage: '{acct} was approved!' },
|
approved: { id: 'admin.awaiting_approval.approved_message', defaultMessage: '{acct} was approved!' },
|
||||||
rejected: { id: 'admin.awaiting_approval.rejected_message', defaultMessage: '{acct} was rejected.' },
|
rejected: { id: 'admin.awaiting_approval.rejected_message', defaultMessage: '{acct} was rejected.' },
|
||||||
|
|
|
@ -26,7 +26,7 @@ const LoginForm: React.FC<ILoginForm> = ({ isLoading, handleSubmit }) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className='pb-4 sm:pb-10 mb-4 border-b border-gray-200 border-solid -mx-4 sm:-mx-10'>
|
<div className='pb-4 sm:pb-10 mb-4 border-b border-gray-200 border-solid -mx-4 sm:-mx-10'>
|
||||||
<h1 className='text-center font-bold text-2xl'>{intl.formatMessage({ id: 'login_form.header', defaultMessage: 'Sign In' })}</h1>
|
<h1 className='text-center font-bold text-2xl'><FormattedMessage id='login_form.header' defaultMessage='Sign In' /></h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='sm:pt-10 sm:w-2/3 md:w-1/2 mx-auto'>
|
<div className='sm:pt-10 sm:w-2/3 md:w-1/2 mx-auto'>
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { Button, Form, FormActions, FormGroup, Input } from 'soapbox/components/
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
otpCodeHint: { id: 'login.fields.otp_code_hint', defaultMessage: 'Enter the two-factor code generated by your phone app or use one of your recovery codes' },
|
otpCodeHint: { id: 'login.fields.otp_code_hint', defaultMessage: 'Enter the two-factor code generated by your phone app or use one of your recovery codes' },
|
||||||
otpCodeLabel: { id: 'login.fields.otp_code_label', defaultMessage: 'Two-factor code:' },
|
otpCodeLabel: { id: 'login.fields.otp_code_label', defaultMessage: 'Two-factor code:' },
|
||||||
|
otpLoginFail: { id: 'login.otp_log_in.fail', defaultMessage: 'Invalid code, please try again.' },
|
||||||
});
|
});
|
||||||
|
|
||||||
export default @connect()
|
export default @connect()
|
||||||
|
@ -70,7 +71,7 @@ class OtpAuthForm extends ImmutablePureComponent {
|
||||||
<FormGroup
|
<FormGroup
|
||||||
labelText={intl.formatMessage(messages.otpCodeLabel)}
|
labelText={intl.formatMessage(messages.otpCodeLabel)}
|
||||||
hintText={intl.formatMessage(messages.otpCodeHint)}
|
hintText={intl.formatMessage(messages.otpCodeHint)}
|
||||||
errors={code_error ? [intl.formatMessage({ id: 'login.otp_log_in.fail', defaultMessage: 'Invalid code, please try again.' })] : []}
|
errors={code_error ? [intl.formatMessage(messages.otpLoginFail)] : []}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
name='code'
|
name='code'
|
||||||
|
|
|
@ -44,7 +44,7 @@ class PasswordReset extends ImmutablePureComponent {
|
||||||
<div>
|
<div>
|
||||||
<div className='pb-4 sm:pb-10 mb-4 border-b border-gray-200 dark:border-gray-600 border-solid -mx-4 sm:-mx-10'>
|
<div className='pb-4 sm:pb-10 mb-4 border-b border-gray-200 dark:border-gray-600 border-solid -mx-4 sm:-mx-10'>
|
||||||
<h1 className='text-center font-bold text-2xl'>
|
<h1 className='text-center font-bold text-2xl'>
|
||||||
{intl.formatMessage({ id: 'password_reset.header', defaultMessage: 'Reset Password' })}
|
<FormattedMessage id='password_reset.header' defaultMessage='Reset Password' />
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { FormattedMessage, injectIntl, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { Redirect } from 'react-router-dom';
|
import { Redirect } from 'react-router-dom';
|
||||||
|
|
||||||
import { resetPasswordConfirm } from 'soapbox/actions/security';
|
import { resetPasswordConfirm } from 'soapbox/actions/security';
|
||||||
import { Button, Form, FormActions, FormGroup, Input } from 'soapbox/components/ui';
|
import { Button, Form, FormActions, FormGroup, Input } from 'soapbox/components/ui';
|
||||||
|
import { useAppDispatch } from 'soapbox/hooks';
|
||||||
|
|
||||||
const token = new URLSearchParams(window.location.search).get('reset_password_token');
|
const token = new URLSearchParams(window.location.search).get('reset_password_token');
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
resetPasswordFail: { id: 'reset_password.fail', defaultMessage: 'Expired token, please try again.' },
|
||||||
|
});
|
||||||
|
|
||||||
const Statuses = {
|
const Statuses = {
|
||||||
IDLE: 'IDLE',
|
IDLE: 'IDLE',
|
||||||
LOADING: 'LOADING',
|
LOADING: 'LOADING',
|
||||||
|
@ -16,12 +19,9 @@ const Statuses = {
|
||||||
FAIL: 'FAIL',
|
FAIL: 'FAIL',
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const PasswordResetConfirm = () => {
|
||||||
resetPasswordConfirm: (password, token) => dispatch(resetPasswordConfirm(password, token)),
|
|
||||||
});
|
|
||||||
|
|
||||||
const PasswordResetConfirm = ({ resetPasswordConfirm }) => {
|
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const [password, setPassword] = React.useState('');
|
const [password, setPassword] = React.useState('');
|
||||||
const [status, setStatus] = React.useState(Statuses.IDLE);
|
const [status, setStatus] = React.useState(Statuses.IDLE);
|
||||||
|
@ -32,10 +32,10 @@ const PasswordResetConfirm = ({ resetPasswordConfirm }) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
setStatus(Statuses.LOADING);
|
setStatus(Statuses.LOADING);
|
||||||
resetPasswordConfirm(password, token)
|
dispatch(resetPasswordConfirm(password, token))
|
||||||
.then(() => setStatus(Statuses.SUCCESS))
|
.then(() => setStatus(Statuses.SUCCESS))
|
||||||
.catch(() => setStatus(Statuses.FAIL));
|
.catch(() => setStatus(Statuses.FAIL));
|
||||||
}, [resetPasswordConfirm, password]);
|
}, [password]);
|
||||||
|
|
||||||
const onChange = React.useCallback((event) => {
|
const onChange = React.useCallback((event) => {
|
||||||
setPassword(event.target.value);
|
setPassword(event.target.value);
|
||||||
|
@ -43,7 +43,7 @@ const PasswordResetConfirm = ({ resetPasswordConfirm }) => {
|
||||||
|
|
||||||
const renderErrors = () => {
|
const renderErrors = () => {
|
||||||
if (status === Statuses.FAIL) {
|
if (status === Statuses.FAIL) {
|
||||||
return [intl.formatMessage({ id: 'reset_password.fail', defaultMessage: 'Expired token, please try again.' })];
|
return [intl.formatMessage(messages.resetPasswordFail)];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
|
@ -84,8 +84,4 @@ const PasswordResetConfirm = ({ resetPasswordConfirm }) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
PasswordResetConfirm.propTypes = {
|
export default PasswordResetConfirm;
|
||||||
resetPasswordConfirm: PropTypes.func,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default injectIntl(connect(null, mapDispatchToProps)(PasswordResetConfirm));
|
|
|
@ -208,9 +208,9 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEmojiPick = (data) => {
|
handleEmojiPick = (data) => {
|
||||||
const { text } = this.props;
|
const { text } = this.props;
|
||||||
const position = this.autosuggestTextarea.textarea.selectionStart;
|
const position = this.autosuggestTextarea.textarea.selectionStart;
|
||||||
const needsSpace = data.custom && position > 0 && !allowedAroundShortCode.includes(text[position - 1]);
|
const needsSpace = data.custom && position > 0 && !allowedAroundShortCode.includes(text[position - 1]);
|
||||||
|
|
||||||
this.props.onPickEmoji(position, data, needsSpace);
|
this.props.onPickEmoji(position, data, needsSpace);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,16 +6,15 @@ import { defineMessages, useIntl } from 'react-intl';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
import AutosuggestAccountInput from 'soapbox/components/autosuggest_account_input';
|
|
||||||
import SvgIcon from 'soapbox/components/ui/icon/svg-icon';
|
|
||||||
import { useAppSelector } from 'soapbox/hooks';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
changeSearch,
|
changeSearch,
|
||||||
clearSearch,
|
clearSearch,
|
||||||
submitSearch,
|
submitSearch,
|
||||||
showSearch,
|
showSearch,
|
||||||
} from '../../../actions/search';
|
} from 'soapbox/actions/search';
|
||||||
|
import AutosuggestAccountInput from 'soapbox/components/autosuggest_account_input';
|
||||||
|
import SvgIcon from 'soapbox/components/ui/icon/svg-icon';
|
||||||
|
import { useAppSelector } from 'soapbox/hooks';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
placeholder: { id: 'search.placeholder', defaultMessage: 'Search' },
|
placeholder: { id: 'search.placeholder', defaultMessage: 'Search' },
|
||||||
|
|
|
@ -86,7 +86,7 @@ class Directory extends React.PureComponent {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isLoading, accountIds, intl, title, features } = this.props;
|
const { isLoading, accountIds, intl, title, features } = this.props;
|
||||||
const { order, local } = this.getParams(this.props, this.state);
|
const { order, local } = this.getParams(this.props, this.state);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column icon='address-book-o' label={intl.formatMessage(messages.title)}>
|
<Column icon='address-book-o' label={intl.formatMessage(messages.title)}>
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
import { useDispatch } from 'react-redux';
|
|
||||||
|
|
||||||
import { changeEmail } from 'soapbox/actions/security';
|
import { changeEmail } from 'soapbox/actions/security';
|
||||||
import snackbar from 'soapbox/actions/snackbar';
|
import snackbar from 'soapbox/actions/snackbar';
|
||||||
|
import { Button, Card, CardBody, CardHeader, CardTitle, Column, Form, FormActions, FormGroup, Input } from 'soapbox/components/ui';
|
||||||
import { Button, Card, CardBody, CardHeader, CardTitle, Column, Form, FormActions, FormGroup, Input } from '../../components/ui';
|
import { useAppDispatch } from 'soapbox/hooks';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
header: { id: 'edit_email.header', defaultMessage: 'Change Email' },
|
||||||
updateEmailSuccess: { id: 'security.update_email.success', defaultMessage: 'Email successfully updated.' },
|
updateEmailSuccess: { id: 'security.update_email.success', defaultMessage: 'Email successfully updated.' },
|
||||||
updateEmailFail: { id: 'security.update_email.fail', defaultMessage: 'Update email failed.' },
|
updateEmailFail: { id: 'security.update_email.fail', defaultMessage: 'Update email failed.' },
|
||||||
emailFieldLabel: { id: 'security.fields.email.label', defaultMessage: 'Email address' },
|
emailFieldLabel: { id: 'security.fields.email.label', defaultMessage: 'Email address' },
|
||||||
|
emailFieldPlaceholder: { id: 'edit_email.placeholder', defaultMessage: 'me@example.com' },
|
||||||
passwordFieldLabel: { id: 'security.fields.password.label', defaultMessage: 'Password' },
|
passwordFieldLabel: { id: 'security.fields.password.label', defaultMessage: 'Password' },
|
||||||
submit: { id: 'security.submit', defaultMessage: 'Save changes' },
|
submit: { id: 'security.submit', defaultMessage: 'Save changes' },
|
||||||
cancel: { id: 'common.cancel', defaultMessage: 'Cancel' },
|
cancel: { id: 'common.cancel', defaultMessage: 'Cancel' },
|
||||||
|
@ -20,7 +21,7 @@ const initialState = { email: '', password: '' };
|
||||||
|
|
||||||
const EditEmail = () => {
|
const EditEmail = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const [state, setState] = React.useState(initialState);
|
const [state, setState] = React.useState(initialState);
|
||||||
const [isLoading, setLoading] = React.useState(false);
|
const [isLoading, setLoading] = React.useState(false);
|
||||||
|
@ -48,14 +49,14 @@ const EditEmail = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column
|
<Column
|
||||||
label={intl.formatMessage({ id: 'edit_email.header', defaultMessage: 'Change Email' })}
|
label={intl.formatMessage(messages.header)}
|
||||||
transparent
|
transparent
|
||||||
withHeader={false}
|
withHeader={false}
|
||||||
>
|
>
|
||||||
<Card variant='rounded'>
|
<Card variant='rounded'>
|
||||||
<CardHeader backHref='/settings'>
|
<CardHeader backHref='/settings'>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
title={intl.formatMessage({ id: 'edit_email.header', defaultMessage: 'Change Email' })}
|
title={intl.formatMessage(messages.header)}
|
||||||
/>
|
/>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|
||||||
|
@ -63,9 +64,10 @@ const EditEmail = () => {
|
||||||
<Form onSubmit={handleSubmit}>
|
<Form onSubmit={handleSubmit}>
|
||||||
<FormGroup labelText={intl.formatMessage(messages.emailFieldLabel)}>
|
<FormGroup labelText={intl.formatMessage(messages.emailFieldLabel)}>
|
||||||
<Input
|
<Input
|
||||||
placeholder={intl.formatMessage({ id: 'edit_email.placeholder', defaultMessage: 'me@example.com' })}
|
type='text'
|
||||||
|
placeholder={intl.formatMessage(messages.emailFieldPlaceholder)}
|
||||||
name='email'
|
name='email'
|
||||||
autocomplete='off'
|
autoComplete='off'
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
value={email}
|
value={email}
|
||||||
/>
|
/>
|
|
@ -1,14 +1,12 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
import { useDispatch } from 'react-redux';
|
|
||||||
import { Redirect } from 'react-router-dom';
|
import { Redirect } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { confirmChangedEmail } from 'soapbox/actions/security';
|
||||||
import snackbar from 'soapbox/actions/snackbar';
|
import snackbar from 'soapbox/actions/snackbar';
|
||||||
import { Spinner } from 'soapbox/components/ui';
|
import { Spinner } from 'soapbox/components/ui';
|
||||||
|
import { useAppDispatch } from 'soapbox/hooks';
|
||||||
import { confirmChangedEmail } from '../../actions/security';
|
import { buildErrorMessage } from 'soapbox/utils/errors';
|
||||||
import { buildErrorMessage } from '../../utils/errors';
|
|
||||||
|
|
||||||
const Statuses = {
|
const Statuses = {
|
||||||
IDLE: 'IDLE',
|
IDLE: 'IDLE',
|
||||||
|
@ -16,11 +14,15 @@ const Statuses = {
|
||||||
FAIL: 'FAIL',
|
FAIL: 'FAIL',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
success: { id: 'email_confirmation.success', defaultMessage: 'Your email has been confirmed!' },
|
||||||
|
});
|
||||||
|
|
||||||
const token = new URLSearchParams(window.location.search).get('confirmation_token');
|
const token = new URLSearchParams(window.location.search).get('confirmation_token');
|
||||||
|
|
||||||
const EmailConfirmation = () => {
|
const EmailConfirmation = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const [status, setStatus] = React.useState(Statuses.IDLE);
|
const [status, setStatus] = React.useState(Statuses.IDLE);
|
||||||
|
|
||||||
|
@ -32,10 +34,7 @@ const EmailConfirmation = () => {
|
||||||
|
|
||||||
dispatch(
|
dispatch(
|
||||||
snackbar.success(
|
snackbar.success(
|
||||||
intl.formatMessage({
|
intl.formatMessage(messages.success),
|
||||||
id: 'email_confirmation.success',
|
|
||||||
defaultMessage: 'Your email has been confirmed!',
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
@ -43,14 +42,15 @@ const EmailConfirmation = () => {
|
||||||
setStatus(Statuses.FAIL);
|
setStatus(Statuses.FAIL);
|
||||||
|
|
||||||
if (error.response.data.error) {
|
if (error.response.data.error) {
|
||||||
const defaultMessage = buildErrorMessage(error.response.data.error);
|
const message = buildErrorMessage(error.response.data.error);
|
||||||
|
|
||||||
dispatch(
|
dispatch(
|
||||||
snackbar.error(
|
snackbar.error(
|
||||||
intl.formatMessage({
|
message,
|
||||||
id: 'email_confirmation.fail',
|
// intl.formatMessage({
|
||||||
defaultMessage,
|
// id: 'email_confirmation.fail',
|
||||||
}),
|
// defaultMessage,
|
||||||
|
// }),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,4 @@ const EmailConfirmation = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
EmailConfirmation.propTypes = {
|
|
||||||
history: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EmailConfirmation;
|
export default EmailConfirmation;
|
|
@ -31,11 +31,11 @@ class HashtagTimeline extends React.PureComponent {
|
||||||
// TODO: wtf is all this?
|
// TODO: wtf is all this?
|
||||||
// It exists in Mastodon's codebase, but undocumented
|
// It exists in Mastodon's codebase, but undocumented
|
||||||
if (this.additionalFor('any')) {
|
if (this.additionalFor('any')) {
|
||||||
title.push(' ', <FormattedMessage key='any' id='hashtag.column_header.tag_mode.any' values={{ additional: this.additionalFor('any') }} defaultMessage='or {additional}' />);
|
title.push(' ', <FormattedMessage key='any' id='hashtag.column_header.tag_mode.any' values={{ additional: this.additionalFor('any') }} defaultMessage='or {additional}' />);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.additionalFor('all')) {
|
if (this.additionalFor('all')) {
|
||||||
title.push(' ', <FormattedMessage key='all' id='hashtag.column_header.tag_mode.all' values={{ additional: this.additionalFor('all') }} defaultMessage='and {additional}' />);
|
title.push(' ', <FormattedMessage key='all' id='hashtag.column_header.tag_mode.all' values={{ additional: this.additionalFor('all') }} defaultMessage='and {additional}' />);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.additionalFor('none')) {
|
if (this.additionalFor('none')) {
|
||||||
|
|
|
@ -23,6 +23,8 @@ const messages = defineMessages({
|
||||||
sessions: { id: 'settings.sessions', defaultMessage: 'Active sessions' },
|
sessions: { id: 'settings.sessions', defaultMessage: 'Active sessions' },
|
||||||
deleteAccount: { id: 'settings.delete_account', defaultMessage: 'Delete Account' },
|
deleteAccount: { id: 'settings.delete_account', defaultMessage: 'Delete Account' },
|
||||||
other: { id: 'settings.other', defaultMessage: 'Other options' },
|
other: { id: 'settings.other', defaultMessage: 'Other options' },
|
||||||
|
mfaEnabled: { id: 'mfa.enabled', defaultMessage: 'Enabled' },
|
||||||
|
mfaDisabled: { id: 'mfa.disabled', defaultMessage: 'Disabled' },
|
||||||
});
|
});
|
||||||
|
|
||||||
/** User settings page. */
|
/** User settings page. */
|
||||||
|
@ -77,8 +79,8 @@ const Settings = () => {
|
||||||
<ListItem label={intl.formatMessage(messages.changePassword)} onClick={navigateToChangePassword} />
|
<ListItem label={intl.formatMessage(messages.changePassword)} onClick={navigateToChangePassword} />
|
||||||
<ListItem label={intl.formatMessage(messages.configureMfa)} onClick={navigateToMfa}>
|
<ListItem label={intl.formatMessage(messages.configureMfa)} onClick={navigateToMfa}>
|
||||||
{isMfaEnabled ?
|
{isMfaEnabled ?
|
||||||
intl.formatMessage({ id: 'mfa.enabled', defaultMessage: 'Enabled' }) :
|
intl.formatMessage(messages.mfaEnabled) :
|
||||||
intl.formatMessage({ id: 'mfa.disabled', defaultMessage: 'Disabled' })}
|
intl.formatMessage(messages.mfaDisabled)}
|
||||||
</ListItem>
|
</ListItem>
|
||||||
{features.sessionsAPI && (
|
{features.sessionsAPI && (
|
||||||
<ListItem label={intl.formatMessage(messages.sessions)} onClick={navigateToSessions} />
|
<ListItem label={intl.formatMessage(messages.sessions)} onClick={navigateToSessions} />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { Redirect } from 'react-router-dom';
|
import { Redirect } from 'react-router-dom';
|
||||||
|
|
||||||
|
@ -10,10 +10,24 @@ import { startOnboarding } from 'soapbox/actions/onboarding';
|
||||||
import snackbar from 'soapbox/actions/snackbar';
|
import snackbar from 'soapbox/actions/snackbar';
|
||||||
import { createAccount } from 'soapbox/actions/verification';
|
import { createAccount } from 'soapbox/actions/verification';
|
||||||
import { removeStoredVerification } from 'soapbox/actions/verification';
|
import { removeStoredVerification } from 'soapbox/actions/verification';
|
||||||
|
import { Button, Form, FormGroup, Input } from 'soapbox/components/ui';
|
||||||
import { useAppSelector } from 'soapbox/hooks';
|
import { useAppSelector } from 'soapbox/hooks';
|
||||||
import { getRedirectUrl } from 'soapbox/utils/redirect';
|
import { getRedirectUrl } from 'soapbox/utils/redirect';
|
||||||
|
|
||||||
import { Button, Form, FormGroup, Input } from '../../components/ui';
|
const messages = defineMessages({
|
||||||
|
success: {
|
||||||
|
id: 'registrations.success',
|
||||||
|
defaultMessage: 'Welcome to {siteTitle}!',
|
||||||
|
},
|
||||||
|
usernameTaken: {
|
||||||
|
id: 'registrations.unprocessable_entity',
|
||||||
|
defaultMessage: 'This username has already been taken.',
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
id: 'registrations.error',
|
||||||
|
defaultMessage: 'Failed to register your account.',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
username: '',
|
username: '',
|
||||||
|
@ -45,10 +59,7 @@ const Registration = () => {
|
||||||
dispatch(startOnboarding());
|
dispatch(startOnboarding());
|
||||||
dispatch(
|
dispatch(
|
||||||
snackbar.success(
|
snackbar.success(
|
||||||
intl.formatMessage({
|
intl.formatMessage(messages.success, { siteTitle }),
|
||||||
id: 'registrations.success',
|
|
||||||
defaultMessage: 'Welcome to {siteTitle}!',
|
|
||||||
}, { siteTitle }),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
@ -56,19 +67,13 @@ const Registration = () => {
|
||||||
if (error?.response?.status === 422) {
|
if (error?.response?.status === 422) {
|
||||||
dispatch(
|
dispatch(
|
||||||
snackbar.error(
|
snackbar.error(
|
||||||
intl.formatMessage({
|
intl.formatMessage(messages.usernameTaken),
|
||||||
id: 'registrations.unprocessable_entity',
|
|
||||||
defaultMessage: 'This username has already been taken.',
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
dispatch(
|
dispatch(
|
||||||
snackbar.error(
|
snackbar.error(
|
||||||
intl.formatMessage({
|
intl.formatMessage(messages.error),
|
||||||
id: 'registrations.error',
|
|
||||||
defaultMessage: 'Failed to register your account.',
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -90,7 +95,7 @@ const Registration = () => {
|
||||||
<div>
|
<div>
|
||||||
<div className='pb-4 sm:pb-10 mb-4 border-b border-gray-200 border-solid -mx-4 sm:-mx-10'>
|
<div className='pb-4 sm:pb-10 mb-4 border-b border-gray-200 border-solid -mx-4 sm:-mx-10'>
|
||||||
<h1 className='text-center font-bold text-2xl'>
|
<h1 className='text-center font-bold text-2xl'>
|
||||||
{intl.formatMessage({ id: 'registration.header', defaultMessage: 'Register your account' })}
|
<FormattedMessage id='registration.header' defaultMessage='Register your account' />
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import DatePicker from 'react-datepicker';
|
import DatePicker from 'react-datepicker';
|
||||||
import { useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
import snackbar from 'soapbox/actions/snackbar';
|
import snackbar from 'soapbox/actions/snackbar';
|
||||||
import { verifyAge } from 'soapbox/actions/verification';
|
import { verifyAge } from 'soapbox/actions/verification';
|
||||||
|
import { Button, Form, FormGroup, Text } from 'soapbox/components/ui';
|
||||||
|
|
||||||
import { Button, Form, FormGroup, Text } from '../../../components/ui';
|
const messages = defineMessages({
|
||||||
|
fail: {
|
||||||
|
id: 'age_verification.fail',
|
||||||
|
defaultMessage: 'You must be {ageMinimum, plural, one {# year} other {# years}} old or older.',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
function meetsAgeMinimum(birthday, ageMinimum) {
|
function meetsAgeMinimum(birthday, ageMinimum) {
|
||||||
const month = birthday.getUTCMonth();
|
const month = birthday.getUTCMonth();
|
||||||
|
@ -46,15 +52,9 @@ const AgeVerification = () => {
|
||||||
dispatch(verifyAge(birthday));
|
dispatch(verifyAge(birthday));
|
||||||
} else {
|
} else {
|
||||||
dispatch(
|
dispatch(
|
||||||
snackbar.error(
|
snackbar.error(intl.formatMessage(messages.fail, {
|
||||||
intl.formatMessage({
|
ageMinimum,
|
||||||
id: 'age_verification.fail',
|
})),
|
||||||
defaultMessage: 'You must be {ageMinimum, plural, one {# year} other {# years}} old or older.',
|
|
||||||
values: {
|
|
||||||
ageMinimum,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, [date, ageMinimum]);
|
}, [date, ageMinimum]);
|
||||||
|
@ -63,7 +63,7 @@ const AgeVerification = () => {
|
||||||
<div>
|
<div>
|
||||||
<div className='pb-4 sm:pb-10 mb-4 border-b border-gray-200 border-solid -mx-4 sm:-mx-10'>
|
<div className='pb-4 sm:pb-10 mb-4 border-b border-gray-200 border-solid -mx-4 sm:-mx-10'>
|
||||||
<h1 className='text-center font-bold text-2xl'>
|
<h1 className='text-center font-bold text-2xl'>
|
||||||
{intl.formatMessage({ id: 'age_verification.header', defaultMessage: 'Enter your birth date' })}
|
<FormattedMessage id='age_verification.header' defaultMessage='Enter your birth date' />
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue