Add persistence to live tile expansion in Wild West (#398)
* Discover: add persistence to the livestream section's fold state The persisted value should only apply when livestream section is needed, hence the need for 2 state variables. Also renamed the variables for clarity. * Discover: add "show less livestreams" at upper-right Wanted to put it as an injected tile, but requires more work to do it in a general-purpose way, as opposed to a hardcoded way like how ads are currently injected. It also needs to work on both Tile and List format. So ... just place the button at the upper-right for now. Although a bit odd, at least it'll be a consistent place (i.e. position won't be affected by live tile count).
This commit is contained in:
parent
dd96d1222d
commit
935eaa6edb
1 changed files with 46 additions and 20 deletions
|
@ -3,12 +3,13 @@ import { SHOW_ADS, DOMAIN, SIMPLE_SITE, ENABLE_NO_SOURCE_CLAIMS } from 'config';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import * as PAGES from 'constants/pages';
|
import * as PAGES from 'constants/pages';
|
||||||
import * as CS from 'constants/claim_search';
|
import * as CS from 'constants/claim_search';
|
||||||
import React, { useRef } from 'react';
|
import React, { useState, useRef } from 'react';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import ClaimListDiscover from 'component/claimListDiscover';
|
import ClaimListDiscover from 'component/claimListDiscover';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import useHover from 'effects/use-hover';
|
import useHover from 'effects/use-hover';
|
||||||
import { useIsMobile, useIsLargeScreen } from 'effects/use-screensize';
|
import { useIsMobile, useIsLargeScreen } from 'effects/use-screensize';
|
||||||
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
import analytics from 'analytics';
|
import analytics from 'analytics';
|
||||||
import HiddenNsfw from 'component/common/hidden-nsfw';
|
import HiddenNsfw from 'component/common/hidden-nsfw';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
|
@ -20,6 +21,12 @@ import { getLivestreamUris } from 'util/livestream';
|
||||||
|
|
||||||
const DEFAULT_LIVESTREAM_TILE_LIMIT = 8;
|
const DEFAULT_LIVESTREAM_TILE_LIMIT = 8;
|
||||||
|
|
||||||
|
const SECTION = {
|
||||||
|
HIDDEN: 0,
|
||||||
|
LESS: 1,
|
||||||
|
MORE: 2,
|
||||||
|
};
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
location: { search: string },
|
location: { search: string },
|
||||||
followedTags: Array<Tag>,
|
followedTags: Array<Tag>,
|
||||||
|
@ -48,6 +55,9 @@ function DiscoverPage(props: Props) {
|
||||||
doFetchActiveLivestreams,
|
doFetchActiveLivestreams,
|
||||||
dynamicRouteProps,
|
dynamicRouteProps,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const [liveSectionStore, setLiveSectionStore] = usePersistedState('discover:liveSection', SECTION.LESS);
|
||||||
|
|
||||||
const buttonRef = useRef();
|
const buttonRef = useRef();
|
||||||
const isHovering = useHover(buttonRef);
|
const isHovering = useHover(buttonRef);
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
@ -73,27 +83,33 @@ function DiscoverPage(props: Props) {
|
||||||
label = __('Unfollow');
|
label = __('Unfollow');
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialLivestreamTileLimit = getPageSize(DEFAULT_LIVESTREAM_TILE_LIMIT);
|
const initialLiveTileLimit = getPageSize(DEFAULT_LIVESTREAM_TILE_LIMIT);
|
||||||
|
|
||||||
const showLivestreams = window.location.pathname === `/$/${PAGES.WILD_WEST}`;
|
const includeLivestreams = window.location.pathname === `/$/${PAGES.WILD_WEST}`;
|
||||||
const [showViewMoreLivestreams, setShowViewMoreLivestreams] = React.useState(showLivestreams);
|
const [liveSection, setLiveSection] = useState(includeLivestreams ? liveSectionStore : SECTION.HIDDEN);
|
||||||
const livestreamUris = showLivestreams && getLivestreamUris(activeLivestreams, channelIds);
|
const livestreamUris = includeLivestreams && getLivestreamUris(activeLivestreams, channelIds);
|
||||||
const useDualList = showViewMoreLivestreams && livestreamUris && livestreamUris.length > initialLivestreamTileLimit;
|
const useDualList = liveSection === SECTION.LESS && livestreamUris && livestreamUris.length > initialLiveTileLimit;
|
||||||
|
|
||||||
|
function getMeta() {
|
||||||
|
if (liveSection === SECTION.MORE) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
label={__('Show less livestreams')}
|
||||||
|
button="link"
|
||||||
|
iconRight={ICONS.UP}
|
||||||
|
className="claim-grid__title--secondary"
|
||||||
|
onClick={() => setLiveSection(SECTION.LESS)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function getElemMeta() {
|
|
||||||
return !dynamicRouteProps ? (
|
return !dynamicRouteProps ? (
|
||||||
<a
|
<a
|
||||||
className="help"
|
className="help"
|
||||||
href="https://odysee.com/@OdyseeHelp:b/trending:50"
|
href="https://odysee.com/@OdyseeHelp:b/trending:50"
|
||||||
title={__('Learn more about Credits on %DOMAIN%', { DOMAIN })}
|
title={__('Learn more about Credits on %DOMAIN%', { DOMAIN })}
|
||||||
>
|
>
|
||||||
<I18nMessage
|
<I18nMessage tokens={{ lbc: <LbcSymbol /> }}>Results boosted by %lbc%</I18nMessage>
|
||||||
tokens={{
|
|
||||||
lbc: <LbcSymbol />,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Results boosted by %lbc%
|
|
||||||
</I18nMessage>
|
|
||||||
</a>
|
</a>
|
||||||
) : (
|
) : (
|
||||||
tag && !isMobile && (
|
tag && !isMobile && (
|
||||||
|
@ -155,12 +171,22 @@ function DiscoverPage(props: Props) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync liveSection --> liveSectionStore
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (showViewMoreLivestreams) {
|
if (liveSection !== SECTION.HIDDEN && liveSection !== liveSectionStore) {
|
||||||
|
setLiveSectionStore(liveSection);
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [liveSection]);
|
||||||
|
|
||||||
|
// Fetch active livestreams on mount
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (liveSection === SECTION.LESS) {
|
||||||
doFetchActiveLivestreams(CS.ORDER_BY_TRENDING_VALUE);
|
doFetchActiveLivestreams(CS.ORDER_BY_TRENDING_VALUE);
|
||||||
} else {
|
} else {
|
||||||
doFetchActiveLivestreams();
|
doFetchActiveLivestreams();
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps, (on mount only)
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -168,7 +194,7 @@ function DiscoverPage(props: Props) {
|
||||||
{useDualList && (
|
{useDualList && (
|
||||||
<>
|
<>
|
||||||
<ClaimListDiscover
|
<ClaimListDiscover
|
||||||
uris={livestreamUris && livestreamUris.slice(0, initialLivestreamTileLimit)}
|
uris={livestreamUris && livestreamUris.slice(0, initialLiveTileLimit)}
|
||||||
headerLabel={headerLabel}
|
headerLabel={headerLabel}
|
||||||
header={repostedUri ? <span /> : undefined}
|
header={repostedUri ? <span /> : undefined}
|
||||||
tileLayout={repostedUri ? false : tileLayout}
|
tileLayout={repostedUri ? false : tileLayout}
|
||||||
|
@ -177,17 +203,17 @@ function DiscoverPage(props: Props) {
|
||||||
infiniteScroll={false}
|
infiniteScroll={false}
|
||||||
loading={false}
|
loading={false}
|
||||||
showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS}
|
showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS}
|
||||||
meta={getElemMeta()}
|
meta={getMeta()}
|
||||||
/>
|
/>
|
||||||
<div className="livestream-list--view-more">
|
<div className="livestream-list--view-more">
|
||||||
<Button
|
<Button
|
||||||
label={__('Show more livestreams')}
|
label={__('Show more livestreams')}
|
||||||
button="link"
|
button="link"
|
||||||
iconRight={ICONS.ARROW_RIGHT}
|
iconRight={ICONS.DOWN}
|
||||||
className="claim-grid__title--secondary"
|
className="claim-grid__title--secondary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
doFetchActiveLivestreams();
|
doFetchActiveLivestreams();
|
||||||
setShowViewMoreLivestreams(false);
|
setLiveSection(SECTION.MORE);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -227,7 +253,7 @@ function DiscoverPage(props: Props) {
|
||||||
undefined
|
undefined
|
||||||
: 3
|
: 3
|
||||||
}
|
}
|
||||||
meta={!useDualList && getElemMeta()}
|
meta={!useDualList && getMeta()}
|
||||||
hasSource
|
hasSource
|
||||||
showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS}
|
showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS}
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in a new issue