Livestream category improvements #7115
8 changed files with 12 additions and 202 deletions
|
@ -1,12 +1,10 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import ClaimList from './view';
|
import ClaimList from './view';
|
||||||
import { SETTINGS, selectClaimSearchByQuery, selectClaimsByUri } from 'lbry-redux';
|
import { SETTINGS } from 'lbry-redux';
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
|
|
||||||
const select = (state) => ({
|
const select = (state) => ({
|
||||||
searchInLanguage: makeSelectClientSetting(SETTINGS.SEARCH_IN_LANGUAGE)(state),
|
searchInLanguage: makeSelectClientSetting(SETTINGS.SEARCH_IN_LANGUAGE)(state),
|
||||||
claimSearchByQuery: selectClaimSearchByQuery(state),
|
|
||||||
claimsByUri: selectClaimsByUri(state),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select)(ClaimList);
|
export default connect(select)(ClaimList);
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { FormField } from 'component/common/form';
|
||||||
import usePersistedState from 'effects/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
import debounce from 'util/debounce';
|
import debounce from 'util/debounce';
|
||||||
import ClaimPreviewTile from 'component/claimPreviewTile';
|
import ClaimPreviewTile from 'component/claimPreviewTile';
|
||||||
import { prioritizeActiveLivestreams } from 'component/claimTilesDiscover/view';
|
|
||||||
|
|
||||||
const DEBOUNCE_SCROLL_HANDLER_MS = 150;
|
const DEBOUNCE_SCROLL_HANDLER_MS = 150;
|
||||||
const SORT_NEW = 'new';
|
const SORT_NEW = 'new';
|
||||||
|
@ -41,9 +40,6 @@ type Props = {
|
||||||
hideMenu?: boolean,
|
hideMenu?: boolean,
|
||||||
claimSearchByQuery: { [string]: Array<string> },
|
claimSearchByQuery: { [string]: Array<string> },
|
||||||
claimsByUri: { [string]: any },
|
claimsByUri: { [string]: any },
|
||||||
liveLivestreamsFirst?: boolean,
|
|
||||||
livestreamMap?: { [string]: any },
|
|
||||||
searchOptions?: any,
|
|
||||||
collectionId?: string,
|
collectionId?: string,
|
||||||
showNoSourceClaims?: boolean,
|
showNoSourceClaims?: boolean,
|
||||||
onClick?: (e: any, claim?: ?Claim, index?: number) => void,
|
onClick?: (e: any, claim?: ?Claim, index?: number) => void,
|
||||||
|
@ -73,11 +69,6 @@ export default function ClaimList(props: Props) {
|
||||||
renderProperties,
|
renderProperties,
|
||||||
searchInLanguage,
|
searchInLanguage,
|
||||||
hideMenu,
|
hideMenu,
|
||||||
claimSearchByQuery,
|
|
||||||
claimsByUri,
|
|
||||||
liveLivestreamsFirst,
|
|
||||||
livestreamMap,
|
|
||||||
searchOptions,
|
|
||||||
collectionId,
|
collectionId,
|
||||||
showNoSourceClaims,
|
showNoSourceClaims,
|
||||||
onClick,
|
onClick,
|
||||||
|
@ -87,23 +78,11 @@ export default function ClaimList(props: Props) {
|
||||||
const timedOut = uris === null;
|
const timedOut = uris === null;
|
||||||
const urisLength = (uris && uris.length) || 0;
|
const urisLength = (uris && uris.length) || 0;
|
||||||
|
|
||||||
const liveUris = [];
|
|
||||||
if (liveLivestreamsFirst && livestreamMap) {
|
|
||||||
prioritizeActiveLivestreams(uris, liveUris, livestreamMap, claimsByUri, claimSearchByQuery, searchOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
const sortedUris = (urisLength > 0 && (currentSort === SORT_NEW ? uris : uris.slice().reverse())) || [];
|
const sortedUris = (urisLength > 0 && (currentSort === SORT_NEW ? uris : uris.slice().reverse())) || [];
|
||||||
const noResultMsg = searchInLanguage
|
const noResultMsg = searchInLanguage
|
||||||
? __('No results. Contents may be hidden by the Language filter.')
|
? __('No results. Contents may be hidden by the Language filter.')
|
||||||
: __('No results');
|
: __('No results');
|
||||||
|
|
||||||
const resolveLive = (index) => {
|
|
||||||
if (liveLivestreamsFirst && livestreamMap && index < liveUris.length) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
function handleSortChange() {
|
function handleSortChange() {
|
||||||
setCurrentSort(currentSort === SORT_NEW ? SORT_OLD : SORT_NEW);
|
setCurrentSort(currentSort === SORT_NEW ? SORT_OLD : SORT_NEW);
|
||||||
}
|
}
|
||||||
|
@ -138,13 +117,12 @@ export default function ClaimList(props: Props) {
|
||||||
return tileLayout && !header ? (
|
return tileLayout && !header ? (
|
||||||
<section className="claim-grid">
|
<section className="claim-grid">
|
||||||
{urisLength > 0 &&
|
{urisLength > 0 &&
|
||||||
uris.map((uri, index) => (
|
uris.map((uri) => (
|
||||||
<ClaimPreviewTile
|
<ClaimPreviewTile
|
||||||
key={uri}
|
key={uri}
|
||||||
uri={uri}
|
uri={uri}
|
||||||
showHiddenByUser={showHiddenByUser}
|
showHiddenByUser={showHiddenByUser}
|
||||||
properties={renderProperties}
|
properties={renderProperties}
|
||||||
live={resolveLive(index)}
|
|
||||||
collectionId={collectionId}
|
collectionId={collectionId}
|
||||||
showNoSourceClaims={showNoSourceClaims}
|
showNoSourceClaims={showNoSourceClaims}
|
||||||
/>
|
/>
|
||||||
|
@ -216,7 +194,6 @@ export default function ClaimList(props: Props) {
|
||||||
// https://github.com/lbryio/lbry-redux/blob/master/src/redux/actions/publish.js#L74-L79
|
// https://github.com/lbryio/lbry-redux/blob/master/src/redux/actions/publish.js#L74-L79
|
||||||
return claim.name.length === 24 && !claim.name.includes(' ') && claim.value.author === 'Spee.ch';
|
return claim.name.length === 24 && !claim.name.includes(' ') && claim.value.author === 'Spee.ch';
|
||||||
}}
|
}}
|
||||||
live={resolveLive(index)}
|
|
||||||
onClick={(e, claim, index) => handleClaimClicked(e, claim, index)}
|
onClick={(e, claim, index) => handleClaimClicked(e, claim, index)}
|
||||||
/>
|
/>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
|
|
|
@ -14,7 +14,6 @@ import ClaimPreviewTile from 'component/claimPreviewTile';
|
||||||
import I18nMessage from 'component/i18nMessage';
|
import I18nMessage from 'component/i18nMessage';
|
||||||
import ClaimListHeader from 'component/claimListHeader';
|
import ClaimListHeader from 'component/claimListHeader';
|
||||||
import { useIsLargeScreen } from 'effects/use-screensize';
|
import { useIsLargeScreen } from 'effects/use-screensize';
|
||||||
import { getLivestreamOnlyOptions } from 'util/search';
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uris: Array<string>,
|
uris: Array<string>,
|
||||||
|
@ -31,7 +30,6 @@ type Props = {
|
||||||
includeSupportAction?: boolean,
|
includeSupportAction?: boolean,
|
||||||
infiniteScroll?: Boolean,
|
infiniteScroll?: Boolean,
|
||||||
isChannel?: boolean,
|
isChannel?: boolean,
|
||||||
liveLivestreamsFirst?: boolean,
|
|
||||||
personalView: boolean,
|
personalView: boolean,
|
||||||
showHeader: boolean,
|
showHeader: boolean,
|
||||||
showHiddenByUser?: boolean,
|
showHiddenByUser?: boolean,
|
||||||
|
@ -64,7 +62,6 @@ type Props = {
|
||||||
channelIds?: Array<string>,
|
channelIds?: Array<string>,
|
||||||
claimIds?: Array<string>,
|
claimIds?: Array<string>,
|
||||||
subscribedChannels: Array<Subscription>,
|
subscribedChannels: Array<Subscription>,
|
||||||
livestreamMap?: { [string]: any },
|
|
||||||
|
|
||||||
header?: Node,
|
header?: Node,
|
||||||
headerLabel?: string | Node,
|
headerLabel?: string | Node,
|
||||||
|
@ -148,8 +145,6 @@ function ClaimListDiscover(props: Props) {
|
||||||
releaseTime,
|
releaseTime,
|
||||||
scrollAnchor,
|
scrollAnchor,
|
||||||
showHiddenByUser = false,
|
showHiddenByUser = false,
|
||||||
liveLivestreamsFirst,
|
|
||||||
livestreamMap,
|
|
||||||
hasSource,
|
hasSource,
|
||||||
hasNoSource,
|
hasNoSource,
|
||||||
isChannel = false,
|
isChannel = false,
|
||||||
|
@ -400,11 +395,6 @@ function ClaimListDiscover(props: Props) {
|
||||||
// claimSearchResult.splice(2, 0, fixUri);
|
// claimSearchResult.splice(2, 0, fixUri);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const livestreamSearchKey = liveLivestreamsFirst
|
|
||||||
? createNormalizedClaimSearchKey(getLivestreamOnlyOptions(options))
|
|
||||||
: undefined;
|
|
||||||
const livestreamSearchResult = livestreamSearchKey && claimSearchByQuery[livestreamSearchKey];
|
|
||||||
|
|
||||||
const [finalUris, setFinalUris] = React.useState(
|
const [finalUris, setFinalUris] = React.useState(
|
||||||
getFinalUrisInitialState(history.action === 'POP', claimSearchResult)
|
getFinalUrisInitialState(history.action === 'POP', claimSearchResult)
|
||||||
);
|
);
|
||||||
|
@ -571,10 +561,6 @@ function ClaimListDiscover(props: Props) {
|
||||||
if (shouldPerformSearch) {
|
if (shouldPerformSearch) {
|
||||||
const searchOptions = JSON.parse(optionsStringForEffect);
|
const searchOptions = JSON.parse(optionsStringForEffect);
|
||||||
doClaimSearch(searchOptions);
|
doClaimSearch(searchOptions);
|
||||||
|
|
||||||
if (liveLivestreamsFirst && options.page === 1) {
|
|
||||||
doClaimSearch(getLivestreamOnlyOptions(searchOptions));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, [doClaimSearch, shouldPerformSearch, optionsStringForEffect, forceRefresh]);
|
}, [doClaimSearch, shouldPerformSearch, optionsStringForEffect, forceRefresh]);
|
||||||
|
|
||||||
|
@ -586,12 +572,12 @@ function ClaimListDiscover(props: Props) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Wait until all queries are done before updating the uris to avoid layout shifts.
|
// Wait until all queries are done before updating the uris to avoid layout shifts.
|
||||||
const pending = claimSearchResult === undefined || (liveLivestreamsFirst && livestreamSearchResult === undefined);
|
const pending = claimSearchResult === undefined;
|
||||||
if (!pending && !urisEqual(claimSearchResult, finalUris)) {
|
if (!pending && !urisEqual(claimSearchResult, finalUris)) {
|
||||||
setFinalUris(claimSearchResult);
|
setFinalUris(claimSearchResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [uris, claimSearchResult, finalUris, setFinalUris, liveLivestreamsFirst, livestreamSearchResult]);
|
}, [uris, claimSearchResult, finalUris, setFinalUris]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (fetchViewCount) {
|
if (fetchViewCount) {
|
||||||
|
@ -645,8 +631,6 @@ function ClaimListDiscover(props: Props) {
|
||||||
includeSupportAction={includeSupportAction}
|
includeSupportAction={includeSupportAction}
|
||||||
injectedItem={injectedItem}
|
injectedItem={injectedItem}
|
||||||
showHiddenByUser={showHiddenByUser}
|
showHiddenByUser={showHiddenByUser}
|
||||||
liveLivestreamsFirst={liveLivestreamsFirst}
|
|
||||||
livestreamMap={livestreamMap}
|
|
||||||
searchOptions={options}
|
searchOptions={options}
|
||||||
showNoSourceClaims={showNoSourceClaims}
|
showNoSourceClaims={showNoSourceClaims}
|
||||||
empty={empty}
|
empty={empty}
|
||||||
|
@ -679,8 +663,6 @@ function ClaimListDiscover(props: Props) {
|
||||||
includeSupportAction={includeSupportAction}
|
includeSupportAction={includeSupportAction}
|
||||||
injectedItem={injectedItem}
|
injectedItem={injectedItem}
|
||||||
showHiddenByUser={showHiddenByUser}
|
showHiddenByUser={showHiddenByUser}
|
||||||
liveLivestreamsFirst={liveLivestreamsFirst}
|
|
||||||
livestreamMap={livestreamMap}
|
|
||||||
searchOptions={options}
|
searchOptions={options}
|
||||||
showNoSourceClaims={hasNoSource || showNoSourceClaims}
|
showNoSourceClaims={hasNoSource || showNoSourceClaims}
|
||||||
empty={empty}
|
empty={empty}
|
||||||
|
|
|
@ -6,90 +6,11 @@ import React from 'react';
|
||||||
import { createNormalizedClaimSearchKey, MATURE_TAGS, splitBySeparator } from 'lbry-redux';
|
import { createNormalizedClaimSearchKey, MATURE_TAGS, splitBySeparator } from 'lbry-redux';
|
||||||
import ClaimPreviewTile from 'component/claimPreviewTile';
|
import ClaimPreviewTile from 'component/claimPreviewTile';
|
||||||
import { useHistory } from 'react-router';
|
import { useHistory } from 'react-router';
|
||||||
import { getLivestreamOnlyOptions } from 'util/search';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates 'uris' by adding and/or moving active livestreams to the front of
|
|
||||||
* list.
|
|
||||||
* 'liveUris' is also updated with any entries that were moved to the
|
|
||||||
* front, for convenience.
|
|
||||||
*
|
|
||||||
* @param uris [Ref]
|
|
||||||
* @param liveUris [Ref]
|
|
||||||
* @param livestreamMap
|
|
||||||
* @param claimsByUri
|
|
||||||
* @param claimSearchByQuery
|
|
||||||
* @param options
|
|
||||||
*/
|
|
||||||
export function prioritizeActiveLivestreams(
|
|
||||||
uris: Array<string>,
|
|
||||||
liveUris: Array<string>,
|
|
||||||
livestreamMap: { [string]: any },
|
|
||||||
claimsByUri: { [string]: any },
|
|
||||||
claimSearchByQuery: { [string]: Array<string> },
|
|
||||||
options: any
|
|
||||||
) {
|
|
||||||
if (!livestreamMap || !uris) return;
|
|
||||||
|
|
||||||
const claimIsLive = (claim, liveChannelIds) => {
|
|
||||||
// This function relies on:
|
|
||||||
// 1. Only 1 actual livestream per channel (i.e. all other livestream-claims
|
|
||||||
// for that channel actually point to the same source).
|
|
||||||
// 2. 'liveChannelIds' needs to be pruned after being accounted for,
|
|
||||||
// otherwise all livestream-claims will be "live" (we'll only take the
|
|
||||||
// latest one as "live" ).
|
|
||||||
return (
|
|
||||||
claim &&
|
|
||||||
claim.value_type === 'stream' &&
|
|
||||||
claim.value.source === undefined &&
|
|
||||||
claim.signing_channel &&
|
|
||||||
liveChannelIds.includes(claim.signing_channel.claim_id)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
let liveChannelIds = Object.keys(livestreamMap);
|
|
||||||
|
|
||||||
// 1. Collect active livestreams from the primary search to put in front.
|
|
||||||
uris.forEach((uri) => {
|
|
||||||
const claim = claimsByUri[uri];
|
|
||||||
if (claimIsLive(claim, liveChannelIds)) {
|
|
||||||
liveUris.push(uri);
|
|
||||||
// This live channel has been accounted for, so remove it.
|
|
||||||
liveChannelIds.splice(liveChannelIds.indexOf(claim.signing_channel.claim_id), 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 2. Now, repeat on the secondary search.
|
|
||||||
if (options) {
|
|
||||||
const livestreamsOnlySearchCacheQuery = createNormalizedClaimSearchKey(getLivestreamOnlyOptions(options));
|
|
||||||
const livestreamsOnlyUris = claimSearchByQuery[livestreamsOnlySearchCacheQuery];
|
|
||||||
if (livestreamsOnlyUris) {
|
|
||||||
livestreamsOnlyUris.forEach((uri) => {
|
|
||||||
const claim = claimsByUri[uri];
|
|
||||||
if (!uris.includes(uri) && claimIsLive(claim, liveChannelIds)) {
|
|
||||||
liveUris.push(uri);
|
|
||||||
// This live channel has been accounted for, so remove it.
|
|
||||||
liveChannelIds.splice(liveChannelIds.indexOf(claim.signing_channel.claim_id), 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Finalize uris by putting live livestreams in front.
|
|
||||||
const newUris = liveUris.concat(uris.filter((uri) => !liveUris.includes(uri)));
|
|
||||||
uris.splice(0, uris.length, ...newUris);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ****************************************************************************
|
|
||||||
// ClaimTilesDiscover
|
|
||||||
// ****************************************************************************
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
prefixUris?: Array<string>,
|
prefixUris?: Array<string>,
|
||||||
pinUrls?: Array<string>,
|
pinUrls?: Array<string>,
|
||||||
uris: Array<string>,
|
uris: Array<string>,
|
||||||
liveLivestreamsFirst?: boolean,
|
|
||||||
livestreamMap?: { [string]: any },
|
|
||||||
showNoSourceClaims?: boolean,
|
showNoSourceClaims?: boolean,
|
||||||
renderProperties?: (Claim) => ?Node,
|
renderProperties?: (Claim) => ?Node,
|
||||||
fetchViewCount?: boolean,
|
fetchViewCount?: boolean,
|
||||||
|
@ -148,8 +69,6 @@ function ClaimTilesDiscover(props: Props) {
|
||||||
renderProperties,
|
renderProperties,
|
||||||
blockedUris,
|
blockedUris,
|
||||||
mutedUris,
|
mutedUris,
|
||||||
liveLivestreamsFirst,
|
|
||||||
livestreamMap,
|
|
||||||
pinUrls,
|
pinUrls,
|
||||||
prefixUris,
|
prefixUris,
|
||||||
showNoSourceClaims,
|
showNoSourceClaims,
|
||||||
|
@ -163,7 +82,7 @@ function ClaimTilesDiscover(props: Props) {
|
||||||
const mutedAndBlockedChannelIds = Array.from(
|
const mutedAndBlockedChannelIds = Array.from(
|
||||||
new Set(mutedUris.concat(blockedUris).map((uri) => splitBySeparator(uri)[1]))
|
new Set(mutedUris.concat(blockedUris).map((uri) => splitBySeparator(uri)[1]))
|
||||||
);
|
);
|
||||||
const liveUris = [];
|
|
||||||
let streamTypesParam;
|
let streamTypesParam;
|
||||||
if (streamTypes) {
|
if (streamTypes) {
|
||||||
streamTypesParam = streamTypes;
|
streamTypesParam = streamTypes;
|
||||||
|
@ -245,28 +164,16 @@ function ClaimTilesDiscover(props: Props) {
|
||||||
options.claim_ids = claimIds;
|
options.claim_ids = claimIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mainSearchKey = createNormalizedClaimSearchKey(options);
|
const searchKey = createNormalizedClaimSearchKey(options);
|
||||||
const livestreamSearchKey = liveLivestreamsFirst
|
const isLoading = fetchingClaimSearchByQuery[searchKey];
|
||||||
? createNormalizedClaimSearchKey(getLivestreamOnlyOptions(options))
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
let uris = (prefixUris || []).concat(claimSearchByQuery[mainSearchKey] || []);
|
let uris = (prefixUris || []).concat(claimSearchByQuery[searchKey] || []);
|
||||||
|
|
||||||
const isLoading = fetchingClaimSearchByQuery[mainSearchKey];
|
|
||||||
|
|
||||||
if (liveLivestreamsFirst && livestreamMap && !isLoading) {
|
|
||||||
prioritizeActiveLivestreams(uris, liveUris, livestreamMap, claimsByUri, claimSearchByQuery, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't use the query from createNormalizedClaimSearchKey for the effect since that doesn't include page & release_time
|
// Don't use the query from createNormalizedClaimSearchKey for the effect since that doesn't include page & release_time
|
||||||
const optionsStringForEffect = JSON.stringify(options);
|
const optionsStringForEffect = JSON.stringify(options);
|
||||||
const shouldPerformSearch = !isLoading && uris.length === 0;
|
const shouldPerformSearch = !isLoading && uris.length === 0;
|
||||||
|
|
||||||
if (
|
if (prefixUris === undefined && claimSearchByQuery[searchKey] === undefined) {
|
||||||
prefixUris === undefined &&
|
|
||||||
(claimSearchByQuery[mainSearchKey] === undefined ||
|
|
||||||
(livestreamSearchKey && claimSearchByQuery[livestreamSearchKey] === undefined))
|
|
||||||
) {
|
|
||||||
// This is a new query and we don't have results yet ...
|
// This is a new query and we don't have results yet ...
|
||||||
if (prevUris.length !== 0) {
|
if (prevUris.length !== 0) {
|
||||||
// ... but we have previous results. Use it until new results are here.
|
// ... but we have previous results. Use it until new results are here.
|
||||||
|
@ -288,16 +195,6 @@ function ClaimTilesDiscover(props: Props) {
|
||||||
modifiedUris.splice(2, 0, ...fixUris);
|
modifiedUris.splice(2, 0, ...fixUris);
|
||||||
}
|
}
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
function resolveLive(index) {
|
|
||||||
if (liveLivestreamsFirst && livestreamMap && index < liveUris.length) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fetchViewCountForUris(uris) {
|
function fetchViewCountForUris(uris) {
|
||||||
const claimIds = [];
|
const claimIds = [];
|
||||||
|
|
||||||
|
@ -314,19 +211,12 @@ function ClaimTilesDiscover(props: Props) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (shouldPerformSearch) {
|
if (shouldPerformSearch) {
|
||||||
const searchOptions = JSON.parse(optionsStringForEffect);
|
const searchOptions = JSON.parse(optionsStringForEffect);
|
||||||
doClaimSearch(searchOptions);
|
doClaimSearch(searchOptions);
|
||||||
|
|
||||||
if (liveLivestreamsFirst) {
|
|
||||||
doClaimSearch(getLivestreamOnlyOptions(searchOptions));
|
|
||||||
}
|
}
|
||||||
}
|
}, [doClaimSearch, shouldPerformSearch, optionsStringForEffect]);
|
||||||
}, [doClaimSearch, shouldPerformSearch, optionsStringForEffect, liveLivestreamsFirst]);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (JSON.stringify(prevUris) !== JSON.stringify(uris) && !shouldPerformSearch) {
|
if (JSON.stringify(prevUris) !== JSON.stringify(uris) && !shouldPerformSearch) {
|
||||||
|
@ -345,13 +235,12 @@ function ClaimTilesDiscover(props: Props) {
|
||||||
return (
|
return (
|
||||||
<ul className="claim-grid">
|
<ul className="claim-grid">
|
||||||
{modifiedUris && modifiedUris.length
|
{modifiedUris && modifiedUris.length
|
||||||
? modifiedUris.map((uri, index) => (
|
? modifiedUris.map((uri) => (
|
||||||
<ClaimPreviewTile
|
<ClaimPreviewTile
|
||||||
showNoSourceClaims={hasNoSource || showNoSourceClaims}
|
showNoSourceClaims={hasNoSource || showNoSourceClaims}
|
||||||
key={uri}
|
key={uri}
|
||||||
uri={uri}
|
uri={uri}
|
||||||
properties={renderProperties}
|
properties={renderProperties}
|
||||||
live={resolveLive(index)}
|
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
: new Array(pageSize)
|
: new Array(pageSize)
|
||||||
|
|
|
@ -9,7 +9,6 @@ import ClaimListDiscover from 'component/claimListDiscover';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import useGetLivestreams from 'effects/use-get-livestreams';
|
|
||||||
import { splitBySeparator } from 'lbry-redux';
|
import { splitBySeparator } from 'lbry-redux';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -20,7 +19,6 @@ type Props = {
|
||||||
function ChannelsFollowingPage(props: Props) {
|
function ChannelsFollowingPage(props: Props) {
|
||||||
const { subscribedChannels, tileLayout } = props;
|
const { subscribedChannels, tileLayout } = props;
|
||||||
const hasSubsribedChannels = subscribedChannels.length > 0;
|
const hasSubsribedChannels = subscribedChannels.length > 0;
|
||||||
const { livestreamMap } = useGetLivestreams();
|
|
||||||
|
|
||||||
return !hasSubsribedChannels ? (
|
return !hasSubsribedChannels ? (
|
||||||
<ChannelsFollowingDiscoverPage />
|
<ChannelsFollowingDiscoverPage />
|
||||||
|
@ -46,8 +44,6 @@ function ChannelsFollowingPage(props: Props) {
|
||||||
navigate={`/$/${PAGES.CHANNELS_FOLLOWING_DISCOVER}`}
|
navigate={`/$/${PAGES.CHANNELS_FOLLOWING_DISCOVER}`}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
liveLivestreamsFirst
|
|
||||||
livestreamMap={livestreamMap}
|
|
||||||
showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS}
|
showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS}
|
||||||
hasSource
|
hasSource
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -15,7 +15,6 @@ import Icon from 'component/common/icon';
|
||||||
import Ads from 'web/component/ads';
|
import Ads from 'web/component/ads';
|
||||||
import LbcSymbol from 'component/common/lbc-symbol';
|
import LbcSymbol from 'component/common/lbc-symbol';
|
||||||
import I18nMessage from 'component/i18nMessage';
|
import I18nMessage from 'component/i18nMessage';
|
||||||
import useGetLivestreams from 'effects/use-get-livestreams';
|
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -45,7 +44,6 @@ function DiscoverPage(props: Props) {
|
||||||
const buttonRef = useRef();
|
const buttonRef = useRef();
|
||||||
const isHovering = useHover(buttonRef);
|
const isHovering = useHover(buttonRef);
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const { livestreamMap } = useGetLivestreams();
|
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(search);
|
const urlParams = new URLSearchParams(search);
|
||||||
const claimType = urlParams.get('claim_type');
|
const claimType = urlParams.get('claim_type');
|
||||||
|
@ -172,8 +170,6 @@ function DiscoverPage(props: Props) {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
liveLivestreamsFirst
|
|
||||||
livestreamMap={livestreamMap}
|
|
||||||
hasSource
|
hasSource
|
||||||
showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS}
|
showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -9,7 +9,6 @@ import ClaimTilesDiscover from 'component/claimTilesDiscover';
|
||||||
import ClaimPreviewTile from 'component/claimPreviewTile';
|
import ClaimPreviewTile from 'component/claimPreviewTile';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import WaitUntilOnPage from 'component/common/wait-until-on-page';
|
import WaitUntilOnPage from 'component/common/wait-until-on-page';
|
||||||
import useGetLivestreams from 'effects/use-get-livestreams';
|
|
||||||
import { GetLinksData } from 'util/buildHomepage';
|
import { GetLinksData } from 'util/buildHomepage';
|
||||||
|
|
||||||
// @if TARGET='web'
|
// @if TARGET='web'
|
||||||
|
@ -30,7 +29,6 @@ function HomePage(props: Props) {
|
||||||
const showPersonalizedChannels = (authenticated || !IS_WEB) && subscribedChannels && subscribedChannels.length > 0;
|
const showPersonalizedChannels = (authenticated || !IS_WEB) && subscribedChannels && subscribedChannels.length > 0;
|
||||||
const showPersonalizedTags = (authenticated || !IS_WEB) && followedTags && followedTags.length > 0;
|
const showPersonalizedTags = (authenticated || !IS_WEB) && followedTags && followedTags.length > 0;
|
||||||
const showIndividualTags = showPersonalizedTags && followedTags.length < 5;
|
const showIndividualTags = showPersonalizedTags && followedTags.length < 5;
|
||||||
const { livestreamMap } = useGetLivestreams();
|
|
||||||
|
|
||||||
const rowData: Array<RowDataItem> = GetLinksData(
|
const rowData: Array<RowDataItem> = GetLinksData(
|
||||||
homepageData,
|
homepageData,
|
||||||
|
@ -53,14 +51,7 @@ function HomePage(props: Props) {
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
const claimTiles = (
|
const claimTiles = (
|
||||||
<ClaimTilesDiscover
|
<ClaimTilesDiscover {...options} showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS} hasSource pinUrls={pinUrls} />
|
||||||
{...options}
|
|
||||||
liveLivestreamsFirst
|
|
||||||
livestreamMap={livestreamMap}
|
|
||||||
showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS}
|
|
||||||
hasSource
|
|
||||||
pinUrls={pinUrls}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -21,25 +21,6 @@ export function createNormalizedSearchKey(query: string) {
|
||||||
return normalizedQuery;
|
return normalizedQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the "livestream only" version of the given 'options'.
|
|
||||||
*
|
|
||||||
* Currently, the 'has_source' attribute is being used to identify livestreams.
|
|
||||||
*
|
|
||||||
* @param options
|
|
||||||
* @returns {*}
|
|
||||||
*/
|
|
||||||
export function getLivestreamOnlyOptions(options: any) {
|
|
||||||
const newOptions = Object.assign({}, options);
|
|
||||||
delete newOptions.has_source;
|
|
||||||
delete newOptions.stream_types;
|
|
||||||
newOptions.has_no_source = true;
|
|
||||||
newOptions.claim_type = ['stream'];
|
|
||||||
newOptions.page_size = 50;
|
|
||||||
newOptions.order_by = ['release_time'];
|
|
||||||
return newOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getUriForSearchTerm
|
* getUriForSearchTerm
|
||||||
* @param term
|
* @param term
|
||||||
|
|
Loading…
Reference in a new issue