lbry-desktop/ui/page/discover/livestreamSection.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

163 lines
5.4 KiB
JavaScript

// @flow
import React from 'react';
import Button from 'component/button';
import { ENABLE_NO_SOURCE_CLAIMS } from 'config';
import * as CS from 'constants/claim_search';
import * as ICONS from 'constants/icons';
import ClaimListDiscover from 'component/claimListDiscover';
import { useIsMobile, useIsLargeScreen } from 'effects/use-screensize';
import usePersistedState from 'effects/use-persisted-state';
import { getLivestreamUris } from 'util/livestream';
import { resolveLangForClaimSearch } from 'util/default-languages';
const DEFAULT_LIVESTREAM_TILE_LIMIT = 8;
const SECTION = Object.freeze({ COLLAPSED: 1, EXPANDED: 2 });
function getTileLimit(isLargeScreen, originalSize) {
return isLargeScreen ? originalSize * (3 / 2) : originalSize;
}
// ****************************************************************************
// ****************************************************************************
type Props = {
tileLayout: boolean,
channelIds?: Array<string>,
activeLivestreams: ?LivestreamInfo,
doFetchActiveLivestreams: (orderBy: ?Array<string>, lang: ?Array<string>) => void,
searchLanguages?: Array<string>,
languageSetting?: string,
searchInLanguage?: boolean,
langParam?: string | null,
};
export default function LivestreamSection(props: Props) {
const {
tileLayout,
channelIds,
activeLivestreams,
doFetchActiveLivestreams,
searchLanguages,
languageSetting,
searchInLanguage,
langParam,
} = props;
const [liveSectionStore, setLiveSectionStore] = usePersistedState('discover:lsSection', SECTION.COLLAPSED);
const [expandedYPos, setExpandedYPos] = React.useState(null);
const isMobile = useIsMobile();
const isLargeScreen = useIsLargeScreen();
const initialLiveTileLimit = getTileLimit(isLargeScreen, DEFAULT_LIVESTREAM_TILE_LIMIT);
const [liveSection, setLiveSection] = React.useState(liveSectionStore || SECTION.COLLAPSED);
const livestreamUris = getLivestreamUris(activeLivestreams, channelIds);
const liveTilesOverLimit = livestreamUris && livestreamUris.length > initialLiveTileLimit;
function collapseSection() {
window.scrollTo(0, 0);
setLiveSection(SECTION.COLLAPSED);
}
React.useEffect(() => {
// Sync liveSection --> liveSectionStore
if (liveSection !== liveSectionStore) {
setLiveSectionStore(liveSection);
}
}, [liveSection, setLiveSectionStore, liveSectionStore]);
React.useEffect(() => {
// Fetch active livestreams on mount
const language = searchLanguages ? searchLanguages.join(',') : languageSetting;
const searchInSelectedLangOnly = Boolean(searchLanguages) || searchInLanguage;
const langCsv = resolveLangForClaimSearch(language, searchInSelectedLangOnly, langParam);
const lang = langCsv ? langCsv.split(',') : null;
doFetchActiveLivestreams(CS.ORDER_BY_NEW_VALUE, lang);
// eslint-disable-next-line react-hooks/exhaustive-deps, (on mount only)
}, []);
React.useEffect(() => {
// Maintain y-position when expanding livestreams section:
if (liveSection === SECTION.EXPANDED && expandedYPos !== null) {
window.scrollTo(0, expandedYPos);
setExpandedYPos(null);
}
}, [liveSection, expandedYPos]);
if (!livestreamUris || livestreamUris.length === 0) {
return null;
}
if (isMobile) {
return (
<div className="livestream-list">
<ClaimListDiscover
uris={livestreamUris}
tileLayout={livestreamUris.length > 1 ? true : tileLayout}
swipeLayout={livestreamUris.length > 1}
headerLabel={<div className="section__title">{__('Livestreams')}</div>}
useSkeletonScreen={false}
showHeader={false}
hideFilters
infiniteScroll={false}
loading={false}
showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS}
/>
</div>
);
}
return (
<div className="livestream-list">
{liveTilesOverLimit && liveSection === SECTION.EXPANDED && (
<div className="livestream-list--view-more">
<Button
label={__('Show less livestreams')}
button="link"
iconRight={ICONS.UP}
className="claim-grid__title--secondary"
onClick={collapseSection}
/>
</div>
)}
<ClaimListDiscover
uris={liveSection === SECTION.COLLAPSED ? livestreamUris.slice(0, initialLiveTileLimit) : livestreamUris}
tileLayout={tileLayout}
showHeader={false}
hideFilters
infiniteScroll={false}
loading={false}
showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS}
/>
{liveTilesOverLimit && liveSection === SECTION.COLLAPSED && (
<div className="livestream-list--view-more">
<Button
label={__('Show more livestreams')}
button="link"
iconRight={ICONS.DOWN}
className="claim-grid__title--secondary"
onClick={() => {
doFetchActiveLivestreams();
setExpandedYPos(window.scrollY);
setLiveSection(SECTION.EXPANDED);
}}
/>
</div>
)}
{liveTilesOverLimit && liveSection === SECTION.EXPANDED && (
<div className="livestream-list--view-more">
<Button
label={__('Show less livestreams')}
button="link"
iconRight={ICONS.UP}
className="claim-grid__title--secondary"
onClick={collapseSection}
/>
</div>
)}
</div>
);
}