diff --git a/package.json b/package.json index be807332d..0a67781fb 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "postinstall": "electron-builder install-app-deps && node build/downloadDaemon.js" }, "dependencies": { + "@lbry/components": "^2.2.0", "@types/three": "^0.93.1", "bluebird": "^3.5.1", "breakdance": "^3.0.1", @@ -52,7 +53,7 @@ "hast-util-sanitize": "^1.1.2", "keytar": "^4.2.1", "lbry-format": "https://github.com/lbryio/lbry-format.git", - "lbry-redux": "lbryio/lbry-redux#42c185e922a7c6091b0e1580bacbfd8e02f45a91", + "lbry-redux": "lbryio/lbry-redux#3ab065b11a52d3e2e6a50a25459f9ff0aac03b13", "lbryinc": "lbryio/lbryinc#60d80401891743f991c040bafa8e51da7e939777", "localforage": "^1.7.1", "mammoth": "^1.4.6", @@ -62,8 +63,8 @@ "node-fetch": "^2.3.0", "qrcode.react": "^0.8.0", "rc-progress": "^2.0.6", - "react": "^16.6.0", - "react-dom": "^16.6.0", + "react": "^16.8.2", + "react-dom": "^16.8.2", "react-feather": "^1.0.8", "react-modal": "^3.1.7", "react-paginate": "^5.2.1", @@ -89,7 +90,6 @@ "y18n": "^4.0.0" }, "devDependencies": { - "@lbry/components": "^2.2.0", "babel-eslint": "^8.2.2", "babel-plugin-module-resolver": "^3.1.1", "babel-polyfill": "^6.26.0", diff --git a/src/renderer/component/common/form-components/form-field.jsx b/src/renderer/component/common/form-components/form-field.jsx index 7ed2209d2..3e2ba111c 100644 --- a/src/renderer/component/common/form-components/form-field.jsx +++ b/src/renderer/component/common/form-components/form-field.jsx @@ -29,14 +29,16 @@ type Props = { disabled?: boolean, }, inputButton: ?React.Node, + blockWrap: boolean, }; export class FormField extends React.PureComponent { static defaultProps = { labelOnLeft: false, + blockWrap: true, }; - constructor(props) { + constructor(props: Props) { super(props); this.input = React.createRef(); } @@ -66,31 +68,39 @@ export class FormField extends React.PureComponent { autoFocus, inputButton, labelOnLeft, + blockWrap, ...inputProps } = this.props; const errorMessage = typeof error === 'object' ? error.message : error; + const Wrapper = blockWrap + ? ({ children: innerChildren }) => {innerChildren} + : ({ children: innerChildren }) => {innerChildren}; + let input; if (type) { if (type === 'radio') { input = ( - + - + ); } else if (type === 'checkbox') { + // web components treat props weird + // we need to fully remove it for proper component:attribute css styling + const elementProps = inputProps.disabled ? { disabled: true } : {}; input = ( - - + + - + ); } else if (type === 'setting') { // 'setting' should only be used for settings. Forms should use "checkbox" diff --git a/src/renderer/component/fileListSearch/index.js b/src/renderer/component/fileListSearch/index.js index 351776461..32b04d220 100644 --- a/src/renderer/component/fileListSearch/index.js +++ b/src/renderer/component/fileListSearch/index.js @@ -1,9 +1,14 @@ import { connect } from 'react-redux'; -import { makeSelectSearchUris, selectIsSearching, selectSearchDownloadUris } from 'lbry-redux'; +import { + makeSelectSearchUris, + selectIsSearching, + selectSearchDownloadUris, + makeSelectQueryWithOptions, +} from 'lbry-redux'; import FileListSearch from './view'; const select = (state, props) => ({ - uris: makeSelectSearchUris(props.query)(state), + uris: makeSelectSearchUris(makeSelectQueryWithOptions()(state))(state), downloadUris: selectSearchDownloadUris(props.query)(state), isSearching: selectIsSearching(state), }); diff --git a/src/renderer/component/fileListSearch/view.jsx b/src/renderer/component/fileListSearch/view.jsx index 35f95b9ab..d4398fb2b 100644 --- a/src/renderer/component/fileListSearch/view.jsx +++ b/src/renderer/component/fileListSearch/view.jsx @@ -11,26 +11,11 @@ type Props = { query: string, isSearching: boolean, uris: ?Array, - downloadUris: ?Array, }; class FileListSearch extends React.PureComponent { render() { - const { uris, query, downloadUris, isSearching } = this.props; - - const fileResults = []; - const channelResults = []; - if (uris && uris.length) { - uris.forEach(uri => { - const isChannel = parseURI(uri).claimName[0] === '@'; - if (isChannel) { - channelResults.push(uri); - } else { - fileResults.push(uri); - } - }); - } - + const { uris, query, isSearching } = this.props; return ( query && ( @@ -38,26 +23,15 @@ class FileListSearch extends React.PureComponent {
{__('Search Results')}
- {!isSearching && fileResults.length ? ( - fileResults.map(uri => ) - ) : ( - - )} -
- -
-
{__('Channels')}
- {!isSearching && channelResults.length ? ( - channelResults.map(uri => ) - ) : ( - - )} -
- -
-
{__('Your downloads')}
- {downloadUris && downloadUris.length ? ( - downloadUris.map(uri => ) + {!isSearching && uris && uris.length ? ( + uris.map( + uri => + parseURI(uri).claimName[0] === '@' ? ( + + ) : ( + + ) + ) ) : ( )} diff --git a/src/renderer/component/fileTile/view.jsx b/src/renderer/component/fileTile/view.jsx index 9527ed0dc..863c8fae5 100644 --- a/src/renderer/component/fileTile/view.jsx +++ b/src/renderer/component/fileTile/view.jsx @@ -156,10 +156,12 @@ class FileTile extends React.PureComponent {
{(title || name) && ( - + )}
+ {size === 'small' && this.renderFileProperties()} + {size !== 'small' ? (
{__('Published to')} {' '} @@ -169,9 +171,9 @@ class FileTile extends React.PureComponent {
-
-
- +
+ +
)} @@ -184,7 +186,7 @@ class FileTile extends React.PureComponent {
)} - {this.renderFileProperties()} + {size !== 'small' && this.renderFileProperties()} {!name && ( ({ + options: selectSearchOptions(state), +}); + +const perform = dispatch => ({ + setSearchOption: (option, value) => dispatch(doUpdateSearchOptions({ [option]: value })), +}); + +export default connect( + select, + perform +)(SearchOptions); diff --git a/src/renderer/component/searchOptions/view.jsx b/src/renderer/component/searchOptions/view.jsx new file mode 100644 index 000000000..39df0f152 --- /dev/null +++ b/src/renderer/component/searchOptions/view.jsx @@ -0,0 +1,123 @@ +// @flow +import * as ICONS from 'constants/icons'; +import React, { useState } from 'react'; +import { SEARCH_OPTIONS } from 'lbry-redux'; +import { Form, FormField } from 'component/common/form'; +import posed from 'react-pose'; +import Button from 'component/button'; + +const ExpandableOptions = posed.div({ + hide: { height: 0, opacity: 0 }, + show: { height: 280, opacity: 1 }, +}); + +type Props = { + setSearchOption: (string, boolean | string | number) => void, + options: {}, +}; + +const SearchOptions = (props: Props) => { + const { options, setSearchOption } = props; + const [expanded, setExpanded] = useState(false); + const resultCount = options[SEARCH_OPTIONS.RESULT_COUNT]; + + return ( +
+
+
*/} +
+ + {expanded && ( +
+
+ {__('Search For')} + {[ + { + option: SEARCH_OPTIONS.INCLUDE_FILES, + label: __('Files'), + }, + { + option: SEARCH_OPTIONS.INCLUDE_CHANNELS, + label: __('Channels'), + }, + { + option: SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS, + label: __('Everything'), + }, + ].map(({ option, label }) => ( + setSearchOption(SEARCH_OPTIONS.CLAIM_TYPE, option)} + /> + ))} +
+ +
+ {__('File Types')} + {[ + { + option: SEARCH_OPTIONS.MEDIA_VIDEO, + label: __('Videos'), + }, + { + option: SEARCH_OPTIONS.MEDIA_AUDIO, + label: __('Sounds'), + }, + { + option: SEARCH_OPTIONS.MEDIA_IMAGE, + label: __('Images'), + }, + { + option: SEARCH_OPTIONS.MEDIA_TEXT, + label: __('Text'), + }, + { + option: SEARCH_OPTIONS.MEDIA_APPLICATION, + label: __('Other Files'), + }, + ].map(({ option, label }) => ( + setSearchOption(option, !options[option])} + /> + ))} +
+ +
+ {__('Other Options')} + setSearchOption(SEARCH_OPTIONS.RESULT_COUNT, e.target.value)} + blockWrap={false} + label={__('Returned Results')} + /> +
+
+ )} +
+ + ); +}; + +export default SearchOptions; diff --git a/src/renderer/component/wunderbar/index.js b/src/renderer/component/wunderbar/index.js index 8c8107940..beb65642d 100644 --- a/src/renderer/component/wunderbar/index.js +++ b/src/renderer/component/wunderbar/index.js @@ -10,8 +10,6 @@ import { doToast, } from 'lbry-redux'; import analytics from 'analytics'; -import { makeSelectClientSetting } from 'redux/selectors/settings'; -import * as settings from 'constants/settings'; import { doNavigate } from 'redux/actions/navigation'; import Wunderbar from './view'; @@ -27,13 +25,12 @@ const select = state => { ...searchState, wunderbarValue, suggestions: selectSearchSuggestions(state), - resultCount: makeSelectClientSetting(settings.RESULT_COUNT)(state), }; }; const perform = dispatch => ({ - onSearch: (query, size) => { - dispatch(doSearch(query, size)); + onSearch: query => { + dispatch(doSearch(query)); dispatch(doNavigate(`/search`, { query })); analytics.apiLogSearch(); }, diff --git a/src/renderer/component/wunderbar/view.jsx b/src/renderer/component/wunderbar/view.jsx index 4b546094d..85e38c243 100644 --- a/src/renderer/component/wunderbar/view.jsx +++ b/src/renderer/component/wunderbar/view.jsx @@ -12,13 +12,12 @@ const ESC_KEY_CODE = 27; type Props = { updateSearchQuery: string => void, - onSearch: (string, ?number) => void, + onSearch: string => void, onSubmit: (string, {}) => void, wunderbarValue: ?string, suggestions: Array, doFocus: () => void, doBlur: () => void, - resultCount: number, focused: boolean, doShowSnackBar: ({}) => void, }; @@ -82,7 +81,7 @@ class WunderBar extends React.PureComponent { } handleSubmit(value: string, suggestion?: { value: string, type: string }) { - const { onSubmit, onSearch, resultCount } = this.props; + const { onSubmit, onSearch } = this.props; const query = value.trim(); const getParams = () => { const parts = query.split('?'); @@ -98,7 +97,7 @@ class WunderBar extends React.PureComponent { // User selected a suggestion if (suggestion) { if (suggestion.type === 'search') { - onSearch(query, resultCount); + onSearch(query); } else if (isURIValid(query)) { const params = getParams(); const uri = normalizeURI(query); @@ -125,7 +124,7 @@ class WunderBar extends React.PureComponent { }); } } catch (e) { - onSearch(query, resultCount); + onSearch(query); } } diff --git a/src/renderer/constants/icons.js b/src/renderer/constants/icons.js index 52754f7d3..945023cee 100644 --- a/src/renderer/constants/icons.js +++ b/src/renderer/constants/icons.js @@ -41,3 +41,6 @@ export const WALLET = 'CreditCard'; export const SETTINGS = 'Settings'; export const INVITE = 'Users'; export const FILE = 'File'; +export const OPTIONS = 'Sliders'; +export const YES = 'ThumbsUp'; +export const NO = 'ThumbsDown'; diff --git a/src/renderer/page/search/index.js b/src/renderer/page/search/index.js index d47469617..5952146a3 100644 --- a/src/renderer/page/search/index.js +++ b/src/renderer/page/search/index.js @@ -1,22 +1,16 @@ import { connect } from 'react-redux'; -import * as settings from 'constants/settings'; import { selectIsSearching, makeSelectCurrentParam, doUpdateSearchQuery } from 'lbry-redux'; -import { doSetClientSetting } from 'redux/actions/settings'; import { doNavigate } from 'redux/actions/navigation'; -import { makeSelectClientSetting } from 'redux/selectors/settings'; import SearchPage from './view'; const select = state => ({ isSearching: selectIsSearching(state), query: makeSelectCurrentParam('query')(state), - showUnavailable: makeSelectClientSetting(settings.SHOW_UNAVAILABLE)(state), - resultCount: makeSelectClientSetting(settings.RESULT_COUNT)(state), }); const perform = dispatch => ({ navigate: path => dispatch(doNavigate(path)), updateSearchQuery: query => dispatch(doUpdateSearchQuery(query)), - setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), }); export default connect( diff --git a/src/renderer/page/search/view.jsx b/src/renderer/page/search/view.jsx index fd947d965..ffc38346b 100644 --- a/src/renderer/page/search/view.jsx +++ b/src/renderer/page/search/view.jsx @@ -1,5 +1,4 @@ // @flow -import * as SETTINGS from 'constants/settings'; import * as ICONS from 'constants/icons'; import * as React from 'react'; import { isURIValid, normalizeURI, parseURI } from 'lbry-redux'; @@ -9,32 +8,15 @@ import FileListSearch from 'component/fileListSearch'; import Page from 'component/page'; import ToolTip from 'component/common/tooltip'; import Icon from 'component/common/icon'; +import SearchOptions from 'component/searchOptions'; type Props = { query: ?string, - resultCount: number, - setClientSetting: (string, number | boolean) => void, }; class SearchPage extends React.PureComponent { - constructor() { - super(); - (this: any).onShowUnavailableChange = this.onShowUnavailableChange.bind(this); - (this: any).onSearchResultCountChange = this.onSearchResultCountChange.bind(this); - } - - onSearchResultCountChange(event: SyntheticInputEvent<*>) { - const count = Number(event.target.value); - this.props.setClientSetting(SETTINGS.RESULT_COUNT, count); - } - - onShowUnavailableChange(event: SyntheticInputEvent<*>) { - this.props.setClientSetting(SETTINGS.SHOW_UNAVAILABLE, event.target.checked); - } - render() { - const { query, resultCount } = this.props; - + const { query } = this.props; const isValid = isURIValid(query); let uri; @@ -69,14 +51,9 @@ class SearchPage extends React.PureComponent { )} - {/* - Commented out until I figure out what to do with it in my next PR -
- - */} -
+ +
{__('These search results are provided by LBRY, Inc.')}
diff --git a/src/renderer/scss/component/_button.scss b/src/renderer/scss/component/_button.scss index 35e827908..24b9d49b5 100644 --- a/src/renderer/scss/component/_button.scss +++ b/src/renderer/scss/component/_button.scss @@ -97,7 +97,11 @@ } .button--uri-indicator { - color: rgba($lbry-white, 0.9); + width: 100%; + overflow: hidden; + text-align: left; + text-overflow: ellipsis; + white-space: nowrap; transition: color 0.2s; &:hover { diff --git a/src/renderer/scss/component/_form-field.scss b/src/renderer/scss/component/_form-field.scss index 9b41662af..002c9f974 100644 --- a/src/renderer/scss/component/_form-field.scss +++ b/src/renderer/scss/component/_form-field.scss @@ -2,6 +2,17 @@ // lbry/components overrides and minor styles +input[type='number'] { + padding: var(--spacing-s); + width: 8em; +} + +checkbox-element { + &[disabled='true'] { + opacity: 0.3; + } +} + checkbox-element, radio-element, fieldset:last-child, @@ -9,6 +20,21 @@ fieldset-section:last-child { margin-bottom: 0; } +checkbox-element, +radio-element { + input[type='checkbox']:checked + label { + color: $lbry-black; + + [data-mode='dark'] & { + color: $lbry-white; + + &:hover { + color: $lbry-teal-4; + } + } + } +} + fieldset-group.fieldset-group--smushed { justify-content: flex-start; @@ -41,6 +67,10 @@ form { background-color: $lbry-teal-5; border-color: $lbry-teal-5; } + + legend { + background-color: $lbry-cyan-5; + } } } diff --git a/src/renderer/scss/component/_media.scss b/src/renderer/scss/component/_media.scss index b29641c73..74e90998d 100644 --- a/src/renderer/scss/component/_media.scss +++ b/src/renderer/scss/component/_media.scss @@ -14,6 +14,7 @@ .media-tile { display: flex; font-size: 1.5rem; + position: relative; &:not(:last-of-type) { margin-bottom: var(--spacing-vertical-large); @@ -26,6 +27,7 @@ .media__info { margin-left: var(--spacing-vertical-medium); width: calc(80% - 20rem); + min-width: 40rem; } } @@ -38,7 +40,7 @@ .media__info { margin-left: var(--spacing-vertical-large); - width: calc(80% - 30rem); + flex: 1; } .media__subtext { @@ -54,21 +56,26 @@ } .media__thumb { - width: 10em; + width: 11em; } .media__info { - // padding-left: var(--spacing-vertical-medium); width: calc(100% - 10em); + min-width: auto; + position: relative; } .media__title { margin-bottom: var(--spacing-vertical-small); } + .media__subtext:last-child { + margin-bottom: 0; + } + .media__properties { - bottom: -1.5rem; - left: calc(-100% - 1.5rem); + bottom: 0.5rem; + left: calc(-100% - -2rem); position: absolute; padding: 0 var(--spacing-vertical-small); border-radius: 5px; @@ -143,7 +150,7 @@ .media__action-group { > *:not(:last-child) { - margin-right: var(--spacing-vertical-large); + margin-right: var(--spacing-vertical-medium); } } @@ -193,6 +200,11 @@ .media__subtitle { font-size: 0.8em; + color: rgba($lbry-black, 0.8); + + [data-mode='dark'] & { + color: rgba($lbry-white, 0.8); + } } .media__subtitle--large { @@ -412,7 +424,7 @@ color: $lbry-white; } - .media__subtext { + .media__subtitle { color: mix($lbry-cyan-5, $lbry-white, 20%); } } diff --git a/src/renderer/scss/component/_search.scss b/src/renderer/scss/component/_search.scss index fbcdfc78a..5155333c1 100644 --- a/src/renderer/scss/component/_search.scss +++ b/src/renderer/scss/component/_search.scss @@ -12,6 +12,10 @@ color: rgba($lbry-white, 0.6); } + .media__subtitle { + color: rgba($lbry-white, 0.9); + } + html[data-mode='dark'] & { background-color: transparent; border-bottom: 1px solid rgba($lbry-white, 0.1); @@ -46,3 +50,43 @@ @extend .media-group__header-title; margin-bottom: var(--spacing-vertical-large); } + +.search__options-wrapper { + font-size: 1.25em; +} + +.search__options { + margin-top: var(--spacing-vertical-large); + + legend { + &.search__legend--1 { + background-color: $lbry-teal-1; + } + + &.search__legend--2 { + background-color: $lbry-cyan-1; + } + + &.search__legend--3 { + background-color: $lbry-pink-1; + } + + [data-mode='dark'] & { + &.search__legend--1 { + background-color: $lbry-teal-5; + } + + &.search__legend--2 { + background-color: $lbry-cyan-5; + } + + &.search__legend--3 { + background-color: $lbry-pink-5; + } + } + } + + fieldset:not(:first-child) { + margin-top: var(--spacing-vertical-large); + } +} diff --git a/src/renderer/scss/init/_gui.scss b/src/renderer/scss/init/_gui.scss index 2b3be69d0..f3de30d6b 100644 --- a/src/renderer/scss/init/_gui.scss +++ b/src/renderer/scss/init/_gui.scss @@ -86,7 +86,9 @@ code { } .truncated-text { - @include truncate; + display: -webkit-box; + overflow: hidden; + -webkit-box-orient: vertical; } .busy-indicator__loader { diff --git a/src/renderer/scss/init/_mixins.scss b/src/renderer/scss/init/_mixins.scss index 9ee779c07..471d84666 100644 --- a/src/renderer/scss/init/_mixins.scss +++ b/src/renderer/scss/init/_mixins.scss @@ -1,30 +1,3 @@ -@mixin between { - display: flex; - justify-content: space-between; -} - -@mixin ellipsis { - // to take over for truncate on LBRY Web - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -@mixin font-mono { - font-family: Inconsolata, 'Fira Mono', 'Droid Sans Mono', 'Source Code Pro', Consolas, - 'Lucida Console', 'Courier New', Courier, monospace; -} - -@mixin font-sans { - font-family: 'Inter UI', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, - sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; -} - -@mixin font-serif { - font-family: 'Apple Garamond', Baskerville, Georgia, 'Times New Roman', 'Droid Serif', Times, - 'Source Serif Pro', serif; -} - @mixin placeholder { animation: pulse 2s infinite ease-in-out; background-color: $lbry-gray-2; @@ -33,26 +6,3 @@ background-color: rgba($lbry-white, 0.1); } } - -@mixin thumbnail { - &::before, - &::after { - content: ''; - } - - &::before { - float: left; - padding-top: var(--video-aspect-ratio); - } - - &::after { - clear: both; - display: block; - } -} - -@mixin truncate { - display: -webkit-box; - overflow: hidden; - -webkit-box-orient: vertical; -} diff --git a/src/renderer/store.js b/src/renderer/store.js index 3b1da6665..3ac37293a 100644 --- a/src/renderer/store.js +++ b/src/renderer/store.js @@ -102,12 +102,13 @@ const fileInfoFilter = createFilter('fileInfo', [ const appFilter = createFilter('app', ['hasClickedComment']); // We only need to persist the receiveAddress for the wallet const walletFilter = createFilter('wallet', ['receiveAddress']); +const searchFilter = createFilter('search', ['options']); const persistOptions = { - whitelist: ['subscriptions', 'publish', 'wallet', 'content', 'fileInfo', 'app'], + whitelist: ['subscriptions', 'publish', 'wallet', 'content', 'fileInfo', 'app', 'search'], // Order is important. Needs to be compressed last or other transforms can't // read the data - transforms: [walletFilter, contentFilter, fileInfoFilter, appFilter, compressor], + transforms: [walletFilter, contentFilter, fileInfoFilter, appFilter, searchFilter, compressor], debounce: 10000, storage: localForage, }; diff --git a/yarn.lock b/yarn.lock index c8caad665..4fd479e9e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5660,9 +5660,9 @@ lazy-val@^1.0.3: tar-stream "^1.6.2" zstd-codec "^0.1.1" -lbry-redux@lbryio/lbry-redux#42c185e922a7c6091b0e1580bacbfd8e02f45a91: +lbry-redux@lbryio/lbry-redux#2b725cb31729234ba73117e2a74688b8bba26e7c: version "0.0.1" - resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/42c185e922a7c6091b0e1580bacbfd8e02f45a91" + resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/2b725cb31729234ba73117e2a74688b8bba26e7c" dependencies: proxy-polyfill "0.1.6" reselect "^3.0.0" @@ -7868,14 +7868,15 @@ rc@^1.0.1, rc@^1.1.2, rc@^1.1.6, rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-dom@^16.6.0: - version "16.7.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0.tgz#a17b2a7ca89ee7390bc1ed5eb81783c7461748b8" +react-dom@^16.8.2: + version "16.8.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.2.tgz#7c8a69545dd554d45d66442230ba04a6a0a3c3d3" + integrity sha512-cPGfgFfwi+VCZjk73buu14pYkYBR1b/SRMSYqkLDdhSEHnSwcuYTPu6/Bh6ZphJFIk80XLvbSe2azfcRzNF+Xg== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.12.0" + scheduler "^0.13.2" react-feather@^1.0.8: version "1.1.1" @@ -7952,14 +7953,15 @@ react@^0.14.5: envify "^3.0.0" fbjs "^0.6.1" -react@^16.6.0: - version "16.7.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.7.0.tgz#b674ec396b0a5715873b350446f7ea0802ab6381" +react@^16.8.2: + version "16.8.2" + resolved "https://registry.yarnpkg.com/react/-/react-16.8.2.tgz#83064596feaa98d9c2857c4deae1848b542c9c0c" + integrity sha512-aB2ctx9uQ9vo09HVknqv3DGRpI7OIGJhCx3Bt0QqoRluEjHSaObJl+nG12GDdYH6sTgE7YiPJ6ZUyMx9kICdXw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.12.0" + scheduler "^0.13.2" read-config-file@3.1.0, read-config-file@^3.0.0: version "3.1.0" @@ -8532,13 +8534,6 @@ sass-loader@^6.0.7: neo-async "^2.5.0" pify "^3.0.0" -sass@^1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.17.0.tgz#e370b9302af121c9eadad5639619127772094ae6" - integrity sha512-aFi9RQqrCYkHB2DaLKBBbdUhos1N5o3l1ke9N5JqWzgSPmYwZsdmA+ViPVatUy/RPA21uejgYVUXM7GCh8lcdw== - dependencies: - chokidar "^2.0.0" - sax@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" @@ -8551,9 +8546,10 @@ sax@~1.1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/sax/-/sax-1.1.6.tgz#5d616be8a5e607d54e114afae55b7eaf2fcc3240" -scheduler@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.12.0.tgz#8ab17699939c0aedc5a196a657743c496538647b" +scheduler@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.2.tgz#969eaee2764a51d2e97b20a60963b2546beff8fa" + integrity sha512-qK5P8tHS7vdEMCW5IPyt8v9MJOHqTrOUgPXib7tqm9vh834ibBX5BNhwkplX/0iOzHW5sXyluehYfS9yrkz9+w== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1"