commit: 989c3f40022bc65d69915be597acda3c4d58de60
parent: 1bfbce7b4542739a3601e0722a975b450e86bfb2
Author: Eugen Rochko <eugen@zeonfederated.com>
Date: Fri, 6 Jan 2017 22:09:55 +0100
Add tab bar alternative to desktop UI, upgrade react & react-redux
Diffstat:
9 files changed, 103 insertions(+), 32 deletions(-)
diff --git a/app/assets/javascripts/components/containers/mastodon.jsx b/app/assets/javascripts/components/containers/mastodon.jsx
@@ -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} />
diff --git a/app/assets/javascripts/components/features/compose/components/drawer.jsx b/app/assets/javascripts/components/features/compose/components/drawer.jsx
@@ -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 tabStyle = {
+ display: 'block',
+ flex: '1 1 auto',
+ padding: '15px',
+ paddingBottom: '13px',
+ color: '#9baec8',
+ textDecoration: 'none',
+ textAlign: 'center',
+ fontSize: '16px',
+ borderBottom: '2px solid transparent'
};
-const Drawer = React.createClass({
+const tabActiveStyle = {
+ color: '#2b90d9',
+ borderBottom: '2px solid #2b90d9'
+};
- mixins: [PureRenderMixin],
+const Drawer = ({ children, withHeader, intl }) => {
+ let header = '';
- render () {
- return (
- <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>
);
}
-});
+ return (
+ <div className='drawer' style={outerStyle}>
+ {header}
+
+ <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 Drawer;
+export default injectIntl(Drawer);
diff --git a/app/assets/javascripts/components/features/compose/components/navigation_bar.jsx b/app/assets/javascripts/components/features/compose/components/navigation_bar.jsx
@@ -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>
);
diff --git a/app/assets/javascripts/components/features/compose/index.jsx b/app/assets/javascripts/components/features/compose/index.jsx
@@ -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 />
diff --git a/app/assets/javascripts/components/features/ui/components/tabs_bar.jsx b/app/assets/javascripts/components/features/ui/components/tabs_bar.jsx
@@ -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>
);
};
diff --git a/app/assets/javascripts/components/features/ui/index.jsx b/app/assets/javascripts/components/features/ui/index.jsx
@@ -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}
diff --git a/app/assets/stylesheets/components.scss b/app/assets/stylesheets/components.scss
@@ -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;
diff --git a/package.json b/package.json
@@ -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"
}
}
diff --git a/yarn.lock b/yarn.lock
@@ -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"