Upgrade to react-router v5 (#25047)

Co-authored-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
Renaud Chaput 2023-10-19 19:44:55 +02:00 committed by GitHub
parent 126cd7705d
commit 1b70d7ed7c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 419 additions and 361 deletions

View file

@ -14,10 +14,6 @@ const messages = defineMessages({
class FeaturedTags extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = {
account: ImmutablePropTypes.map,
featuredTags: ImmutablePropTypes.list,

View file

@ -4,7 +4,7 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { Helmet } from 'react-helmet';
import { NavLink } from 'react-router-dom';
import { NavLink, withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
@ -19,6 +19,7 @@ import { ShortNumber } from 'mastodon/components/short_number';
import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';
import { autoPlayGif, me, domain } from 'mastodon/initial_state';
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import AccountNoteContainer from '../containers/account_note_container';
import FollowRequestNoteContainer from '../containers/follow_request_note_container';
@ -83,11 +84,6 @@ const dateFormatOptions = {
class Header extends ImmutablePureComponent {
static contextTypes = {
identity: PropTypes.object,
router: PropTypes.object,
};
static propTypes = {
account: ImmutablePropTypes.map,
identity_props: ImmutablePropTypes.list,
@ -111,6 +107,11 @@ class Header extends ImmutablePureComponent {
intl: PropTypes.object.isRequired,
domain: PropTypes.string.isRequired,
hidden: PropTypes.bool,
...WithRouterPropTypes,
};
static contextTypes = {
identity: PropTypes.object,
};
setRef = c => {
@ -173,25 +174,24 @@ class Header extends ImmutablePureComponent {
};
handleHashtagClick = e => {
const { router } = this.context;
const { history } = this.props;
const value = e.currentTarget.textContent.replace(/^#/, '');
if (router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
if (history && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
router.history.push(`/tags/${value}`);
history.push(`/tags/${value}`);
}
};
handleMentionClick = e => {
const { router } = this.context;
const { onOpenURL } = this.props;
const { history, onOpenURL } = this.props;
if (router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
if (history && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
const link = e.currentTarget;
onOpenURL(link.href, router.history, () => {
onOpenURL(link.href, history, () => {
window.location = link.href;
});
}
@ -492,4 +492,4 @@ class Header extends ImmutablePureComponent {
}
export default injectIntl(Header);
export default withRouter(injectIntl(Header));

View file

@ -2,17 +2,19 @@ import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { NavLink } from 'react-router-dom';
import { NavLink, withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import InnerHeader from '../../account/components/header';
import MemorialNote from './memorial_note';
import MovedNote from './moved_note';
export default class Header extends ImmutablePureComponent {
class Header extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
@ -34,10 +36,7 @@ export default class Header extends ImmutablePureComponent {
hideTabs: PropTypes.bool,
domain: PropTypes.string.isRequired,
hidden: PropTypes.bool,
};
static contextTypes = {
router: PropTypes.object,
...WithRouterPropTypes,
};
handleFollow = () => {
@ -49,11 +48,11 @@ export default class Header extends ImmutablePureComponent {
};
handleMention = () => {
this.props.onMention(this.props.account, this.context.router.history);
this.props.onMention(this.props.account, this.props.history);
};
handleDirect = () => {
this.props.onDirect(this.props.account, this.context.router.history);
this.props.onDirect(this.props.account, this.props.history);
};
handleReport = () => {
@ -159,3 +158,5 @@ export default class Header extends ImmutablePureComponent {
}
}
export default withRouter(Header);

View file

@ -39,7 +39,6 @@ const mapStateToProps = (state, { columnId }) => {
class CommunityTimeline extends PureComponent {
static contextTypes = {
router: PropTypes.object,
identity: PropTypes.object,
};

View file

@ -10,6 +10,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import { length } from 'stringz';
import { Icon } from 'mastodon/components/icon';
import { WithOptionalRouterPropTypes, withOptionalRouter } from 'mastodon/utils/react_router';
import AutosuggestInput from '../../../components/autosuggest_input';
import AutosuggestTextarea from '../../../components/autosuggest_textarea';
@ -39,11 +40,6 @@ const messages = defineMessages({
});
class ComposeForm extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = {
intl: PropTypes.object.isRequired,
text: PropTypes.string.isRequired,
@ -71,6 +67,7 @@ class ComposeForm extends ImmutablePureComponent {
isInReply: PropTypes.bool,
singleColumn: PropTypes.bool,
lang: PropTypes.string,
...WithOptionalRouterPropTypes
};
static defaultProps = {
@ -114,7 +111,7 @@ class ComposeForm extends ImmutablePureComponent {
return;
}
this.props.onSubmit(this.context.router ? this.context.router.history : null);
this.props.onSubmit(this.props.history || null);
if (e) {
e.preventDefault();
@ -318,4 +315,4 @@ class ComposeForm extends ImmutablePureComponent {
}
export default injectIntl(ComposeForm);
export default withOptionalRouter(injectIntl(ComposeForm));

View file

@ -6,6 +6,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import AttachmentList from 'mastodon/components/attachment_list';
import { WithOptionalRouterPropTypes, withOptionalRouter } from 'mastodon/utils/react_router';
import { Avatar } from '../../../components/avatar';
import { DisplayName } from '../../../components/display_name';
@ -17,14 +18,11 @@ const messages = defineMessages({
class ReplyIndicator extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = {
status: ImmutablePropTypes.map,
onCancel: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
...WithOptionalRouterPropTypes,
};
handleClick = () => {
@ -34,7 +32,7 @@ class ReplyIndicator extends ImmutablePureComponent {
handleAccountClick = (e) => {
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
this.props.history?.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
}
};
@ -72,4 +70,4 @@ class ReplyIndicator extends ImmutablePureComponent {
}
export default injectIntl(ReplyIndicator);
export default withOptionalRouter(injectIntl(ReplyIndicator));

View file

@ -4,12 +4,14 @@ import { PureComponent } from 'react';
import { defineMessages, injectIntl, FormattedMessage, FormattedList } from 'react-intl';
import classNames from 'classnames';
import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { Icon } from 'mastodon/components/icon';
import { domain, searchEnabled } from 'mastodon/initial_state';
import { HASHTAG_REGEX } from 'mastodon/utils/hashtags';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
const messages = defineMessages({
placeholder: { id: 'search.placeholder', defaultMessage: 'Search' },
@ -30,7 +32,6 @@ const labelForRecentSearch = search => {
class Search extends PureComponent {
static contextTypes = {
router: PropTypes.object.isRequired,
identity: PropTypes.object.isRequired,
};
@ -48,6 +49,7 @@ class Search extends PureComponent {
openInRoute: PropTypes.bool,
intl: PropTypes.object.isRequired,
singleColumn: PropTypes.bool,
...WithRouterPropTypes,
};
state = {
@ -160,32 +162,29 @@ class Search extends PureComponent {
};
handleHashtagClick = () => {
const { router } = this.context;
const { value, onClickSearchResult } = this.props;
const { value, onClickSearchResult, history } = this.props;
const query = value.trim().replace(/^#/, '');
router.history.push(`/tags/${query}`);
history.push(`/tags/${query}`);
onClickSearchResult(query, 'hashtag');
this._unfocus();
};
handleAccountClick = () => {
const { router } = this.context;
const { value, onClickSearchResult } = this.props;
const { value, onClickSearchResult, history } = this.props;
const query = value.trim().replace(/^@/, '');
router.history.push(`/@${query}`);
history.push(`/@${query}`);
onClickSearchResult(query, 'account');
this._unfocus();
};
handleURLClick = () => {
const { router } = this.context;
const { value, onOpenURL } = this.props;
const { value, onOpenURL, history } = this.props;
onOpenURL(value, router.history);
onOpenURL(value, history);
this._unfocus();
};
@ -198,13 +197,12 @@ class Search extends PureComponent {
};
handleRecentSearchClick = search => {
const { onChange } = this.props;
const { router } = this.context;
const { onChange, history } = this.props;
if (search.get('type') === 'account') {
router.history.push(`/@${search.get('q')}`);
history.push(`/@${search.get('q')}`);
} else if (search.get('type') === 'hashtag') {
router.history.push(`/tags/${search.get('q')}`);
history.push(`/tags/${search.get('q')}`);
} else {
onChange(search.get('q'));
this._submit(search.get('type'));
@ -236,8 +234,7 @@ class Search extends PureComponent {
}
_submit (type) {
const { onSubmit, openInRoute, value, onClickSearchResult } = this.props;
const { router } = this.context;
const { onSubmit, openInRoute, value, onClickSearchResult, history } = this.props;
onSubmit(type);
@ -246,7 +243,7 @@ class Search extends PureComponent {
}
if (openInRoute) {
router.history.push('/search');
history.push('/search');
}
this._unfocus();
@ -395,4 +392,4 @@ class Search extends PureComponent {
}
export default injectIntl(Search);
export default withRouter(injectIntl(Search));

View file

@ -13,10 +13,6 @@ import Motion from '../../ui/util/optional_motion';
export default class Upload extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = {
media: ImmutablePropTypes.map.isRequired,
onUndo: PropTypes.func.isRequired,

View file

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { Link } from 'react-router-dom';
import { Link, withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
@ -17,6 +17,7 @@ import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
import StatusContent from 'mastodon/components/status_content';
import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';
import { autoPlayGif } from 'mastodon/initial_state';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
const messages = defineMessages({
more: { id: 'status.more', defaultMessage: 'More' },
@ -30,10 +31,6 @@ const messages = defineMessages({
class Conversation extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = {
conversationId: PropTypes.string.isRequired,
accounts: ImmutablePropTypes.list.isRequired,
@ -45,6 +42,7 @@ class Conversation extends ImmutablePureComponent {
markRead: PropTypes.func.isRequired,
delete: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
...WithRouterPropTypes,
};
handleMouseEnter = ({ currentTarget }) => {
@ -74,7 +72,7 @@ class Conversation extends ImmutablePureComponent {
};
handleClick = () => {
if (!this.context.router) {
if (!this.props.history) {
return;
}
@ -84,7 +82,7 @@ class Conversation extends ImmutablePureComponent {
markRead();
}
this.context.router.history.push(`/@${lastStatus.getIn(['account', 'acct'])}/${lastStatus.get('id')}`);
this.props.history.push(`/@${lastStatus.getIn(['account', 'acct'])}/${lastStatus.get('id')}`);
};
handleMarkAsRead = () => {
@ -92,7 +90,7 @@ class Conversation extends ImmutablePureComponent {
};
handleReply = () => {
this.props.reply(this.props.lastStatus, this.context.router.history);
this.props.reply(this.props.lastStatus, this.props.history);
};
handleDelete = () => {
@ -202,4 +200,4 @@ class Conversation extends ImmutablePureComponent {
}
export default injectIntl(Conversation);
export default withRouter(injectIntl(Conversation));

View file

@ -36,10 +36,6 @@ const mapStateToProps = state => ({
class Directory extends PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = {
isLoading: PropTypes.bool,
accountIds: ImmutablePropTypes.list.isRequired,

View file

@ -32,7 +32,6 @@ const mapStateToProps = state => ({
class Explore extends PureComponent {
static contextTypes = {
router: PropTypes.object,
identity: PropTypes.object,
};

View file

@ -4,6 +4,7 @@ import { PureComponent } from 'react';
import { defineMessages, injectIntl, FormattedMessage, FormattedDate } from 'react-intl';
import classNames from 'classnames';
import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
@ -20,6 +21,7 @@ import EmojiPickerDropdown from 'mastodon/features/compose/containers/emoji_pick
import unicodeMapping from 'mastodon/features/emoji/emoji_unicode_mapping_light';
import { autoPlayGif, reduceMotion, disableSwiping, mascot } from 'mastodon/initial_state';
import { assetHost } from 'mastodon/utils/config';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
const messages = defineMessages({
close: { id: 'lightbox.close', defaultMessage: 'Close' },
@ -27,14 +29,10 @@ const messages = defineMessages({
next: { id: 'lightbox.next', defaultMessage: 'Next' },
});
class Content extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
class ContentWithRouter extends ImmutablePureComponent {
static propTypes = {
announcement: ImmutablePropTypes.map.isRequired,
...WithRouterPropTypes,
};
setRef = c => {
@ -89,25 +87,25 @@ class Content extends ImmutablePureComponent {
}
onMentionClick = (mention, e) => {
if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
if (this.props.history && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
this.context.router.history.push(`/@${mention.get('acct')}`);
this.props.history.push(`/@${mention.get('acct')}`);
}
};
onHashtagClick = (hashtag, e) => {
hashtag = hashtag.replace(/^#/, '');
if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
if (this.props.history&& e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
this.context.router.history.push(`/tags/${hashtag}`);
this.props.history.push(`/tags/${hashtag}`);
}
};
onStatusClick = (status, e) => {
if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
if (this.props.history && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
this.context.router.history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
this.props.history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
}
};
@ -153,6 +151,8 @@ class Content extends ImmutablePureComponent {
}
const Content = withRouter(ContentWithRouter);
class Emoji extends PureComponent {
static propTypes = {

View file

@ -66,7 +66,6 @@ const badgeDisplay = (number, limit) => {
class GettingStarted extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object.isRequired,
identity: PropTypes.object,
};

View file

@ -4,6 +4,7 @@ import { PureComponent } from 'react';
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import { Helmet } from 'react-helmet';
import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
@ -22,6 +23,7 @@ import { LoadingIndicator } from 'mastodon/components/loading_indicator';
import { RadioButton } from 'mastodon/components/radio_button';
import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error';
import StatusListContainer from 'mastodon/features/ui/containers/status_list_container';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
const messages = defineMessages({
deleteMessage: { id: 'confirmations.delete_list.message', defaultMessage: 'Are you sure you want to permanently delete this list?' },
@ -38,10 +40,6 @@ const mapStateToProps = (state, props) => ({
class ListTimeline extends PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
@ -50,6 +48,7 @@ class ListTimeline extends PureComponent {
multiColumn: PropTypes.bool,
list: PropTypes.oneOfType([ImmutablePropTypes.map, PropTypes.bool]),
intl: PropTypes.object.isRequired,
...WithRouterPropTypes,
};
handlePin = () => {
@ -59,7 +58,7 @@ class ListTimeline extends PureComponent {
dispatch(removeColumn(columnId));
} else {
dispatch(addColumn('LIST', { id: this.props.params.id }));
this.context.router.history.push('/');
this.props.history.push('/');
}
};
@ -137,7 +136,7 @@ class ListTimeline extends PureComponent {
if (columnId) {
dispatch(removeColumn(columnId));
} else {
this.context.router.history.push('/lists');
this.props.history.push('/lists');
}
},
},
@ -240,4 +239,4 @@ class ListTimeline extends PureComponent {
}
export default connect(mapStateToProps)(injectIntl(ListTimeline));
export default withRouter(connect(mapStateToProps)(injectIntl(ListTimeline)));

View file

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { injectIntl, FormattedMessage, defineMessages } from 'react-intl';
import classNames from 'classnames';
import { Link } from 'react-router-dom';
import { Link, withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
@ -14,6 +14,7 @@ import { Icon } from 'mastodon/components/icon';
import AccountContainer from 'mastodon/containers/account_container';
import StatusContainer from 'mastodon/containers/status_container';
import { me } from 'mastodon/initial_state';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import FollowRequestContainer from '../containers/follow_request_container';
@ -40,11 +41,6 @@ const notificationForScreenReader = (intl, message, timestamp) => {
};
class Notification extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = {
notification: ImmutablePropTypes.map.isRequired,
hidden: PropTypes.bool,
@ -61,6 +57,7 @@ class Notification extends ImmutablePureComponent {
cacheMediaWidth: PropTypes.func,
cachedMediaWidth: PropTypes.number,
unread: PropTypes.bool,
...WithRouterPropTypes,
};
handleMoveUp = () => {
@ -77,7 +74,7 @@ class Notification extends ImmutablePureComponent {
const { notification } = this.props;
if (notification.get('status')) {
this.context.router.history.push(`/@${notification.getIn(['status', 'account', 'acct'])}/${notification.get('status')}`);
this.props.history.push(`/@${notification.getIn(['status', 'account', 'acct'])}/${notification.get('status')}`);
} else {
this.handleOpenProfile();
}
@ -85,14 +82,14 @@ class Notification extends ImmutablePureComponent {
handleOpenProfile = () => {
const { notification } = this.props;
this.context.router.history.push(`/@${notification.getIn(['account', 'acct'])}`);
this.props.history.push(`/@${notification.getIn(['account', 'acct'])}`);
};
handleMention = e => {
e.preventDefault();
const { notification, onMention } = this.props;
onMention(notification.get('account'), this.context.router.history);
onMention(notification.get('account'), this.props.history);
};
handleHotkeyFavourite = () => {
@ -453,4 +450,4 @@ class Notification extends ImmutablePureComponent {
}
export default injectIntl(Notification);
export default withRouter(injectIntl(Notification));

View file

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import { Link, withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
@ -19,6 +19,7 @@ import Column from 'mastodon/features/ui/components/column';
import { me } from 'mastodon/initial_state';
import { makeGetAccount } from 'mastodon/selectors';
import { assetHost } from 'mastodon/utils/config';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import ArrowSmallRight from './components/arrow_small_right';
import Step from './components/step';
@ -38,15 +39,11 @@ const mapStateToProps = () => {
};
class Onboarding extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object.isRequired,
};
static propTypes = {
dispatch: PropTypes.func.isRequired,
account: ImmutablePropTypes.map,
multiColumn: PropTypes.bool,
...WithRouterPropTypes,
};
state = {
@ -56,11 +53,10 @@ class Onboarding extends ImmutablePureComponent {
};
handleClose = () => {
const { dispatch } = this.props;
const { router } = this.context;
const { dispatch, history } = this.props;
dispatch(closeOnboarding());
router.history.push('/home');
history.push('/home');
};
handleProfileClick = () => {
@ -72,10 +68,9 @@ class Onboarding extends ImmutablePureComponent {
};
handleComposeClick = () => {
const { dispatch, intl } = this.props;
const { router } = this.context;
const { dispatch, intl, history } = this.props;
dispatch(focusCompose(router.history, intl.formatMessage(messages.template)));
dispatch(focusCompose(history, intl.formatMessage(messages.template)));
};
handleShareClick = () => {
@ -150,4 +145,4 @@ class Onboarding extends ImmutablePureComponent {
}
export default connect(mapStateToProps)(injectIntl(Onboarding));
export default withRouter(connect(mapStateToProps)(injectIntl(Onboarding)));

View file

@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl';
import classNames from 'classnames';
import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
@ -15,6 +16,7 @@ import { openModal } from 'mastodon/actions/modal';
import { IconButton } from 'mastodon/components/icon_button';
import { me, boostModal } from 'mastodon/initial_state';
import { makeGetStatus } from 'mastodon/selectors';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
const messages = defineMessages({
reply: { id: 'status.reply', defaultMessage: 'Reply' },
@ -43,7 +45,6 @@ const makeMapStateToProps = () => {
class Footer extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
identity: PropTypes.object,
};
@ -55,17 +56,17 @@ class Footer extends ImmutablePureComponent {
askReplyConfirmation: PropTypes.bool,
withOpenButton: PropTypes.bool,
onClose: PropTypes.func,
...WithRouterPropTypes,
};
_performReply = () => {
const { dispatch, status, onClose } = this.props;
const { router } = this.context;
const { dispatch, status, onClose, history } = this.props;
if (onClose) {
onClose(true);
}
dispatch(replyCompose(status, router.history));
dispatch(replyCompose(status, history));
};
handleReplyClick = () => {
@ -149,9 +150,7 @@ class Footer extends ImmutablePureComponent {
};
handleOpenClick = e => {
const { router } = this.context;
if (e.button !== 0 || !router) {
if (e.button !== 0 || !history) {
return;
}
@ -161,7 +160,7 @@ class Footer extends ImmutablePureComponent {
onClose();
}
router.history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
};
render () {
@ -204,4 +203,4 @@ class Footer extends ImmutablePureComponent {
}
export default connect(makeMapStateToProps)(injectIntl(Footer));
export default withRouter(connect(makeMapStateToProps)(injectIntl(Footer)));

View file

@ -41,7 +41,6 @@ const mapStateToProps = (state, { columnId }) => {
class PublicTimeline extends PureComponent {
static contextTypes = {
router: PropTypes.object,
identity: PropTypes.object,
};

View file

@ -4,11 +4,13 @@ import { PureComponent } from 'react';
import { defineMessages, injectIntl } from 'react-intl';
import classNames from 'classnames';
import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import { IconButton } from '../../../components/icon_button';
import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
@ -55,7 +57,6 @@ const mapStateToProps = (state, { status }) => ({
class ActionBar extends PureComponent {
static contextTypes = {
router: PropTypes.object,
identity: PropTypes.object,
};
@ -81,6 +82,7 @@ class ActionBar extends PureComponent {
onPin: PropTypes.func,
onEmbed: PropTypes.func,
intl: PropTypes.object.isRequired,
...WithRouterPropTypes,
};
handleReplyClick = () => {
@ -100,23 +102,23 @@ class ActionBar extends PureComponent {
};
handleDeleteClick = () => {
this.props.onDelete(this.props.status, this.context.router.history);
this.props.onDelete(this.props.status, this.props.history);
};
handleRedraftClick = () => {
this.props.onDelete(this.props.status, this.context.router.history, true);
this.props.onDelete(this.props.status, this.props.history, true);
};
handleEditClick = () => {
this.props.onEdit(this.props.status, this.context.router.history);
this.props.onEdit(this.props.status, this.props.history);
};
handleDirectClick = () => {
this.props.onDirect(this.props.status.get('account'), this.context.router.history);
this.props.onDirect(this.props.status.get('account'), this.props.history);
};
handleMentionClick = () => {
this.props.onMention(this.props.status.get('account'), this.context.router.history);
this.props.onMention(this.props.status.get('account'), this.props.history);
};
handleMuteClick = () => {
@ -303,4 +305,4 @@ class ActionBar extends PureComponent {
}
export default connect(mapStateToProps)(injectIntl(ActionBar));
export default withRouter(connect(mapStateToProps)(injectIntl(ActionBar)));

View file

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { injectIntl, defineMessages, FormattedDate, FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { Link } from 'react-router-dom';
import { Link, withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
@ -13,6 +13,7 @@ import EditedTimestamp from 'mastodon/components/edited_timestamp';
import { getHashtagBarForStatus } from 'mastodon/components/hashtag_bar';
import { Icon } from 'mastodon/components/icon';
import PictureInPicturePlaceholder from 'mastodon/components/picture_in_picture_placeholder';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import { Avatar } from '../../../components/avatar';
import { DisplayName } from '../../../components/display_name';
@ -33,10 +34,6 @@ const messages = defineMessages({
class DetailedStatus extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = {
status: ImmutablePropTypes.map,
onOpenMedia: PropTypes.func.isRequired,
@ -53,6 +50,7 @@ class DetailedStatus extends ImmutablePureComponent {
available: PropTypes.bool,
}),
onToggleMediaVisibility: PropTypes.func,
...WithRouterPropTypes,
};
state = {
@ -60,9 +58,9 @@ class DetailedStatus extends ImmutablePureComponent {
};
handleAccountClick = (e) => {
if (e.button === 0 && !(e.ctrlKey || e.metaKey) && this.context.router) {
if (e.button === 0 && !(e.ctrlKey || e.metaKey) && this.props.history) {
e.preventDefault();
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
this.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
}
e.stopPropagation();
@ -237,7 +235,7 @@ class DetailedStatus extends ImmutablePureComponent {
if (['private', 'direct'].includes(status.get('visibility'))) {
reblogLink = '';
} else if (this.context.router) {
} else if (this.props.history) {
reblogLink = (
<>
{' · '}
@ -263,7 +261,7 @@ class DetailedStatus extends ImmutablePureComponent {
);
}
if (this.context.router) {
if (this.props.history) {
favouriteLink = (
<Link to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/favourites`} className='detailed-status__link'>
<Icon id='star' />
@ -333,4 +331,4 @@ class DetailedStatus extends ImmutablePureComponent {
}
export default injectIntl(DetailedStatus);
export default withRouter(injectIntl(DetailedStatus));

View file

@ -4,6 +4,7 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { Helmet } from 'react-helmet';
import { withRouter } from 'react-router-dom';
import Immutable from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes';
@ -17,6 +18,7 @@ import { Icon } from 'mastodon/components/icon';
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
import ScrollContainer from 'mastodon/containers/scroll_container';
import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import {
unblockAccount,
@ -68,6 +70,7 @@ import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from
import ActionBar from './components/action_bar';
import DetailedStatus from './components/detailed_status';
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?' },
@ -187,7 +190,6 @@ const titleFromStatus = (intl, status) => {
class Status extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
identity: PropTypes.object,
};
@ -206,6 +208,7 @@ class Status extends ImmutablePureComponent {
inUse: PropTypes.bool,
available: PropTypes.bool,
}),
...WithRouterPropTypes
};
state = {
@ -279,11 +282,11 @@ class Status extends ImmutablePureComponent {
modalProps: {
message: intl.formatMessage(messages.replyMessage),
confirm: intl.formatMessage(messages.replyConfirm),
onConfirm: () => dispatch(replyCompose(status, this.context.router.history)),
onConfirm: () => dispatch(replyCompose(status, this.props.history)),
},
}));
} else {
dispatch(replyCompose(status, this.context.router.history));
dispatch(replyCompose(status, this.props.history));
}
} else {
dispatch(openModal({
@ -501,7 +504,7 @@ class Status extends ImmutablePureComponent {
};
handleHotkeyOpenProfile = () => {
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
this.props.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
};
handleHotkeyToggleHidden = () => {
@ -745,4 +748,4 @@ class Status extends ImmutablePureComponent {
}
export default injectIntl(connect(makeMapStateToProps)(Status));
export default withRouter(injectIntl(connect(makeMapStateToProps)(Status)));

View file

@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
@ -12,6 +13,7 @@ import { changeBoostPrivacy } from 'mastodon/actions/boosts';
import AttachmentList from 'mastodon/components/attachment_list';
import { Icon } from 'mastodon/components/icon';
import PrivacyDropdown from 'mastodon/features/compose/components/privacy_dropdown';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import { Avatar } from '../../../components/avatar';
import Button from '../../../components/button';
@ -43,11 +45,6 @@ const mapDispatchToProps = dispatch => {
};
class BoostModal extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = {
status: ImmutablePropTypes.map.isRequired,
onReblog: PropTypes.func.isRequired,
@ -55,6 +52,7 @@ class BoostModal extends ImmutablePureComponent {
onChangeBoostPrivacy: PropTypes.func.isRequired,
privacy: PropTypes.string.isRequired,
intl: PropTypes.object.isRequired,
...WithRouterPropTypes,
};
componentDidMount() {
@ -70,7 +68,7 @@ class BoostModal extends ImmutablePureComponent {
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
this.props.onClose();
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
this.props.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
}
};
@ -143,4 +141,4 @@ class BoostModal extends ImmutablePureComponent {
}
export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(BoostModal));
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(injectIntl(BoostModal)));

View file

@ -44,11 +44,6 @@ const componentMap = {
};
export default class ColumnsArea extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object.isRequired,
};
static propTypes = {
columns: ImmutablePropTypes.list.isRequired,
isModalOpen: PropTypes.bool.isRequired,

View file

@ -1,7 +1,5 @@
import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux';
@ -55,4 +53,4 @@ class ListPanel extends ImmutablePureComponent {
}
export default withRouter(connect(mapStateToProps)(ListPanel));
export default connect(mapStateToProps)(ListPanel);

View file

@ -6,7 +6,7 @@ import { defineMessages, injectIntl } from 'react-intl';
import { Link } from 'react-router-dom';
import { WordmarkLogo } from 'mastodon/components/logo';
import NavigationPortal from 'mastodon/components/navigation_portal';
import { NavigationPortal } from 'mastodon/components/navigation_portal';
import { timelinePreview, trendsEnabled } from 'mastodon/initial_state';
import { transientSingleColumn } from 'mastodon/is_mobile';
@ -37,7 +37,6 @@ const messages = defineMessages({
class NavigationPanel extends Component {
static contextTypes = {
router: PropTypes.object.isRequired,
identity: PropTypes.object.isRequired,
};

View file

@ -16,6 +16,7 @@ import { synchronouslySubmitMarkers, submitMarkers, fetchMarkers } from 'mastodo
import { INTRODUCTION_VERSION } from 'mastodon/actions/onboarding';
import PictureInPicture from 'mastodon/features/picture_in_picture';
import { layoutFromWindow } from 'mastodon/is_mobile';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import { uploadCompose, resetCompose, changeComposeSpoilerness } from '../../actions/compose';
import { clearHeight } from '../../actions/height_cache';
@ -248,7 +249,6 @@ class SwitchingColumnsArea extends PureComponent {
class UI extends PureComponent {
static contextTypes = {
router: PropTypes.object.isRequired,
identity: PropTypes.object.isRequired,
};
@ -259,12 +259,12 @@ class UI extends PureComponent {
hasComposingText: PropTypes.bool,
hasMediaAttachments: PropTypes.bool,
canUploadMore: PropTypes.bool,
location: PropTypes.object,
intl: PropTypes.object.isRequired,
dropdownMenuIsOpen: PropTypes.bool,
layout: PropTypes.string.isRequired,
firstLaunch: PropTypes.bool,
username: PropTypes.string,
...WithRouterPropTypes,
};
state = {
@ -361,7 +361,7 @@ class UI extends PureComponent {
handleServiceWorkerPostMessage = ({ data }) => {
if (data.type === 'navigate') {
this.context.router.history.push(data.path);
this.props.history.push(data.path);
} else {
console.warn('Unknown message type:', data.type);
}
@ -482,12 +482,12 @@ class UI extends PureComponent {
};
handleHotkeyBack = () => {
const { router } = this.context;
const { history } = this.props;
if (router.history.location?.state?.fromMastodon) {
router.history.goBack();
if (history.location?.state?.fromMastodon) {
history.goBack();
} else {
router.history.push('/');
history.push('/');
}
};
@ -497,58 +497,58 @@ class UI extends PureComponent {
handleHotkeyToggleHelp = () => {
if (this.props.location.pathname === '/keyboard-shortcuts') {
this.context.router.history.goBack();
this.props.history.goBack();
} else {
this.context.router.history.push('/keyboard-shortcuts');
this.props.history.push('/keyboard-shortcuts');
}
};
handleHotkeyGoToHome = () => {
this.context.router.history.push('/home');
this.props.history.push('/home');
};
handleHotkeyGoToNotifications = () => {
this.context.router.history.push('/notifications');
this.props.history.push('/notifications');
};
handleHotkeyGoToLocal = () => {
this.context.router.history.push('/public/local');
this.props.history.push('/public/local');
};
handleHotkeyGoToFederated = () => {
this.context.router.history.push('/public');
this.props.history.push('/public');
};
handleHotkeyGoToDirect = () => {
this.context.router.history.push('/conversations');
this.props.history.push('/conversations');
};
handleHotkeyGoToStart = () => {
this.context.router.history.push('/getting-started');
this.props.history.push('/getting-started');
};
handleHotkeyGoToFavourites = () => {
this.context.router.history.push('/favourites');
this.props.history.push('/favourites');
};
handleHotkeyGoToPinned = () => {
this.context.router.history.push('/pinned');
this.props.history.push('/pinned');
};
handleHotkeyGoToProfile = () => {
this.context.router.history.push(`/@${this.props.username}`);
this.props.history.push(`/@${this.props.username}`);
};
handleHotkeyGoToBlocked = () => {
this.context.router.history.push('/blocks');
this.props.history.push('/blocks');
};
handleHotkeyGoToMuted = () => {
this.context.router.history.push('/mutes');
this.props.history.push('/mutes');
};
handleHotkeyGoToRequests = () => {
this.context.router.history.push('/follow_requests');
this.props.history.push('/follow_requests');
};
render () {

View file

@ -1,7 +1,7 @@
import PropTypes from 'prop-types';
import { Component, PureComponent, cloneElement, Children } from 'react';
import { Component, cloneElement, Children } from 'react';
import { Switch, Route } from 'react-router-dom';
import { Switch, Route, useLocation } from 'react-router-dom';
import StackTrace from 'stacktrace-js';
@ -10,27 +10,20 @@ import ColumnLoading from '../components/column_loading';
import BundleContainer from '../containers/bundle_container';
// Small wrapper to pass multiColumn to the route components
export class WrappedSwitch extends PureComponent {
static contextTypes = {
router: PropTypes.object,
};
export const WrappedSwitch = ({ multiColumn, children }) => {
const location = useLocation();
render () {
const { multiColumn, children } = this.props;
const { location } = this.context.router.route;
const decklessLocation = multiColumn && location.pathname.startsWith('/deck')
? {...location, pathname: location.pathname.slice(5)}
: location;
const decklessLocation = multiColumn && location.pathname.startsWith('/deck')
? {...location, pathname: location.pathname.slice(5)}
: location;
return (
<Switch location={decklessLocation}>
{Children.map(children, child => child ? cloneElement(child, { multiColumn }) : null)}
</Switch>
);
};
return (
<Switch location={decklessLocation}>
{Children.map(children, child => child ? cloneElement(child, { multiColumn }) : null)}
</Switch>
);
}
}
WrappedSwitch.propTypes = {
multiColumn: PropTypes.bool,