From 8f03fdce7fa16fcaa829a40f395cefc85eb957d5 Mon Sep 17 00:00:00 2001 From: Sorin Davidoi Date: Tue, 20 Jun 2017 20:40:03 +0200 Subject: Upgrade React Router (#3677) * chore(yarn): Remove react-router * chore(yarn): Remove react-router-scroll * chore(yarn): Remove history * chore(yarn): Add react-router-dom * chore: Remove usages of react-router-scroll * refactor: Upgrade to react-router-web * refactor: Use fork of react-router-scroll This reverts commit 2ddea9a6c8d39fc64b7d0b587f3fbda7a45a7fa2. * fix: Issues mentions in the PR feedback --- .../mastodon/components/column_back_button.js | 4 +- .../mastodon/components/column_back_button_slim.js | 4 +- .../mastodon/components/column_header.js | 4 +- .../mastodon/components/dropdown_menu.js | 2 +- app/javascript/mastodon/components/permalink.js | 2 +- app/javascript/mastodon/components/status.js | 4 +- .../mastodon/components/status_action_bar.js | 8 +- .../mastodon/components/status_content.js | 4 +- app/javascript/mastodon/containers/mastodon.js | 70 ++-------------- .../features/account/components/action_bar.js | 2 +- .../features/account_timeline/components/header.js | 4 +- .../features/compose/components/navigation_bar.js | 2 +- .../features/compose/components/reply_indicator.js | 2 +- .../features/compose/components/search_results.js | 2 +- app/javascript/mastodon/features/compose/index.js | 2 +- .../mastodon/features/follow_requests/index.js | 1 + .../mastodon/features/getting_started/index.js | 2 +- .../mastodon/features/home_timeline/index.js | 2 +- app/javascript/mastodon/features/report/index.js | 4 +- .../features/status/components/action_bar.js | 4 +- .../features/status/components/detailed_status.js | 4 +- app/javascript/mastodon/features/status/index.js | 2 +- .../mastodon/features/ui/components/boost_modal.js | 2 +- .../mastodon/features/ui/components/column_link.js | 2 +- .../mastodon/features/ui/components/tabs_bar.js | 14 ++-- app/javascript/mastodon/features/ui/index.js | 95 +++++++++++++++++++++- 26 files changed, 144 insertions(+), 104 deletions(-) (limited to 'app/javascript/mastodon') diff --git a/app/javascript/mastodon/components/column_back_button.js b/app/javascript/mastodon/components/column_back_button.js index 3add65968..191c0f597 100644 --- a/app/javascript/mastodon/components/column_back_button.js +++ b/app/javascript/mastodon/components/column_back_button.js @@ -9,8 +9,8 @@ class ColumnBackButton extends React.PureComponent { }; handleClick = () => { - if (window.history && window.history.length === 1) this.context.router.push('/'); - else this.context.router.goBack(); + if (window.history && window.history.length === 1) this.context.router.history.push('/'); + else this.context.router.history.goBack(); } render () { diff --git a/app/javascript/mastodon/components/column_back_button_slim.js b/app/javascript/mastodon/components/column_back_button_slim.js index 2d3f1b57a..ffb05fa02 100644 --- a/app/javascript/mastodon/components/column_back_button_slim.js +++ b/app/javascript/mastodon/components/column_back_button_slim.js @@ -9,8 +9,8 @@ class ColumnBackButtonSlim extends React.PureComponent { }; handleClick = () => { - if (window.history && window.history.length === 1) this.context.router.push('/'); - else this.context.router.goBack(); + if (window.history && window.history.length === 1) this.context.router.history.push('/'); + else this.context.router.history.goBack(); } render () { diff --git a/app/javascript/mastodon/components/column_header.js b/app/javascript/mastodon/components/column_header.js index 175ee800f..076f1cdad 100644 --- a/app/javascript/mastodon/components/column_header.js +++ b/app/javascript/mastodon/components/column_header.js @@ -45,8 +45,8 @@ class ColumnHeader extends React.PureComponent { } handleBackClick = () => { - if (window.history && window.history.length === 1) this.context.router.push('/'); - else this.context.router.goBack(); + if (window.history && window.history.length === 1) this.context.router.history.push('/'); + else this.context.router.history.goBack(); } handleTransitionEnd = () => { diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js index 5712cffab..6e394a95d 100644 --- a/app/javascript/mastodon/components/dropdown_menu.js +++ b/app/javascript/mastodon/components/dropdown_menu.js @@ -41,7 +41,7 @@ class DropdownMenu extends React.PureComponent { action(); } else if (to) { e.preventDefault(); - this.context.router.push(to); + this.context.router.history.push(to); } this.dropdown.hide(); diff --git a/app/javascript/mastodon/components/permalink.js b/app/javascript/mastodon/components/permalink.js index b45969d85..7149e8380 100644 --- a/app/javascript/mastodon/components/permalink.js +++ b/app/javascript/mastodon/components/permalink.js @@ -17,7 +17,7 @@ class Permalink extends React.PureComponent { handleClick = (e) => { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { e.preventDefault(); - this.context.router.push(this.props.to); + this.context.router.history.push(this.props.to); } } diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index 8c4443967..b2214f72a 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -144,14 +144,14 @@ class Status extends ImmutablePureComponent { handleClick = () => { const { status } = this.props; - this.context.router.push(`/statuses/${status.getIn(['reblog', 'id'], status.get('id'))}`); + this.context.router.history.push(`/statuses/${status.getIn(['reblog', 'id'], status.get('id'))}`); } handleAccountClick = (e) => { if (e.button === 0) { const id = Number(e.currentTarget.getAttribute('data-id')); e.preventDefault(); - this.context.router.push(`/accounts/${id}`); + this.context.router.history.push(`/accounts/${id}`); } } diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js index 99e01d972..800f0d0fb 100644 --- a/app/javascript/mastodon/components/status_action_bar.js +++ b/app/javascript/mastodon/components/status_action_bar.js @@ -53,7 +53,7 @@ class StatusActionBar extends ImmutablePureComponent { ] handleReplyClick = () => { - this.props.onReply(this.props.status, this.context.router); + this.props.onReply(this.props.status, this.context.router.history); } handleFavouriteClick = () => { @@ -69,7 +69,7 @@ class StatusActionBar extends ImmutablePureComponent { } handleMentionClick = () => { - this.props.onMention(this.props.status.get('account'), this.context.router); + this.props.onMention(this.props.status.get('account'), this.context.router.history); } handleMuteClick = () => { @@ -81,12 +81,12 @@ class StatusActionBar extends ImmutablePureComponent { } handleOpen = () => { - this.context.router.push(`/statuses/${this.props.status.get('id')}`); + this.context.router.history.push(`/statuses/${this.props.status.get('id')}`); } handleReport = () => { this.props.onReport(this.props.status); - this.context.router.push('/report'); + this.context.router.history.push('/report'); } handleConversationMuteClick = () => { diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js index 0a71cbba7..d02083d3e 100644 --- a/app/javascript/mastodon/components/status_content.js +++ b/app/javascript/mastodon/components/status_content.js @@ -56,7 +56,7 @@ class StatusContent extends React.PureComponent { onMentionClick = (mention, e) => { if (e.button === 0) { e.preventDefault(); - this.context.router.push(`/accounts/${mention.get('id')}`); + this.context.router.history.push(`/accounts/${mention.get('id')}`); } } @@ -65,7 +65,7 @@ class StatusContent extends React.PureComponent { if (e.button === 0) { e.preventDefault(); - this.context.router.push(`/timelines/tag/${hashtag}`); + this.context.router.history.push(`/timelines/tag/${hashtag}`); } } diff --git a/app/javascript/mastodon/containers/mastodon.js b/app/javascript/mastodon/containers/mastodon.js index 5e009cfa3..d44cb1be4 100644 --- a/app/javascript/mastodon/containers/mastodon.js +++ b/app/javascript/mastodon/containers/mastodon.js @@ -12,35 +12,10 @@ import { } from '../actions/timelines'; import { showOnboardingOnce } from '../actions/onboarding'; import { updateNotifications, refreshNotifications } from '../actions/notifications'; -import createBrowserHistory from 'history/lib/createBrowserHistory'; -import applyRouterMiddleware from 'react-router/lib/applyRouterMiddleware'; -import useRouterHistory from 'react-router/lib/useRouterHistory'; -import Router from 'react-router/lib/Router'; -import Route from 'react-router/lib/Route'; -import IndexRedirect from 'react-router/lib/IndexRedirect'; -import IndexRoute from 'react-router/lib/IndexRoute'; -import { useScroll } from 'react-router-scroll'; +import BrowserRouter from 'react-router-dom/BrowserRouter'; +import Route from 'react-router-dom/Route'; +import ScrollContext from 'react-router-scroll/lib/ScrollBehaviorContext'; import UI from '../features/ui'; -import Status from '../features/status'; -import GettingStarted from '../features/getting_started'; -import PublicTimeline from '../features/public_timeline'; -import CommunityTimeline from '../features/community_timeline'; -import AccountTimeline from '../features/account_timeline'; -import AccountGallery from '../features/account_gallery'; -import HomeTimeline from '../features/home_timeline'; -import Compose from '../features/compose'; -import Followers from '../features/followers'; -import Following from '../features/following'; -import Reblogs from '../features/reblogs'; -import Favourites from '../features/favourites'; -import HashtagTimeline from '../features/hashtag_timeline'; -import Notifications from '../features/notifications'; -import FollowRequests from '../features/follow_requests'; -import GenericNotFound from '../features/generic_not_found'; -import FavouritedStatuses from '../features/favourited_statuses'; -import Blocks from '../features/blocks'; -import Mutes from '../features/mutes'; -import Report from '../features/report'; import { hydrateStore } from '../actions/store'; import createStream from '../stream'; import { IntlProvider, addLocaleData } from 'react-intl'; @@ -52,10 +27,6 @@ const store = configureStore(); const initialState = JSON.parse(document.getElementById('initial-state').textContent); store.dispatch(hydrateStore(initialState)); -const browserHistory = useRouterHistory(createBrowserHistory)({ - basename: '/web', -}); - class Mastodon extends React.PureComponent { componentDidMount() { @@ -136,36 +107,11 @@ class Mastodon extends React.PureComponent { return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + ); diff --git a/app/javascript/mastodon/features/account/components/action_bar.js b/app/javascript/mastodon/features/account/components/action_bar.js index 15fdd1a50..0ea8ad347 100644 --- a/app/javascript/mastodon/features/account/components/action_bar.js +++ b/app/javascript/mastodon/features/account/components/action_bar.js @@ -2,7 +2,7 @@ import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import DropdownMenu from '../../../components/dropdown_menu'; -import Link from 'react-router/lib/Link'; +import Link from 'react-router-dom/Link'; import { defineMessages, injectIntl, FormattedMessage, FormattedNumber } from 'react-intl'; const messages = defineMessages({ diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.js index d2fe86476..55fdc4167 100644 --- a/app/javascript/mastodon/features/account_timeline/components/header.js +++ b/app/javascript/mastodon/features/account_timeline/components/header.js @@ -33,12 +33,12 @@ class Header extends ImmutablePureComponent { } handleMention = () => { - this.props.onMention(this.props.account, this.context.router); + this.props.onMention(this.props.account, this.context.router.history); } handleReport = () => { this.props.onReport(this.props.account); - this.context.router.push('/report'); + this.context.router.history.push('/report'); } handleMute = () => { diff --git a/app/javascript/mastodon/features/compose/components/navigation_bar.js b/app/javascript/mastodon/features/compose/components/navigation_bar.js index 6f3dbc5af..1c135a733 100644 --- a/app/javascript/mastodon/features/compose/components/navigation_bar.js +++ b/app/javascript/mastodon/features/compose/components/navigation_bar.js @@ -5,7 +5,7 @@ import IconButton from '../../../components/icon_button'; import DisplayName from '../../../components/display_name'; import Permalink from '../../../components/permalink'; import { FormattedMessage } from 'react-intl'; -import Link from 'react-router/lib/Link'; +import Link from 'react-router-dom/Link'; import ImmutablePureComponent from 'react-immutable-pure-component'; class NavigationBar extends ImmutablePureComponent { diff --git a/app/javascript/mastodon/features/compose/components/reply_indicator.js b/app/javascript/mastodon/features/compose/components/reply_indicator.js index 8ad401121..474549a5f 100644 --- a/app/javascript/mastodon/features/compose/components/reply_indicator.js +++ b/app/javascript/mastodon/features/compose/components/reply_indicator.js @@ -31,7 +31,7 @@ class ReplyIndicator extends ImmutablePureComponent { handleAccountClick = (e) => { if (e.button === 0) { e.preventDefault(); - this.context.router.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`); + this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`); } } diff --git a/app/javascript/mastodon/features/compose/components/search_results.js b/app/javascript/mastodon/features/compose/components/search_results.js index a553a8280..26d766a1c 100644 --- a/app/javascript/mastodon/features/compose/components/search_results.js +++ b/app/javascript/mastodon/features/compose/components/search_results.js @@ -3,7 +3,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import AccountContainer from '../../../containers/account_container'; import StatusContainer from '../../../containers/status_container'; -import Link from 'react-router/lib/Link'; +import Link from 'react-router-dom/Link'; import ImmutablePureComponent from 'react-immutable-pure-component'; class SearchResults extends ImmutablePureComponent { diff --git a/app/javascript/mastodon/features/compose/index.js b/app/javascript/mastodon/features/compose/index.js index e7d933e86..a87e48a23 100644 --- a/app/javascript/mastodon/features/compose/index.js +++ b/app/javascript/mastodon/features/compose/index.js @@ -5,7 +5,7 @@ import NavigationContainer from './containers/navigation_container'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { mountCompose, unmountCompose } from '../../actions/compose'; -import Link from 'react-router/lib/Link'; +import Link from 'react-router-dom/Link'; import { injectIntl, defineMessages } from 'react-intl'; import SearchContainer from './containers/search_container'; import Motion from 'react-motion/lib/Motion'; diff --git a/app/javascript/mastodon/features/follow_requests/index.js b/app/javascript/mastodon/features/follow_requests/index.js index 446fdbc6e..286f128f4 100644 --- a/app/javascript/mastodon/features/follow_requests/index.js +++ b/app/javascript/mastodon/features/follow_requests/index.js @@ -54,6 +54,7 @@ class FollowRequests extends ImmutablePureComponent { return ( +
{accountIds.map(id => diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js index f30dea446..a4549e609 100644 --- a/app/javascript/mastodon/features/getting_started/index.js +++ b/app/javascript/mastodon/features/getting_started/index.js @@ -2,7 +2,7 @@ import React from 'react'; import Column from '../ui/components/column'; import ColumnLink from '../ui/components/column_link'; import ColumnSubheading from '../ui/components/column_subheading'; -import Link from 'react-router/lib/Link'; +import Link from 'react-router-dom/Link'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; diff --git a/app/javascript/mastodon/features/home_timeline/index.js b/app/javascript/mastodon/features/home_timeline/index.js index 6d3968751..ddebf2379 100644 --- a/app/javascript/mastodon/features/home_timeline/index.js +++ b/app/javascript/mastodon/features/home_timeline/index.js @@ -8,7 +8,7 @@ import ColumnHeader from '../../components/column_header'; import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import ColumnSettingsContainer from './containers/column_settings_container'; -import Link from 'react-router/lib/Link'; +import Link from 'react-router-dom/Link'; const messages = defineMessages({ title: { id: 'column.home', defaultMessage: 'Home' }, diff --git a/app/javascript/mastodon/features/report/index.js b/app/javascript/mastodon/features/report/index.js index 217802b5c..23aba39de 100644 --- a/app/javascript/mastodon/features/report/index.js +++ b/app/javascript/mastodon/features/report/index.js @@ -52,7 +52,7 @@ class Report extends React.PureComponent { componentWillMount () { if (!this.props.account) { - this.context.router.replace('/'); + this.context.router.history.replace('/'); } } @@ -76,7 +76,7 @@ class Report extends React.PureComponent { handleSubmit = () => { this.props.dispatch(submitReport()); - this.context.router.replace('/'); + this.context.router.history.replace('/'); } render () { diff --git a/app/javascript/mastodon/features/status/components/action_bar.js b/app/javascript/mastodon/features/status/components/action_bar.js index 16ea83e40..21c2fd682 100644 --- a/app/javascript/mastodon/features/status/components/action_bar.js +++ b/app/javascript/mastodon/features/status/components/action_bar.js @@ -50,12 +50,12 @@ class ActionBar extends React.PureComponent { } handleMentionClick = () => { - this.props.onMention(this.props.status.get('account'), this.context.router); + this.props.onMention(this.props.status.get('account'), this.context.router.history); } handleReport = () => { this.props.onReport(this.props.status); - this.context.router.push('/report'); + this.context.router.history.push('/report'); } render () { diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js index 6bbb8ca33..a77c4f0bb 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.js +++ b/app/javascript/mastodon/features/status/components/detailed_status.js @@ -7,7 +7,7 @@ import StatusContent from '../../../components/status_content'; import MediaGallery from '../../../components/media_gallery'; import VideoPlayer from '../../../components/video_player'; import AttachmentList from '../../../components/attachment_list'; -import Link from 'react-router/lib/Link'; +import Link from 'react-router-dom/Link'; import { FormattedDate, FormattedNumber } from 'react-intl'; import CardContainer from '../containers/card_container'; import ImmutablePureComponent from 'react-immutable-pure-component'; @@ -28,7 +28,7 @@ class DetailedStatus extends ImmutablePureComponent { handleAccountClick = (e) => { if (e.button === 0) { e.preventDefault(); - this.context.router.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`); + this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`); } e.stopPropagation(); diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js index f8a87ccb1..19cee2435 100644 --- a/app/javascript/mastodon/features/status/index.js +++ b/app/javascript/mastodon/features/status/index.js @@ -93,7 +93,7 @@ class Status extends ImmutablePureComponent { } handleReplyClick = (status) => { - this.props.dispatch(replyCompose(status, this.context.router)); + this.props.dispatch(replyCompose(status, this.context.router.history)); } handleModalReblog = (status) => { diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.js b/app/javascript/mastodon/features/ui/components/boost_modal.js index 9d99b5336..da2be5264 100644 --- a/app/javascript/mastodon/features/ui/components/boost_modal.js +++ b/app/javascript/mastodon/features/ui/components/boost_modal.js @@ -40,7 +40,7 @@ class BoostModal extends ImmutablePureComponent { if (e.button === 0) { e.preventDefault(); this.props.onClose(); - this.context.router.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`); + this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`); } } diff --git a/app/javascript/mastodon/features/ui/components/column_link.js b/app/javascript/mastodon/features/ui/components/column_link.js index 24387af57..cbdb6534f 100644 --- a/app/javascript/mastodon/features/ui/components/column_link.js +++ b/app/javascript/mastodon/features/ui/components/column_link.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import Link from 'react-router/lib/Link'; +import Link from 'react-router-dom/Link'; const ColumnLink = ({ icon, text, to, href, method, hideOnMobile }) => { if (href) { diff --git a/app/javascript/mastodon/features/ui/components/tabs_bar.js b/app/javascript/mastodon/features/ui/components/tabs_bar.js index b108e8244..265cb818b 100644 --- a/app/javascript/mastodon/features/ui/components/tabs_bar.js +++ b/app/javascript/mastodon/features/ui/components/tabs_bar.js @@ -1,5 +1,5 @@ import React from 'react'; -import Link from 'react-router/lib/Link'; +import NavLink from 'react-router-dom/NavLink'; import { FormattedMessage } from 'react-intl'; class TabsBar extends React.Component { @@ -7,14 +7,14 @@ class TabsBar extends React.Component { render () { return (
- - - + + + - - + + - +
); } diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index 9f31b5443..39600607f 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -1,4 +1,7 @@ import React from 'react'; +import Switch from 'react-router-dom/Switch'; +import Route from 'react-router-dom/Route'; +import Redirect from 'react-router-dom/Redirect'; import NotificationsContainer from './containers/notifications_container'; import PropTypes from 'prop-types'; import LoadingBarContainer from './containers/loading_bar_container'; @@ -13,6 +16,67 @@ import { refreshNotifications } from '../../actions/notifications'; import UploadArea from './components/upload_area'; import ColumnsAreaContainer from './containers/columns_area_container'; +import Status from '../../features/status'; +import GettingStarted from '../../features/getting_started'; +import PublicTimeline from '../../features/public_timeline'; +import CommunityTimeline from '../../features/community_timeline'; +import AccountTimeline from '../../features/account_timeline'; +import AccountGallery from '../../features/account_gallery'; +import HomeTimeline from '../../features/home_timeline'; +import Compose from '../../features/compose'; +import Followers from '../../features/followers'; +import Following from '../../features/following'; +import Reblogs from '../../features/reblogs'; +import Favourites from '../../features/favourites'; +import HashtagTimeline from '../../features/hashtag_timeline'; +import Notifications from '../../features/notifications'; +import FollowRequests from '../../features/follow_requests'; +import GenericNotFound from '../../features/generic_not_found'; +import FavouritedStatuses from '../../features/favourited_statuses'; +import Blocks from '../../features/blocks'; +import Mutes from '../../features/mutes'; +import Report from '../../features/report'; + +// Small wrapper to pass multiColumn to the route components +const WrappedSwitch = ({ multiColumn, children }) => ( + + {React.Children.map(children, child => React.cloneElement(child, { multiColumn }))} + +); + +WrappedSwitch.propTypes = { + multiColumn: PropTypes.bool, + children: PropTypes.node, +}; + +// Small Wraper to extract the params from the route and pass +// them to the rendered component, together with the content to +// be rendered inside (the children) +class WrappedRoute extends React.Component { + + static propTypes = { + component: PropTypes.func.isRequired, + content: PropTypes.node, + multiColumn: PropTypes.bool, + } + + renderComponent = ({ match: { params } }) => { + const { component: Component, content, multiColumn } = this.props; + + return {content}; + } + + render () { + const { component: Component, content, ...rest } = this.props; + + return ; + } + +} + +const noOp = () => false; + + class UI extends React.PureComponent { static propTypes = { @@ -119,7 +183,36 @@ class UI extends React.PureComponent { return (
- {children} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit