Merge branch 'next-react-router-5' into 'next'

Next: upgrade to react-router v5.3

See merge request soapbox-pub/soapbox-fe!1124
virtualized-window
Alex Gleason 3 years ago
commit c9a4087108

@ -1,26 +1,25 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { withRouter } from 'react-router-dom';
import Icon from 'soapbox/components/icon'; import Icon from 'soapbox/components/icon';
export default class ColumnBackButton extends React.PureComponent { export default @withRouter
class ColumnBackButton extends React.PureComponent {
static propTypes = { static propTypes = {
to: PropTypes.string, to: PropTypes.string,
}; history: PropTypes.object,
static contextTypes = {
router: PropTypes.object,
}; };
handleClick = () => { handleClick = () => {
const { to } = this.props; const { to } = this.props;
if (window.history?.length === 1) { if (window.history?.length === 1) {
this.context.router.history.push(to ? to : '/'); this.props.history.push(to ? to : '/');
} else { } else {
this.context.router.history.goBack(); this.props.history.goBack();
} }
} }

@ -2,6 +2,7 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { withRouter } from 'react-router-dom';
// import classNames from 'classnames'; // import classNames from 'classnames';
// import { injectIntl, defineMessages } from 'react-intl'; // import { injectIntl, defineMessages } from 'react-intl';
@ -13,11 +14,8 @@ import SubNavigation from 'soapbox/components/sub_navigation';
// hide: { id: 'column_header.hide_settings', defaultMessage: 'Hide settings' }, // hide: { id: 'column_header.hide_settings', defaultMessage: 'Hide settings' },
// }); // });
export default class ColumnHeader extends React.PureComponent { export default @withRouter
class ColumnHeader extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
// intl: PropTypes.object.isRequired, // intl: PropTypes.object.isRequired,
@ -26,6 +24,7 @@ export default class ColumnHeader extends React.PureComponent {
active: PropTypes.bool, active: PropTypes.bool,
extraButton: PropTypes.node, extraButton: PropTypes.node,
children: PropTypes.node, children: PropTypes.node,
history: PropTypes.object,
}; };
state = { state = {
@ -35,9 +34,9 @@ export default class ColumnHeader extends React.PureComponent {
historyBack = () => { historyBack = () => {
if (window.history?.length === 1) { if (window.history?.length === 1) {
this.context.router.history.push('/'); this.props.history.push('/');
} else { } else {
this.context.router.history.goBack(); this.props.history.goBack();
} }
} }

@ -5,6 +5,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import spring from 'react-motion/lib/spring'; import spring from 'react-motion/lib/spring';
import Overlay from 'react-overlays/lib/Overlay'; import Overlay from 'react-overlays/lib/Overlay';
import { withRouter } from 'react-router-dom';
import Icon from 'soapbox/components/icon'; import Icon from 'soapbox/components/icon';
@ -15,12 +16,9 @@ import { IconButton } from './ui';
const listenerOptions = supportsPassiveEvents ? { passive: true } : false; const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
let id = 0; let id = 0;
@withRouter
class DropdownMenu extends React.PureComponent { class DropdownMenu extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
items: PropTypes.array.isRequired, items: PropTypes.array.isRequired,
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
@ -29,6 +27,7 @@ class DropdownMenu extends React.PureComponent {
arrowOffsetLeft: PropTypes.string, arrowOffsetLeft: PropTypes.string,
arrowOffsetTop: PropTypes.string, arrowOffsetTop: PropTypes.string,
openedViaKeyboard: PropTypes.bool, openedViaKeyboard: PropTypes.bool,
history: PropTypes.object,
}; };
static defaultProps = { static defaultProps = {
@ -124,7 +123,7 @@ class DropdownMenu extends React.PureComponent {
action(e); action(e);
} else if (to) { } else if (to) {
e.preventDefault(); e.preventDefault();
this.context.router.history.push(to); this.props.history.push(to);
} }
} }
@ -196,11 +195,8 @@ class DropdownMenu extends React.PureComponent {
} }
export default class Dropdown extends React.PureComponent { export default @withRouter
class Dropdown extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
icon: PropTypes.string, icon: PropTypes.string,
@ -221,6 +217,7 @@ export default class Dropdown extends React.PureComponent {
openedViaKeyboard: PropTypes.bool, openedViaKeyboard: PropTypes.bool,
text: PropTypes.string, text: PropTypes.string,
onShiftClick: PropTypes.func, onShiftClick: PropTypes.func,
history: PropTypes.object,
}; };
static defaultProps = { static defaultProps = {
@ -293,7 +290,7 @@ export default class Dropdown extends React.PureComponent {
if (typeof action === 'function') { if (typeof action === 'function') {
action(e); action(e);
} else if (to) { } else if (to) {
this.context.router.history.push(to); this.props.history.push(to);
} }
} }

@ -2,17 +2,16 @@ import classNames from 'classnames';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { withRouter } from 'react-router-dom';
export default class FilterBar extends React.PureComponent { export default @withRouter
class FilterBar extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
items: PropTypes.array.isRequired, items: PropTypes.array.isRequired,
active: PropTypes.string, active: PropTypes.string,
className: PropTypes.string, className: PropTypes.string,
history: PropTypes.object,
}; };
state = { state = {
@ -88,7 +87,7 @@ export default class FilterBar extends React.PureComponent {
action(e); action(e);
} else if (to) { } else if (to) {
e.preventDefault(); e.preventDefault();
this.context.router.history.push(to); this.props.history.push(to);
} }
} }
@ -153,4 +152,4 @@ export default class FilterBar extends React.PureComponent {
); );
} }
} }

@ -5,6 +5,7 @@ import React from 'react';
import 'wicg-inert'; import 'wicg-inert';
import { injectIntl, FormattedMessage, defineMessages } from 'react-intl'; import { injectIntl, FormattedMessage, defineMessages } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { cancelReplyCompose } from '../actions/compose'; import { cancelReplyCompose } from '../actions/compose';
import { openModal, closeModal } from '../actions/modals'; import { openModal, closeModal } from '../actions/modals';
@ -41,6 +42,7 @@ const mapDispatchToProps = (dispatch) => ({
}, },
}); });
@withRouter
class ModalRoot extends React.PureComponent { class ModalRoot extends React.PureComponent {
static propTypes = { static propTypes = {
@ -53,10 +55,7 @@ class ModalRoot extends React.PureComponent {
hasComposeContent: PropTypes.bool, hasComposeContent: PropTypes.bool,
type: PropTypes.string, type: PropTypes.string,
onCancel: PropTypes.func, onCancel: PropTypes.func,
}; history: PropTypes.object,
static contextTypes = {
router: PropTypes.object,
}; };
state = { state = {
@ -116,7 +115,7 @@ class ModalRoot extends React.PureComponent {
componentDidMount() { componentDidMount() {
window.addEventListener('keyup', this.handleKeyUp, false); window.addEventListener('keyup', this.handleKeyUp, false);
window.addEventListener('keydown', this.handleKeyDown, false); window.addEventListener('keydown', this.handleKeyDown, false);
this.history = this.context.router ? this.context.router.history : createBrowserHistory(); this.history = this.props.history || createBrowserHistory();
} }
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {

@ -1,11 +1,9 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { withRouter } from 'react-router-dom';
export default class Permalink extends React.PureComponent { export default @withRouter
class Permalink extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
className: PropTypes.string, className: PropTypes.string,
@ -13,6 +11,7 @@ export default class Permalink extends React.PureComponent {
to: PropTypes.string.isRequired, to: PropTypes.string.isRequired,
children: PropTypes.node, children: PropTypes.node,
onInterceptClick: PropTypes.func, onInterceptClick: PropTypes.func,
history: PropTypes.object,
}; };
handleClick = e => { handleClick = e => {
@ -21,9 +20,9 @@ export default class Permalink extends React.PureComponent {
return; return;
} }
if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) { if (this.props.history && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault(); e.preventDefault();
this.context.router.history.push(this.props.to); this.props.history.push(this.props.to);
} }
} }

@ -4,6 +4,7 @@ import { throttle } from 'lodash';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { getSettings } from 'soapbox/actions/settings'; import { getSettings } from 'soapbox/actions/settings';
import PullToRefresh from 'soapbox/components/pull-to-refresh'; import PullToRefresh from 'soapbox/components/pull-to-refresh';
@ -26,12 +27,9 @@ const mapStateToProps = state => {
}; };
export default @connect(mapStateToProps, null, null, { forwardRef: true }) export default @connect(mapStateToProps, null, null, { forwardRef: true })
@withRouter
class ScrollableList extends PureComponent { class ScrollableList extends PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
scrollKey: PropTypes.string.isRequired, scrollKey: PropTypes.string.isRequired,
onLoadMore: PropTypes.func, onLoadMore: PropTypes.func,
@ -50,6 +48,7 @@ class ScrollableList extends PureComponent {
autoload: PropTypes.bool, autoload: PropTypes.bool,
onRefresh: PropTypes.func, onRefresh: PropTypes.func,
className: PropTypes.string, className: PropTypes.string,
location: PropTypes.object,
}; };
state = { state = {
@ -302,7 +301,7 @@ class ScrollableList extends PureComponent {
index={index} index={index}
listLength={childrenCount} listLength={childrenCount}
intersectionObserverWrapper={this.intersectionObserverWrapper} intersectionObserverWrapper={this.intersectionObserverWrapper}
saveHeightKey={trackScroll ? `${this.context.router.route.location.key}:${scrollKey}` : null} saveHeightKey={trackScroll ? `${this.props.location.key}:${scrollKey}` : null}
> >
{React.cloneElement(child, { {React.cloneElement(child, {
getScrollPosition: this.getScrollPosition, getScrollPosition: this.getScrollPosition,

@ -5,7 +5,7 @@ import { HotKeys } from 'react-hotkeys';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { injectIntl, FormattedMessage } from 'react-intl'; import { injectIntl, FormattedMessage } from 'react-intl';
import { NavLink } from 'react-router-dom'; import { NavLink, withRouter } from 'react-router-dom';
import Icon from 'soapbox/components/icon'; import Icon from 'soapbox/components/icon';
import PlaceholderCard from 'soapbox/features/placeholder/components/placeholder_card'; import PlaceholderCard from 'soapbox/features/placeholder/components/placeholder_card';
@ -51,13 +51,9 @@ export const defaultMediaVisibility = (status, displayMedia) => {
return (displayMedia !== 'hide_all' && !status.get('sensitive') || displayMedia === 'show_all'); return (displayMedia !== 'hide_all' && !status.get('sensitive') || displayMedia === 'show_all');
}; };
export default @injectIntl export default @injectIntl @withRouter
class Status extends ImmutablePureComponent { class Status extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
status: ImmutablePropTypes.map, status: ImmutablePropTypes.map,
account: ImmutablePropTypes.map, account: ImmutablePropTypes.map,
@ -93,6 +89,7 @@ class Status extends ImmutablePureComponent {
displayMedia: PropTypes.string, displayMedia: PropTypes.string,
allowedEmoji: ImmutablePropTypes.list, allowedEmoji: ImmutablePropTypes.list,
focusable: PropTypes.bool, focusable: PropTypes.bool,
history: PropTypes.object,
}; };
static defaultProps = { static defaultProps = {
@ -176,20 +173,20 @@ class Status extends ImmutablePureComponent {
return; return;
} }
if (!this.context.router) { if (!this.props.history) {
return; return;
} }
this.context.router.history.push(`/@${this._properStatus().getIn(['account', 'acct'])}/posts/${this._properStatus().get('id')}`); this.props.history.push(`/@${this._properStatus().getIn(['account', 'acct'])}/posts/${this._properStatus().get('id')}`);
} }
handleExpandClick = (e) => { handleExpandClick = (e) => {
if (e.button === 0) { if (e.button === 0) {
if (!this.context.router) { if (!this.props.history) {
return; return;
} }
this.context.router.history.push(`/@${this._properStatus().getIn(['account', 'acct'])}/posts/${this._properStatus().get('id')}`); this.props.history.push(`/@${this._properStatus().getIn(['account', 'acct'])}/posts/${this._properStatus().get('id')}`);
} }
} }
@ -234,7 +231,7 @@ class Status extends ImmutablePureComponent {
handleHotkeyReply = e => { handleHotkeyReply = e => {
e.preventDefault(); e.preventDefault();
this.props.onReply(this._properStatus(), this.context.router.history); this.props.onReply(this._properStatus(), this.props.history);
} }
handleHotkeyFavourite = () => { handleHotkeyFavourite = () => {
@ -247,15 +244,15 @@ class Status extends ImmutablePureComponent {
handleHotkeyMention = e => { handleHotkeyMention = e => {
e.preventDefault(); e.preventDefault();
this.props.onMention(this._properStatus().get('account'), this.context.router.history); this.props.onMention(this._properStatus().get('account'), this.props.history);
} }
handleHotkeyOpen = () => { handleHotkeyOpen = () => {
this.context.router.history.push(`/@${this._properStatus().getIn(['account', 'acct'])}/posts/${this._properStatus().get('id')}`); this.props.history.push(`/@${this._properStatus().getIn(['account', 'acct'])}/posts/${this._properStatus().get('id')}`);
} }
handleHotkeyOpenProfile = () => { handleHotkeyOpenProfile = () => {
this.context.router.history.push(`/@${this._properStatus().getIn(['account', 'acct'])}`); this.props.history.push(`/@${this._properStatus().getIn(['account', 'acct'])}`);
} }
handleHotkeyMoveUp = e => { handleHotkeyMoveUp = e => {

@ -6,7 +6,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Link } from 'react-router-dom'; import { Link, withRouter } from 'react-router-dom';
import { simpleEmojiReact } from 'soapbox/actions/emoji_reacts'; import { simpleEmojiReact } from 'soapbox/actions/emoji_reacts';
import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container'; import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container';
@ -68,10 +68,6 @@ const messages = defineMessages({
class StatusActionBar extends ImmutablePureComponent { class StatusActionBar extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
status: ImmutablePropTypes.map.isRequired, status: ImmutablePropTypes.map.isRequired,
onOpenUnauthorizedModal: PropTypes.func.isRequired, onOpenUnauthorizedModal: PropTypes.func.isRequired,
@ -105,6 +101,7 @@ class StatusActionBar extends ImmutablePureComponent {
emojiSelectorFocused: PropTypes.bool, emojiSelectorFocused: PropTypes.bool,
handleEmojiSelectorUnfocus: PropTypes.func.isRequired, handleEmojiSelectorUnfocus: PropTypes.func.isRequired,
features: PropTypes.object.isRequired, features: PropTypes.object.isRequired,
history: PropTypes.object,
}; };
static defaultProps = { static defaultProps = {
@ -128,7 +125,7 @@ class StatusActionBar extends ImmutablePureComponent {
event.stopPropagation(); event.stopPropagation();
if (me) { if (me) {
onReply(status, this.context.router.history); onReply(status, this.props.history);
} else { } else {
onOpenUnauthorizedModal('REPLY'); onOpenUnauthorizedModal('REPLY');
} }
@ -220,7 +217,7 @@ class StatusActionBar extends ImmutablePureComponent {
e.stopPropagation(); e.stopPropagation();
const { me, onQuote, onOpenUnauthorizedModal, status } = this.props; const { me, onQuote, onOpenUnauthorizedModal, status } = this.props;
if (me) { if (me) {
onQuote(status, this.context.router.history); onQuote(status, this.props.history);
} else { } else {
onOpenUnauthorizedModal('REBLOG'); onOpenUnauthorizedModal('REBLOG');
} }
@ -228,12 +225,12 @@ class StatusActionBar extends ImmutablePureComponent {
handleDeleteClick = (e) => { handleDeleteClick = (e) => {
e.stopPropagation(); e.stopPropagation();
this.props.onDelete(this.props.status, this.context.router.history); this.props.onDelete(this.props.status, this.props.history);
} }
handleRedraftClick = (e) => { handleRedraftClick = (e) => {
e.stopPropagation(); e.stopPropagation();
this.props.onDelete(this.props.status, this.context.router.history, true); this.props.onDelete(this.props.status, this.props.history, true);
} }
handlePinClick = (e) => { handlePinClick = (e) => {
@ -243,17 +240,17 @@ class StatusActionBar extends ImmutablePureComponent {
handleMentionClick = (e) => { handleMentionClick = (e) => {
e.stopPropagation(); e.stopPropagation();
this.props.onMention(this.props.status.get('account'), this.context.router.history); this.props.onMention(this.props.status.get('account'), this.props.history);
} }
handleDirectClick = (e) => { handleDirectClick = (e) => {
e.stopPropagation(); e.stopPropagation();
this.props.onDirect(this.props.status.get('account'), this.context.router.history); this.props.onDirect(this.props.status.get('account'), this.props.history);
} }
handleChatClick = (e) => { handleChatClick = (e) => {
e.stopPropagation(); e.stopPropagation();
this.props.onChat(this.props.status.get('account'), this.context.router.history); this.props.onChat(this.props.status.get('account'), this.props.history);
} }
handleMuteClick = (e) => { handleMuteClick = (e) => {
@ -268,7 +265,7 @@ class StatusActionBar extends ImmutablePureComponent {
handleOpen = (e) => { handleOpen = (e) => {
e.stopPropagation(); e.stopPropagation();
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}/posts/${this.props.status.get('id')}`); this.props.history.push(`/@${this.props.status.getIn(['account', 'acct'])}/posts/${this.props.status.get('id')}`);
} }
handleEmbed = () => { handleEmbed = () => {
@ -737,6 +734,6 @@ const mapDispatchToProps = (dispatch, { status }) => ({
}, },
}); });
export default injectIntl( export default withRouter(injectIntl(
connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true }, connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true },
)(StatusActionBar)); )(StatusActionBar)));

@ -4,6 +4,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { getSoapboxConfig } from 'soapbox/actions/soapbox'; import { getSoapboxConfig } from 'soapbox/actions/soapbox';
import Icon from 'soapbox/components/icon'; import Icon from 'soapbox/components/icon';
@ -23,12 +24,9 @@ const mapStateToProps = state => ({
}); });
export default @connect(mapStateToProps) export default @connect(mapStateToProps)
@withRouter
class StatusContent extends React.PureComponent { class StatusContent extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
status: ImmutablePropTypes.map.isRequired, status: ImmutablePropTypes.map.isRequired,
reblogContent: PropTypes.string, reblogContent: PropTypes.string,
@ -37,6 +35,7 @@ class StatusContent extends React.PureComponent {
onClick: PropTypes.func, onClick: PropTypes.func,
collapsable: PropTypes.bool, collapsable: PropTypes.bool,
greentext: PropTypes.bool, greentext: PropTypes.bool,
history: PropTypes.object,
}; };
state = { state = {
@ -118,18 +117,18 @@ class StatusContent extends React.PureComponent {
} }
onMentionClick = (mention, e) => { 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(); e.preventDefault();
this.context.router.history.push(`/@${mention.get('acct')}`); this.props.history.push(`/@${mention.get('acct')}`);
} }
} }
onHashtagClick = (hashtag, e) => { onHashtagClick = (hashtag, e) => {
hashtag = hashtag.replace(/^#/, '').toLowerCase(); hashtag = hashtag.replace(/^#/, '').toLowerCase();
if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) { if (this.props.history && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault(); e.preventDefault();
this.context.router.history.push(`/tags/${hashtag}`); this.props.history.push(`/tags/${hashtag}`);
} }
} }
@ -202,7 +201,7 @@ class StatusContent extends React.PureComponent {
const spoilerContent = { __html: status.get('spoilerHtml') }; const spoilerContent = { __html: status.get('spoilerHtml') };
const directionStyle = { direction: 'ltr' }; const directionStyle = { direction: 'ltr' };
const classNames = classnames('status__content', { const classNames = classnames('status__content', {
'status__content--with-action': this.props.onClick && this.context.router, 'status__content--with-action': this.props.onClick && this.props.history,
'status__content--with-spoiler': status.get('spoiler_text').length > 0, 'status__content--with-spoiler': status.get('spoiler_text').length > 0,
'status__content--collapsed': this.state.collapsed === true, 'status__content--collapsed': this.state.collapsed === true,
'status__content--big': onlyEmoji, 'status__content--big': onlyEmoji,

@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { injectIntl, defineMessages } from 'react-intl'; import { injectIntl, defineMessages } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { openModal } from 'soapbox/actions/modals'; import { openModal } from 'soapbox/actions/modals';
@ -23,6 +24,7 @@ const mapDispatchToProps = (dispatch, { settings: Settings }) => {
export default @connect(undefined, mapDispatchToProps) export default @connect(undefined, mapDispatchToProps)
@injectIntl @injectIntl
@withRouter
class SubNavigation extends React.PureComponent { class SubNavigation extends React.PureComponent {
static propTypes = { static propTypes = {
@ -30,10 +32,7 @@ class SubNavigation extends React.PureComponent {
message: PropTypes.string, message: PropTypes.string,
settings: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), settings: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
onOpenSettings: PropTypes.func.isRequired, onOpenSettings: PropTypes.func.isRequired,
} history: PropTypes.object,
static contextTypes = {
router: PropTypes.object.isRequired,
} }
state = { state = {
@ -42,9 +41,9 @@ class SubNavigation extends React.PureComponent {
handleBackClick = () => { handleBackClick = () => {
if (window.history && window.history.length === 1) { if (window.history && window.history.length === 1) {
this.context.router.history.push('/'); this.props.history.push('/');
} else { } else {
this.context.router.history.goBack(); this.props.history.goBack();
} }
} }

@ -2,12 +2,14 @@ import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { withRouter } from 'react-router-dom';
import InnerHeader from '../../account/components/header'; import InnerHeader from '../../account/components/header';
import MovedNote from './moved_note'; import MovedNote from './moved_note';
export default class Header extends ImmutablePureComponent { export default @withRouter
class Header extends ImmutablePureComponent {
static propTypes = { static propTypes = {
account: ImmutablePropTypes.map, account: ImmutablePropTypes.map,
@ -25,10 +27,7 @@ export default class Header extends ImmutablePureComponent {
onEndorseToggle: PropTypes.func.isRequired, onEndorseToggle: PropTypes.func.isRequired,
onAddToList: PropTypes.func.isRequired, onAddToList: PropTypes.func.isRequired,
username: PropTypes.string, username: PropTypes.string,
}; history: PropTypes.object,
static contextTypes = {
router: PropTypes.object,
}; };
handleFollow = () => { handleFollow = () => {
@ -40,11 +39,11 @@ export default class Header extends ImmutablePureComponent {
} }
handleMention = () => { handleMention = () => {
this.props.onMention(this.props.account, this.context.router.history); this.props.onMention(this.props.account, this.props.history);
} }
handleDirect = () => { handleDirect = () => {
this.props.onDirect(this.props.account, this.context.router.history); this.props.onDirect(this.props.account, this.props.history);
} }
handleReport = () => { handleReport = () => {
@ -84,7 +83,7 @@ export default class Header extends ImmutablePureComponent {
} }
handleChat = () => { handleChat = () => {
this.props.onChat(this.props.account, this.context.router.history); this.props.onChat(this.props.account, this.props.history);
} }
handleEndorseToggle = () => { handleEndorseToggle = () => {

@ -1,4 +1,3 @@
import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
@ -12,10 +11,6 @@ import DisplayName from '../../../components/display_name';
export default class MovedNote extends ImmutablePureComponent { export default class MovedNote extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
from: ImmutablePropTypes.map.isRequired, from: ImmutablePropTypes.map.isRequired,
to: ImmutablePropTypes.map.isRequired, to: ImmutablePropTypes.map.isRequired,

@ -7,7 +7,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { injectIntl, FormattedMessage, defineMessages } from 'react-intl'; import { injectIntl, FormattedMessage, defineMessages } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Link } from 'react-router-dom'; import { Link, withRouter } from 'react-router-dom';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { accountLookup } from 'soapbox/actions/accounts'; import { accountLookup } from 'soapbox/actions/accounts';
@ -52,6 +52,7 @@ const mapStateToProps = (state, props) => ({
export default @connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
@withRouter
class RegistrationForm extends ImmutablePureComponent { class RegistrationForm extends ImmutablePureComponent {
static propTypes = { static propTypes = {
@ -64,12 +65,9 @@ class RegistrationForm extends ImmutablePureComponent {
supportsAccountLookup: PropTypes.bool, supportsAccountLookup: PropTypes.bool,
inviteToken: PropTypes.string, inviteToken: PropTypes.string,
birthdayRequired: PropTypes.bool, birthdayRequired: PropTypes.bool,
history: PropTypes.object,
} }
static contextTypes = {
router: PropTypes.object,
};
state = { state = {
captchaLoading: true, captchaLoading: true,
submissionLoading: false, submissionLoading: false,
@ -168,14 +166,13 @@ class RegistrationForm extends ImmutablePureComponent {
} }
postRegisterAction = ({ access_token }) => { postRegisterAction = ({ access_token }) => {
const { dispatch, needsConfirmation, needsApproval } = this.props; const { dispatch, needsConfirmation, needsApproval, history } = this.props;
const { router } = this.context;
if (needsConfirmation || needsApproval) { if (needsConfirmation || needsApproval) {
return this.launchModal(); return this.launchModal();
} else { } else {
return dispatch(verifyCredentials(access_token)).then(() => { return dispatch(verifyCredentials(access_token)).then(() => {
router.history.push('/'); history.push('/');
}); });
} }
} }

@ -26,10 +26,6 @@ export default @connect(mapStateToProps)
@injectIntl @injectIntl
class Bookmarks extends ImmutablePureComponent { class Bookmarks extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
shouldUpdateScroll: PropTypes.func, shouldUpdateScroll: PropTypes.func,

@ -6,6 +6,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { injectIntl, defineMessages } from 'react-intl'; import { injectIntl, defineMessages } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { openChat, launchChat, toggleMainWindow } from 'soapbox/actions/chats'; import { openChat, launchChat, toggleMainWindow } from 'soapbox/actions/chats';
@ -52,17 +53,15 @@ const makeMapStateToProps = () => {
export default @connect(makeMapStateToProps) export default @connect(makeMapStateToProps)
@injectIntl @injectIntl
@withRouter
class ChatPanes extends ImmutablePureComponent { class ChatPanes extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
mainWindowState: PropTypes.string, mainWindowState: PropTypes.string,
panes: ImmutablePropTypes.list, panes: ImmutablePropTypes.list,
history: PropTypes.object,
} }
handleClickChat = (chat) => { handleClickChat = (chat) => {
@ -70,7 +69,7 @@ class ChatPanes extends ImmutablePureComponent {
} }
handleSuggestion = accountId => { handleSuggestion = accountId => {
this.props.dispatch(launchChat(accountId, this.context.router.history)); this.props.dispatch(launchChat(accountId, this.props.history));
} }
handleMainWindowToggle = () => { handleMainWindowToggle = () => {

@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { fetchChats, launchChat } from 'soapbox/actions/chats'; import { fetchChats, launchChat } from 'soapbox/actions/chats';
import AccountSearch from 'soapbox/components/account_search'; import AccountSearch from 'soapbox/components/account_search';
@ -19,23 +20,21 @@ const messages = defineMessages({
export default @connect() export default @connect()
@injectIntl @injectIntl
@withRouter
class ChatIndex extends React.PureComponent { class ChatIndex extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
history: PropTypes.object,
}; };
handleSuggestion = accountId => { handleSuggestion = accountId => {
this.props.dispatch(launchChat(accountId, this.context.router.history, true)); this.props.dispatch(launchChat(accountId, this.props.history, true));
} }
handleClickChat = (chat) => { handleClickChat = (chat) => {
this.context.router.history.push(`/chats/${chat.get('id')}`); this.props.history.push(`/chats/${chat.get('id')}`);
} }
handleRefresh = () => { handleRefresh = () => {

@ -33,10 +33,6 @@ export default @connect(mapStateToProps)
@injectIntl @injectIntl
class CommunityTimeline extends React.PureComponent { class CommunityTimeline extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,

@ -5,7 +5,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, FormattedMessage } from 'react-intl'; import { defineMessages, FormattedMessage } from 'react-intl';
import { Link } from 'react-router-dom'; import { Link, withRouter } from 'react-router-dom';
import { length } from 'stringz'; import { length } from 'stringz';
import Icon from 'soapbox/components/icon'; import Icon from 'soapbox/components/icon';
@ -45,16 +45,13 @@ const messages = defineMessages({
schedule: { id: 'compose_form.schedule', defaultMessage: 'Schedule' }, schedule: { id: 'compose_form.schedule', defaultMessage: 'Schedule' },
}); });
export default class ComposeForm extends ImmutablePureComponent { export default @withRouter
class ComposeForm extends ImmutablePureComponent {
state = { state = {
composeFocused: false, composeFocused: false,
} }
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
text: PropTypes.string.isRequired, text: PropTypes.string.isRequired,
@ -155,7 +152,7 @@ export default class ComposeForm extends ImmutablePureComponent {
return; return;
} }
this.props.onSubmit(this.context.router ? this.context.router.history : null, this.props.group); this.props.onSubmit(this.props.history ? this.props.history : null, this.props.group);
} }
onSuggestionsClearRequested = () => { onSuggestionsClearRequested = () => {

@ -11,10 +11,6 @@ import { isRtl } from '../../../rtl';
export default class ReplyIndicator extends ImmutablePureComponent { export default class ReplyIndicator extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
status: ImmutablePropTypes.map, status: ImmutablePropTypes.map,
onCancel: PropTypes.func.isRequired, onCancel: PropTypes.func.isRequired,

@ -5,6 +5,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import spring from 'react-motion/lib/spring'; import spring from 'react-motion/lib/spring';
import { withRouter } from 'react-router-dom';
import Blurhash from 'soapbox/components/blurhash'; import Blurhash from 'soapbox/components/blurhash';
import Icon from 'soapbox/components/icon'; import Icon from 'soapbox/components/icon';
@ -51,13 +52,9 @@ const messages = defineMessages({
delete: { id: 'upload_form.undo', defaultMessage: 'Delete' }, delete: { id: 'upload_form.undo', defaultMessage: 'Delete' },
}); });
export default @injectIntl export default @injectIntl @withRouter
class Upload extends ImmutablePureComponent { class Upload extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
media: ImmutablePropTypes.map.isRequired, media: ImmutablePropTypes.map.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
@ -65,6 +62,7 @@ class Upload extends ImmutablePureComponent {
onDescriptionChange: PropTypes.func.isRequired, onDescriptionChange: PropTypes.func.isRequired,
onOpenFocalPoint: PropTypes.func.isRequired, onOpenFocalPoint: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired, onSubmit: PropTypes.func.isRequired,
history: PropTypes.object.isRequired,
}; };
state = { state = {
@ -81,7 +79,7 @@ class Upload extends ImmutablePureComponent {
handleSubmit = () => { handleSubmit = () => {
this.handleInputBlur(); this.handleInputBlur();
this.props.onSubmit(this.context.router.history); this.props.onSubmit(this.props.history);
} }
handleUndoClick = e => { handleUndoClick = e => {

@ -2,14 +2,12 @@ import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { withRouter } from 'react-router-dom';
import StatusContainer from '../../../containers/status_container'; import StatusContainer from '../../../containers/status_container';
export default class Conversation extends ImmutablePureComponent { export default @withRouter
class Conversation extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
conversationId: PropTypes.string.isRequired, conversationId: PropTypes.string.isRequired,
@ -19,10 +17,11 @@ export default class Conversation extends ImmutablePureComponent {
onMoveUp: PropTypes.func, onMoveUp: PropTypes.func,
onMoveDown: PropTypes.func, onMoveDown: PropTypes.func,
markRead: PropTypes.func.isRequired, markRead: PropTypes.func.isRequired,
history: PropTypes.object,
}; };
handleClick = () => { handleClick = () => {
if (!this.context.router) { if (!this.props.history) {
return; return;
} }
@ -32,8 +31,7 @@ export default class Conversation extends ImmutablePureComponent {
markRead(); markRead();
} }
// : TODO : this.props.history.push(`/statuses/${lastStatusId}`);
this.context.router.history.push(`/statuses/${lastStatusId}`);
} }
handleHotkeyMoveUp = () => { handleHotkeyMoveUp = () => {

@ -1,20 +1,20 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { withRouter } from 'react-router-dom';
import Column from 'soapbox/features/ui/components/column'; import Column from 'soapbox/features/ui/components/column';
import FollowRecommendationsContainer from './components/follow_recommendations_container'; import FollowRecommendationsContainer from './components/follow_recommendations_container';
export default class FollowRecommendations extends React.Component { export default @withRouter
class FollowRecommendations extends React.Component {
static contextTypes = { static propTypes = {
router: PropTypes.object.isRequired, history: PropTypes.object.isRequired,
}; };
onDone = () => { onDone = () => {
const { router } = this.context; this.props.history.push('/');
router.history.push('/');
} }
render() { render() {

@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { changeValue, submit, reset } from '../../../actions/group_editor'; import { changeValue, submit, reset } from '../../../actions/group_editor';
@ -31,12 +32,9 @@ const mapDispatchToProps = dispatch => ({
export default @connect(mapStateToProps, mapDispatchToProps) export default @connect(mapStateToProps, mapDispatchToProps)
@injectIntl @injectIntl
@withRouter
class Create extends React.PureComponent { class Create extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
}
static propTypes = { static propTypes = {
title: PropTypes.string.isRequired, title: PropTypes.string.isRequired,
description: PropTypes.string.isRequired, description: PropTypes.string.isRequired,
@ -48,6 +46,7 @@ class Create extends React.PureComponent {
reset: PropTypes.func.isRequired, reset: PropTypes.func.isRequired,
onDescriptionChange: PropTypes.func.isRequired, onDescriptionChange: PropTypes.func.isRequired,
onCoverImageChange: PropTypes.func.isRequired, onCoverImageChange: PropTypes.func.isRequired,
history: PropTypes.object,
}; };
constructor(props) { constructor(props) {
@ -69,7 +68,7 @@ class Create extends React.PureComponent {
handleSubmit = e => { handleSubmit = e => {
e.preventDefault(); e.preventDefault();
this.props.onSubmit(this.context.router.history); this.props.onSubmit(this.props.history);
} }
render() { render() {

@ -4,6 +4,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import MissingIndicator from 'soapbox/components/missing_indicator'; import MissingIndicator from 'soapbox/components/missing_indicator';
import { Column, Spinner } from 'soapbox/components/ui'; import { Column, Spinner } from 'soapbox/components/ui';
@ -36,12 +37,9 @@ const mapDispatchToProps = dispatch => ({
export default @connect(mapStateToProps, mapDispatchToProps) export default @connect(mapStateToProps, mapDispatchToProps)
@injectIntl @injectIntl
@withRouter
class Edit extends React.PureComponent { class Edit extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
}
static propTypes = { static propTypes = {
group: ImmutablePropTypes.map, group: ImmutablePropTypes.map,
title: PropTypes.string.isRequired, title: PropTypes.string.isRequired,
@ -54,6 +52,7 @@ class Edit extends React.PureComponent {
onDescriptionChange: PropTypes.func.isRequired, onDescriptionChange: PropTypes.func.isRequired,
onCoverImageChange: PropTypes.func.isRequired, onCoverImageChange: PropTypes.func.isRequired,
setUp: PropTypes.func.isRequired, setUp: PropTypes.func.isRequired,
history: PropTypes.object,
}; };
constructor(props) { constructor(props) {
@ -81,11 +80,11 @@ class Edit extends React.PureComponent {
handleSubmit = e => { handleSubmit = e => {
e.preventDefault(); e.preventDefault();
this.props.onSubmit(this.context.router.history); this.props.onSubmit(this.props.history);
} }
handleClick = () => { handleClick = () => {
this.props.onSubmit(this.context.router.history); this.props.onSubmit(this.props.history);
} }
render() { render() {

@ -25,10 +25,6 @@ class Header extends ImmutablePureComponent {
toggleMembership: PropTypes.func.isRequired, toggleMembership: PropTypes.func.isRequired,
}; };
static contextTypes = {
router: PropTypes.object,
};
toggle = () => { toggle = () => {
const { group, relationships, toggleMembership } = this.props; const { group, relationships, toggleMembership } = this.props;
toggleMembership(group, relationships); toggleMembership(group, relationships);

@ -28,10 +28,6 @@ export default @connect(mapStateToProps)
@injectIntl @injectIntl
class GroupTimeline extends React.PureComponent { class GroupTimeline extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,

@ -3,6 +3,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { Button, Spinner } from 'soapbox/components/ui'; import { Button, Spinner } from 'soapbox/components/ui';
import Column from 'soapbox/features/ui/components/column'; import Column from 'soapbox/features/ui/components/column';
@ -27,18 +28,16 @@ const mapStateToProps = (state, props) => ({
export default @connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
@withRouter
class ListTimeline extends React.PureComponent { class ListTimeline extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
// hasUnread: PropTypes.bool, // hasUnread: PropTypes.bool,
list: PropTypes.oneOfType([ImmutablePropTypes.map, PropTypes.bool]), list: PropTypes.oneOfType([ImmutablePropTypes.map, PropTypes.bool]),
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
history: PropTypes.object,
}; };
componentDidMount() { componentDidMount() {
@ -92,7 +91,7 @@ class ListTimeline extends React.PureComponent {
confirm: intl.formatMessage(messages.deleteConfirm), confirm: intl.formatMessage(messages.deleteConfirm),
onConfirm: () => { onConfirm: () => {
dispatch(deleteList(id)); dispatch(deleteList(id));
this.context.router.history.push('/lists'); this.props.history.push('/lists');
}, },
})); }));
} }

@ -41,10 +41,6 @@ export default @connect(mapStateToProps)
@injectIntl @injectIntl
class CommunityTimeline extends React.PureComponent { class CommunityTimeline extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,

@ -19,10 +19,6 @@ const mapStateToProps = state => {
class PinnedHostsPicker extends React.PureComponent { class PinnedHostsPicker extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
pinnedHosts: ImmutablePropTypes.orderedSet, pinnedHosts: ImmutablePropTypes.orderedSet,

@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { getSettings } from 'soapbox/actions/settings'; import { getSettings } from 'soapbox/actions/settings';
import IconButton from 'soapbox/components/icon_button'; import IconButton from 'soapbox/components/icon_button';
@ -35,12 +36,9 @@ const mapStateToProps = (state, props) => {
export default @connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
@withRouter
class RemoteTimeline extends React.PureComponent { class RemoteTimeline extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
@ -49,6 +47,7 @@ class RemoteTimeline extends React.PureComponent {
timelineId: PropTypes.string, timelineId: PropTypes.string,
instance: PropTypes.string.isRequired, instance: PropTypes.string.isRequired,
pinned: PropTypes.bool, pinned: PropTypes.bool,
history: PropTypes.object,
}; };
componentDidMount() { componentDidMount() {
@ -75,7 +74,7 @@ class RemoteTimeline extends React.PureComponent {
} }
handleCloseClick = e => { handleCloseClick = e => {
this.context.router.history.push('/timeline/fediverse'); this.props.history.push('/timeline/fediverse');
} }
handleLoadMore = maxId => { handleLoadMore = maxId => {

@ -47,10 +47,6 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
class ScheduledStatusActionBar extends ImmutablePureComponent { class ScheduledStatusActionBar extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
status: ImmutablePropTypes.map.isRequired, status: ImmutablePropTypes.map.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,

@ -27,10 +27,6 @@ export default @connect(mapStateToProps)
@injectIntl @injectIntl
class ScheduledStatuses extends ImmutablePureComponent { class ScheduledStatuses extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
statusIds: ImmutablePropTypes.orderedSet.isRequired, statusIds: ImmutablePropTypes.orderedSet.isRequired,

@ -5,6 +5,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import snackbar from 'soapbox/actions/snackbar'; import snackbar from 'soapbox/actions/snackbar';
import { Spinner } from 'soapbox/components/ui'; import { Spinner } from 'soapbox/components/ui';
@ -49,16 +50,14 @@ const mapStateToProps = state => ({
export default @connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
@withRouter
class MfaForm extends ImmutablePureComponent { class MfaForm extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
mfa: ImmutablePropTypes.map.isRequired, mfa: ImmutablePropTypes.map.isRequired,
history: PropTypes.object,
}; };
state = { state = {
@ -105,15 +104,13 @@ class MfaForm extends ImmutablePureComponent {
@connect() @connect()
@injectIntl @injectIntl
@withRouter
class DisableOtpForm extends ImmutablePureComponent { class DisableOtpForm extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
history: PropTypes.object,
}; };
state = { state = {
@ -133,7 +130,7 @@ class DisableOtpForm extends ImmutablePureComponent {
dispatch(disableMfa('totp', password)).then(() => { dispatch(disableMfa('totp', password)).then(() => {
dispatch(snackbar.success(intl.formatMessage(messages.mfaDisableSuccess))); dispatch(snackbar.success(intl.formatMessage(messages.mfaDisableSuccess)));
this.context.router.history.push('../auth/edit'); this.props.history.push('../auth/edit');
}).catch(error => { }).catch(error => {
dispatch(snackbar.error(intl.formatMessage(messages.disableFail))); dispatch(snackbar.error(intl.formatMessage(messages.disableFail)));
this.setState({ isLoading: false }); this.setState({ isLoading: false });
@ -189,15 +186,13 @@ class DisableOtpForm extends ImmutablePureComponent {
@connect() @connect()
@injectIntl @injectIntl
@withRouter
class EnableOtpForm extends ImmutablePureComponent { class EnableOtpForm extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
history: PropTypes.object,
}; };
state = { state = {
@ -215,7 +210,7 @@ class EnableOtpForm extends ImmutablePureComponent {
} }
handleCancelClick = e => { handleCancelClick = e => {
this.context.router.history.push('../auth/edit'); this.props.history.push('../auth/edit');
e.preventDefault(); e.preventDefault();
} }
@ -280,14 +275,12 @@ class EnableOtpForm extends ImmutablePureComponent {
@connect() @connect()
@injectIntl @injectIntl
@withRouter
class OtpConfirmForm extends ImmutablePureComponent { class OtpConfirmForm extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
history: PropTypes.object,
}; };
state = { state = {
@ -313,7 +306,7 @@ class OtpConfirmForm extends ImmutablePureComponent {
} }
handleCancelClick = e => { handleCancelClick = e => {
this.context.router.history.push('../auth/edit'); this.props.history.push('../auth/edit');
e.preventDefault(); e.preventDefault();
} }
@ -325,7 +318,7 @@ class OtpConfirmForm extends ImmutablePureComponent {
dispatch(confirmMfa('totp', code, password)).then(() => { dispatch(confirmMfa('totp', code, password)).then(() => {
dispatch(snackbar.success(intl.formatMessage(messages.mfaConfirmSuccess))); dispatch(snackbar.success(intl.formatMessage(messages.mfaConfirmSuccess)));
this.context.router.history.push('../auth/edit'); this.props.history.push('../auth/edit');
}).catch(error => { }).catch(error => {
dispatch(snackbar.error(intl.formatMessage(messages.confirmFail))); dispatch(snackbar.error(intl.formatMessage(messages.confirmFail)));
this.setState({ isLoading: false }); this.setState({ isLoading: false });

@ -4,6 +4,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { isUserTouching } from 'soapbox/is_mobile'; import { isUserTouching } from 'soapbox/is_mobile';
import { isStaff, isAdmin } from 'soapbox/utils/accounts'; import { isStaff, isAdmin } from 'soapbox/utils/accounts';
@ -79,12 +80,9 @@ const mapDispatchToProps = (dispatch, { status }) => ({
}, },
}); });
@withRouter
class ActionBar extends React.PureComponent { class ActionBar extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
status: ImmutablePropTypes.map.isRequired, status: ImmutablePropTypes.map.isRequired,
onReply: PropTypes.func.isRequired, onReply: PropTypes.func.isRequired,
@ -117,6 +115,7 @@ class ActionBar extends React.PureComponent {
handleEmojiSelectorExpand: PropTypes.func.isRequired, handleEmojiSelectorExpand: PropTypes.func.isRequired,
handleEmojiSelectorUnfocus: PropTypes.func.isRequired, handleEmojiSelectorUnfocus: PropTypes.func.isRequired,
features: PropTypes.object.isRequired, features: PropTypes.object.isRequired,
history: PropTypes.object,
}; };
static defaultProps = { static defaultProps = {
@ -153,7 +152,7 @@ class ActionBar extends React.PureComponent {
handleQuoteClick = () => { handleQuoteClick = () => {
const { me, onQuote, onOpenUnauthorizedModal, status } = this.props; const { me, onQuote, onOpenUnauthorizedModal, status } = this.props;
if (me) { if (me) {
onQuote(status, this.context.router.history); onQuote(status, this.props.history);
} else { } else {
onOpenUnauthorizedModal('REBLOG'); onOpenUnauthorizedModal('REBLOG');
} }
@ -225,23 +224,23 @@ class ActionBar extends React.PureComponent {
} }
handleDeleteClick = () => { handleDeleteClick = () => {
this.props.onDelete(this.props.status, this.context.router.history); this.props.onDelete(this.props.status, this.props.history);
} }
handleRedraftClick = () => { handleRedraftClick = () => {
this.props.onDelete(this.props.status, this.context.router.history, true); this.props.onDelete(this.props.status, this.props.history, true);
} }
handleDirectClick = () => { handleDirectClick = () => {
this.props.onDirect(this.props.status.get('account'), this.context.router.history); this.props.onDirect(this.props.status.get('account'), this.props.history);
} }
handleChatClick = () => { handleChatClick = () => {
this.props.onChat(this.props.status.get('account'), this.context.router.history); this.props.onChat(this.props.status.get('account'), this.props.history);
} }
handleMentionClick = () => { 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 = () => { handleMuteClick = () => {

@ -26,10 +26,6 @@ import StatusInteractionBar from './status_interaction_bar';
export default @injectIntl export default @injectIntl
class DetailedStatus extends ImmutablePureComponent { class DetailedStatus extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
status: ImmutablePropTypes.map, status: ImmutablePropTypes.map,
onOpenMedia: PropTypes.func.isRequired, onOpenMedia: PropTypes.func.isRequired,

@ -3,7 +3,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { NavLink } from 'react-router-dom'; import { NavLink, withRouter } from 'react-router-dom';
import AttachmentThumbs from 'soapbox/components/attachment_thumbs'; import AttachmentThumbs from 'soapbox/components/attachment_thumbs';
import Avatar from 'soapbox/components/avatar'; import Avatar from 'soapbox/components/avatar';
@ -16,29 +16,26 @@ const messages = defineMessages({
cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' }, cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' },
}); });
export default @injectIntl export default @injectIntl @withRouter
class QuotedStatus extends ImmutablePureComponent { class QuotedStatus extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
status: ImmutablePropTypes.map, status: ImmutablePropTypes.map,
onCancel: PropTypes.func, onCancel: PropTypes.func,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
compose: PropTypes.bool, compose: PropTypes.bool,
history: PropTypes.object,
}; };
handleExpandClick = e => { handleExpandClick = e => {
const { compose, status } = this.props; const { compose, status } = this.props;
if (!compose && e.button === 0) { if (!compose && e.button === 0) {
if (!this.context.router) { if (!this.props.history) {
return; return;
} }
this.context.router.history.push(`/@${status.getIn(['account', 'acct'])}/posts/${status.get('id')}`); this.props.history.push(`/@${status.getIn(['account', 'acct'])}/posts/${status.get('id')}`);
e.preventDefault(); e.preventDefault();
} }

@ -7,6 +7,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { launchChat } from 'soapbox/actions/chats'; import { launchChat } from 'soapbox/actions/chats';
@ -156,14 +157,11 @@ const makeMapStateToProps = () => {
return mapStateToProps; return mapStateToProps;
}; };
export default @injectIntl export default @connect(makeMapStateToProps)
@connect(makeMapStateToProps) @injectIntl
@withRouter
class Status extends ImmutablePureComponent { class Status extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
@ -174,6 +172,7 @@ class Status extends ImmutablePureComponent {
askReplyConfirmation: PropTypes.bool, askReplyConfirmation: PropTypes.bool,
domain: PropTypes.string, domain: PropTypes.string,
displayMedia: PropTypes.string, displayMedia: PropTypes.string,
history: PropTypes.object,
}; };
state = { state = {
@ -233,10 +232,10 @@ class Status extends ImmutablePureComponent {
dispatch(openModal('CONFIRM', { dispatch(openModal('CONFIRM', {
message: intl.formatMessage(messages.replyMessage), message: intl.formatMessage(messages.replyMessage),
confirm: intl.formatMessage(messages.replyConfirm), confirm: intl.formatMessage(messages.replyConfirm),
onConfirm: () => dispatch(replyCompose(status, this.context.router.history)), onConfirm: () => dispatch(replyCompose(status, this.props.history)),
})); }));
} else { } else {
dispatch(replyCompose(status, this.context.router.history)); dispatch(replyCompose(status, this.props.history));
} }
} }
@ -265,10 +264,10 @@ class Status extends ImmutablePureComponent {
dispatch(openModal('CONFIRM', { dispatch(openModal('CONFIRM', {
message: intl.formatMessage(messages.replyMessage), message: intl.formatMessage(messages.replyMessage),
confirm: intl.formatMessage(messages.replyConfirm), confirm: intl.formatMessage(messages.replyConfirm),
onConfirm: () => dispatch(quoteCompose(status, this.context.router.history)), onConfirm: () => dispatch(quoteCompose(status, this.props.history)),
})); }));
} else { } else {
dispatch(quoteCompose(status, this.context.router.history)); dispatch(quoteCompose(status, this.props.history));
} }
} }
@ -430,7 +429,7 @@ class Status extends ImmutablePureComponent {
} }
handleHotkeyOpenProfile = () => { handleHotkeyOpenProfile = () => {
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`); this.props.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
} }
handleHotkeyToggleHidden = () => { handleHotkeyToggleHidden = () => {

@ -3,6 +3,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { injectIntl, FormattedMessage, defineMessages } from 'react-intl'; import { injectIntl, FormattedMessage, defineMessages } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import IconButton from 'soapbox/components/icon_button'; import IconButton from 'soapbox/components/icon_button';
import ScrollableList from 'soapbox/components/scrollable_list'; import ScrollableList from 'soapbox/components/scrollable_list';
@ -23,20 +24,18 @@ const mapStateToProps = (state) => {
export default @connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
@withRouter
class BirthdaysModal extends React.PureComponent { class BirthdaysModal extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
accountIds: ImmutablePropTypes.orderedSet, accountIds: ImmutablePropTypes.orderedSet,
history: PropTypes.object,
}; };
componentDidMount() { componentDidMount() {
this.unlistenHistory = this.context.router.history.listen((_, action) => { this.unlistenHistory = this.props.history.listen((_, action) => {
if (action === 'PUSH') { if (action === 'PUSH') {
this.onClickClose(null, true); this.onClickClose(null, true);
} }

@ -3,6 +3,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { withRouter } from 'react-router-dom';
import Icon from 'soapbox/components/icon'; import Icon from 'soapbox/components/icon';
import { Modal, Stack, Text } from 'soapbox/components/ui'; import { Modal, Stack, Text } from 'soapbox/components/ui';
@ -13,18 +14,15 @@ const messages = defineMessages({
reblog: { id: 'status.reblog', defaultMessage: 'Repost' }, reblog: { id: 'status.reblog', defaultMessage: 'Repost' },
}); });
export default @injectIntl export default @injectIntl @withRouter
class BoostModal extends ImmutablePureComponent { class BoostModal extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
status: ImmutablePropTypes.map.isRequired, status: ImmutablePropTypes.map.isRequired,
onReblog: PropTypes.func.isRequired, onReblog: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
history: PropTypes.object,
}; };
handleReblog = () => { handleReblog = () => {
@ -36,7 +34,7 @@ class BoostModal extends ImmutablePureComponent {
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault(); e.preventDefault();
this.props.onClose(); this.props.onClose();
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`); this.props.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
} }
} }
@ -44,7 +42,7 @@ class BoostModal extends ImmutablePureComponent {
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault(); e.preventDefault();
this.props.onClose(); this.props.onClose();
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}/posts/${this.props.status.get('url')}`); this.props.history.push(`/@${this.props.status.getIn(['account', 'acct'])}/posts/${this.props.status.get('url')}`);
} }
} }

@ -4,6 +4,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { withRouter } from 'react-router-dom';
import ReactSwipeableViews from 'react-swipeable-views'; import ReactSwipeableViews from 'react-swipeable-views';
import ExtendedVideoPlayer from 'soapbox/components/extended_video_player'; import ExtendedVideoPlayer from 'soapbox/components/extended_video_player';
@ -20,7 +21,7 @@ const messages = defineMessages({
next: { id: 'lightbox.next', defaultMessage: 'Next' }, next: { id: 'lightbox.next', defaultMessage: 'Next' },
}); });
export default @injectIntl export default @injectIntl @withRouter
class MediaModal extends ImmutablePureComponent { class MediaModal extends ImmutablePureComponent {
static propTypes = { static propTypes = {
@ -30,12 +31,9 @@ class MediaModal extends ImmutablePureComponent {
index: PropTypes.number.isRequired, index: PropTypes.number.isRequired,
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
history: PropTypes.object,
}; };
static contextTypes = {
router: PropTypes.object,
}
state = { state = {
index: null, index: null,
navigationHidden: false, navigationHidden: false,
@ -97,7 +95,7 @@ class MediaModal extends ImmutablePureComponent {
const { status, account } = this.props; const { status, account } = this.props;
const acct = account.get('acct'); const acct = account.get('acct');
const statusId = status.get('id'); const statusId = status.get('id');
this.context.router.history.push(`/@${acct}/posts/${statusId}`); this.props.history.push(`/@${acct}/posts/${statusId}`);
this.props.onClose(null, true); this.props.onClose(null, true);
} }
} }

@ -3,6 +3,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { injectIntl, FormattedMessage } from 'react-intl'; import { injectIntl, FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { fetchReblogs } from 'soapbox/actions/interactions'; import { fetchReblogs } from 'soapbox/actions/interactions';
import { fetchStatus } from 'soapbox/actions/statuses'; import { fetchStatus } from 'soapbox/actions/statuses';
@ -18,12 +19,9 @@ const mapStateToProps = (state, props) => {
export default @connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
@withRouter
class ReblogsModal extends React.PureComponent { class ReblogsModal extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = { static propTypes = {
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
@ -31,6 +29,7 @@ class ReblogsModal extends React.PureComponent {
username: PropTypes.string.isRequired, username: PropTypes.string.isRequired,
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.orderedSet, accountIds: ImmutablePropTypes.orderedSet,
history: PropTypes.object,
}; };
fetchData = () => { fetchData = () => {
@ -42,7 +41,7 @@ class ReblogsModal extends React.PureComponent {
componentDidMount() { componentDidMount() {
this.fetchData(); this.fetchData();
this.unlistenHistory = this.context.router.history.listen((_, action) => { this.unlistenHistory = this.props.history.listen((_, action) => {
if (action === 'PUSH') { if (action === 'PUSH') {
this.onClickClose(null, true); this.onClickClose(null, true);
} }

@ -54,16 +54,13 @@ const mapDispatchToProps = dispatch => ({
@withRouter @withRouter
class UnauthorizedModal extends ImmutablePureComponent { class UnauthorizedModal extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object.isRequired,
};
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
features: PropTypes.object.isRequired, features: PropTypes.object.isRequired,
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
onRemoteInteraction: PropTypes.func.isRequired, onRemoteInteraction: PropTypes.func.isRequired,
userName: PropTypes.string, userName: PropTypes.string,
history: PropTypes.object.isRequired,
singleUserMode: PropTypes.bool, singleUserMode: PropTypes.bool,
}; };
@ -100,14 +97,14 @@ class UnauthorizedModal extends ImmutablePureComponent {
onLogin = (e) => { onLogin = (e) => {
e.preventDefault(); e.preventDefault();
this.context.router.history.push('/login'); this.props.history.push('/login');
this.onClickClose(); this.onClickClose();
} }
onRegister = (e) => { onRegister = (e) => {
e.preventDefault(); e.preventDefault();
this.context.router.history.push('/'); this.props.history.push('/');
this.onClickClose(); this.onClickClose();
} }

@ -3,10 +3,12 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { withRouter } from 'react-router-dom';
import Video from 'soapbox/features/video'; import Video from 'soapbox/features/video';
export default class VideoModal extends ImmutablePureComponent { export default @withRouter
class VideoModal extends ImmutablePureComponent {
static propTypes = { static propTypes = {
media: ImmutablePropTypes.map.isRequired, media: ImmutablePropTypes.map.isRequired,
@ -14,13 +16,14 @@ export default class VideoModal extends ImmutablePureComponent {
account: ImmutablePropTypes.map, account: ImmutablePropTypes.map,
time: PropTypes.number, time: PropTypes.number,
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
history: PropTypes.object,
}; };
handleStatusClick = e => { handleStatusClick = e => {
const { status, account } = this.props; const { status, account } = this.props;
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault(); e.preventDefault();
this.context.router.history.push(`/@${account.get('acct')}/posts/${status.get('id')}`); this.props.history.push(`/@${account.get('acct')}/posts/${status.get('id')}`);
} }
} }

@ -366,14 +366,11 @@ export default @connect(mapStateToProps)
@withRouter @withRouter
class UI extends React.PureComponent { class UI extends React.PureComponent {
static contextTypes = {
router: PropTypes.object.isRequired,
};
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
children: PropTypes.node, children: PropTypes.node,
location: PropTypes.object, location: PropTypes.object,
history: PropTypes.object,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
dropdownMenuIsOpen: PropTypes.bool, dropdownMenuIsOpen: PropTypes.bool,
me: SoapboxPropTypes.me, me: SoapboxPropTypes.me,
@ -462,7 +459,7 @@ class UI extends React.PureComponent {
handleServiceWorkerPostMessage = ({ data }) => { handleServiceWorkerPostMessage = ({ data }) => {
if (data.type === 'navigate') { if (data.type === 'navigate') {
this.context.router.history.push(data.path); this.props.history.push(data.path);
} else { } else {
console.warn('Unknown message type:', data.type); console.warn('Unknown message type:', data.type);
} }
@ -613,9 +610,9 @@ class UI extends React.PureComponent {
handleHotkeyBack = () => { handleHotkeyBack = () => {
if (window.history && window.history.length === 1) { if (window.history && window.history.length === 1) {
this.context.router.history.push('/'); this.props.history.push('/');
} else { } else {
this.context.router.history.goBack(); this.props.history.goBack();
} }
} }
@ -634,44 +631,44 @@ class UI extends React.PureComponent {
} }
handleHotkeyGoToHome = () => { handleHotkeyGoToHome = () => {
this.context.router.history.push('/'); this.props.history.push('/');
} }
handleHotkeyGoToNotifications = () => { handleHotkeyGoToNotifications = () => {
this.context.router.history.push('/notifications'); this.props.history.push('/notifications');
} }
handleHotkeyGoToFavourites = () => { handleHotkeyGoToFavourites = () => {
const { account } = this.props; const { account } = this.props;
if (!account) return; if (!account) return;
this.context.router.history.push(`/@${account.get('username')}/favorites`); this.props.history.push(`/@${account.get('username')}/favorites`);
} }
handleHotkeyGoToPinned = () => { handleHotkeyGoToPinned = () => {
const { account } = this.props; const { account } = this.props;
if (!account) return; if (!account) return;
this.context.router.history.push(`/@${account.get('username')}/pins`); this.props.history.push(`/@${account.get('username')}/pins`);
} }
handleHotkeyGoToProfile = () => { handleHotkeyGoToProfile = () => {
const { account } = this.props; const { account } = this.props;
if (!account) return; if (!account) return;
this.context.router.history.push(`/@${account.get('username')}`); this.props.history.push(`/@${account.get('username')}`);
} }
handleHotkeyGoToBlocked = () => { handleHotkeyGoToBlocked = () => {
this.context.router.history.push('/blocks'); this.props.history.push('/blocks');
} }
handleHotkeyGoToMuted = () => { handleHotkeyGoToMuted = () => {
this.context.router.history.push('/mutes'); this.props.history.push('/mutes');
} }
handleHotkeyGoToRequests = () => { handleHotkeyGoToRequests = () => {
this.context.router.history.push('/follow_requests'); this.props.history.push('/follow_requests');
} }
handleOpenComposeModal = () => { handleOpenComposeModal = () => {
@ -679,10 +676,15 @@ class UI extends React.PureComponent {
} }
shouldHideFAB = () => { shouldHideFAB = () => {
const path = this.context.router.history.location.pathname; const path = this.props.location.pathname;
return path.match(/^\/posts\/|^\/search|^\/getting-started|^\/chats/); return path.match(/^\/posts\/|^\/search|^\/getting-started|^\/chats/);
} }
isChatRoomLocation = () => {
const path = this.props.location.pathname;
return path.match(/^\/chats\/(.*)/);
}
render() { render() {
const { features, soapbox } = this.props; const { features, soapbox } = this.props;
const { draggingOver, mobile } = this.state; const { draggingOver, mobile } = this.state;

@ -150,7 +150,7 @@
"react-overlays": "^0.9.0", "react-overlays": "^0.9.0",
"react-popper": "^2.2.3", "react-popper": "^2.2.3",
"react-redux": "^7.2.5", "react-redux": "^7.2.5",
"react-router-dom": "^4.3.1", "react-router-dom": "^5.3.0",
"react-router-scroll-4": "^1.0.0-beta.1", "react-router-scroll-4": "^1.0.0-beta.1",
"react-simple-pull-to-refresh": "^1.3.0", "react-simple-pull-to-refresh": "^1.3.0",
"react-sparklines": "^1.7.0", "react-sparklines": "^1.7.0",

@ -1141,7 +1141,7 @@
dependencies: dependencies:
regenerator-runtime "^0.13.4" regenerator-runtime "^0.13.4"
"@babel/runtime@^7.17.0": "@babel/runtime@^7.12.13", "@babel/runtime@^7.17.0":
version "7.17.8" version "7.17.8"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.8.tgz#3e56e4aff81befa55ac3ac6a0967349fd1c5bca2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.8.tgz#3e56e4aff81befa55ac3ac6a0967349fd1c5bca2"
integrity sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA== integrity sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==
@ -5374,7 +5374,7 @@ history@*:
dependencies: dependencies:
"@babel/runtime" "^7.7.6" "@babel/runtime" "^7.7.6"
history@^4.10.1, history@^4.7.2: history@^4.10.1, history@^4.9.0:
version "4.10.1" version "4.10.1"
resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3"
integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==
@ -5386,12 +5386,7 @@ history@^4.10.1, history@^4.7.2:
tiny-warning "^1.0.0" tiny-warning "^1.0.0"
value-equal "^1.0.1" value-equal "^1.0.1"
hoist-non-react-statics@^2.5.0: hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
version "2.5.5"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47"
integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==
hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
version "3.3.2" version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@ -7412,6 +7407,14 @@ min-indent@^1.0.0:
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
mini-create-react-context@^0.4.0:
version "0.4.1"
resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz#072171561bfdc922da08a60c2197a497cc2d1d5e"
integrity sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==
dependencies:
"@babel/runtime" "^7.12.1"
tiny-warning "^1.0.3"
mini-css-extract-plugin@^1.6.2: mini-css-extract-plugin@^1.6.2:
version "1.6.2" version "1.6.2"
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz#83172b4fd812f8fc4a09d6f6d16f924f53990ca8" resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz#83172b4fd812f8fc4a09d6f6d16f924f53990ca8"
@ -8596,7 +8599,7 @@ prop-types-extra@^1.0.1:
react-is "^16.3.2" react-is "^16.3.2"
warning "^4.0.0" warning "^4.0.0"
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2" version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
@ -8840,7 +8843,7 @@ react-intl@^5.0.0:
intl-messageformat "9.9.1" intl-messageformat "9.9.1"
tslib "^2.1.0" tslib "^2.1.0"
react-is@^16.13.1, react-is@^16.3.2, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6: react-is@^16.13.1, react-is@^16.3.2, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6:
version "16.13.1" version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@ -8921,17 +8924,18 @@ react-redux@^7.2.5:
prop-types "^15.7.2" prop-types "^15.7.2"
react-is "^16.13.1" react-is "^16.13.1"
react-router-dom@^4.3.1: react-router-dom@^5.3.0:
version "4.3.1" version "5.3.0"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.3.1.tgz#4c2619fc24c4fa87c9fd18f4fb4a43fe63fbd5c6" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.0.tgz#da1bfb535a0e89a712a93b97dd76f47ad1f32363"
integrity sha512-c/MlywfxDdCp7EnB7YfPMOfMD3tOtIjrQlj/CKfNMBxdmpJP8xcz5P/UAFn3JbnQCNUxsHyVVqllF9LhgVyFCA== integrity sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ==
dependencies: dependencies:
history "^4.7.2" "@babel/runtime" "^7.12.13"
invariant "^2.2.4" history "^4.9.0"
loose-envify "^1.3.1" loose-envify "^1.3.1"
prop-types "^15.6.1" prop-types "^15.6.2"
react-router "^4.3.1" react-router "5.2.1"
warning "^4.0.1" tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
react-router-scroll-4@^1.0.0-beta.1: react-router-scroll-4@^1.0.0-beta.1:
version "1.0.0-beta.2" version "1.0.0-beta.2"
@ -8941,18 +8945,21 @@ react-router-scroll-4@^1.0.0-beta.1:
scroll-behavior "^0.9.1" scroll-behavior "^0.9.1"
warning "^3.0.0" warning "^3.0.0"
react-router@^4.3.1: react-router@5.2.1:
version "4.3.1" version "5.2.1"
resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.3.1.tgz#aada4aef14c809cb2e686b05cee4742234506c4e" resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.1.tgz#4d2e4e9d5ae9425091845b8dbc6d9d276239774d"
integrity sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg== integrity sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ==
dependencies: dependencies:
history "^4.7.2" "@babel/runtime" "^7.12.13"
hoist-non-react-statics "^2.5.0" history "^4.9.0"
invariant "^2.2.4" hoist-non-react-statics "^3.1.0"
loose-envify "^1.3.1" loose-envify "^1.3.1"
mini-create-react-context "^0.4.0"
path-to-regexp "^1.7.0" path-to-regexp "^1.7.0"
prop-types "^15.6.1" prop-types "^15.6.2"
warning "^4.0.1" react-is "^16.6.0"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
react-side-effect@^2.1.0: react-side-effect@^2.1.0:
version "2.1.1" version "2.1.1"

Loading…
Cancel
Save