Code-split #6228

Merged
infinite-persistence merged 8 commits from ip/code-split into master 2021-06-25 10:26:57 +02:00
22 changed files with 598 additions and 471 deletions
Showing only changes of commit 3539031e5a - Show all commits

View file

@ -6,31 +6,20 @@ import analytics from 'analytics';
import { buildURI, parseURI } from 'lbry-redux'; import { buildURI, parseURI } from 'lbry-redux';
import { SIMPLE_SITE } from 'config'; import { SIMPLE_SITE } from 'config';
import Router from 'component/router/index'; import Router from 'component/router/index';
import ModalRouter from 'modal/modalRouter';
import ReactModal from 'react-modal'; import ReactModal from 'react-modal';
import { openContextMenu } from 'util/context-menu'; import { openContextMenu } from 'util/context-menu';
import useKonamiListener from 'util/enhanced-layout'; import useKonamiListener from 'util/enhanced-layout';
import Yrbl from 'component/yrbl';
import FileRenderFloating from 'component/fileRenderFloating'; import FileRenderFloating from 'component/fileRenderFloating';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
import usePrevious from 'effects/use-previous'; import usePrevious from 'effects/use-previous';
import Nag from 'component/common/nag';
import REWARDS from 'rewards'; import REWARDS from 'rewards';
import usePersistedState from 'effects/use-persisted-state'; import usePersistedState from 'effects/use-persisted-state';
import FileDrop from 'component/fileDrop';
import NagContinueFirstRun from 'component/nagContinueFirstRun';
import Spinner from 'component/spinner'; import Spinner from 'component/spinner';
import SyncFatalError from 'component/syncFatalError';
// @if TARGET='app' // @if TARGET='app'
import useZoom from 'effects/use-zoom'; import useZoom from 'effects/use-zoom';
import useHistoryNav from 'effects/use-history-nav'; import useHistoryNav from 'effects/use-history-nav';
// @endif // @endif
// @if TARGET='web' // @if TARGET='web'
import OpenInAppLink from 'web/component/openInAppLink';
import YoutubeWelcome from 'web/component/youtubeReferralWelcome';
import NagDegradedPerformance from 'web/component/nag-degraded-performance';
import NagDataCollection from 'web/component/nag-data-collection';
import NagNoUser from 'web/component/nag-no-user';
import { import {
useDegradedPerformance, useDegradedPerformance,
STATUS_OK, STATUS_OK,
@ -40,6 +29,24 @@ import {
} from 'web/effects/use-degraded-performance'; } from 'web/effects/use-degraded-performance';
// @endif // @endif
import LANGUAGE_MIGRATIONS from 'constants/language-migrations'; import LANGUAGE_MIGRATIONS from 'constants/language-migrations';
const FileDrop = React.lazy(() => import('component/fileDrop' /* webpackChunkName: "fileDrop" */));
const ModalRouter = React.lazy(() => import('modal/modalRouter' /* webpackChunkName: "modalRouter" */));
const Nag = React.lazy(() => import('component/common/nag' /* webpackChunkName: "nag" */));
const NagContinueFirstRun = React.lazy(() => import('component/nagContinueFirstRun' /* webpackChunkName: "nagContinueFirstRun" */));
const OpenInAppLink = React.lazy(() => import('web/component/openInAppLink' /* webpackChunkName: "openInAppLink" */));
const SyncFatalError = React.lazy(() => import('component/syncFatalError' /* webpackChunkName: "syncFatalError" */));
const Yrbl = React.lazy(() => import('component/yrbl' /* webpackChunkName: "yrbl" */));
// @if TARGET='web'
const NagDataCollection = React.lazy(() => import('web/component/nag-data-collection' /* webpackChunkName: "nag-data-collection" */));
const NagDegradedPerformance = React.lazy(() => import('web/component/nag-degraded-performance' /* webpackChunkName: "nag-degraded-performance" */));
const NagNoUser = React.lazy(() => import('web/component/nag-no-user' /* webpackChunkName: "nag-no-user" */));
const YoutubeWelcome = React.lazy(() => import('web/component/youtubeReferralWelcome' /* webpackChunkName: "youtubeReferralWelcome" */));
// @endif
// ****************************************************************************
export const MAIN_WRAPPER_CLASS = 'main-wrapper'; export const MAIN_WRAPPER_CLASS = 'main-wrapper';
export const IS_MAC = navigator.userAgent.indexOf('Mac OS X') !== -1; export const IS_MAC = navigator.userAgent.indexOf('Mac OS X') !== -1;
@ -377,11 +384,13 @@ function App(props: Props) {
if (syncFatalError) { if (syncFatalError) {
return ( return (
<React.Suspense fallback={null}>
<SyncFatalError <SyncFatalError
// @if TARGET='web' // @if TARGET='web'
lbryTvApiStatus={lbryTvApiStatus} lbryTvApiStatus={lbryTvApiStatus}
// @endif // @endif
/> />
</React.Suspense>
); );
} }
@ -397,17 +406,22 @@ function App(props: Props) {
onContextMenu={IS_WEB ? undefined : (e) => openContextMenu(e)} onContextMenu={IS_WEB ? undefined : (e) => openContextMenu(e)}
> >
{IS_WEB && lbryTvApiStatus === STATUS_DOWN ? ( {IS_WEB && lbryTvApiStatus === STATUS_DOWN ? (
<React.Suspense fallback={null}>
<Yrbl <Yrbl
className="main--empty" className="main--empty"
title={__('lbry.tv is currently down')} title={__('lbry.tv is currently down')}
subtitle={__('My wheel broke, but the good news is that someone from LBRY is working on it.')} subtitle={__('My wheel broke, but the good news is that someone from LBRY is working on it.')}
/> />
</React.Suspense>
) : ( ) : (
<React.Fragment> <React.Fragment>
<Router /> <Router />
<React.Suspense fallback={null}>
<ModalRouter /> <ModalRouter />
<FileDrop /> <FileDrop />
</React.Suspense>
<FileRenderFloating /> <FileRenderFloating />
<React.Suspense fallback={null}>
{isEnhancedLayout && <Yrbl className="yrbl--enhanced" />} {isEnhancedLayout && <Yrbl className="yrbl--enhanced" />}
{/* @if TARGET='app' */} {/* @if TARGET='app' */}
@ -433,6 +447,7 @@ function App(props: Props) {
)} )}
{user === null && <NagNoUser />} {user === null && <NagNoUser />}
{/* @endif */} {/* @endif */}
</React.Suspense>
</React.Fragment> </React.Fragment>
)} )}
</div> </div>

View file

@ -4,7 +4,7 @@ import classnames from 'classnames';
import EmbedPlayButton from 'component/embedPlayButton'; import EmbedPlayButton from 'component/embedPlayButton';
import Button from 'component/button'; import Button from 'component/button';
import UriIndicator from 'component/uriIndicator'; import UriIndicator from 'component/uriIndicator';
import { INLINE_PLAYER_WRAPPER_CLASS } from 'component/fileRenderFloating/view'; import { INLINE_PLAYER_WRAPPER_CLASS } from 'constants/classnames';
import { SIMPLE_SITE } from 'config'; import { SIMPLE_SITE } from 'config';
type Props = { type Props = {

View file

@ -18,7 +18,6 @@ import ClaimPreviewTitle from 'component/claimPreviewTitle';
import ClaimPreviewSubtitle from 'component/claimPreviewSubtitle'; import ClaimPreviewSubtitle from 'component/claimPreviewSubtitle';
import ClaimRepostAuthor from 'component/claimRepostAuthor'; import ClaimRepostAuthor from 'component/claimRepostAuthor';
import FileDownloadLink from 'component/fileDownloadLink'; import FileDownloadLink from 'component/fileDownloadLink';
import AbandonedChannelPreview from 'component/abandonedChannelPreview';
import PublishPending from 'component/publishPending'; import PublishPending from 'component/publishPending';
import ClaimMenuList from 'component/claimMenuList'; import ClaimMenuList from 'component/claimMenuList';
import ClaimPreviewLoading from './claim-preview-loading'; import ClaimPreviewLoading from './claim-preview-loading';
@ -28,6 +27,8 @@ import { ENABLE_NO_SOURCE_CLAIMS } from 'config';
import Button from 'component/button'; import Button from 'component/button';
import * as ICONS from 'constants/icons'; import * as ICONS from 'constants/icons';
const AbandonedChannelPreview = React.lazy(() => import('component/abandonedChannelPreview' /* webpackChunkName: "abandonedChannelPreview" */));
type Props = { type Props = {
uri: string, uri: string,
claim: ?Claim, // maybe? claim: ?Claim, // maybe?
@ -254,7 +255,11 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
} }
if (!shouldFetch && showUnresolvedClaim && !isResolvingUri && isChannelUri && claim === null) { if (!shouldFetch && showUnresolvedClaim && !isResolvingUri && isChannelUri && claim === null) {
return <AbandonedChannelPreview uri={uri} type />; return (
<React.Suspense fallback={null}>
<AbandonedChannelPreview uri={uri} type />
</React.Suspense>
);
} }
if (placeholder === 'publish' && !claim && uri.startsWith('lbry://@')) { if (placeholder === 'publish' && !claim && uri.startsWith('lbry://@')) {
return null; return null;

View file

@ -274,7 +274,8 @@ export class FormField extends React.PureComponent<Props> {
{...inputProps} {...inputProps}
/> />
<div className="form-field__textarea-info"> <div className="form-field__textarea-info">
{!noEmojis && <div className="form-field__quick-emojis"> {!noEmojis && (
<div className="form-field__quick-emojis">
{QUICK_EMOJIS.map((emoji) => ( {QUICK_EMOJIS.map((emoji) => (
<Button <Button
key={emoji} key={emoji}
@ -289,7 +290,8 @@ export class FormField extends React.PureComponent<Props> {
}} }}
/> />
))} ))}
</div>} </div>
)}
{countInfo} {countInfo}
</div> </div>
</fieldset-section> </fieldset-section>

View file

@ -1,18 +1,19 @@
// @flow // @flow
import type { Node } from 'react'; import type { Node } from 'react';
import React from 'react'; import React from 'react';
import Yrbl from 'component/yrbl';
import Button from 'component/button';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
import analytics from 'analytics'; import analytics from 'analytics';
import I18nMessage from 'component/i18nMessage';
import Native from 'native'; import Native from 'native';
import { Lbry } from 'lbry-redux'; import { Lbry } from 'lbry-redux';
const Button = React.lazy(() => import('component/button' /* webpackChunkName: "button" */));
const I18nMessage = React.lazy(() => import('component/i18nMessage' /* webpackChunkName: "i18nMessage" */));
const Yrbl = React.lazy(() => import('component/yrbl' /* webpackChunkName: "yrbl" */));
type Props = { type Props = {
children: Node, children: Node,
history: { history: {
replace: string => void, replace: (string) => void,
}, },
}; };
@ -36,7 +37,7 @@ class ErrorBoundary extends React.Component<Props, State> {
componentDidCatch(error, errorInfo) { componentDidCatch(error, errorInfo) {
// @if TARGET='web' // @if TARGET='web'
analytics.sentryError(error, errorInfo).then(sentryEventId => { analytics.sentryError(error, errorInfo).then((sentryEventId) => {
this.setState({ sentryEventId }); this.setState({ sentryEventId });
}); });
// @endif // @endif
@ -49,7 +50,7 @@ class ErrorBoundary extends React.Component<Props, State> {
errorMessage += `sdk version: ${sdkVersion}\n`; errorMessage += `sdk version: ${sdkVersion}\n`;
errorMessage += `page: ${window.location.href.split('.html')[1]}\n`; errorMessage += `page: ${window.location.href.split('.html')[1]}\n`;
errorMessage += `${error.stack}`; errorMessage += `${error.stack}`;
analytics.error(errorMessage).then(isSharingData => { analytics.error(errorMessage).then((isSharingData) => {
this.setState({ desktopErrorReported: isSharingData }); this.setState({ desktopErrorReported: isSharingData });
}); });
}); });
@ -74,6 +75,7 @@ class ErrorBoundary extends React.Component<Props, State> {
if (hasError) { if (hasError) {
return ( return (
<div className="main main--full-width main--empty"> <div className="main main--full-width main--empty">
<React.Suspense fallback={null}>
<Yrbl <Yrbl
type="sad" type="sad"
title={__('Aw shucks!')} title={__('Aw shucks!')}
@ -95,6 +97,7 @@ class ErrorBoundary extends React.Component<Props, State> {
</I18nMessage> </I18nMessage>
} }
/> />
</React.Suspense>
{!errorWasReported && ( {!errorWasReported && (
<div className="error__wrapper"> <div className="error__wrapper">
<span className="error__text"> <span className="error__text">

View file

@ -3,16 +3,11 @@ import { remote } from 'electron';
import React from 'react'; import React from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
import * as RENDER_MODES from 'constants/file_render_modes'; import * as RENDER_MODES from 'constants/file_render_modes';
import VideoViewer from 'component/viewers/videoViewer';
import ImageViewer from 'component/viewers/imageViewer';
import AppViewer from 'component/viewers/appViewer';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import fs from 'fs'; import fs from 'fs';
import analytics from 'analytics'; import analytics from 'analytics';
import DocumentViewer from 'component/viewers/documentViewer'; import DocumentViewer from 'component/viewers/documentViewer';
import PdfViewer from 'component/viewers/pdfViewer';
import HtmlViewer from 'component/viewers/htmlViewer';
// @if TARGET='app' // @if TARGET='app'
// should match // should match
@ -21,6 +16,18 @@ import ComicBookViewer from 'component/viewers/comicBookViewer';
import ThreeViewer from 'component/viewers/threeViewer'; import ThreeViewer from 'component/viewers/threeViewer';
// @endif // @endif
const AppViewer = React.lazy(() => import('component/viewers/appViewer' /* webpackChunkName: "viewers/appViewer" */));
const HtmlViewer = React.lazy(() =>
import('component/viewers/htmlViewer' /* webpackChunkName: "viewers/htmlViewer" */)
);
const ImageViewer = React.lazy(() =>
import('component/viewers/imageViewer' /* webpackChunkName: "viewers/imageViewer" */)
);
const PdfViewer = React.lazy(() => import('component/viewers/pdfViewer' /* webpackChunkName: "viewers/pdfViewer" */));
const VideoViewer = React.lazy(() =>
import('component/viewers/videoViewer' /* webpackChunkName: "viewers/videoViewer" */)
);
type Props = { type Props = {
uri: string, uri: string,
streamingUrl: string, streamingUrl: string,
@ -85,17 +92,27 @@ class FileRender extends React.PureComponent<Props> {
case RENDER_MODES.AUDIO: case RENDER_MODES.AUDIO:
case RENDER_MODES.VIDEO: case RENDER_MODES.VIDEO:
return ( return (
<React.Suspense fallback={null}>
<VideoViewer <VideoViewer
uri={uri} uri={uri}
source={source} source={source}
contentType={contentType} contentType={contentType}
desktopPlayStartTime={desktopPlayStartTime} desktopPlayStartTime={desktopPlayStartTime}
/> />
</React.Suspense>
); );
case RENDER_MODES.IMAGE: case RENDER_MODES.IMAGE:
return <ImageViewer uri={uri} source={source} />; return (
<React.Suspense fallback={null}>
<ImageViewer uri={uri} source={source} />;
</React.Suspense>
);
case RENDER_MODES.HTML: case RENDER_MODES.HTML:
return <HtmlViewer source={downloadPath || source} />; return (
<React.Suspense fallback={null}>
<HtmlViewer source={downloadPath || source} />;
</React.Suspense>
);
case RENDER_MODES.DOCUMENT: case RENDER_MODES.DOCUMENT:
case RENDER_MODES.MARKDOWN: case RENDER_MODES.MARKDOWN:
return ( return (
@ -115,7 +132,11 @@ class FileRender extends React.PureComponent<Props> {
case RENDER_MODES.DOCX: case RENDER_MODES.DOCX:
return <DocxViewer source={downloadPath} />; return <DocxViewer source={downloadPath} />;
case RENDER_MODES.PDF: case RENDER_MODES.PDF:
return <PdfViewer source={downloadPath || source} />; return (
<React.Suspense fallback={null}>
<PdfViewer source={downloadPath || source} />;
</React.Suspense>
);
case RENDER_MODES.CAD: case RENDER_MODES.CAD:
return ( return (
<ThreeViewer <ThreeViewer
@ -139,7 +160,11 @@ class FileRender extends React.PureComponent<Props> {
/> />
); );
case RENDER_MODES.APPLICATION: case RENDER_MODES.APPLICATION:
return <AppViewer uri={uri} />; return (
<React.Suspense fallback={null}>
<AppViewer uri={uri} />;
</React.Suspense>
);
} }
return null; return null;

View file

@ -1,23 +1,24 @@
// @flow // @flow
import * as ICONS from 'constants/icons'; import * as ICONS from 'constants/icons';
import * as RENDER_MODES from 'constants/file_render_modes'; import * as RENDER_MODES from 'constants/file_render_modes';
import { INLINE_PLAYER_WRAPPER_CLASS } from 'constants/classnames';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import Button from 'component/button'; import Button from 'component/button';
import classnames from 'classnames'; import classnames from 'classnames';
import LoadingScreen from 'component/common/loading-screen'; import LoadingScreen from 'component/common/loading-screen';
import FileRender from 'component/fileRender';
import UriIndicator from 'component/uriIndicator'; import UriIndicator from 'component/uriIndicator';
import usePersistedState from 'effects/use-persisted-state'; import usePersistedState from 'effects/use-persisted-state';
import { PRIMARY_PLAYER_WRAPPER_CLASS } from 'page/file/view'; import { PRIMARY_PLAYER_WRAPPER_CLASS } from 'page/file/view';
import Draggable from 'react-draggable';
import { onFullscreenChange } from 'util/full-screen'; import { onFullscreenChange } from 'util/full-screen';
import { useIsMobile } from 'effects/use-screensize'; import { useIsMobile } from 'effects/use-screensize';
import debounce from 'util/debounce'; import debounce from 'util/debounce';
import { useHistory } from 'react-router'; import { useHistory } from 'react-router';
const Draggable = React.lazy(() => import('react-draggable' /* webpackChunkName: "draggable" */));
const FileRender = React.lazy(() => import('component/fileRender' /* webpackChunkName: "fileRender" */));
const IS_DESKTOP_MAC = typeof process === 'object' ? process.platform === 'darwin' : false; const IS_DESKTOP_MAC = typeof process === 'object' ? process.platform === 'darwin' : false;
const DEBOUNCE_WINDOW_RESIZE_HANDLER_MS = 60; const DEBOUNCE_WINDOW_RESIZE_HANDLER_MS = 60;
export const INLINE_PLAYER_WRAPPER_CLASS = 'inline-player__wrapper';
type Props = { type Props = {
isFloating: boolean, isFloating: boolean,
@ -243,6 +244,7 @@ export default function FileRenderFloating(props: Props) {
} }
return ( return (
<React.Suspense fallback={null}>
<Draggable <Draggable
onDrag={handleDragMove} onDrag={handleDragMove}
onStart={handleDragStart} onStart={handleDragStart}
@ -289,6 +291,7 @@ export default function FileRenderFloating(props: Props) {
)} )}
{isReadyToPlay ? ( {isReadyToPlay ? (
<React.Suspense fallback={null}>
<FileRender <FileRender
className="draggable" className="draggable"
uri={uri} uri={uri}
@ -296,6 +299,7 @@ export default function FileRenderFloating(props: Props) {
desktopPlayStartTime={desktopPlayStartTime} desktopPlayStartTime={desktopPlayStartTime}
// @endif // @endif
/> />
</React.Suspense>
) : ( ) : (
<LoadingScreen status={loadingMessage} /> <LoadingScreen status={loadingMessage} />
)} )}
@ -310,5 +314,6 @@ export default function FileRenderFloating(props: Props) {
</div> </div>
</div> </div>
</Draggable> </Draggable>
</React.Suspense>
); );
} }

View file

@ -1,9 +1,10 @@
// @flow // @flow
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import FileRender from 'component/fileRender';
import LoadingScreen from 'component/common/loading-screen'; import LoadingScreen from 'component/common/loading-screen';
import { NON_STREAM_MODES } from 'constants/file_render_modes'; import { NON_STREAM_MODES } from 'constants/file_render_modes';
const FileRender = React.lazy(() => import('component/fileRender' /* webpackChunkName: "fileRender" */));
type Props = { type Props = {
isPlaying: boolean, isPlaying: boolean,
fileInfo: FileListItem, fileInfo: FileListItem,
@ -69,5 +70,11 @@ export default function FileRenderInline(props: Props) {
return null; return null;
} }
return renderContent ? <FileRender uri={uri} /> : <LoadingScreen isDocument />; return renderContent ? (
<React.Suspense fallback={null}>
<FileRender uri={uri} />
</React.Suspense>
) : (
<LoadingScreen isDocument />
);
} }

View file

@ -4,7 +4,6 @@ import React, { Fragment } from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
import SideNavigation from 'component/sideNavigation'; import SideNavigation from 'component/sideNavigation';
import Header from 'component/header'; import Header from 'component/header';
import Footer from 'web/component/footer';
/* @if TARGET='app' */ /* @if TARGET='app' */
import StatusBar from 'component/common/status-bar'; import StatusBar from 'component/common/status-bar';
/* @endif */ /* @endif */
@ -13,6 +12,8 @@ import { useHistory } from 'react-router';
import { useIsMobile, useIsMediumScreen } from 'effects/use-screensize'; import { useIsMobile, useIsMediumScreen } from 'effects/use-screensize';
import { parseURI } from 'lbry-redux'; import { parseURI } from 'lbry-redux';
const Footer = React.lazy(() => import('web/component/footer' /* webpackChunkName: "component/footer" */));
export const MAIN_CLASS = 'main'; export const MAIN_CLASS = 'main';
type Props = { type Props = {
children: Node | Array<Node>, children: Node | Array<Node>,
@ -126,7 +127,7 @@ function Page(props: Props) {
{/* @endif */} {/* @endif */}
</div> </div>
{/* @if TARGET='web' */} {/* @if TARGET='web' */}
{!noFooter && <Footer />} {!noFooter && <React.Suspense fallback={null}><Footer /></React.Suspense>}
{/* @endif */} {/* @endif */}
</Fragment> </Fragment>
); );

View file

@ -13,7 +13,7 @@ type Props = {
title: ?string, title: ?string,
thumbnail: ?string, thumbnail: ?string,
description: ?string, description: ?string,
history: { push: string => void }, history: { push: (string) => void },
}; };
class PreviewLink extends React.PureComponent<Props> { class PreviewLink extends React.PureComponent<Props> {

View file

@ -1,67 +1,78 @@
// @flow // @flow
import * as PAGES from 'constants/pages';
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { Route, Redirect, Switch, withRouter } from 'react-router-dom'; import { Route, Redirect, Switch, withRouter } from 'react-router-dom';
import SettingsPage from 'page/settings';
import SettingsNotificationsPage from 'page/settingsNotifications';
import SettingsAdvancedPage from 'page/settingsAdvanced';
import SettingsCreatorPage from 'page/settingsCreator';
import HelpPage from 'page/help';
// @if TARGET='app'
import BackupPage from 'page/backup';
// @endif
// @if TARGET='web'
import Code2257Page from 'web/page/code2257';
// @endif
import ReportPage from 'page/report';
import ReportContentPage from 'page/reportContent';
import ShowPage from 'page/show';
import PublishPage from 'page/publish';
import DiscoverPage from 'page/discover';
import HomePage from 'page/home';
import InvitedPage from 'page/invited';
import RewardsPage from 'page/rewards';
import FileListPublished from 'page/fileListPublished';
import InvitePage from 'page/invite';
import SearchPage from 'page/search';
import ListsPage from 'page/lists';
import LibraryPage from 'page/library';
import WalletPage from 'page/wallet';
import TagsFollowingPage from 'page/tagsFollowing';
import ChannelsFollowingPage from 'page/channelsFollowing';
import ChannelsFollowingDiscoverPage from 'page/channelsFollowingDiscover';
import TagsFollowingManagePage from 'page/tagsFollowingManage';
import ListBlockedPage from 'page/listBlocked';
import FourOhFourPage from 'page/fourOhFour';
import SignInPage from 'page/signIn';
import SignUpPage from 'page/signUp';
import PasswordResetPage from 'page/passwordReset';
import PasswordSetPage from 'page/passwordSet';
import SignInVerifyPage from 'page/signInVerify';
import ChannelsPage from 'page/channels';
import LiveStreamSetupPage from 'page/livestreamSetup';
import LivestreamCurrentPage from 'page/livestreamCurrent';
import EmbedWrapperPage from 'page/embedWrapper';
import TopPage from 'page/top';
import Welcome from 'page/welcome';
import CreatorDashboard from 'page/creatorDashboard';
import RewardsVerifyPage from 'page/rewardsVerify';
import CheckoutPage from 'page/checkoutPage';
import ChannelNew from 'page/channelNew';
import RepostNew from 'page/repost';
import BuyPage from 'page/buy';
import ReceivePage from 'page/receive';
import SendPage from 'page/send';
import SwapPage from 'page/swap';
import NotificationsPage from 'page/notifications';
import SignInWalletPasswordPage from 'page/signInWalletPassword';
import YoutubeSyncPage from 'page/youtubeSync';
import CollectionPage from 'page/collection';
import * as PAGES from 'constants/pages';
import { LINKED_COMMENT_QUERY_PARAM } from 'constants/comment'; import { LINKED_COMMENT_QUERY_PARAM } from 'constants/comment';
import { parseURI, isURIValid } from 'lbry-redux'; import { parseURI, isURIValid } from 'lbry-redux';
import { SITE_TITLE, WELCOME_VERSION, SIMPLE_SITE } from 'config'; import { SITE_TITLE, WELCOME_VERSION, SIMPLE_SITE } from 'config';
import HomePage from 'page/home';
// @if TARGET='app'
const BackupPage = React.lazy(() => import('page/backup' /* webpackChunkName: "backup" */));
// @endif
// @if TARGET='web'
const Code2257Page = React.lazy(() => import('web/page/code2257'));
// @endif
// Chunk: "authenticate"
const SignInPage = React.lazy(() => import('page/signIn' /* webpackChunkName: "authenticate" */));
const SignInWalletPasswordPage = React.lazy(() =>
import('page/signInWalletPassword' /* webpackChunkName: "authenticate" */)
);
const SignUpPage = React.lazy(() => import('page/signUp' /* webpackChunkName: "authenticate" */));
const SignInVerifyPage = React.lazy(() => import('page/signInVerify' /* webpackChunkName: "authenticate" */));
// Chunk: "wallet"
const BuyPage = React.lazy(() => import('page/buy' /* webpackChunkName: "wallet" */));
const ReceivePage = React.lazy(() => import('page/receive' /* webpackChunkName: "wallet" */));
const SendPage = React.lazy(() => import('page/send' /* webpackChunkName: "wallet" */));
const SwapPage = React.lazy(() => import('page/swap' /* webpackChunkName: "wallet" */));
const WalletPage = React.lazy(() => import('page/wallet' /* webpackChunkName: "wallet" */));
// Chunk: none
const NotificationsPage = React.lazy(() => import('page/notifications' /* webpackChunkName: "notifications" */));
const CollectionPage = React.lazy(() => import('page/collection' /* webpackChunkName: "collection" */));
const ChannelNew = React.lazy(() => import('page/channelNew' /* webpackChunkName: "channelNew" */));
const ChannelsFollowingDiscoverPage = React.lazy(() => import('page/channelsFollowingDiscover' /* webpackChunkName: "channelsFollowingDiscover" */));
const ChannelsFollowingPage = React.lazy(() => import('page/channelsFollowing' /* webpackChunkName: "channelsFollowing" */));
const ChannelsPage = React.lazy(() => import('page/channels' /* webpackChunkName: "channels" */));
const CheckoutPage = React.lazy(() => import('page/checkoutPage' /* webpackChunkName: "checkoutPage" */));
const CreatorDashboard = React.lazy(() => import('page/creatorDashboard' /* webpackChunkName: "creatorDashboard" */));
const DiscoverPage = React.lazy(() => import('page/discover' /* webpackChunkName: "discover" */));
const EmbedWrapperPage = React.lazy(() => import('page/embedWrapper' /* webpackChunkName: "embedWrapper" */));
const FileListPublished = React.lazy(() => import('page/fileListPublished' /* webpackChunkName: "fileListPublished" */));
const FourOhFourPage = React.lazy(() => import('page/fourOhFour' /* webpackChunkName: "fourOhFour" */));
const HelpPage = React.lazy(() => import('page/help' /* webpackChunkName: "help" */));
const InvitePage = React.lazy(() => import('page/invite' /* webpackChunkName: "invite" */));
const InvitedPage = React.lazy(() => import('page/invited' /* webpackChunkName: "invited" */));
const LibraryPage = React.lazy(() => import('page/library' /* webpackChunkName: "library" */));
const ListBlockedPage = React.lazy(() => import('page/listBlocked' /* webpackChunkName: "listBlocked" */));
const ListsPage = React.lazy(() => import('page/lists' /* webpackChunkName: "lists" */));
const LiveStreamSetupPage = React.lazy(() => import('page/livestreamSetup' /* webpackChunkName: "livestreamSetup" */));
const LivestreamCurrentPage = React.lazy(() => import('page/livestreamCurrent' /* webpackChunkName: "livestreamCurrent" */));
const PasswordResetPage = React.lazy(() => import('page/passwordReset' /* webpackChunkName: "passwordReset" */));
const PasswordSetPage = React.lazy(() => import('page/passwordSet' /* webpackChunkName: "passwordSet" */));
const PublishPage = React.lazy(() => import('page/publish' /* webpackChunkName: "publish" */));
const ReportContentPage = React.lazy(() => import('page/reportContent' /* webpackChunkName: "reportContent" */));
const ReportPage = React.lazy(() => import('page/report' /* webpackChunkName: "report" */));
const RepostNew = React.lazy(() => import('page/repost' /* webpackChunkName: "repost" */));
const RewardsPage = React.lazy(() => import('page/rewards' /* webpackChunkName: "rewards" */));
const RewardsVerifyPage = React.lazy(() => import('page/rewardsVerify' /* webpackChunkName: "rewardsVerify" */));
const SearchPage = React.lazy(() => import('page/search' /* webpackChunkName: "search" */));
const SettingsAdvancedPage = React.lazy(() => import('page/settingsAdvanced' /* webpackChunkName: "settingsAdvanced" */));
const SettingsCreatorPage = React.lazy(() => import('page/settingsCreator' /* webpackChunkName: "settingsCreator" */));
const SettingsNotificationsPage = React.lazy(() => import('page/settingsNotifications' /* webpackChunkName: "settingsNotifications" */));
const SettingsPage = React.lazy(() => import('page/settings' /* webpackChunkName: "settings" */));
const ShowPage = React.lazy(() => import('page/show' /* webpackChunkName: "show" */));
const TagsFollowingManagePage = React.lazy(() => import('page/tagsFollowingManage' /* webpackChunkName: "tagsFollowingManage" */));
const TagsFollowingPage = React.lazy(() => import('page/tagsFollowing' /* webpackChunkName: "tagsFollowing" */));
const TopPage = React.lazy(() => import('page/top' /* webpackChunkName: "top" */));
const Welcome = React.lazy(() => import('page/welcome' /* webpackChunkName: "welcome" */));
const YoutubeSyncPage = React.lazy(() => import('page/youtubeSync' /* webpackChunkName: "youtubeSync" */));
// Tell the browser we are handling scroll restoration // Tell the browser we are handling scroll restoration
if ('scrollRestoration' in history) { if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual'; history.scrollRestoration = 'manual';
@ -210,6 +221,7 @@ function AppRouter(props: Props) {
} }
return ( return (
<React.Suspense fallback={<div>TODO.....................</div>}>
<Switch> <Switch>
{/* @if TARGET='app' */} {/* @if TARGET='app' */}
{welcomeVersion < WELCOME_VERSION && <Route path="/*" component={Welcome} />} {welcomeVersion < WELCOME_VERSION && <Route path="/*" component={Welcome} />}
@ -308,6 +320,7 @@ function AppRouter(props: Props) {
<Route path="/:claimName/:streamName" exact component={ShowPage} /> <Route path="/:claimName/:streamName" exact component={ShowPage} />
<Route path="/*" component={FourOhFourPage} /> <Route path="/*" component={FourOhFourPage} />
</Switch> </Switch>
</React.Suspense>
); );
} }

View file

@ -5,7 +5,6 @@ import * as ICONS from 'constants/icons';
import React, { useEffect, useState, useContext, useCallback } from 'react'; import React, { useEffect, useState, useContext, useCallback } from 'react';
import { stopContextMenu } from 'util/context-menu'; import { stopContextMenu } from 'util/context-menu';
import type { Player } from './internal/videojs'; import type { Player } from './internal/videojs';
import VideoJs from './internal/videojs';
import analytics from 'analytics'; import analytics from 'analytics';
import { EmbedContext } from 'page/embedWrapper/view'; import { EmbedContext } from 'page/embedWrapper/view';
import classnames from 'classnames'; import classnames from 'classnames';
@ -21,6 +20,8 @@ import Button from 'component/button';
import I18nMessage from 'component/i18nMessage'; import I18nMessage from 'component/i18nMessage';
import { useHistory } from 'react-router'; import { useHistory } from 'react-router';
const VideoJs = React.lazy(() => import('./internal/videojs' /* webpackChunkName: "videojs" */));
const PLAY_TIMEOUT_ERROR = 'play_timeout_error'; const PLAY_TIMEOUT_ERROR = 'play_timeout_error';
const PLAY_TIMEOUT_LIMIT = 2000; const PLAY_TIMEOUT_LIMIT = 2000;
@ -332,6 +333,7 @@ function VideoViewer(props: Props) {
)} )}
{!isFetchingAd && ( {!isFetchingAd && (
<React.Suspense fallback={null}>
<VideoJs <VideoJs
adUrl={adUrl} adUrl={adUrl}
source={adUrl || source} source={adUrl || source}
@ -343,6 +345,7 @@ function VideoViewer(props: Props) {
toggleVideoTheaterMode={toggleVideoTheaterMode} toggleVideoTheaterMode={toggleVideoTheaterMode}
autoplay={!embedded || autoplayIfEmbedded} autoplay={!embedded || autoplayIfEmbedded}
/> />
</React.Suspense>
)} )}
</div> </div>
); );

View file

@ -1,9 +1,11 @@
// @flow // @flow
import * as ICONS from 'constants/icons'; import * as ICONS from 'constants/icons';
import React from 'react'; import React from 'react';
import Button from 'component/button';
import { useIsMobile } from 'effects/use-screensize'; import { useIsMobile } from 'effects/use-screensize';
import WunderbarSuggestions from 'component/wunderbarSuggestions';
const Button = React.lazy(() => import('component/button' /* webpackChunkName: "button" */));
const Icon = React.lazy(() => import('component/common/icon' /* webpackChunkName: "icon" */));
const WunderbarSuggestions = React.lazy(() => import('component/wunderbarSuggestions' /* webpackChunkName: "wunderbarSuggestions" */));
type Props = { type Props = {
doOpenMobileSearch: (any) => void, doOpenMobileSearch: (any) => void,
@ -18,13 +20,23 @@ export default function WunderBar(props: Props) {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
return isMobile ? ( return isMobile ? (
<React.Suspense fallback={null}>
<Button icon={ICONS.SEARCH} className="wunderbar__mobile-search" onClick={() => doOpenMobileSearch({ ...props })} /> <Button icon={ICONS.SEARCH} className="wunderbar__mobile-search" onClick={() => doOpenMobileSearch({ ...props })} />
</React.Suspense>
) : ( ) : (
<React.Suspense
fallback={
<div className="wunderbar__wrapper wunderbar wunderbar__input" aria-disabled>
<Icon icon={ICONS.SEARCH} aria-disabled />
</div>
}
>
<WunderbarSuggestions <WunderbarSuggestions
channelsOnly={channelsOnly} channelsOnly={channelsOnly}
noTopSuggestion={noTopSuggestion} noTopSuggestion={noTopSuggestion}
noBottomLinks={noBottomLinks} noBottomLinks={noBottomLinks}
customSelectAction={customSelectAction} customSelectAction={customSelectAction}
/> />
</React.Suspense>
); );
} }

View file

@ -0,0 +1,2 @@
// component/fileRenderFloating
export const INLINE_PLAYER_WRAPPER_CLASS = 'inline-player__wrapper';

View file

@ -2,46 +2,47 @@
import React from 'react'; import React from 'react';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
import * as MODALS from 'constants/modal_types'; import * as MODALS from 'constants/modal_types';
import ModalError from 'modal/modalError';
import ModalDownloading from 'modal/modalDownloading'; const ModalAffirmPurchase = React.lazy(() => import('modal/modalAffirmPurchase' /* webpackChunkName: "modalAffirmPurchase" */));
import ModalAutoGenerateThumbnail from 'modal/modalAutoGenerateThumbnail'; const ModalAutoGenerateThumbnail = React.lazy(() => import('modal/modalAutoGenerateThumbnail' /* webpackChunkName: "modalAutoGenerateThumbnail" */));
import ModalAutoUpdateDownloaded from 'modal/modalAutoUpdateDownloaded'; const ModalAutoUpdateDownloaded = React.lazy(() => import('modal/modalAutoUpdateDownloaded' /* webpackChunkName: "modalAutoUpdateDownloaded" */));
import ModalUpgrade from 'modal/modalUpgrade'; const ModalClaimCollectionAdd = React.lazy(() => import('modal/modalClaimCollectionAdd' /* webpackChunkName: "modalClaimCollectionAdd" */));
import ModalFirstReward from 'modal/modalFirstReward'; const ModalCommentAcknowledgement = React.lazy(() => import('modal/modalCommentAcknowledgement' /* webpackChunkName: "modalCommentAcknowledgement" */));
import ModalRemoveFile from 'modal/modalRemoveFile'; const ModalConfirmAge = React.lazy(() => import('modal/modalConfirmAge' /* webpackChunkName: "modalConfirmAge" */));
import ModalTransactionFailed from 'modal/modalTransactionFailed'; const ModalConfirmThumbnailUpload = React.lazy(() => import('modal/modalConfirmThumbnailUpload' /* webpackChunkName: "modalConfirmThumbnailUpload" */));
import ModalFileTimeout from 'modal/modalFileTimeout'; const ModalConfirmTransaction = React.lazy(() => import('modal/modalConfirmTransaction' /* webpackChunkName: "modalConfirmTransaction" */));
import ModalAffirmPurchase from 'modal/modalAffirmPurchase'; const ModalDeleteCollection = React.lazy(() => import('modal/modalRemoveCollection' /* webpackChunkName: "modalRemoveCollection" */));
import ModalRevokeClaim from 'modal/modalRevokeClaim'; const ModalDownloading = React.lazy(() => import('modal/modalDownloading' /* webpackChunkName: "modalDownloading" */));
import ModalPhoneCollection from 'modal/modalPhoneCollection'; const ModalError = React.lazy(() => import('modal/modalError' /* webpackChunkName: "modalError" */));
import ModalFirstSubscription from 'modal/modalFirstSubscription'; const ModalFileSelection = React.lazy(() => import('modal/modalFileSelection' /* webpackChunkName: "modalFileSelection" */));
import ModalConfirmTransaction from 'modal/modalConfirmTransaction'; const ModalFileTimeout = React.lazy(() => import('modal/modalFileTimeout' /* webpackChunkName: "modalFileTimeout" */));
import ModalSocialShare from 'modal/modalSocialShare'; const ModalFirstReward = React.lazy(() => import('modal/modalFirstReward' /* webpackChunkName: "modalFirstReward" */));
import ModalSendTip from 'modal/modalSendTip'; const ModalFirstSubscription = React.lazy(() => import('modal/modalFirstSubscription' /* webpackChunkName: "modalFirstSubscription" */));
import ModalPublish from 'modal/modalPublish'; const ModalImageUpload = React.lazy(() => import('modal/modalImageUpload' /* webpackChunkName: "modalImageUpload" */));
import ModalPublishPreview from 'modal/modalPublishPreview'; const ModalMassTipsUnlock = React.lazy(() => import('modal/modalMassTipUnlock' /* webpackChunkName: "modalMassTipUnlock" */));
import ModalOpenExternalResource from 'modal/modalOpenExternalResource'; const ModalMobileSearch = React.lazy(() => import('modal/modalMobileSearch' /* webpackChunkName: "modalMobileSearch" */));
import ModalConfirmThumbnailUpload from 'modal/modalConfirmThumbnailUpload'; const ModalOpenExternalResource = React.lazy(() => import('modal/modalOpenExternalResource' /* webpackChunkName: "modalOpenExternalResource" */));
import ModalWalletEncrypt from 'modal/modalWalletEncrypt'; const ModalPasswordUnsave = React.lazy(() => import('modal/modalPasswordUnsave' /* webpackChunkName: "modalPasswordUnsave" */));
import ModalWalletDecrypt from 'modal/modalWalletDecrypt'; const ModalPhoneCollection = React.lazy(() => import('modal/modalPhoneCollection' /* webpackChunkName: "modalPhoneCollection" */));
import ModalWalletUnlock from 'modal/modalWalletUnlock'; const ModalPublish = React.lazy(() => import('modal/modalPublish' /* webpackChunkName: "modalPublish" */));
import ModalRewardCode from 'modal/modalRewardCode'; const ModalPublishPreview = React.lazy(() => import('modal/modalPublishPreview' /* webpackChunkName: "modalPublishPreview" */));
import ModalPasswordUnsave from 'modal/modalPasswordUnsave'; const ModalRemoveBtcSwapAddress = React.lazy(() => import('modal/modalRemoveBtcSwapAddress' /* webpackChunkName: "modalRemoveBtcSwapAddress" */));
import ModalCommentAcknowledgement from 'modal/modalCommentAcknowledgement'; const ModalRemoveFile = React.lazy(() => import('modal/modalRemoveFile' /* webpackChunkName: "modalRemoveFile" */));
import ModalYoutubeWelcome from 'modal/modalYoutubeWelcome'; const ModalRevokeClaim = React.lazy(() => import('modal/modalRevokeClaim' /* webpackChunkName: "modalRevokeClaim" */));
import ModalSetReferrer from 'modal/modalSetReferrer'; const ModalRewardCode = React.lazy(() => import('modal/modalRewardCode' /* webpackChunkName: "modalRewardCode" */));
import ModalSignOut from 'modal/modalSignOut'; const ModalSendTip = React.lazy(() => import('modal/modalSendTip' /* webpackChunkName: "modalSendTip" */));
import ModalSupportsLiquidate from 'modal/modalSupportsLiquidate'; const ModalSetReferrer = React.lazy(() => import('modal/modalSetReferrer' /* webpackChunkName: "modalSetReferrer" */));
import ModalConfirmAge from 'modal/modalConfirmAge'; const ModalSignOut = React.lazy(() => import('modal/modalSignOut' /* webpackChunkName: "modalSignOut" */));
import ModalFileSelection from 'modal/modalFileSelection'; const ModalSocialShare = React.lazy(() => import('modal/modalSocialShare' /* webpackChunkName: "modalSocialShare" */));
import ModalSyncEnable from 'modal/modalSyncEnable'; const ModalSupportsLiquidate = React.lazy(() => import('modal/modalSupportsLiquidate' /* webpackChunkName: "modalSupportsLiquidate" */));
import ModalImageUpload from 'modal/modalImageUpload'; const ModalSyncEnable = React.lazy(() => import('modal/modalSyncEnable' /* webpackChunkName: "modalSyncEnable" */));
import ModalMobileSearch from 'modal/modalMobileSearch'; const ModalTransactionFailed = React.lazy(() => import('modal/modalTransactionFailed' /* webpackChunkName: "modalTransactionFailed" */));
import ModalViewImage from 'modal/modalViewImage'; const ModalUpgrade = React.lazy(() => import('modal/modalUpgrade' /* webpackChunkName: "modalUpgrade" */));
import ModalMassTipsUnlock from 'modal/modalMassTipUnlock'; const ModalViewImage = React.lazy(() => import('modal/modalViewImage' /* webpackChunkName: "modalViewImage" */));
import ModalRemoveBtcSwapAddress from 'modal/modalRemoveBtcSwapAddress'; const ModalWalletDecrypt = React.lazy(() => import('modal/modalWalletDecrypt' /* webpackChunkName: "modalWalletDecrypt" */));
import ModalClaimCollectionAdd from 'modal/modalClaimCollectionAdd'; const ModalWalletEncrypt = React.lazy(() => import('modal/modalWalletEncrypt' /* webpackChunkName: "modalWalletEncrypt" */));
import ModalDeleteCollection from 'modal/modalRemoveCollection'; const ModalWalletUnlock = React.lazy(() => import('modal/modalWalletUnlock' /* webpackChunkName: "modalWalletUnlock" */));
const ModalYoutubeWelcome = React.lazy(() => import('modal/modalYoutubeWelcome' /* webpackChunkName: "modalYoutubeWelcome" */));
type Props = { type Props = {
modal: { id: string, modalProps: {} }, modal: { id: string, modalProps: {} },
@ -66,92 +67,105 @@ function ModalRouter(props: Props) {
return null; return null;
} }
const { id, modalProps } = modal; function getModal(id) {
switch (id) { switch (id) {
case MODALS.UPGRADE: case MODALS.UPGRADE:
return <ModalUpgrade {...modalProps} />; return ModalUpgrade;
case MODALS.DOWNLOADING: case MODALS.DOWNLOADING:
return <ModalDownloading {...modalProps} />; return ModalDownloading;
case MODALS.AUTO_GENERATE_THUMBNAIL: case MODALS.AUTO_GENERATE_THUMBNAIL:
return <ModalAutoGenerateThumbnail {...modalProps} />; return ModalAutoGenerateThumbnail;
case MODALS.AUTO_UPDATE_DOWNLOADED: case MODALS.AUTO_UPDATE_DOWNLOADED:
return <ModalAutoUpdateDownloaded {...modalProps} />; return ModalAutoUpdateDownloaded;
case MODALS.ERROR: case MODALS.ERROR:
return <ModalError {...modalProps} />; return ModalError;
case MODALS.FILE_TIMEOUT: case MODALS.FILE_TIMEOUT:
return <ModalFileTimeout {...modalProps} />; return ModalFileTimeout;
case MODALS.FIRST_REWARD: case MODALS.FIRST_REWARD:
return <ModalFirstReward {...modalProps} />; return ModalFirstReward;
case MODALS.TRANSACTION_FAILED: case MODALS.TRANSACTION_FAILED:
return <ModalTransactionFailed {...modalProps} />; return ModalTransactionFailed;
case MODALS.CONFIRM_FILE_REMOVE: case MODALS.CONFIRM_FILE_REMOVE:
return <ModalRemoveFile {...modalProps} />; return ModalRemoveFile;
case MODALS.AFFIRM_PURCHASE: case MODALS.AFFIRM_PURCHASE:
return <ModalAffirmPurchase {...modalProps} />; return ModalAffirmPurchase;
case MODALS.CONFIRM_CLAIM_REVOKE: case MODALS.CONFIRM_CLAIM_REVOKE:
return <ModalRevokeClaim {...modalProps} />; return ModalRevokeClaim;
case MODALS.PHONE_COLLECTION: case MODALS.PHONE_COLLECTION:
return <ModalPhoneCollection {...modalProps} />; return ModalPhoneCollection;
case MODALS.FIRST_SUBSCRIPTION: case MODALS.FIRST_SUBSCRIPTION:
return <ModalFirstSubscription {...modalProps} />; return ModalFirstSubscription;
case MODALS.SEND_TIP: case MODALS.SEND_TIP:
return <ModalSendTip {...modalProps} />; return ModalSendTip;
case MODALS.SOCIAL_SHARE: case MODALS.SOCIAL_SHARE:
return <ModalSocialShare {...modalProps} />; return ModalSocialShare;
case MODALS.PUBLISH: case MODALS.PUBLISH:
return <ModalPublish {...modalProps} />; return ModalPublish;
case MODALS.PUBLISH_PREVIEW: case MODALS.PUBLISH_PREVIEW:
return <ModalPublishPreview {...modalProps} />; return ModalPublishPreview;
case MODALS.CONFIRM_EXTERNAL_RESOURCE: case MODALS.CONFIRM_EXTERNAL_RESOURCE:
return <ModalOpenExternalResource {...modalProps} />; return ModalOpenExternalResource;
case MODALS.CONFIRM_TRANSACTION: case MODALS.CONFIRM_TRANSACTION:
return <ModalConfirmTransaction {...modalProps} />; return ModalConfirmTransaction;
case MODALS.CONFIRM_THUMBNAIL_UPLOAD: case MODALS.CONFIRM_THUMBNAIL_UPLOAD:
return <ModalConfirmThumbnailUpload {...modalProps} />; return ModalConfirmThumbnailUpload;
case MODALS.WALLET_ENCRYPT: case MODALS.WALLET_ENCRYPT:
return <ModalWalletEncrypt {...modalProps} />; return ModalWalletEncrypt;
case MODALS.WALLET_DECRYPT: case MODALS.WALLET_DECRYPT:
return <ModalWalletDecrypt {...modalProps} />; return ModalWalletDecrypt;
case MODALS.WALLET_UNLOCK: case MODALS.WALLET_UNLOCK:
return <ModalWalletUnlock {...modalProps} />; return ModalWalletUnlock;
case MODALS.WALLET_PASSWORD_UNSAVE: case MODALS.WALLET_PASSWORD_UNSAVE:
return <ModalPasswordUnsave {...modalProps} />; return ModalPasswordUnsave;
case MODALS.REWARD_GENERATED_CODE: case MODALS.REWARD_GENERATED_CODE:
return <ModalRewardCode {...modalProps} />; return ModalRewardCode;
case MODALS.COMMENT_ACKNOWEDGEMENT: case MODALS.COMMENT_ACKNOWEDGEMENT:
return <ModalCommentAcknowledgement {...modalProps} />; return ModalCommentAcknowledgement;
case MODALS.YOUTUBE_WELCOME: case MODALS.YOUTUBE_WELCOME:
return <ModalYoutubeWelcome />; return ModalYoutubeWelcome;
case MODALS.SET_REFERRER: case MODALS.SET_REFERRER:
return <ModalSetReferrer {...modalProps} />; return ModalSetReferrer;
case MODALS.SIGN_OUT: case MODALS.SIGN_OUT:
return <ModalSignOut {...modalProps} />; return ModalSignOut;
case MODALS.CONFIRM_AGE: case MODALS.CONFIRM_AGE:
return <ModalConfirmAge {...modalProps} />; return ModalConfirmAge;
case MODALS.FILE_SELECTION: case MODALS.FILE_SELECTION:
return <ModalFileSelection {...modalProps} />; return ModalFileSelection;
case MODALS.LIQUIDATE_SUPPORTS: case MODALS.LIQUIDATE_SUPPORTS:
return <ModalSupportsLiquidate {...modalProps} />; return ModalSupportsLiquidate;
case MODALS.IMAGE_UPLOAD: case MODALS.IMAGE_UPLOAD:
return <ModalImageUpload {...modalProps} />; return ModalImageUpload;
case MODALS.SYNC_ENABLE: case MODALS.SYNC_ENABLE:
return <ModalSyncEnable {...modalProps} />; return ModalSyncEnable;
case MODALS.MOBILE_SEARCH: case MODALS.MOBILE_SEARCH:
return <ModalMobileSearch {...modalProps} />; return ModalMobileSearch;
case MODALS.VIEW_IMAGE: case MODALS.VIEW_IMAGE:
return <ModalViewImage {...modalProps} />; return ModalViewImage;
case MODALS.MASS_TIP_UNLOCK: case MODALS.MASS_TIP_UNLOCK:
return <ModalMassTipsUnlock {...modalProps} />; return ModalMassTipsUnlock;
case MODALS.CONFIRM_REMOVE_BTC_SWAP_ADDRESS: case MODALS.CONFIRM_REMOVE_BTC_SWAP_ADDRESS:
return <ModalRemoveBtcSwapAddress {...modalProps} />; return ModalRemoveBtcSwapAddress;
case MODALS.COLLECTION_ADD: case MODALS.COLLECTION_ADD:
return <ModalClaimCollectionAdd {...modalProps} />; return ModalClaimCollectionAdd;
case MODALS.COLLECTION_DELETE: case MODALS.COLLECTION_DELETE:
return <ModalDeleteCollection {...modalProps} />; return ModalDeleteCollection;
default: default:
return null; return null;
} }
} }
const { id, modalProps } = modal;
const SelectedModal = getModal(id);
if (SelectedModal === null) {
return null;
}
return (
<React.Suspense fallback={null}>
<SelectedModal {...modalProps} />
</React.Suspense>
);
}
export default withRouter(ModalRouter); export default withRouter(ModalRouter);

View file

@ -1,7 +1,6 @@
// @flow // @flow
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
import FileRender from 'component/fileRender';
import FileViewerEmbeddedTitle from 'component/fileViewerEmbeddedTitle'; import FileViewerEmbeddedTitle from 'component/fileViewerEmbeddedTitle';
import Spinner from 'component/spinner'; import Spinner from 'component/spinner';
import Button from 'component/button'; import Button from 'component/button';
@ -9,6 +8,8 @@ import Card from 'component/common/card';
import { formatLbryUrlForWeb } from 'util/url'; import { formatLbryUrlForWeb } from 'util/url';
import { useHistory } from 'react-router'; import { useHistory } from 'react-router';
const FileRender = React.lazy(() => import('component/fileRender' /* webpackChunkName: "fileRender" */));
type Props = { type Props = {
uri: string, uri: string,
resolveUri: (string) => void, resolveUri: (string) => void,
@ -98,7 +99,9 @@ const EmbedWrapperPage = (props: Props) => {
> >
<EmbedContext.Provider value> <EmbedContext.Provider value>
{readyToDisplay ? ( {readyToDisplay ? (
<React.Suspense fallback={null}>
<FileRender uri={uri} embedded /> <FileRender uri={uri} embedded />
</React.Suspense>
) : ( ) : (
<div className="embed__loading"> <div className="embed__loading">
<FileViewerEmbeddedTitle uri={uri} /> <FileViewerEmbeddedTitle uri={uri} />

View file

@ -10,9 +10,10 @@ import FileRenderDownload from 'component/fileRenderDownload';
import RecommendedContent from 'component/recommendedContent'; import RecommendedContent from 'component/recommendedContent';
import CollectionContent from 'component/collectionContentSidebar'; import CollectionContent from 'component/collectionContentSidebar';
import CommentsList from 'component/commentsList'; import CommentsList from 'component/commentsList';
import PostViewer from 'component/postViewer';
import Empty from 'component/common/empty'; import Empty from 'component/common/empty';
const PostViewer = React.lazy(() => import('component/postViewer' /* webpackChunkName: "postViewer" */));
export const PRIMARY_PLAYER_WRAPPER_CLASS = 'file-page__video-container'; export const PRIMARY_PLAYER_WRAPPER_CLASS = 'file-page__video-container';
type Props = { type Props = {
@ -96,7 +97,11 @@ function FilePage(props: Props) {
} }
if (isMarkdown) { if (isMarkdown) {
return <PostViewer uri={uri} />; return (
<React.Suspense fallback={null}>
<PostViewer uri={uri} />
</React.Suspense>
);
} }
if (RENDER_MODES.TEXT_MODES.includes(renderMode)) { if (RENDER_MODES.TEXT_MODES.includes(renderMode)) {

View file

@ -5,16 +5,17 @@ import React, { useEffect } from 'react';
import { Redirect, useHistory } from 'react-router-dom'; import { Redirect, useHistory } from 'react-router-dom';
import Spinner from 'component/spinner'; import Spinner from 'component/spinner';
import ChannelPage from 'page/channel'; import ChannelPage from 'page/channel';
import FilePage from 'page/file';
import LivestreamPage from 'page/livestream';
import Page from 'component/page'; import Page from 'component/page';
import Button from 'component/button'; import Button from 'component/button';
import Card from 'component/common/card'; import Card from 'component/common/card';
import AbandonedChannelPreview from 'component/abandonedChannelPreview';
import Yrbl from 'component/yrbl';
import { formatLbryUrlForWeb } from 'util/url'; import { formatLbryUrlForWeb } from 'util/url';
import { parseURI, COLLECTIONS_CONSTS } from 'lbry-redux'; import { parseURI, COLLECTIONS_CONSTS } from 'lbry-redux';
const AbandonedChannelPreview = React.lazy(() => import('component/abandonedChannelPreview' /* webpackChunkName: "abandonedChannelPreview" */));
const FilePage = React.lazy(() => import('page/file' /* webpackChunkName: "filePage" */));
const LivestreamPage = React.lazy(() => import('page/livestream' /* webpackChunkName: "livestream" */));
const Yrbl = React.lazy(() => import('component/yrbl' /* webpackChunkName: "yrbl" */));
type Props = { type Props = {
isResolvingUri: boolean, isResolvingUri: boolean,
resolveUri: (string) => void, resolveUri: (string) => void,
@ -157,7 +158,11 @@ function ShowPage(props: Props) {
/> />
</div> </div>
)} )}
{!isResolvingUri && isSubscribed && claim === null && <AbandonedChannelPreview uri={uri} type={'large'} />} {!isResolvingUri && isSubscribed && claim === null && (
<React.Suspense fallback={null}>
<AbandonedChannelPreview uri={uri} type={'large'} />
</React.Suspense>
)}
</Page> </Page>
); );
} else if (claim.name.length && claim.name[0] === '@') { } else if (claim.name.length && claim.name[0] === '@') {
@ -196,7 +201,7 @@ function ShowPage(props: Props) {
} }
} }
return innerContent; return <React.Suspense fallback={null}>{innerContent}</React.Suspense>;
} }
export default ShowPage; export default ShowPage;

View file

@ -41,6 +41,7 @@
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: black;
} }
.content__wrapper--floating { .content__wrapper--floating {

View file

@ -528,7 +528,7 @@ video::-internal-media-controls-overlay-cast-button {
.vjs-playback-rate .vjs-menu { .vjs-playback-rate .vjs-menu {
// Extend the width to prevent a potential scrollbar from blocking the text. // Extend the width to prevent a potential scrollbar from blocking the text.
width: 8em; width: 8em;
left: -2em; left: -3em;
} }
} }

View file

@ -84,6 +84,11 @@
font-size: 10px; font-size: 10px;
} }
.vjs-playback-rate .vjs-menu .vjs-menu-content .vjs-menu-item {
margin: 0 0;
padding: 5px 10px;
}
// Volume slider // Volume slider
.vjs-volume-panel { .vjs-volume-panel {
&.vjs-control { &.vjs-control {

View file

@ -118,6 +118,7 @@ const webConfig = {
filename: '[name].js', filename: '[name].js',
path: path.join(__dirname, 'dist/public/'), path: path.join(__dirname, 'dist/public/'),
publicPath: '/public/', publicPath: '/public/',
chunkFilename: '[name]-[chunkhash].js',
}, },
devServer: { devServer: {
port: WEBPACK_WEB_PORT, port: WEBPACK_WEB_PORT,