diff options
Diffstat (limited to 'app/javascript/mastodon/features/ui/components')
-rw-r--r-- | app/javascript/mastodon/features/ui/components/__tests__/column-test.jsx (renamed from app/javascript/mastodon/features/ui/components/__tests__/column-test.js) | 0 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/actions_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/actions_modal.js) | 4 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/audio_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/audio_modal.js) | 8 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/block_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/block_modal.js) | 12 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/boost_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/boost_modal.js) | 12 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/bundle.jsx (renamed from app/javascript/mastodon/features/ui/components/bundle.js) | 10 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/bundle_column_error.jsx (renamed from app/javascript/mastodon/features/ui/components/bundle_column_error.js) | 11 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/bundle_modal_error.jsx (renamed from app/javascript/mastodon/features/ui/components/bundle_modal_error.js) | 4 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/column.jsx (renamed from app/javascript/mastodon/features/ui/components/column.js) | 6 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/column_header.jsx (renamed from app/javascript/mastodon/features/ui/components/column_header.js) | 2 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/column_link.jsx (renamed from app/javascript/mastodon/features/ui/components/column_link.js) | 0 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/column_loading.jsx (renamed from app/javascript/mastodon/features/ui/components/column_loading.js) | 0 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/column_subheading.jsx (renamed from app/javascript/mastodon/features/ui/components/column_subheading.js) | 0 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/columns_area.jsx (renamed from app/javascript/mastodon/features/ui/components/columns_area.js) | 12 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/compare_history_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/compare_history_modal.js) | 14 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/compose_panel.jsx (renamed from app/javascript/mastodon/features/ui/components/compose_panel.js) | 7 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/confirmation_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/confirmation_modal.js) | 11 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/disabled_account_banner.jsx (renamed from app/javascript/mastodon/features/ui/components/disabled_account_banner.js) | 6 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/drawer_loading.jsx (renamed from app/javascript/mastodon/features/ui/components/drawer_loading.js) | 0 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/embed_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/embed_modal.js) | 9 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/filter_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/filter_modal.js) | 4 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/focal_point_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/focal_point_modal.js) | 44 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/follow_requests_column_link.jsx (renamed from app/javascript/mastodon/features/ui/components/follow_requests_column_link.js) | 4 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/header.jsx (renamed from app/javascript/mastodon/features/ui/components/header.js) | 4 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/image_loader.jsx (renamed from app/javascript/mastodon/features/ui/components/image_loader.js) | 13 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/image_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/image_modal.js) | 3 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/link_footer.jsx (renamed from app/javascript/mastodon/features/ui/components/link_footer.js) | 22 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/list_panel.jsx (renamed from app/javascript/mastodon/features/ui/components/list_panel.js) | 4 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/media_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/media_modal.js) | 29 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/modal_loading.jsx (renamed from app/javascript/mastodon/features/ui/components/modal_loading.js) | 0 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/modal_root.jsx (renamed from app/javascript/mastodon/features/ui/components/modal_root.js) | 12 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/mute_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/mute_modal.js) | 14 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/navigation_panel.jsx (renamed from app/javascript/mastodon/features/ui/components/navigation_panel.js) | 7 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/report_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/report_modal.js) | 6 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/sign_in_banner.jsx (renamed from app/javascript/mastodon/features/ui/components/sign_in_banner.js) | 2 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/upload_area.jsx (renamed from app/javascript/mastodon/features/ui/components/upload_area.js) | 2 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/video_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/video_modal.js) | 13 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/zoomable_image.jsx (renamed from app/javascript/mastodon/features/ui/components/zoomable_image.js) | 36 |
38 files changed, 198 insertions, 149 deletions
diff --git a/app/javascript/mastodon/features/ui/components/__tests__/column-test.js b/app/javascript/mastodon/features/ui/components/__tests__/column-test.jsx index a56859be0..a56859be0 100644 --- a/app/javascript/mastodon/features/ui/components/__tests__/column-test.js +++ b/app/javascript/mastodon/features/ui/components/__tests__/column-test.jsx diff --git a/app/javascript/mastodon/features/ui/components/actions_modal.js b/app/javascript/mastodon/features/ui/components/actions_modal.jsx index 67be69d43..35090e242 100644 --- a/app/javascript/mastodon/features/ui/components/actions_modal.js +++ b/app/javascript/mastodon/features/ui/components/actions_modal.jsx @@ -23,7 +23,7 @@ export default class ActionsModal extends ImmutablePureComponent { return ( <li key={`${text}-${i}`}> <a href={href} target='_blank' rel='noopener noreferrer' onClick={this.props.onClick} data-index={i} className={classNames({ active })}> - {icon && <IconButton title={text} icon={icon} role='presentation' tabIndex='-1' inverted />} + {icon && <IconButton title={text} icon={icon} role='presentation' tabIndex={-1} inverted />} <div> <div className={classNames({ 'actions-modal__item-label': !!meta })}>{text}</div> <div>{meta}</div> @@ -31,7 +31,7 @@ export default class ActionsModal extends ImmutablePureComponent { </a> </li> ); - } + }; render () { return ( diff --git a/app/javascript/mastodon/features/ui/components/audio_modal.js b/app/javascript/mastodon/features/ui/components/audio_modal.jsx index c46fefce8..c0ac12ba7 100644 --- a/app/javascript/mastodon/features/ui/components/audio_modal.js +++ b/app/javascript/mastodon/features/ui/components/audio_modal.jsx @@ -7,15 +7,16 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import Footer from 'mastodon/features/picture_in_picture/components/footer'; const mapStateToProps = (state, { statusId }) => ({ + language: state.getIn(['statuses', statusId, 'language']), accountStaticAvatar: state.getIn(['accounts', state.getIn(['statuses', statusId, 'account']), 'avatar_static']), }); -export default @connect(mapStateToProps) class AudioModal extends ImmutablePureComponent { static propTypes = { media: ImmutablePropTypes.map.isRequired, statusId: PropTypes.string.isRequired, + language: PropTypes.string, accountStaticAvatar: PropTypes.string.isRequired, options: PropTypes.shape({ autoPlay: PropTypes.bool, @@ -25,7 +26,7 @@ class AudioModal extends ImmutablePureComponent { }; render () { - const { media, accountStaticAvatar, statusId, onClose } = this.props; + const { media, language, accountStaticAvatar, statusId, onClose } = this.props; const options = this.props.options || {}; return ( @@ -34,6 +35,7 @@ class AudioModal extends ImmutablePureComponent { <Audio src={media.get('url')} alt={media.get('description')} + lang={language} duration={media.getIn(['meta', 'original', 'duration'], 0)} height={150} poster={media.get('preview_url') || accountStaticAvatar} @@ -52,3 +54,5 @@ class AudioModal extends ImmutablePureComponent { } } + +export default connect(mapStateToProps, null, null, { forwardRef: true })(AudioModal); diff --git a/app/javascript/mastodon/features/ui/components/block_modal.js b/app/javascript/mastodon/features/ui/components/block_modal.jsx index a07baeaa6..a9506aa69 100644 --- a/app/javascript/mastodon/features/ui/components/block_modal.js +++ b/app/javascript/mastodon/features/ui/components/block_modal.jsx @@ -36,8 +36,6 @@ const mapDispatchToProps = dispatch => { }; }; -export default @connect(makeMapStateToProps, mapDispatchToProps) -@injectIntl class BlockModal extends React.PureComponent { static propTypes = { @@ -55,20 +53,20 @@ class BlockModal extends React.PureComponent { handleClick = () => { this.props.onClose(); this.props.onConfirm(this.props.account); - } + }; handleSecondary = () => { this.props.onClose(); this.props.onBlockAndReport(this.props.account); - } + }; handleCancel = () => { this.props.onClose(); - } + }; setRef = (c) => { this.button = c; - } + }; render () { const { account } = this.props; @@ -101,3 +99,5 @@ class BlockModal extends React.PureComponent { } } + +export default connect(makeMapStateToProps, mapDispatchToProps)(injectIntl(BlockModal)); diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.js b/app/javascript/mastodon/features/ui/components/boost_modal.jsx index 077ce7b35..fe55c963a 100644 --- a/app/javascript/mastodon/features/ui/components/boost_modal.js +++ b/app/javascript/mastodon/features/ui/components/boost_modal.jsx @@ -38,8 +38,6 @@ const mapDispatchToProps = dispatch => { }; }; -export default @connect(mapStateToProps, mapDispatchToProps) -@injectIntl class BoostModal extends ImmutablePureComponent { static contextTypes = { @@ -62,7 +60,7 @@ class BoostModal extends ImmutablePureComponent { handleReblog = () => { this.props.onReblog(this.props.status, this.props.privacy); this.props.onClose(); - } + }; handleAccountClick = (e) => { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { @@ -70,7 +68,7 @@ class BoostModal extends ImmutablePureComponent { this.props.onClose(); this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`); } - } + }; _findContainer = () => { return document.getElementsByClassName('modal-root__container')[0]; @@ -78,7 +76,7 @@ class BoostModal extends ImmutablePureComponent { setRef = (c) => { this.button = c; - } + }; render () { const { status, privacy, intl } = this.props; @@ -98,7 +96,7 @@ class BoostModal extends ImmutablePureComponent { <div className='boost-modal__container'> <div className={classNames('status', `status-${status.get('visibility')}`, 'light')}> <div className='status__info'> - <a href={`/@${status.getIn(['account', 'acct'])}\/${status.get('id')}`} className='status__relative-time' target='_blank' rel='noopener noreferrer'> + <a href={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} className='status__relative-time' target='_blank' rel='noopener noreferrer'> <span className='status__visibility-icon'><Icon id={visibilityIcon.icon} title={visibilityIcon.text} /></span> <RelativeTimestamp timestamp={status.get('created_at')} /> </a> @@ -140,3 +138,5 @@ class BoostModal extends ImmutablePureComponent { } } + +export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(BoostModal)); diff --git a/app/javascript/mastodon/features/ui/components/bundle.js b/app/javascript/mastodon/features/ui/components/bundle.jsx index a60ace35b..1b10a218b 100644 --- a/app/javascript/mastodon/features/ui/components/bundle.js +++ b/app/javascript/mastodon/features/ui/components/bundle.jsx @@ -15,7 +15,7 @@ class Bundle extends React.PureComponent { onFetch: PropTypes.func, onFetchSuccess: PropTypes.func, onFetchFail: PropTypes.func, - } + }; static defaultProps = { loading: emptyComponent, @@ -24,14 +24,14 @@ class Bundle extends React.PureComponent { onFetch: noop, onFetchSuccess: noop, onFetchFail: noop, - } + }; - static cache = new Map + static cache = new Map; state = { mod: undefined, forceRender: false, - } + }; componentWillMount() { this.load(this.props); @@ -83,7 +83,7 @@ class Bundle extends React.PureComponent { this.setState({ mod: null }); onFetchFail(error); }); - } + }; render() { const { loading: Loading, error: Error, children, renderDelay } = this.props; diff --git a/app/javascript/mastodon/features/ui/components/bundle_column_error.js b/app/javascript/mastodon/features/ui/components/bundle_column_error.jsx index dfe970ad0..dc9b0e539 100644 --- a/app/javascript/mastodon/features/ui/components/bundle_column_error.js +++ b/app/javascript/mastodon/features/ui/components/bundle_column_error.jsx @@ -31,7 +31,7 @@ class GIF extends React.PureComponent { if (!animate) { this.setState({ hovering: true }); } - } + }; handleMouseLeave = () => { const { animate } = this.props; @@ -39,7 +39,7 @@ class GIF extends React.PureComponent { if (!animate) { this.setState({ hovering: false }); } - } + }; render () { const { src, staticSrc, className, animate } = this.props; @@ -75,7 +75,7 @@ class CopyButton extends React.PureComponent { navigator.clipboard.writeText(value); this.setState({ copied: true }); this.timeout = setTimeout(() => this.setState({ copied: false }), 700); - } + }; componentWillUnmount () { if (this.timeout) clearTimeout(this.timeout); @@ -92,7 +92,6 @@ class CopyButton extends React.PureComponent { } -export default @injectIntl class BundleColumnError extends React.PureComponent { static propTypes = { @@ -113,7 +112,7 @@ class BundleColumnError extends React.PureComponent { if (onRetry) { onRetry(); } - } + }; render () { const { errorType, multiColumn, stacktrace } = this.props; @@ -160,3 +159,5 @@ class BundleColumnError extends React.PureComponent { } } + +export default injectIntl(BundleColumnError); diff --git a/app/javascript/mastodon/features/ui/components/bundle_modal_error.js b/app/javascript/mastodon/features/ui/components/bundle_modal_error.jsx index f9365b95b..d79d0ca4a 100644 --- a/app/javascript/mastodon/features/ui/components/bundle_modal_error.js +++ b/app/javascript/mastodon/features/ui/components/bundle_modal_error.jsx @@ -16,11 +16,11 @@ class BundleModalError extends React.PureComponent { onRetry: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, - } + }; handleRetry = () => { this.props.onRetry(); - } + }; render () { const { onClose, intl: { formatMessage } } = this.props; diff --git a/app/javascript/mastodon/features/ui/components/column.js b/app/javascript/mastodon/features/ui/components/column.jsx index 15538ea38..7bc2f7e00 100644 --- a/app/javascript/mastodon/features/ui/components/column.js +++ b/app/javascript/mastodon/features/ui/components/column.jsx @@ -23,7 +23,7 @@ export default class Column extends React.PureComponent { } this._interruptScrollAnimation = scrollTop(scrollable); - } + }; scrollTop () { const scrollable = this.node.querySelector('.scrollable'); @@ -40,11 +40,11 @@ export default class Column extends React.PureComponent { if (typeof this._interruptScrollAnimation !== 'undefined') { this._interruptScrollAnimation(); } - }, 200) + }, 200); setRef = (c) => { this.node = c; - } + }; render () { const { heading, icon, children, active, hideHeadingOnMobile } = this.props; diff --git a/app/javascript/mastodon/features/ui/components/column_header.js b/app/javascript/mastodon/features/ui/components/column_header.jsx index b1a36e173..4ceef5957 100644 --- a/app/javascript/mastodon/features/ui/components/column_header.js +++ b/app/javascript/mastodon/features/ui/components/column_header.jsx @@ -15,7 +15,7 @@ export default class ColumnHeader extends React.PureComponent { handleClick = () => { this.props.onClick(); - } + }; render () { const { icon, type, active, columnHeaderId } = this.props; diff --git a/app/javascript/mastodon/features/ui/components/column_link.js b/app/javascript/mastodon/features/ui/components/column_link.jsx index 8eebbf526..8eebbf526 100644 --- a/app/javascript/mastodon/features/ui/components/column_link.js +++ b/app/javascript/mastodon/features/ui/components/column_link.jsx diff --git a/app/javascript/mastodon/features/ui/components/column_loading.js b/app/javascript/mastodon/features/ui/components/column_loading.jsx index e5ed22584..e5ed22584 100644 --- a/app/javascript/mastodon/features/ui/components/column_loading.js +++ b/app/javascript/mastodon/features/ui/components/column_loading.jsx diff --git a/app/javascript/mastodon/features/ui/components/column_subheading.js b/app/javascript/mastodon/features/ui/components/column_subheading.jsx index 8160c4aa3..8160c4aa3 100644 --- a/app/javascript/mastodon/features/ui/components/column_subheading.js +++ b/app/javascript/mastodon/features/ui/components/column_subheading.jsx diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.jsx index e7def800e..1dd6e34e8 100644 --- a/app/javascript/mastodon/features/ui/components/columns_area.js +++ b/app/javascript/mastodon/features/ui/components/columns_area.jsx @@ -57,7 +57,7 @@ export default class ColumnsArea extends ImmutablePureComponent { state = { renderComposePanel: !(this.mediaQuery && this.mediaQuery.matches), - } + }; componentDidMount() { if (!this.props.singleColumn) { @@ -111,7 +111,7 @@ export default class ColumnsArea extends ImmutablePureComponent { handleLayoutChange = (e) => { this.setState({ renderComposePanel: !e.matches }); - } + }; handleWheel = () => { if (typeof this._interruptScrollAnimation !== 'function') { @@ -119,19 +119,19 @@ export default class ColumnsArea extends ImmutablePureComponent { } this._interruptScrollAnimation(); - } + }; setRef = (node) => { this.node = node; - } + }; renderLoading = columnId => () => { return columnId === 'COMPOSE' ? <DrawerLoading /> : <ColumnLoading multiColumn />; - } + }; renderError = (props) => { return <BundleColumnError multiColumn errorType='network' {...props} />; - } + }; render () { const { columns, children, singleColumn, isModalOpen } = this.props; diff --git a/app/javascript/mastodon/features/ui/components/compare_history_modal.js b/app/javascript/mastodon/features/ui/components/compare_history_modal.jsx index ecccc8f7d..1802c167c 100644 --- a/app/javascript/mastodon/features/ui/components/compare_history_modal.js +++ b/app/javascript/mastodon/features/ui/components/compare_history_modal.jsx @@ -12,6 +12,7 @@ import RelativeTimestamp from 'mastodon/components/relative_timestamp'; import MediaAttachments from 'mastodon/components/media_attachments'; const mapStateToProps = (state, { statusId }) => ({ + language: state.getIn(['statuses', statusId, 'language']), versions: state.getIn(['history', statusId, 'items']), }); @@ -23,18 +24,18 @@ const mapDispatchToProps = dispatch => ({ }); -export default @connect(mapStateToProps, mapDispatchToProps) class CompareHistoryModal extends React.PureComponent { static propTypes = { onClose: PropTypes.func.isRequired, index: PropTypes.number.isRequired, statusId: PropTypes.string.isRequired, + language: PropTypes.string.isRequired, versions: ImmutablePropTypes.list.isRequired, }; render () { - const { index, versions, onClose } = this.props; + const { index, versions, language, onClose } = this.props; const currentVersion = versions.get(index); const emojiMap = currentVersion.get('emojis').reduce((obj, emoji) => { @@ -65,12 +66,12 @@ class CompareHistoryModal extends React.PureComponent { <div className='status__content'> {currentVersion.get('spoiler_text').length > 0 && ( <React.Fragment> - <div className='translate' dangerouslySetInnerHTML={spoilerContent} /> + <div className='translate' dangerouslySetInnerHTML={spoilerContent} lang={language} /> <hr /> </React.Fragment> )} - <div className='status__content__text status__content__text--visible translate' dangerouslySetInnerHTML={content} /> + <div className='status__content__text status__content__text--visible translate' dangerouslySetInnerHTML={content} lang={language} /> {!!currentVersion.get('poll') && ( <div className='poll'> @@ -82,6 +83,7 @@ class CompareHistoryModal extends React.PureComponent { <span className='poll__option__text translate' dangerouslySetInnerHTML={{ __html: emojify(escapeTextContentForBrowser(option.get('title')), emojiMap) }} + lang={language} /> </li> ))} @@ -89,7 +91,7 @@ class CompareHistoryModal extends React.PureComponent { </div> )} - <MediaAttachments status={currentVersion} /> + <MediaAttachments status={currentVersion} lang={language} /> </div> </div> </div> @@ -97,3 +99,5 @@ class CompareHistoryModal extends React.PureComponent { } } + +export default connect(mapStateToProps, mapDispatchToProps)(CompareHistoryModal); diff --git a/app/javascript/mastodon/features/ui/components/compose_panel.js b/app/javascript/mastodon/features/ui/components/compose_panel.jsx index 92d16b5b3..1c6f80ad5 100644 --- a/app/javascript/mastodon/features/ui/components/compose_panel.js +++ b/app/javascript/mastodon/features/ui/components/compose_panel.jsx @@ -8,7 +8,6 @@ import LinkFooter from './link_footer'; import ServerBanner from 'mastodon/components/server_banner'; import { changeComposing, mountCompose, unmountCompose } from 'mastodon/actions/compose'; -export default @connect() class ComposePanel extends React.PureComponent { static contextTypes = { @@ -22,12 +21,12 @@ class ComposePanel extends React.PureComponent { onFocus = () => { const { dispatch } = this.props; dispatch(changeComposing(true)); - } + }; onBlur = () => { const { dispatch } = this.props; dispatch(changeComposing(false)); - } + }; componentDidMount () { const { dispatch } = this.props; @@ -66,3 +65,5 @@ class ComposePanel extends React.PureComponent { } } + +export default connect()(ComposePanel); diff --git a/app/javascript/mastodon/features/ui/components/confirmation_modal.js b/app/javascript/mastodon/features/ui/components/confirmation_modal.jsx index 65d97ca16..4437567a1 100644 --- a/app/javascript/mastodon/features/ui/components/confirmation_modal.js +++ b/app/javascript/mastodon/features/ui/components/confirmation_modal.jsx @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import { injectIntl, FormattedMessage } from 'react-intl'; import Button from '../../../components/button'; -export default @injectIntl class ConfirmationModal extends React.PureComponent { static propTypes = { @@ -30,20 +29,20 @@ class ConfirmationModal extends React.PureComponent { this.props.onClose(); } this.props.onConfirm(); - } + }; handleSecondary = () => { this.props.onClose(); this.props.onSecondary(); - } + }; handleCancel = () => { this.props.onClose(); - } + }; setRef = (c) => { this.button = c; - } + }; render () { const { message, confirm, secondary } = this.props; @@ -68,3 +67,5 @@ class ConfirmationModal extends React.PureComponent { } } + +export default injectIntl(ConfirmationModal); diff --git a/app/javascript/mastodon/features/ui/components/disabled_account_banner.js b/app/javascript/mastodon/features/ui/components/disabled_account_banner.jsx index 038cc3553..ea11cea44 100644 --- a/app/javascript/mastodon/features/ui/components/disabled_account_banner.js +++ b/app/javascript/mastodon/features/ui/components/disabled_account_banner.jsx @@ -28,8 +28,6 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ }, }); -export default @injectIntl -@connect(mapStateToProps, mapDispatchToProps) class DisabledAccountBanner extends React.PureComponent { static propTypes = { @@ -46,7 +44,7 @@ class DisabledAccountBanner extends React.PureComponent { this.props.onLogout(); return false; - } + }; render () { const { disabledAcct, movedToAcct } = this.props; @@ -90,3 +88,5 @@ class DisabledAccountBanner extends React.PureComponent { } } + +export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(DisabledAccountBanner)); diff --git a/app/javascript/mastodon/features/ui/components/drawer_loading.js b/app/javascript/mastodon/features/ui/components/drawer_loading.jsx index 08b0d2347..08b0d2347 100644 --- a/app/javascript/mastodon/features/ui/components/drawer_loading.js +++ b/app/javascript/mastodon/features/ui/components/drawer_loading.jsx diff --git a/app/javascript/mastodon/features/ui/components/embed_modal.js b/app/javascript/mastodon/features/ui/components/embed_modal.jsx index 4679c9650..baf6be411 100644 --- a/app/javascript/mastodon/features/ui/components/embed_modal.js +++ b/app/javascript/mastodon/features/ui/components/embed_modal.jsx @@ -9,7 +9,6 @@ const messages = defineMessages({ close: { id: 'lightbox.close', defaultMessage: 'Close' }, }); -export default @injectIntl class EmbedModal extends ImmutablePureComponent { static propTypes = { @@ -17,7 +16,7 @@ class EmbedModal extends ImmutablePureComponent { onClose: PropTypes.func.isRequired, onError: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, - } + }; state = { loading: false, @@ -48,11 +47,11 @@ class EmbedModal extends ImmutablePureComponent { setIframeRef = c => { this.iframe = c; - } + }; handleTextareaClick = (e) => { e.target.select(); - } + }; render () { const { intl, onClose } = this.props; @@ -95,3 +94,5 @@ class EmbedModal extends ImmutablePureComponent { } } + +export default injectIntl(EmbedModal); diff --git a/app/javascript/mastodon/features/ui/components/filter_modal.js b/app/javascript/mastodon/features/ui/components/filter_modal.jsx index 376db961d..32ebaf7b7 100644 --- a/app/javascript/mastodon/features/ui/components/filter_modal.js +++ b/app/javascript/mastodon/features/ui/components/filter_modal.jsx @@ -13,8 +13,6 @@ const messages = defineMessages({ close: { id: 'lightbox.close', defaultMessage: 'Close' }, }); -export default @connect(undefined) -@injectIntl class FilterModal extends ImmutablePureComponent { static propTypes = { @@ -132,3 +130,5 @@ class FilterModal extends ImmutablePureComponent { } } + +export default connect(injectIntl(FilterModal)); diff --git a/app/javascript/mastodon/features/ui/components/focal_point_modal.js b/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx index 479f4abd2..11c4c5237 100644 --- a/app/javascript/mastodon/features/ui/components/focal_point_modal.js +++ b/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx @@ -39,6 +39,7 @@ const mapStateToProps = (state, { id }) => ({ account: state.getIn(['accounts', me]), isUploadingThumbnail: state.getIn(['compose', 'isUploadingThumbnail']), description: state.getIn(['compose', 'media_modal', 'description']), + lang: state.getIn(['compose', 'language']), focusX: state.getIn(['compose', 'media_modal', 'focusX']), focusY: state.getIn(['compose', 'media_modal', 'focusY']), dirty: state.getIn(['compose', 'media_modal', 'dirty']), @@ -99,8 +100,6 @@ class ImageLoader extends React.PureComponent { } -export default @connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true }) -@(component => injectIntl(component, { withRef: true })) class FocalPointModal extends ImmutablePureComponent { static propTypes = { @@ -134,7 +133,7 @@ class FocalPointModal extends ImmutablePureComponent { this.updatePosition(e); this.setState({ dragging: true }); - } + }; handleTouchStart = e => { document.addEventListener('touchmove', this.handleMouseMove); @@ -142,25 +141,25 @@ class FocalPointModal extends ImmutablePureComponent { this.updatePosition(e); this.setState({ dragging: true }); - } + }; handleMouseMove = e => { this.updatePosition(e); - } + }; handleMouseUp = () => { document.removeEventListener('mousemove', this.handleMouseMove); document.removeEventListener('mouseup', this.handleMouseUp); this.setState({ dragging: false }); - } + }; handleTouchEnd = () => { document.removeEventListener('touchmove', this.handleMouseMove); document.removeEventListener('touchend', this.handleTouchEnd); this.setState({ dragging: false }); - } + }; updatePosition = e => { const { x, y } = getPointerPosition(this.node, e); @@ -168,24 +167,24 @@ class FocalPointModal extends ImmutablePureComponent { const focusY = (y - .5) * -2; this.props.onChangeFocus(focusX, focusY); - } + }; handleChange = e => { this.props.onChangeDescription(e.target.value); - } + }; handleKeyDown = (e) => { if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) { this.props.onChangeDescription(e.target.value); this.handleSubmit(e); } - } + }; handleSubmit = (e) => { e.preventDefault(); e.stopPropagation(); this.props.onSave(this.props.description, this.props.focusX, this.props.focusY); - } + }; getCloseConfirmationMessage = () => { const { intl, dirty } = this.props; @@ -198,15 +197,15 @@ class FocalPointModal extends ImmutablePureComponent { } else { return null; } - } + }; setRef = c => { this.node = c; - } + }; handleTextDetection = () => { this._detectText(); - } + }; _detectText = (refreshCache = false) => { const { media } = this.props; @@ -257,24 +256,24 @@ class FocalPointModal extends ImmutablePureComponent { console.error(e); this.setState({ detecting: false }); }); - } + }; handleThumbnailChange = e => { if (e.target.files.length > 0) { this.props.onSelectThumbnail(e.target.files); } - } + }; setFileInputRef = c => { this.fileInput = c; - } + }; handleFileInputClick = () => { this.fileInput.click(); - } + }; render () { - const { media, intl, account, onClose, isUploadingThumbnail, description, focusX, focusY, dirty, is_changing_upload } = this.props; + const { media, intl, account, onClose, isUploadingThumbnail, description, lang, focusX, focusY, dirty, is_changing_upload } = this.props; const { dragging, detecting, progress, ocrStatus } = this.state; const x = (focusX / 2) + .5; const y = (focusY / -2) + .5; @@ -320,7 +319,7 @@ class FocalPointModal extends ImmutablePureComponent { <React.Fragment> <label className='setting-text-label' htmlFor='upload-modal__thumbnail'><FormattedMessage id='upload_form.thumbnail' defaultMessage='Change thumbnail' /></label> - <Button disabled={isUploadingThumbnail} text={intl.formatMessage(messages.chooseImage)} onClick={this.handleFileInputClick} /> + <Button disabled={isUploadingThumbnail || !media.get('unattached')} text={intl.formatMessage(messages.chooseImage)} onClick={this.handleFileInputClick} /> <label> <span style={{ display: 'none' }}>{intl.formatMessage(messages.chooseImage)}</span> @@ -349,6 +348,7 @@ class FocalPointModal extends ImmutablePureComponent { id='upload-modal__description' className='setting-text light' value={detecting ? '…' : description} + lang={lang} onChange={this.handleChange} onKeyDown={this.handleKeyDown} disabled={detecting || is_changing_upload} @@ -426,3 +426,7 @@ class FocalPointModal extends ImmutablePureComponent { } } + +export default connect(mapStateToProps, mapDispatchToProps, null, { + forwardRef: true, +})(injectIntl(FocalPointModal, { withRef: true })); diff --git a/app/javascript/mastodon/features/ui/components/follow_requests_column_link.js b/app/javascript/mastodon/features/ui/components/follow_requests_column_link.jsx index d04d58011..e6ffbdb84 100644 --- a/app/javascript/mastodon/features/ui/components/follow_requests_column_link.js +++ b/app/javascript/mastodon/features/ui/components/follow_requests_column_link.jsx @@ -15,8 +15,6 @@ const mapStateToProps = state => ({ count: state.getIn(['user_lists', 'follow_requests', 'items'], ImmutableList()).size, }); -export default @injectIntl -@connect(mapStateToProps) class FollowRequestsColumnLink extends React.Component { static propTypes = { @@ -45,3 +43,5 @@ class FollowRequestsColumnLink extends React.Component { } } + +export default injectIntl(connect(mapStateToProps)(FollowRequestsColumnLink)); diff --git a/app/javascript/mastodon/features/ui/components/header.js b/app/javascript/mastodon/features/ui/components/header.jsx index 1384bebda..c14c6faa7 100644 --- a/app/javascript/mastodon/features/ui/components/header.js +++ b/app/javascript/mastodon/features/ui/components/header.jsx @@ -22,8 +22,6 @@ const mapDispatchToProps = (dispatch) => ({ }, }); -export default @connect(null, mapDispatchToProps) -@withRouter class Header extends React.PureComponent { static contextTypes = { @@ -85,3 +83,5 @@ class Header extends React.PureComponent { } } + +export default withRouter(connect(null, mapDispatchToProps)(Header)); diff --git a/app/javascript/mastodon/features/ui/components/image_loader.js b/app/javascript/mastodon/features/ui/components/image_loader.jsx index dfa0efe49..9093eab28 100644 --- a/app/javascript/mastodon/features/ui/components/image_loader.js +++ b/app/javascript/mastodon/features/ui/components/image_loader.jsx @@ -8,16 +8,18 @@ export default class ImageLoader extends PureComponent { static propTypes = { alt: PropTypes.string, + lang: PropTypes.string, src: PropTypes.string.isRequired, previewSrc: PropTypes.string, width: PropTypes.number, height: PropTypes.number, onClick: PropTypes.func, zoomButtonHidden: PropTypes.bool, - } + }; static defaultProps = { alt: '', + lang: '', width: null, height: null, }; @@ -26,7 +28,7 @@ export default class ImageLoader extends PureComponent { loading: true, error: false, width: null, - } + }; removers = []; canvas = null; @@ -86,7 +88,7 @@ export default class ImageLoader extends PureComponent { image.addEventListener('load', handleLoad); image.src = previewSrc; this.removers.push(removeEventListeners); - }) + }); clearPreviewCanvas () { const { width, height } = this.canvas; @@ -126,10 +128,10 @@ export default class ImageLoader extends PureComponent { setCanvasRef = c => { this.canvas = c; if (c) this.setState({ width: c.offsetWidth }); - } + }; render () { - const { alt, src, width, height, onClick } = this.props; + const { alt, lang, src, width, height, onClick } = this.props; const { loading } = this.state; const className = classNames('image-loader', { @@ -154,6 +156,7 @@ export default class ImageLoader extends PureComponent { ) : ( <ZoomableImage alt={alt} + lang={lang} src={src} onClick={onClick} width={width} diff --git a/app/javascript/mastodon/features/ui/components/image_modal.js b/app/javascript/mastodon/features/ui/components/image_modal.jsx index 7522c3da5..ca93d7b4e 100644 --- a/app/javascript/mastodon/features/ui/components/image_modal.js +++ b/app/javascript/mastodon/features/ui/components/image_modal.jsx @@ -9,7 +9,6 @@ const messages = defineMessages({ close: { id: 'lightbox.close', defaultMessage: 'Close' }, }); -export default @injectIntl class ImageModal extends React.PureComponent { static propTypes = { @@ -57,3 +56,5 @@ class ImageModal extends React.PureComponent { } } + +export default injectIntl(ImageModal); diff --git a/app/javascript/mastodon/features/ui/components/link_footer.js b/app/javascript/mastodon/features/ui/components/link_footer.jsx index 3664a05bf..68ef015ab 100644 --- a/app/javascript/mastodon/features/ui/components/link_footer.js +++ b/app/javascript/mastodon/features/ui/components/link_footer.jsx @@ -3,7 +3,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; import { Link } from 'react-router-dom'; -import { domain, version, source_url, profile_directory as profileDirectory } from 'mastodon/initial_state'; +import { domain, version, source_url, statusPageUrl, profile_directory as profileDirectory } from 'mastodon/initial_state'; import { logOut } from 'mastodon/utils/log_out'; import { openModal } from 'mastodon/actions/modal'; import { PERMISSION_INVITE_USERS } from 'mastodon/permissions'; @@ -24,8 +24,6 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ }, }); -export default @injectIntl -@connect(null, mapDispatchToProps) class LinkFooter extends React.PureComponent { static contextTypes = { @@ -44,7 +42,7 @@ class LinkFooter extends React.PureComponent { this.props.onLogout(); return false; - } + }; render () { const { signedIn, permissions } = this.context.identity; @@ -59,21 +57,27 @@ class LinkFooter extends React.PureComponent { <p> <strong>{domain}</strong>: {' '} - <Link key='about' to='/about'><FormattedMessage id='footer.about' defaultMessage='About' /></Link> + <Link to='/about'><FormattedMessage id='footer.about' defaultMessage='About' /></Link> + {statusPageUrl && ( + <> + {DividingCircle} + <a href={statusPageUrl} target='_blank' rel='noopener'><FormattedMessage id='footer.status' defaultMessage='Status' /></a> + </> + )} {canInvite && ( <> {DividingCircle} - <a key='invites' href='/invites' target='_blank'><FormattedMessage id='footer.invite' defaultMessage='Invite people' /></a> + <a href='/invites' target='_blank'><FormattedMessage id='footer.invite' defaultMessage='Invite people' /></a> </> )} {canProfileDirectory && ( <> {DividingCircle} - <Link key='directory' to='/directory'><FormattedMessage id='footer.directory' defaultMessage='Profiles directory' /></Link> + <Link to='/directory'><FormattedMessage id='footer.directory' defaultMessage='Profiles directory' /></Link> </> )} {DividingCircle} - <Link key='privacy-policy' to='/privacy-policy'><FormattedMessage id='footer.privacy_policy' defaultMessage='Privacy policy' /></Link> + <Link to='/privacy-policy'><FormattedMessage id='footer.privacy_policy' defaultMessage='Privacy policy' /></Link> </p> <p> @@ -94,3 +98,5 @@ class LinkFooter extends React.PureComponent { } } + +export default injectIntl(connect(null, mapDispatchToProps)(LinkFooter)); diff --git a/app/javascript/mastodon/features/ui/components/list_panel.js b/app/javascript/mastodon/features/ui/components/list_panel.jsx index 2f92a9254..fcff4e37d 100644 --- a/app/javascript/mastodon/features/ui/components/list_panel.js +++ b/app/javascript/mastodon/features/ui/components/list_panel.jsx @@ -20,8 +20,6 @@ const mapStateToProps = state => ({ lists: getOrderedLists(state), }); -export default @withRouter -@connect(mapStateToProps) class ListPanel extends ImmutablePureComponent { static propTypes = { @@ -53,3 +51,5 @@ class ListPanel extends ImmutablePureComponent { } } + +export default withRouter(connect(mapStateToProps)(ListPanel)); diff --git a/app/javascript/mastodon/features/ui/components/media_modal.js b/app/javascript/mastodon/features/ui/components/media_modal.jsx index 7f50572e7..e8005e67a 100644 --- a/app/javascript/mastodon/features/ui/components/media_modal.js +++ b/app/javascript/mastodon/features/ui/components/media_modal.jsx @@ -3,6 +3,7 @@ import ReactSwipeableViews from 'react-swipeable-views'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import Video from 'mastodon/features/video'; +import { connect } from 'react-redux'; import classNames from 'classnames'; import { defineMessages, injectIntl } from 'react-intl'; import IconButton from 'mastodon/components/icon_button'; @@ -20,7 +21,10 @@ const messages = defineMessages({ next: { id: 'lightbox.next', defaultMessage: 'Next' }, }); -export default @injectIntl +const mapStateToProps = (state, { statusId }) => ({ + language: state.getIn(['statuses', statusId, 'language']), +}); + class MediaModal extends ImmutablePureComponent { static propTypes = { @@ -43,27 +47,27 @@ class MediaModal extends ImmutablePureComponent { handleSwipe = (index) => { this.setState({ index: index % this.props.media.size }); - } + }; handleTransitionEnd = () => { this.setState({ zoomButtonHidden: false, }); - } + }; handleNextClick = () => { this.setState({ index: (this.getIndex() + 1) % this.props.media.size, zoomButtonHidden: true, }); - } + }; handlePrevClick = () => { this.setState({ index: (this.props.media.size + this.getIndex() - 1) % this.props.media.size, zoomButtonHidden: true, }); - } + }; handleChangeIndex = (e) => { const index = Number(e.currentTarget.getAttribute('data-index')); @@ -72,7 +76,7 @@ class MediaModal extends ImmutablePureComponent { index: index % this.props.media.size, zoomButtonHidden: true, }); - } + }; handleKeyDown = (e) => { switch(e.key) { @@ -87,7 +91,7 @@ class MediaModal extends ImmutablePureComponent { e.stopPropagation(); break; } - } + }; componentDidMount () { window.addEventListener('keydown', this.handleKeyDown, false); @@ -110,13 +114,13 @@ class MediaModal extends ImmutablePureComponent { }; render () { - const { media, statusId, intl, onClose } = this.props; + const { media, language, statusId, intl, onClose } = this.props; const { navigationHidden } = this.state; const index = this.getIndex(); - const leftNav = media.size > 1 && <button tabIndex='0' className='media-modal__nav media-modal__nav--left' onClick={this.handlePrevClick} aria-label={intl.formatMessage(messages.previous)}><Icon id='chevron-left' fixedWidth /></button>; - const rightNav = media.size > 1 && <button tabIndex='0' className='media-modal__nav media-modal__nav--right' onClick={this.handleNextClick} aria-label={intl.formatMessage(messages.next)}><Icon id='chevron-right' fixedWidth /></button>; + const leftNav = media.size > 1 && <button tabIndex={0} className='media-modal__nav media-modal__nav--left' onClick={this.handlePrevClick} aria-label={intl.formatMessage(messages.previous)}><Icon id='chevron-left' fixedWidth /></button>; + const rightNav = media.size > 1 && <button tabIndex={0} className='media-modal__nav media-modal__nav--right' onClick={this.handleNextClick} aria-label={intl.formatMessage(messages.next)}><Icon id='chevron-right' fixedWidth /></button>; const content = media.map((image) => { const width = image.getIn(['meta', 'original', 'width']) || null; @@ -130,6 +134,7 @@ class MediaModal extends ImmutablePureComponent { width={width} height={height} alt={image.get('description')} + lang={language} key={image.get('url')} onClick={this.toggleNavigation} zoomButtonHidden={this.state.zoomButtonHidden} @@ -152,6 +157,7 @@ class MediaModal extends ImmutablePureComponent { onCloseVideo={onClose} detailed alt={image.get('description')} + lang={language} key={image.get('url')} /> ); @@ -163,6 +169,7 @@ class MediaModal extends ImmutablePureComponent { height={height} key={image.get('preview_url')} alt={image.get('description')} + lang={language} onClick={this.toggleNavigation} /> ); @@ -229,3 +236,5 @@ class MediaModal extends ImmutablePureComponent { } } + +export default connect(mapStateToProps, null, null, { forwardRef: true })(injectIntl(MediaModal)); diff --git a/app/javascript/mastodon/features/ui/components/modal_loading.js b/app/javascript/mastodon/features/ui/components/modal_loading.jsx index f403ca4c9..f403ca4c9 100644 --- a/app/javascript/mastodon/features/ui/components/modal_loading.js +++ b/app/javascript/mastodon/features/ui/components/modal_loading.jsx diff --git a/app/javascript/mastodon/features/ui/components/modal_root.js b/app/javascript/mastodon/features/ui/components/modal_root.jsx index 6c4aabae5..c252e6caa 100644 --- a/app/javascript/mastodon/features/ui/components/modal_root.js +++ b/app/javascript/mastodon/features/ui/components/modal_root.jsx @@ -73,23 +73,23 @@ export default class ModalRoot extends React.PureComponent { document.documentElement.style.marginRight = `${getScrollbarWidth()}px`; } else { document.body.classList.remove('with-modals--active'); - document.documentElement.style.marginRight = 0; + document.documentElement.style.marginRight = '0'; } } setBackgroundColor = color => { this.setState({ backgroundColor: color }); - } + }; renderLoading = modalId => () => { return ['MEDIA', 'VIDEO', 'BOOST', 'CONFIRM', 'ACTIONS'].indexOf(modalId) === -1 ? <ModalLoading /> : null; - } + }; renderError = (props) => { const { onClose } = this.props; return <BundleModalError {...props} onClose={onClose} />; - } + }; handleClose = (ignoreFocus = false) => { const { onClose } = this.props; @@ -102,11 +102,11 @@ export default class ModalRoot extends React.PureComponent { // This would be much smoother with react-intl 3+ and `forwardRef`. } onClose(message, ignoreFocus); - } + }; setModalRef = (c) => { this._modal = c; - } + }; render () { const { type, props, ignoreFocus } = this.props; diff --git a/app/javascript/mastodon/features/ui/components/mute_modal.js b/app/javascript/mastodon/features/ui/components/mute_modal.jsx index d8d8e68c3..fa64bf0f4 100644 --- a/app/javascript/mastodon/features/ui/components/mute_modal.js +++ b/app/javascript/mastodon/features/ui/components/mute_modal.jsx @@ -43,8 +43,6 @@ const mapDispatchToProps = dispatch => { }; }; -export default @connect(mapStateToProps, mapDispatchToProps) -@injectIntl class MuteModal extends React.PureComponent { static propTypes = { @@ -65,23 +63,23 @@ class MuteModal extends React.PureComponent { handleClick = () => { this.props.onClose(); this.props.onConfirm(this.props.account, this.props.notifications, this.props.muteDuration); - } + }; handleCancel = () => { this.props.onClose(); - } + }; setRef = (c) => { this.button = c; - } + }; toggleNotifications = () => { this.props.onToggleNotifications(); - } + }; changeMuteDuration = (e) => { this.props.onChangeMuteDuration(e); - } + }; render () { const { account, notifications, muteDuration, intl } = this.props; @@ -138,3 +136,5 @@ class MuteModal extends React.PureComponent { } } + +export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(MuteModal)); diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.js b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx index 9a9309be0..ee1a83cc6 100644 --- a/app/javascript/mastodon/features/ui/components/navigation_panel.js +++ b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx @@ -18,7 +18,7 @@ const messages = defineMessages({ explore: { id: 'explore.title', defaultMessage: 'Explore' }, local: { id: 'tabs_bar.local_timeline', defaultMessage: 'Local' }, federated: { id: 'tabs_bar.federated_timeline', defaultMessage: 'Federated' }, - direct: { id: 'navigation_bar.direct', defaultMessage: 'Direct messages' }, + direct: { id: 'navigation_bar.direct', defaultMessage: 'Private mentions' }, favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' }, bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' }, lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' }, @@ -28,7 +28,6 @@ const messages = defineMessages({ search: { id: 'navigation_bar.search', defaultMessage: 'Search' }, }); -export default @injectIntl class NavigationPanel extends React.Component { static contextTypes = { @@ -82,8 +81,8 @@ class NavigationPanel extends React.Component { {signedIn && ( <React.Fragment> <ColumnLink transparent to='/conversations' icon='at' text={intl.formatMessage(messages.direct)} /> - <ColumnLink transparent to='/favourites' icon='star' text={intl.formatMessage(messages.favourites)} /> <ColumnLink transparent to='/bookmarks' icon='bookmark' text={intl.formatMessage(messages.bookmarks)} /> + <ColumnLink transparent to='/favourites' icon='star' text={intl.formatMessage(messages.favourites)} /> <ColumnLink transparent to='/lists' icon='list-ul' text={intl.formatMessage(messages.lists)} /> <ListPanel /> @@ -105,3 +104,5 @@ class NavigationPanel extends React.Component { } } + +export default injectIntl(NavigationPanel); diff --git a/app/javascript/mastodon/features/ui/components/report_modal.js b/app/javascript/mastodon/features/ui/components/report_modal.jsx index 264da07ce..8b505b8bd 100644 --- a/app/javascript/mastodon/features/ui/components/report_modal.js +++ b/app/javascript/mastodon/features/ui/components/report_modal.jsx @@ -30,8 +30,6 @@ const makeMapStateToProps = () => { return mapStateToProps; }; -export default @connect(makeMapStateToProps) -@injectIntl class ReportModal extends ImmutablePureComponent { static propTypes = { @@ -95,7 +93,7 @@ class ReportModal extends ImmutablePureComponent { } else { this.setState({ selectedRuleIds: selectedRuleIds.remove(ruleId) }); } - } + }; handleChangeCategory = category => { this.setState({ category }); @@ -217,3 +215,5 @@ class ReportModal extends ImmutablePureComponent { } } + +export default connect(makeMapStateToProps)(injectIntl(ReportModal)); diff --git a/app/javascript/mastodon/features/ui/components/sign_in_banner.js b/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx index 8bd32edf9..86fcc11b5 100644 --- a/app/javascript/mastodon/features/ui/components/sign_in_banner.js +++ b/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx @@ -30,7 +30,7 @@ const SignInBanner = () => { return ( <div className='sign-in-banner'> - <p><FormattedMessage id='sign_in_banner.text' defaultMessage='Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.' /></p> + <p><FormattedMessage id='sign_in_banner.text' defaultMessage='Sign in to follow profiles or hashtags, favourite, share and reply to posts. You can also interact from your account on a different server.' /></p> <a href='/auth/sign_in' className='button button--block'><FormattedMessage id='sign_in_banner.sign_in' defaultMessage='Sign in' /></a> {signupButton} </div> diff --git a/app/javascript/mastodon/features/ui/components/upload_area.js b/app/javascript/mastodon/features/ui/components/upload_area.jsx index 6c423b2c1..035fe7a26 100644 --- a/app/javascript/mastodon/features/ui/components/upload_area.js +++ b/app/javascript/mastodon/features/ui/components/upload_area.jsx @@ -22,7 +22,7 @@ export default class UploadArea extends React.PureComponent { break; } } - } + }; componentDidMount () { window.addEventListener('keyup', this.handleKeyUp, false); diff --git a/app/javascript/mastodon/features/ui/components/video_modal.js b/app/javascript/mastodon/features/ui/components/video_modal.jsx index a1533eba0..0e754ccc7 100644 --- a/app/javascript/mastodon/features/ui/components/video_modal.js +++ b/app/javascript/mastodon/features/ui/components/video_modal.jsx @@ -2,15 +2,21 @@ import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import Video from 'mastodon/features/video'; +import { connect } from 'react-redux'; import ImmutablePureComponent from 'react-immutable-pure-component'; import Footer from 'mastodon/features/picture_in_picture/components/footer'; import { getAverageFromBlurhash } from 'mastodon/blurhash'; -export default class VideoModal extends ImmutablePureComponent { +const mapStateToProps = (state, { statusId }) => ({ + language: state.getIn(['statuses', statusId, 'language']), +}); + +class VideoModal extends ImmutablePureComponent { static propTypes = { media: ImmutablePropTypes.map.isRequired, statusId: PropTypes.string, + language: PropTypes.string, options: PropTypes.shape({ startTime: PropTypes.number, autoPlay: PropTypes.bool, @@ -25,7 +31,7 @@ export default class VideoModal extends ImmutablePureComponent { } render () { - const { media, statusId, onClose } = this.props; + const { media, statusId, language, onClose } = this.props; const options = this.props.options || {}; return ( @@ -43,6 +49,7 @@ export default class VideoModal extends ImmutablePureComponent { autoFocus detailed alt={media.get('description')} + lang={language} /> </div> @@ -54,3 +61,5 @@ export default class VideoModal extends ImmutablePureComponent { } } + +export default connect(mapStateToProps, null, null, { forwardRef: true })(VideoModal); diff --git a/app/javascript/mastodon/features/ui/components/zoomable_image.js b/app/javascript/mastodon/features/ui/components/zoomable_image.jsx index 1cf263cb9..b41d0fe31 100644 --- a/app/javascript/mastodon/features/ui/components/zoomable_image.js +++ b/app/javascript/mastodon/features/ui/components/zoomable_image.jsx @@ -91,21 +91,22 @@ const normalizeWheel = event => { }; }; -export default @injectIntl class ZoomableImage extends React.PureComponent { static propTypes = { alt: PropTypes.string, + lang: PropTypes.string, src: PropTypes.string.isRequired, width: PropTypes.number, height: PropTypes.number, onClick: PropTypes.func, zoomButtonHidden: PropTypes.bool, intl: PropTypes.object.isRequired, - } + }; static defaultProps = { alt: '', + lang: '', width: null, height: null, }; @@ -132,7 +133,7 @@ class ZoomableImage extends React.PureComponent { dragged: false, lockScroll: { x: 0, y: 0 }, lockTranslate: { x: 0, y: 0 }, - } + }; removers = []; container = null; @@ -212,7 +213,7 @@ class ZoomableImage extends React.PureComponent { // lock horizontal scroll this.container.scrollLeft = Math.max(this.container.scrollLeft + event.pixelX, this.state.lockScroll.x); - } + }; mouseDownHandler = e => { this.container.style.cursor = 'grabbing'; @@ -228,7 +229,7 @@ class ZoomableImage extends React.PureComponent { this.image.addEventListener('mousemove', this.mouseMoveHandler); this.image.addEventListener('mouseup', this.mouseUpHandler); - } + }; mouseMoveHandler = e => { const dx = e.clientX - this.state.dragPosition.x; @@ -238,7 +239,7 @@ class ZoomableImage extends React.PureComponent { this.container.scrollTop = Math.max(this.state.dragPosition.top - dy, this.state.lockScroll.y); this.setState({ dragged: true }); - } + }; mouseUpHandler = () => { this.container.style.cursor = 'grab'; @@ -246,13 +247,13 @@ class ZoomableImage extends React.PureComponent { this.image.removeEventListener('mousemove', this.mouseMoveHandler); this.image.removeEventListener('mouseup', this.mouseUpHandler); - } + }; handleTouchStart = e => { if (e.touches.length !== 2) return; this.lastDistance = getDistance(...e.touches); - } + }; handleTouchMove = e => { const { scrollTop, scrollHeight, clientHeight } = this.container; @@ -275,7 +276,7 @@ class ZoomableImage extends React.PureComponent { this.lastMidpoint = midpoint; this.lastDistance = distance; - } + }; zoom(nextScale, midpoint) { const { scale, zoomMatrix } = this.state; @@ -314,11 +315,11 @@ class ZoomableImage extends React.PureComponent { const handler = this.props.onClick; if (handler) handler(); this.setState({ navigationHidden: !this.state.navigationHidden }); - } + }; handleMouseDown = e => { e.preventDefault(); - } + }; initZoomMatrix = () => { const { width, height } = this.props; @@ -350,7 +351,7 @@ class ZoomableImage extends React.PureComponent { translateY: translateY, }, }); - } + }; handleZoomClick = e => { e.preventDefault(); @@ -392,18 +393,18 @@ class ZoomableImage extends React.PureComponent { this.container.style.cursor = 'grab'; this.container.style.removeProperty('user-select'); - } + }; setContainerRef = c => { this.container = c; - } + }; setImageRef = c => { this.image = c; - } + }; render () { - const { alt, src, width, height, intl } = this.props; + const { alt, lang, src, width, height, intl } = this.props; const { scale, lockTranslate } = this.state; const overflow = scale === MIN_SCALE ? 'hidden' : 'scroll'; const zoomButtonShouldHide = this.state.navigationHidden || this.props.zoomButtonHidden || this.state.zoomMatrix.rate <= MIN_SCALE ? 'media-modal__zoom-button--hidden' : ''; @@ -431,6 +432,7 @@ class ZoomableImage extends React.PureComponent { ref={this.setImageRef} alt={alt} title={alt} + lang={lang} src={src} width={width} height={height} @@ -448,3 +450,5 @@ class ZoomableImage extends React.PureComponent { } } + +export default injectIntl(ZoomableImage); |