diff --git a/.flowconfig b/.flowconfig index de74dca59..6731231c0 100644 --- a/.flowconfig +++ b/.flowconfig @@ -24,6 +24,7 @@ module.name_mapper='^app\(.*\)$' -> '/src/ui/app\1' module.name_mapper='^native\(.*\)$' -> '/src/ui/native\1' module.name_mapper='^analytics\(.*\)$' -> '/src/ui/analytics\1' module.name_mapper='^i18n\(.*\)$' -> '/src/ui/i18n\1' +module.name_mapper='^effects\(.*\)$' -> '/src/ui/effects\1' module.name_mapper='^config\(.*\)$' -> '/config\1' diff --git a/package.json b/package.json index 08e3c07cf..d4c5a1018 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "husky": "^0.14.3", "json-loader": "^0.5.4", "lbry-format": "https://github.com/lbryio/lbry-format.git", - "lbry-redux": "lbryio/lbry-redux#d44cd9ca56dee784dba42c0cc13061ae75cbd46c", + "lbry-redux": "lbryio/lbry-redux#42bf926138872d14523be7191694309be4f37605", "lbryinc": "lbryio/lbryinc#368040d64658cf2a4b8a7a6725ec1787329ce65d", "lint-staged": "^7.0.2", "localforage": "^1.7.1", diff --git a/src/ui/component/app/view.jsx b/src/ui/component/app/view.jsx index 18efb36ed..6125ce56e 100644 --- a/src/ui/component/app/view.jsx +++ b/src/ui/component/app/view.jsx @@ -11,8 +11,7 @@ import useKonamiListener from 'util/enhanced-layout'; import Yrbl from 'component/yrbl'; import FileViewer from 'component/fileViewer'; import { withRouter } from 'react-router'; -import usePrevious from 'util/use-previous'; -import SyncBackgroundManager from 'component/syncBackgroundManager'; +import usePrevious from 'effects/use-previous'; import Button from 'component/button'; export const MAIN_WRAPPER_CLASS = 'main-wrapper'; @@ -121,7 +120,6 @@ function App(props: Props) { - {/* @if TARGET='app' */} {showUpgradeButton && ( diff --git a/src/ui/component/blockButton/view.jsx b/src/ui/component/blockButton/view.jsx index ea1228c47..62e75e1ea 100644 --- a/src/ui/component/blockButton/view.jsx +++ b/src/ui/component/blockButton/view.jsx @@ -3,7 +3,7 @@ import * as ICONS from 'constants/icons'; import * as PAGES from 'constants/pages'; import React, { useRef } from 'react'; import Button from 'component/button'; -import useHover from 'util/use-hover'; +import useHover from 'effects/use-hover'; type Props = { permanentUrl: ?string, diff --git a/src/ui/component/channelContent/view.jsx b/src/ui/component/channelContent/view.jsx index dfd03a35b..2aec0ddf9 100644 --- a/src/ui/component/channelContent/view.jsx +++ b/src/ui/component/channelContent/view.jsx @@ -64,7 +64,7 @@ function ChannelContent(props: Props) { )} - {!channelIsMine && } + {!channelIsMine && } {hasContent && !channelIsBlocked && !channelIsBlackListed && ( claim && claim.canonical_url)} /> diff --git a/src/ui/component/channelEdit/view.jsx b/src/ui/component/channelEdit/view.jsx index 725e2389d..bb0ec1418 100644 --- a/src/ui/component/channelEdit/view.jsx +++ b/src/ui/component/channelEdit/view.jsx @@ -182,7 +182,7 @@ function ChannelForm(props: Props) { onChange={text => setParams({ ...params, description: text })} /> ((props: Props, ref: any) => {
{claim ? : {__('Nothing here')}}
- {actions !== undefined - ? actions - : !hideActions && ( -
- {isChannel && !channelIsBlocked && !claimIsMine && ( - - )} - {isChannel && !isSubscribed && !claimIsMine && ( - - )} - {!isChannel && claim && } -
+ {!hideActions && actions !== undefined ? ( + actions + ) : ( +
+ {isChannel && !channelIsBlocked && !claimIsMine && ( + )} + {isChannel && !isSubscribed && !claimIsMine && ( + + )} + {!isChannel && claim && } +
+ )}
diff --git a/src/ui/component/commentCreate/view.jsx b/src/ui/component/commentCreate/view.jsx index acdfe185e..2fc32a584 100644 --- a/src/ui/component/commentCreate/view.jsx +++ b/src/ui/component/commentCreate/view.jsx @@ -5,7 +5,7 @@ import { FormField, Form } from 'component/common/form'; import Button from 'component/button'; import ChannelSection from 'component/selectChannel'; import UnsupportedOnWeb from 'component/common/unsupported-on-web'; -import usePersistedState from 'util/use-persisted-state'; +import usePersistedState from 'effects/use-persisted-state'; type Props = { uri: string, diff --git a/src/ui/component/common/card.jsx b/src/ui/component/common/card.jsx index 586a8746d..c10dd7470 100644 --- a/src/ui/component/common/card.jsx +++ b/src/ui/component/common/card.jsx @@ -5,7 +5,7 @@ import classnames from 'classnames'; import Icon from 'component/common/icon'; type Props = { - title: string | Node, + title?: string | Node, subtitle?: string | Node, body?: string | Node, actions?: string | Node, @@ -16,15 +16,17 @@ export default function Card(props: Props) { const { title, subtitle, body, actions, icon } = props; return (
-
-
- {icon && } -
-

{title}

-

{subtitle}

+ {title && ( +
+
+ {icon && } +
+

{title}

+

{subtitle}

+
-
+ )} {body &&
{body}
} {actions && ( diff --git a/src/ui/component/fileViewer/view.jsx b/src/ui/component/fileViewer/view.jsx index b69cd3b2e..a8235c88b 100644 --- a/src/ui/component/fileViewer/view.jsx +++ b/src/ui/component/fileViewer/view.jsx @@ -6,8 +6,8 @@ import classnames from 'classnames'; import LoadingScreen from 'component/common/loading-screen'; import FileRender from 'component/fileRender'; import UriIndicator from 'component/uriIndicator'; -import usePersistedState from 'util/use-persisted-state'; -import usePrevious from 'util/use-previous'; +import usePersistedState from 'effects/use-persisted-state'; +import usePrevious from 'effects/use-previous'; import { FILE_WRAPPER_CLASS } from 'page/file/view'; import Draggable from 'react-draggable'; import Tooltip from 'component/common/tooltip'; @@ -86,7 +86,7 @@ export default function FileViewer(props: Props) { function handleResize() { const element = document.querySelector(`.${FILE_WRAPPER_CLASS}`); if (!element) { - console.error("Can't find file viewer wrapper to attach to the inline viewer to"); + console.error("Can't find file viewer wrapper to attach to the inline viewer to"); // eslint-disable-line return; } diff --git a/src/ui/component/hiddenNsfwClaims/view.jsx b/src/ui/component/hiddenNsfwClaims/view.jsx index fb71a0d9b..4fa2d335e 100644 --- a/src/ui/component/hiddenNsfwClaims/view.jsx +++ b/src/ui/component/hiddenNsfwClaims/view.jsx @@ -1,7 +1,6 @@ // @flow import React from 'react'; import Button from 'component/button'; -import classnames from 'classnames'; type Props = { numberOfNsfwClaims: number, @@ -10,12 +9,12 @@ type Props = { }; export default (props: Props) => { - const { numberOfNsfwClaims, obscureNsfw, className } = props; + const { numberOfNsfwClaims, obscureNsfw } = props; return ( obscureNsfw && Boolean(numberOfNsfwClaims) && ( -
+
{numberOfNsfwClaims} {numberOfNsfwClaims > 1 ? __('files') : __('file')} {__('hidden due to your')}{' '}
diff --git a/src/ui/component/publishAdditionalOptions/view.jsx b/src/ui/component/publishAdditionalOptions/view.jsx index 6f0ac6316..0985f258f 100644 --- a/src/ui/component/publishAdditionalOptions/view.jsx +++ b/src/ui/component/publishAdditionalOptions/view.jsx @@ -1,10 +1,11 @@ // @flow import React from 'react'; import classnames from 'classnames'; -import usePersistedState from 'util/use-persisted-state'; +import usePersistedState from 'effects/use-persisted-state'; import { FormField } from 'component/common/form'; import Button from 'component/button'; import LicenseType from './license-type'; +import Card from 'component/common/card'; type Props = { language: ?string, @@ -25,67 +26,75 @@ function PublishAdvanced(props: Props) { } return ( -
- {!hideSection && ( -
- updatePublishForm({ language: event.target.value })} - > - - - - - - - - - - - - - - - - - - - - - - - - - - + + {!hideSection && ( +
+ updatePublishForm({ language: event.target.value })} + > + + + + + + + + + + + + + + + + + + + + + + + + + + - - updatePublishForm({ - licenseType: newLicenseType, - licenseUrl: newLicenseUrl, - }) - } - handleLicenseDescriptionChange={event => - updatePublishForm({ - otherLicenseDescription: event.target.value, - }) - } - handleLicenseUrlChange={event => updatePublishForm({ licenseUrl: event.target.value })} - /> -
- )} + + updatePublishForm({ + licenseType: newLicenseType, + licenseUrl: newLicenseUrl, + }) + } + handleLicenseDescriptionChange={event => + updatePublishForm({ + otherLicenseDescription: event.target.value, + }) + } + handleLicenseUrlChange={event => updatePublishForm({ licenseUrl: event.target.value })} + /> +
+ )} -
-
-
+
+
+ + } + /> ); } diff --git a/src/ui/component/publishFile/view.jsx b/src/ui/component/publishFile/view.jsx index ba3ce716c..f5b4bc663 100644 --- a/src/ui/component/publishFile/view.jsx +++ b/src/ui/component/publishFile/view.jsx @@ -1,9 +1,10 @@ // @flow +import * as ICONS from 'constants/icons'; import React from 'react'; import { regexInvalidURI } from 'lbry-redux'; -import classnames from 'classnames'; import FileSelector from 'component/common/file-selector'; import Button from 'component/button'; +import Card from 'component/common/card'; type Props = { name: ?string, @@ -11,10 +12,11 @@ type Props = { isStillEditing: boolean, balance: number, updatePublishForm: ({}) => void, + disabled: boolean, }; function PublishFile(props: Props) { - const { name, balance, filePath, isStillEditing, updatePublishForm } = props; + const { name, balance, filePath, isStillEditing, updatePublishForm, disabled } = props; function handleFileChange(filePath: string, fileName: string) { const publishFormParams: { filePath: string, name?: string } = { filePath }; @@ -28,29 +30,29 @@ function PublishFile(props: Props) { } return ( -
-

{isStillEditing ? __('Edit') : __('Publish')}

- {isStillEditing &&

{__('You are currently editing a claim.')}

} - -
- - {!isStillEditing && ( -

- {__('For video content, use MP4s in H264/AAC format for best compatibility.')}{' '} -

-
+ + + {!isStillEditing && ( +

+ {__('For video content, use MP4s in H264/AAC format for best compatibility.')}{' '} +

-
+ updatePublishForm({ description: advancedEditor ? value : value.target.value })} + /> +
+
+ + } + /> ); } diff --git a/src/ui/component/rewardTotal/view.jsx b/src/ui/component/rewardTotal/view.jsx index a0a67ead4..d816830eb 100644 --- a/src/ui/component/rewardTotal/view.jsx +++ b/src/ui/component/rewardTotal/view.jsx @@ -1,7 +1,7 @@ // @flow import React from 'react'; import TotalBackground from './total-background.png'; -import useTween from 'util/use-tween'; +import useTween from 'effects/use-tween'; type Props = { rewards: Array, diff --git a/src/ui/component/sideBar/view.jsx b/src/ui/component/sideBar/view.jsx index 6a7ed7c61..a0d0239f2 100644 --- a/src/ui/component/sideBar/view.jsx +++ b/src/ui/component/sideBar/view.jsx @@ -69,25 +69,27 @@ function SideBar(props: Props) { className="navigation-link" activeClass="navigation-link--active" /> -
    - {followedTags.map(({ name }, key) => ( -
  • - -
  • - ))} -
-
    - {subscriptions.map(({ uri, channelName }, index) => ( -
  • -
  • - ))} -
+
+
    + {followedTags.map(({ name }, key) => ( +
  • + +
  • + ))} +
+
    + {subscriptions.map(({ uri, channelName }, index) => ( +
  • +
  • + ))} +
+
); diff --git a/src/ui/component/splash/view.jsx b/src/ui/component/splash/view.jsx index e9691e9bf..6236ae42e 100644 --- a/src/ui/component/splash/view.jsx +++ b/src/ui/component/splash/view.jsx @@ -124,11 +124,6 @@ export default class SplashScreen extends React.PureComponent { clearTimeout(this.timeout); } - // - // - // Try to unlock by default here - // - // // Make sure there isn't another active modal (like INCOMPATIBLE_DAEMON) if (launchedModal === false && !modal) { this.setState({ launchedModal: true }, () => notifyUnlockWallet()); @@ -153,10 +148,10 @@ export default class SplashScreen extends React.PureComponent { }); } } else if (wallet && wallet.blocks_behind > 0) { - const format = wallet.blocks_behind === 1 ? '%s block behind' : '%s blocks behind'; + const amountBehind = wallet.blocks_behind === 1 ? '%amountBehind% block behind' : '%amountBehind% blocks behind'; this.setState({ message: __('Blockchain Sync'), - details: `${__('Catching up...')} (${__(format, wallet.blocks_behind)})`, + details: `${__('Catching up...')} (${__(amountBehind, { amountBehind: wallet.blocks_behind })})`, }); } else if ( wallet && diff --git a/src/ui/component/subscribeButton/view.jsx b/src/ui/component/subscribeButton/view.jsx index 6432a8945..0e2526c85 100644 --- a/src/ui/component/subscribeButton/view.jsx +++ b/src/ui/component/subscribeButton/view.jsx @@ -4,7 +4,7 @@ import * as ICONS from 'constants/icons'; import React, { useRef } from 'react'; import { parseURI } from 'lbry-redux'; import Button from 'component/button'; -import useHover from 'util/use-hover'; +import useHover from 'effects/use-hover'; type SubscriptionArgs = { channelName: string, diff --git a/src/ui/component/syncBackgroundManager/index.js b/src/ui/component/syncBackgroundManager/index.js deleted file mode 100644 index e0889b8b7..000000000 --- a/src/ui/component/syncBackgroundManager/index.js +++ /dev/null @@ -1,24 +0,0 @@ -import * as SETTINGS from 'constants/settings'; -import { connect } from 'react-redux'; -import { selectBalance } from 'lbry-redux'; -import { doGetSync, selectSyncHash, selectUserVerifiedEmail } from 'lbryinc'; -import { doSetClientSetting } from 'redux/actions/settings'; -import { makeSelectClientSetting } from 'redux/selectors/settings'; -import WalletSecurityAndSync from './view'; - -const select = state => ({ - balance: selectBalance(state), - verifiedEmail: selectUserVerifiedEmail(state), - syncEnabled: makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state), - hasSyncHash: selectSyncHash(state), -}); - -const perform = dispatch => ({ - getSync: password => dispatch(doGetSync(password)), - setSync: value => dispatch(doSetClientSetting(SETTINGS.ENABLE_SYNC, value)), -}); - -export default connect( - select, - perform -)(WalletSecurityAndSync); diff --git a/src/ui/component/syncBackgroundManager/view.jsx b/src/ui/component/syncBackgroundManager/view.jsx deleted file mode 100644 index 3f239480a..000000000 --- a/src/ui/component/syncBackgroundManager/view.jsx +++ /dev/null @@ -1,22 +0,0 @@ -// @flow -import React from 'react'; - -type Props = { - syncEnabled: boolean, - verifiedEmail?: string, - getSync: () => void, -}; - -function SyncBackgroundManager(props: Props) { - const { syncEnabled, getSync, verifiedEmail } = props; - - React.useEffect(() => { - if (syncEnabled && verifiedEmail) { - getSync(); - } - }, [syncEnabled, verifiedEmail, getSync]); - - return null; -} - -export default SyncBackgroundManager; diff --git a/src/ui/component/tagsSelect/view.jsx b/src/ui/component/tagsSelect/view.jsx index 7f90ac235..a4b15653b 100644 --- a/src/ui/component/tagsSelect/view.jsx +++ b/src/ui/component/tagsSelect/view.jsx @@ -4,7 +4,7 @@ import * as React from 'react'; import Button from 'component/button'; import Tag from 'component/tag'; import TagsSearch from 'component/tagsSearch'; -import usePersistedState from 'util/use-persisted-state'; +import usePersistedState from 'effects/use-persisted-state'; import analytics from 'analytics'; import Card from 'component/common/card'; @@ -73,7 +73,15 @@ export default function TagSelect(props: Props) { )} } - body={ + subtitle={ + help !== false && ( + + {help || __("The tags you follow will change what's trending for you.")}{' '} +