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:
infinite-persistence 2021-12-01 06:36:35 -08:00 committed by GitHub
parent dd96d1222d
commit 935eaa6edb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -3,12 +3,13 @@ import { SHOW_ADS, DOMAIN, SIMPLE_SITE, ENABLE_NO_SOURCE_CLAIMS } from 'config';
import * as ICONS from 'constants/icons';
import * as PAGES from 'constants/pages';
import * as CS from 'constants/claim_search';
import React, { useRef } from 'react';
import React, { useState, useRef } from 'react';
import Page from 'component/page';
import ClaimListDiscover from 'component/claimListDiscover';
import Button from 'component/button';
import useHover from 'effects/use-hover';
import { useIsMobile, useIsLargeScreen } from 'effects/use-screensize';
import usePersistedState from 'effects/use-persisted-state';
import analytics from 'analytics';
import HiddenNsfw from 'component/common/hidden-nsfw';
import Icon from 'component/common/icon';
@ -20,6 +21,12 @@ import { getLivestreamUris } from 'util/livestream';
const DEFAULT_LIVESTREAM_TILE_LIMIT = 8;
const SECTION = {
HIDDEN: 0,
LESS: 1,
MORE: 2,
};
type Props = {
location: { search: string },
followedTags: Array<Tag>,
@ -48,6 +55,9 @@ function DiscoverPage(props: Props) {
doFetchActiveLivestreams,
dynamicRouteProps,
} = props;
const [liveSectionStore, setLiveSectionStore] = usePersistedState('discover:liveSection', SECTION.LESS);
const buttonRef = useRef();
const isHovering = useHover(buttonRef);
const isMobile = useIsMobile();
@ -73,27 +83,33 @@ function DiscoverPage(props: Props) {
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 [showViewMoreLivestreams, setShowViewMoreLivestreams] = React.useState(showLivestreams);
const livestreamUris = showLivestreams && getLivestreamUris(activeLivestreams, channelIds);
const useDualList = showViewMoreLivestreams && livestreamUris && livestreamUris.length > initialLivestreamTileLimit;
const includeLivestreams = window.location.pathname === `/$/${PAGES.WILD_WEST}`;
const [liveSection, setLiveSection] = useState(includeLivestreams ? liveSectionStore : SECTION.HIDDEN);
const livestreamUris = includeLivestreams && getLivestreamUris(activeLivestreams, channelIds);
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 ? (
<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>
<I18nMessage tokens={{ lbc: <LbcSymbol /> }}>Results boosted by %lbc%</I18nMessage>
</a>
) : (
tag && !isMobile && (
@ -155,12 +171,22 @@ function DiscoverPage(props: Props) {
);
}
// Sync liveSection --> liveSectionStore
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);
} else {
doFetchActiveLivestreams();
}
// eslint-disable-next-line react-hooks/exhaustive-deps, (on mount only)
}, []);
return (
@ -168,7 +194,7 @@ function DiscoverPage(props: Props) {
{useDualList && (
<>
<ClaimListDiscover
uris={livestreamUris && livestreamUris.slice(0, initialLivestreamTileLimit)}
uris={livestreamUris && livestreamUris.slice(0, initialLiveTileLimit)}
headerLabel={headerLabel}
header={repostedUri ? <span /> : undefined}
tileLayout={repostedUri ? false : tileLayout}
@ -177,17 +203,17 @@ function DiscoverPage(props: Props) {
infiniteScroll={false}
loading={false}
showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS}
meta={getElemMeta()}
meta={getMeta()}
/>
<div className="livestream-list--view-more">
<Button
label={__('Show more livestreams')}
button="link"
iconRight={ICONS.ARROW_RIGHT}
iconRight={ICONS.DOWN}
className="claim-grid__title--secondary"
onClick={() => {
doFetchActiveLivestreams();
setShowViewMoreLivestreams(false);
setLiveSection(SECTION.MORE);
}}
/>
</div>
@ -227,7 +253,7 @@ function DiscoverPage(props: Props) {
undefined
: 3
}
meta={!useDualList && getElemMeta()}
meta={!useDualList && getMeta()}
hasSource
showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS}
/>