Add tab bar alternative to desktop UI, upgrade react & react-redux
This commit is contained in:
		
							parent
							
								
									1bfbce7b45
								
							
						
					
					
						commit
						989c3f4002
					
				
					 9 changed files with 103 additions and 32 deletions
				
			
		| 
						 | 
					@ -9,7 +9,6 @@ import {
 | 
				
			||||||
import { updateNotifications } from '../actions/notifications';
 | 
					import { updateNotifications } from '../actions/notifications';
 | 
				
			||||||
import { setAccessToken } from '../actions/meta';
 | 
					import { setAccessToken } from '../actions/meta';
 | 
				
			||||||
import { setAccountSelf } from '../actions/accounts';
 | 
					import { setAccountSelf } from '../actions/accounts';
 | 
				
			||||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
 | 
					 | 
				
			||||||
import createBrowserHistory from 'history/lib/createBrowserHistory';
 | 
					import createBrowserHistory from 'history/lib/createBrowserHistory';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  applyRouterMiddleware,
 | 
					  applyRouterMiddleware,
 | 
				
			||||||
| 
						 | 
					@ -63,8 +62,6 @@ const Mastodon = React.createClass({
 | 
				
			||||||
    locale: React.PropTypes.string.isRequired
 | 
					    locale: React.PropTypes.string.isRequired
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mixins: [PureRenderMixin],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  componentWillMount() {
 | 
					  componentWillMount() {
 | 
				
			||||||
    const { token, account, locale } = this.props;
 | 
					    const { token, account, locale } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,9 +105,9 @@ const Mastodon = React.createClass({
 | 
				
			||||||
        <Provider store={store}>
 | 
					        <Provider store={store}>
 | 
				
			||||||
          <Router history={browserHistory} render={applyRouterMiddleware(useScroll())}>
 | 
					          <Router history={browserHistory} render={applyRouterMiddleware(useScroll())}>
 | 
				
			||||||
            <Route path='/' component={UI}>
 | 
					            <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/home' component={HomeTimeline} />
 | 
				
			||||||
              <Route path='timelines/mentions' component={MentionsTimeline} />
 | 
					              <Route path='timelines/mentions' component={MentionsTimeline} />
 | 
				
			||||||
              <Route path='timelines/public' component={PublicTimeline} />
 | 
					              <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',
 | 
					  boxSizing: 'border-box',
 | 
				
			||||||
  background: '#454b5e',
 | 
					 | 
				
			||||||
  padding: '0',
 | 
					  padding: '0',
 | 
				
			||||||
  display: 'flex',
 | 
					  display: 'flex',
 | 
				
			||||||
  flexDirection: 'column',
 | 
					  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 () {
 | 
					const Drawer = ({ children, withHeader, intl }) => {
 | 
				
			||||||
    return (
 | 
					  let header = '';
 | 
				
			||||||
      <div className='drawer' style={style}>
 | 
					
 | 
				
			||||||
        {this.props.children}
 | 
					  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>
 | 
					      </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' }}>
 | 
					        <div style={{ flex: '1 1 auto', marginLeft: '8px', color: '#9baec8' }}>
 | 
				
			||||||
          <strong style={{ fontWeight: '500', display: 'block', color: '#fff' }}>{this.props.account.get('acct')}</strong>
 | 
					          <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>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,8 @@ import { mountCompose, unmountCompose } from '../../actions/compose';
 | 
				
			||||||
const Compose = React.createClass({
 | 
					const Compose = React.createClass({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  propTypes: {
 | 
					  propTypes: {
 | 
				
			||||||
    dispatch: React.PropTypes.func.isRequired
 | 
					    dispatch: React.PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					    withHeader: React.PropTypes.bool
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mixins: [PureRenderMixin],
 | 
					  mixins: [PureRenderMixin],
 | 
				
			||||||
| 
						 | 
					@ -25,7 +26,7 @@ const Compose = React.createClass({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  render () {
 | 
					  render () {
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <Drawer>
 | 
					      <Drawer withHeader={this.props.withHeader}>
 | 
				
			||||||
        <SearchContainer />
 | 
					        <SearchContainer />
 | 
				
			||||||
        <NavigationContainer />
 | 
					        <NavigationContainer />
 | 
				
			||||||
        <ComposeFormContainer />
 | 
					        <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='/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='/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} 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>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,11 @@ import { connect } from 'react-redux';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const UI = React.createClass({
 | 
					const UI = React.createClass({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  propTypes: {
 | 
				
			||||||
 | 
					    dispatch: React.PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					    children: React.PropTypes.node
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getInitialState () {
 | 
					  getInitialState () {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      width: window.innerWidth
 | 
					      width: window.innerWidth
 | 
				
			||||||
| 
						 | 
					@ -41,7 +46,7 @@ const UI = React.createClass({
 | 
				
			||||||
  handleDrop (e) {
 | 
					  handleDrop (e) {
 | 
				
			||||||
    e.preventDefault();
 | 
					    e.preventDefault();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (e.dataTransfer) {
 | 
					    if (e.dataTransfer && e.dataTransfer.files.length === 1) {
 | 
				
			||||||
      this.props.dispatch(uploadCompose(e.dataTransfer.files));
 | 
					      this.props.dispatch(uploadCompose(e.dataTransfer.files));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
| 
						 | 
					@ -72,7 +77,7 @@ const UI = React.createClass({
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      mountedColumns = (
 | 
					      mountedColumns = (
 | 
				
			||||||
        <ColumnsArea>
 | 
					        <ColumnsArea>
 | 
				
			||||||
          <Compose />
 | 
					          <Compose withHeader={true} />
 | 
				
			||||||
          <HomeTimeline trackScroll={false} />
 | 
					          <HomeTimeline trackScroll={false} />
 | 
				
			||||||
          <Notifications trackScroll={false} />
 | 
					          <Notifications trackScroll={false} />
 | 
				
			||||||
          {this.props.children}
 | 
					          {this.props.children}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -349,6 +349,28 @@
 | 
				
			||||||
  width: 280px;
 | 
					  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 {
 | 
					.column, .drawer {
 | 
				
			||||||
  margin-left: 5px;
 | 
					  margin-left: 5px;
 | 
				
			||||||
  margin-right: 5px;
 | 
					  margin-right: 5px;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@
 | 
				
			||||||
    "chai": "^3.5.0",
 | 
					    "chai": "^3.5.0",
 | 
				
			||||||
    "chai-enzyme": "^0.5.2",
 | 
					    "chai-enzyme": "^0.5.2",
 | 
				
			||||||
    "css-loader": "^0.26.1",
 | 
					    "css-loader": "^0.26.1",
 | 
				
			||||||
    "emojione": "^2.2.6",
 | 
					    "emojione": "latest",
 | 
				
			||||||
    "enzyme": "^2.4.1",
 | 
					    "enzyme": "^2.4.1",
 | 
				
			||||||
    "es6-promise": "^3.2.1",
 | 
					    "es6-promise": "^3.2.1",
 | 
				
			||||||
    "http-link-header": "^0.5.0",
 | 
					    "http-link-header": "^0.5.0",
 | 
				
			||||||
| 
						 | 
					@ -39,22 +39,19 @@
 | 
				
			||||||
    "react-motion": "^0.4.5",
 | 
					    "react-motion": "^0.4.5",
 | 
				
			||||||
    "react-notification": "^6.4.0",
 | 
					    "react-notification": "^6.4.0",
 | 
				
			||||||
    "react-proxy": "^1.1.8",
 | 
					    "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-redux-loading-bar": "^2.4.1",
 | 
				
			||||||
    "react-router": "^2.8.0",
 | 
					    "react-router": "^2.8.0",
 | 
				
			||||||
    "react-router-scroll": "^0.3.2",
 | 
					    "react-router-scroll": "^0.3.2",
 | 
				
			||||||
    "react-simple-dropdown": "^1.1.4",
 | 
					    "react-simple-dropdown": "^1.1.4",
 | 
				
			||||||
    "react-storybook-addon-intl": "^0.1.0",
 | 
					    "react-storybook-addon-intl": "^0.1.0",
 | 
				
			||||||
    "react-toggle": "^2.1.1",
 | 
					    "react-toggle": "^2.1.1",
 | 
				
			||||||
    "redux": "^3.5.2",
 | 
					    "redux": "^3.6.0",
 | 
				
			||||||
    "redux-immutable": "^3.0.8",
 | 
					    "redux-immutable": "^3.0.8",
 | 
				
			||||||
    "redux-thunk": "^2.1.0",
 | 
					    "redux-thunk": "^2.1.0",
 | 
				
			||||||
    "reselect": "^2.5.4",
 | 
					    "reselect": "^2.5.4",
 | 
				
			||||||
    "sass-loader": "^4.0.2",
 | 
					    "sass-loader": "^4.0.2",
 | 
				
			||||||
    "sinon": "^1.17.6",
 | 
					    "sinon": "^1.17.6",
 | 
				
			||||||
    "style-loader": "^0.13.1"
 | 
					    "style-loader": "^0.13.1"
 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "dependencies": {
 | 
					 | 
				
			||||||
    "emojione": "latest"
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4301,9 +4301,9 @@ react-redux@^4.4.5:
 | 
				
			||||||
    lodash "^4.2.0"
 | 
					    lodash "^4.2.0"
 | 
				
			||||||
    loose-envify "^1.1.0"
 | 
					    loose-envify "^1.1.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
react-redux@^5.0.0-beta.3:
 | 
					react-redux@^5.0.1:
 | 
				
			||||||
  version "5.0.0-beta.3"
 | 
					  version "5.0.1"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.0-beta.3.tgz#d50bfb00799cf7d2a9fd55fe34d6b3ecc24d3072"
 | 
					  resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.1.tgz#84a41bd4cdd180452bb6922bc79ad25bd5abb7c4"
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    hoist-non-react-statics "^1.0.3"
 | 
					    hoist-non-react-statics "^1.0.3"
 | 
				
			||||||
    invariant "^2.0.0"
 | 
					    invariant "^2.0.0"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue