Move PremiumPlusTile into Ads (#1522)

* Move `PremiumPlusTile` into `Ads`

This saves the need to repeat the logic everywhere.

* Add option to disable fallback.
This commit is contained in:
infinite-persistence 2022-05-19 01:52:46 +08:00 committed by GitHub
parent 855d3dae01
commit 53079d92b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 50 additions and 99 deletions

View file

@ -7,13 +7,11 @@ import {
makeSelectTotalPagesInChannelSearch, makeSelectTotalPagesInChannelSearch,
selectClaimForUri, selectClaimForUri,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { selectOdyseeMembershipIsPremiumPlus } from 'redux/selectors/user';
import { doResolveUris } from 'redux/actions/claims'; import { doResolveUris } from 'redux/actions/claims';
import * as SETTINGS from 'constants/settings'; import * as SETTINGS from 'constants/settings';
import { makeSelectChannelIsMuted } from 'redux/selectors/blocked'; import { makeSelectChannelIsMuted } from 'redux/selectors/blocked';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
import { selectClientSetting, selectShowMatureContent } from 'redux/selectors/settings'; import { selectClientSetting, selectShowMatureContent } from 'redux/selectors/settings';
import { selectAdBlockerFound } from 'redux/selectors/app';
import { doFetchChannelLiveStatus } from 'redux/actions/livestream'; import { doFetchChannelLiveStatus } from 'redux/actions/livestream';
import { selectActiveLivestreamForChannel, selectActiveLivestreamInitialized } from 'redux/selectors/livestream'; import { selectActiveLivestreamForChannel, selectActiveLivestreamInitialized } from 'redux/selectors/livestream';
import { getChannelIdFromClaim } from 'util/claim'; import { getChannelIdFromClaim } from 'util/claim';
@ -37,8 +35,6 @@ const select = (state, props) => {
tileLayout: selectClientSetting(state, SETTINGS.TILE_LAYOUT), tileLayout: selectClientSetting(state, SETTINGS.TILE_LAYOUT),
activeLivestreamForChannel: selectActiveLivestreamForChannel(state, channelClaimId), activeLivestreamForChannel: selectActiveLivestreamForChannel(state, channelClaimId),
activeLivestreamInitialized: selectActiveLivestreamInitialized(state), activeLivestreamInitialized: selectActiveLivestreamInitialized(state),
adBlockerFound: selectAdBlockerFound(state),
hasPremiumPlus: selectOdyseeMembershipIsPremiumPlus(state),
}; };
}; };

View file

@ -15,7 +15,6 @@ import ScheduledStreams from 'component/scheduledStreams';
import { SearchResults } from './internal/searchResults'; import { SearchResults } from './internal/searchResults';
import useFetchLiveStatus from 'effects/use-fetch-live'; import useFetchLiveStatus from 'effects/use-fetch-live';
import { useIsLargeScreen } from 'effects/use-screensize'; import { useIsLargeScreen } from 'effects/use-screensize';
import PremiumPlusTile from 'component/premiumPlusTile';
const TYPES_TO_ALLOW_FILTER = ['stream', 'repost']; const TYPES_TO_ALLOW_FILTER = ['stream', 'repost'];
@ -42,8 +41,6 @@ type Props = {
doFetchChannelLiveStatus: (string) => void, doFetchChannelLiveStatus: (string) => void,
activeLivestreamForChannel: any, activeLivestreamForChannel: any,
activeLivestreamInitialized: boolean, activeLivestreamInitialized: boolean,
adBlockerFound: ?boolean,
hasPremiumPlus: ?boolean,
}; };
function ChannelContent(props: Props) { function ChannelContent(props: Props) {
@ -65,8 +62,6 @@ function ChannelContent(props: Props) {
doFetchChannelLiveStatus, doFetchChannelLiveStatus,
activeLivestreamForChannel, activeLivestreamForChannel,
activeLivestreamInitialized, activeLivestreamInitialized,
adBlockerFound,
hasPremiumPlus,
} = props; } = props;
// const claimsInChannel = (claim && claim.meta.claims_in_channel) || 0; // const claimsInChannel = (claim && claim.meta.claims_in_channel) || 0;
@ -164,15 +159,7 @@ function ChannelContent(props: Props) {
defaultOrderBy={CS.ORDER_BY_NEW} defaultOrderBy={CS.ORDER_BY_NEW}
pageSize={dynamicPageSize} pageSize={dynamicPageSize}
infiniteScroll={defaultInfiniteScroll} infiniteScroll={defaultInfiniteScroll}
injectedItem={ injectedItem={{ node: <Ads small type="video" tileLayout /> }}
!hasPremiumPlus && {
node: adBlockerFound ? (
<PremiumPlusTile tileLayout={tileLayout} />
) : (
<Ads small type="video" tileLayout />
),
}
}
meta={ meta={
showFilters && ( showFilters && (
<Form onSubmit={() => {}} className="wunderbar--inline"> <Form onSubmit={() => {}} className="wunderbar--inline">

View file

@ -79,7 +79,7 @@ export default React.memo<Props>(function RecommendedContent(props: Props) {
const InjectedAd = const InjectedAd =
injectAds && !blacklistTriggered injectAds && !blacklistTriggered
? { ? {
node: <Ads small type="video" className="ads__claim-item--recommended" />, node: <Ads small type="video" className="ads__claim-item--recommended" noFallback />,
index: isMobile ? 0 : 3, index: isMobile ? 0 : 3,
} }
: null; : null;

View file

@ -8,8 +8,6 @@ import { selectActiveLivestreams } from 'redux/selectors/livestream';
import { selectFollowedTags } from 'redux/selectors/tags'; import { selectFollowedTags } from 'redux/selectors/tags';
import { doToggleTagFollowDesktop } from 'redux/actions/tags'; import { doToggleTagFollowDesktop } from 'redux/actions/tags';
import { selectClientSetting, selectLanguage } from 'redux/selectors/settings'; import { selectClientSetting, selectLanguage } from 'redux/selectors/settings';
import { selectAdBlockerFound } from 'redux/selectors/app';
import { selectOdyseeMembershipIsPremiumPlus, selectUserCountry } from 'redux/selectors/user';
import DiscoverPage from './view'; import DiscoverPage from './view';
const select = (state, props) => { const select = (state, props) => {
@ -25,9 +23,6 @@ const select = (state, props) => {
activeLivestreams: selectActiveLivestreams(state), activeLivestreams: selectActiveLivestreams(state),
languageSetting: selectLanguage(state), languageSetting: selectLanguage(state),
searchInLanguage: selectClientSetting(state, SETTINGS.SEARCH_IN_LANGUAGE), searchInLanguage: selectClientSetting(state, SETTINGS.SEARCH_IN_LANGUAGE),
adBlockerFound: selectAdBlockerFound(state),
hasPremiumPlus: selectOdyseeMembershipIsPremiumPlus(state),
userCountry: selectUserCountry(state),
}; };
}; };

View file

@ -19,7 +19,6 @@ 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 LivestreamSection from './livestreamSection'; import LivestreamSection from './livestreamSection';
import PremiumPlusTile from 'component/premiumPlusTile';
const CATEGORY_CONTENT_TYPES_FILTER = CS.CONTENT_TYPES.filter((x) => x !== CS.CLAIM_REPOST); const CATEGORY_CONTENT_TYPES_FILTER = CS.CONTENT_TYPES.filter((x) => x !== CS.CLAIM_REPOST);
@ -36,9 +35,6 @@ type Props = {
tileLayout: boolean, tileLayout: boolean,
activeLivestreams: ?LivestreamInfo, activeLivestreams: ?LivestreamInfo,
doFetchActiveLivestreams: (orderBy: ?Array<string>, lang: ?Array<string>) => void, doFetchActiveLivestreams: (orderBy: ?Array<string>, lang: ?Array<string>) => void,
adBlockerFound: ?boolean,
hasPremiumPlus: ?boolean,
userCountry: string,
}; };
function DiscoverPage(props: Props) { function DiscoverPage(props: Props) {
@ -55,9 +51,6 @@ function DiscoverPage(props: Props) {
activeLivestreams, activeLivestreams,
doFetchActiveLivestreams, doFetchActiveLivestreams,
dynamicRouteProps, dynamicRouteProps,
adBlockerFound,
hasPremiumPlus,
userCountry,
} = props; } = props;
const buttonRef = useRef(); const buttonRef = useRef();
@ -65,7 +58,6 @@ function DiscoverPage(props: Props) {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const isWildWest = dynamicRouteProps && dynamicRouteProps.id === 'WILD_WEST'; const isWildWest = dynamicRouteProps && dynamicRouteProps.id === 'WILD_WEST';
const isCategory = Boolean(dynamicRouteProps); const isCategory = Boolean(dynamicRouteProps);
const userIsInUS = userCountry === 'US';
const urlParams = new URLSearchParams(search); const urlParams = new URLSearchParams(search);
const langParam = urlParams.get(CS.LANGUAGE_KEY) || null; const langParam = urlParams.get(CS.LANGUAGE_KEY) || null;
@ -229,17 +221,7 @@ function DiscoverPage(props: Props) {
tags={tags} tags={tags}
hiddenNsfwMessage={<HiddenNsfw type="page" />} hiddenNsfwMessage={<HiddenNsfw type="page" />}
repostedClaimId={repostedClaim ? repostedClaim.claim_id : null} repostedClaimId={repostedClaim ? repostedClaim.claim_id : null}
injectedItem={ injectedItem={!isWildWest && { node: <Ads small type="video" tileLayout /> }}
!isWildWest &&
!hasPremiumPlus && {
node:
adBlockerFound || !userIsInUS ? (
<PremiumPlusTile tileLayout={tileLayout} />
) : (
<Ads small type="video" tileLayout />
),
}
}
// TODO: find a better way to determine discover / wild west vs other modes release times // TODO: find a better way to determine discover / wild west vs other modes release times
// for now including && !tags so that // for now including && !tags so that
releaseTime={releaseTime || undefined} releaseTime={releaseTime || undefined}

View file

@ -2,16 +2,9 @@ import { connect } from 'react-redux';
import * as SETTINGS from 'constants/settings'; import * as SETTINGS from 'constants/settings';
import { doOpenModal } from 'redux/actions/app'; import { doOpenModal } from 'redux/actions/app';
import { doFetchActiveLivestreams } from 'redux/actions/livestream'; import { doFetchActiveLivestreams } from 'redux/actions/livestream';
import { selectAdBlockerFound } from 'redux/selectors/app';
import { selectActiveLivestreams, selectFetchingActiveLivestreams } from 'redux/selectors/livestream'; import { selectActiveLivestreams, selectFetchingActiveLivestreams } from 'redux/selectors/livestream';
import { selectFollowedTags } from 'redux/selectors/tags'; import { selectFollowedTags } from 'redux/selectors/tags';
import { import { selectHasOdyseeMembership, selectHomepageFetched, selectUserVerifiedEmail } from 'redux/selectors/user';
selectOdyseeMembershipIsPremiumPlus,
selectHasOdyseeMembership,
selectHomepageFetched,
selectUserVerifiedEmail,
selectUserCountry,
} from 'redux/selectors/user';
import { selectSubscriptions } from 'redux/selectors/subscriptions'; import { selectSubscriptions } from 'redux/selectors/subscriptions';
import { import {
selectShowMatureContent, selectShowMatureContent,
@ -33,11 +26,8 @@ const select = (state) => ({
activeLivestreams: selectActiveLivestreams(state), activeLivestreams: selectActiveLivestreams(state),
fetchingActiveLivestreams: selectFetchingActiveLivestreams(state), fetchingActiveLivestreams: selectFetchingActiveLivestreams(state),
hideScheduledLivestreams: selectClientSetting(state, SETTINGS.HIDE_SCHEDULED_LIVESTREAMS), hideScheduledLivestreams: selectClientSetting(state, SETTINGS.HIDE_SCHEDULED_LIVESTREAMS),
adBlockerFound: selectAdBlockerFound(state),
homepageOrder: selectClientSetting(state, SETTINGS.HOMEPAGE_ORDER), homepageOrder: selectClientSetting(state, SETTINGS.HOMEPAGE_ORDER),
hasMembership: selectHasOdyseeMembership(state), hasMembership: selectHasOdyseeMembership(state),
hasPremiumPlus: selectOdyseeMembershipIsPremiumPlus(state),
userCountry: selectUserCountry(state),
}); });
const perform = (dispatch) => ({ const perform = (dispatch) => ({

View file

@ -20,7 +20,6 @@ import { splitBySeparator } from 'util/lbryURI';
import classnames from 'classnames'; import classnames from 'classnames';
import Ads from 'web/component/ads'; import Ads from 'web/component/ads';
import Meme from 'web/component/meme'; import Meme from 'web/component/meme';
import PremiumPlusTile from 'component/premiumPlusTile';
const FYP_SECTION: RowDataItem = { const FYP_SECTION: RowDataItem = {
id: 'FYP', id: 'FYP',
@ -43,12 +42,9 @@ type Props = {
doFetchActiveLivestreams: () => void, doFetchActiveLivestreams: () => void,
fetchingActiveLivestreams: boolean, fetchingActiveLivestreams: boolean,
hideScheduledLivestreams: boolean, hideScheduledLivestreams: boolean,
adBlockerFound: ?boolean,
homepageOrder: HomepageOrder, homepageOrder: HomepageOrder,
doOpenModal: (id: string, ?{}) => void, doOpenModal: (id: string, ?{}) => void,
hasMembership: ?boolean, hasMembership: ?boolean,
hasPremiumPlus: ?boolean,
userCountry: string,
}; };
function HomePage(props: Props) { function HomePage(props: Props) {
@ -64,12 +60,9 @@ function HomePage(props: Props) {
doFetchActiveLivestreams, doFetchActiveLivestreams,
fetchingActiveLivestreams, fetchingActiveLivestreams,
hideScheduledLivestreams, hideScheduledLivestreams,
adBlockerFound,
homepageOrder, homepageOrder,
doOpenModal, doOpenModal,
hasMembership, hasMembership,
hasPremiumPlus,
userCountry,
} = props; } = props;
const showPersonalizedChannels = (authenticated || !IS_WEB) && subscribedChannels && subscribedChannels.length > 0; const showPersonalizedChannels = (authenticated || !IS_WEB) && subscribedChannels && subscribedChannels.length > 0;
@ -77,7 +70,6 @@ function HomePage(props: Props) {
const showIndividualTags = showPersonalizedTags && followedTags.length < 5; const showIndividualTags = showPersonalizedTags && followedTags.length < 5;
const isLargeScreen = useIsLargeScreen(); const isLargeScreen = useIsLargeScreen();
const channelIds = subscribedChannels.map((sub) => splitBySeparator(sub.uri)[1]); const channelIds = subscribedChannels.map((sub) => splitBySeparator(sub.uri)[1]);
const userIsInUS = userCountry === 'US';
const rowData: Array<RowDataItem> = GetLinksData( const rowData: Array<RowDataItem> = GetLinksData(
homepageData, homepageData,
@ -168,16 +160,9 @@ function HomePage(props: Props) {
hasSource hasSource
prefixUris={getLivestreamUris(activeLivestreams, options.channelIds)} prefixUris={getLivestreamUris(activeLivestreams, options.channelIds)}
pins={{ urls: pinUrls, claimIds: pinnedClaimIds }} pins={{ urls: pinUrls, claimIds: pinnedClaimIds }}
injectedItem={ injectedItem={index === 0 && { node: <Ads small type="video" tileLayout /> }}
index === 0 &&
!hasPremiumPlus && {
node:
adBlockerFound || !userIsInUS ? <PremiumPlusTile tileLayout /> : <Ads small type="video" tileLayout />,
}
}
forceShowReposts={id !== 'FOLLOWING'} forceShowReposts={id !== 'FOLLOWING'}
loading={id === 'FOLLOWING' ? fetchingActiveLivestreams : false} loading={id === 'FOLLOWING' ? fetchingActiveLivestreams : false}
adBlockerFound={adBlockerFound}
/> />
); );

View file

@ -1,15 +1,14 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doSetAdBlockerFound } from 'redux/actions/app'; import { doSetAdBlockerFound } from 'redux/actions/app';
import { selectTheme } from 'redux/selectors/settings';
import { makeSelectClaimForUri, selectClaimIsNsfwForUri } from 'redux/selectors/claims'; import { makeSelectClaimForUri, selectClaimIsNsfwForUri } from 'redux/selectors/claims';
import { selectOdyseeMembershipIsPremiumPlus } from 'redux/selectors/user'; import { selectOdyseeMembershipIsPremiumPlus, selectUserCountry } from 'redux/selectors/user';
import Ads from './view'; import Ads from './view';
const select = (state, props) => ({ const select = (state, props) => ({
theme: selectTheme(state),
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
isMature: selectClaimIsNsfwForUri(state, props.uri), isMature: selectClaimIsNsfwForUri(state, props.uri),
userHasPremiumPlus: selectOdyseeMembershipIsPremiumPlus(state), userHasPremiumPlus: selectOdyseeMembershipIsPremiumPlus(state),
userCountry: selectUserCountry(state),
}); });
const perform = { const perform = {

View file

@ -4,6 +4,7 @@ import * as PAGES from 'constants/pages';
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import I18nMessage from 'component/i18nMessage'; import I18nMessage from 'component/i18nMessage';
import Button from 'component/button'; import Button from 'component/button';
import PremiumPlusTile from 'component/premiumPlusTile';
import classnames from 'classnames'; import classnames from 'classnames';
import { platform } from 'util/platform'; import { platform } from 'util/platform';
import Icon from 'component/common/icon'; import Icon from 'component/common/icon';
@ -31,11 +32,14 @@ let ad_blocker_detected;
type Props = { type Props = {
type: string, type: string,
tileLayout?: boolean, tileLayout?: boolean,
small: boolean, small?: boolean,
className?: string,
noFallback?: boolean,
// --- redux ---
claim: Claim, claim: Claim,
isMature: boolean, isMature: boolean,
userHasPremiumPlus: boolean, userHasPremiumPlus: boolean,
className?: string, userCountry: string,
doSetAdBlockerFound: (boolean) => void, doSetAdBlockerFound: (boolean) => void,
}; };
@ -45,7 +49,16 @@ function removeIfExists(querySelector) {
} }
function Ads(props: Props) { function Ads(props: Props) {
const { type = 'video', tileLayout, small, userHasPremiumPlus, className, doSetAdBlockerFound } = props; const {
type = 'video',
tileLayout,
small,
userHasPremiumPlus,
userCountry,
className,
noFallback,
doSetAdBlockerFound,
} = props;
const [shouldShowAds, setShouldShowAds] = React.useState(resolveAdVisibility()); const [shouldShowAds, setShouldShowAds] = React.useState(resolveAdVisibility());
const mobileAds = platform.isAndroid() || platform.isIOS(); const mobileAds = platform.isAndroid() || platform.isIOS();
@ -57,7 +70,7 @@ function Ads(props: Props) {
function resolveAdVisibility() { function resolveAdVisibility() {
// 'ad_blocker_detected' will be undefined at startup. Wait until we are // 'ad_blocker_detected' will be undefined at startup. Wait until we are
// sure it is not blocked (i.e. === false) before showing the component. // sure it is not blocked (i.e. === false) before showing the component.
return ad_blocker_detected === false && SHOW_ADS && !userHasPremiumPlus; return ad_blocker_detected === false && SHOW_ADS && !userHasPremiumPlus && userCountry !== 'US';
} }
useEffect(() => { useEffect(() => {
@ -130,7 +143,8 @@ function Ads(props: Props) {
</I18nMessage> </I18nMessage>
); );
if (shouldShowAds && type === 'video') { if (type === 'video') {
if (shouldShowAds) {
return ( return (
<div <div
className={classnames('ads ads__claim-item', className, { className={classnames('ads ads__claim-item', className, {
@ -158,6 +172,9 @@ function Ads(props: Props) {
</div> </div>
</div> </div>
); );
} else if (!noFallback) {
return <PremiumPlusTile tileLayout={tileLayout} />;
}
} }
return null; return null;