lbry-desktop/ui/page/discover/view.jsx
infinite-persistence 7b85d7a585
Allow Category definitions to specify language to search in.
This will be entirely up to the homepage maintainer, and will override the user's "Search only in the this language" setting.
2022-04-20 22:56:15 +08:00

224 lines
7.2 KiB
JavaScript

// @flow
import React, { useRef } from 'react';
import classnames from 'classnames';
import { DOMAIN, SIMPLE_SITE } from 'config';
import * as ICONS from 'constants/icons';
import * as PAGES from 'constants/pages';
import * as CS from 'constants/claim_search';
import Page from 'component/page';
import ClaimListDiscover from 'component/claimListDiscover';
import Button from 'component/button';
import useHover from 'effects/use-hover';
import { useIsMobile } from 'effects/use-screensize';
import analytics from 'analytics';
import HiddenNsfw from 'component/common/hidden-nsfw';
import Icon from 'component/common/icon';
import Ads from 'web/component/ads';
import LbcSymbol from 'component/common/lbc-symbol';
import I18nMessage from 'component/i18nMessage';
import moment from 'moment';
import LivestreamSection from './livestreamSection';
type Props = {
dynamicRouteProps: RowDataItem,
location: { search: string },
followedTags: Array<Tag>,
repostedUri: string,
repostedClaim: ?GenericClaim,
languageSetting: string,
searchInLanguage: boolean,
doToggleTagFollowDesktop: (string) => void,
doResolveUri: (string) => void,
tileLayout: boolean,
activeLivestreams: ?LivestreamInfo,
doFetchActiveLivestreams: (orderBy: ?Array<string>, lang: ?Array<string>) => void,
};
function DiscoverPage(props: Props) {
const {
location: { search },
followedTags,
repostedClaim,
repostedUri,
languageSetting,
searchInLanguage,
doToggleTagFollowDesktop,
doResolveUri,
tileLayout,
activeLivestreams,
doFetchActiveLivestreams,
dynamicRouteProps,
} = props;
const buttonRef = useRef();
const isHovering = useHover(buttonRef);
const isMobile = useIsMobile();
const isWildWest = dynamicRouteProps && dynamicRouteProps.id === 'WILD_WEST';
const urlParams = new URLSearchParams(search);
const langParam = urlParams.get(CS.LANGUAGE_KEY) || null;
const claimType = urlParams.get('claim_type');
const tagsQuery = urlParams.get('t') || null;
const tags = tagsQuery ? tagsQuery.split(',') : null;
const repostedClaimIsResolved = repostedUri && repostedClaim;
const hideRepostRibbon = !isWildWest;
// Eventually allow more than one tag on this page
// Restricting to one to make follow/unfollow simpler
const tag = (tags && tags[0]) || null;
const channelIds =
(dynamicRouteProps && dynamicRouteProps.options && dynamicRouteProps.options.channelIds) || undefined;
const isFollowing = followedTags.map(({ name }) => name).includes(tag);
let label = isFollowing ? __('Following --[button label indicating a channel has been followed]--') : __('Follow');
if (isHovering && isFollowing) {
label = __('Unfollow');
}
const includeLivestreams = !tagsQuery;
function getMeta() {
if (!dynamicRouteProps) {
return (
<a
className="help"
href="https://odysee.com/@OdyseeHelp:b/trending:50"
title={__('Learn more about Credits on %DOMAIN%', { DOMAIN })}
>
<I18nMessage tokens={{ lbc: <LbcSymbol /> }}>Results boosted by %lbc%</I18nMessage>
</a>
);
}
if (tag && !isMobile) {
return (
<Button
ref={buttonRef}
button="alt"
icon={ICONS.SUBSCRIBE}
iconColor="red"
onClick={handleFollowClick}
requiresAuth={IS_WEB}
label={label}
/>
);
}
return null;
}
function getSubSection() {
if (includeLivestreams) {
return (
<LivestreamSection
tileLayout={repostedUri ? false : tileLayout}
channelIds={channelIds}
activeLivestreams={activeLivestreams}
doFetchActiveLivestreams={doFetchActiveLivestreams}
searchLanguages={dynamicRouteProps?.options?.searchLanguages}
languageSetting={languageSetting}
searchInLanguage={searchInLanguage}
langParam={langParam}
/>
);
}
return null;
}
function getPins(routeProps) {
if (routeProps && (routeProps.pinnedUrls || routeProps.pinnedClaimIds)) {
return {
urls: routeProps.pinnedUrls,
claimIds: routeProps.pinnedClaimIds,
onlyPinForOrder: CS.ORDER_BY_TRENDING,
};
}
}
React.useEffect(() => {
if (repostedUri && !repostedClaimIsResolved) {
doResolveUri(repostedUri);
}
}, [repostedUri, repostedClaimIsResolved, doResolveUri]);
function handleFollowClick() {
if (tag) {
doToggleTagFollowDesktop(tag);
const nowFollowing = !isFollowing;
analytics.tagFollowEvent(tag, nowFollowing, 'tag-page');
}
}
let headerLabel;
if (repostedClaim) {
headerLabel = __('Reposts of %uri%', { uri: repostedUri });
} else if (tag) {
headerLabel = (
<span>
<Icon icon={ICONS.TAG} size={10} />
{(tag === CS.TAGS_ALL && __('All Content')) || (tag === CS.TAGS_FOLLOWED && __('Followed Tags')) || tag}
<Button
className="claim-search__tags-link"
button="link"
label={__('Manage Tags')}
navigate={`/$/${PAGES.TAGS_FOLLOWING_MANAGE}`}
/>
</span>
);
} else {
headerLabel = (
<span>
<Icon icon={(dynamicRouteProps && dynamicRouteProps.icon) || ICONS.DISCOVER} size={10} />
{(dynamicRouteProps && __(`${dynamicRouteProps.title}`)) || __('All Content')}
</span>
);
}
let releaseTime =
dynamicRouteProps && dynamicRouteProps.options && dynamicRouteProps.options.releaseTime
? dynamicRouteProps.options.releaseTime
: !isWildWest && `>${Math.floor(moment().subtract(0, 'hour').startOf('week').unix())}`;
return (
<Page
noFooter
fullWidthPage={tileLayout}
className={classnames('main__discover', { 'hide-ribbon': hideRepostRibbon })}
>
<ClaimListDiscover
pins={getPins(dynamicRouteProps)}
hideFilters={isWildWest ? true : undefined}
header={repostedUri ? <span /> : undefined}
subSection={getSubSection()}
tileLayout={repostedUri ? false : tileLayout}
defaultOrderBy={isWildWest || tags ? CS.ORDER_BY_TRENDING : undefined}
claimType={claimType ? [claimType] : undefined}
headerLabel={headerLabel}
tags={tags}
hiddenNsfwMessage={<HiddenNsfw type="page" />}
repostedClaimId={repostedClaim ? repostedClaim.claim_id : null}
injectedItem={!isWildWest && { node: <Ads small type="video" tileLayout={tileLayout} /> }}
// Assume wild west page if no dynamicRouteProps
// Not a very good solution, but just doing it for now
// until we are sure this page will stay around
// TODO: find a better way to determine discover / wild west vs other modes release times
// for now including && !tags so that
releaseTime={releaseTime || undefined}
feeAmount={isWildWest || tags ? CS.FEE_AMOUNT_ANY : undefined}
channelIds={channelIds}
limitClaimsPerChannel={
SIMPLE_SITE
? (dynamicRouteProps && dynamicRouteProps.options && dynamicRouteProps.options.limitClaimsPerChannel) || 3
: 3
}
meta={getMeta()}
hasSource
forceShowReposts={dynamicRouteProps}
searchLanguages={dynamicRouteProps?.options?.searchLanguages}
/>
</Page>
);
}
export default DiscoverPage;