Add tab bar alternative to desktop UI, upgrade react & react-redux

This commit is contained in:
Eugen Rochko
2017-01-06 22:09:55 +01:00
parent 1bfbce7b45
commit 989c3f4002
9 changed files with 103 additions and 32 deletions

View File

@ -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} />

View File

@ -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);

View File

@ -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>
);

View File

@ -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 />

View File

@ -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>
);
};

View File

@ -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}

View File

@ -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;