From 312c51b5c87e23c62d163770d550dc94df32627f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 10 Jan 2017 17:25:10 +0100 Subject: [PATCH] Home column filters --- .../components/actions/settings.jsx | 14 +- .../components/column_collapsable.jsx | 60 ++++++++ .../components/column_settings.jsx | 68 +++++++++ .../home_timeline/components/setting_text.jsx | 41 ++++++ .../containers/column_settings_container.jsx | 21 +++ .../features/home_timeline/index.jsx | 5 +- .../components/column_settings.jsx | 131 ++++-------------- .../components/setting_toggle.jsx | 32 +++++ .../containers/column_settings_container.jsx | 6 +- .../ui/containers/status_list_container.jsx | 59 ++++++-- .../javascripts/components/locales/de.jsx | 8 +- .../components/reducers/settings.jsx | 7 + app/assets/stylesheets/components.scss | 14 +- .../api/web/settings_controller.rb | 2 +- package.json | 3 + yarn.lock | 127 +++++++++++++++-- 16 files changed, 455 insertions(+), 143 deletions(-) create mode 100644 app/assets/javascripts/components/components/column_collapsable.jsx create mode 100644 app/assets/javascripts/components/features/home_timeline/components/column_settings.jsx create mode 100644 app/assets/javascripts/components/features/home_timeline/components/setting_text.jsx create mode 100644 app/assets/javascripts/components/features/home_timeline/containers/column_settings_container.jsx create mode 100644 app/assets/javascripts/components/features/notifications/components/setting_toggle.jsx diff --git a/app/assets/javascripts/components/actions/settings.jsx b/app/assets/javascripts/components/actions/settings.jsx index 0a6fb7cdb6..c754b30ca2 100644 --- a/app/assets/javascripts/components/actions/settings.jsx +++ b/app/assets/javascripts/components/actions/settings.jsx @@ -3,13 +3,15 @@ import axios from 'axios'; export const SETTING_CHANGE = 'SETTING_CHANGE'; export function changeSetting(key, value) { - return (dispatch, getState) => { - dispatch({ - type: SETTING_CHANGE, - key, - value - }); + return { + type: SETTING_CHANGE, + key, + value + }; +}; +export function saveSettings() { + return (_, getState) => { axios.put('/api/web/settings', { data: getState().get('settings').toJS() }); diff --git a/app/assets/javascripts/components/components/column_collapsable.jsx b/app/assets/javascripts/components/components/column_collapsable.jsx new file mode 100644 index 0000000000..abd65d6337 --- /dev/null +++ b/app/assets/javascripts/components/components/column_collapsable.jsx @@ -0,0 +1,60 @@ +import PureRenderMixin from 'react-addons-pure-render-mixin'; +import { Motion, spring } from 'react-motion'; + +const iconStyle = { + fontSize: '16px', + padding: '15px', + position: 'absolute', + right: '0', + top: '-48px', + cursor: 'pointer' +}; + +const ColumnCollapsable = React.createClass({ + + propTypes: { + icon: React.PropTypes.string.isRequired, + fullHeight: React.PropTypes.number.isRequired, + children: React.PropTypes.node, + onCollapse: React.PropTypes.func + }, + + getInitialState () { + return { + collapsed: true + }; + }, + + mixins: [PureRenderMixin], + + handleToggleCollapsed () { + const currentState = this.state.collapsed; + + this.setState({ collapsed: !currentState }); + + if (!currentState && this.props.onCollapse) { + this.props.onCollapse(); + } + }, + + render () { + const { icon, fullHeight, children } = this.props; + const { collapsed } = this.state; + + return ( +
+
+ + + {({ opacity, height }) => +
+ {children} +
+ } +
+
+ ); + } +}); + +export default ColumnCollapsable; diff --git a/app/assets/javascripts/components/features/home_timeline/components/column_settings.jsx b/app/assets/javascripts/components/features/home_timeline/components/column_settings.jsx new file mode 100644 index 0000000000..714be309bc --- /dev/null +++ b/app/assets/javascripts/components/features/home_timeline/components/column_settings.jsx @@ -0,0 +1,68 @@ +import PureRenderMixin from 'react-addons-pure-render-mixin'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import ColumnCollapsable from '../../../components/column_collapsable'; +import SettingToggle from '../../notifications/components/setting_toggle'; +import SettingText from './setting_text'; + +const messages = defineMessages({ + filter_regex: { id: 'home.column_settings.filter_regex', defaultMessage: 'Filter by regular expressions' } +}); + +const outerStyle = { + background: '#373b4a', + padding: '15px' +}; + +const sectionStyle = { + cursor: 'default', + display: 'block', + fontWeight: '500', + color: '#9baec8', + marginBottom: '10px' +}; + +const rowStyle = { + +}; + +const ColumnSettings = React.createClass({ + + propTypes: { + settings: ImmutablePropTypes.map.isRequired, + onChange: React.PropTypes.func.isRequired, + onSave: React.PropTypes.func.isRequired, + intl: React.PropTypes.object.isRequired + }, + + mixins: [PureRenderMixin], + + render () { + const { settings, onChange, onSave, intl } = this.props; + + return ( + +
+ + +
+ } /> +
+ +
+ } /> +
+ + + +
+ +
+
+
+ ); + } + +}); + +export default injectIntl(ColumnSettings); diff --git a/app/assets/javascripts/components/features/home_timeline/components/setting_text.jsx b/app/assets/javascripts/components/features/home_timeline/components/setting_text.jsx new file mode 100644 index 0000000000..79697e8698 --- /dev/null +++ b/app/assets/javascripts/components/features/home_timeline/components/setting_text.jsx @@ -0,0 +1,41 @@ +import ImmutablePropTypes from 'react-immutable-proptypes'; + +const style = { + display: 'block', + fontFamily: 'inherit', + marginBottom: '10px', + padding: '7px 0', + boxSizing: 'border-box', + width: '100%' +}; + +const SettingText = React.createClass({ + + propTypes: { + settings: ImmutablePropTypes.map.isRequired, + settingKey: React.PropTypes.array.isRequired, + label: React.PropTypes.string.isRequired, + onChange: React.PropTypes.func.isRequired + }, + + handleChange (e) { + this.props.onChange(this.props.settingKey, e.target.value) + }, + + render () { + const { settings, settingKey, label } = this.props; + + return ( + + ); + } + +}); + +export default SettingText; diff --git a/app/assets/javascripts/components/features/home_timeline/containers/column_settings_container.jsx b/app/assets/javascripts/components/features/home_timeline/containers/column_settings_container.jsx new file mode 100644 index 0000000000..3b3ce19bc0 --- /dev/null +++ b/app/assets/javascripts/components/features/home_timeline/containers/column_settings_container.jsx @@ -0,0 +1,21 @@ +import { connect } from 'react-redux'; +import ColumnSettings from '../components/column_settings'; +import { changeSetting, saveSettings } from '../../../actions/settings'; + +const mapStateToProps = state => ({ + settings: state.getIn(['settings', 'home']) +}); + +const mapDispatchToProps = dispatch => ({ + + onChange (key, checked) { + dispatch(changeSetting(['home', ...key], checked)); + }, + + onSave () { + dispatch(saveSettings()); + } + +}); + +export default connect(mapStateToProps, mapDispatchToProps)(ColumnSettings); diff --git a/app/assets/javascripts/components/features/home_timeline/index.jsx b/app/assets/javascripts/components/features/home_timeline/index.jsx index e4f4fa7c71..8703d0b70e 100644 --- a/app/assets/javascripts/components/features/home_timeline/index.jsx +++ b/app/assets/javascripts/components/features/home_timeline/index.jsx @@ -4,6 +4,7 @@ import StatusListContainer from '../ui/containers/status_list_container'; import Column from '../ui/components/column'; import { refreshTimeline } from '../../actions/timelines'; import { defineMessages, injectIntl } from 'react-intl'; +import ColumnSettingsContainer from './containers/column_settings_container'; const messages = defineMessages({ title: { id: 'column.home', defaultMessage: 'Home' } @@ -12,7 +13,8 @@ const messages = defineMessages({ const HomeTimeline = React.createClass({ propTypes: { - dispatch: React.PropTypes.func.isRequired + dispatch: React.PropTypes.func.isRequired, + intl: React.PropTypes.object.isRequired }, mixins: [PureRenderMixin], @@ -26,6 +28,7 @@ const HomeTimeline = React.createClass({ return ( + ); diff --git a/app/assets/javascripts/components/features/notifications/components/column_settings.jsx b/app/assets/javascripts/components/features/notifications/components/column_settings.jsx index b4035c20d5..dfb59713c4 100644 --- a/app/assets/javascripts/components/features/notifications/components/column_settings.jsx +++ b/app/assets/javascripts/components/features/notifications/components/column_settings.jsx @@ -1,37 +1,14 @@ import PureRenderMixin from 'react-addons-pure-render-mixin'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import Toggle from 'react-toggle'; -import { Motion, spring } from 'react-motion'; import { FormattedMessage } from 'react-intl'; +import ColumnCollapsable from '../../../components/column_collapsable'; +import SettingToggle from './setting_toggle'; const outerStyle = { background: '#373b4a', padding: '15px' }; -const iconStyle = { - fontSize: '16px', - padding: '15px', - position: 'absolute', - right: '0', - top: '-48px', - cursor: 'pointer' -}; - -const labelStyle = { - display: 'block', - lineHeight: '24px', - verticalAlign: 'middle' -}; - -const labelSpanStyle = { - display: 'inline-block', - verticalAlign: 'middle', - marginBottom: '14px', - marginLeft: '8px', - color: '#9baec8' -}; - const sectionStyle = { cursor: 'default', display: 'block', @@ -48,100 +25,50 @@ const ColumnSettings = React.createClass({ propTypes: { settings: ImmutablePropTypes.map.isRequired, - onChange: React.PropTypes.func.isRequired - }, - - getInitialState () { - return { - collapsed: true - }; + onChange: React.PropTypes.func.isRequired, + onSave: React.PropTypes.func.isRequired }, mixins: [PureRenderMixin], - handleToggleCollapsed () { - this.setState({ collapsed: !this.state.collapsed }); - }, - - handleChange (key, e) { - this.props.onChange(key, e.target.checked); - }, - render () { - const { settings } = this.props; - const { collapsed } = this.state; + const { settings, onChange, onSave } = this.props; const alertStr = ; const showStr = ; return ( -
-
+ +
+ - - {({ opacity, height }) => -
-
- +
+ + +
-
- + - -
+
+ + +
- + -
- +
+ + +
- -
+ - - -
- - - -
- - - -
- - - -
-
-
- } -
-
+
+ + +
+
+ ); } diff --git a/app/assets/javascripts/components/features/notifications/components/setting_toggle.jsx b/app/assets/javascripts/components/features/notifications/components/setting_toggle.jsx new file mode 100644 index 0000000000..c2438f716e --- /dev/null +++ b/app/assets/javascripts/components/features/notifications/components/setting_toggle.jsx @@ -0,0 +1,32 @@ +import ImmutablePropTypes from 'react-immutable-proptypes'; +import Toggle from 'react-toggle'; + +const labelStyle = { + display: 'block', + lineHeight: '24px', + verticalAlign: 'middle' +}; + +const labelSpanStyle = { + display: 'inline-block', + verticalAlign: 'middle', + marginBottom: '14px', + marginLeft: '8px', + color: '#9baec8' +}; + +const SettingToggle = ({ settings, settingKey, label, onChange }) => ( + +); + +SettingToggle.propTypes = { + settings: ImmutablePropTypes.map.isRequired, + settingKey: React.PropTypes.array.isRequired, + label: React.PropTypes.node.isRequired, + onChange: React.PropTypes.func.isRequired +}; + +export default SettingToggle; diff --git a/app/assets/javascripts/components/features/notifications/containers/column_settings_container.jsx b/app/assets/javascripts/components/features/notifications/containers/column_settings_container.jsx index 5792e97e37..bc24c75e0a 100644 --- a/app/assets/javascripts/components/features/notifications/containers/column_settings_container.jsx +++ b/app/assets/javascripts/components/features/notifications/containers/column_settings_container.jsx @@ -1,6 +1,6 @@ import { connect } from 'react-redux'; import ColumnSettings from '../components/column_settings'; -import { changeSetting } from '../../../actions/settings'; +import { changeSetting, saveSettings } from '../../../actions/settings'; const mapStateToProps = state => ({ settings: state.getIn(['settings', 'notifications']) @@ -10,6 +10,10 @@ const mapDispatchToProps = dispatch => ({ onChange (key, checked) { dispatch(changeSetting(['notifications', ...key], checked)); + }, + + onSave () { + dispatch(saveSettings()); } }); diff --git a/app/assets/javascripts/components/features/ui/containers/status_list_container.jsx b/app/assets/javascripts/components/features/ui/containers/status_list_container.jsx index 1621cec7b3..7b893711c1 100644 --- a/app/assets/javascripts/components/features/ui/containers/status_list_container.jsx +++ b/app/assets/javascripts/components/features/ui/containers/status_list_container.jsx @@ -2,26 +2,55 @@ import { connect } from 'react-redux'; import StatusList from '../../../components/status_list'; import { expandTimeline, scrollTopTimeline } from '../../../actions/timelines'; import Immutable from 'immutable'; +import { createSelector } from 'reselect'; + +const getStatusIds = createSelector([ + (state, { type }) => state.getIn(['settings', type]), + (state, { type }) => state.getIn(['timelines', type, 'items'], Immutable.List()), + (state) => state.get('statuses') +], (columnSettings, statusIds, statuses) => statusIds.filter(id => { + const statusForId = statuses.get(id); + let showStatus = true; + + if (columnSettings.getIn(['shows', 'reblog']) === false) { + showStatus = showStatus && statusForId.get('reblog') === null; + } + + if (columnSettings.getIn(['shows', 'reply']) === false) { + showStatus = showStatus && statusForId.get('in_reply_to_id') === null; + } + + if (columnSettings.getIn(['regex', 'body'], '').trim().length > 0) { + try { + const regex = new RegExp(columnSettings.getIn(['regex', 'body']).trim(), 'i'); + showStatus = showStatus && !regex.test(statusForId.get('reblog') ? statuses.getIn([statusForId.get('reblog'), 'content']) : statusForId.get('content')); + } catch(e) { + // Bad regex, don't affect filters + } + } + + return showStatus; +})); const mapStateToProps = (state, props) => ({ - statusIds: state.getIn(['timelines', props.type, 'items'], Immutable.List()) + statusIds: getStatusIds(state, props) }); -const mapDispatchToProps = function (dispatch, props) { - return { - onScrollToBottom () { - dispatch(scrollTopTimeline(props.type, false)); - dispatch(expandTimeline(props.type, props.id)); - }, +const mapDispatchToProps = (dispatch, { type, id }) => ({ - onScrollToTop () { - dispatch(scrollTopTimeline(props.type, true)); - }, + onScrollToBottom () { + dispatch(scrollTopTimeline(type, false)); + dispatch(expandTimeline(type, id)); + }, - onScroll () { - dispatch(scrollTopTimeline(props.type, false)); - } - }; -}; + onScrollToTop () { + dispatch(scrollTopTimeline(type, true)); + }, + + onScroll () { + dispatch(scrollTopTimeline(type, false)); + } + +}); export default connect(mapStateToProps, mapDispatchToProps)(StatusList); diff --git a/app/assets/javascripts/components/locales/de.jsx b/app/assets/javascripts/components/locales/de.jsx index c37a71c211..7d32824f14 100644 --- a/app/assets/javascripts/components/locales/de.jsx +++ b/app/assets/javascripts/components/locales/de.jsx @@ -65,7 +65,13 @@ const en = { "notifications.column_settings.mention": "Erwähnungen:", "notifications.column_settings.reblog": "Geteilte Beiträge:", "follow_request.authorize": "Erlauben", - "follow_request.reject": "Ablehnen" + "follow_request.reject": "Ablehnen", + "home.column_settings.basic": "Einfach", + "home.column_settings.advanced": "Fortgeschritten", + "home.column_settings.show_reblogs": "Geteilte Beiträge anzeigen", + "home.column_settings.show_replies": "Antworten anzeigen", + "home.column_settings.filter_regex": "Filter durch reguläre Ausdrücke", + "missing_indicator.label": "Nicht gefunden" }; export default en; diff --git a/app/assets/javascripts/components/reducers/settings.jsx b/app/assets/javascripts/components/reducers/settings.jsx index 2a834d81c1..8bd9edae21 100644 --- a/app/assets/javascripts/components/reducers/settings.jsx +++ b/app/assets/javascripts/components/reducers/settings.jsx @@ -3,6 +3,13 @@ import { STORE_HYDRATE } from '../actions/store'; import Immutable from 'immutable'; const initialState = Immutable.Map({ + home: Immutable.Map({ + shows: Immutable.Map({ + reblog: true, + reply: true + }) + }), + notifications: Immutable.Map({ alerts: Immutable.Map({ follow: true, diff --git a/app/assets/stylesheets/components.scss b/app/assets/stylesheets/components.scss index 0abe8c808c..f1edfce9df 100644 --- a/app/assets/stylesheets/components.scss +++ b/app/assets/stylesheets/components.scss @@ -649,4 +649,16 @@ right: 8px !important; left: initial !important; } -} \ No newline at end of file +} + +.setting-text { + color: #9baec8; + background: transparent; + border: none; + border-bottom: 2px solid #9baec8; + + &:focus, &:active { + color: #fff; + border-bottom-color: #2b90d9; + } +} diff --git a/app/controllers/api/web/settings_controller.rb b/app/controllers/api/web/settings_controller.rb index e6f6901144..c00e016a4a 100644 --- a/app/controllers/api/web/settings_controller.rb +++ b/app/controllers/api/web/settings_controller.rb @@ -6,7 +6,7 @@ class Api::Web::SettingsController < ApiController before_action :require_user! def update - setting = Web::Setting.where(user: current_user).first_or_initialize(user: current_user) + setting = ::Web::Setting.where(user: current_user).first_or_initialize(user: current_user) setting.data = params[:data] setting.save! diff --git a/package.json b/package.json index 6a072ca064..8c75d632be 100644 --- a/package.json +++ b/package.json @@ -53,5 +53,8 @@ "sass-loader": "^4.0.2", "sinon": "^1.17.6", "style-loader": "^0.13.1" + }, + "dependencies": { + "webpack": "^1.14.0" } } diff --git a/yarn.lock b/yarn.lock index 948de9ba82..fac04d0b3d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1124,6 +1124,12 @@ browser-stdout@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" +browserify-aes@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-0.4.0.tgz#067149b668df31c4b58533e02d01e806d8608e2c" + dependencies: + inherits "^2.0.1" + browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.0.6.tgz#5e7725dbdef1fd5930d4ebab48567ce451c48a0a" @@ -1186,7 +1192,7 @@ browserify-sign@^4.0.0: inherits "^2.0.1" parse-asn1 "^5.0.0" -browserify-zlib@~0.1.2, browserify-zlib@~0.1.4: +browserify-zlib@^0.1.4, browserify-zlib@~0.1.2, browserify-zlib@~0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" dependencies: @@ -1520,7 +1526,7 @@ constants-browserify@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-0.0.1.tgz#92577db527ba6c4cf0a4568d84bc031f441e21f2" -constants-browserify@~1.0.0: +constants-browserify@^1.0.0, constants-browserify@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -1596,6 +1602,15 @@ cryptiles@2.x.x: dependencies: boom "2.x.x" +crypto-browserify@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.3.0.tgz#b9fc75bb4a0ed61dcf1cd5dae96eb30c9c3e506c" + dependencies: + browserify-aes "0.4.0" + pbkdf2-compat "2.0.1" + ripemd160 "0.2.0" + sha.js "2.2.6" + crypto-browserify@^3.0.0: version "3.11.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.0.tgz#3652a0906ab9b2a7e0c3ce66a408e957a2485522" @@ -2559,7 +2574,7 @@ https-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.0.tgz#b3ffdfe734b2a3d4a9efd58e8654c91fce86eafd" -https-browserify@~0.0.0: +https-browserify@0.0.1, https-browserify@~0.0.0: version "0.0.1" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82" @@ -3458,6 +3473,34 @@ node-libs-browser@^0.6.0: util "~0.10.3" vm-browserify "0.0.4" +node-libs-browser@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-0.7.0.tgz#3e272c0819e308935e26674408d7af0e1491b83b" + dependencies: + assert "^1.1.1" + browserify-zlib "^0.1.4" + buffer "^4.9.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "3.3.0" + domain-browser "^1.1.1" + events "^1.0.0" + https-browserify "0.0.1" + os-browserify "^0.2.0" + path-browserify "0.0.0" + process "^0.11.0" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.0.5" + stream-browserify "^2.0.1" + stream-http "^2.3.1" + string_decoder "^0.10.25" + timers-browserify "^2.0.2" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.10.3" + vm-browserify "0.0.4" + node-pre-gyp@^0.6.29: version "0.6.30" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.30.tgz#64d3073a6f573003717ccfe30c89023297babba1" @@ -3663,6 +3706,10 @@ optionator@^0.8.1: type-check "~0.3.2" wordwrap "~1.0.0" +os-browserify@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.2.1.tgz#63fc4ccee5d2d7763d26bbf8601078e6c2e0044f" + os-browserify@~0.1.1, os-browserify@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.1.2.tgz#49ca0293e0b19590a5f5de10c7f265a617d8fe54" @@ -4133,7 +4180,7 @@ query-string@^4.1.0: object-assign "^4.1.0" strict-uri-encode "^1.0.0" -querystring-es3@~0.2.0: +querystring-es3@^0.2.0, querystring-es3@~0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -4397,7 +4444,7 @@ readable-stream@1.1, readable-stream@^1.0.27-1, readable-stream@^1.1.13: isarray "0.0.1" string_decoder "~0.10.x" -"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.0, readable-stream@~2.1.4: +"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.0, readable-stream@~2.1.4: version "2.1.5" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" dependencies: @@ -4689,6 +4736,10 @@ set-immediate-shim@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + setprototypeof@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.1.tgz#52009b27888c4dc48f591949c0a8275834c1ca7e" @@ -4784,6 +4835,10 @@ source-list-map@^0.1.4, source-list-map@~0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.6.tgz#e1e6f94f0b40c4d28dcf8f5b8766e0e45636877f" +source-list-map@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.7.tgz#d4b5ce2a46535c72c7e8527c71a77d250618172e" + source-map-support@^0.4.2: version "0.4.3" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.3.tgz#693c8383d4389a4569486987c219744dfc601685" @@ -4861,7 +4916,7 @@ stream-browserify@^1.0.0: inherits "~2.0.1" readable-stream "^1.0.27-1" -stream-browserify@^2.0.0: +stream-browserify@^2.0.0, stream-browserify@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" dependencies: @@ -4879,7 +4934,7 @@ stream-consume@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f" -stream-http@^2.0.0: +stream-http@^2.0.0, stream-http@^2.3.1: version "2.4.0" resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.4.0.tgz#9599aa8e263667ce4190e0dc04a1d065d3595a7e" dependencies: @@ -4924,7 +4979,7 @@ string.prototype.padstart@^3.0.0: es-abstract "^1.4.3" function-bind "^1.0.2" -string_decoder@~0.10.0, string_decoder@~0.10.25, string_decoder@~0.10.x: +string_decoder@^0.10.25, string_decoder@~0.10.0, string_decoder@~0.10.25, string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" @@ -5051,6 +5106,12 @@ timers-browserify@^1.0.1: dependencies: process "~0.11.0" +timers-browserify@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.2.tgz#ab4883cf597dcd50af211349a00fbca56ac86b86" + dependencies: + setimmediate "^1.0.4" + to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" @@ -5125,6 +5186,15 @@ uglify-js@~2.6.0: uglify-to-browserify "~1.0.0" yargs "~3.10.0" +uglify-js@~2.7.3: + version "2.7.5" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.5.tgz#4612c0c7baaee2ba7c487de4904ae122079f2ca8" + dependencies: + async "~0.2.6" + source-map "~0.5.1" + uglify-to-browserify "~1.0.0" + yargs "~3.10.0" + uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" @@ -5162,16 +5232,16 @@ url-loader@^0.5.7: loader-utils "0.2.x" mime "1.2.x" -url@~0.10.1: - version "0.10.3" - resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" +url@^0.11.0, url@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" dependencies: punycode "1.3.2" querystring "0.2.0" -url@~0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" +url@~0.10.1: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" dependencies: punycode "1.3.2" querystring "0.2.0" @@ -5184,7 +5254,7 @@ util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" -util@0.10.3, "util@>=0.10.3 <1", util@~0.10.1, util@~0.10.3: +util@0.10.3, "util@>=0.10.3 <1", util@^0.10.3, util@~0.10.1, util@~0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" dependencies: @@ -5260,6 +5330,13 @@ webpack-core@~0.6.0: source-list-map "~0.1.0" source-map "~0.4.1" +webpack-core@~0.6.9: + version "0.6.9" + resolved "https://registry.yarnpkg.com/webpack-core/-/webpack-core-0.6.9.tgz#fc571588c8558da77be9efb6debdc5a3b172bdc2" + dependencies: + source-list-map "~0.1.7" + source-map "~0.4.1" + webpack-dev-middleware@^1.6.0: version "1.8.4" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.8.4.tgz#e8765c9122887ce9e3abd4cc9c3eb31b61e0948d" @@ -5298,6 +5375,26 @@ webpack@^1.13.1: watchpack "^0.2.1" webpack-core "~0.6.0" +webpack@^1.14.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-1.14.0.tgz#54f1ffb92051a328a5b2057d6ae33c289462c823" + dependencies: + acorn "^3.0.0" + async "^1.3.0" + clone "^1.0.2" + enhanced-resolve "~0.9.0" + interpret "^0.6.4" + loader-utils "^0.2.11" + memory-fs "~0.3.0" + mkdirp "~0.5.0" + node-libs-browser "^0.7.0" + optimist "~0.6.0" + supports-color "^3.1.0" + tapable "~0.1.8" + uglify-js "~2.7.3" + watchpack "^0.2.1" + webpack-core "~0.6.9" + whatwg-fetch@>=0.10.0: version "1.0.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-1.0.0.tgz#01c2ac4df40e236aaa18480e3be74bd5c8eb798e"