Commit 34a1d7f5 authored by Igor Stuev's avatar Igor Stuev Committed by GitHub

Merge pull request #399 from blockscout/add-ad

ad banners
parents a45684aa 1a7f145e
......@@ -37,6 +37,8 @@ NEXT_PUBLIC_HOMEPAGE_CHARTS=__PLACEHOLDER_FOR_NEXT_PUBLIC_HOMEPAGE_CHARTS__
NEXT_PUBLIC_HOMEPAGE_PLATE_GRADIENT=__PLACEHOLDER_FOR_NEXT_PUBLIC_HOMEPAGE_PLATE_GRADIENT__
NEXT_PUBLIC_HOMEPAGE_SHOW_GAS_TRACKER=__PLACEHOLDER_FOR_NEXT_PUBLIC_HOMEPAGE_SHOW_GAS_TRACKER__
NEXT_PUBLIC_HOMEPAGE_SHOW_AVG_BLOCK_TIME=__PLACEHOLDER_FOR_NEXT_PUBLIC_HOMEPAGE_SHOW_AVG_BLOCK_TIME__
NEXT_PUBLIC_AD_DOMAIN_WITH_AD=__PLACEHOLDER_FOR_NEXT_PUBLIC_DOMAIN_WITH_AD__
NEXT_PUBLIC_AD_ADBUTLER_ON=__PLACEHOLDER_FORNEXT_PUBLIC_AD_ADBUTLER_ON__
# api config
NEXT_PUBLIC_API_HOST=__PLACEHOLDER_FOR_NEXT_PUBLIC_API_HOST__
......
......@@ -76,7 +76,8 @@ The app instance could be customized by passing following variables to NodeJS en
| NEXT_PUBLIC_HOMEPAGE_PLATE_GRADIENT | `string` *(optional)* | Gradient value for hero plate on the homepage | `radial-gradient(at 15% 86%, hsla(350,65%,70%,1) 0px, transparent 50%), radial-gradient(at 72% 57%, hsla(14,95%,76%,1) 0px, transparent 50%)` |
| NEXT_PUBLIC_HOMEPAGE_SHOW_GAS_TRACKER | `boolean` *(optional)* | Set to false if network doesn't have gas tracker | `true` |
| NEXT_PUBLIC_HOMEPAGE_SHOW_AVG_BLOCK_TIME | `boolean` *(optional)* | Set to false if average block time is useless for the network | `true` |
| NEXT_PUBLIC_DOMAIN_WITH_AD | `string` *(optional)* | The domain on which we display ads | `blockscout.com` |
| NEXT_PUBLIC_AD_ADBUTLER_ON | `boolean` *(optional)* | Set to true to show Adbutler banner instead of Coinzilla banner | `false` |
### App configuration
| Variable | Type | Description | Default value
......
......@@ -85,6 +85,10 @@ const config = Object.freeze({
baseUrl,
authUrl,
logoutUrl,
ad: {
domainWithAd: getEnvValue(process.env.NEXT_PUBLIC_AD_DOMAIN_WITH_AD) || 'blockscout.com',
adButlerOn: getEnvValue(process.env.NEXT_PUBLIC_AD_ADBUTLER_ON) === 'true',
},
api: {
endpoint: apiHost ? `https://${ apiHost }` : 'https://blockscout.com',
socket: apiHost ? `wss://${ apiHost }` : 'wss://blockscout.com',
......
......@@ -63,6 +63,9 @@ function makePolicyMap() {
'sentry.io', '*.sentry.io',
appConfig.api.socket,
// ad
'request-global.czilladx.com',
],
'script-src': [
......@@ -76,6 +79,12 @@ function makePolicyMap() {
// hash of ColorModeScript
'\'sha256-e7MRMmTzLsLQvIy1iizO1lXf7VWYoQ6ysj5fuUzvRwE=\'',
// ad
'coinzillatag.com',
'servedbyadbutler.com',
'\'sha256-wMOeDjJaOTjCfNjluteV+tSqHW547T89sgxd8W6tQJM=\'',
'\'sha256-FcyIn1h7zra8TVnnRhYrwrplxJW7dpD5TV7kP2AG/kI=\'',
],
'style-src': [
......@@ -113,6 +122,9 @@ function makePolicyMap() {
// marketplace apps logos
...getMarketplaceAppsLogosOrigins().map((url) => url.host),
// ad
'servedbyadbutler.com',
],
'font-src': [
......@@ -135,7 +147,12 @@ function makePolicyMap() {
KEY_WORDS.NONE,
],
'frame-src': getMarketplaceAppsOrigins(),
'frame-src': [
...getMarketplaceAppsOrigins(),
// ad
'request-global.czilladx.com',
],
...(REPORT_URI ? {
'report-uri': [
......
import appConfig from 'configs/app/config';
export default function isSelfHosted() {
return appConfig.host?.endsWith(appConfig.ad.domainWithAd) || appConfig.host === 'localhost';
}
export default async function insertAdText() {
const ad = document.getElementsByClassName('coinzilla');
ad[0].textContent = 'coinzilla banner!';
}
......@@ -5,6 +5,7 @@ import * as blockMock from 'mocks/blocks/block';
import * as dailyTxsMock from 'mocks/stats/daily_txs';
import * as statsMock from 'mocks/stats/index';
import * as txMock from 'mocks/txs/tx';
import insertAdText from 'playwright/scripts/insertAdText';
import TestApp from 'playwright/TestApp';
import Home from './Home';
......@@ -40,5 +41,7 @@ test('default view -@default +@desktop-xl +@mobile +@dark-mode', async({ mount,
</TestApp>,
);
await page.evaluate(insertAdText);
await expect(component).toHaveScreenshot();
});
......@@ -6,6 +6,7 @@ import ChainIndicators from 'ui/home/indicators/ChainIndicators';
import LatestBlocks from 'ui/home/LatestBlocks';
import LatestTxs from 'ui/home/LatestTxs';
import Stats from 'ui/home/Stats';
import AdBanner from 'ui/shared/ad/AdBanner';
import Page from 'ui/shared/Page/Page';
import ColorModeToggler from 'ui/snippets/header/ColorModeToggler';
import ProfileMenuDesktop from 'ui/snippets/profileMenu/ProfileMenuDesktop';
......@@ -47,6 +48,7 @@ const Home = () => {
</Box>
<Stats/>
<ChainIndicators/>
<AdBanner mt={{ base: 6, lg: 8 }} justifyContent="center"/>
<Flex mt={ 8 } direction={{ base: 'column', lg: 'row' }} columnGap={ 12 } rowGap={ 8 }>
<LatestBlocks/>
<LatestTxs/>
......
......@@ -11,6 +11,7 @@ import { useAppContext } from 'lib/appContext';
import useFetch from 'lib/hooks/useFetch';
import isBrowser from 'lib/isBrowser';
import networkExplorers from 'lib/networks/networkExplorers';
import AdBanner from 'ui/shared/ad/AdBanner';
import ExternalLink from 'ui/shared/ExternalLink';
import Page from 'ui/shared/Page/Page';
import PageTitle from 'ui/shared/Page/PageTitle';
......@@ -83,6 +84,7 @@ const TransactionPageContent = () => {
) }
</Flex>
<RoutedTabs tabs={ TABS }/>
<AdBanner mt={ 6 } justifyContent={{ base: 'center', lg: 'start' }}/>
</Page>
);
};
......
import { chakra } from '@chakra-ui/react';
import React from 'react';
import appConfig from 'configs/app/config';
import isSelfHosted from 'lib/isSelfHosted';
import AdbutlerBanner from './AdbutlerBanner';
import CoinzillaBanner from './CoinzillaBanner';
const AdBanner = ({ className }: { className?: string }) => {
if (!isSelfHosted()) {
return null;
}
if (appConfig.ad.adButlerOn) {
return <AdbutlerBanner className={ className }/>;
}
return <CoinzillaBanner className={ className }/>;
};
export default chakra(AdBanner);
/* eslint-disable max-len */
import { Flex, chakra } from '@chakra-ui/react';
import React from 'react';
// eslint-disable-next-line @typescript-eslint/no-var-requires
// const adbutlerHTML = require('ui/shared/ad/adbutler.html');
// didn't find a way to raw-load html that works both for webpack (app build) and vite (playwright build)
const adbutlerHTML = `
<div id="ad-banner"></div>
<script type="text/javascript">if (!window.AdButler){(function(){var s = document.createElement("script"); s.async = true; s.type = "text/javascript";s.src = 'https://servedbyadbutler.com/app.js';var n = document.getElementsByTagName("script")[0]; n.parentNode.insertBefore(s, n);}());}</script>
<script type="text/javascript">
var AdButler = AdButler || {}; AdButler.ads = AdButler.ads || [];
var abkw = window.abkw || '';
const isMobile = window.matchMedia("only screen and (max-width: 760px)").matches;
if (isMobile) {
var plc539876 = window.plc539876 || 0;
document.getElementById('ad-banner').innerHTML += '<'+'div id="placement_539876_'+plc539876+'"></'+'div>';
document.getElementById("ad-banner").className = "ad-container mb-3";
AdButler.ads.push({handler: function(opt){ AdButler.register(182226, 539876, [320,100], 'placement_539876_'+opt.place, opt); }, opt: { place: plc539876++, keywords: abkw, domain: 'servedbyadbutler.com', click:'CLICK_MACRO_PLACEHOLDER' }});
} else {
var plc523705 = window.plc523705 || 0;
document.getElementById('ad-banner').innerHTML += '<'+'div id="placement_523705_'+plc523705+'"></'+'div>';
AdButler.ads.push({handler: function(opt){ AdButler.register(182226, 523705, [728,90], 'placement_523705_'+opt.place, opt); }, opt: { place: plc523705++, keywords: abkw, domain: 'servedbyadbutler.com', click:'CLICK_MACRO_PLACEHOLDER' }});
}
</script>
`;
const AdbutlerBanner = ({ className }: { className?: string }) => {
return (
<Flex className={ className } dangerouslySetInnerHTML={{ __html: adbutlerHTML }}/>
);
};
export default chakra(AdbutlerBanner);
import { Flex, chakra } from '@chakra-ui/react';
import React from 'react';
import isBrowser from 'lib/isBrowser';
declare global {
interface Window {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
coinzilla_display: any;
}
}
type CPreferences = {
zone: string;
width: string;
height: string;
}
const CoinzillaBanner = ({ className }: { className?: string }) => {
const isInBrowser = isBrowser();
if (isInBrowser) {
window.coinzilla_display = window.coinzilla_display || [];
const cDisplayPreferences = {} as CPreferences;
cDisplayPreferences.zone = '26660bf627543e46851';
cDisplayPreferences.width = '728';
cDisplayPreferences.height = '90';
window.coinzilla_display.push(cDisplayPreferences);
}
return (
<Flex className={ className }>
<script async src="https://coinzillatag.com/lib/display.js"></script>
<div className="coinzilla" data-zone="C-26660bf627543e46851"></div>
</Flex>
);
};
export default chakra(CoinzillaBanner);
<div id="ad-banner"></div>
<script type="text/javascript">if (!window.AdButler){(function(){var s = document.createElement("script"); s.async = true; s.type = "text/javascript";s.src = 'https://servedbyadbutler.com/app.js';var n = document.getElementsByTagName("script")[0]; n.parentNode.insertBefore(s, n);}());}</script>
<script type="text/javascript">
var AdButler = AdButler || {}; AdButler.ads = AdButler.ads || [];
var abkw = window.abkw || '';
const isMobile = window.matchMedia("only screen and (max-width: 760px)").matches;
if (isMobile) {
var plc539876 = window.plc539876 || 0;
document.getElementById('ad-banner').innerHTML += '<'+'div id="placement_539876_'+plc539876+'"></'+'div>';
document.getElementById("ad-banner").className = "ad-container mb-3";
AdButler.ads.push({handler: function(opt){ AdButler.register(182226, 539876, [320,100], 'placement_539876_'+opt.place, opt); }, opt: { place: plc539876++, keywords: abkw, domain: 'servedbyadbutler.com', click:'CLICK_MACRO_PLACEHOLDER' }});
} else {
var plc523705 = window.plc523705 || 0;
document.getElementById('ad-banner').innerHTML += '<'+'div id="placement_523705_'+plc523705+'"></'+'div>';
AdButler.ads.push({handler: function(opt){ AdButler.register(182226, 523705, [728,90], 'placement_523705_'+opt.place, opt); }, opt: { place: plc523705++, keywords: abkw, domain: 'servedbyadbutler.com', click:'CLICK_MACRO_PLACEHOLDER' }});
}
</script>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment