diff --git a/app/soapbox/components/icon_with_counter.js b/app/soapbox/components/icon_with_counter.tsx similarity index 68% rename from app/soapbox/components/icon_with_counter.js rename to app/soapbox/components/icon_with_counter.tsx index c7de5f896..0e09503cf 100644 --- a/app/soapbox/components/icon_with_counter.js +++ b/app/soapbox/components/icon_with_counter.tsx @@ -1,10 +1,15 @@ -import PropTypes from 'prop-types'; import React from 'react'; import Icon from 'soapbox/components/icon'; import { shortNumberFormat } from 'soapbox/utils/numbers'; -const IconWithCounter = ({ icon, count, ...rest }) => { +interface IIconWithCounter extends React.HTMLAttributes { + count: number, + icon?: string; + src?: string; +} + +const IconWithCounter: React.FC = ({ icon, count, ...rest }) => { return (
@@ -16,9 +21,4 @@ const IconWithCounter = ({ icon, count, ...rest }) => { ); }; -IconWithCounter.propTypes = { - icon: PropTypes.string, - count: PropTypes.number.isRequired, -}; - export default IconWithCounter; diff --git a/app/soapbox/components/thumb_navigation-link.tsx b/app/soapbox/components/thumb_navigation-link.tsx new file mode 100644 index 000000000..ae3c4facb --- /dev/null +++ b/app/soapbox/components/thumb_navigation-link.tsx @@ -0,0 +1,57 @@ +import classNames from 'classnames'; +import React from 'react'; +import { NavLink, useLocation } from 'react-router-dom'; + +import IconWithCounter from 'soapbox/components/icon_with_counter'; +import { Icon, Text } from 'soapbox/components/ui'; + +interface IThumbNavigationLink { + count?: number, + src: string, + text: string | React.ReactElement, + to: string, + exact?: boolean, + paths?: Array, +} + +const ThumbNavigationLink: React.FC = ({ count, src, text, to, exact, paths }): JSX.Element => { + const location = useLocation(); + + const active = paths + ? paths.some(location.pathname.startsWith) + : (exact + ? location.pathname === to + : location.pathname.startsWith(to)); + + + return ( + + {count !== undefined ? ( + + ) : ( + + )} + + + {text} + + + ); +}; + +export default ThumbNavigationLink; diff --git a/app/soapbox/components/thumb_navigation.js b/app/soapbox/components/thumb_navigation.js deleted file mode 100644 index 021c18ced..000000000 --- a/app/soapbox/components/thumb_navigation.js +++ /dev/null @@ -1,152 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import { FormattedMessage } from 'react-intl'; -import { connect } from 'react-redux'; -import { NavLink, withRouter } from 'react-router-dom'; - -import { getSoapboxConfig } from 'soapbox/actions/soapbox'; -import IconWithCounter from 'soapbox/components/icon_with_counter'; -import { Icon, Text } from 'soapbox/components/ui'; -import { getFeatures } from 'soapbox/utils/features'; - -const mapStateToProps = state => { - const me = state.get('me'); - const reportsCount = state.getIn(['admin', 'openReports']).count(); - const approvalCount = state.getIn(['admin', 'awaitingApproval']).count(); - const instance = state.get('instance'); - - return { - account: state.getIn(['accounts', me]), - logo: getSoapboxConfig(state).get('logo'), - notificationCount: state.getIn(['notifications', 'unread']), - chatsCount: state.getIn(['chats', 'items']).reduce((acc, curr) => acc + Math.min(curr.get('unread', 0), 1), 0), - dashboardCount: reportsCount + approvalCount, - features: getFeatures(instance), - }; -}; - -export default @withRouter -@connect(mapStateToProps) -class ThumbNavigation extends React.PureComponent { - - static propTypes = { - logo: PropTypes.string, - account: ImmutablePropTypes.record, - dashboardCount: PropTypes.number, - notificationCount: PropTypes.number, - chatsCount: PropTypes.number, - features: PropTypes.object.isRequired, - location: PropTypes.object, - } - - render() { - const { account, notificationCount, chatsCount, location, features } = this.props; - - return ( -
- - - - - - - - - - - - - - - - - {account && ( - - - - - - - - )} - - {account && ( - features.chats ? ( - - - - - - - ) : ( - - - - - - - - ) - )} - - {/* (account && isStaff(account)) && ( - - - - - - - - ) */} -
- ); - } - -} diff --git a/app/soapbox/components/thumb_navigation.tsx b/app/soapbox/components/thumb_navigation.tsx new file mode 100644 index 000000000..7e1debc61 --- /dev/null +++ b/app/soapbox/components/thumb_navigation.tsx @@ -0,0 +1,72 @@ +import React from 'react'; +import { FormattedMessage } from 'react-intl'; + +import ThumbNavigationLink from 'soapbox/components/thumb_navigation-link'; +import { useAppSelector, useOwnAccount } from 'soapbox/hooks'; +import { getFeatures } from 'soapbox/utils/features'; + +const ThumbNavigation: React.FC = (): JSX.Element => { + const account = useOwnAccount(); + const notificationCount = useAppSelector((state) => state.notifications.unread); + const chatsCount = useAppSelector((state) => state.chats.get('items').reduce((acc: number, curr: any) => acc + Math.min(curr.get('unread', 0), 1), 0)); + // const dashboardCount = useAppSelector((state) => state.admin.openReports.count() + state.admin.awaitingApproval.count()); + const features = getFeatures(useAppSelector((state) => state.instance)); + + return ( +
+ } + to='/' + exact + /> + + } + to='/search' + exact + /> + + {account && ( + } + to='/notifications' + exact + count={notificationCount} + /> + )} + + {account && ( + features.chats ? ( + } + to='/chats' + exact + count={chatsCount} + /> + ) : ( + } + to='/messages' + paths={['/messages', '/conversations']} + /> + ) + )} + + {/* (account && isStaff(account)) && ( + } + to='/admin' + count={dashboardCount} + /> + ) */} +
+ ); +}; + +export default ThumbNavigation;