Upgrade to react-router v5 (#25047)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
		@@ -236,7 +236,7 @@ module.exports = {
 | 
			
		||||
          },
 | 
			
		||||
          // Common React utilities
 | 
			
		||||
          {
 | 
			
		||||
            pattern: '{classnames,react-helmet,react-router-dom}',
 | 
			
		||||
            pattern: '{classnames,react-helmet,react-router,react-router-dom}',
 | 
			
		||||
            group: 'external',
 | 
			
		||||
            position: 'before',
 | 
			
		||||
          },
 | 
			
		||||
 
 | 
			
		||||
@@ -4,29 +4,28 @@ import { createPortal } from 'react-dom';
 | 
			
		||||
 | 
			
		||||
import { FormattedMessage } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
import { withRouter } from 'react-router-dom';
 | 
			
		||||
 | 
			
		||||
import { Icon }  from 'mastodon/components/icon';
 | 
			
		||||
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
 | 
			
		||||
 | 
			
		||||
export default class ColumnBackButton extends PureComponent {
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
class ColumnBackButton extends PureComponent {
 | 
			
		||||
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    multiColumn: PropTypes.bool,
 | 
			
		||||
    onClick: PropTypes.func,
 | 
			
		||||
    ...WithRouterPropTypes,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleClick = () => {
 | 
			
		||||
    const { router } = this.context;
 | 
			
		||||
    const { onClick } = this.props;
 | 
			
		||||
    const { onClick, history } = this.props;
 | 
			
		||||
 | 
			
		||||
    if (onClick) {
 | 
			
		||||
      onClick();
 | 
			
		||||
    } else if (router.history.location?.state?.fromMastodon) {
 | 
			
		||||
      router.history.goBack();
 | 
			
		||||
    } else if (history.location?.state?.fromMastodon) {
 | 
			
		||||
      history.goBack();
 | 
			
		||||
    } else {
 | 
			
		||||
      router.history.push('/');
 | 
			
		||||
      history.push('/');
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@@ -60,3 +59,5 @@ export default class ColumnBackButton extends PureComponent {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default withRouter(ColumnBackButton);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,10 @@ import { createPortal } from 'react-dom';
 | 
			
		||||
import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
import classNames from 'classnames';
 | 
			
		||||
import { withRouter } from 'react-router-dom';
 | 
			
		||||
 | 
			
		||||
import { Icon }  from 'mastodon/components/icon';
 | 
			
		||||
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
 | 
			
		||||
 | 
			
		||||
const messages = defineMessages({
 | 
			
		||||
  show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' },
 | 
			
		||||
@@ -18,7 +20,6 @@ const messages = defineMessages({
 | 
			
		||||
class ColumnHeader extends PureComponent {
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
    identity: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@@ -38,6 +39,7 @@ class ColumnHeader extends PureComponent {
 | 
			
		||||
    onClick: PropTypes.func,
 | 
			
		||||
    appendContent: PropTypes.node,
 | 
			
		||||
    collapseIssues: PropTypes.bool,
 | 
			
		||||
    ...WithRouterPropTypes,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  state = {
 | 
			
		||||
@@ -63,12 +65,12 @@ class ColumnHeader extends PureComponent {
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleBackClick = () => {
 | 
			
		||||
    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('/');
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@@ -78,15 +80,14 @@ class ColumnHeader extends PureComponent {
 | 
			
		||||
 | 
			
		||||
  handlePin = () => {
 | 
			
		||||
    if (!this.props.pinned) {
 | 
			
		||||
      this.context.router.history.replace('/');
 | 
			
		||||
      this.props.history.replace('/');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.props.onPin();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  render () {
 | 
			
		||||
    const { router } = this.context;
 | 
			
		||||
    const { title, icon, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues } = this.props;
 | 
			
		||||
    const { title, icon, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues, history } = this.props;
 | 
			
		||||
    const { collapsed, animating } = this.state;
 | 
			
		||||
 | 
			
		||||
    const wrapperClassName = classNames('column-header__wrapper', {
 | 
			
		||||
@@ -129,7 +130,7 @@ class ColumnHeader extends PureComponent {
 | 
			
		||||
      pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='plus' /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!pinned && ((multiColumn && router.history.location?.state?.fromMastodon) || showBackButton)) {
 | 
			
		||||
    if (!pinned && ((multiColumn && history.location?.state?.fromMastodon) || showBackButton)) {
 | 
			
		||||
      backButton = (
 | 
			
		||||
        <button onClick={this.handleBackClick} className='column-header__back-button'>
 | 
			
		||||
          <Icon id='chevron-left' className='column-back-button__icon' fixedWidth />
 | 
			
		||||
@@ -215,4 +216,4 @@ class ColumnHeader extends PureComponent {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default injectIntl(ColumnHeader);
 | 
			
		||||
export default injectIntl(withRouter(ColumnHeader));
 | 
			
		||||
 
 | 
			
		||||
@@ -2,13 +2,16 @@ import PropTypes from 'prop-types';
 | 
			
		||||
import { PureComponent, cloneElement, Children } from 'react';
 | 
			
		||||
 | 
			
		||||
import classNames from 'classnames';
 | 
			
		||||
import { withRouter } from 'react-router-dom';
 | 
			
		||||
 | 
			
		||||
import ImmutablePropTypes from 'react-immutable-proptypes';
 | 
			
		||||
 | 
			
		||||
import { supportsPassiveEvents } from 'detect-passive-events';
 | 
			
		||||
import Overlay from 'react-overlays/Overlay';
 | 
			
		||||
 | 
			
		||||
import { CircularProgress } from "./circular_progress";
 | 
			
		||||
import { CircularProgress } from 'mastodon/components/circular_progress';
 | 
			
		||||
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
 | 
			
		||||
 | 
			
		||||
import { IconButton } from './icon_button';
 | 
			
		||||
 | 
			
		||||
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
 | 
			
		||||
@@ -16,10 +19,6 @@ let id = 0;
 | 
			
		||||
 | 
			
		||||
class DropdownMenu extends PureComponent {
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    items: PropTypes.oneOfType([PropTypes.array, ImmutablePropTypes.list]).isRequired,
 | 
			
		||||
    loading: PropTypes.bool,
 | 
			
		||||
@@ -159,11 +158,7 @@ class DropdownMenu extends PureComponent {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default class Dropdown extends PureComponent {
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
class Dropdown extends PureComponent {
 | 
			
		||||
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    children: PropTypes.node,
 | 
			
		||||
@@ -183,6 +178,7 @@ export default class Dropdown extends PureComponent {
 | 
			
		||||
    renderItem: PropTypes.func,
 | 
			
		||||
    renderHeader: PropTypes.func,
 | 
			
		||||
    onItemClick: PropTypes.func,
 | 
			
		||||
    ...WithRouterPropTypes
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static defaultProps = {
 | 
			
		||||
@@ -250,7 +246,7 @@ export default class Dropdown extends PureComponent {
 | 
			
		||||
      item.action();
 | 
			
		||||
    } else if (item && item.to) {
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      this.context.router.history.push(item.to);
 | 
			
		||||
      this.props.history.push(item.to);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@@ -338,3 +334,5 @@ export default class Dropdown extends PureComponent {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default withRouter(Dropdown);
 | 
			
		||||
 
 | 
			
		||||
@@ -2,14 +2,13 @@ import PropTypes from 'prop-types';
 | 
			
		||||
import { PureComponent } from 'react';
 | 
			
		||||
 | 
			
		||||
import 'wicg-inert';
 | 
			
		||||
 | 
			
		||||
import { multiply } from 'color-blend';
 | 
			
		||||
import { createBrowserHistory } from 'history';
 | 
			
		||||
 | 
			
		||||
export default class ModalRoot extends PureComponent {
 | 
			
		||||
import { WithOptionalRouterPropTypes, withOptionalRouter } from 'mastodon/utils/react_router';
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
class ModalRoot extends PureComponent {
 | 
			
		||||
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    children: PropTypes.node,
 | 
			
		||||
@@ -20,6 +19,7 @@ export default class ModalRoot extends PureComponent {
 | 
			
		||||
      b: PropTypes.number,
 | 
			
		||||
    }),
 | 
			
		||||
    ignoreFocus: PropTypes.bool,
 | 
			
		||||
    ...WithOptionalRouterPropTypes,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  activeElement = this.props.children ? document.activeElement : null;
 | 
			
		||||
@@ -55,7 +55,7 @@ export default class ModalRoot extends PureComponent {
 | 
			
		||||
  componentDidMount () {
 | 
			
		||||
    window.addEventListener('keyup', this.handleKeyUp, false);
 | 
			
		||||
    window.addEventListener('keydown', this.handleKeyDown, false);
 | 
			
		||||
    this.history = this.context.router ? this.context.router.history : createBrowserHistory();
 | 
			
		||||
    this.history = this.props.history || createBrowserHistory();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  UNSAFE_componentWillReceiveProps (nextProps) {
 | 
			
		||||
@@ -156,3 +156,5 @@ export default class ModalRoot extends PureComponent {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default withOptionalRouter(ModalRoot);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
import { PureComponent } from 'react';
 | 
			
		||||
 | 
			
		||||
import { Switch, Route, withRouter } from 'react-router-dom';
 | 
			
		||||
 | 
			
		||||
import AccountNavigation from 'mastodon/features/account/navigation';
 | 
			
		||||
import Trends from 'mastodon/features/getting_started/containers/trends_container';
 | 
			
		||||
import { showTrends } from 'mastodon/initial_state';
 | 
			
		||||
 | 
			
		||||
const DefaultNavigation = () => (
 | 
			
		||||
  showTrends ? (
 | 
			
		||||
    <>
 | 
			
		||||
      <div className='flex-spacer' />
 | 
			
		||||
      <Trends />
 | 
			
		||||
    </>
 | 
			
		||||
  ) : null
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
class NavigationPortal extends PureComponent {
 | 
			
		||||
 | 
			
		||||
  render () {
 | 
			
		||||
    return (
 | 
			
		||||
      <Switch>
 | 
			
		||||
        <Route path='/@:acct' exact component={AccountNavigation} />
 | 
			
		||||
        <Route path='/@:acct/tagged/:tagged?' exact component={AccountNavigation} />
 | 
			
		||||
        <Route path='/@:acct/with_replies' exact component={AccountNavigation} />
 | 
			
		||||
        <Route path='/@:acct/followers' exact component={AccountNavigation} />
 | 
			
		||||
        <Route path='/@:acct/following' exact component={AccountNavigation} />
 | 
			
		||||
        <Route path='/@:acct/media' exact component={AccountNavigation} />
 | 
			
		||||
        <Route component={DefaultNavigation} />
 | 
			
		||||
      </Switch>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
export default withRouter(NavigationPortal);
 | 
			
		||||
							
								
								
									
										25
									
								
								app/javascript/mastodon/components/navigation_portal.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								app/javascript/mastodon/components/navigation_portal.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
import { Switch, Route } from 'react-router-dom';
 | 
			
		||||
 | 
			
		||||
import AccountNavigation from 'mastodon/features/account/navigation';
 | 
			
		||||
import Trends from 'mastodon/features/getting_started/containers/trends_container';
 | 
			
		||||
import { showTrends } from 'mastodon/initial_state';
 | 
			
		||||
 | 
			
		||||
const DefaultNavigation: React.FC = () =>
 | 
			
		||||
  showTrends ? (
 | 
			
		||||
    <>
 | 
			
		||||
      <div className='flex-spacer' />
 | 
			
		||||
      <Trends />
 | 
			
		||||
    </>
 | 
			
		||||
  ) : null;
 | 
			
		||||
 | 
			
		||||
export const NavigationPortal: React.FC = () => (
 | 
			
		||||
  <Switch>
 | 
			
		||||
    <Route path='/@:acct' exact component={AccountNavigation} />
 | 
			
		||||
    <Route path='/@:acct/tagged/:tagged?' exact component={AccountNavigation} />
 | 
			
		||||
    <Route path='/@:acct/with_replies' exact component={AccountNavigation} />
 | 
			
		||||
    <Route path='/@:acct/followers' exact component={AccountNavigation} />
 | 
			
		||||
    <Route path='/@:acct/following' exact component={AccountNavigation} />
 | 
			
		||||
    <Route path='/@:acct/media' exact component={AccountNavigation} />
 | 
			
		||||
    <Route component={DefaultNavigation} />
 | 
			
		||||
  </Switch>
 | 
			
		||||
);
 | 
			
		||||
@@ -1,15 +1,18 @@
 | 
			
		||||
import type { PropsWithChildren } from 'react';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
 | 
			
		||||
import { createBrowserHistory } from 'history';
 | 
			
		||||
import { Router as OriginalRouter } from 'react-router';
 | 
			
		||||
 | 
			
		||||
import type { LocationDescriptor, Path } from 'history';
 | 
			
		||||
import { createBrowserHistory } from 'history';
 | 
			
		||||
 | 
			
		||||
import { layoutFromWindow } from 'mastodon/is_mobile';
 | 
			
		||||
 | 
			
		||||
interface MastodonLocationState {
 | 
			
		||||
  fromMastodon?: boolean;
 | 
			
		||||
  mastodonModalKey?: string;
 | 
			
		||||
}
 | 
			
		||||
type HistoryPath = Path | LocationDescriptor<MastodonLocationState>;
 | 
			
		||||
 | 
			
		||||
const browserHistory = createBrowserHistory<
 | 
			
		||||
  MastodonLocationState | undefined
 | 
			
		||||
@@ -17,25 +20,36 @@ const browserHistory = createBrowserHistory<
 | 
			
		||||
const originalPush = browserHistory.push.bind(browserHistory);
 | 
			
		||||
const originalReplace = browserHistory.replace.bind(browserHistory);
 | 
			
		||||
 | 
			
		||||
browserHistory.push = (path: string, state?: MastodonLocationState) => {
 | 
			
		||||
function extractRealPath(path: HistoryPath) {
 | 
			
		||||
  if (typeof path === 'string') return path;
 | 
			
		||||
  else return path.pathname;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
browserHistory.push = (path: HistoryPath, state?: MastodonLocationState) => {
 | 
			
		||||
  state = state ?? {};
 | 
			
		||||
  state.fromMastodon = true;
 | 
			
		||||
 | 
			
		||||
  if (layoutFromWindow() === 'multi-column' && !path.startsWith('/deck')) {
 | 
			
		||||
    originalPush(`/deck${path}`, state);
 | 
			
		||||
  const realPath = extractRealPath(path);
 | 
			
		||||
  if (!realPath) return;
 | 
			
		||||
 | 
			
		||||
  if (layoutFromWindow() === 'multi-column' && !realPath.startsWith('/deck')) {
 | 
			
		||||
    originalPush(`/deck${realPath}`, state);
 | 
			
		||||
  } else {
 | 
			
		||||
    originalPush(path, state);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
browserHistory.replace = (path: string, state?: MastodonLocationState) => {
 | 
			
		||||
browserHistory.replace = (path: HistoryPath, state?: MastodonLocationState) => {
 | 
			
		||||
  if (browserHistory.location.state?.fromMastodon) {
 | 
			
		||||
    state = state ?? {};
 | 
			
		||||
    state.fromMastodon = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (layoutFromWindow() === 'multi-column' && !path.startsWith('/deck')) {
 | 
			
		||||
    originalReplace(`/deck${path}`, state);
 | 
			
		||||
  const realPath = extractRealPath(path);
 | 
			
		||||
  if (!realPath) return;
 | 
			
		||||
 | 
			
		||||
  if (layoutFromWindow() === 'multi-column' && !realPath.startsWith('/deck')) {
 | 
			
		||||
    originalReplace(`/deck${realPath}`, state);
 | 
			
		||||
  } else {
 | 
			
		||||
    originalReplace(path, state);
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
 | 
			
		||||
import { Children, cloneElement, PureComponent } from 'react';
 | 
			
		||||
 | 
			
		||||
import classNames from 'classnames';
 | 
			
		||||
import { useLocation } from 'react-router-dom';
 | 
			
		||||
 | 
			
		||||
import { List as ImmutableList } from 'immutable';
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
@@ -34,11 +35,32 @@ const mapStateToProps = (state, { scrollKey }) => {
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ScrollableList extends PureComponent {
 | 
			
		||||
// This component only exists to be able to call useLocation()
 | 
			
		||||
const IOArticleContainerWrapper = ({id, index, listLength, intersectionObserverWrapper, trackScroll, scrollKey, children}) => {
 | 
			
		||||
  const location = useLocation();
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
  return (<IntersectionObserverArticleContainer
 | 
			
		||||
    id={id}
 | 
			
		||||
    index={index}
 | 
			
		||||
    listLength={listLength}
 | 
			
		||||
    intersectionObserverWrapper={intersectionObserverWrapper}
 | 
			
		||||
    saveHeightKey={trackScroll ? `${location.key}:${scrollKey}` : null}
 | 
			
		||||
  >
 | 
			
		||||
    {children}
 | 
			
		||||
  </IntersectionObserverArticleContainer>);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
IOArticleContainerWrapper.propTypes =  {
 | 
			
		||||
  id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
 | 
			
		||||
  index: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
 | 
			
		||||
  listLength: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
 | 
			
		||||
  scrollKey: PropTypes.string.isRequired,
 | 
			
		||||
  intersectionObserverWrapper: PropTypes.object.isRequired,
 | 
			
		||||
  trackScroll: PropTypes.bool.isRequired,
 | 
			
		||||
  children: PropTypes.node,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ScrollableList extends PureComponent {
 | 
			
		||||
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    scrollKey: PropTypes.string.isRequired,
 | 
			
		||||
@@ -331,13 +353,14 @@ class ScrollableList extends PureComponent {
 | 
			
		||||
            {loadPending}
 | 
			
		||||
 | 
			
		||||
            {Children.map(this.props.children, (child, index) => (
 | 
			
		||||
              <IntersectionObserverArticleContainer
 | 
			
		||||
              <IOArticleContainerWrapper
 | 
			
		||||
                key={child.key}
 | 
			
		||||
                id={child.key}
 | 
			
		||||
                index={index}
 | 
			
		||||
                listLength={childrenCount}
 | 
			
		||||
                intersectionObserverWrapper={this.intersectionObserverWrapper}
 | 
			
		||||
                saveHeightKey={trackScroll ? `${this.context.router.route.location.key}:${scrollKey}` : null}
 | 
			
		||||
                trackScroll={trackScroll}
 | 
			
		||||
                scrollKey={scrollKey}
 | 
			
		||||
              >
 | 
			
		||||
                {cloneElement(child, {
 | 
			
		||||
                  getScrollPosition: this.getScrollPosition,
 | 
			
		||||
@@ -345,7 +368,7 @@ class ScrollableList extends PureComponent {
 | 
			
		||||
                  cachedMediaWidth: this.state.cachedMediaWidth,
 | 
			
		||||
                  cacheMediaWidth: this.cacheMediaWidth,
 | 
			
		||||
                })}
 | 
			
		||||
              </IntersectionObserverArticleContainer>
 | 
			
		||||
              </IOArticleContainerWrapper>
 | 
			
		||||
            ))}
 | 
			
		||||
 | 
			
		||||
            {loadMore}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ import { HotKeys } from 'react-hotkeys';
 | 
			
		||||
 | 
			
		||||
import { Icon }  from 'mastodon/components/icon';
 | 
			
		||||
import PictureInPicturePlaceholder from 'mastodon/components/picture_in_picture_placeholder';
 | 
			
		||||
import { withOptionalRouter, WithRouterPropTypes } from 'mastodon/utils/react_router';
 | 
			
		||||
 | 
			
		||||
import Card from '../features/status/components/card';
 | 
			
		||||
// We use the component (and not the container) since we do not want
 | 
			
		||||
@@ -72,10 +73,6 @@ const messages = defineMessages({
 | 
			
		||||
 | 
			
		||||
class Status extends ImmutablePureComponent {
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    status: ImmutablePropTypes.map,
 | 
			
		||||
    account: ImmutablePropTypes.map,
 | 
			
		||||
@@ -116,6 +113,7 @@ class Status extends ImmutablePureComponent {
 | 
			
		||||
      inUse: PropTypes.bool,
 | 
			
		||||
      available: PropTypes.bool,
 | 
			
		||||
    }),
 | 
			
		||||
    ...WithRouterPropTypes,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Avoid checking props that are functions (and whose equality will always
 | 
			
		||||
@@ -258,7 +256,7 @@ class Status extends ImmutablePureComponent {
 | 
			
		||||
 | 
			
		||||
  handleHotkeyReply = e => {
 | 
			
		||||
    e.preventDefault();
 | 
			
		||||
    this.props.onReply(this._properStatus(), this.context.router.history);
 | 
			
		||||
    this.props.onReply(this._properStatus(), this.props.history);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleHotkeyFavourite = () => {
 | 
			
		||||
@@ -271,7 +269,7 @@ class Status extends ImmutablePureComponent {
 | 
			
		||||
 | 
			
		||||
  handleHotkeyMention = e => {
 | 
			
		||||
    e.preventDefault();
 | 
			
		||||
    this.props.onMention(this._properStatus().get('account'), this.context.router.history);
 | 
			
		||||
    this.props.onMention(this._properStatus().get('account'), this.props.history);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleHotkeyOpen = () => {
 | 
			
		||||
@@ -280,14 +278,14 @@ class Status extends ImmutablePureComponent {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const { router } = this.context;
 | 
			
		||||
    const { history } = this.props;
 | 
			
		||||
    const status = this._properStatus();
 | 
			
		||||
 | 
			
		||||
    if (!router) {
 | 
			
		||||
    if (!history) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    router.history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
 | 
			
		||||
    history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleHotkeyOpenProfile = () => {
 | 
			
		||||
@@ -295,14 +293,14 @@ class Status extends ImmutablePureComponent {
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  _openProfile = (proper = true) => {
 | 
			
		||||
    const { router } = this.context;
 | 
			
		||||
    const { history } = this.props;
 | 
			
		||||
    const status = proper ? this._properStatus() : this.props.status;
 | 
			
		||||
 | 
			
		||||
    if (!router) {
 | 
			
		||||
    if (!history) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    router.history.push(`/@${status.getIn(['account', 'acct'])}`);
 | 
			
		||||
    history.push(`/@${status.getIn(['account', 'acct'])}`);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleHotkeyMoveUp = e => {
 | 
			
		||||
@@ -596,4 +594,4 @@ class Status extends ImmutablePureComponent {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default injectIntl(Status);
 | 
			
		||||
export default withOptionalRouter(injectIntl(Status));
 | 
			
		||||
 
 | 
			
		||||
@@ -3,12 +3,14 @@ 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';
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
 | 
			
		||||
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
 | 
			
		||||
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
 | 
			
		||||
 | 
			
		||||
import DropdownMenuContainer from '../containers/dropdown_menu_container';
 | 
			
		||||
import { me } from '../initial_state';
 | 
			
		||||
@@ -61,7 +63,6 @@ const mapStateToProps = (state, { status }) => ({
 | 
			
		||||
class StatusActionBar extends ImmutablePureComponent {
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
    identity: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@@ -92,6 +93,7 @@ class StatusActionBar extends ImmutablePureComponent {
 | 
			
		||||
    withCounters: PropTypes.bool,
 | 
			
		||||
    scrollKey: PropTypes.string,
 | 
			
		||||
    intl: PropTypes.object.isRequired,
 | 
			
		||||
    ...WithRouterPropTypes,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Avoid checking props that are functions (and whose equality will always
 | 
			
		||||
@@ -106,7 +108,7 @@ class StatusActionBar extends ImmutablePureComponent {
 | 
			
		||||
    const { signedIn } = this.context.identity;
 | 
			
		||||
 | 
			
		||||
    if (signedIn) {
 | 
			
		||||
      this.props.onReply(this.props.status, this.context.router.history);
 | 
			
		||||
      this.props.onReply(this.props.status, this.props.history);
 | 
			
		||||
    } else {
 | 
			
		||||
      this.props.onInteractionModal('reply', this.props.status);
 | 
			
		||||
    }
 | 
			
		||||
@@ -145,15 +147,15 @@ class StatusActionBar extends ImmutablePureComponent {
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handlePinClick = () => {
 | 
			
		||||
@@ -161,11 +163,11 @@ class StatusActionBar extends ImmutablePureComponent {
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleMentionClick = () => {
 | 
			
		||||
    this.props.onMention(this.props.status.get('account'), this.context.router.history);
 | 
			
		||||
    this.props.onMention(this.props.status.get('account'), 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);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleMuteClick = () => {
 | 
			
		||||
@@ -205,7 +207,7 @@ class StatusActionBar extends ImmutablePureComponent {
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleOpen = () => {
 | 
			
		||||
    this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}/${this.props.status.get('id')}`);
 | 
			
		||||
    this.props.history.push(`/@${this.props.status.getIn(['account', 'acct'])}/${this.props.status.get('id')}`);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleEmbed = () => {
 | 
			
		||||
@@ -386,4 +388,4 @@ class StatusActionBar extends ImmutablePureComponent {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default connect(mapStateToProps)(injectIntl(StatusActionBar));
 | 
			
		||||
export default withRouter(connect(mapStateToProps)(injectIntl(StatusActionBar)));
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ import { PureComponent } from 'react';
 | 
			
		||||
import { FormattedMessage, injectIntl } 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 { connect } from 'react-redux';
 | 
			
		||||
@@ -68,7 +68,6 @@ const mapStateToProps = state => ({
 | 
			
		||||
class StatusContent extends PureComponent {
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
    identity: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@@ -83,6 +82,10 @@ class StatusContent extends PureComponent {
 | 
			
		||||
    onCollapsedToggle: PropTypes.func,
 | 
			
		||||
    languages: ImmutablePropTypes.map,
 | 
			
		||||
    intl: PropTypes.object,
 | 
			
		||||
    // from react-router
 | 
			
		||||
    match: PropTypes.object.isRequired,
 | 
			
		||||
    location: PropTypes.object.isRequired,
 | 
			
		||||
    history: PropTypes.object.isRequired
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  state = {
 | 
			
		||||
@@ -173,18 +176,18 @@ class StatusContent extends PureComponent {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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}`);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@@ -247,7 +250,7 @@ class StatusContent extends PureComponent {
 | 
			
		||||
    const spoilerContent = { __html: status.getIn(['translation', 'spoilerHtml']) || status.get('spoilerHtml') };
 | 
			
		||||
    const language = status.getIn(['translation', 'language']) || status.get('language');
 | 
			
		||||
    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--collapsed': renderReadMore,
 | 
			
		||||
    });
 | 
			
		||||
@@ -324,4 +327,4 @@ class StatusContent extends PureComponent {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default connect(mapStateToProps)(injectIntl(StatusContent));
 | 
			
		||||
export default withRouter(connect(mapStateToProps)(injectIntl(StatusContent)));
 | 
			
		||||
 
 | 
			
		||||
@@ -14,10 +14,6 @@ const messages = defineMessages({
 | 
			
		||||
 | 
			
		||||
class FeaturedTags extends ImmutablePureComponent {
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    account: ImmutablePropTypes.map,
 | 
			
		||||
    featuredTags: ImmutablePropTypes.list,
 | 
			
		||||
 
 | 
			
		||||
@@ -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));
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,6 @@ const mapStateToProps = (state, { columnId }) => {
 | 
			
		||||
class CommunityTimeline extends PureComponent {
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
    identity: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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));
 | 
			
		||||
 
 | 
			
		||||
@@ -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));
 | 
			
		||||
 
 | 
			
		||||
@@ -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));
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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));
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,6 @@ const mapStateToProps = state => ({
 | 
			
		||||
class Explore extends PureComponent {
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
    identity: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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 = {
 | 
			
		||||
 
 | 
			
		||||
@@ -66,7 +66,6 @@ const badgeDisplay = (number, limit) => {
 | 
			
		||||
class GettingStarted extends ImmutablePureComponent {
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object.isRequired,
 | 
			
		||||
    identity: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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)));
 | 
			
		||||
 
 | 
			
		||||
@@ -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));
 | 
			
		||||
 
 | 
			
		||||
@@ -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)));
 | 
			
		||||
 
 | 
			
		||||
@@ -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)));
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,6 @@ const mapStateToProps = (state, { columnId }) => {
 | 
			
		||||
class PublicTimeline extends PureComponent {
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
    identity: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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)));
 | 
			
		||||
 
 | 
			
		||||
@@ -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));
 | 
			
		||||
 
 | 
			
		||||
@@ -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)));
 | 
			
		||||
 
 | 
			
		||||
@@ -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)));
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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 () {
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										60
									
								
								app/javascript/mastodon/utils/react_router.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								app/javascript/mastodon/utils/react_router.jsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
import PropTypes from "prop-types";
 | 
			
		||||
 | 
			
		||||
import { __RouterContext } from "react-router";
 | 
			
		||||
 | 
			
		||||
import hoistStatics from "hoist-non-react-statics";
 | 
			
		||||
 | 
			
		||||
export const WithRouterPropTypes = {
 | 
			
		||||
  match: PropTypes.object.isRequired,
 | 
			
		||||
  location: PropTypes.object.isRequired,
 | 
			
		||||
  history: PropTypes.object.isRequired,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const WithOptionalRouterPropTypes = {
 | 
			
		||||
  match: PropTypes.object,
 | 
			
		||||
  location: PropTypes.object,
 | 
			
		||||
  history: PropTypes.object,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// This is copied from https://github.com/remix-run/react-router/blob/v5.3.4/packages/react-router/modules/withRouter.js
 | 
			
		||||
// but does not fail if called outside of a React Router context
 | 
			
		||||
export function withOptionalRouter(Component) {
 | 
			
		||||
  const displayName = `withRouter(${Component.displayName || Component.name})`;
 | 
			
		||||
  const C = props => {
 | 
			
		||||
    const { wrappedComponentRef, ...remainingProps } = props;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <__RouterContext.Consumer>
 | 
			
		||||
        {context => {
 | 
			
		||||
          if(context)
 | 
			
		||||
            return (
 | 
			
		||||
              <Component
 | 
			
		||||
                {...remainingProps}
 | 
			
		||||
                {...context}
 | 
			
		||||
                ref={wrappedComponentRef}
 | 
			
		||||
              />
 | 
			
		||||
            );
 | 
			
		||||
          else
 | 
			
		||||
            return (
 | 
			
		||||
              <Component
 | 
			
		||||
                {...remainingProps}
 | 
			
		||||
                ref={wrappedComponentRef}
 | 
			
		||||
              />
 | 
			
		||||
            );
 | 
			
		||||
        }}
 | 
			
		||||
      </__RouterContext.Consumer>
 | 
			
		||||
    );
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  C.displayName = displayName;
 | 
			
		||||
  C.WrappedComponent = Component;
 | 
			
		||||
  C.propTypes = {
 | 
			
		||||
    wrappedComponentRef: PropTypes.oneOfType([
 | 
			
		||||
      PropTypes.string,
 | 
			
		||||
      PropTypes.func,
 | 
			
		||||
      PropTypes.object
 | 
			
		||||
    ])
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return hoistStatics(C, Component);
 | 
			
		||||
}
 | 
			
		||||
@@ -78,6 +78,7 @@
 | 
			
		||||
    "fuzzysort": "^2.0.4",
 | 
			
		||||
    "glob": "^10.2.6",
 | 
			
		||||
    "history": "^4.10.1",
 | 
			
		||||
    "hoist-non-react-statics": "^3.3.2",
 | 
			
		||||
    "http-link-header": "^1.1.1",
 | 
			
		||||
    "immutable": "^4.3.0",
 | 
			
		||||
    "imports-loader": "^1.2.0",
 | 
			
		||||
@@ -111,8 +112,8 @@
 | 
			
		||||
    "react-overlays": "^5.2.1",
 | 
			
		||||
    "react-redux": "^8.0.4",
 | 
			
		||||
    "react-redux-loading-bar": "^5.0.4",
 | 
			
		||||
    "react-router": "^4.3.1",
 | 
			
		||||
    "react-router-dom": "^4.1.1",
 | 
			
		||||
    "react-router": "^5.3.4",
 | 
			
		||||
    "react-router-dom": "^5.3.4",
 | 
			
		||||
    "react-router-scroll-4": "^1.0.0-beta.1",
 | 
			
		||||
    "react-select": "^5.7.3",
 | 
			
		||||
    "react-sparklines": "^1.7.0",
 | 
			
		||||
@@ -158,6 +159,7 @@
 | 
			
		||||
    "@types/emoji-mart": "^3.0.9",
 | 
			
		||||
    "@types/escape-html": "^1.0.2",
 | 
			
		||||
    "@types/express": "^4.17.17",
 | 
			
		||||
    "@types/hoist-non-react-statics": "^3.3.1",
 | 
			
		||||
    "@types/http-link-header": "^1.0.3",
 | 
			
		||||
    "@types/intl": "^1.2.0",
 | 
			
		||||
    "@types/jest": "^29.5.2",
 | 
			
		||||
@@ -174,6 +176,7 @@
 | 
			
		||||
    "@types/react-immutable-proptypes": "^2.1.0",
 | 
			
		||||
    "@types/react-motion": "^0.0.35",
 | 
			
		||||
    "@types/react-overlays": "^3.1.0",
 | 
			
		||||
    "@types/react-router": "^5.1.20",
 | 
			
		||||
    "@types/react-router-dom": "^5.3.3",
 | 
			
		||||
    "@types/react-select": "^5.0.1",
 | 
			
		||||
    "@types/react-sparklines": "^1.7.2",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										80
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								yarn.lock
									
									
									
									
									
								
							@@ -1096,12 +1096,12 @@
 | 
			
		||||
  dependencies:
 | 
			
		||||
    regenerator-runtime "^0.12.0"
 | 
			
		||||
 | 
			
		||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.2.0", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.7", "@babel/runtime@^7.22.3", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
 | 
			
		||||
  version "7.22.15"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.15.tgz#38f46494ccf6cf020bd4eed7124b425e83e523b8"
 | 
			
		||||
  integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==
 | 
			
		||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.8", "@babel/runtime@^7.2.0", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.7", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
 | 
			
		||||
  version "7.21.5"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200"
 | 
			
		||||
  integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    regenerator-runtime "^0.14.0"
 | 
			
		||||
    regenerator-runtime "^0.13.11"
 | 
			
		||||
 | 
			
		||||
"@babel/runtime@^7.12.1", "@babel/runtime@^7.9.2":
 | 
			
		||||
  version "7.23.1"
 | 
			
		||||
@@ -1110,6 +1110,20 @@
 | 
			
		||||
  dependencies:
 | 
			
		||||
    regenerator-runtime "^0.14.0"
 | 
			
		||||
 | 
			
		||||
"@babel/runtime@^7.18.3":
 | 
			
		||||
  version "7.22.5"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec"
 | 
			
		||||
  integrity sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    regenerator-runtime "^0.13.11"
 | 
			
		||||
 | 
			
		||||
"@babel/runtime@^7.22.3":
 | 
			
		||||
  version "7.22.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.3.tgz#0a7fce51d43adbf0f7b517a71f4c3aaca92ebcbb"
 | 
			
		||||
  integrity sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    regenerator-runtime "^0.13.11"
 | 
			
		||||
 | 
			
		||||
"@babel/template@^7.22.15", "@babel/template@^7.22.5":
 | 
			
		||||
  version "7.22.15"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38"
 | 
			
		||||
@@ -2425,7 +2439,7 @@
 | 
			
		||||
    "@types/react" "*"
 | 
			
		||||
    "@types/react-router" "*"
 | 
			
		||||
 | 
			
		||||
"@types/react-router@*":
 | 
			
		||||
"@types/react-router@*", "@types/react-router@^5.1.20":
 | 
			
		||||
  version "5.1.20"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.20.tgz#88eccaa122a82405ef3efbcaaa5dcdd9f021387c"
 | 
			
		||||
  integrity sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==
 | 
			
		||||
@@ -6477,7 +6491,7 @@ hash.js@^1.0.0, hash.js@^1.0.3:
 | 
			
		||||
    inherits "^2.0.3"
 | 
			
		||||
    minimalistic-assert "^1.0.1"
 | 
			
		||||
 | 
			
		||||
history@^4.10.1, history@^4.7.2:
 | 
			
		||||
history@^4.10.1, history@^4.9.0:
 | 
			
		||||
  version "4.10.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3"
 | 
			
		||||
  integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==
 | 
			
		||||
@@ -6498,12 +6512,7 @@ hmac-drbg@^1.0.1:
 | 
			
		||||
    minimalistic-assert "^1.0.0"
 | 
			
		||||
    minimalistic-crypto-utils "^1.0.1"
 | 
			
		||||
 | 
			
		||||
hoist-non-react-statics@^2.5.0:
 | 
			
		||||
  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.1, hoist-non-react-statics@^3.3.2:
 | 
			
		||||
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^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"
 | 
			
		||||
  integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
 | 
			
		||||
@@ -9866,7 +9875,7 @@ prompts@^2.0.1:
 | 
			
		||||
    kleur "^3.0.3"
 | 
			
		||||
    sisteransi "^1.0.5"
 | 
			
		||||
 | 
			
		||||
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.8.1:
 | 
			
		||||
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, prop-types@^15.8.1:
 | 
			
		||||
  version "15.8.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
 | 
			
		||||
  integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
 | 
			
		||||
@@ -10085,7 +10094,7 @@ react-intl@^6.4.2:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
 | 
			
		||||
  integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
 | 
			
		||||
 | 
			
		||||
react-is@^16.13.1, react-is@^16.7.0:
 | 
			
		||||
react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0:
 | 
			
		||||
  version "16.13.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
 | 
			
		||||
  integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
 | 
			
		||||
@@ -10150,17 +10159,18 @@ react-redux@^8.0.4:
 | 
			
		||||
    react-is "^18.0.0"
 | 
			
		||||
    use-sync-external-store "^1.0.0"
 | 
			
		||||
 | 
			
		||||
react-router-dom@^4.1.1:
 | 
			
		||||
  version "4.3.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.3.1.tgz#4c2619fc24c4fa87c9fd18f4fb4a43fe63fbd5c6"
 | 
			
		||||
  integrity sha512-c/MlywfxDdCp7EnB7YfPMOfMD3tOtIjrQlj/CKfNMBxdmpJP8xcz5P/UAFn3JbnQCNUxsHyVVqllF9LhgVyFCA==
 | 
			
		||||
react-router-dom@^5.3.4:
 | 
			
		||||
  version "5.3.4"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.4.tgz#2ed62ffd88cae6db134445f4a0c0ae8b91d2e5e6"
 | 
			
		||||
  integrity sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    history "^4.7.2"
 | 
			
		||||
    invariant "^2.2.4"
 | 
			
		||||
    "@babel/runtime" "^7.12.13"
 | 
			
		||||
    history "^4.9.0"
 | 
			
		||||
    loose-envify "^1.3.1"
 | 
			
		||||
    prop-types "^15.6.1"
 | 
			
		||||
    react-router "^4.3.1"
 | 
			
		||||
    warning "^4.0.1"
 | 
			
		||||
    prop-types "^15.6.2"
 | 
			
		||||
    react-router "5.3.4"
 | 
			
		||||
    tiny-invariant "^1.0.2"
 | 
			
		||||
    tiny-warning "^1.0.0"
 | 
			
		||||
 | 
			
		||||
react-router-scroll-4@^1.0.0-beta.1:
 | 
			
		||||
  version "1.0.0-beta.2"
 | 
			
		||||
@@ -10170,18 +10180,20 @@ react-router-scroll-4@^1.0.0-beta.1:
 | 
			
		||||
    scroll-behavior "^0.9.1"
 | 
			
		||||
    warning "^3.0.0"
 | 
			
		||||
 | 
			
		||||
react-router@^4.3.1:
 | 
			
		||||
  version "4.3.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.3.1.tgz#aada4aef14c809cb2e686b05cee4742234506c4e"
 | 
			
		||||
  integrity sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==
 | 
			
		||||
react-router@5.3.4, react-router@^5.3.4:
 | 
			
		||||
  version "5.3.4"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.3.4.tgz#8ca252d70fcc37841e31473c7a151cf777887bb5"
 | 
			
		||||
  integrity sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    history "^4.7.2"
 | 
			
		||||
    hoist-non-react-statics "^2.5.0"
 | 
			
		||||
    invariant "^2.2.4"
 | 
			
		||||
    "@babel/runtime" "^7.12.13"
 | 
			
		||||
    history "^4.9.0"
 | 
			
		||||
    hoist-non-react-statics "^3.1.0"
 | 
			
		||||
    loose-envify "^1.3.1"
 | 
			
		||||
    path-to-regexp "^1.7.0"
 | 
			
		||||
    prop-types "^15.6.1"
 | 
			
		||||
    warning "^4.0.1"
 | 
			
		||||
    prop-types "^15.6.2"
 | 
			
		||||
    react-is "^16.6.0"
 | 
			
		||||
    tiny-invariant "^1.0.2"
 | 
			
		||||
    tiny-warning "^1.0.0"
 | 
			
		||||
 | 
			
		||||
react-select@*, react-select@^5.7.3:
 | 
			
		||||
  version "5.7.4"
 | 
			
		||||
@@ -10432,7 +10444,7 @@ regenerator-runtime@^0.12.0:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de"
 | 
			
		||||
  integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==
 | 
			
		||||
 | 
			
		||||
regenerator-runtime@^0.13.3:
 | 
			
		||||
regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.3:
 | 
			
		||||
  version "0.13.11"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
 | 
			
		||||
  integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user