Livestream category improvements #7115

Merged
infinite-persistence merged 15 commits from ip/category.livestream into master 2021-09-24 16:26:22 +02:00
6 changed files with 66 additions and 10 deletions
Showing only changes of commit dcb44e647d - Show all commits

View file

@ -1,13 +1,18 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { SETTINGS } from 'lbry-redux'; import { SETTINGS } from 'lbry-redux';
import { doFetchActiveLivestreams } from 'redux/actions/livestream';
import { selectActiveLivestreams } from 'redux/selectors/livestream';
import { selectSubscriptions } from 'redux/selectors/subscriptions'; import { selectSubscriptions } from 'redux/selectors/subscriptions';
import { makeSelectClientSetting } from 'redux/selectors/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings';
import ChannelsFollowingPage from './view'; import ChannelsFollowingPage from './view';
const select = state => ({ const select = (state) => ({
subscribedChannels: selectSubscriptions(state), subscribedChannels: selectSubscriptions(state),
tileLayout: makeSelectClientSetting(SETTINGS.TILE_LAYOUT)(state), tileLayout: makeSelectClientSetting(SETTINGS.TILE_LAYOUT)(state),
activeLivestreams: selectActiveLivestreams(state),
}); });
export default connect(select)(ChannelsFollowingPage); export default connect(select, {
doFetchActiveLivestreams,
})(ChannelsFollowingPage);

View file

@ -10,21 +10,31 @@ 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 { splitBySeparator } from 'lbry-redux'; import { splitBySeparator } from 'lbry-redux';
import { getLivestreamUris } from 'util/livestream';
type Props = { type Props = {
subscribedChannels: Array<Subscription>, subscribedChannels: Array<Subscription>,
tileLayout: boolean, tileLayout: boolean,
activeLivestreams: ?LivestreamInfo,
doFetchActiveLivestreams: () => void,
}; };
function ChannelsFollowingPage(props: Props) { function ChannelsFollowingPage(props: Props) {
const { subscribedChannels, tileLayout } = props; const { subscribedChannels, tileLayout, activeLivestreams, doFetchActiveLivestreams } = props;
const hasSubsribedChannels = subscribedChannels.length > 0; const hasSubsribedChannels = subscribedChannels.length > 0;
const channelIds = subscribedChannels.map((sub) => splitBySeparator(sub.uri)[1]);
React.useEffect(() => {
doFetchActiveLivestreams();
}, []);
return !hasSubsribedChannels ? ( return !hasSubsribedChannels ? (
<ChannelsFollowingDiscoverPage /> <ChannelsFollowingDiscoverPage />
) : ( ) : (
<Page noFooter fullWidthPage={tileLayout}> <Page noFooter fullWidthPage={tileLayout}>
<ClaimListDiscover <ClaimListDiscover
prefixUris={getLivestreamUris(activeLivestreams, channelIds)}
hideAdvancedFilter={SIMPLE_SITE} hideAdvancedFilter={SIMPLE_SITE}
streamType={SIMPLE_SITE ? CS.CONTENT_ALL : undefined} streamType={SIMPLE_SITE ? CS.CONTENT_ALL : undefined}
tileLayout={tileLayout} tileLayout={tileLayout}
@ -35,7 +45,7 @@ function ChannelsFollowingPage(props: Props) {
</span> </span>
} }
defaultOrderBy={CS.ORDER_BY_NEW} defaultOrderBy={CS.ORDER_BY_NEW}
channelIds={subscribedChannels.map((sub) => splitBySeparator(sub.uri)[1])} channelIds={channelIds}
meta={ meta={
<Button <Button
icon={ICONS.SEARCH} icon={ICONS.SEARCH}

View file

@ -1,6 +1,8 @@
import * as CS from 'constants/claim_search'; import * as CS from 'constants/claim_search';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectClaimForUri, doResolveUri, SETTINGS } from 'lbry-redux'; import { makeSelectClaimForUri, doResolveUri, SETTINGS } from 'lbry-redux';
import { doFetchActiveLivestreams } from 'redux/actions/livestream';
import { selectActiveLivestreams } from 'redux/selectors/livestream';
import { selectUserVerifiedEmail } from 'redux/selectors/user'; import { selectUserVerifiedEmail } from 'redux/selectors/user';
import { selectFollowedTags } from 'redux/selectors/tags'; import { selectFollowedTags } from 'redux/selectors/tags';
import { doToggleTagFollowDesktop } from 'redux/actions/tags'; import { doToggleTagFollowDesktop } from 'redux/actions/tags';
@ -18,10 +20,12 @@ const select = (state, props) => {
repostedClaim: repostedUri ? makeSelectClaimForUri(repostedUri)(state) : null, repostedClaim: repostedUri ? makeSelectClaimForUri(repostedUri)(state) : null,
isAuthenticated: selectUserVerifiedEmail(state), isAuthenticated: selectUserVerifiedEmail(state),
tileLayout: makeSelectClientSetting(SETTINGS.TILE_LAYOUT)(state), tileLayout: makeSelectClientSetting(SETTINGS.TILE_LAYOUT)(state),
activeLivestreams: selectActiveLivestreams(state),
}; };
}; };
export default connect(select, { export default connect(select, {
doToggleTagFollowDesktop, doToggleTagFollowDesktop,
doResolveUri, doResolveUri,
doFetchActiveLivestreams,
})(Tags); })(Tags);

View file

@ -16,6 +16,7 @@ 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 moment from 'moment'; import moment from 'moment';
import { getLivestreamUris } from 'util/livestream';
type Props = { type Props = {
location: { search: string }, location: { search: string },
@ -27,6 +28,8 @@ type Props = {
isAuthenticated: boolean, isAuthenticated: boolean,
dynamicRouteProps: RowDataItem, dynamicRouteProps: RowDataItem,
tileLayout: boolean, tileLayout: boolean,
activeLivestreams: ?LivestreamInfo,
doFetchActiveLivestreams: () => void,
}; };
function DiscoverPage(props: Props) { function DiscoverPage(props: Props) {
@ -39,6 +42,8 @@ function DiscoverPage(props: Props) {
doResolveUri, doResolveUri,
isAuthenticated, isAuthenticated,
tileLayout, tileLayout,
activeLivestreams,
doFetchActiveLivestreams,
dynamicRouteProps, dynamicRouteProps,
} = props; } = props;
const buttonRef = useRef(); const buttonRef = useRef();
@ -56,6 +61,8 @@ function DiscoverPage(props: Props) {
// Eventually allow more than one tag on this page // Eventually allow more than one tag on this page
// Restricting to one to make follow/unfollow simpler // Restricting to one to make follow/unfollow simpler
const tag = (tags && tags[0]) || null; const tag = (tags && tags[0]) || null;
const channelIds =
(dynamicRouteProps && dynamicRouteProps.options && dynamicRouteProps.options.channelIds) || undefined;
const isFollowing = followedTags.map(({ name }) => name).includes(tag); const isFollowing = followedTags.map(({ name }) => name).includes(tag);
let label = isFollowing ? __('Following --[button label indicating a channel has been followed]--') : __('Follow'); let label = isFollowing ? __('Following --[button label indicating a channel has been followed]--') : __('Follow');
@ -104,9 +111,14 @@ function DiscoverPage(props: Props) {
); );
} }
React.useEffect(() => {
doFetchActiveLivestreams();
}, []);
return ( return (
<Page noFooter fullWidthPage={tileLayout}> <Page noFooter fullWidthPage={tileLayout}>
<ClaimListDiscover <ClaimListDiscover
prefixUris={getLivestreamUris(activeLivestreams, channelIds)}
hideAdvancedFilter={SIMPLE_SITE} hideAdvancedFilter={SIMPLE_SITE}
hideFilters={SIMPLE_SITE ? !dynamicRouteProps : undefined} hideFilters={SIMPLE_SITE ? !dynamicRouteProps : undefined}
header={repostedUri ? <span /> : undefined} header={repostedUri ? <span /> : undefined}
@ -131,9 +143,7 @@ function DiscoverPage(props: Props) {
: undefined : undefined
} }
feeAmount={SIMPLE_SITE ? !dynamicRouteProps && CS.FEE_AMOUNT_ANY : undefined} feeAmount={SIMPLE_SITE ? !dynamicRouteProps && CS.FEE_AMOUNT_ANY : undefined}
channelIds={ channelIds={channelIds}
(dynamicRouteProps && dynamicRouteProps.options && dynamicRouteProps.options.channelIds) || undefined
}
limitClaimsPerChannel={ limitClaimsPerChannel={
SIMPLE_SITE SIMPLE_SITE
? (dynamicRouteProps && dynamicRouteProps.options && dynamicRouteProps.options.limitClaimsPerChannel) || ? (dynamicRouteProps && dynamicRouteProps.options && dynamicRouteProps.options.limitClaimsPerChannel) ||

View file

@ -1,4 +1,6 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doFetchActiveLivestreams } from 'redux/actions/livestream';
import { selectActiveLivestreams } from 'redux/selectors/livestream';
import { selectFollowedTags } from 'redux/selectors/tags'; import { selectFollowedTags } from 'redux/selectors/tags';
import { selectUserVerifiedEmail } from 'redux/selectors/user'; import { selectUserVerifiedEmail } from 'redux/selectors/user';
import { selectSubscriptions } from 'redux/selectors/subscriptions'; import { selectSubscriptions } from 'redux/selectors/subscriptions';
@ -12,8 +14,11 @@ const select = (state) => ({
authenticated: selectUserVerifiedEmail(state), authenticated: selectUserVerifiedEmail(state),
showNsfw: selectShowMatureContent(state), showNsfw: selectShowMatureContent(state),
homepageData: selectHomepageData(state), homepageData: selectHomepageData(state),
activeLivestreams: selectActiveLivestreams(state),
}); });
const perform = {}; const perform = (dispatch) => ({
doFetchActiveLivestreams: () => dispatch(doFetchActiveLivestreams()),
});
export default connect(select, perform)(DiscoverPage); export default connect(select, perform)(DiscoverPage);

View file

@ -10,6 +10,7 @@ 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 { GetLinksData } from 'util/buildHomepage'; import { GetLinksData } from 'util/buildHomepage';
import { getLivestreamUris } from 'util/livestream';
// @if TARGET='web' // @if TARGET='web'
import Pixel from 'web/component/pixel'; import Pixel from 'web/component/pixel';
@ -22,10 +23,20 @@ type Props = {
subscribedChannels: Array<Subscription>, subscribedChannels: Array<Subscription>,
showNsfw: boolean, showNsfw: boolean,
homepageData: any, homepageData: any,
activeLivestreams: any,
doFetchActiveLivestreams: () => void,
}; };
function HomePage(props: Props) { function HomePage(props: Props) {
const { followedTags, subscribedChannels, authenticated, showNsfw, homepageData } = props; const {
followedTags,
subscribedChannels,
authenticated,
showNsfw,
homepageData,
activeLivestreams,
doFetchActiveLivestreams,
} = 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;
@ -50,8 +61,15 @@ function HomePage(props: Props) {
))} ))}
</ul> </ul>
); );
const claimTiles = ( const claimTiles = (
<ClaimTilesDiscover {...options} showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS} hasSource pinUrls={pinUrls} /> <ClaimTilesDiscover
{...options}
showNoSourceClaims={ENABLE_NO_SOURCE_CLAIMS}
hasSource
prefixUris={getLivestreamUris(activeLivestreams, options.channelIds)}
pinUrls={pinUrls}
/>
); );
return ( return (
@ -86,6 +104,10 @@ function HomePage(props: Props) {
); );
} }
React.useEffect(() => {
doFetchActiveLivestreams();
}, []);
return ( return (
<Page fullWidthPage> <Page fullWidthPage>
{!SIMPLE_SITE && (authenticated || !IS_WEB) && !subscribedChannels.length && ( {!SIMPLE_SITE && (authenticated || !IS_WEB) && !subscribedChannels.length && (