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