Merge pull request #344 from chriswmartin/getting-started-badge-merge
merge tootsuite pr #6313 into glitch & move getting_started dispatch stuff to mapDispatchToProps
This commit is contained in:
		
						commit
						2395a4c313
					
				
					 3 changed files with 57 additions and 17 deletions
				
			
		|  | @ -9,6 +9,8 @@ import PropTypes from 'prop-types'; | ||||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||||
| import { me } from 'flavours/glitch/util/initial_state'; | import { me } from 'flavours/glitch/util/initial_state'; | ||||||
|  | import { fetchFollowRequests } from 'flavours/glitch/actions/accounts'; | ||||||
|  | import { List as ImmutableList } from 'immutable'; | ||||||
| import { createSelector } from 'reselect'; | import { createSelector } from 'reselect'; | ||||||
| import { fetchLists } from 'flavours/glitch/actions/lists'; | import { fetchLists } from 'flavours/glitch/actions/lists'; | ||||||
| 
 | 
 | ||||||
|  | @ -45,13 +47,31 @@ const makeMapStateToProps = () => { | ||||||
|     lists: getOrderedLists(state), |     lists: getOrderedLists(state), | ||||||
|     myAccount: state.getIn(['accounts', me]), |     myAccount: state.getIn(['accounts', me]), | ||||||
|     columns: state.getIn(['settings', 'columns']), |     columns: state.getIn(['settings', 'columns']), | ||||||
|  |     unreadFollowRequests: state.getIn(['user_lists', 'follow_requests', 'items'], ImmutableList()).size, | ||||||
|  |     unreadNotifications: state.getIn(['notifications', 'unread']), | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   return mapStateToProps; |   return mapStateToProps; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | const mapDispatchToProps = dispatch => ({ | ||||||
|  |   fetchFollowRequests: () => dispatch(fetchFollowRequests()), | ||||||
|  |   fetchLists: () => dispatch(fetchLists()), | ||||||
|  |   openSettings: () => dispatch(openModal('SETTINGS', {})), | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const badgeDisplay = (number, limit) => { | ||||||
|  |   if (number === 0) { | ||||||
|  |     return undefined; | ||||||
|  |   } else if (limit && number >= limit) { | ||||||
|  |     return `${limit}+`; | ||||||
|  |   } else { | ||||||
|  |     return number; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | @connect(makeMapStateToProps, mapDispatchToProps) | ||||||
| @injectIntl | @injectIntl | ||||||
| @connect(makeMapStateToProps) |  | ||||||
| export default class GettingStarted extends ImmutablePureComponent { | export default class GettingStarted extends ImmutablePureComponent { | ||||||
| 
 | 
 | ||||||
|   static propTypes = { |   static propTypes = { | ||||||
|  | @ -59,25 +79,28 @@ export default class GettingStarted extends ImmutablePureComponent { | ||||||
|     myAccount: ImmutablePropTypes.map.isRequired, |     myAccount: ImmutablePropTypes.map.isRequired, | ||||||
|     columns: ImmutablePropTypes.list, |     columns: ImmutablePropTypes.list, | ||||||
|     multiColumn: PropTypes.bool, |     multiColumn: PropTypes.bool, | ||||||
|     dispatch: PropTypes.func.isRequired, |     fetchFollowRequests: PropTypes.func.isRequired, | ||||||
|  |     unreadFollowRequests: PropTypes.number, | ||||||
|  |     unreadNotifications: PropTypes.number, | ||||||
|     lists: ImmutablePropTypes.list, |     lists: ImmutablePropTypes.list, | ||||||
|  |     fetchLists: PropTypes.func.isRequired, | ||||||
|  |     openSettings: PropTypes.func.isRequired, | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   openSettings = () => { |  | ||||||
|     this.props.dispatch(openModal('SETTINGS', {})); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   openOnboardingModal = (e) => { |  | ||||||
|     e.preventDefault(); |  | ||||||
|     this.props.dispatch(openModal('ONBOARDING')); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   componentWillMount () { |   componentWillMount () { | ||||||
|     this.props.dispatch(fetchLists()); |     this.props.fetchLists(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   componentDidMount () { | ||||||
|  |     const { myAccount, fetchFollowRequests } = this.props; | ||||||
|  | 
 | ||||||
|  |     if (myAccount.get('locked')) { | ||||||
|  |       fetchFollowRequests(); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   render () { |   render () { | ||||||
|     const { intl, myAccount, columns, multiColumn, lists } = this.props; |     const { intl, myAccount, columns, multiColumn, unreadFollowRequests, unreadNotifications, lists, openSettings } = this.props; | ||||||
| 
 | 
 | ||||||
|     const navItems = []; |     const navItems = []; | ||||||
|     let listItems = []; |     let listItems = []; | ||||||
|  | @ -88,7 +111,7 @@ export default class GettingStarted extends ImmutablePureComponent { | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       if (!columns.find(item => item.get('id') === 'NOTIFICATIONS')) { |       if (!columns.find(item => item.get('id') === 'NOTIFICATIONS')) { | ||||||
|         navItems.push(<ColumnLink key='1' icon='bell' text={intl.formatMessage(messages.notifications)} to='/notifications' />); |         navItems.push(<ColumnLink key='1' icon='bell' text={intl.formatMessage(messages.notifications)} badge={badgeDisplay(unreadNotifications)} to='/notifications' />); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       if (!columns.find(item => item.get('id') === 'COMMUNITY')) { |       if (!columns.find(item => item.get('id') === 'COMMUNITY')) { | ||||||
|  | @ -105,7 +128,7 @@ export default class GettingStarted extends ImmutablePureComponent { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (myAccount.get('locked')) { |     if (myAccount.get('locked')) { | ||||||
|       navItems.push(<ColumnLink key='5' icon='users' text={intl.formatMessage(messages.follow_requests)} to='/follow_requests' />); |       navItems.push(<ColumnLink key='5' icon='users' text={intl.formatMessage(messages.follow_requests)} badge={badgeDisplay(unreadFollowRequests, 40)} to='/follow_requests' />); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     navItems.push(<ColumnLink key='6' icon='ellipsis-h' text={intl.formatMessage(messages.misc)} to='/getting-started-misc' />); |     navItems.push(<ColumnLink key='6' icon='ellipsis-h' text={intl.formatMessage(messages.misc)} to='/getting-started-misc' />); | ||||||
|  | @ -129,7 +152,7 @@ export default class GettingStarted extends ImmutablePureComponent { | ||||||
|             {listItems} |             {listItems} | ||||||
|             <ColumnSubheading text={intl.formatMessage(messages.settings_subheading)} /> |             <ColumnSubheading text={intl.formatMessage(messages.settings_subheading)} /> | ||||||
|             <ColumnLink icon='cog' text={intl.formatMessage(messages.preferences)} href='/settings/preferences' /> |             <ColumnLink icon='cog' text={intl.formatMessage(messages.preferences)} href='/settings/preferences' /> | ||||||
|             <ColumnLink icon='cogs' text={intl.formatMessage(messages.settings)} onClick={this.openSettings} /> |             <ColumnLink icon='cogs' text={intl.formatMessage(messages.settings)} onClick={openSettings} /> | ||||||
|             <ColumnLink icon='sign-out' text={intl.formatMessage(messages.sign_out)} href='/auth/sign_out' method='delete' /> |             <ColumnLink icon='sign-out' text={intl.formatMessage(messages.sign_out)} href='/auth/sign_out' method='delete' /> | ||||||
|           </div> |           </div> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,12 +2,15 @@ import React from 'react'; | ||||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||||
| import { Link } from 'react-router-dom'; | import { Link } from 'react-router-dom'; | ||||||
| 
 | 
 | ||||||
| const ColumnLink = ({ icon, text, to, onClick, href, method }) => { | const ColumnLink = ({ icon, text, to, onClick, href, method, badge }) => { | ||||||
|  |   const badgeElement = typeof badge !== 'undefined' ? <span className='column-link__badge'>{badge}</span> : null; | ||||||
|  | 
 | ||||||
|   if (href) { |   if (href) { | ||||||
|     return ( |     return ( | ||||||
|       <a href={href} className='column-link' data-method={method}> |       <a href={href} className='column-link' data-method={method}> | ||||||
|         <i className={`fa fa-fw fa-${icon} column-link__icon`} /> |         <i className={`fa fa-fw fa-${icon} column-link__icon`} /> | ||||||
|         {text} |         {text} | ||||||
|  |         {badgeElement} | ||||||
|       </a> |       </a> | ||||||
|     ); |     ); | ||||||
|   } else if (to) { |   } else if (to) { | ||||||
|  | @ -15,6 +18,7 @@ const ColumnLink = ({ icon, text, to, onClick, href, method }) => { | ||||||
|       <Link to={to} className='column-link'> |       <Link to={to} className='column-link'> | ||||||
|         <i className={`fa fa-fw fa-${icon} column-link__icon`} /> |         <i className={`fa fa-fw fa-${icon} column-link__icon`} /> | ||||||
|         {text} |         {text} | ||||||
|  |         {badgeElement} | ||||||
|       </Link> |       </Link> | ||||||
|     ); |     ); | ||||||
|   } else { |   } else { | ||||||
|  | @ -22,6 +26,7 @@ const ColumnLink = ({ icon, text, to, onClick, href, method }) => { | ||||||
|       <a onClick={onClick} className='column-link' role='button' tabIndex='0' data-method={method}> |       <a onClick={onClick} className='column-link' role='button' tabIndex='0' data-method={method}> | ||||||
|         <i className={`fa fa-fw fa-${icon} column-link__icon`} /> |         <i className={`fa fa-fw fa-${icon} column-link__icon`} /> | ||||||
|         {text} |         {text} | ||||||
|  |         {badgeElement} | ||||||
|       </a> |       </a> | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  | @ -34,6 +39,7 @@ ColumnLink.propTypes = { | ||||||
|   onClick: PropTypes.func, |   onClick: PropTypes.func, | ||||||
|   href: PropTypes.string, |   href: PropTypes.string, | ||||||
|   method: PropTypes.string, |   method: PropTypes.string, | ||||||
|  |   badge: PropTypes.node, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export default ColumnLink; | export default ColumnLink; | ||||||
|  |  | ||||||
|  | @ -753,6 +753,17 @@ | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .column-link__badge { | ||||||
|  |   display: inline-block; | ||||||
|  |   border-radius: 4px; | ||||||
|  |   font-size: 12px; | ||||||
|  |   line-height: 19px; | ||||||
|  |   font-weight: 500; | ||||||
|  |   background: $ui-base-color; | ||||||
|  |   padding: 4px 8px; | ||||||
|  |   margin: -6px 10px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .keyboard-shortcuts { | .keyboard-shortcuts { | ||||||
|   padding: 8px 0 0; |   padding: 8px 0 0; | ||||||
|   overflow: hidden; |   overflow: hidden; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue