lbry-desktop/ui/component/router/view.jsx
2020-02-14 17:28:48 -05:00

169 lines
6.5 KiB
JavaScript

// @flow
import * as PAGES from 'constants/pages';
import React, { useEffect } from 'react';
import { Route, Redirect, Switch, withRouter } from 'react-router-dom';
import SettingsPage from 'page/settings';
import HelpPage from 'page/help';
import ReportPage from 'page/report';
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 FileListDownloaded from 'page/fileListDownloaded';
import FileListPublished from 'page/fileListPublished';
import TransactionHistoryPage from 'page/transactionHistory';
import InvitePage from 'page/invite';
import SearchPage from 'page/search';
import LibraryPage from 'page/library';
import WalletPage from 'page/wallet';
import TagsPage from 'page/tags';
import TagsFollowingPage from 'page/tagsFollowing';
import ChannelsFollowingPage from 'page/channelsFollowing';
import ChannelsFollowingManagePage from 'page/channelsFollowingManage';
import TagsFollowingManagePage from 'page/tagsFollowingManage';
import ListBlockedPage from 'page/listBlocked';
import FourOhFourPage from 'page/fourOhFour';
import SignInPage from 'page/signIn';
import SignInVerifyPage from 'page/signInVerify';
import ChannelsPage from 'page/channels';
import EmbedWrapperPage from 'page/embedWrapper';
import TopPage from 'page/top';
import { parseURI } from 'lbry-redux';
import { SITE_TITLE } from 'config';
// Tell the browser we are handling scroll restoration
if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual';
}
type PrivateRouteProps = {
component: any,
isAuthenticated: boolean,
location: { pathname: string },
};
function PrivateRoute(props: PrivateRouteProps) {
const { component: Component, isAuthenticated, ...rest } = props;
return (
<Route
{...rest}
render={props =>
isAuthenticated || !IS_WEB ? (
<Component {...props} />
) : (
<Redirect to={`/$/${PAGES.AUTH}?redirect=${props.location.pathname}`} />
)
}
/>
);
}
type Props = {
currentScroll: number,
isAuthenticated: boolean,
location: { pathname: string, search: string },
history: {
entries: { title: string }[],
goBack: () => void,
goForward: () => void,
index: number,
length: number,
location: { pathname: string },
push: string => void,
state: {},
replaceState: ({}, string, string) => void,
},
uri: string,
title: string,
};
function AppRouter(props: Props) {
const {
currentScroll,
location: { pathname },
isAuthenticated,
history,
uri,
title,
} = props;
const { channelName, streamName } = parseURI(uri);
const { entries } = history;
const entryIndex = history.index;
useEffect(() => {
if (typeof title !== 'undefined' && title !== '') {
document.title = title;
} else if (typeof streamName !== 'undefined' && streamName !== 'undefined' && streamName !== '') {
document.title = streamName;
} else if (typeof channelName !== 'undefined' && channelName !== '') {
document.title = channelName;
} else {
document.title = IS_WEB ? SITE_TITLE : 'LBRY';
}
entries[entryIndex].title = document.title;
return () => {
document.title = IS_WEB ? SITE_TITLE : 'LBRY';
};
}, [channelName, entries, entryIndex, streamName, title]);
useEffect(() => {
window.scrollTo(0, currentScroll);
}, [currentScroll, pathname]);
// react-router doesn't decode pathanmes before doing the route matching check
// We have to redirect here because if we redirect on the server, it might get encoded again
// in the browser causing a redirect loop
const decodedPathname = decodeURIComponent(pathname);
if (decodedPathname !== pathname) {
return <Redirect to={decodedPathname} />;
}
return (
<Switch>
<Route path={`/`} exact component={HomePage} />
<Route path={`/$/${PAGES.DISCOVER}`} exact component={DiscoverPage} />
<Route path={`/$/${PAGES.AUTH}`} exact component={SignInPage} />
<Route path={`/$/${PAGES.TAGS}`} exact component={TagsPage} />
<Route path={`/$/${PAGES.TAGS_FOLLOWING}`} exact component={TagsFollowingPage} />
<Route
path={`/$/${PAGES.CHANNELS_FOLLOWING}`}
exact
component={isAuthenticated || !IS_WEB ? ChannelsFollowingPage : DiscoverPage}
/>
<Route path={`/$/${PAGES.CHANNELS_FOLLOWING_MANAGE}`} exact component={ChannelsFollowingManagePage} />
<Route path={`/$/${PAGES.HELP}`} exact component={HelpPage} />
<Route path={`/$/${PAGES.AUTH_VERIFY}`} exact component={SignInVerifyPage} />
<Route path={`/$/${PAGES.SEARCH}`} exact component={SearchPage} />
<Route path={`/$/${PAGES.TOP}`} exact component={TopPage} />
<Route path={`/$/${PAGES.SETTINGS}`} exact component={SettingsPage} />
<Route path={`/$/${PAGES.INVITE}/:referrer`} exact component={InvitedPage} />
<PrivateRoute {...props} path={`/$/${PAGES.INVITE}`} component={InvitePage} />
<PrivateRoute {...props} path={`/$/${PAGES.DOWNLOADED}`} component={FileListDownloaded} />
<PrivateRoute {...props} path={`/$/${PAGES.PUBLISHED}`} component={FileListPublished} />
<PrivateRoute {...props} path={`/$/${PAGES.PUBLISH}`} component={PublishPage} />
<PrivateRoute {...props} path={`/$/${PAGES.REPORT}`} component={ReportPage} />
<PrivateRoute {...props} path={`/$/${PAGES.REWARDS}`} component={RewardsPage} />
<PrivateRoute {...props} path={`/$/${PAGES.TRANSACTIONS}`} component={TransactionHistoryPage} />
<PrivateRoute {...props} path={`/$/${PAGES.LIBRARY}`} component={LibraryPage} />
<PrivateRoute {...props} path={`/$/${PAGES.TAGS_FOLLOWING_MANAGE}`} component={TagsFollowingManagePage} />
<PrivateRoute {...props} path={`/$/${PAGES.BLOCKED}`} component={ListBlockedPage} />
<PrivateRoute {...props} path={`/$/${PAGES.WALLET}`} exact component={WalletPage} />
<PrivateRoute {...props} path={`/$/${PAGES.CHANNELS}`} component={ChannelsPage} />
<Route path={`/$/${PAGES.EMBED}/:claimName`} exact component={EmbedWrapperPage} />
<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="/*" component={FourOhFourPage} />
</Switch>
);
}
export default withRouter(AppRouter);