forked from treehouse/mastodon
Responsively changing layout to single-column + nav on smaller screens
parent
e2ff39bf5d
commit
45776b55b0
|
@ -15,12 +15,15 @@ import {
|
||||||
hashHistory,
|
hashHistory,
|
||||||
IndexRoute
|
IndexRoute
|
||||||
} from 'react-router';
|
} from 'react-router';
|
||||||
|
import UI from '../features/ui';
|
||||||
import Account from '../features/account';
|
import Account from '../features/account';
|
||||||
import Status from '../features/status';
|
import Status from '../features/status';
|
||||||
import GettingStarted from '../features/getting_started';
|
import GettingStarted from '../features/getting_started';
|
||||||
import PublicTimeline from '../features/public_timeline';
|
import PublicTimeline from '../features/public_timeline';
|
||||||
import UI from '../features/ui';
|
|
||||||
import AccountTimeline from '../features/account_timeline';
|
import AccountTimeline from '../features/account_timeline';
|
||||||
|
import HomeTimeline from '../features/home_timeline';
|
||||||
|
import MentionsTimeline from '../features/mentions_timeline';
|
||||||
|
import Compose from '../features/compose';
|
||||||
|
|
||||||
const store = configureStore();
|
const store = configureStore();
|
||||||
|
|
||||||
|
@ -77,6 +80,9 @@ const Mastodon = React.createClass({
|
||||||
<Router history={hashHistory}>
|
<Router history={hashHistory}>
|
||||||
<Route path='/' component={UI}>
|
<Route path='/' component={UI}>
|
||||||
<IndexRoute component={GettingStarted} />
|
<IndexRoute component={GettingStarted} />
|
||||||
|
<Route path='/statuses/new' component={Compose} />
|
||||||
|
<Route path='/statuses/home' component={HomeTimeline} />
|
||||||
|
<Route path='/statuses/mentions' component={MentionsTimeline} />
|
||||||
<Route path='/statuses/all' component={PublicTimeline} />
|
<Route path='/statuses/all' component={PublicTimeline} />
|
||||||
<Route path='/statuses/:statusId' component={Status} />
|
<Route path='/statuses/:statusId' component={Status} />
|
||||||
<Route path='/accounts/:accountId' component={Account}>
|
<Route path='/accounts/:accountId' component={Account}>
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import Drawer from '../ui/components/drawer';
|
||||||
|
import ComposeFormContainer from '../ui/containers/compose_form_container';
|
||||||
|
import FollowFormContainer from '../ui/containers/follow_form_container';
|
||||||
|
import UploadFormContainer from '../ui/containers/upload_form_container';
|
||||||
|
import NavigationContainer from '../ui/containers/navigation_container';
|
||||||
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
|
|
||||||
|
const Compose = React.createClass({
|
||||||
|
|
||||||
|
mixins: [PureRenderMixin],
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<Drawer>
|
||||||
|
<div style={{ flex: '1 1 auto' }}>
|
||||||
|
<NavigationContainer />
|
||||||
|
<ComposeFormContainer />
|
||||||
|
<UploadFormContainer />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FollowFormContainer />
|
||||||
|
</Drawer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Compose;
|
|
@ -0,0 +1,19 @@
|
||||||
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
|
import StatusListContainer from '../ui/containers/status_list_container';
|
||||||
|
import Column from '../ui/components/column';
|
||||||
|
|
||||||
|
const HomeTimeline = React.createClass({
|
||||||
|
|
||||||
|
mixins: [PureRenderMixin],
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<Column icon='home' heading='Home'>
|
||||||
|
<StatusListContainer type='home' />
|
||||||
|
</Column>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export default HomeTimeline;
|
|
@ -0,0 +1,19 @@
|
||||||
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
|
import StatusListContainer from '../ui/containers/status_list_container';
|
||||||
|
import Column from '../ui/components/column';
|
||||||
|
|
||||||
|
const MentionsTimeline = React.createClass({
|
||||||
|
|
||||||
|
mixins: [PureRenderMixin],
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<Column icon='at' heading='Mentions'>
|
||||||
|
<StatusListContainer type='mentions' />
|
||||||
|
</Column>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export default MentionsTimeline;
|
|
@ -1,43 +1,14 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import StatusListContainer from '../ui/containers/status_list_container';
|
||||||
import StatusList from '../../components/status_list';
|
|
||||||
import Column from '../ui/components/column';
|
import Column from '../ui/components/column';
|
||||||
import Immutable from 'immutable';
|
|
||||||
import { makeGetTimeline } from '../../selectors';
|
|
||||||
import {
|
import {
|
||||||
updateTimeline,
|
|
||||||
refreshTimeline,
|
refreshTimeline,
|
||||||
expandTimeline
|
updateTimeline
|
||||||
} from '../../actions/timelines';
|
} from '../../actions/timelines';
|
||||||
import { deleteStatus } from '../../actions/statuses';
|
|
||||||
import { replyCompose } from '../../actions/compose';
|
|
||||||
import {
|
|
||||||
favourite,
|
|
||||||
reblog,
|
|
||||||
unreblog,
|
|
||||||
unfavourite
|
|
||||||
} from '../../actions/interactions';
|
|
||||||
|
|
||||||
const makeMapStateToProps = () => {
|
|
||||||
const getTimeline = makeGetTimeline();
|
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
|
||||||
statuses: getTimeline(state, 'public'),
|
|
||||||
me: state.getIn(['timelines', 'me'])
|
|
||||||
});
|
|
||||||
|
|
||||||
return mapStateToProps;
|
|
||||||
};
|
|
||||||
|
|
||||||
const PublicTimeline = React.createClass({
|
const PublicTimeline = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
|
||||||
statuses: ImmutablePropTypes.list.isRequired,
|
|
||||||
me: React.PropTypes.number.isRequired,
|
|
||||||
dispatch: React.PropTypes.func.isRequired
|
|
||||||
},
|
|
||||||
|
|
||||||
mixins: [PureRenderMixin],
|
mixins: [PureRenderMixin],
|
||||||
|
|
||||||
componentWillMount () {
|
componentWillMount () {
|
||||||
|
@ -62,44 +33,14 @@ const PublicTimeline = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handleReply (status) {
|
|
||||||
this.props.dispatch(replyCompose(status));
|
|
||||||
},
|
|
||||||
|
|
||||||
handleReblog (status) {
|
|
||||||
if (status.get('reblogged')) {
|
|
||||||
this.props.dispatch(unreblog(status));
|
|
||||||
} else {
|
|
||||||
this.props.dispatch(reblog(status));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handleFavourite (status) {
|
|
||||||
if (status.get('favourited')) {
|
|
||||||
this.props.dispatch(unfavourite(status));
|
|
||||||
} else {
|
|
||||||
this.props.dispatch(favourite(status));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handleDelete (status) {
|
|
||||||
this.props.dispatch(deleteStatus(status.get('id')));
|
|
||||||
},
|
|
||||||
|
|
||||||
handleScrollToBottom () {
|
|
||||||
this.props.dispatch(expandTimeline('public'));
|
|
||||||
},
|
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { statuses, me } = this.props;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column icon='globe' heading='Public'>
|
<Column icon='globe' heading='Public'>
|
||||||
<StatusList statuses={statuses} me={me} onScrollToBottom={this.handleScrollToBottom} onReply={this.handleReply} onReblog={this.handleReblog} onFavourite={this.handleFavourite} onDelete={this.handleDelete} />
|
<StatusListContainer type='public' />
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(makeMapStateToProps)(PublicTimeline);
|
export default connect()(PublicTimeline);
|
||||||
|
|
|
@ -29,6 +29,15 @@ const scrollTop = (node) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const style = {
|
||||||
|
height: '100%',
|
||||||
|
boxSizing: 'border-box',
|
||||||
|
flex: '0 0 auto',
|
||||||
|
background: '#282c37',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column'
|
||||||
|
};
|
||||||
|
|
||||||
const Column = React.createClass({
|
const Column = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -56,10 +65,8 @@ const Column = React.createClass({
|
||||||
header = <ColumnHeader icon={this.props.icon} type={this.props.heading} onClick={this.handleHeaderClick} />;
|
header = <ColumnHeader icon={this.props.icon} type={this.props.heading} onClick={this.handleHeaderClick} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const style = { width: '330px', flex: '0 0 auto', background: '#282c37', margin: '10px', marginRight: '0', marginBottom: '0', display: 'flex', flexDirection: 'column' };
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={style} onWheel={this.handleWheel}>
|
<div className='column' style={style} onWheel={this.handleWheel}>
|
||||||
{header}
|
{header}
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
|
|
||||||
|
const style = {
|
||||||
|
display: 'flex',
|
||||||
|
flex: '1 1 auto',
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'flex-start',
|
||||||
|
overflowX: 'auto'
|
||||||
|
};
|
||||||
|
|
||||||
const ColumnsArea = React.createClass({
|
const ColumnsArea = React.createClass({
|
||||||
|
|
||||||
mixins: [PureRenderMixin],
|
mixins: [PureRenderMixin],
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex', flexDirection: 'row', flex: '1', justifyContent: 'flex-start', marginRight: '10px', marginBottom: '10px', overflowX: 'auto' }}>
|
<div className='columns-area' style={style}>
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,12 +1,22 @@
|
||||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
|
|
||||||
|
const style = {
|
||||||
|
height: '100%',
|
||||||
|
flex: '0 0 auto',
|
||||||
|
boxSizing: 'border-box',
|
||||||
|
background: '#454b5e',
|
||||||
|
padding: '0',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column'
|
||||||
|
};
|
||||||
|
|
||||||
const Drawer = React.createClass({
|
const Drawer = React.createClass({
|
||||||
|
|
||||||
mixins: [PureRenderMixin],
|
mixins: [PureRenderMixin],
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div style={{ width: '280px', flex: '0 0 auto', boxSizing: 'border-box', background: '#454b5e', margin: '10px', marginRight: '0', padding: '0', display: 'flex', flexDirection: 'column' }}>
|
<div className='drawer' style={style}>
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
|
const outerStyle = {
|
||||||
|
background: '#373b4a',
|
||||||
|
margin: '10px',
|
||||||
|
flex: '0 0 auto',
|
||||||
|
marginBottom: '0',
|
||||||
|
display: 'flex'
|
||||||
|
};
|
||||||
|
|
||||||
|
const tabStyle = {
|
||||||
|
display: 'block',
|
||||||
|
flex: '1 1 auto',
|
||||||
|
padding: '10px',
|
||||||
|
color: '#fff',
|
||||||
|
textDecoration: 'none',
|
||||||
|
fontSize: '12px',
|
||||||
|
fontWeight: '500',
|
||||||
|
borderBottom: '2px solid #373b4a'
|
||||||
|
};
|
||||||
|
|
||||||
|
const tabActiveStyle = {
|
||||||
|
borderBottom: '2px solid #2b90d9',
|
||||||
|
color: '#2b90d9'
|
||||||
|
};
|
||||||
|
|
||||||
|
const TabsBar = () => {
|
||||||
|
return (
|
||||||
|
<div style={outerStyle}>
|
||||||
|
<Link style={tabStyle} activeStyle={tabActiveStyle} to='/statuses/new'><i className='fa fa-fw fa-pencil' /> Compose</Link>
|
||||||
|
<Link style={tabStyle} activeStyle={tabActiveStyle} to='/statuses/home'><i className='fa fa-fw fa-home' /> Home</Link>
|
||||||
|
<Link style={tabStyle} activeStyle={tabActiveStyle} to='/statuses/mentions'><i className='fa fa-fw fa-at' /> Mentions</Link>
|
||||||
|
<Link style={tabStyle} activeStyle={tabActiveStyle} to='/statuses/all'><i className='fa fa-fw fa-globe' /> Public</Link>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TabsBar;
|
|
@ -1,47 +1,38 @@
|
||||||
import ColumnsArea from './components/columns_area';
|
import ColumnsArea from './components/columns_area';
|
||||||
import Column from './components/column';
|
|
||||||
import Drawer from './components/drawer';
|
|
||||||
import ComposeFormContainer from './containers/compose_form_container';
|
|
||||||
import FollowFormContainer from './containers/follow_form_container';
|
|
||||||
import UploadFormContainer from './containers/upload_form_container';
|
|
||||||
import StatusListContainer from './containers/status_list_container';
|
|
||||||
import NotificationsContainer from './containers/notifications_container';
|
import NotificationsContainer from './containers/notifications_container';
|
||||||
import NavigationContainer from './containers/navigation_container';
|
|
||||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
import LoadingBarContainer from './containers/loading_bar_container';
|
import LoadingBarContainer from './containers/loading_bar_container';
|
||||||
|
import HomeTimeline from '../home_timeline';
|
||||||
|
import MentionsTimeline from '../mentions_timeline';
|
||||||
|
import Compose from '../compose';
|
||||||
|
import MediaQuery from 'react-responsive';
|
||||||
|
import TabsBar from './components/tabs_bar';
|
||||||
|
|
||||||
const UI = React.createClass({
|
const UI = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
|
||||||
router: React.PropTypes.object
|
|
||||||
},
|
|
||||||
|
|
||||||
mixins: [PureRenderMixin],
|
mixins: [PureRenderMixin],
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
const layoutBreakpoint = 1024;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ flex: '0 0 auto', display: 'flex', width: '100%', height: '100%', background: '#1a1c23' }}>
|
<div style={{ flex: '0 0 auto', display: 'flex', flexDirection: 'column', width: '100%', height: '100%', background: '#1a1c23' }}>
|
||||||
<Drawer>
|
<MediaQuery maxWidth={layoutBreakpoint}>
|
||||||
<div style={{ flex: '1 1 auto' }}>
|
<TabsBar />
|
||||||
<NavigationContainer />
|
</MediaQuery>
|
||||||
<ComposeFormContainer />
|
|
||||||
<UploadFormContainer />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<FollowFormContainer />
|
<MediaQuery maxWidth={layoutBreakpoint} component={ColumnsArea}>
|
||||||
</Drawer>
|
{this.props.children}
|
||||||
|
</MediaQuery>
|
||||||
|
|
||||||
|
<MediaQuery minWidth={layoutBreakpoint}>
|
||||||
<ColumnsArea>
|
<ColumnsArea>
|
||||||
<Column icon='home' heading='Home'>
|
<Compose />
|
||||||
<StatusListContainer type='home' />
|
<HomeTimeline />
|
||||||
</Column>
|
<MentionsTimeline />
|
||||||
|
|
||||||
<Column icon='at' heading='Mentions'>
|
|
||||||
<StatusListContainer type='mentions' />
|
|
||||||
</Column>
|
|
||||||
|
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</ColumnsArea>
|
</ColumnsArea>
|
||||||
|
</MediaQuery>
|
||||||
|
|
||||||
<NotificationsContainer />
|
<NotificationsContainer />
|
||||||
<LoadingBarContainer style={{ backgroundColor: '#2b90d9', left: '0', top: '0' }} />
|
<LoadingBarContainer style={{ backgroundColor: '#2b90d9', left: '0', top: '0' }} />
|
||||||
|
|
|
@ -227,3 +227,31 @@
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.columns-area {
|
||||||
|
margin: 10px;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column {
|
||||||
|
width: 330px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer {
|
||||||
|
width: 280px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column, .drawer {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1024px) {
|
||||||
|
.column, .drawer {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns-area {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -38,5 +38,8 @@
|
||||||
"redux-thunk": "^2.1.0",
|
"redux-thunk": "^2.1.0",
|
||||||
"reselect": "^2.5.4",
|
"reselect": "^2.5.4",
|
||||||
"sinon": "^1.17.6"
|
"sinon": "^1.17.6"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"react-responsive": "^1.1.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
yarn.lock
22
yarn.lock
|
@ -1541,6 +1541,10 @@ css-loader@0.25.0:
|
||||||
postcss-modules-values "^1.1.0"
|
postcss-modules-values "^1.1.0"
|
||||||
source-list-map "^0.1.4"
|
source-list-map "^0.1.4"
|
||||||
|
|
||||||
|
css-mediaquery@^0.1.2:
|
||||||
|
version "0.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/css-mediaquery/-/css-mediaquery-0.1.2.tgz#6a2c37344928618631c54bd33cedd301da18bea0"
|
||||||
|
|
||||||
css-select@~1.2.0:
|
css-select@~1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
|
resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
|
||||||
|
@ -2359,6 +2363,10 @@ https-browserify@0.0.0:
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.0.tgz#b3ffdfe734b2a3d4a9efd58e8654c91fce86eafd"
|
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.0.tgz#b3ffdfe734b2a3d4a9efd58e8654c91fce86eafd"
|
||||||
|
|
||||||
|
hyphenate-style-name@^1.0.0:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.1.tgz#bc49b9446e02b4570641afdd29c1ce7609d1b9cc"
|
||||||
|
|
||||||
iconv-lite@^0.4.13, iconv-lite@~0.4.13:
|
iconv-lite@^0.4.13, iconv-lite@~0.4.13:
|
||||||
version "0.4.13"
|
version "0.4.13"
|
||||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2"
|
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2"
|
||||||
|
@ -2928,6 +2936,12 @@ mantra-core@^1.6.1:
|
||||||
react-komposer "^1.9.0"
|
react-komposer "^1.9.0"
|
||||||
react-simple-di "^1.2.0"
|
react-simple-di "^1.2.0"
|
||||||
|
|
||||||
|
matchmedia@^0.1.2:
|
||||||
|
version "0.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/matchmedia/-/matchmedia-0.1.2.tgz#cfd47f2bf68fbc7f5ea1bd3a3cf1715ecba3c1bd"
|
||||||
|
dependencies:
|
||||||
|
css-mediaquery "^0.1.2"
|
||||||
|
|
||||||
math-expression-evaluator@^1.2.14:
|
math-expression-evaluator@^1.2.14:
|
||||||
version "1.2.14"
|
version "1.2.14"
|
||||||
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.14.tgz#39511771ed9602405fba9affff17eb4d2a3843ab"
|
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.14.tgz#39511771ed9602405fba9affff17eb4d2a3843ab"
|
||||||
|
@ -3823,6 +3837,14 @@ react-redux@^5.0.0-beta.3:
|
||||||
lodash-es "^4.2.0"
|
lodash-es "^4.2.0"
|
||||||
loose-envify "^1.1.0"
|
loose-envify "^1.1.0"
|
||||||
|
|
||||||
|
react-responsive:
|
||||||
|
version "1.1.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-responsive/-/react-responsive-1.1.5.tgz#a7019a28817dcb601ef31d10d72f798a0d710a17"
|
||||||
|
dependencies:
|
||||||
|
hyphenate-style-name "^1.0.0"
|
||||||
|
matchmedia "^0.1.2"
|
||||||
|
object-assign "^4.0.1"
|
||||||
|
|
||||||
react-router@^2.8.0:
|
react-router@^2.8.0:
|
||||||
version "2.8.1"
|
version "2.8.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-router/-/react-router-2.8.1.tgz#73e9491f6ceb316d0f779829081863e378ee4ed7"
|
resolved "https://registry.yarnpkg.com/react-router/-/react-router-2.8.1.tgz#73e9491f6ceb316d0f779829081863e378ee4ed7"
|
||||||
|
|
Loading…
Reference in New Issue