+
{
@@ -263,5 +262,3 @@ class ActionBar extends PureComponent {
}
}
-
-export default injectIntl(ActionBar);
diff --git a/app/javascript/flavours/glitch/features/status/components/card.jsx b/app/javascript/flavours/glitch/features/status/components/card.jsx
index 632d84ed3..359dbbc20 100644
--- a/app/javascript/flavours/glitch/features/status/components/card.jsx
+++ b/app/javascript/flavours/glitch/features/status/components/card.jsx
@@ -1,17 +1,15 @@
+import React from 'react';
import PropTypes from 'prop-types';
-import { PureComponent } from 'react';
-
-import { FormattedMessage } from 'react-intl';
-
-import classnames from 'classnames';
-
import Immutable from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes';
-
-import { Blurhash } from 'flavours/glitch/components/blurhash';
-import { Icon } from 'flavours/glitch/components/icon';
-import { useBlurhash } from 'flavours/glitch/initial_state';
+import { FormattedMessage } from 'react-intl';
+import punycode from 'punycode';
+import classnames from 'classnames';
import { decode as decodeIDNA } from 'flavours/glitch/utils/idna';
+import Icon from 'flavours/glitch/components/icon';
+import { useBlurhash } from 'flavours/glitch/initial_state';
+import Blurhash from 'flavours/glitch/components/blurhash';
+import { debounce } from 'lodash';
const getHostname = url => {
const parser = document.createElement('a');
@@ -19,6 +17,16 @@ const getHostname = url => {
return parser.hostname;
};
+const trim = (text, len) => {
+ const cut = text.indexOf(' ', len);
+
+ if (cut === -1) {
+ return text;
+ }
+
+ return text.slice(0, cut) + (text.length > len ? '…' : '');
+};
+
const domParser = new DOMParser();
const addAutoPlay = html => {
@@ -42,26 +50,31 @@ const addAutoPlay = html => {
return html;
};
-export default class Card extends PureComponent {
+export default class Card extends React.PureComponent {
static propTypes = {
card: ImmutablePropTypes.map,
+ maxDescription: PropTypes.number,
onOpenMedia: PropTypes.func.isRequired,
compact: PropTypes.bool,
+ defaultWidth: PropTypes.number,
+ cacheWidth: PropTypes.func,
sensitive: PropTypes.bool,
};
static defaultProps = {
+ maxDescription: 50,
compact: false,
};
state = {
+ width: this.props.defaultWidth || 280,
previewLoaded: false,
embedded: false,
revealed: !this.props.sensitive,
};
- UNSAFE_componentWillReceiveProps (nextProps) {
+ componentWillReceiveProps (nextProps) {
if (!Immutable.is(this.props.card, nextProps.card)) {
this.setState({ embedded: false, previewLoaded: false });
}
@@ -78,6 +91,24 @@ export default class Card extends PureComponent {
window.removeEventListener('resize', this.handleResize);
}
+ _setDimensions () {
+ const width = this.node.offsetWidth;
+
+ if (this.props.cacheWidth) {
+ this.props.cacheWidth(width);
+ }
+
+ this.setState({ width });
+ }
+
+ handleResize = debounce(() => {
+ if (this.node) {
+ this._setDimensions();
+ }
+ }, 250, {
+ trailing: true,
+ });
+
handlePhotoClick = () => {
const { card, onOpenMedia } = this.props;
@@ -111,6 +142,10 @@ export default class Card extends PureComponent {
setRef = c => {
this.node = c;
+
+ if (this.node) {
+ this._setDimensions();
+ }
};
handleImageLoad = () => {
@@ -126,48 +161,45 @@ export default class Card extends PureComponent {
renderVideo () {
const { card } = this.props;
const content = { __html: addAutoPlay(card.get('html')) };
+ const { width } = this.state;
+ const ratio = card.get('width') / card.get('height');
+ const height = width / ratio;
return (
);
}
render () {
- const { card, compact } = this.props;
- const { embedded, revealed } = this.state;
+ const { card, maxDescription, compact, defaultWidth } = this.props;
+ const { width, embedded, revealed } = this.state;
if (card === null) {
return null;
}
const provider = card.get('provider_name').length === 0 ? decodeIDNA(getHostname(card.get('url'))) : card.get('provider_name');
- const horizontal = (!compact && card.get('width') > card.get('height')) || card.get('type') !== 'link' || embedded;
+ const horizontal = (!compact && card.get('width') > card.get('height') && (card.get('width') + 100 >= width)) || card.get('type') !== 'link' || embedded;
const interactive = card.get('type') !== 'link';
const className = classnames('status-card', { horizontal, compact, interactive });
const title = interactive ?
{card.get('title')} :
{card.get('title')};
const language = card.get('language') || '';
+ const ratio = card.get('width') / card.get('height');
+ const height = (compact && !embedded) ? (width / (16 / 9)) : (width / ratio);
const description = (
{title}
- {!(horizontal || compact) &&
{card.get('description')}
}
+ {!(horizontal || compact) &&
{trim(card.get('description') || '', maxDescription)}
}
{provider}
);
- const thumbnailStyle = {
- visibility: revealed? null : 'hidden',
- };
-
- if (horizontal) {
- thumbnailStyle.aspectRatio = (compact && !embedded) ? '16 / 9' : `${card.get('width')} / ${card.get('height')}`;
- }
-
let embed = '';
let canvas = (
);
- let thumbnail =
;
+ let thumbnail =
;
let spoilerButton = (
@@ -353,5 +347,3 @@ class DetailedStatus extends ImmutablePureComponent {
}
}
-
-export default injectIntl(DetailedStatus);
diff --git a/app/javascript/flavours/glitch/features/status/containers/detailed_status_container.js b/app/javascript/flavours/glitch/features/status/containers/detailed_status_container.js
index 96d9090da..087316401 100644
--- a/app/javascript/flavours/glitch/features/status/containers/detailed_status_container.js
+++ b/app/javascript/flavours/glitch/features/status/containers/detailed_status_container.js
@@ -1,12 +1,9 @@
-import { defineMessages, injectIntl } from 'react-intl';
-
import { connect } from 'react-redux';
-
-import { showAlertForError } from 'flavours/glitch/actions/alerts';
-import { initBlockModal } from 'flavours/glitch/actions/blocks';
-import { initBoostModal } from 'flavours/glitch/actions/boosts';
+import DetailedStatus from '../components/detailed_status';
+import { makeGetStatus } from 'flavours/glitch/selectors';
import {
replyCompose,
+ quoteCompose,
mentionCompose,
directCompose,
} from 'flavours/glitch/actions/compose';
@@ -18,22 +15,27 @@ import {
pin,
unpin,
} from 'flavours/glitch/actions/interactions';
-import { openModal } from 'flavours/glitch/actions/modal';
-import { initMuteModal } from 'flavours/glitch/actions/mutes';
-import { initReport } from 'flavours/glitch/actions/reports';
import {
muteStatus,
unmuteStatus,
deleteStatus,
+ hideStatus,
+ revealStatus,
} from 'flavours/glitch/actions/statuses';
+import { initMuteModal } from 'flavours/glitch/actions/mutes';
+import { initBlockModal } from 'flavours/glitch/actions/blocks';
+import { initReport } from 'flavours/glitch/actions/reports';
+import { initBoostModal } from 'flavours/glitch/actions/boosts';
+import { openModal } from 'flavours/glitch/actions/modal';
+import { defineMessages, injectIntl } from 'react-intl';
import { boostModal, deleteModal } from 'flavours/glitch/initial_state';
-import { makeGetStatus } from 'flavours/glitch/selectors';
-
-import DetailedStatus from '../components/detailed_status';
+import { showAlertForError } from 'flavours/glitch/actions/alerts';
const messages = defineMessages({
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
+ quoteConfirm: { id: 'confirmations.quote.confirm', defaultMessage: 'Quote' },
+ quoteMessage: { id: 'confirmations.quote.message', defaultMessage: 'Quoting now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.' },
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
@@ -58,13 +60,10 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
dispatch((_, getState) => {
let state = getState();
if (state.getIn(['compose', 'text']).trim().length !== 0) {
- dispatch(openModal({
- modalType: 'CONFIRM',
- modalProps: {
- message: intl.formatMessage(messages.replyMessage),
- confirm: intl.formatMessage(messages.replyConfirm),
- onConfirm: () => dispatch(replyCompose(status, router)),
- },
+ dispatch(openModal('CONFIRM', {
+ message: intl.formatMessage(messages.replyMessage),
+ confirm: intl.formatMessage(messages.replyConfirm),
+ onConfirm: () => dispatch(replyCompose(status, router)),
}));
} else {
dispatch(replyCompose(status, router));
@@ -72,6 +71,21 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
});
},
+ onQuote (status, router) {
+ dispatch((_, getState) => {
+ let state = getState();
+ if (state.getIn(['compose', 'text']).trim().length !== 0) {
+ dispatch(openModal('CONFIRM', {
+ message: intl.formatMessage(messages.quoteMessage),
+ confirm: intl.formatMessage(messages.quoteConfirm),
+ onConfirm: () => dispatch(quoteCompose(status, router)),
+ }));
+ } else {
+ dispatch(quoteCompose(status, router));
+ }
+ });
+ },
+
onModalReblog (status, privacy) {
dispatch(reblog(status, privacy));
},
@@ -105,12 +119,9 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
},
onEmbed (status) {
- dispatch(openModal({
- modalType: 'EMBED',
- modalProps: {
- url: status.get('url'),
- onError: error => dispatch(showAlertForError(error)),
- },
+ dispatch(openModal('EMBED', {
+ url: status.get('url'),
+ onError: error => dispatch(showAlertForError(error)),
}));
},
@@ -118,13 +129,10 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
if (!deleteModal) {
dispatch(deleteStatus(status.get('id'), history, withRedraft));
} else {
- dispatch(openModal({
- modalType: 'CONFIRM',
- modalProps: {
- message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
- confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
- onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)),
- },
+ dispatch(openModal('CONFIRM', {
+ message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
+ confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
+ onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)),
}));
}
},
@@ -137,18 +145,12 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
dispatch(mentionCompose(account, router));
},
- onOpenMedia (media, index, lang) {
- dispatch(openModal({
- modalType: 'MEDIA',
- modalProps: { media, index, lang },
- }));
+ onOpenMedia (media, index) {
+ dispatch(openModal('MEDIA', { media, index }));
},
- onOpenVideo (media, lang, options) {
- dispatch(openModal({
- modalType: 'VIDEO',
- modalProps: { media, lang, options },
- }));
+ onOpenVideo (media, options) {
+ dispatch(openModal('VIDEO', { media, options }));
},
onBlock (status) {
diff --git a/app/javascript/flavours/glitch/features/status/index.jsx b/app/javascript/flavours/glitch/features/status/index.jsx
index f6b01605a..7298a1879 100644
--- a/app/javascript/flavours/glitch/features/status/index.jsx
+++ b/app/javascript/flavours/glitch/features/status/index.jsx
@@ -1,25 +1,26 @@
-import PropTypes from 'prop-types';
-
-import { defineMessages, injectIntl } from 'react-intl';
-
-import classNames from 'classnames';
-import { Helmet } from 'react-helmet';
-
import Immutable from 'immutable';
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import ImmutablePureComponent from 'react-immutable-pure-component';
+import React from 'react';
import { connect } from 'react-redux';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import ImmutablePropTypes from 'react-immutable-proptypes';
import { createSelector } from 'reselect';
-
-import { HotKeys } from 'react-hotkeys';
-
-import { initBlockModal } from 'flavours/glitch/actions/blocks';
-import { initBoostModal } from 'flavours/glitch/actions/boosts';
import {
- replyCompose,
- mentionCompose,
- directCompose,
-} from 'flavours/glitch/actions/compose';
+ fetchStatus,
+ muteStatus,
+ unmuteStatus,
+ deleteStatus,
+ editStatus,
+ hideStatus,
+ revealStatus,
+ translateStatus,
+ undoStatusTranslation,
+} from 'flavours/glitch/actions/statuses';
+import MissingIndicator from 'flavours/glitch/components/missing_indicator';
+import LoadingIndicator from 'flavours/glitch/components/loading_indicator';
+import DetailedStatus from './components/detailed_status';
+import ActionBar from './components/action_bar';
+import Column from 'flavours/glitch/features/ui/components/column';
import {
favourite,
unfavourite,
@@ -32,46 +33,40 @@ import {
addReaction,
removeReaction,
} from 'flavours/glitch/actions/interactions';
-import { changeLocalSetting } from 'flavours/glitch/actions/local_settings';
-import { openModal } from 'flavours/glitch/actions/modal';
-import { initMuteModal } from 'flavours/glitch/actions/mutes';
-import { initReport } from 'flavours/glitch/actions/reports';
import {
- fetchStatus,
- muteStatus,
- unmuteStatus,
- deleteStatus,
- editStatus,
- hideStatus,
- revealStatus,
- translateStatus,
- undoStatusTranslation,
-} from 'flavours/glitch/actions/statuses';
-import { Icon } from 'flavours/glitch/components/icon';
-import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator';
-import { textForScreenReader, defaultMediaVisibility } from 'flavours/glitch/components/status';
+ replyCompose,
+ quoteCompose,
+ mentionCompose,
+ directCompose,
+} from 'flavours/glitch/actions/compose';
+import { changeLocalSetting } from 'flavours/glitch/actions/local_settings';
+import { initMuteModal } from 'flavours/glitch/actions/mutes';
+import { initBlockModal } from 'flavours/glitch/actions/blocks';
+import { initReport } from 'flavours/glitch/actions/reports';
+import { initBoostModal } from 'flavours/glitch/actions/boosts';
+import { makeCustomEmojiMap, makeGetStatus, makeGetPictureInPicture } from 'flavours/glitch/selectors';
import ScrollContainer from 'flavours/glitch/containers/scroll_container';
-import StatusContainer from 'flavours/glitch/containers/status_container';
-import BundleColumnError from 'flavours/glitch/features/ui/components/bundle_column_error';
-import Column from 'flavours/glitch/features/ui/components/column';
-import { boostModal, favouriteModal, deleteModal } from 'flavours/glitch/initial_state';
-import { makeGetStatus, makeGetPictureInPicture } from 'flavours/glitch/selectors';
-import { autoUnfoldCW } from 'flavours/glitch/utils/content_warning';
-
+import ColumnBackButton from 'flavours/glitch/components/column_back_button';
import ColumnHeader from '../../components/column_header';
+import StatusContainer from 'flavours/glitch/containers/status_container';
+import { openModal } from 'flavours/glitch/actions/modal';
+import { defineMessages, injectIntl } from 'react-intl';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import { HotKeys } from 'react-hotkeys';
+import { boostModal, favouriteModal, deleteModal } from 'flavours/glitch/initial_state';
import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../ui/util/fullscreen';
-
-import ActionBar from './components/action_bar';
-import DetailedStatus from './components/detailed_status';
+import { autoUnfoldCW } from 'flavours/glitch/utils/content_warning';
+import { textForScreenReader, defaultMediaVisibility } from 'flavours/glitch/components/status';
+import Icon from 'flavours/glitch/components/icon';
+import { Helmet } from 'react-helmet';
const messages = defineMessages({
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
- redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.' },
+ redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.' },
revealAll: { id: 'status.show_more_all', defaultMessage: 'Show more for all' },
hideAll: { id: 'status.show_less_all', defaultMessage: 'Show less for all' },
- statusTitleWithAttachments: { id: 'status.title.with_attachments', defaultMessage: '{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}' },
detailedStatus: { id: 'status.detailed_status', defaultMessage: 'Detailed conversation view' },
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
@@ -156,6 +151,7 @@ const makeMapStateToProps = () => {
askReplyConfirmation: state.getIn(['local_settings', 'confirm_before_clearing_draft']) && state.getIn(['compose', 'text']).trim().length !== 0,
domain: state.getIn(['meta', 'domain']),
pictureInPicture: getPictureInPicture(state, { id: props.params.statusId }),
+ emojiMap: makeCustomEmojiMap(state),
};
};
@@ -163,24 +159,24 @@ const makeMapStateToProps = () => {
};
const truncate = (str, num) => {
- const arr = Array.from(str);
- if (arr.length > num) {
- return arr.slice(0, num).join('') + '…';
+ if (str.length > num) {
+ return str.slice(0, num) + '…';
} else {
return str;
}
};
-const titleFromStatus = (intl, status) => {
+const titleFromStatus = status => {
const displayName = status.getIn(['account', 'display_name']);
const username = status.getIn(['account', 'username']);
- const user = displayName.trim().length === 0 ? username : displayName;
+ const prefix = displayName.trim().length === 0 ? username : displayName;
const text = status.get('search_index');
- const attachmentCount = status.get('media_attachments').size;
- return text ? `${user}: "${truncate(text, 30)}"` : intl.formatMessage(messages.statusTitleWithAttachments, { user, attachmentCount });
+ return `${prefix}: "${truncate(text, 30)}"`;
};
+export default @injectIntl
+@connect(makeMapStateToProps)
class Status extends ImmutablePureComponent {
static contextTypes = {
@@ -292,23 +288,14 @@ class Status extends ImmutablePureComponent {
if ((e && e.shiftKey) || !favouriteModal) {
this.handleModalFavourite(status);
} else {
- dispatch(openModal({
- modalType: 'FAVOURITE',
- modalProps: {
- status,
- onFavourite: this.handleModalFavourite,
- },
- }));
+ dispatch(openModal('FAVOURITE', { status, onFavourite: this.handleModalFavourite }));
}
}
} else {
- dispatch(openModal({
- modalType: 'INTERACTION',
- modalProps: {
- type: 'favourite',
- accountId: status.getIn(['account', 'id']),
- url: status.get('url'),
- },
+ dispatch(openModal('INTERACTION', {
+ type: 'favourite',
+ accountId: status.getIn(['account', 'id']),
+ url: status.get('url'),
}));
}
};
@@ -320,11 +307,11 @@ class Status extends ImmutablePureComponent {
if (signedIn) {
dispatch(addReaction(statusId, name, url));
}
- };
+ }
handleReactionRemove = (statusId, name) => {
this.props.dispatch(removeReaction(statusId, name));
- };
+ }
handlePin = (status) => {
if (status.get('pinned')) {
@@ -340,30 +327,39 @@ class Status extends ImmutablePureComponent {
if (signedIn) {
if (askReplyConfirmation) {
- dispatch(openModal({
- modalType: 'CONFIRM',
- modalProps: {
- message: intl.formatMessage(messages.replyMessage),
- confirm: intl.formatMessage(messages.replyConfirm),
- onDoNotAsk: () => dispatch(changeLocalSetting(['confirm_before_clearing_draft'], false)),
- onConfirm: () => dispatch(replyCompose(status, this.context.router.history)),
- },
+ dispatch(openModal('CONFIRM', {
+ message: intl.formatMessage(messages.replyMessage),
+ confirm: intl.formatMessage(messages.replyConfirm),
+ onDoNotAsk: () => dispatch(changeLocalSetting(['confirm_before_clearing_draft'], false)),
+ onConfirm: () => dispatch(replyCompose(status, this.context.router.history)),
}));
} else {
dispatch(replyCompose(status, this.context.router.history));
}
} else {
- dispatch(openModal({
- modalType: 'INTERACTION',
- modalProps: {
- type: 'reply',
- accountId: status.getIn(['account', 'id']),
- url: status.get('url'),
- },
+ dispatch(openModal('INTERACTION', {
+ type: 'reply',
+ accountId: status.getIn(['account', 'id']),
+ url: status.get('url'),
}));
}
};
+ handleQuoteClick = (status) => {
+ const { dispatch } = this.props;
+ const { signedIn } = this.context.identity;
+
+ if (signedIn) {
+ dispatch(quoteCompose(status, this.context.router.history));
+ } else {
+ dispatch(openModal('INTERACTION', {
+ type: 'reply',
+ accountId: status.getIn(['account', 'id']),
+ url: status.get('url'),
+ }));
+ }
+ }
+
handleModalReblog = (status, privacy) => {
const { dispatch } = this.props;
@@ -387,13 +383,10 @@ class Status extends ImmutablePureComponent {
dispatch(initBoostModal({ status, onReblog: this.handleModalReblog }));
}
} else {
- dispatch(openModal({
- modalType: 'INTERACTION',
- modalProps: {
- type: 'reblog',
- accountId: status.getIn(['account', 'id']),
- url: status.get('url'),
- },
+ dispatch(openModal('INTERACTION', {
+ type: 'reblog',
+ accountId: status.getIn(['account', 'id']),
+ url: status.get('url'),
}));
}
};
@@ -412,13 +405,10 @@ class Status extends ImmutablePureComponent {
if (!deleteModal) {
dispatch(deleteStatus(status.get('id'), history, withRedraft));
} else {
- dispatch(openModal({
- modalType: 'CONFIRM',
- modalProps: {
- message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
- confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
- onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)),
- },
+ dispatch(openModal('CONFIRM', {
+ message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
+ confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
+ onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)),
}));
}
};
@@ -435,18 +425,12 @@ class Status extends ImmutablePureComponent {
this.props.dispatch(mentionCompose(account, router));
};
- handleOpenMedia = (media, index, lang) => {
- this.props.dispatch(openModal({
- modalType: 'MEDIA',
- modalProps: { statusId: this.props.status.get('id'), media, index, lang },
- }));
+ handleOpenMedia = (media, index) => {
+ this.props.dispatch(openModal('MEDIA', { statusId: this.props.status.get('id'), media, index }));
};
- handleOpenVideo = (media, lang, options) => {
- this.props.dispatch(openModal({
- modalType: 'VIDEO',
- modalProps: { statusId: this.props.status.get('id'), media, lang, options },
- }));
+ handleOpenVideo = (media, options) => {
+ this.props.dispatch(openModal('VIDEO', { statusId: this.props.status.get('id'), media, options }));
};
handleHotkeyOpenMedia = e => {
@@ -496,7 +480,7 @@ class Status extends ImmutablePureComponent {
const { dispatch } = this.props;
if (status.get('translation')) {
- dispatch(undoStatusTranslation(status.get('id'), status.get('poll')));
+ dispatch(undoStatusTranslation(status.get('id')));
} else {
dispatch(translateStatus(status.get('id')));
}
@@ -513,10 +497,7 @@ class Status extends ImmutablePureComponent {
};
handleEmbed = (status) => {
- this.props.dispatch(openModal({
- modalType: 'EMBED',
- modalProps: { url: status.get('url') },
- }));
+ this.props.dispatch(openModal('EMBED', { url: status.get('url') }));
};
handleHotkeyToggleSensitive = () => {
@@ -554,7 +535,9 @@ class Status extends ImmutablePureComponent {
};
handleHotkeyOpenProfile = () => {
- this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
+ let state = { ...this.context.router.history.location.state };
+ state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
+ this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`, state);
};
handleMoveUp = id => {
@@ -609,10 +592,8 @@ class Status extends ImmutablePureComponent {
this.column.scrollTop();
};
- renderChildren (list, ancestors) {
- const { params: { statusId } } = this.props;
-
- return list.map((id, i) => (
+ renderChildren (list) {
+ return list.map(id => (
0 && list.get(i - 1)}
- nextId={list.get(i + 1) || (ancestors && statusId)}
- rootId={statusId}
/>
));
}
@@ -676,18 +654,21 @@ class Status extends ImmutablePureComponent {
if (status === null) {
return (
-
+
+
+
+
);
}
const isExpanded = settings.getIn(['content_warnings', 'shared_state']) ? !status.get('hidden') : this.state.isExpanded;
if (ancestorsIds && ancestorsIds.size > 0) {
- ancestors = <>{this.renderChildren(ancestorsIds, true)}>;
+ ancestors = {this.renderChildren(ancestorsIds)}
;
}
if (descendantsIds && descendantsIds.size > 0) {
- descendants = <>{this.renderChildren(descendantsIds)}>;
+ descendants = {this.renderChildren(descendantsIds)}
;
}
const isLocal = status.getIn(['account', 'acct'], '').indexOf('@') === -1;
@@ -725,7 +706,7 @@ class Status extends ImmutablePureComponent {
{ancestors}
-
+
- {titleFromStatus(intl, status)}
+ {titleFromStatus(status)}
@@ -778,5 +761,3 @@ class Status extends ImmutablePureComponent {
}
}
-
-export default injectIntl(connect(makeMapStateToProps)(Status));
diff --git a/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.jsx b/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.jsx
index 9905301e7..35083503c 100644
--- a/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.jsx
+++ b/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.jsx
@@ -1,18 +1,16 @@
+import React from 'react';
import PropTypes from 'prop-types';
-
-import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
-
-import { is, List as ImmutableList, Set as ImmutableSet } from 'immutable';
-import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
+import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
-
-import { followAccount } from 'flavours/glitch/actions/accounts';
-import Button from 'flavours/glitch/components/button';
-import { IconButton } from 'flavours/glitch/components/icon_button';
-import Option from 'flavours/glitch/features/report/components/option';
+import { is, List as ImmutableList, Set as ImmutableSet } from 'immutable';
import { languages as preloadedLanguages } from 'flavours/glitch/initial_state';
+import Option from 'flavours/glitch/features/report/components/option';
+import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
+import IconButton from 'flavours/glitch/components/icon_button';
+import Button from 'flavours/glitch/components/button';
+import { followAccount } from 'flavours/glitch/actions/accounts';
const messages = defineMessages({
close: { id: 'lightbox.close', defaultMessage: 'Close' },
@@ -38,6 +36,8 @@ const mapDispatchToProps = (dispatch, { accountId }) => ({
});
+export default @connect(mapStateToProps, mapDispatchToProps)
+@injectIntl
class SubscribedLanguagesModal extends ImmutablePureComponent {
static propTypes = {
@@ -123,5 +123,3 @@ class SubscribedLanguagesModal extends ImmutablePureComponent {
}
}
-
-export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(SubscribedLanguagesModal));
diff --git a/app/javascript/flavours/glitch/features/ui/components/actions_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/actions_modal.jsx
index 5fe914d93..c6e3ee37c 100644
--- a/app/javascript/flavours/glitch/features/ui/components/actions_modal.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/actions_modal.jsx
@@ -1,15 +1,13 @@
+import React from 'react';
import PropTypes from 'prop-types';
-
-import classNames from 'classnames';
-
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
-
-import { Avatar } from 'flavours/glitch/components/avatar';
-import { DisplayName } from 'flavours/glitch/components/display_name';
-import { IconButton } from 'flavours/glitch/components/icon_button';
-import { RelativeTimestamp } from 'flavours/glitch/components/relative_timestamp';
import StatusContent from 'flavours/glitch/components/status_content';
+import Avatar from 'flavours/glitch/components/avatar';
+import RelativeTimestamp from 'flavours/glitch/components/relative_timestamp';
+import DisplayName from 'flavours/glitch/components/display_name';
+import classNames from 'classnames';
+import IconButton from 'flavours/glitch/components/icon_button';
export default class ActionsModal extends ImmutablePureComponent {
@@ -37,13 +35,13 @@ export default class ActionsModal extends ImmutablePureComponent {
if (!contents) {
contents = (
- <>
- {icon && }
+
+ {icon && }
- >
+
);
}
diff --git a/app/javascript/flavours/glitch/features/ui/components/audio_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/audio_modal.jsx
index a6e15e543..ff7687c1e 100644
--- a/app/javascript/flavours/glitch/features/ui/components/audio_modal.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/audio_modal.jsx
@@ -1,23 +1,23 @@
-import PropTypes from 'prop-types';
-
+import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
-import ImmutablePureComponent from 'react-immutable-pure-component';
-import { connect } from 'react-redux';
-
+import PropTypes from 'prop-types';
import Audio from 'flavours/glitch/features/audio';
+import { connect } from 'react-redux';
+import ImmutablePureComponent from 'react-immutable-pure-component';
import Footer from 'flavours/glitch/features/picture_in_picture/components/footer';
const mapStateToProps = (state, { statusId }) => ({
- status: state.getIn(['statuses', statusId]),
+ language: state.getIn(['statuses', statusId, 'language']),
accountStaticAvatar: state.getIn(['accounts', state.getIn(['statuses', statusId, 'account']), 'avatar_static']),
});
+export default @connect(mapStateToProps, null, null, { forwardRef: true })
class AudioModal extends ImmutablePureComponent {
static propTypes = {
media: ImmutablePropTypes.map.isRequired,
statusId: PropTypes.string.isRequired,
- status: ImmutablePropTypes.map.isRequired,
+ language: PropTypes.string,
accountStaticAvatar: PropTypes.string.isRequired,
options: PropTypes.shape({
autoPlay: PropTypes.bool,
@@ -31,17 +31,15 @@ class AudioModal extends ImmutablePureComponent {
};
render () {
- const { media, status, accountStaticAvatar, onClose } = this.props;
+ const { media, language, accountStaticAvatar, statusId, onClose } = this.props;
const options = this.props.options || {};
- const language = status.getIn(['translation', 'language']) || status.get('language');
- const description = media.getIn(['translation', 'description']) || media.get('description');
return (
);
}
}
-
-export default connect(mapStateToProps, null, null, { forwardRef: true })(AudioModal);
diff --git a/app/javascript/flavours/glitch/features/ui/components/block_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/block_modal.jsx
index c2965d617..6c9d2043c 100644
--- a/app/javascript/flavours/glitch/features/ui/components/block_modal.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/block_modal.jsx
@@ -1,15 +1,12 @@
-import PropTypes from 'prop-types';
-import { PureComponent } from 'react';
-
-import { injectIntl, FormattedMessage } from 'react-intl';
-
+import React from 'react';
import { connect } from 'react-redux';
-
-import { blockAccount } from '../../../actions/accounts';
-import { closeModal } from '../../../actions/modal';
-import { initReport } from '../../../actions/reports';
-import Button from '../../../components/button';
+import PropTypes from 'prop-types';
+import { injectIntl, FormattedMessage } from 'react-intl';
import { makeGetAccount } from '../../../selectors';
+import Button from '../../../components/button';
+import { closeModal } from '../../../actions/modal';
+import { blockAccount } from '../../../actions/accounts';
+import { initReport } from '../../../actions/reports';
const makeMapStateToProps = () => {
@@ -34,15 +31,14 @@ const mapDispatchToProps = dispatch => {
},
onClose() {
- dispatch(closeModal({
- modalType: undefined,
- ignoreFocus: false,
- }));
+ dispatch(closeModal());
},
};
};
-class BlockModal extends PureComponent {
+export default @connect(makeMapStateToProps, mapDispatchToProps)
+@injectIntl
+class BlockModal extends React.PureComponent {
static propTypes = {
account: PropTypes.object.isRequired,
@@ -105,5 +101,3 @@ class BlockModal extends PureComponent {
}
}
-
-export default connect(makeMapStateToProps, mapDispatchToProps)(injectIntl(BlockModal));
diff --git a/app/javascript/flavours/glitch/features/ui/components/boost_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/boost_modal.jsx
index b1c424ce3..a65b84e20 100644
--- a/app/javascript/flavours/glitch/features/ui/components/boost_modal.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/boost_modal.jsx
@@ -1,23 +1,20 @@
-import PropTypes from 'prop-types';
-
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-
-import classNames from 'classnames';
-
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import ImmutablePureComponent from 'react-immutable-pure-component';
+import React from 'react';
import { connect } from 'react-redux';
-
-import { changeBoostPrivacy } from 'flavours/glitch/actions/boosts';
-import AttachmentList from 'flavours/glitch/components/attachment_list';
-import { Avatar } from 'flavours/glitch/components/avatar';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import PropTypes from 'prop-types';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import Button from 'flavours/glitch/components/button';
-import { DisplayName } from 'flavours/glitch/components/display_name';
-import { Icon } from 'flavours/glitch/components/icon';
-import { RelativeTimestamp } from 'flavours/glitch/components/relative_timestamp';
import StatusContent from 'flavours/glitch/components/status_content';
-import VisibilityIcon from 'flavours/glitch/components/status_visibility_icon';
+import Avatar from 'flavours/glitch/components/avatar';
+import RelativeTimestamp from 'flavours/glitch/components/relative_timestamp';
+import DisplayName from 'flavours/glitch/components/display_name';
+import AttachmentList from 'flavours/glitch/components/attachment_list';
+import Icon from 'flavours/glitch/components/icon';
+import ImmutablePureComponent from 'react-immutable-pure-component';
import PrivacyDropdown from 'flavours/glitch/features/compose/components/privacy_dropdown';
+import classNames from 'classnames';
+import { changeBoostPrivacy } from 'flavours/glitch/actions/boosts';
+import VisibilityIcon from 'flavours/glitch/components/status_visibility_icon';
const messages = defineMessages({
cancel_reblog: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' },
@@ -38,6 +35,8 @@ const mapDispatchToProps = dispatch => {
};
};
+export default @connect(mapStateToProps, mapDispatchToProps)
+@injectIntl
class BoostModal extends ImmutablePureComponent {
static contextTypes = {
@@ -65,7 +64,9 @@ class BoostModal extends ImmutablePureComponent {
if (e.button === 0) {
e.preventDefault();
this.props.onClose();
- this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
+ let state = { ...this.context.router.history.location.state };
+ state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
+ this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`, state);
}
};
@@ -136,5 +137,3 @@ class BoostModal extends ImmutablePureComponent {
}
}
-
-export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(BoostModal));
diff --git a/app/javascript/flavours/glitch/features/ui/components/bundle.jsx b/app/javascript/flavours/glitch/features/ui/components/bundle.jsx
index ccbb565fb..27b13ecfe 100644
--- a/app/javascript/flavours/glitch/features/ui/components/bundle.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/bundle.jsx
@@ -1,10 +1,10 @@
+import React from 'react';
import PropTypes from 'prop-types';
-import { Component } from 'react';
const emptyComponent = () => null;
const noop = () => { };
-class Bundle extends Component {
+class Bundle extends React.Component {
static propTypes = {
fetchComponent: PropTypes.func.isRequired,
@@ -33,11 +33,11 @@ class Bundle extends Component {
forceRender: false,
};
- UNSAFE_componentWillMount() {
+ componentWillMount() {
this.load(this.props);
}
- UNSAFE_componentWillReceiveProps(nextProps) {
+ componentWillReceiveProps(nextProps) {
if (nextProps.fetchComponent !== this.props.fetchComponent) {
this.load(nextProps);
}
diff --git a/app/javascript/flavours/glitch/features/ui/components/bundle_column_error.jsx b/app/javascript/flavours/glitch/features/ui/components/bundle_column_error.jsx
index cd971f9f2..88304dc36 100644
--- a/app/javascript/flavours/glitch/features/ui/components/bundle_column_error.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/bundle_column_error.jsx
@@ -1,17 +1,14 @@
+import React from 'react';
import PropTypes from 'prop-types';
-import { PureComponent } from 'react';
-
import { injectIntl, FormattedMessage } from 'react-intl';
-
-import classNames from 'classnames';
+import Column from 'flavours/glitch/components/column';
+import Button from 'flavours/glitch/components/button';
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
-
-import Button from 'flavours/glitch/components/button';
-import Column from 'flavours/glitch/components/column';
+import classNames from 'classnames';
import { autoPlayGif } from 'flavours/glitch/initial_state';
-class GIF extends PureComponent {
+class GIF extends React.PureComponent {
static propTypes = {
src: PropTypes.string.isRequired,
@@ -62,7 +59,7 @@ class GIF extends PureComponent {
}
-class CopyButton extends PureComponent {
+class CopyButton extends React.PureComponent {
static propTypes = {
children: PropTypes.node.isRequired,
@@ -95,7 +92,8 @@ class CopyButton extends PureComponent {
}
-class BundleColumnError extends PureComponent {
+export default @injectIntl
+class BundleColumnError extends React.PureComponent {
static propTypes = {
errorType: PropTypes.oneOf(['routing', 'network', 'error']),
@@ -162,5 +160,3 @@ class BundleColumnError extends PureComponent {
}
}
-
-export default injectIntl(BundleColumnError);
diff --git a/app/javascript/flavours/glitch/features/ui/components/bundle_modal_error.jsx b/app/javascript/flavours/glitch/features/ui/components/bundle_modal_error.jsx
index de4320648..b79105450 100644
--- a/app/javascript/flavours/glitch/features/ui/components/bundle_modal_error.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/bundle_modal_error.jsx
@@ -1,9 +1,8 @@
+import React from 'react';
import PropTypes from 'prop-types';
-import { Component } from 'react';
-
import { defineMessages, injectIntl } from 'react-intl';
-import { IconButton } from 'flavours/glitch/components/icon_button';
+import IconButton from 'flavours/glitch/components/icon_button';
const messages = defineMessages({
error: { id: 'bundle_modal_error.message', defaultMessage: 'Something went wrong while loading this component.' },
@@ -11,7 +10,7 @@ const messages = defineMessages({
close: { id: 'bundle_modal_error.close', defaultMessage: 'Close' },
});
-class BundleModalError extends Component {
+class BundleModalError extends React.Component {
static propTypes = {
onRetry: PropTypes.func.isRequired,
diff --git a/app/javascript/flavours/glitch/features/ui/components/column.jsx b/app/javascript/flavours/glitch/features/ui/components/column.jsx
index 8f6259e5b..cc2abc43a 100644
--- a/app/javascript/flavours/glitch/features/ui/components/column.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/column.jsx
@@ -1,14 +1,11 @@
-import PropTypes from 'prop-types';
-import { PureComponent } from 'react';
-
-import { debounce } from 'lodash';
-
-import { isMobile } from 'flavours/glitch/is_mobile';
-import { scrollTop } from 'flavours/glitch/scroll';
-
+import React from 'react';
import ColumnHeader from './column_header';
+import PropTypes from 'prop-types';
+import { debounce } from 'lodash';
+import { scrollTop } from 'flavours/glitch/scroll';
+import { isMobile } from 'flavours/glitch/is_mobile';
-export default class Column extends PureComponent {
+export default class Column extends React.PureComponent {
static propTypes = {
heading: PropTypes.string,
diff --git a/app/javascript/flavours/glitch/features/ui/components/column_header.jsx b/app/javascript/flavours/glitch/features/ui/components/column_header.jsx
index a2934e60f..151476f8b 100644
--- a/app/javascript/flavours/glitch/features/ui/components/column_header.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/column_header.jsx
@@ -1,11 +1,9 @@
+import React from 'react';
import PropTypes from 'prop-types';
-import { PureComponent } from 'react';
-
import classNames from 'classnames';
+import Icon from 'flavours/glitch/components/icon';
-import { Icon } from 'flavours/glitch/components/icon';
-
-export default class ColumnHeader extends PureComponent {
+export default class ColumnHeader extends React.PureComponent {
static propTypes = {
icon: PropTypes.string,
diff --git a/app/javascript/flavours/glitch/features/ui/components/column_link.jsx b/app/javascript/flavours/glitch/features/ui/components/column_link.jsx
index be8f4ca4b..dcdac077f 100644
--- a/app/javascript/flavours/glitch/features/ui/components/column_link.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/column_link.jsx
@@ -1,9 +1,8 @@
+import React from 'react';
import PropTypes from 'prop-types';
-
-import classNames from 'classnames';
import { NavLink } from 'react-router-dom';
-
-import { Icon } from 'flavours/glitch/components/icon';
+import Icon from 'flavours/glitch/components/icon';
+import classNames from 'classnames';
const ColumnLink = ({ icon, text, to, onClick, href, method, badge, transparent, ...other }) => {
const className = classNames('column-link', { 'column-link--transparent': transparent });
@@ -33,8 +32,7 @@ const ColumnLink = ({ icon, text, to, onClick, href, method, badge, transparent,
return onClick(e);
};
return (
- // eslint-disable-next-line jsx-a11y/anchor-is-valid -- intentional to have the same look and feel as other menu items
-
+
{iconElement}
{text}
{badgeElement}
diff --git a/app/javascript/flavours/glitch/features/ui/components/column_loading.jsx b/app/javascript/flavours/glitch/features/ui/components/column_loading.jsx
index c6a9fb278..b07385397 100644
--- a/app/javascript/flavours/glitch/features/ui/components/column_loading.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/column_loading.jsx
@@ -1,9 +1,9 @@
+import React from 'react';
import PropTypes from 'prop-types';
-import ImmutablePureComponent from 'react-immutable-pure-component';
-
import Column from 'flavours/glitch/components/column';
import ColumnHeader from 'flavours/glitch/components/column_header';
+import ImmutablePureComponent from 'react-immutable-pure-component';
export default class ColumnLoading extends ImmutablePureComponent {
diff --git a/app/javascript/flavours/glitch/features/ui/components/column_subheading.jsx b/app/javascript/flavours/glitch/features/ui/components/column_subheading.jsx
index e970a0bfd..8160c4aa3 100644
--- a/app/javascript/flavours/glitch/features/ui/components/column_subheading.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/column_subheading.jsx
@@ -1,3 +1,4 @@
+import React from 'react';
import PropTypes from 'prop-types';
const ColumnSubheading = ({ text }) => {
diff --git a/app/javascript/flavours/glitch/features/ui/components/columns_area.jsx b/app/javascript/flavours/glitch/features/ui/components/columns_area.jsx
index 6eb5ee0e5..3b3b0d58f 100644
--- a/app/javascript/flavours/glitch/features/ui/components/columns_area.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/columns_area.jsx
@@ -1,14 +1,11 @@
+import React from 'react';
import PropTypes from 'prop-types';
-import { Children, cloneElement } from 'react';
-
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
-
-import { supportsPassiveEvents } from 'detect-passive-events';
-
-import { scrollRight } from 'flavours/glitch/scroll';
-
import BundleContainer from '../containers/bundle_container';
+import ColumnLoading from './column_loading';
+import DrawerLoading from './drawer_loading';
+import BundleColumnError from './bundle_column_error';
import {
Compose,
Notifications,
@@ -21,14 +18,13 @@ import {
BookmarkedStatuses,
ListTimeline,
Directory,
-} from '../util/async-components';
-
-import BundleColumnError from './bundle_column_error';
-import ColumnLoading from './column_loading';
+} from '../../ui/util/async-components';
import ComposePanel from './compose_panel';
-import DrawerLoading from './drawer_loading';
import NavigationPanel from './navigation_panel';
+import { supportsPassiveEvents } from 'detect-passive-events';
+import { scrollRight } from 'flavours/glitch/scroll';
+
const componentMap = {
'COMPOSE': Compose,
'HOME': HomeTimeline,
@@ -54,6 +50,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
columns: ImmutablePropTypes.list.isRequired,
singleColumn: PropTypes.bool,
children: PropTypes.node,
+ navbarUnder: PropTypes.bool,
openSettings: PropTypes.func,
};
@@ -139,7 +136,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
};
render () {
- const { columns, children, singleColumn, openSettings } = this.props;
+ const { columns, children, singleColumn, navbarUnder, openSettings } = this.props;
const { renderComposePanel } = this.state;
if (singleColumn) {
@@ -178,7 +175,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
);
})}
- {Children.map(children, child => cloneElement(child, { multiColumn: true }))}
+ {React.Children.map(children, child => React.cloneElement(child, { multiColumn: true }))}
);
}
diff --git a/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx
index 409342bdd..4e74feb02 100644
--- a/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx
@@ -1,19 +1,15 @@
+import React from 'react';
import PropTypes from 'prop-types';
-import { PureComponent } from 'react';
-
-import { FormattedMessage } from 'react-intl';
-
import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
-
-import escapeTextContentForBrowser from 'escape-html';
-
+import { FormattedMessage } from 'react-intl';
import { closeModal } from 'flavours/glitch/actions/modal';
-import { IconButton } from 'flavours/glitch/components/icon_button';
-import InlineAccount from 'flavours/glitch/components/inline_account';
-import MediaAttachments from 'flavours/glitch/components/media_attachments';
-import { RelativeTimestamp } from 'flavours/glitch/components/relative_timestamp';
import emojify from 'flavours/glitch/features/emoji/emoji';
+import escapeTextContentForBrowser from 'escape-html';
+import InlineAccount from 'flavours/glitch/components/inline_account';
+import IconButton from 'flavours/glitch/components/icon_button';
+import RelativeTimestamp from 'flavours/glitch/components/relative_timestamp';
+import MediaAttachments from 'flavours/glitch/components/media_attachments';
const mapStateToProps = (state, { statusId }) => ({
language: state.getIn(['statuses', statusId, 'language']),
@@ -23,15 +19,13 @@ const mapStateToProps = (state, { statusId }) => ({
const mapDispatchToProps = dispatch => ({
onClose() {
- dispatch(closeModal({
- modalType: undefined,
- ignoreFocus: false,
- }));
+ dispatch(closeModal());
},
});
-class CompareHistoryModal extends PureComponent {
+export default @connect(mapStateToProps, mapDispatchToProps)
+class CompareHistoryModal extends React.PureComponent {
static propTypes = {
onClose: PropTypes.func.isRequired,
@@ -72,10 +66,10 @@ class CompareHistoryModal extends PureComponent {
{currentVersion.get('spoiler_text').length > 0 && (
- <>
+
- >
+
)}
@@ -106,5 +100,3 @@ class CompareHistoryModal extends PureComponent {
}
}
-
-export default connect(mapStateToProps, mapDispatchToProps)(CompareHistoryModal);
diff --git a/app/javascript/flavours/glitch/features/ui/components/compose_panel.jsx b/app/javascript/flavours/glitch/features/ui/components/compose_panel.jsx
index 1b92ac398..34c194c99 100644
--- a/app/javascript/flavours/glitch/features/ui/components/compose_panel.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/compose_panel.jsx
@@ -1,18 +1,15 @@
-import PropTypes from 'prop-types';
-import { PureComponent } from 'react';
-
+import React from 'react';
import { connect } from 'react-redux';
-
-import { mountCompose, unmountCompose } from 'flavours/glitch/actions/compose';
-import ServerBanner from 'flavours/glitch/components/server_banner';
+import PropTypes from 'prop-types';
+import SearchContainer from 'flavours/glitch/features/compose/containers/search_container';
import ComposeFormContainer from 'flavours/glitch/features/compose/containers/compose_form_container';
import NavigationContainer from 'flavours/glitch/features/compose/containers/navigation_container';
-import SearchContainer from 'flavours/glitch/features/compose/containers/search_container';
-
import LinkFooter from './link_footer';
+import ServerBanner from 'flavours/glitch/components/server_banner';
+import { mountCompose, unmountCompose } from 'flavours/glitch/actions/compose';
-
-class ComposePanel extends PureComponent {
+export default @connect()
+class ComposePanel extends React.PureComponent {
static contextTypes = {
identity: PropTypes.object.isRequired,
@@ -40,17 +37,17 @@ class ComposePanel extends PureComponent {
{!signedIn && (
- <>
+
- >
+
)}
{signedIn && (
- <>
+
- >
+
)}
@@ -59,5 +56,3 @@ class ComposePanel extends PureComponent {
}
}
-
-export default connect()(ComposePanel);
diff --git a/app/javascript/flavours/glitch/features/ui/components/confirmation_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/confirmation_modal.jsx
index 2fc7e3f3e..94935de5d 100644
--- a/app/javascript/flavours/glitch/features/ui/components/confirmation_modal.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/confirmation_modal.jsx
@@ -1,11 +1,10 @@
+import React from 'react';
import PropTypes from 'prop-types';
-import { PureComponent } from 'react';
-
import { injectIntl, FormattedMessage } from 'react-intl';
-
import Button from 'flavours/glitch/components/button';
-class ConfirmationModal extends PureComponent {
+export default @injectIntl
+class ConfirmationModal extends React.PureComponent {
static propTypes = {
message: PropTypes.node.isRequired,
@@ -87,5 +86,3 @@ class ConfirmationModal extends PureComponent {
}
}
-
-export default injectIntl(ConfirmationModal);
diff --git a/app/javascript/flavours/glitch/features/ui/components/deprecated_settings_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/deprecated_settings_modal.jsx
index ba77feb6a..37f52b014 100644
--- a/app/javascript/flavours/glitch/features/ui/components/deprecated_settings_modal.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/deprecated_settings_modal.jsx
@@ -1,14 +1,11 @@
+import React from 'react';
import PropTypes from 'prop-types';
-import { PureComponent } from 'react';
-
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-
import ImmutablePropTypes from 'react-immutable-proptypes';
-
-import Button from 'flavours/glitch/components/button';
-import { Icon } from 'flavours/glitch/components/icon';
-import illustration from 'flavours/glitch/images/logo_warn_glitch.svg';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { preferenceLink } from 'flavours/glitch/utils/backend_links';
+import Button from 'flavours/glitch/components/button';
+import Icon from 'flavours/glitch/components/icon';
+import illustration from 'flavours/glitch/images/logo_warn_glitch.svg';
const messages = defineMessages({
discardChanges: { id: 'confirmations.deprecated_settings.confirm', defaultMessage: 'Use Mastodon preferences' },
@@ -16,7 +13,8 @@ const messages = defineMessages({
user_setting_disable_swiping: { id: 'settings.swipe_to_change_columns', defaultMessage: 'Allow swiping to change columns (Mobile only)' },
});
-class DeprecatedSettingsModal extends PureComponent {
+export default @injectIntl
+class DeprecatedSettingsModal extends React.PureComponent {
static propTypes = {
settings: ImmutablePropTypes.list.isRequired,
@@ -67,7 +65,7 @@ class DeprecatedSettingsModal extends PureComponent {
{ settings.map((setting_name) => (
- -
+
-
)) }
@@ -86,5 +84,3 @@ class DeprecatedSettingsModal extends PureComponent {
}
}
-
-export default injectIntl(DeprecatedSettingsModal);
diff --git a/app/javascript/flavours/glitch/features/ui/components/disabled_account_banner.jsx b/app/javascript/flavours/glitch/features/ui/components/disabled_account_banner.jsx
index 396127829..35933bedb 100644
--- a/app/javascript/flavours/glitch/features/ui/components/disabled_account_banner.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/disabled_account_banner.jsx
@@ -1,14 +1,10 @@
+import React from 'react';
import PropTypes from 'prop-types';
-import { PureComponent } from 'react';
-
-import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
-
-import { Link } from 'react-router-dom';
-
import { connect } from 'react-redux';
-
-import { openModal } from 'flavours/glitch/actions/modal';
+import { Link } from 'react-router-dom';
+import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import { disabledAccountId, movedToAccountId, domain } from 'flavours/glitch/initial_state';
+import { openModal } from 'flavours/glitch/actions/modal';
import { logOut } from 'flavours/glitch/utils/log_out';
const messages = defineMessages({
@@ -23,19 +19,18 @@ const mapStateToProps = (state) => ({
const mapDispatchToProps = (dispatch, { intl }) => ({
onLogout () {
- dispatch(openModal({
- modalType: 'CONFIRM',
- modalProps: {
- message: intl.formatMessage(messages.logoutMessage),
- confirm: intl.formatMessage(messages.logoutConfirm),
- closeWhenConfirm: false,
- onConfirm: () => logOut(),
- },
+ dispatch(openModal('CONFIRM', {
+ message: intl.formatMessage(messages.logoutMessage),
+ confirm: intl.formatMessage(messages.logoutConfirm),
+ closeWhenConfirm: false,
+ onConfirm: () => logOut(),
}));
},
});
-class DisabledAccountBanner extends PureComponent {
+export default @injectIntl
+@connect(mapStateToProps, mapDispatchToProps)
+class DisabledAccountBanner extends React.PureComponent {
static propTypes = {
disabledAcct: PropTypes.string.isRequired,
@@ -95,5 +90,3 @@ class DisabledAccountBanner extends PureComponent {
}
}
-
-export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(DisabledAccountBanner));
diff --git a/app/javascript/flavours/glitch/features/ui/components/doodle_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/doodle_modal.jsx
index b59435358..c8ea33a0e 100644
--- a/app/javascript/flavours/glitch/features/ui/components/doodle_modal.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/doodle_modal.jsx
@@ -1,17 +1,15 @@
+import React from 'react';
import PropTypes from 'prop-types';
-
+import Button from 'flavours/glitch/components/button';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import Atrament from 'atrament'; // the doodling library
+import { connect } from 'react-redux';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { doodleSet, uploadCompose } from 'flavours/glitch/actions/compose';
+import IconButton from 'flavours/glitch/components/icon_button';
+import { debounce, mapValues } from 'lodash';
import classNames from 'classnames';
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import ImmutablePureComponent from 'react-immutable-pure-component';
-import { connect } from 'react-redux';
-
-import Atrament from 'atrament'; // the doodling library
-import { debounce, mapValues } from 'lodash';
-
-import { doodleSet, uploadCompose } from 'flavours/glitch/actions/compose';
-import Button from 'flavours/glitch/components/button';
-import { IconButton } from 'flavours/glitch/components/icon_button';
// palette nicked from MyPaint, CC0
const palette = [
['rgb( 0, 0, 0)', 'Black'],
@@ -127,15 +125,9 @@ const mapStateToProps = state => ({
});
const mapDispatchToProps = dispatch => ({
- /**
- * Set options in the redux store
- * @param opts
- */
+ /** Set options in the redux store */
setOpt: (opts) => dispatch(doodleSet(opts)),
- /**
- * Submit doodle for upload
- * @param file
- */
+ /** Submit doodle for upload */
submit: (file) => dispatch(uploadCompose([file])),
});
@@ -153,6 +145,7 @@ const mapDispatchToProps = dispatch => ({
* - Ctrl + left mouse button: pick background
* - Right mouse button: pick background
*/
+export default @connect(mapStateToProps, mapDispatchToProps)
class DoodleModal extends ImmutablePureComponent {
static propTypes = {
@@ -238,10 +231,7 @@ class DoodleModal extends ImmutablePureComponent {
//endregion
- /**
- * Key up handler
- * @param e
- */
+ /** Key up handler */
handleKeyUp = (e) => {
if (e.target.nodeName === 'INPUT') return;
@@ -267,10 +257,7 @@ class DoodleModal extends ImmutablePureComponent {
}
};
- /**
- * Key down handler
- * @param e
- */
+ /** Key down handler */
handleKeyDown = (e) => {
if (e.key === 'Control' || e.key === 'Meta') {
this.controlHeld = true;
@@ -306,6 +293,7 @@ class DoodleModal extends ImmutablePureComponent {
/**
* Set reference to the canvas element.
* This is called during component init
+ *
* @param elem - canvas element
*/
setCanvasRef = (elem) => {
@@ -347,6 +335,7 @@ class DoodleModal extends ImmutablePureComponent {
/**
* Set up the sketcher instance
+ *
* @param canvas - canvas element. Null if we're just resizing
*/
initSketcher (canvas = null) {
@@ -445,6 +434,7 @@ class DoodleModal extends ImmutablePureComponent {
/**
* Palette left click.
* Selects Fg color (or Bg, if Control/Meta is held)
+ *
* @param e - event
*/
onPaletteClick = (e) => {
@@ -463,6 +453,7 @@ class DoodleModal extends ImmutablePureComponent {
/**
* Palette right click.
* Selects Bg color
+ *
* @param e - event
*/
onPaletteRClick = (e) => {
@@ -473,6 +464,7 @@ class DoodleModal extends ImmutablePureComponent {
/**
* Handle click on the Draw mode button
+ *
* @param e - event
*/
setModeDraw = (e) => {
@@ -482,6 +474,7 @@ class DoodleModal extends ImmutablePureComponent {
/**
* Handle click on the Fill mode button
+ *
* @param e - event
*/
setModeFill = (e) => {
@@ -491,6 +484,7 @@ class DoodleModal extends ImmutablePureComponent {
/**
* Handle click on Smooth checkbox
+ *
* @param e - event
*/
tglSmooth = (e) => {
@@ -500,6 +494,7 @@ class DoodleModal extends ImmutablePureComponent {
/**
* Handle click on Adaptive checkbox
+ *
* @param e - event
*/
tglAdaptive = (e) => {
@@ -509,6 +504,7 @@ class DoodleModal extends ImmutablePureComponent {
/**
* Handle change of the Weight input field
+ *
* @param e - event
*/
setWeight = (e) => {
@@ -517,6 +513,7 @@ class DoodleModal extends ImmutablePureComponent {
/**
* Set size - clalback from the select box
+ *
* @param e - event
*/
changeSize = (e) => {
@@ -615,5 +612,3 @@ class DoodleModal extends ImmutablePureComponent {
}
}
-
-export default connect(mapStateToProps, mapDispatchToProps)(DoodleModal);
diff --git a/app/javascript/flavours/glitch/features/ui/components/drawer_loading.jsx b/app/javascript/flavours/glitch/features/ui/components/drawer_loading.jsx
index 11072ad98..08b0d2347 100644
--- a/app/javascript/flavours/glitch/features/ui/components/drawer_loading.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/drawer_loading.jsx
@@ -1,3 +1,5 @@
+import React from 'react';
+
const DrawerLoading = () => (
diff --git a/app/javascript/flavours/glitch/features/ui/components/embed_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/embed_modal.jsx
index dffa36142..92bfa79c4 100644
--- a/app/javascript/flavours/glitch/features/ui/components/embed_modal.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/embed_modal.jsx
@@ -1,16 +1,15 @@
+import React from 'react';
import PropTypes from 'prop-types';
-
-import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
-
import ImmutablePureComponent from 'react-immutable-pure-component';
-
+import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
import api from 'flavours/glitch/api';
-import { IconButton } from 'flavours/glitch/components/icon_button';
+import IconButton from 'flavours/glitch/components/icon_button';
const messages = defineMessages({
close: { id: 'lightbox.close', defaultMessage: 'Close' },
});
+export default @injectIntl
class EmbedModal extends ImmutablePureComponent {
static propTypes = {
@@ -87,7 +86,7 @@ class EmbedModal extends ImmutablePureComponent {
className='embed-modal__iframe'
frameBorder='0'
ref={this.setIframeRef}
- sandbox='allow-scripts allow-same-origin'
+ sandbox='allow-same-origin'
title='preview'
/>
@@ -96,5 +95,3 @@ class EmbedModal extends ImmutablePureComponent {
}
}
-
-export default injectIntl(EmbedModal);
diff --git a/app/javascript/flavours/glitch/features/ui/components/favourite_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/favourite_modal.jsx
index fa955b048..78cbfeb51 100644
--- a/app/javascript/flavours/glitch/features/ui/components/favourite_modal.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/favourite_modal.jsx
@@ -1,25 +1,23 @@
-import PropTypes from 'prop-types';
-
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-
-import classNames from 'classnames';
-
+import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
-import ImmutablePureComponent from 'react-immutable-pure-component';
-
-import AttachmentList from 'flavours/glitch/components/attachment_list';
-import { Avatar } from 'flavours/glitch/components/avatar';
+import PropTypes from 'prop-types';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import Button from 'flavours/glitch/components/button';
-import { DisplayName } from 'flavours/glitch/components/display_name';
-import { Icon } from 'flavours/glitch/components/icon';
-import { RelativeTimestamp } from 'flavours/glitch/components/relative_timestamp';
import StatusContent from 'flavours/glitch/components/status_content';
+import Avatar from 'flavours/glitch/components/avatar';
+import RelativeTimestamp from 'flavours/glitch/components/relative_timestamp';
+import DisplayName from 'flavours/glitch/components/display_name';
+import AttachmentList from 'flavours/glitch/components/attachment_list';
+import Icon from 'flavours/glitch/components/icon';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import classNames from 'classnames';
import VisibilityIcon from 'flavours/glitch/components/status_visibility_icon';
const messages = defineMessages({
favourite: { id: 'status.favourite', defaultMessage: 'Favourite' },
});
+export default @injectIntl
class FavouriteModal extends ImmutablePureComponent {
static contextTypes = {
@@ -46,7 +44,9 @@ class FavouriteModal extends ImmutablePureComponent {
if (e.button === 0) {
e.preventDefault();
this.props.onClose();
- this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
+ let state = { ...this.context.router.history.location.state };
+ state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
+ this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`, state);
}
};
@@ -99,5 +99,3 @@ class FavouriteModal extends ImmutablePureComponent {
}
}
-
-export default injectIntl(FavouriteModal);
diff --git a/app/javascript/flavours/glitch/features/ui/components/filter_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/filter_modal.jsx
index 8bd74a001..d2482e733 100644
--- a/app/javascript/flavours/glitch/features/ui/components/filter_modal.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/filter_modal.jsx
@@ -1,20 +1,20 @@
-import PropTypes from 'prop-types';
-
-import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
-
-import ImmutablePureComponent from 'react-immutable-pure-component';
+import React from 'react';
import { connect } from 'react-redux';
-
-import { fetchFilters, createFilter, createFilterStatus } from 'flavours/glitch/actions/filters';
import { fetchStatus } from 'flavours/glitch/actions/statuses';
-import { IconButton } from 'flavours/glitch/components/icon_button';
-import AddedToFilter from 'flavours/glitch/features/filters/added_to_filter';
+import { fetchFilters, createFilter, createFilterStatus } from 'flavours/glitch/actions/filters';
+import PropTypes from 'prop-types';
+import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import IconButton from 'flavours/glitch/components/icon_button';
import SelectFilter from 'flavours/glitch/features/filters/select_filter';
+import AddedToFilter from 'flavours/glitch/features/filters/added_to_filter';
const messages = defineMessages({
close: { id: 'lightbox.close', defaultMessage: 'Close' },
});
+export default @connect(undefined)
+@injectIntl
class FilterModal extends ImmutablePureComponent {
static propTypes = {
@@ -132,5 +132,3 @@ class FilterModal extends ImmutablePureComponent {
}
}
-
-export default connect()(injectIntl(FilterModal));
diff --git a/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.jsx
index ed3bed47e..8e624adb3 100644
--- a/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.jsx
+++ b/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.jsx
@@ -1,34 +1,28 @@
-import PropTypes from 'prop-types';
-import { PureComponent } from 'react';
-
-import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
-
-import classNames from 'classnames';
-
+import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
+import PropTypes from 'prop-types';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux';
-
+import classNames from 'classnames';
+import { changeUploadCompose, uploadThumbnail, onChangeMediaDescription, onChangeMediaFocus } from 'flavours/glitch/actions/compose';
+import Video, { getPointerPosition } from 'flavours/glitch/features/video';
+import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
+import IconButton from 'flavours/glitch/components/icon_button';
+import Button from 'flavours/glitch/components/button';
+import Audio from 'flavours/glitch/features/audio';
import Textarea from 'react-textarea-autosize';
+import UploadProgress from 'flavours/glitch/features/compose/components/upload_progress';
+import CharacterCounter from 'flavours/glitch/features/compose/components/character_counter';
import { length } from 'stringz';
-// eslint-disable-next-line import/extensions
-import tesseractWorkerPath from 'tesseract.js/dist/worker.min.js';
+import { Tesseract as fetchTesseract } from 'flavours/glitch/features/ui/util/async-components';
+import GIFV from 'flavours/glitch/components/gifv';
+import { me } from 'flavours/glitch/initial_state';
// eslint-disable-next-line import/no-extraneous-dependencies
import tesseractCorePath from 'tesseract.js-core/tesseract-core.wasm.js';
-
-import Button from 'flavours/glitch/components/button';
-import { GIFV } from 'flavours/glitch/components/gifv';
-import { IconButton } from 'flavours/glitch/components/icon_button';
-import Audio from 'flavours/glitch/features/audio';
-import CharacterCounter from 'flavours/glitch/features/compose/components/character_counter';
-import UploadProgress from 'flavours/glitch/features/compose/components/upload_progress';
-import { Tesseract as fetchTesseract } from 'flavours/glitch/features/ui/util/async-components';
-import Video, { getPointerPosition } from 'flavours/glitch/features/video';
-import { me } from 'flavours/glitch/initial_state';
+// eslint-disable-next-line import/extensions
+import tesseractWorkerPath from 'tesseract.js/dist/worker.min.js';
import { assetHost } from 'flavours/glitch/utils/config';
-import { changeUploadCompose, uploadThumbnail, onChangeMediaDescription, onChangeMediaFocus } from '../../../actions/compose';
-
const messages = defineMessages({
close: { id: 'lightbox.close', defaultMessage: 'Close' },
apply: { id: 'upload_modal.apply', defaultMessage: 'Apply' },
@@ -75,7 +69,7 @@ const removeExtraLineBreaks = str => str.replace(/\n\n/g, '******')
.replace(/\n/g, ' ')
.replace(/\*\*\*\*\*\*/g, '\n\n');
-class ImageLoader extends PureComponent {
+class ImageLoader extends React.PureComponent {
static propTypes = {
src: PropTypes.string.isRequired,
@@ -105,6 +99,8 @@ class ImageLoader extends PureComponent {
}
+export default @connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true })
+@(component => injectIntl(component, { withRef: true }))
class FocalPointModal extends ImmutablePureComponent {
static propTypes = {
@@ -321,7 +317,7 @@ class FocalPointModal extends ImmutablePureComponent {
{focals &&
}
{thumbnailable && (
- <>
+
@@ -341,7 +337,7 @@ class FocalPointModal extends ImmutablePureComponent {
- >
+
)}