diff --git a/.flowconfig b/.flowconfig index 4124fddb6..8a6fdca75 100644 --- a/.flowconfig +++ b/.flowconfig @@ -24,7 +24,7 @@ module.name_mapper='^modal\(.*\)$' -> '/ui/modal\1' module.name_mapper='^app\(.*\)$' -> '/ui/app\1' module.name_mapper='^native\(.*\)$' -> '/ui/native\1' module.name_mapper='^analytics\(.*\)$' -> '/ui/analytics\1' -module.name_mapper='^recsys\(.*\)$' -> '/ui/recsys\1' +module.name_mapper='^recsys\(.*\)$' -> '/extras/recsys\1' module.name_mapper='^rewards\(.*\)$' -> '/ui/rewards\1' module.name_mapper='^i18n\(.*\)$' -> '/ui/i18n\1' module.name_mapper='^effects\(.*\)$' -> '/ui/effects\1' diff --git a/extras/lbryinc/redux/actions/stats.js b/extras/lbryinc/redux/actions/stats.js index 7e152b55c..9d2a12178 100644 --- a/extras/lbryinc/redux/actions/stats.js +++ b/extras/lbryinc/redux/actions/stats.js @@ -2,7 +2,7 @@ import { Lbryio } from 'lbryinc'; import * as ACTIONS from 'constants/action_types'; -export const doFetchViewCount = (claimIdCsv: string) => dispatch => { +export const doFetchViewCount = (claimIdCsv: string) => (dispatch: Dispatch) => { dispatch({ type: ACTIONS.FETCH_VIEW_COUNT_STARTED }); return Lbryio.call('file', 'view_count', { claim_id: claimIdCsv }) @@ -15,7 +15,7 @@ export const doFetchViewCount = (claimIdCsv: string) => dispatch => { }); }; -export const doFetchSubCount = (claimId: string) => dispatch => { +export const doFetchSubCount = (claimId: string) => (dispatch: Dispatch) => { dispatch({ type: ACTIONS.FETCH_SUB_COUNT_STARTED }); return Lbryio.call('subscription', 'sub_count', { claim_id: claimId }) diff --git a/extras/lbryinc/redux/reducers/web.js b/extras/lbryinc/redux/reducers/web.js index 70e90296e..7cb9f674d 100644 --- a/extras/lbryinc/redux/reducers/web.js +++ b/extras/lbryinc/redux/reducers/web.js @@ -55,7 +55,7 @@ reducers[ACTIONS.UPDATE_UPLOAD_PROGRESS] = (state: TvState, action) => { return { ...state, currentUploads }; }; -export function webReducer(state = defaultState, action) { +export function webReducer(state: TvState = defaultState, action: any) { const handler = reducers[action.type]; if (handler) return handler(state, action); return state; diff --git a/extras/recsys/index.js b/extras/recsys/index.js new file mode 100644 index 000000000..509e68439 --- /dev/null +++ b/extras/recsys/index.js @@ -0,0 +1,3 @@ +import Recsys from './recsys'; + +export { Recsys }; diff --git a/ui/component/channelEdit/view.jsx b/ui/component/channelEdit/view.jsx index 9148ad33c..c32c584f8 100644 --- a/ui/component/channelEdit/view.jsx +++ b/ui/component/channelEdit/view.jsx @@ -253,7 +253,7 @@ function ChannelForm(props: Props) { let nameError; if (!name && name !== undefined) { nameError = __('A name is required for your url'); - } else if (!isNameValid(name, false)) { + } else if (!isNameValid(name)) { nameError = INVALID_NAME_ERROR; } diff --git a/ui/component/channelThumbnail/view.jsx b/ui/component/channelThumbnail/view.jsx index f1449cc5d..c5bc3dd02 100644 --- a/ui/component/channelThumbnail/view.jsx +++ b/ui/component/channelThumbnail/view.jsx @@ -10,7 +10,7 @@ import { AVATAR_DEFAULT } from 'config'; type Props = { thumbnail: ?string, - uri: ?string, + uri: string, className?: string, thumbnailPreview: ?string, obscure?: boolean, diff --git a/ui/component/claimMenuList/view.jsx b/ui/component/claimMenuList/view.jsx index 71fbd9631..eb7b2ab77 100644 --- a/ui/component/claimMenuList/view.jsx +++ b/ui/component/claimMenuList/view.jsx @@ -175,12 +175,13 @@ function ClaimMenuList(props: Props) { function handleFollow() { const subscriptionHandler = isSubscribed ? doChannelUnsubscribe : doChannelSubscribe; - - subscriptionHandler({ - channelName: '@' + channelName, - uri: contentChannelUri, - notificationsDisabled: true, - }); + if (channelName) { + subscriptionHandler({ + channelName: '@' + channelName, + uri: contentChannelUri, + notificationsDisabled: true, + }); + } } function handleToggleMute() { @@ -203,7 +204,7 @@ function ClaimMenuList(props: Props) { if (!isChannel) { const signingChannelName = contentSigningChannel && contentSigningChannel.name; - const uriObject: { streamName: string, streamClaimId: string, channelName?: string } = { + const uriObject: LbryUrlObj = { streamName: claim.name, streamClaimId: claim.claim_id, }; diff --git a/ui/component/claimPreviewSubtitle/view.jsx b/ui/component/claimPreviewSubtitle/view.jsx index 6fb8ec833..507abf2a7 100644 --- a/ui/component/claimPreviewSubtitle/view.jsx +++ b/ui/component/claimPreviewSubtitle/view.jsx @@ -12,7 +12,7 @@ type Props = { claim: ?Claim, pending?: boolean, type: string, - beginPublish: (string) => void, + beginPublish: (?string) => void, isLivestream: boolean, }; diff --git a/ui/component/fileActions/view.jsx b/ui/component/fileActions/view.jsx index 24b68961d..b872f8347 100644 --- a/ui/component/fileActions/view.jsx +++ b/ui/component/fileActions/view.jsx @@ -74,7 +74,7 @@ function FileActions(props: Props) { // We will select the claim id before they publish let editUri; if (claimIsMine) { - const uriObject: { streamName: string, streamClaimId: string, channelName?: string } = { + const uriObject: LbryUrlObj = { streamName: claim.name, streamClaimId: claim.claim_id, }; diff --git a/ui/component/fileRenderFloating/view.jsx b/ui/component/fileRenderFloating/view.jsx index 0ff49a17a..2bd7e4bfe 100644 --- a/ui/component/fileRenderFloating/view.jsx +++ b/ui/component/fileRenderFloating/view.jsx @@ -73,7 +73,7 @@ export default function FileRenderFloating(props: Props) { const playingUriSource = playingUri && playingUri.source; const isComment = playingUriSource === 'comment'; const isMobile = useIsMobile(); - const mainFilePlaying = !isFloating && isURIEqual(uri, primaryUri); + const mainFilePlaying = !isFloating && primaryUri && isURIEqual(uri, primaryUri); const [fileViewerRect, setFileViewerRect] = useState(); const [desktopPlayStartTime, setDesktopPlayStartTime] = useState(); diff --git a/ui/component/invited/view.jsx b/ui/component/invited/view.jsx index c6ff3403f..9c757e855 100644 --- a/ui/component/invited/view.jsx +++ b/ui/component/invited/view.jsx @@ -57,11 +57,18 @@ function Invited(props: Props) { // always follow if it's a channel useEffect(() => { - if (fullUri && !isSubscribed) { - channelSubscribe({ - channelName: parseURI(fullUri).claimName, - uri: fullUri, - }); + if (fullUri && !isSubscribed && fullUri) { + let channelName; + try { + const { claimName } = parseURI(fullUri); + channelName = claimName; + } catch (e) {} + if (channelName) { + channelSubscribe({ + channelName: channelName, + uri: fullUri, + }); + } } }, [fullUri, isSubscribed, channelSubscribe]); diff --git a/ui/component/notification/view.jsx b/ui/component/notification/view.jsx index cab730c3f..b0f4b8587 100644 --- a/ui/component/notification/view.jsx +++ b/ui/component/notification/view.jsx @@ -107,10 +107,12 @@ export default function Notification(props: Props) { } let channelName; - try { - const { claimName } = parseURI(channelUrl); - channelName = claimName; - } catch (e) {} + if (channelUrl) { + try { + const { claimName } = parseURI(channelUrl); + channelName = claimName; + } catch (e) {} + } const notificationTitle = notification_parameters.device.title; const titleSplit = notificationTitle.split(' '); diff --git a/ui/component/recommendedContent/view.jsx b/ui/component/recommendedContent/view.jsx index 88cf76186..2de10bd10 100644 --- a/ui/component/recommendedContent/view.jsx +++ b/ui/component/recommendedContent/view.jsx @@ -8,7 +8,7 @@ import Card from 'component/common/card'; import { useIsMobile, useIsMediumScreen } from 'effects/use-screensize'; import Button from 'component/button'; import classnames from 'classnames'; -import RecSys from 'extras/recsys/recsys'; +import RecSys from 'recsys'; const VIEW_ALL_RELATED = 'view_all_related'; const VIEW_MORE_FROM = 'view_more_from'; diff --git a/ui/component/router/view.jsx b/ui/component/router/view.jsx index 49b64eb8c..8e1363028 100644 --- a/ui/component/router/view.jsx +++ b/ui/component/router/view.jsx @@ -115,7 +115,7 @@ type Props = { welcomeVersion: number, hasNavigated: boolean, setHasNavigated: () => void, - setReferrer: (string) => void, + setReferrer: (?string) => void, hasUnclaimedRefereeReward: boolean, homepageData: any, }; diff --git a/ui/component/searchTopClaim/view.jsx b/ui/component/searchTopClaim/view.jsx index 8e5f2c65c..ab884740f 100644 --- a/ui/component/searchTopClaim/view.jsx +++ b/ui/component/searchTopClaim/view.jsx @@ -18,7 +18,7 @@ type Props = { doResolveUris: (Array) => void, hideLink?: boolean, setChannelActive: (boolean) => void, - beginPublish: (string) => void, + beginPublish: (?string) => void, pendingIds: Array, isResolvingWinningUri: boolean, winningClaim: ?Claim, @@ -44,8 +44,6 @@ export default function SearchTopClaim(props: Props) { let winningUriIsChannel; try { const { isChannel, streamName, channelName } = parseURI(uriFromQuery); - const { isChannel: winnerIsChannel } = parseURI(winningUri); - winningUriIsChannel = winnerIsChannel; if (!isChannel) { channelUriFromQuery = `lbry://@${query}`; name = streamName; @@ -54,6 +52,13 @@ export default function SearchTopClaim(props: Props) { } } catch (e) {} + if (winningUri) { + try { + const { isChannel: winnerIsChannel } = parseURI(winningUri); + winningUriIsChannel = winnerIsChannel; + } catch (e) {} + } + React.useEffect(() => { setChannelActive && winningUriIsChannel && setChannelActive(true); }, [setChannelActive, winningUriIsChannel]); @@ -111,7 +116,11 @@ export default function SearchTopClaim(props: Props) { push(`/$/${PAGES.REPOST_NEW}?to=${name}`)} label={__('Repost')} /> +