Refactor
- some cleanups - uri was being parsed the same way in different places, so do it only once for simplicity
This commit is contained in:
parent
b75a4014b6
commit
bf158ad696
6 changed files with 63 additions and 142 deletions
|
@ -13,17 +13,11 @@ import { selectUnclaimedRewards } from 'redux/selectors/rewards';
|
|||
import { doFetchChannelListMine, doFetchCollectionListMine } from 'redux/actions/claims';
|
||||
import { selectMyChannelClaimIds } from 'redux/selectors/claims';
|
||||
import { selectLanguage, selectLoadedLanguages, selectThemePath } from 'redux/selectors/settings';
|
||||
import {
|
||||
selectIsUpgradeAvailable,
|
||||
selectAutoUpdateDownloaded,
|
||||
selectModal,
|
||||
selectActiveChannelClaim,
|
||||
selectIsReloadRequired,
|
||||
} from 'redux/selectors/app';
|
||||
import { selectModal, selectActiveChannelClaim, selectIsReloadRequired } from 'redux/selectors/app';
|
||||
import { selectUploadCount } from 'redux/selectors/publish';
|
||||
import { doSetLanguage } from 'redux/actions/settings';
|
||||
import { doSyncLoop } from 'redux/actions/sync';
|
||||
import { doDownloadUpgradeRequested, doSignIn, doSetIncognito } from 'redux/actions/app';
|
||||
import { doSignIn, doSetIncognito } from 'redux/actions/app';
|
||||
import { doFetchModBlockedList, doFetchCommentModAmIList } from 'redux/actions/comments';
|
||||
import App from './view';
|
||||
|
||||
|
@ -33,8 +27,6 @@ const select = (state) => ({
|
|||
theme: selectThemePath(state),
|
||||
language: selectLanguage(state),
|
||||
languages: selectLoadedLanguages(state),
|
||||
autoUpdateDownloaded: selectAutoUpdateDownloaded(state),
|
||||
isUpgradeAvailable: selectIsUpgradeAvailable(state),
|
||||
isReloadRequired: selectIsReloadRequired(state),
|
||||
syncError: selectGetSyncErrorMessage(state),
|
||||
syncIsLocked: selectSyncIsLocked(state),
|
||||
|
@ -49,17 +41,16 @@ const select = (state) => ({
|
|||
homepageFetched: selectHomepageFetched(state),
|
||||
});
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
|
||||
fetchCollectionListMine: () => dispatch(doFetchCollectionListMine()),
|
||||
setLanguage: (language) => dispatch(doSetLanguage(language)),
|
||||
signIn: () => dispatch(doSignIn()),
|
||||
requestDownloadUpgrade: () => dispatch(doDownloadUpgradeRequested()),
|
||||
syncLoop: (noInterval) => dispatch(doSyncLoop(noInterval)),
|
||||
setReferrer: (referrer, doClaim) => dispatch(doUserSetReferrer(referrer, doClaim)),
|
||||
setIncognito: () => dispatch(doSetIncognito()),
|
||||
fetchModBlockedList: () => dispatch(doFetchModBlockedList()),
|
||||
fetchModAmIList: () => dispatch(doFetchCommentModAmIList()),
|
||||
});
|
||||
const perform = {
|
||||
fetchChannelListMine: doFetchChannelListMine,
|
||||
fetchCollectionListMine: doFetchCollectionListMine,
|
||||
setLanguage: doSetLanguage,
|
||||
signIn: doSignIn,
|
||||
syncLoop: doSyncLoop,
|
||||
setReferrer: doUserSetReferrer,
|
||||
setIncognito: doSetIncognito,
|
||||
fetchModBlockedList: doFetchModBlockedList,
|
||||
fetchModAmIList: doFetchCommentModAmIList,
|
||||
};
|
||||
|
||||
export default hot(connect(select, perform)(App));
|
||||
|
|
|
@ -3,15 +3,13 @@ import * as PAGES from 'constants/pages';
|
|||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { lazyImport } from 'util/lazyImport';
|
||||
import { tusUnlockAndNotify, tusHandleTabUpdates } from 'util/tus';
|
||||
import classnames from 'classnames';
|
||||
import analytics from 'analytics';
|
||||
import { setSearchUserId } from 'redux/actions/search';
|
||||
import { buildURI, parseURI } from 'util/lbryURI';
|
||||
import { SIMPLE_SITE } from 'config';
|
||||
import { normalizeURI } from 'util/lbryURI';
|
||||
import { generateGoogleCacheUrl } from 'util/url';
|
||||
import Router from 'component/router/index';
|
||||
import ModalRouter from 'modal/modalRouter';
|
||||
import ReactModal from 'react-modal';
|
||||
import { openContextMenu } from 'util/context-menu';
|
||||
import useKonamiListener from 'util/enhanced-layout';
|
||||
import Yrbl from 'component/yrbl';
|
||||
import FileRenderFloating from 'component/fileRenderFloating';
|
||||
|
@ -40,8 +38,6 @@ import SUPPORTED_LANGUAGES from 'constants/supported_languages';
|
|||
const FileDrop = lazyImport(() => import('component/fileDrop' /* webpackChunkName: "fileDrop" */));
|
||||
const NagContinueFirstRun = lazyImport(() => import('component/nagContinueFirstRun' /* webpackChunkName: "nagCFR" */));
|
||||
const NagLocaleSwitch = lazyImport(() => import('component/nagLocaleSwitch' /* webpackChunkName: "nagLocaleSwitch" */));
|
||||
const OpenInAppLink = lazyImport(() => import('web/component/openInAppLink' /* webpackChunkName: "openInAppLink" */));
|
||||
const NagDataCollection = lazyImport(() => import('web/component/nag-data-collection' /* webpackChunkName: "nagDC" */));
|
||||
const NagDegradedPerformance = lazyImport(() =>
|
||||
import('web/component/nag-degraded-performance' /* webpackChunkName: "NagDegradedPerformance" */)
|
||||
);
|
||||
|
@ -63,16 +59,13 @@ type Props = {
|
|||
theme: string,
|
||||
user: ?{ id: string, has_verified_email: boolean, is_reward_approved: boolean },
|
||||
locale: ?LocaleInfo,
|
||||
location: { pathname: string, hash: string, search: string },
|
||||
history: { push: (string) => void, location: { pathname: string } },
|
||||
location: { pathname: string, hash: string, search: string, hostname: string, reload: () => void },
|
||||
history: { push: (string) => void, location: { pathname: string }, replace: (string) => void },
|
||||
fetchChannelListMine: () => void,
|
||||
fetchCollectionListMine: () => void,
|
||||
signIn: () => void,
|
||||
requestDownloadUpgrade: () => void,
|
||||
setLanguage: (string) => void,
|
||||
isUpgradeAvailable: boolean,
|
||||
isReloadRequired: boolean,
|
||||
autoUpdateDownloaded: boolean,
|
||||
uploadCount: number,
|
||||
balance: ?number,
|
||||
syncIsLocked: boolean,
|
||||
|
@ -97,13 +90,11 @@ function App(props: Props) {
|
|||
theme,
|
||||
user,
|
||||
locale,
|
||||
location,
|
||||
fetchChannelListMine,
|
||||
fetchCollectionListMine,
|
||||
signIn,
|
||||
autoUpdateDownloaded,
|
||||
isUpgradeAvailable,
|
||||
isReloadRequired,
|
||||
requestDownloadUpgrade,
|
||||
uploadCount,
|
||||
history,
|
||||
syncError,
|
||||
|
@ -137,16 +128,12 @@ function App(props: Props) {
|
|||
|
||||
const [localeLangs, setLocaleLangs] = React.useState();
|
||||
const [localeSwitchDismissed] = usePersistedState('locale-switch-dismissed', false);
|
||||
const [showAnalyticsNag, setShowAnalyticsNag] = usePersistedState('analytics-nag', true);
|
||||
const [lbryTvApiStatus, setLbryTvApiStatus] = useState(STATUS_OK);
|
||||
|
||||
const { pathname, hash, search } = props.location;
|
||||
const [upgradeNagClosed, setUpgradeNagClosed] = useState(false);
|
||||
const { pathname, hash, search, hostname } = location;
|
||||
const [retryingSync, setRetryingSync] = useState(false);
|
||||
const [langRenderKey, setLangRenderKey] = useState(0);
|
||||
const [seenSunsestMessage, setSeenSunsetMessage] = usePersistedState('lbrytv-sunset', false);
|
||||
const showUpgradeButton =
|
||||
(autoUpdateDownloaded || (process.platform === 'linux' && isUpgradeAvailable)) && !upgradeNagClosed;
|
||||
// referral claiming
|
||||
const referredRewardAvailable = rewards && rewards.some((reward) => reward.reward_type === REWARDS.TYPE_REFEREE);
|
||||
const urlParams = new URLSearchParams(search);
|
||||
|
@ -163,14 +150,23 @@ function App(props: Props) {
|
|||
const renderFiledrop = !isMobile && isAuthenticated;
|
||||
const connectionStatus = useConnectionStatus();
|
||||
|
||||
const urlPath = pathname + hash;
|
||||
|
||||
let path = urlPath.slice(1).replace(/:/g, '#');
|
||||
|
||||
if (search && search.startsWith('?q=cache:')) {
|
||||
generateGoogleCacheUrl(search, path);
|
||||
}
|
||||
|
||||
let uri;
|
||||
try {
|
||||
const newpath = buildURI(parseURI(pathname.slice(1).replace(/:/g, '#')));
|
||||
uri = newpath + hash;
|
||||
} catch (e) {}
|
||||
uri = normalizeURI(path);
|
||||
} catch (e) {
|
||||
const match = path.match(/[#/:]/);
|
||||
|
||||
function handleAnalyticsDismiss() {
|
||||
setShowAnalyticsNag(false);
|
||||
if (!path.startsWith('$/') && match && match.index) {
|
||||
uri = `lbry://${path.slice(0, match.index)}`;
|
||||
}
|
||||
}
|
||||
|
||||
function getStatusNag() {
|
||||
|
@ -388,7 +384,7 @@ function App(props: Props) {
|
|||
}
|
||||
|
||||
// $FlowFixMe
|
||||
const useProductionOneTrust = process.env.NODE_ENV === 'production' && location.hostname === 'odysee.com';
|
||||
const useProductionOneTrust = process.env.NODE_ENV === 'production' && hostname === 'odysee.com';
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.src = oneTrustScriptSrc;
|
||||
|
@ -493,17 +489,8 @@ function App(props: Props) {
|
|||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classnames(MAIN_WRAPPER_CLASS, {
|
||||
// @if TARGET='app'
|
||||
[`${MAIN_WRAPPER_CLASS}--mac`]: IS_MAC,
|
||||
// @endif
|
||||
})}
|
||||
ref={appRef}
|
||||
key={langRenderKey}
|
||||
onContextMenu={IS_WEB ? undefined : (e) => openContextMenu(e)}
|
||||
>
|
||||
{IS_WEB && lbryTvApiStatus === STATUS_DOWN ? (
|
||||
<div className={MAIN_WRAPPER_CLASS} ref={appRef} key={langRenderKey}>
|
||||
{lbryTvApiStatus === STATUS_DOWN ? (
|
||||
<Yrbl
|
||||
className="main--empty"
|
||||
title={__('odysee.com is currently down')}
|
||||
|
@ -511,8 +498,9 @@ function App(props: Props) {
|
|||
/>
|
||||
) : (
|
||||
<React.Fragment>
|
||||
<Router />
|
||||
<Router uri={uri} />
|
||||
<ModalRouter />
|
||||
|
||||
<React.Suspense fallback={null}>{renderFiledrop && <FileDrop />}</React.Suspense>
|
||||
|
||||
<FileRenderFloating />
|
||||
|
@ -520,26 +508,11 @@ function App(props: Props) {
|
|||
<React.Suspense fallback={null}>
|
||||
{isEnhancedLayout && <Yrbl className="yrbl--enhanced" />}
|
||||
|
||||
{/* @if TARGET='app' */}
|
||||
{showUpgradeButton && (
|
||||
<Nag
|
||||
message={__('An upgrade is available.')}
|
||||
actionText={__('Install Now')}
|
||||
onClick={requestDownloadUpgrade}
|
||||
onClose={() => setUpgradeNagClosed(true)}
|
||||
/>
|
||||
)}
|
||||
{/* @endif */}
|
||||
|
||||
<YoutubeWelcome />
|
||||
{!SIMPLE_SITE && !shouldHideNag && <OpenInAppLink uri={uri} />}
|
||||
{!shouldHideNag && <NagContinueFirstRun />}
|
||||
{fromLbrytvParam && !seenSunsestMessage && !shouldHideNag && (
|
||||
<NagSunset email={hasVerifiedEmail} onClose={() => setSeenSunsetMessage(true)} />
|
||||
)}
|
||||
{!SIMPLE_SITE && lbryTvApiStatus === STATUS_OK && showAnalyticsNag && !shouldHideNag && (
|
||||
<NagDataCollection onClose={handleAnalyticsDismiss} />
|
||||
)}
|
||||
{getStatusNag()}
|
||||
</React.Suspense>
|
||||
</React.Fragment>
|
||||
|
|
|
@ -4,29 +4,14 @@ import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
|||
import { selectHasNavigated, selectScrollStartingPosition } from 'redux/selectors/app';
|
||||
import { selectClientSetting, selectHomepageData, selectWildWestDisabled } from 'redux/selectors/settings';
|
||||
import Router from './view';
|
||||
import { normalizeURI } from 'util/lbryURI';
|
||||
import { selectTitleForUri } from 'redux/selectors/claims';
|
||||
import { doSetHasNavigated, doSetActiveChannel } from 'redux/actions/app';
|
||||
import { doUserSetReferrer } from 'redux/actions/user';
|
||||
import { selectHasUnclaimedRefereeReward } from 'redux/selectors/rewards';
|
||||
import { selectUnseenNotificationCount } from 'redux/selectors/notifications';
|
||||
|
||||
const select = (state) => {
|
||||
const { pathname, hash } = state.router.location;
|
||||
const urlPath = pathname + hash;
|
||||
// Remove the leading "/" added by the browser
|
||||
const path = urlPath.slice(1).replace(/:/g, '#');
|
||||
|
||||
let uri;
|
||||
try {
|
||||
uri = normalizeURI(path);
|
||||
} catch (e) {
|
||||
const match = path.match(/[#/:]/);
|
||||
|
||||
if (!path.startsWith('$/') && match && match.index) {
|
||||
uri = `lbry://${path.slice(0, match.index)}`;
|
||||
}
|
||||
}
|
||||
const select = (state, props) => {
|
||||
const { uri } = props;
|
||||
|
||||
return {
|
||||
uri,
|
||||
|
|
|
@ -16,17 +16,11 @@ import { buildUnseenCountStr } from 'util/notifications';
|
|||
|
||||
import HomePage from 'page/home';
|
||||
|
||||
// @if TARGET='app'
|
||||
const BackupPage = lazyImport(() => import('page/backup' /* webpackChunkName: "backup" */));
|
||||
// @endif
|
||||
|
||||
// @if TARGET='web'
|
||||
const Code2257Page = lazyImport(() => import('web/page/code2257' /* webpackChunkName: "code2257" */));
|
||||
const PrivacyPolicyPage = lazyImport(() => import('web/page/privacypolicy' /* webpackChunkName: "privacypolicy" */));
|
||||
const TOSPage = lazyImport(() => import('web/page/tos' /* webpackChunkName: "tos" */));
|
||||
const FypPage = lazyImport(() => import('web/page/fyp' /* webpackChunkName: "fyp" */));
|
||||
const YouTubeTOSPage = lazyImport(() => import('web/page/youtubetos' /* webpackChunkName: "youtubetos" */));
|
||||
// @endif
|
||||
|
||||
const SignInPage = lazyImport(() => import('page/signIn' /* webpackChunkName: "signIn" */));
|
||||
const SignInWalletPasswordPage = lazyImport(() =>
|
||||
|
@ -132,7 +126,6 @@ type Props = {
|
|||
},
|
||||
uri: string,
|
||||
title: string,
|
||||
welcomeVersion: number,
|
||||
hasNavigated: boolean,
|
||||
setHasNavigated: () => void,
|
||||
setReferrer: (?string) => void,
|
||||
|
@ -333,16 +326,13 @@ function AppRouter(props: Props) {
|
|||
<Route path={`/$/${PAGES.AUTH}/*`} exact component={SignUpPage} />
|
||||
|
||||
<Route path={`/$/${PAGES.HELP}`} exact component={HelpPage} />
|
||||
{/* @if TARGET='app' */}
|
||||
<Route path={`/$/${PAGES.BACKUP}`} exact component={BackupPage} />
|
||||
{/* @endif */}
|
||||
{/* @if TARGET='web' */}
|
||||
|
||||
<Route path={`/$/${PAGES.CODE_2257}`} exact component={Code2257Page} />
|
||||
<Route path={`/$/${PAGES.PRIVACY_POLICY}`} exact component={PrivacyPolicyPage} />
|
||||
<Route path={`/$/${PAGES.TOS}`} exact component={TOSPage} />
|
||||
<Route path={`/$/${PAGES.FYP}`} exact component={FypPage} />
|
||||
<Route path={`/$/${PAGES.YOUTUBE_TOS}`} exact component={YouTubeTOSPage} />
|
||||
{/* @endif */}
|
||||
|
||||
<Route path={`/$/${PAGES.AUTH_VERIFY}`} exact component={SignInVerifyPage} />
|
||||
<Route path={`/$/${PAGES.SEARCH}`} exact component={SearchPage} />
|
||||
<Route path={`/$/${PAGES.TOP}`} exact component={TopPage} />
|
||||
|
@ -411,8 +401,8 @@ function AppRouter(props: Props) {
|
|||
<Route path={`/$/${PAGES.EMBED}/:claimName/:claimId`} exact component={EmbedWrapperPage} />
|
||||
|
||||
{/* Below need to go at the end to make sure we don't match any of our pages first */}
|
||||
<Route path="/:claimName" exact component={ShowPage} />
|
||||
<Route path="/:claimName/:streamName" exact component={ShowPage} />
|
||||
<Route path="/:claimName" exact render={() => <ShowPage uri={uri} />} />
|
||||
<Route path="/:claimName/:streamName" exact render={() => <ShowPage uri={uri} />} />
|
||||
<Route path="/*" component={FourOhFourPage} />
|
||||
</Switch>
|
||||
</React.Suspense>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { DOMAIN } from 'config';
|
||||
import { connect } from 'react-redux';
|
||||
import { withRouter } from 'react-router';
|
||||
import {
|
||||
|
@ -19,51 +18,17 @@ import { doBeginPublish } from 'redux/actions/publish';
|
|||
import { doOpenModal } from 'redux/actions/app';
|
||||
import { doFetchItemsInCollection } from 'redux/actions/collections';
|
||||
import { isStreamPlaceholderClaim } from 'util/claim';
|
||||
import { normalizeURI } from 'util/lbryURI';
|
||||
import * as COLLECTIONS_CONSTS from 'constants/collections';
|
||||
import { selectIsSubscribedForUri } from 'redux/selectors/subscriptions';
|
||||
import { selectBlacklistedOutpointMap } from 'lbryinc';
|
||||
import ShowPage from './view';
|
||||
|
||||
const select = (state, props) => {
|
||||
const { location, history } = props;
|
||||
const { pathname, hash, search } = location;
|
||||
const { uri, location } = props;
|
||||
const { search } = location;
|
||||
|
||||
const urlPath = pathname + hash;
|
||||
const urlParams = new URLSearchParams(search);
|
||||
|
||||
// Remove the leading "/" added by the browser
|
||||
let path = urlPath.slice(1).replace(/:/g, '#');
|
||||
|
||||
// Google cache url
|
||||
// ex: webcache.googleusercontent.com/search?q=cache:MLwN3a8fCbYJ:https://lbry.tv/%40Bombards_Body_Language:f+&cd=12&hl=en&ct=clnk&gl=us
|
||||
// Extract the lbry url and use that instead
|
||||
// Without this it will try to render lbry://search
|
||||
if (search && search.startsWith('?q=cache:')) {
|
||||
const googleCacheRegex = new RegExp(`(https://${DOMAIN}/)([^+]*)`);
|
||||
const [x, y, googleCachedUrl] = search.match(googleCacheRegex); // eslint-disable-line
|
||||
if (googleCachedUrl) {
|
||||
const actualUrl = decodeURIComponent(googleCachedUrl);
|
||||
if (actualUrl) {
|
||||
path = actualUrl.replace(/:/g, '#');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let uri;
|
||||
try {
|
||||
uri = normalizeURI(path);
|
||||
} catch (e) {
|
||||
const match = path.match(/[#/:]/);
|
||||
|
||||
if (path === '$/') {
|
||||
history.replace(`/`);
|
||||
} else if (!path.startsWith('$/') && match && match.index) {
|
||||
uri = `lbry://${path.slice(0, match.index)}`;
|
||||
history.replace(`/${path.slice(0, match.index)}`);
|
||||
}
|
||||
}
|
||||
|
||||
const claim = selectClaimForUri(state, uri);
|
||||
const collectionId =
|
||||
urlParams.get(COLLECTIONS_CONSTS.COLLECTION_ID) ||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Can't use aliases here because we're doing exports/require
|
||||
|
||||
import { DOMAIN } from 'config';
|
||||
const PAGES = require('../constants/pages');
|
||||
const { parseURI, buildURI } = require('../util/lbryURI');
|
||||
const COLLECTIONS_CONSTS = require('../constants/collections');
|
||||
|
@ -165,3 +166,19 @@ export const generateListSearchUrlParams = (collectionId) => {
|
|||
urlParams.set(COLLECTIONS_CONSTS.COLLECTION_ID, collectionId);
|
||||
return `?` + urlParams.toString();
|
||||
};
|
||||
|
||||
// Google cache url
|
||||
// ex: webcache.googleusercontent.com/search?q=cache:MLwN3a8fCbYJ:https://lbry.tv/%40Bombards_Body_Language:f+&cd=12&hl=en&ct=clnk&gl=us
|
||||
// Extract the lbry url and use that instead
|
||||
// Without this it will try to render lbry://search
|
||||
export function generateGoogleCacheUrl(search, path) {
|
||||
const googleCacheRegex = new RegExp(`(https://${DOMAIN}/)([^+]*)`);
|
||||
const [x, y, googleCachedUrl] = search.match(googleCacheRegex); // eslint-disable-line
|
||||
|
||||
if (googleCachedUrl) {
|
||||
const actualUrl = decodeURIComponent(googleCachedUrl);
|
||||
if (actualUrl) {
|
||||
path = actualUrl.replace(/:/g, '#');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue