index.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import React from 'react';
  2. import Column from 'mastodon/components/column';
  3. import ColumnHeader from 'mastodon/components/column_header';
  4. import ColumnLink from '../ui/components/column_link';
  5. import ColumnSubheading from '../ui/components/column_subheading';
  6. import { defineMessages, injectIntl } from 'react-intl';
  7. import { connect } from 'react-redux';
  8. import PropTypes from 'prop-types';
  9. import ImmutablePropTypes from 'react-immutable-proptypes';
  10. import ImmutablePureComponent from 'react-immutable-pure-component';
  11. import { me, showTrends } from '../../initial_state';
  12. import { fetchFollowRequests } from 'mastodon/actions/accounts';
  13. import { List as ImmutableList } from 'immutable';
  14. import NavigationContainer from '../compose/containers/navigation_container';
  15. import LinkFooter from 'mastodon/features/ui/components/link_footer';
  16. import TrendsContainer from './containers/trends_container';
  17. import { Helmet } from 'react-helmet';
  18. const messages = defineMessages({
  19. home_timeline: { id: 'tabs_bar.home', defaultMessage: 'Home' },
  20. notifications: { id: 'tabs_bar.notifications', defaultMessage: 'Notifications' },
  21. public_timeline: { id: 'navigation_bar.public_timeline', defaultMessage: 'Federated timeline' },
  22. settings_subheading: { id: 'column_subheading.settings', defaultMessage: 'Settings' },
  23. community_timeline: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
  24. explore: { id: 'navigation_bar.explore', defaultMessage: 'Explore' },
  25. direct: { id: 'navigation_bar.direct', defaultMessage: 'Direct messages' },
  26. bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' },
  27. preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
  28. follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
  29. favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' },
  30. blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
  31. domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' },
  32. mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
  33. pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned posts' },
  34. lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' },
  35. discover: { id: 'navigation_bar.discover', defaultMessage: 'Discover' },
  36. personal: { id: 'navigation_bar.personal', defaultMessage: 'Personal' },
  37. security: { id: 'navigation_bar.security', defaultMessage: 'Security' },
  38. menu: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
  39. });
  40. const mapStateToProps = state => ({
  41. myAccount: state.getIn(['accounts', me]),
  42. unreadFollowRequests: state.getIn(['user_lists', 'follow_requests', 'items'], ImmutableList()).size,
  43. });
  44. const mapDispatchToProps = dispatch => ({
  45. fetchFollowRequests: () => dispatch(fetchFollowRequests()),
  46. });
  47. const badgeDisplay = (number, limit) => {
  48. if (number === 0) {
  49. return undefined;
  50. } else if (limit && number >= limit) {
  51. return `${limit}+`;
  52. } else {
  53. return number;
  54. }
  55. };
  56. export default @connect(mapStateToProps, mapDispatchToProps)
  57. @injectIntl
  58. class GettingStarted extends ImmutablePureComponent {
  59. static contextTypes = {
  60. router: PropTypes.object.isRequired,
  61. identity: PropTypes.object,
  62. };
  63. static propTypes = {
  64. intl: PropTypes.object.isRequired,
  65. myAccount: ImmutablePropTypes.map,
  66. multiColumn: PropTypes.bool,
  67. fetchFollowRequests: PropTypes.func.isRequired,
  68. unreadFollowRequests: PropTypes.number,
  69. unreadNotifications: PropTypes.number,
  70. };
  71. componentDidMount () {
  72. const { fetchFollowRequests } = this.props;
  73. const { signedIn } = this.context.identity;
  74. if (!signedIn) {
  75. return;
  76. }
  77. fetchFollowRequests();
  78. }
  79. render () {
  80. const { intl, myAccount, multiColumn, unreadFollowRequests } = this.props;
  81. const { signedIn } = this.context.identity;
  82. const navItems = [];
  83. navItems.push(
  84. <ColumnSubheading key='header-discover' text={intl.formatMessage(messages.discover)} />,
  85. <ColumnLink key='explore' icon='hashtag' text={intl.formatMessage(messages.explore)} to='/explore' />,
  86. <ColumnLink key='community_timeline' icon='users' text={intl.formatMessage(messages.community_timeline)} to='/public/local' />,
  87. <ColumnLink key='public_timeline' icon='globe' text={intl.formatMessage(messages.public_timeline)} to='/public' />,
  88. );
  89. if (signedIn) {
  90. navItems.push(
  91. <ColumnSubheading key='header-personal' text={intl.formatMessage(messages.personal)} />,
  92. <ColumnLink key='home' icon='home' text={intl.formatMessage(messages.home_timeline)} to='/home' />,
  93. <ColumnLink key='direct' icon='at' text={intl.formatMessage(messages.direct)} to='/conversations' />,
  94. <ColumnLink key='bookmark' icon='bookmark' text={intl.formatMessage(messages.bookmarks)} to='/bookmarks' />,
  95. <ColumnLink key='favourites' icon='star' text={intl.formatMessage(messages.favourites)} to='/favourites' />,
  96. <ColumnLink key='lists' icon='list-ul' text={intl.formatMessage(messages.lists)} to='/lists' />,
  97. );
  98. if (myAccount.get('locked') || unreadFollowRequests > 0) {
  99. navItems.push(<ColumnLink key='follow_requests' icon='user-plus' text={intl.formatMessage(messages.follow_requests)} badge={badgeDisplay(unreadFollowRequests, 40)} to='/follow_requests' />);
  100. }
  101. navItems.push(
  102. <ColumnSubheading key='header-settings' text={intl.formatMessage(messages.settings_subheading)} />,
  103. <ColumnLink key='preferences' icon='gears' text={intl.formatMessage(messages.preferences)} href='/settings/preferences' />,
  104. );
  105. }
  106. return (
  107. <Column>
  108. {(signedIn && !multiColumn) ? <NavigationContainer /> : <ColumnHeader title={intl.formatMessage(messages.menu)} icon='bars' multiColumn={multiColumn} />}
  109. <div className='getting-started scrollable scrollable--flex'>
  110. <div className='getting-started__wrapper'>
  111. {navItems}
  112. </div>
  113. {!multiColumn && <div className='flex-spacer' />}
  114. <LinkFooter />
  115. </div>
  116. {(multiColumn && showTrends) && <TrendsContainer />}
  117. <Helmet>
  118. <title>{intl.formatMessage(messages.menu)}</title>
  119. <meta name='robots' content='noindex' />
  120. </Helmet>
  121. </Column>
  122. );
  123. }
  124. }