Add tab bar alternative to desktop UI, upgrade react & react-redux
This commit is contained in:
		
							parent
							
								
									26390b1997
								
							
						
					
					
						commit
						0dac73b5cc
					
				
					 9 changed files with 103 additions and 32 deletions
				
			
		|  | @ -9,7 +9,6 @@ import { | |||
| import { updateNotifications } from '../actions/notifications'; | ||||
| import { setAccessToken } from '../actions/meta'; | ||||
| import { setAccountSelf } from '../actions/accounts'; | ||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||
| import createBrowserHistory from 'history/lib/createBrowserHistory'; | ||||
| import { | ||||
|   applyRouterMiddleware, | ||||
|  | @ -63,8 +62,6 @@ const Mastodon = React.createClass({ | |||
|     locale: React.PropTypes.string.isRequired | ||||
|   }, | ||||
| 
 | ||||
|   mixins: [PureRenderMixin], | ||||
| 
 | ||||
|   componentWillMount() { | ||||
|     const { token, account, locale } = this.props; | ||||
| 
 | ||||
|  | @ -108,9 +105,9 @@ const Mastodon = React.createClass({ | |||
|         <Provider store={store}> | ||||
|           <Router history={browserHistory} render={applyRouterMiddleware(useScroll())}> | ||||
|             <Route path='/' component={UI}> | ||||
|               <IndexRedirect to="/getting_started" /> | ||||
|               <IndexRedirect to="/getting-started" /> | ||||
| 
 | ||||
|               <Route path='getting_started' component={GettingStarted} /> | ||||
|               <Route path='getting-started' component={GettingStarted} /> | ||||
|               <Route path='timelines/home' component={HomeTimeline} /> | ||||
|               <Route path='timelines/mentions' component={MentionsTimeline} /> | ||||
|               <Route path='timelines/public' component={PublicTimeline} /> | ||||
|  |  | |||
|  | @ -1,26 +1,75 @@ | |||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||
| import { Link } from 'react-router'; | ||||
| import { injectIntl, defineMessages } from 'react-intl'; | ||||
| 
 | ||||
| const style = { | ||||
| const messages = defineMessages({ | ||||
|   start: { id: 'getting_started.heading', defaultMessage: 'Getting started' }, | ||||
|   public: { id: 'navigation_bar.public_timeline', defaultMessage: 'Public timeline' }, | ||||
|   preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, | ||||
|   logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' } | ||||
| }); | ||||
| 
 | ||||
| const outerStyle = { | ||||
|   boxSizing: 'border-box', | ||||
|   display: 'flex', | ||||
|   flexDirection: 'column', | ||||
|   overflowY: 'hidden' | ||||
| }; | ||||
| 
 | ||||
| const innerStyle = { | ||||
|   boxSizing: 'border-box', | ||||
|   background: '#454b5e', | ||||
|   padding: '0', | ||||
|   display: 'flex', | ||||
|   flexDirection: 'column', | ||||
|   overflowY: 'auto' | ||||
|   overflowY: 'auto', | ||||
|   flexGrow: '1' | ||||
| }; | ||||
| 
 | ||||
| const Drawer = React.createClass({ | ||||
| const tabStyle = { | ||||
|   display: 'block', | ||||
|   flex: '1 1 auto', | ||||
|   padding: '15px', | ||||
|   paddingBottom: '13px', | ||||
|   color: '#9baec8', | ||||
|   textDecoration: 'none', | ||||
|   textAlign: 'center', | ||||
|   fontSize: '16px', | ||||
|   borderBottom: '2px solid transparent' | ||||
| }; | ||||
| 
 | ||||
|   mixins: [PureRenderMixin], | ||||
| const tabActiveStyle = { | ||||
|   color: '#2b90d9', | ||||
|   borderBottom: '2px solid #2b90d9' | ||||
| }; | ||||
| 
 | ||||
|   render () { | ||||
|     return ( | ||||
|       <div className='drawer' style={style}> | ||||
|         {this.props.children} | ||||
| const Drawer = ({ children, withHeader, intl }) => { | ||||
|   let header = ''; | ||||
| 
 | ||||
|   if (withHeader) { | ||||
|     header = ( | ||||
|       <div className='drawer__header'> | ||||
|         <Link title={intl.formatMessage(messages.start)} style={tabStyle} to='/getting-started'><i className='fa fa-fw fa-bars' /></Link> | ||||
|         <Link title={intl.formatMessage(messages.public)} style={tabStyle} to='/timelines/public'><i className='fa fa-fw fa-globe' /></Link> | ||||
|         <a title={intl.formatMessage(messages.preferences)} style={tabStyle} href='/settings/preferences'><i className='fa fa-fw fa-cog' /></a> | ||||
|         <a title={intl.formatMessage(messages.logout)} style={tabStyle} href='/auth/sign_out' data-method='delete'><i className='fa fa-fw fa-sign-out' /></a> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
| }); | ||||
|   return ( | ||||
|     <div className='drawer' style={outerStyle}> | ||||
|       {header} | ||||
| 
 | ||||
| export default Drawer; | ||||
|       <div className='drawer__inner' style={innerStyle}> | ||||
|         {children} | ||||
|       </div> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| Drawer.propTypes = { | ||||
|   withHeader: React.PropTypes.bool, | ||||
|   children: React.PropTypes.node, | ||||
|   intl: React.PropTypes.object | ||||
| }; | ||||
| 
 | ||||
| export default injectIntl(Drawer); | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ const NavigationBar = React.createClass({ | |||
| 
 | ||||
|         <div style={{ flex: '1 1 auto', marginLeft: '8px', color: '#9baec8' }}> | ||||
|           <strong style={{ fontWeight: '500', display: 'block', color: '#fff' }}>{this.props.account.get('acct')}</strong> | ||||
|           <a href='/settings/profile' style={{ color: 'inherit', textDecoration: 'none' }}><FormattedMessage id='navigation_bar.edit_profile' defaultMessage='Edit profile' /></a> · <a href='/auth/sign_out' data-method='delete' style={{ color: 'inherit', textDecoration: 'none' }}><FormattedMessage id='navigation_bar.logout' defaultMessage='Logout' /></a> | ||||
|           <a href='/settings/profile' style={{ color: 'inherit', textDecoration: 'none' }}><FormattedMessage id='navigation_bar.edit_profile' defaultMessage='Edit profile' /></a> | ||||
|         </div> | ||||
|       </div> | ||||
|     ); | ||||
|  |  | |||
|  | @ -10,7 +10,8 @@ import { mountCompose, unmountCompose } from '../../actions/compose'; | |||
| const Compose = React.createClass({ | ||||
| 
 | ||||
|   propTypes: { | ||||
|     dispatch: React.PropTypes.func.isRequired | ||||
|     dispatch: React.PropTypes.func.isRequired, | ||||
|     withHeader: React.PropTypes.bool | ||||
|   }, | ||||
| 
 | ||||
|   mixins: [PureRenderMixin], | ||||
|  | @ -25,7 +26,7 @@ const Compose = React.createClass({ | |||
| 
 | ||||
|   render () { | ||||
|     return ( | ||||
|       <Drawer> | ||||
|       <Drawer withHeader={this.props.withHeader}> | ||||
|         <SearchContainer /> | ||||
|         <NavigationContainer /> | ||||
|         <ComposeFormContainer /> | ||||
|  |  | |||
|  | @ -30,7 +30,7 @@ const TabsBar = () => { | |||
|       <Link style={tabStyle} activeStyle={tabActiveStyle} to='/statuses/new'><i className='fa fa-fw fa-pencil' /> <FormattedMessage id='tabs_bar.compose' defaultMessage='Compose' /></Link> | ||||
|       <Link style={tabStyle} activeStyle={tabActiveStyle} to='/timelines/home'><i className='fa fa-fw fa-home' /> <FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></Link> | ||||
|       <Link style={tabStyle} activeStyle={tabActiveStyle} to='/notifications'><i className='fa fa-fw fa-bell' /> <FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></Link> | ||||
|       <Link style={{ ...tabStyle, flexGrow: '0', flexBasis: '30px' }} activeStyle={tabActiveStyle} to='/getting_started'><i className='fa fa-fw fa-bars' /></Link> | ||||
|       <Link style={{ ...tabStyle, flexGrow: '0', flexBasis: '30px' }} activeStyle={tabActiveStyle} to='/getting-started'><i className='fa fa-fw fa-bars' /></Link> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
|  |  | |||
|  | @ -14,6 +14,11 @@ import { connect } from 'react-redux'; | |||
| 
 | ||||
| const UI = React.createClass({ | ||||
| 
 | ||||
|   propTypes: { | ||||
|     dispatch: React.PropTypes.func.isRequired, | ||||
|     children: React.PropTypes.node | ||||
|   }, | ||||
| 
 | ||||
|   getInitialState () { | ||||
|     return { | ||||
|       width: window.innerWidth | ||||
|  | @ -41,7 +46,7 @@ const UI = React.createClass({ | |||
|   handleDrop (e) { | ||||
|     e.preventDefault(); | ||||
| 
 | ||||
|     if (e.dataTransfer) { | ||||
|     if (e.dataTransfer && e.dataTransfer.files.length === 1) { | ||||
|       this.props.dispatch(uploadCompose(e.dataTransfer.files)); | ||||
|     } | ||||
|   }, | ||||
|  | @ -72,7 +77,7 @@ const UI = React.createClass({ | |||
|     } else { | ||||
|       mountedColumns = ( | ||||
|         <ColumnsArea> | ||||
|           <Compose /> | ||||
|           <Compose withHeader={true} /> | ||||
|           <HomeTimeline trackScroll={false} /> | ||||
|           <Notifications trackScroll={false} /> | ||||
|           {this.props.children} | ||||
|  |  | |||
|  | @ -349,6 +349,28 @@ | |||
|   width: 280px; | ||||
| } | ||||
| 
 | ||||
| .drawer__inner { | ||||
|   background: linear-gradient(rgba(69, 75, 94, 1), rgba(69, 75, 94, 0.65)); | ||||
| } | ||||
| 
 | ||||
| .drawer__header { | ||||
|   flex: 0 0 auto; | ||||
|   font-size: 16px; | ||||
|   background: darken(#454b5e, 5%); | ||||
|   margin-bottom: 10px; | ||||
|   display: flex; | ||||
|   flex-direction: row; | ||||
| 
 | ||||
|   a { | ||||
|     transition: all 100ms ease-in; | ||||
| 
 | ||||
|     &:hover { | ||||
|       background: darken(#454b5e, 10%); | ||||
|       transition: all 200ms ease-out; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .column, .drawer { | ||||
|   margin-left: 5px; | ||||
|   margin-right: 5px; | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ | |||
|     "chai": "^3.5.0", | ||||
|     "chai-enzyme": "^0.5.2", | ||||
|     "css-loader": "^0.26.1", | ||||
|     "emojione": "^2.2.6", | ||||
|     "emojione": "latest", | ||||
|     "enzyme": "^2.4.1", | ||||
|     "es6-promise": "^3.2.1", | ||||
|     "http-link-header": "^0.5.0", | ||||
|  | @ -39,22 +39,19 @@ | |||
|     "react-motion": "^0.4.5", | ||||
|     "react-notification": "^6.4.0", | ||||
|     "react-proxy": "^1.1.8", | ||||
|     "react-redux": "^5.0.0-beta.3", | ||||
|     "react-redux": "^5.0.1", | ||||
|     "react-redux-loading-bar": "^2.4.1", | ||||
|     "react-router": "^2.8.0", | ||||
|     "react-router-scroll": "^0.3.2", | ||||
|     "react-simple-dropdown": "^1.1.4", | ||||
|     "react-storybook-addon-intl": "^0.1.0", | ||||
|     "react-toggle": "^2.1.1", | ||||
|     "redux": "^3.5.2", | ||||
|     "redux": "^3.6.0", | ||||
|     "redux-immutable": "^3.0.8", | ||||
|     "redux-thunk": "^2.1.0", | ||||
|     "reselect": "^2.5.4", | ||||
|     "sass-loader": "^4.0.2", | ||||
|     "sinon": "^1.17.6", | ||||
|     "style-loader": "^0.13.1" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "emojione": "latest" | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -4301,9 +4301,9 @@ react-redux@^4.4.5: | |||
|     lodash "^4.2.0" | ||||
|     loose-envify "^1.1.0" | ||||
| 
 | ||||
| react-redux@^5.0.0-beta.3: | ||||
|   version "5.0.0-beta.3" | ||||
|   resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.0-beta.3.tgz#d50bfb00799cf7d2a9fd55fe34d6b3ecc24d3072" | ||||
| react-redux@^5.0.1: | ||||
|   version "5.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.1.tgz#84a41bd4cdd180452bb6922bc79ad25bd5abb7c4" | ||||
|   dependencies: | ||||
|     hoist-non-react-statics "^1.0.3" | ||||
|     invariant "^2.0.0" | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue