From 12ed6889a40d6f98b146f78e4ea9accecfa3d9e9 Mon Sep 17 00:00:00 2001 From: Justin Date: Tue, 22 Mar 2022 08:28:18 -0400 Subject: [PATCH 1/5] Use React Router Link in MenuLink --- app/soapbox/features/account/components/header.js | 4 ++-- app/soapbox/features/ui/components/profile-dropdown.tsx | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/soapbox/features/account/components/header.js b/app/soapbox/features/account/components/header.js index 744689830..42fcad65d 100644 --- a/app/soapbox/features/account/components/header.js +++ b/app/soapbox/features/account/components/header.js @@ -9,6 +9,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import InlineSVG from 'react-inlinesvg'; import { defineMessages, injectIntl } from 'react-intl'; import { connect } from 'react-redux'; +import { Link } from 'react-router-dom'; import { openModal } from 'soapbox/actions/modals'; import Avatar from 'soapbox/components/avatar'; @@ -612,8 +613,7 @@ class Header extends ImmutablePureComponent { return ; } else { const Comp = menuItem.action ? MenuItem : MenuLink; - // TODO: Add `as: Link` once React Router is upgraded. - const itemProps = menuItem.action ? { onSelect: menuItem.action } : { to: menuItem.to, target: menuItem.newTab ? '_blank' : '_self' }; + const itemProps = menuItem.action ? { onSelect: menuItem.action } : { to: menuItem.to, as: Link, target: menuItem.newTab ? '_blank' : '_self' }; return ( diff --git a/app/soapbox/features/ui/components/profile-dropdown.tsx b/app/soapbox/features/ui/components/profile-dropdown.tsx index b2aa85e7a..f5a0d355c 100644 --- a/app/soapbox/features/ui/components/profile-dropdown.tsx +++ b/app/soapbox/features/ui/components/profile-dropdown.tsx @@ -2,6 +2,7 @@ import throttle from 'lodash/throttle'; import React from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { useDispatch } from 'react-redux'; +import { Link } from 'react-router-dom'; import { logOut, switchAccount } from 'soapbox/actions/auth'; import { fetchOwnAccounts } from 'soapbox/actions/auth'; @@ -115,7 +116,7 @@ const ProfileDropdown: React.FC = ({ account, children }) => { return ; } else { const Comp: any = menuItem.action ? MenuItem : MenuLink; - const itemProps = menuItem.action ? { onSelect: menuItem.action } : { href: menuItem.to }; + const itemProps = menuItem.action ? { onSelect: menuItem.action } : { to: menuItem.to, as: Link }; return ( From 40cc960985fddf1f5e298696443dbcfbdf87d371 Mon Sep 17 00:00:00 2001 From: Justin Date: Tue, 22 Mar 2022 08:42:26 -0400 Subject: [PATCH 2/5] Use React Router hook for 'history' --- app/soapbox/components/account.tsx | 6 ++-- app/soapbox/components/profile_hover_card.js | 8 ++--- app/soapbox/components/ui/column/column.tsx | 10 +++--- app/soapbox/components/ui/tabs/tabs.tsx | 10 +++--- .../features/compose/components/search.tsx | 8 ++--- .../features/developers/developers_menu.js | 14 +++------ .../notifications/components/notification.js | 9 +++--- app/soapbox/features/settings/index.js | 15 ++++----- .../features/settings/media_display.js | 25 +++++---------- .../features/verification/email_passthru.js | 5 ++- package.json | 2 +- yarn.lock | 31 +++---------------- 12 files changed, 54 insertions(+), 89 deletions(-) diff --git a/app/soapbox/components/account.tsx b/app/soapbox/components/account.tsx index 4fd4d4218..47dc5d769 100644 --- a/app/soapbox/components/account.tsx +++ b/app/soapbox/components/account.tsx @@ -119,7 +119,7 @@ const Account = ({ ); } - const LinkEl = showProfileHoverCard ? Link : 'div'; + const LinkEl: any = showProfileHoverCard ? Link : 'div'; return (
@@ -132,7 +132,7 @@ const Account = ({ event.stopPropagation()} + onClick={(event: React.MouseEvent) => event.stopPropagation()} > @@ -146,7 +146,7 @@ const Account = ({ event.stopPropagation()} + onClick={(event: React.MouseEvent) => event.stopPropagation()} >
{ }; }; -export const ProfileHoverCard = ({ history, visible }) => { +export const ProfileHoverCard = ({ visible }) => { const dispatch = useDispatch(); + const history = useHistory(); const intl = useIntl(); const [popperElement, setPopperElement] = useState(null); @@ -134,11 +135,10 @@ ProfileHoverCard.propTypes = { visible: PropTypes.bool, accountId: PropTypes.string, account: ImmutablePropTypes.map, - history: PropTypes.object.isRequired, }; ProfileHoverCard.defaultProps = { visible: true, }; -export default withRouter(ProfileHoverCard); +export default ProfileHoverCard; diff --git a/app/soapbox/components/ui/column/column.tsx b/app/soapbox/components/ui/column/column.tsx index 08ef17b9a..59d88ace3 100644 --- a/app/soapbox/components/ui/column/column.tsx +++ b/app/soapbox/components/ui/column/column.tsx @@ -1,11 +1,11 @@ import React from 'react'; -import { RouteComponentProps, withRouter } from 'react-router-dom'; +import { useHistory } from 'react-router-dom'; import Helmet from 'soapbox/components/helmet'; import { Card, CardBody, CardHeader, CardTitle } from '../card/card'; -interface IColumn extends RouteComponentProps { +interface IColumn { backHref?: string, label?: string, transparent?: boolean, @@ -13,7 +13,9 @@ interface IColumn extends RouteComponentProps { } const Column: React.FC = React.forwardRef((props, ref: React.ForwardedRef): JSX.Element => { - const { backHref, children, label, history, transparent = false, withHeader = true } = props; + const { backHref, children, label, transparent = false, withHeader = true } = props; + + const history = useHistory(); const handleBackClick = () => { if (backHref) { @@ -57,4 +59,4 @@ const Column: React.FC = React.forwardRef((props, ref: React.ForwardedR ); }); -export default withRouter(Column); +export default Column; diff --git a/app/soapbox/components/ui/tabs/tabs.tsx b/app/soapbox/components/ui/tabs/tabs.tsx index bbb43267d..ad82f7a7a 100644 --- a/app/soapbox/components/ui/tabs/tabs.tsx +++ b/app/soapbox/components/ui/tabs/tabs.tsx @@ -7,7 +7,7 @@ import { } from '@reach/tabs'; import classNames from 'classnames'; import * as React from 'react'; -import { RouteComponentProps, withRouter } from 'react-router-dom'; +import { useHistory } from 'react-router-dom'; import './tabs.css'; @@ -87,14 +87,16 @@ type Item = { action?: () => void, name: string } -interface ITabs extends RouteComponentProps { +interface ITabs { items: Item[], activeItem: string, } -const Tabs = ({ items, activeItem, history }: ITabs) => { +const Tabs = ({ items, activeItem }: ITabs) => { const defaultIndex = items.findIndex(({ name }) => name === activeItem); + const history = useHistory(); + const onChange = (selectedIndex: number) => { const item = items[selectedIndex]; @@ -130,4 +132,4 @@ const Tabs = ({ items, activeItem, history }: ITabs) => { ); }; -export default withRouter(Tabs); +export default Tabs; diff --git a/app/soapbox/features/compose/components/search.tsx b/app/soapbox/features/compose/components/search.tsx index 10e1ebc6b..791aa0dbf 100644 --- a/app/soapbox/features/compose/components/search.tsx +++ b/app/soapbox/features/compose/components/search.tsx @@ -5,7 +5,7 @@ import * as React from 'react'; import InlineSVG from 'react-inlinesvg'; import { defineMessages, useIntl } from 'react-intl'; import { useDispatch } from 'react-redux'; -import { RouteComponentProps, withRouter } from 'react-router-dom'; +import { useHistory } from 'react-router-dom'; import AutosuggestAccountInput from 'soapbox/components/autosuggest_account_input'; import { useAppSelector } from 'soapbox/hooks'; @@ -32,7 +32,7 @@ function redirectToAccount(accountId: number, routerHistory: any) { }; } -interface ISearch extends RouteComponentProps { +interface ISearch { autoFocus?: boolean, autoSubmit?: boolean, autosuggest?: boolean, @@ -44,11 +44,11 @@ const Search = (props: ISearch) => { autoFocus = false, autoSubmit = false, autosuggest = false, - history, openInRoute = false, } = props; const dispatch = useDispatch(); + const history = useHistory(); const intl = useIntl(); const value = useAppSelector((state) => state.search.get('value')); @@ -156,4 +156,4 @@ const Search = (props: ISearch) => { ); }; -export default withRouter(Search); +export default Search; diff --git a/app/soapbox/features/developers/developers_menu.js b/app/soapbox/features/developers/developers_menu.js index 919208c84..79227fb44 100644 --- a/app/soapbox/features/developers/developers_menu.js +++ b/app/soapbox/features/developers/developers_menu.js @@ -1,9 +1,8 @@ -import PropTypes from 'prop-types'; import React from 'react'; import InlineSVG from 'react-inlinesvg'; import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; import { useDispatch } from 'react-redux'; -import { Link, withRouter } from 'react-router-dom'; +import { Link, useHistory } from 'react-router-dom'; import { changeSettingImmediate } from 'soapbox/actions/settings'; import snackbar from 'soapbox/actions/snackbar'; @@ -16,9 +15,10 @@ const messages = defineMessages({ leave: { id: 'developers.leave', defaultMessage: 'You have left developers' }, }); -const Developers = ({ history }) => { - const intl = useIntl(); +const Developers = () => { const dispatch = useDispatch(); + const history = useHistory(); + const intl = useIntl(); const leaveDevelopers = (e) => { e.preventDefault(); @@ -67,8 +67,4 @@ const Developers = ({ history }) => { ); }; -Developers.propTypes = { - history: PropTypes.object, -}; - -export default withRouter(Developers); +export default Developers; diff --git a/app/soapbox/features/notifications/components/notification.js b/app/soapbox/features/notifications/components/notification.js index d399cdcf4..3c5462ce3 100644 --- a/app/soapbox/features/notifications/components/notification.js +++ b/app/soapbox/features/notifications/components/notification.js @@ -3,7 +3,7 @@ import React from 'react'; import { HotKeys } from 'react-hotkeys'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { FormattedMessage, useIntl } from 'react-intl'; -import { withRouter } from 'react-router-dom'; +import { useHistory } from 'react-router-dom'; import Icon from '../../../components/icon'; import Permalink from '../../../components/permalink'; @@ -77,9 +77,11 @@ const buildMessage = (type, account) => { }; const Notification = (props) => { - const { hidden, history, notification, onMoveUp, onMoveDown } = props; + const { hidden, notification, onMoveUp, onMoveDown } = props; + const history = useHistory(); const intl = useIntl(); + const type = notification.get('type'); const timestamp = notification.get('created_at'); const account = notification.get('account'); @@ -226,7 +228,6 @@ const Notification = (props) => { Notification.propTypes = { hidden: PropTypes.bool, - history: PropTypes.object.isRequired, notification: ImmutablePropTypes.map.isRequired, onMoveUp: PropTypes.func.isRequired, onMoveDown: PropTypes.func.isRequired, @@ -241,4 +242,4 @@ Notification.propTypes = { siteTitle: PropTypes.string, }; -export default withRouter(Notification); +export default Notification; diff --git a/app/soapbox/features/settings/index.js b/app/soapbox/features/settings/index.js index 237b38563..f78cddad7 100644 --- a/app/soapbox/features/settings/index.js +++ b/app/soapbox/features/settings/index.js @@ -1,8 +1,7 @@ -import PropTypes from 'prop-types'; import * as React from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { useDispatch, useSelector } from 'react-redux'; -import { withRouter } from 'react-router-dom'; +import { useHistory } from 'react-router-dom'; import { fetchMfa } from 'soapbox/actions/mfa'; @@ -22,9 +21,11 @@ const messages = defineMessages({ deleteAccount: { id: 'settings.delete_account', defaultMessage: 'Delete Account' }, }); -const Settings = ({ history }) => { - const intl = useIntl(); +const Settings = () => { const dispatch = useDispatch(); + const history = useHistory(); + const intl = useIntl(); + const mfa = useSelector((state) => state.getIn(['security', 'mfa'])); const me = useSelector((state) => state.get('me')); const account = useSelector((state) => state.getIn(['accounts', me])); @@ -92,8 +93,4 @@ const Settings = ({ history }) => { ); }; -Settings.propTypes = { - history: PropTypes.object, -}; - -export default withRouter(Settings); +export default Settings; diff --git a/app/soapbox/features/settings/media_display.js b/app/soapbox/features/settings/media_display.js index 3302fa803..0ce0eb51a 100644 --- a/app/soapbox/features/settings/media_display.js +++ b/app/soapbox/features/settings/media_display.js @@ -1,15 +1,13 @@ -import PropTypes from 'prop-types'; import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; import { defineMessages, useIntl } from 'react-intl'; -import { connect } from 'react-redux'; -import { withRouter } from 'react-router-dom'; +import { useDispatch } from 'react-redux'; import { getSettings, changeSettingImmediate } from 'soapbox/actions/settings'; import { SimpleForm, SelectDropdown, } from 'soapbox/features/forms'; +import { useAppSelector } from 'soapbox/hooks'; import List, { ListItem } from '../../components/list'; import { Card, CardBody, CardHeader, CardTitle } from '../../components/ui'; @@ -21,15 +19,12 @@ const messages = defineMessages({ display_media_show_all: { id: 'preferences.fields.display_media.show_all', defaultMessage: 'Always show media' }, }); -const mapStateToProps = state => { - return { - settings: getSettings(state), - }; -}; - -const MediaDisplay = ({ history, settings, dispatch }) => { +const MediaDisplay = () => { + const dispatch = useDispatch(); const intl = useIntl(); + const settings = useAppSelector((state) => getSettings(state)); + const displayMediaOptions = { default: intl.formatMessage(messages.display_media_default), hide_all: intl.formatMessage(messages.display_media_hide_all), @@ -65,10 +60,4 @@ const MediaDisplay = ({ history, settings, dispatch }) => { ); }; -MediaDisplay.propTypes = { - history: PropTypes.object, - dispatch: PropTypes.func.isRequired, - settings: ImmutablePropTypes.map, -}; - -export default withRouter(connect(mapStateToProps)(MediaDisplay)); +export default MediaDisplay; diff --git a/app/soapbox/features/verification/email_passthru.js b/app/soapbox/features/verification/email_passthru.js index 8bf6fecb9..dac2cc3bd 100644 --- a/app/soapbox/features/verification/email_passthru.js +++ b/app/soapbox/features/verification/email_passthru.js @@ -2,7 +2,6 @@ import PropTypes from 'prop-types'; import * as React from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { useDispatch } from 'react-redux'; -import { withRouter } from 'react-router-dom'; import snackbar from 'soapbox/actions/snackbar'; import { confirmEmailVerification } from 'soapbox/actions/verification'; @@ -95,8 +94,8 @@ const TokenExpired = () => { const EmailPassThru = ({ match }) => { const { token } = match.params; - const intl = useIntl(); const dispatch = useDispatch(); + const intl = useIntl(); const [status, setStatus] = React.useState(Statuses.IDLE); @@ -160,4 +159,4 @@ EmailPassThru.propTypes = { match: PropTypes.object, }; -export default withRouter(EmailPassThru); +export default EmailPassThru; diff --git a/package.json b/package.json index 1167ab31f..f4baa47fc 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@types/escape-html": "^1.0.1", "@types/http-link-header": "^1.0.3", "@types/lodash": "^4.14.180", - "@types/react-router-dom": "^4.2.6", + "@types/react-router-dom": "^5.3.3", "@types/uuid": "^8.3.4", "array-includes": "^3.0.3", "autoprefixer": "^10.4.2", diff --git a/yarn.lock b/yarn.lock index a660a31f8..8cb374efb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1148,13 +1148,6 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.7.6": - version "7.17.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941" - integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw== - dependencies: - regenerator-runtime "^0.13.4" - "@babel/template@7", "@babel/template@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" @@ -1989,13 +1982,6 @@ dependencies: "@types/node" "*" -"@types/history@*": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@types/history/-/history-5.0.0.tgz#29f919f0c8e302763798118f45b19cab4a886f14" - integrity sha512-hy8b7Y1J8OGe6LbAjj3xniQrj3v6lsivCcrmf4TzSgPzLkhIeKgc5IZnT7ReIqmEuodjfO8EYAuoFvIrHi/+jQ== - dependencies: - history "*" - "@types/history@^4.7.11": version "4.7.11" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64" @@ -2119,12 +2105,12 @@ hoist-non-react-statics "^3.3.0" redux "^4.0.0" -"@types/react-router-dom@^4.2.6": - version "4.3.5" - resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-4.3.5.tgz#72f229967690c890d00f96e6b85e9ee5780db31f" - integrity sha512-eFajSUASYbPHg2BDM1G8Btx+YqGgvROPIg6sBhl3O4kbDdYXdFdfrgQFf/pcBuQVObjfT9AL/dd15jilR5DIEA== +"@types/react-router-dom@^5.3.3": + version "5.3.3" + resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83" + integrity sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw== dependencies: - "@types/history" "*" + "@types/history" "^4.7.11" "@types/react" "*" "@types/react-router" "*" @@ -5367,13 +5353,6 @@ hex-color-regex@^1.1.0: resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== -history@*: - version "5.3.0" - resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b" - integrity sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ== - dependencies: - "@babel/runtime" "^7.7.6" - history@^4.10.1, history@^4.9.0: version "4.10.1" resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" From 69035c3dab61b5c792ce4706f3fe7ec4b03e6ca9 Mon Sep 17 00:00:00 2001 From: Justin Date: Tue, 22 Mar 2022 08:58:12 -0400 Subject: [PATCH 3/5] Add hint to clarify Feed settings --- app/soapbox/features/preferences/index.tsx | 10 ++++++++-- app/soapbox/locales/en.json | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/soapbox/features/preferences/index.tsx b/app/soapbox/features/preferences/index.tsx index a770fb776..df0d20639 100644 --- a/app/soapbox/features/preferences/index.tsx +++ b/app/soapbox/features/preferences/index.tsx @@ -111,11 +111,17 @@ const Preferences = () => { return (
- }> + } + hint={} + > - }> + } + hint={} + > diff --git a/app/soapbox/locales/en.json b/app/soapbox/locales/en.json index b3d3d18ad..ea087e446 100644 --- a/app/soapbox/locales/en.json +++ b/app/soapbox/locales/en.json @@ -713,6 +713,7 @@ "preferences.fields.system_font_label": "Use system's default font", "preferences.fields.underline_links_label": "Always underline links in posts", "preferences.fields.unfollow_modal_label": "Show confirmation dialog before unfollowing someone", + "preferences.hints.feed": "In your home feed", "preferences.hints.content_type_markdown": "Warning: experimental!", "preferences.hints.demetricator": "Decrease social media anxiety by hiding all numbers from the site.", "preferences.hints.halloween": "Beware: SPOOKY! Supports light/dark toggle.", From 122ee00f582ed320dad1dc13cc318e6c9795e292 Mon Sep 17 00:00:00 2001 From: Justin Date: Tue, 22 Mar 2022 11:13:42 -0400 Subject: [PATCH 4/5] Improve design of sensitive media --- app/soapbox/components/media_gallery.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/app/soapbox/components/media_gallery.js b/app/soapbox/components/media_gallery.js index 2c247df0e..bb293f416 100644 --- a/app/soapbox/components/media_gallery.js +++ b/app/soapbox/components/media_gallery.js @@ -17,6 +17,7 @@ import { isIOS } from '../is_mobile'; import { isPanoramic, isPortrait, isNonConformingRatio, minimumAspectRatio, maximumAspectRatio } from '../utils/media_aspect_ratio'; import IconButton from './icon_button'; +import { Button, Text } from './ui'; const ATTACHMENT_LIMIT = 4; const MAX_FILENAME_LENGTH = 45; @@ -602,10 +603,19 @@ class MediaGallery extends React.PureComponent { onClick={this.handleOpen} /> ) : ( - +
) )} From 430cfc3a2a72f69ee7847bacf955d8a5d29b2de5 Mon Sep 17 00:00:00 2001 From: Justin Date: Tue, 22 Mar 2022 11:41:44 -0400 Subject: [PATCH 5/5] Remove unneeded 'event' when using Reach Menu --- app/soapbox/features/ui/components/profile-dropdown.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/soapbox/features/ui/components/profile-dropdown.tsx b/app/soapbox/features/ui/components/profile-dropdown.tsx index f5a0d355c..43f31cfa3 100644 --- a/app/soapbox/features/ui/components/profile-dropdown.tsx +++ b/app/soapbox/features/ui/components/profile-dropdown.tsx @@ -43,16 +43,13 @@ const ProfileDropdown: React.FC = ({ account, children }) => { const isCurrentAccountStaff = isStaff(currentAccount) || false; const otherAccounts = useAppSelector((state) => authUsers.map((authUser: any) => getAccount(state, authUser.get('id')))); - const handleLogOut = (event: React.MouseEvent) => { - event.preventDefault(); - + const handleLogOut = () => { dispatch(logOut(intl)); }; const handleSwitchAccount = (account: AccountEntity) => { - return (event: React.MouseEvent) => { + return () => { dispatch(switchAccount(account.id)); - event.preventDefault(); }; };