Add outbrain
- Only add for unauthenticated users for now. We can change that to look at premium later without having to touch `app/view.jsx`. - Only show the ad after knowing the ad is filled; this prevents the invisible container from blocking stuff while waiting, or even worse, when not filled.
This commit is contained in:
parent
d2fdcc970f
commit
802b5d5a18
4 changed files with 80 additions and 2 deletions
|
@ -2,7 +2,7 @@ import { hot } from 'react-hot-loader/root';
|
|||
import { connect } from 'react-redux';
|
||||
import { selectGetSyncErrorMessage, selectSyncFatalError, selectSyncIsLocked } from 'redux/selectors/sync';
|
||||
import { doUserSetReferrer } from 'redux/actions/user';
|
||||
import { selectUser, selectUserLocale, selectUserVerifiedEmail } from 'redux/selectors/user';
|
||||
import { selectOdyseeMembershipIsPremiumPlus, selectUser, selectUserLocale, selectUserVerifiedEmail } from 'redux/selectors/user';
|
||||
import { selectUnclaimedRewards } from 'redux/selectors/rewards';
|
||||
import { doFetchChannelListMine, doFetchCollectionListMine, doResolveUris } from 'redux/actions/claims';
|
||||
import { selectMyChannelClaimIds } from 'redux/selectors/claims';
|
||||
|
@ -41,6 +41,7 @@ const select = (state) => ({
|
|||
activeChannelClaim: selectActiveChannelClaim(state),
|
||||
myChannelClaimIds: selectMyChannelClaimIds(state),
|
||||
subscriptions: selectSubscriptions(state),
|
||||
hasPremiumPlus: selectOdyseeMembershipIsPremiumPlus(state),
|
||||
});
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
|
|
|
@ -16,6 +16,7 @@ import useKonamiListener from 'util/enhanced-layout';
|
|||
import Yrbl from 'component/yrbl';
|
||||
import FileRenderFloating from 'component/fileRenderFloating';
|
||||
import { withRouter } from 'react-router';
|
||||
import useAdOutbrain from 'effects/use-ad-outbrain';
|
||||
import usePrevious from 'effects/use-previous';
|
||||
import Nag from 'component/common/nag';
|
||||
import REWARDS from 'rewards';
|
||||
|
@ -86,6 +87,7 @@ type Props = {
|
|||
activeChannelClaim: ?ChannelClaim,
|
||||
myChannelClaimIds: ?Array<string>,
|
||||
subscriptions: Array<Subscription>,
|
||||
hasPremiumPlus: ?boolean,
|
||||
setActiveChannelIfNotSet: () => void,
|
||||
setIncognito: (boolean) => void,
|
||||
fetchModBlockedList: () => void,
|
||||
|
@ -125,6 +127,7 @@ function App(props: Props) {
|
|||
fetchModBlockedList,
|
||||
resolveUris,
|
||||
subscriptions,
|
||||
hasPremiumPlus,
|
||||
fetchModAmIList,
|
||||
} = props;
|
||||
|
||||
|
@ -480,6 +483,8 @@ function App(props: Props) {
|
|||
|
||||
useDegradedPerformance(setLbryTvApiStatus, user);
|
||||
|
||||
useAdOutbrain(Boolean(hasPremiumPlus), isAuthenticated);
|
||||
|
||||
useEffect(() => {
|
||||
// When language is changed or translations are fetched, we render.
|
||||
setLangRenderKey(Date.now());
|
||||
|
|
62
ui/effects/use-ad-outbrain.js
Normal file
62
ui/effects/use-ad-outbrain.js
Normal file
|
@ -0,0 +1,62 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
|
||||
function inIFrame() {
|
||||
try {
|
||||
return window.self !== window.top;
|
||||
} catch (e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const LOAD_AD_DELAY_MS = 3000; // Wait past boot-up and core-vitals period.
|
||||
const OUTBRAIN_CONTAINER_KEY = 'outbrainStickyParent';
|
||||
|
||||
let script;
|
||||
|
||||
export default function useAdOutbrain(hasPremiumPlus: boolean, isAuthenticated: boolean) {
|
||||
// Only look at authentication for now. Eventually, we'll only use 'hasPremiumPlus'.
|
||||
const isAuthenticatedRef = React.useRef(isAuthenticated);
|
||||
isAuthenticatedRef.current = isAuthenticated;
|
||||
|
||||
function loadListener() {
|
||||
const container = window[OUTBRAIN_CONTAINER_KEY];
|
||||
if (container) {
|
||||
// Hide it immediately while we wait for ads to be filled. This prevents
|
||||
// the invisible container from blocking our content.
|
||||
container.style.visibility = 'hidden';
|
||||
|
||||
// Restore visibility after confirming the ad is filled. If it is filled
|
||||
// after the stipulated time, well, no soup for you.
|
||||
setTimeout(() => {
|
||||
const filledAd = document.querySelector('.ob-widget-items-container');
|
||||
if (filledAd && !isAuthenticatedRef.current) {
|
||||
container.style.visibility = 'visible';
|
||||
}
|
||||
}, 5000); // 3s is sufficient for Chrome, but Firefox seems to take ~5s
|
||||
}
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!inIFrame() && !isAuthenticated && !script) {
|
||||
const loadTimer = setTimeout(() => {
|
||||
script = document.createElement('script');
|
||||
script.src = 'https://adncdnend.azureedge.net/adtags/odysee.adn.js';
|
||||
script.async = true;
|
||||
script.addEventListener('load', loadListener); // not using 'script.onload'; seem unreliable with async.
|
||||
|
||||
// $FlowFixMe
|
||||
document.body.appendChild(script);
|
||||
}, LOAD_AD_DELAY_MS);
|
||||
|
||||
return () => clearTimeout(loadTimer);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps, (on mount only)
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (isAuthenticated && window[OUTBRAIN_CONTAINER_KEY]) {
|
||||
window[OUTBRAIN_CONTAINER_KEY].style.display = 'none';
|
||||
}
|
||||
}, [isAuthenticated]);
|
||||
}
|
|
@ -54,7 +54,7 @@
|
|||
width: $width;
|
||||
}
|
||||
|
||||
div[style*='transform-origin: left bottom;'] {
|
||||
div[style*='transform-origin: left bottom'] {
|
||||
// [Floating ad]
|
||||
// Hide for now since can't get it to work in a consistent manner between:
|
||||
// - EU and non-EU version
|
||||
|
@ -187,3 +187,13 @@
|
|||
.exp-ui__logo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
// Outbrain
|
||||
// ****************************************************************************
|
||||
|
||||
.ob-widget-items-container {
|
||||
padding-left: var(--spacing-xs);
|
||||
padding-right: var(--spacing-xs);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue