Refactor ad implementation, fix two bugs (#616)
This commit is contained in:
commit
ec5a9802fc
5 changed files with 141 additions and 381 deletions
|
@ -84,139 +84,6 @@ function ChannelContent(props: Props) {
|
||||||
setSearchQuery(value);
|
setSearchQuery(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if passed element is fully visible on screen
|
|
||||||
// function isScrolledIntoView(el) {
|
|
||||||
// const rect = el.getBoundingClientRect();
|
|
||||||
// const elemTop = rect.top;
|
|
||||||
// const elemBottom = rect.bottom;
|
|
||||||
//
|
|
||||||
// // Only completely visible elements return true:
|
|
||||||
// const isVisible = elemTop >= 0 && elemBottom <= window.innerHeight;
|
|
||||||
// return isVisible;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// React.useEffect(() => {
|
|
||||||
// if (isAuthenticated || !SHOW_ADS) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
// const viewType = urlParams.get('view');
|
|
||||||
//
|
|
||||||
// // only insert ad if it's a content view
|
|
||||||
// if (viewType !== 'content') return;
|
|
||||||
//
|
|
||||||
// (async function () {
|
|
||||||
// // test if adblock is enabled
|
|
||||||
// let adBlockEnabled = false;
|
|
||||||
// const googleAdUrl = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
|
||||||
// try {
|
|
||||||
// await fetch(new Request(googleAdUrl)).catch((_) => {
|
|
||||||
// adBlockEnabled = true;
|
|
||||||
// });
|
|
||||||
// } catch (e) {
|
|
||||||
// adBlockEnabled = true;
|
|
||||||
// } finally {
|
|
||||||
// if (!adBlockEnabled) {
|
|
||||||
// // select the cards on page
|
|
||||||
// let cards = document.getElementsByClassName('card claim-preview--tile');
|
|
||||||
//
|
|
||||||
// // eslint-disable-next-line no-inner-declarations
|
|
||||||
// function checkFlag() {
|
|
||||||
// if (cards.length === 0) {
|
|
||||||
// window.setTimeout(checkFlag, 100);
|
|
||||||
// } else {
|
|
||||||
// // find the last fully visible card
|
|
||||||
// let lastCard;
|
|
||||||
//
|
|
||||||
// // width of browser window
|
|
||||||
// const windowWidth = window.innerWidth;
|
|
||||||
//
|
|
||||||
// // on small screens, grab the second item
|
|
||||||
// if (windowWidth <= 900) {
|
|
||||||
// lastCard = cards[1];
|
|
||||||
// } else {
|
|
||||||
// // otherwise, get the last fully visible card
|
|
||||||
// for (const card of cards) {
|
|
||||||
// const isFullyVisible = isScrolledIntoView(card);
|
|
||||||
// if (!isFullyVisible) break;
|
|
||||||
// lastCard = card;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // clone the last card
|
|
||||||
// // $FlowFixMe
|
|
||||||
// const clonedCard = lastCard.cloneNode(true);
|
|
||||||
//
|
|
||||||
// // insert cloned card
|
|
||||||
// // $FlowFixMe
|
|
||||||
// lastCard.parentNode.insertBefore(clonedCard, lastCard);
|
|
||||||
//
|
|
||||||
// // delete last card so that it doesn't mess up formatting
|
|
||||||
// // $FlowFixMe
|
|
||||||
// // lastCard.remove();
|
|
||||||
//
|
|
||||||
// // change the appearance of the cloned card
|
|
||||||
// // $FlowFixMe
|
|
||||||
// clonedCard.querySelector('.claim__menu-button').remove();
|
|
||||||
//
|
|
||||||
// // $FlowFixMe
|
|
||||||
// clonedCard.querySelector('.truncated-text').innerHTML = __(
|
|
||||||
// 'Hate these? Login to Odysee for an ad free experience'
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// // $FlowFixMe
|
|
||||||
// clonedCard.querySelector('.claim-tile__info').remove();
|
|
||||||
//
|
|
||||||
// // $FlowFixMe
|
|
||||||
// clonedCard.querySelector('[role="none"]').removeAttribute('href');
|
|
||||||
//
|
|
||||||
// // $FlowFixMe
|
|
||||||
// clonedCard.querySelector('.claim-tile__header').firstChild.href = '/$/signin';
|
|
||||||
//
|
|
||||||
// // $FlowFixMe
|
|
||||||
// clonedCard.querySelector('.claim-tile__title').firstChild.removeAttribute('aria-label');
|
|
||||||
//
|
|
||||||
// // $FlowFixMe
|
|
||||||
// clonedCard.querySelector('.claim-tile__title').firstChild.removeAttribute('title');
|
|
||||||
//
|
|
||||||
// // $FlowFixMe
|
|
||||||
// clonedCard.querySelector('.claim-tile__header').firstChild.removeAttribute('aria-label');
|
|
||||||
//
|
|
||||||
// // $FlowFixMe
|
|
||||||
// clonedCard
|
|
||||||
// .querySelector('.media__thumb')
|
|
||||||
// .replaceWith(document.getElementsByClassName('homepageAdContainer')[0]);
|
|
||||||
//
|
|
||||||
// // show the homepage ad which is not displayed at first
|
|
||||||
// document.getElementsByClassName('homepageAdContainer')[0].style.display = 'block';
|
|
||||||
//
|
|
||||||
// // $FlowFixMe
|
|
||||||
// const imageHeight = window.getComputedStyle(lastCard.querySelector('.media__thumb')).height;
|
|
||||||
// // $FlowFixMe
|
|
||||||
// const imageWidth = window.getComputedStyle(lastCard.querySelector('.media__thumb')).width;
|
|
||||||
//
|
|
||||||
// const styles = `#av-container, #AVcontent, #aniBox {
|
|
||||||
// height: ${imageHeight} !important;
|
|
||||||
// width: ${imageWidth} !important;
|
|
||||||
// }`;
|
|
||||||
//
|
|
||||||
// const styleSheet = document.createElement('style');
|
|
||||||
// styleSheet.type = 'text/css';
|
|
||||||
// styleSheet.id = 'customAniviewStyling';
|
|
||||||
// styleSheet.innerText = styles;
|
|
||||||
// // $FlowFixMe
|
|
||||||
// document.head.appendChild(styleSheet);
|
|
||||||
//
|
|
||||||
// window.dispatchEvent(new CustomEvent('scroll'));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// checkFlag();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })();
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
if (searchQuery === '' || !claimId) {
|
if (searchQuery === '' || !claimId) {
|
||||||
|
@ -307,7 +174,7 @@ function ChannelContent(props: Props) {
|
||||||
|
|
||||||
{!channelIsMine && claimsInChannel > 0 && <HiddenNsfwClaims uri={uri} />}
|
{!channelIsMine && claimsInChannel > 0 && <HiddenNsfwClaims uri={uri} />}
|
||||||
|
|
||||||
<Ads type="homepage" />
|
{/* <Ads type="homepage" /> */}
|
||||||
|
|
||||||
{!fetching && (
|
{!fetching && (
|
||||||
<ClaimListDiscover
|
<ClaimListDiscover
|
||||||
|
|
|
@ -13,7 +13,7 @@ import usePersistedState from 'effects/use-persisted-state';
|
||||||
import analytics from 'analytics';
|
import analytics from 'analytics';
|
||||||
import HiddenNsfw from 'component/common/hidden-nsfw';
|
import HiddenNsfw from 'component/common/hidden-nsfw';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import Ads from 'web/component/ads';
|
import Ads, { injectAd } 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';
|
||||||
|
@ -182,131 +182,13 @@ function DiscoverPage(props: Props) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if passed element is fully visible on screen
|
|
||||||
function isScrolledIntoView(el) {
|
|
||||||
const rect = el.getBoundingClientRect();
|
|
||||||
const elemTop = rect.top;
|
|
||||||
const elemBottom = rect.bottom;
|
|
||||||
|
|
||||||
// Only completely visible elements return true:
|
|
||||||
const isVisible = elemTop >= 0 && elemBottom <= window.innerHeight;
|
|
||||||
return isVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isAuthenticated || !SHOW_ADS || window.location.pathname === `/$/${PAGES.WILD_WEST}`) {
|
if (isAuthenticated || !SHOW_ADS || window.location.pathname === `/$/${PAGES.WILD_WEST}`) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(async function () {
|
// inject ad into last visible card
|
||||||
// test if adblock is enabled
|
injectAd();
|
||||||
let adBlockEnabled = false;
|
|
||||||
const googleAdUrl = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
|
||||||
try {
|
|
||||||
await fetch(new Request(googleAdUrl)).catch((_) => {
|
|
||||||
adBlockEnabled = true;
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
adBlockEnabled = true;
|
|
||||||
} finally {
|
|
||||||
if (!adBlockEnabled) {
|
|
||||||
// select the cards on page
|
|
||||||
let cards = document.getElementsByClassName('card claim-preview--tile');
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-inner-declarations
|
|
||||||
function checkFlag() {
|
|
||||||
if (cards.length === 0) {
|
|
||||||
window.setTimeout(checkFlag, 100);
|
|
||||||
} else {
|
|
||||||
// find the last fully visible card
|
|
||||||
let lastCard;
|
|
||||||
|
|
||||||
// width of browser window
|
|
||||||
const windowWidth = window.innerWidth;
|
|
||||||
|
|
||||||
// on small screens, grab the second item
|
|
||||||
if (windowWidth <= 900) {
|
|
||||||
lastCard = cards[1];
|
|
||||||
} else {
|
|
||||||
// otherwise, get the last fully visible card
|
|
||||||
for (const card of cards) {
|
|
||||||
const isFullyVisible = isScrolledIntoView(card);
|
|
||||||
if (!isFullyVisible) break;
|
|
||||||
lastCard = card;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// clone the last card
|
|
||||||
// $FlowFixMe
|
|
||||||
const clonedCard = lastCard.cloneNode(true);
|
|
||||||
|
|
||||||
// insert cloned card
|
|
||||||
// $FlowFixMe
|
|
||||||
lastCard.parentNode.insertBefore(clonedCard, lastCard);
|
|
||||||
|
|
||||||
// delete last card so that it doesn't mess up formatting
|
|
||||||
// $FlowFixMe
|
|
||||||
// lastCard.remove();
|
|
||||||
|
|
||||||
// change the appearance of the cloned card
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('.claim__menu-button').remove();
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('.truncated-text').innerHTML = __(
|
|
||||||
'Hate these? Login to Odysee for an ad free experience'
|
|
||||||
);
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('.claim-tile__info').remove();
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('[role="none"]').removeAttribute('href');
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('.claim-tile__header').firstChild.href = '/$/signin';
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('.claim-tile__title').firstChild.removeAttribute('aria-label');
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('.claim-tile__title').firstChild.removeAttribute('title');
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('.claim-tile__header').firstChild.removeAttribute('aria-label');
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard
|
|
||||||
.querySelector('.media__thumb')
|
|
||||||
.replaceWith(document.getElementsByClassName('homepageAdContainer')[0]);
|
|
||||||
|
|
||||||
// show the homepage ad which is not displayed at first
|
|
||||||
document.getElementsByClassName('homepageAdContainer')[0].style.display = 'block';
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
const imageHeight = window.getComputedStyle(lastCard.querySelector('.media__thumb')).height;
|
|
||||||
// $FlowFixMe
|
|
||||||
const imageWidth = window.getComputedStyle(lastCard.querySelector('.media__thumb')).width;
|
|
||||||
|
|
||||||
const styles = `#av-container, #AVcontent, #aniBox {
|
|
||||||
height: ${imageHeight} !important;
|
|
||||||
width: ${imageWidth} !important;
|
|
||||||
}`;
|
|
||||||
|
|
||||||
const styleSheet = document.createElement('style');
|
|
||||||
styleSheet.type = 'text/css';
|
|
||||||
styleSheet.id = 'customAniviewStyling';
|
|
||||||
styleSheet.innerText = styles;
|
|
||||||
// $FlowFixMe
|
|
||||||
document.head.appendChild(styleSheet);
|
|
||||||
|
|
||||||
window.dispatchEvent(new CustomEvent('scroll'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checkFlag();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}, [isAuthenticated]);
|
}, [isAuthenticated]);
|
||||||
|
|
||||||
// Sync liveSection --> liveSectionStore
|
// Sync liveSection --> liveSectionStore
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import * as PAGES from 'constants/pages';
|
import * as PAGES from 'constants/pages';
|
||||||
import { SHOW_ADS, SITE_NAME, SIMPLE_SITE, ENABLE_NO_SOURCE_CLAIMS } from 'config';
|
import { SITE_NAME, SIMPLE_SITE, ENABLE_NO_SOURCE_CLAIMS, SHOW_ADS } from 'config';
|
||||||
import Ads from 'web/component/ads';
|
import Ads, { injectAd } from 'web/component/ads';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
@ -120,128 +120,10 @@ function HomePage(props: Props) {
|
||||||
doFetchActiveLivestreams();
|
doFetchActiveLivestreams();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// returns true if passed element is fully visible on screen
|
|
||||||
function isScrolledIntoView(el) {
|
|
||||||
const rect = el.getBoundingClientRect();
|
|
||||||
const elemTop = rect.top;
|
|
||||||
const elemBottom = rect.bottom;
|
|
||||||
|
|
||||||
// Only completely visible elements return true:
|
|
||||||
const isVisible = elemTop >= 0 && elemBottom <= window.innerHeight;
|
|
||||||
return isVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (authenticated || !SHOW_ADS) {
|
const shouldShowAds = SHOW_ADS && !authenticated;
|
||||||
return;
|
// inject ad into last visible card
|
||||||
}
|
injectAd(shouldShowAds);
|
||||||
|
|
||||||
(async () => {
|
|
||||||
// test if adblock is enabled
|
|
||||||
let adBlockEnabled = false;
|
|
||||||
const googleAdUrl = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
|
||||||
try {
|
|
||||||
await fetch(new Request(googleAdUrl)).catch((_) => {
|
|
||||||
adBlockEnabled = true;
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
adBlockEnabled = true;
|
|
||||||
} finally {
|
|
||||||
if (!adBlockEnabled) {
|
|
||||||
// select the cards on page
|
|
||||||
let cards = document.getElementsByClassName('card claim-preview--tile');
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-inner-declarations
|
|
||||||
function checkFlag() {
|
|
||||||
if (cards.length === 0) {
|
|
||||||
window.setTimeout(checkFlag, 100);
|
|
||||||
} else {
|
|
||||||
// find the last fully visible card
|
|
||||||
let lastCard;
|
|
||||||
|
|
||||||
// width of browser window
|
|
||||||
const windowWidth = window.innerWidth;
|
|
||||||
|
|
||||||
// on small screens, grab the second item
|
|
||||||
if (windowWidth <= 900) {
|
|
||||||
lastCard = cards[1];
|
|
||||||
} else {
|
|
||||||
// otherwise, get the last fully visible card
|
|
||||||
for (const card of cards) {
|
|
||||||
const isFullyVisible = isScrolledIntoView(card);
|
|
||||||
if (!isFullyVisible) break;
|
|
||||||
lastCard = card;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if no last card was found, just exit the function to not cause errors
|
|
||||||
if (!lastCard) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// clone the last card
|
|
||||||
// $FlowFixMe
|
|
||||||
const clonedCard = lastCard.cloneNode(true);
|
|
||||||
|
|
||||||
// insert cloned card
|
|
||||||
// $FlowFixMe
|
|
||||||
lastCard.parentNode.insertBefore(clonedCard, lastCard);
|
|
||||||
|
|
||||||
// change the appearance of the cloned card
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('.claim__menu-button').remove();
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('.truncated-text').innerHTML = __(
|
|
||||||
'Hate these? Login to Odysee for an ad free experience'
|
|
||||||
);
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('.claim-tile__info').remove();
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('[role="none"]').removeAttribute('href');
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('.claim-tile__header').firstChild.href = '/$/signin';
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('.claim-tile__title').firstChild.removeAttribute('aria-label');
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('.claim-tile__title').firstChild.removeAttribute('title');
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard.querySelector('.claim-tile__header').firstChild.removeAttribute('aria-label');
|
|
||||||
|
|
||||||
// $FlowFixMe
|
|
||||||
clonedCard
|
|
||||||
.querySelector('.media__thumb')
|
|
||||||
.replaceWith(document.getElementsByClassName('homepageAdContainer')[0]);
|
|
||||||
|
|
||||||
// show the homepage ad which is not displayed at first
|
|
||||||
document.getElementsByClassName('homepageAdContainer')[0].style.display = 'block';
|
|
||||||
|
|
||||||
const thumbnail = window.getComputedStyle(lastCard.querySelector('.media__thumb'));
|
|
||||||
|
|
||||||
const styles = `#av-container, #AVcontent, #aniBox {
|
|
||||||
height: ${thumbnail.height} !important;
|
|
||||||
width: ${thumbnail.width} !important;
|
|
||||||
}`;
|
|
||||||
|
|
||||||
const styleSheet = document.createElement('style');
|
|
||||||
styleSheet.type = 'text/css';
|
|
||||||
styleSheet.id = 'customAniviewStyling';
|
|
||||||
styleSheet.innerText = styles;
|
|
||||||
// $FlowFixMe
|
|
||||||
document.head.appendChild(styleSheet);
|
|
||||||
|
|
||||||
// delete last card to not introduce layout shifts
|
|
||||||
lastCard.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checkFlag();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { connect } from 'react-redux';
|
||||||
import { selectTheme } from 'redux/selectors/settings';
|
import { selectTheme } from 'redux/selectors/settings';
|
||||||
import { makeSelectClaimForUri, selectClaimIsNsfwForUri } from 'redux/selectors/claims';
|
import { makeSelectClaimForUri, selectClaimIsNsfwForUri } from 'redux/selectors/claims';
|
||||||
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
||||||
import Ads from './view';
|
import Ads, { injectAd } from './view';
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
theme: selectTheme(state),
|
theme: selectTheme(state),
|
||||||
|
@ -12,3 +12,4 @@ const select = (state, props) => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select)(Ads);
|
export default connect(select)(Ads);
|
||||||
|
export { injectAd };
|
||||||
|
|
|
@ -36,7 +36,7 @@ type Props = {
|
||||||
claim: Claim,
|
claim: Claim,
|
||||||
isMature: boolean,
|
isMature: boolean,
|
||||||
authenticated: boolean,
|
authenticated: boolean,
|
||||||
triggerBlacklist: boolean
|
triggerBlacklist: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
function removeIfExists(querySelector) {
|
function removeIfExists(querySelector) {
|
||||||
|
@ -53,6 +53,8 @@ function Ads(props: Props) {
|
||||||
triggerBlacklist,
|
triggerBlacklist,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const shouldShowAds = SHOW_ADS && !authenticated;
|
||||||
|
|
||||||
// load ad and tags here
|
// load ad and tags here
|
||||||
let scriptUrlToUse;
|
let scriptUrlToUse;
|
||||||
let tagNameToUse;
|
let tagNameToUse;
|
||||||
|
@ -71,7 +73,9 @@ function Ads(props: Props) {
|
||||||
|
|
||||||
// add script to DOM
|
// add script to DOM
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (SHOW_ADS && !authenticated) {
|
if (isFirefoxAndroid) return;
|
||||||
|
|
||||||
|
if (shouldShowAds) {
|
||||||
let script;
|
let script;
|
||||||
try {
|
try {
|
||||||
script = document.createElement('script');
|
script = document.createElement('script');
|
||||||
|
@ -155,4 +159,128 @@ function Ads(props: Props) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns true if passed element is fully visible on screen
|
||||||
|
function isScrolledIntoView(el) {
|
||||||
|
const rect = el.getBoundingClientRect();
|
||||||
|
const elemTop = rect.top;
|
||||||
|
const elemBottom = rect.bottom;
|
||||||
|
|
||||||
|
// Only completely visible elements return true:
|
||||||
|
const isVisible = elemTop >= 0 && elemBottom <= window.innerHeight;
|
||||||
|
return isVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function injectAd(shouldShowAds: boolean) {
|
||||||
|
// don't inject on firefox android or for authenticated users or no ads on instance
|
||||||
|
if (isFirefoxAndroid || !shouldShowAds) return;
|
||||||
|
// test if adblock is enabled
|
||||||
|
let adBlockEnabled = false;
|
||||||
|
const googleAdUrl = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
||||||
|
try {
|
||||||
|
await fetch(new Request(googleAdUrl)).catch((_) => {
|
||||||
|
adBlockEnabled = true;
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
adBlockEnabled = true;
|
||||||
|
} finally {
|
||||||
|
if (!adBlockEnabled) {
|
||||||
|
// select the cards on page
|
||||||
|
let cards = document.getElementsByClassName('card claim-preview--tile');
|
||||||
|
// eslint-disable-next-line no-inner-declarations
|
||||||
|
function checkFlag() {
|
||||||
|
if (cards.length === 0) {
|
||||||
|
window.setTimeout(checkFlag, 100);
|
||||||
|
} else {
|
||||||
|
// find the last fully visible card
|
||||||
|
let lastCard;
|
||||||
|
|
||||||
|
// width of browser window
|
||||||
|
const windowWidth = window.innerWidth;
|
||||||
|
|
||||||
|
// on small screens, grab the second item
|
||||||
|
if (windowWidth <= 900) {
|
||||||
|
lastCard = cards[1];
|
||||||
|
} else {
|
||||||
|
// otherwise, get the last fully visible card
|
||||||
|
for (const card of cards) {
|
||||||
|
const isFullyVisible = isScrolledIntoView(card);
|
||||||
|
if (!isFullyVisible) break;
|
||||||
|
lastCard = card;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no last card was found, just exit the function to not cause errors
|
||||||
|
if (!lastCard) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clone the last card
|
||||||
|
// $FlowFixMe
|
||||||
|
const clonedCard = lastCard.cloneNode(true);
|
||||||
|
|
||||||
|
// insert cloned card
|
||||||
|
// $FlowFixMe
|
||||||
|
lastCard.parentNode.insertBefore(clonedCard, lastCard);
|
||||||
|
|
||||||
|
// change the appearance of the cloned card
|
||||||
|
// $FlowFixMe
|
||||||
|
clonedCard.querySelector('.claim__menu-button').remove();
|
||||||
|
|
||||||
|
// $FlowFixMe
|
||||||
|
clonedCard.querySelector('.truncated-text').innerHTML = __(
|
||||||
|
'Hate these? Login to Odysee for an ad free experience'
|
||||||
|
);
|
||||||
|
|
||||||
|
// $FlowFixMe
|
||||||
|
clonedCard.querySelector('.claim-tile__info').remove();
|
||||||
|
|
||||||
|
// $FlowFixMe
|
||||||
|
clonedCard.querySelector('[role="none"]').removeAttribute('href');
|
||||||
|
|
||||||
|
// $FlowFixMe
|
||||||
|
clonedCard.querySelector('.claim-tile__header').firstChild.href = '/$/signin';
|
||||||
|
|
||||||
|
// $FlowFixMe
|
||||||
|
clonedCard.querySelector('.claim-tile__title').firstChild.removeAttribute('aria-label');
|
||||||
|
|
||||||
|
// $FlowFixMe
|
||||||
|
clonedCard.querySelector('.claim-tile__title').firstChild.removeAttribute('title');
|
||||||
|
|
||||||
|
// $FlowFixMe
|
||||||
|
clonedCard.querySelector('.claim-tile__header').firstChild.removeAttribute('aria-label');
|
||||||
|
|
||||||
|
// $FlowFixMe
|
||||||
|
clonedCard
|
||||||
|
.querySelector('.media__thumb')
|
||||||
|
.replaceWith(document.getElementsByClassName('homepageAdContainer')[0]);
|
||||||
|
|
||||||
|
// show the homepage ad which is not displayed at first
|
||||||
|
document.getElementsByClassName('homepageAdContainer')[0].style.display = 'block';
|
||||||
|
|
||||||
|
const thumbnail = window.getComputedStyle(lastCard.querySelector('.media__thumb'));
|
||||||
|
|
||||||
|
const styles = `#av-container, #AVcontent, #aniBox {
|
||||||
|
height: ${thumbnail.height} !important;
|
||||||
|
width: ${thumbnail.width} !important;
|
||||||
|
}`;
|
||||||
|
|
||||||
|
const styleSheet = document.createElement('style');
|
||||||
|
styleSheet.type = 'text/css';
|
||||||
|
styleSheet.id = 'customAniviewStyling';
|
||||||
|
styleSheet.innerText = styles;
|
||||||
|
|
||||||
|
// $FlowFixMe
|
||||||
|
document.head.appendChild(styleSheet);
|
||||||
|
|
||||||
|
// delete last card to not introduce layout shifts
|
||||||
|
lastCard.remove();
|
||||||
|
|
||||||
|
// addresses bug where ad doesn't show up until a scroll event
|
||||||
|
document.dispatchEvent(new CustomEvent('scroll'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkFlag();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default withRouter(Ads);
|
export default withRouter(Ads);
|
||||||
|
export { injectAd };
|
||||||
|
|
Loading…
Reference in a new issue