Commit 8f72fe60 authored by isstuev's avatar isstuev

Add AdButler as an additional ad provider

parent 9cdbf6d6
import type { Feature } from './types';
import type { AdButlerConfig } from 'types/client/adButlerConfig';
import { SUPPORTED_AD_BANNER_PROVIDERS } from 'types/client/adProviders';
import type { AdBannerProviders } from 'types/client/adProviders';
import type { AdBannerProviders, AdBannerAdditionalProviders } from 'types/client/adProviders';
import { getEnvValue, parseEnvJson } from '../utils';
......@@ -11,6 +11,8 @@ const provider: AdBannerProviders = (() => {
return envValue && SUPPORTED_AD_BANNER_PROVIDERS.includes(envValue) ? envValue : 'slise';
})();
const additionalProvider = getEnvValue('NEXT_PUBLIC_AD_BANNER_ADDITIONAL_PROVIDER') as AdBannerAdditionalProviders;
const title = 'Banner ads';
type AdsBannerFeaturePayload = {
......@@ -23,6 +25,15 @@ type AdsBannerFeaturePayload = {
mobile: AdButlerConfig;
};
};
} | {
provider: Exclude<AdBannerProviders, 'adbutler' | 'none'>;
additionalProvider: 'adbutler';
adButler: {
config: {
desktop: AdButlerConfig;
mobile: AdButlerConfig;
};
};
}
const config: Feature<AdsBannerFeaturePayload> = (() => {
......@@ -44,6 +55,24 @@ const config: Feature<AdsBannerFeaturePayload> = (() => {
});
}
} else if (provider !== 'none') {
if (additionalProvider === 'adbutler') {
const desktopConfig = parseEnvJson<AdButlerConfig>(getEnvValue('NEXT_PUBLIC_AD_ADBUTLER_CONFIG_DESKTOP'));
const mobileConfig = parseEnvJson<AdButlerConfig>(getEnvValue('NEXT_PUBLIC_AD_ADBUTLER_CONFIG_MOBILE'));
return Object.freeze({
title,
isEnabled: true,
provider,
additionalProvider,
adButler: {
config: {
desktop: desktopConfig,
mobile: mobileConfig,
},
},
});
}
return Object.freeze({
title,
isEnabled: true,
......
......@@ -9,8 +9,8 @@ declare module 'yup' {
import * as yup from 'yup';
import type { AdButlerConfig } from '../../../types/client/adButlerConfig';
import { SUPPORTED_AD_TEXT_PROVIDERS, SUPPORTED_AD_BANNER_PROVIDERS } from '../../../types/client/adProviders';
import type { AdTextProviders, AdBannerProviders } from '../../../types/client/adProviders';
import { SUPPORTED_AD_TEXT_PROVIDERS, SUPPORTED_AD_BANNER_PROVIDERS, SUPPORTED_AD_BANNER_ADDITIONAL_PROVIDERS } from '../../../types/client/adProviders';
import type { AdTextProviders, AdBannerProviders, AdBannerAdditionalProviders } from '../../../types/client/adProviders';
import type { ContractCodeIde } from '../../../types/client/contract';
import { GAS_UNITS } from '../../../types/client/gasTracker';
import type { GasUnit } from '../../../types/client/gasTracker';
......@@ -176,12 +176,23 @@ const adButlerConfigSchema = yup
height: yup.number().positive().required(),
})
.required(),
})
.when('NEXT_PUBLIC_AD_BANNER_ADDITIONAL_PROVIDER', {
is: (value: AdBannerProviders) => value === 'adbutler',
then: (schema) => schema
.shape({
id: yup.string().required(),
width: yup.number().positive().required(),
height: yup.number().positive().required(),
})
.required(),
});
const adsBannerSchema = yup
.object()
.shape({
NEXT_PUBLIC_AD_BANNER_PROVIDER: yup.string<AdBannerProviders>().oneOf(SUPPORTED_AD_BANNER_PROVIDERS),
NEXT_PUBLIC_AD_BANNER_ADDITIONAL_PROVIDER: yup.string<AdBannerAdditionalProviders>().oneOf(SUPPORTED_AD_BANNER_ADDITIONAL_PROVIDERS),
NEXT_PUBLIC_AD_ADBUTLER_CONFIG_DESKTOP: adButlerConfigSchema,
NEXT_PUBLIC_AD_ADBUTLER_CONFIG_MOBILE: adButlerConfigSchema,
});
......
NEXT_PUBLIC_AD_BANNER_PROVIDER='slise'
NEXT_PUBLIC_AD_BANNER_ADDITIONAL_PROVIDER='adbutler'
NEXT_PUBLIC_AD_ADBUTLER_CONFIG_DESKTOP={'id':'123456','width':'728','height':'90'}
NEXT_PUBLIC_AD_ADBUTLER_CONFIG_MOBILE={'id':'654321','width':'300','height':'100'}
\ No newline at end of file
......@@ -82,6 +82,9 @@ frontend:
NEXT_PUBLIC_SWAP_BUTTON_URL: uniswap
NEXT_PUBLIC_HAS_CONTRACT_AUDIT_REPORTS: true
NEXT_PUBLIC_AD_BANNER_PROVIDER: getit
NEXT_PUBLIC_AD_BANNER_ADDITIONAL_PROVIDER: adbutler
NEXT_PUBLIC_AD_ADBUTLER_CONFIG_DESKTOP: "{ \"id\": \"632019\", \"width\": \"728\", \"height\": \"90\" }"
NEXT_PUBLIC_AD_ADBUTLER_CONFIG_MOBILE: "{ \"id\": \"632018\", \"width\": \"320\", \"height\": \"100\" }"
envFromSecret:
NEXT_PUBLIC_SENTRY_DSN: ref+vault://deployment-values/blockscout/dev/review?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_SENTRY_DSN
SENTRY_CSP_REPORT_URI: ref+vault://deployment-values/blockscout/dev/review?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/SENTRY_CSP_REPORT_URI
......
......@@ -352,6 +352,7 @@ This feature is **enabled by default** with the `slise` ads provider. To switch
| Variable | Type| Description | Compulsoriness | Default value | Example value |
| --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_AD_BANNER_PROVIDER | `slise` \| `adbutler` \| `coinzilla` \| `hype` \| `getit` \| `none` | Ads provider | - | `slise` | `coinzilla` |
| NEXT_PUBLIC_AD_BANNER_ADDITIONAL_PROVIDER | `adbutler` | Additional ads provider to mix with the main one | - | - | `adbutler` |
| NEXT_PUBLIC_AD_ADBUTLER_CONFIG_DESKTOP | `{ id: string; width: string; height: string }` | Placement config for desktop Adbutler banner | - | - | `{'id':'123456','width':'728','height':'90'}` |
| NEXT_PUBLIC_AD_ADBUTLER_CONFIG_MOBILE | `{ id: string; width: number; height: number }` | Placement config for mobile Adbutler banner | - | - | `{'id':'654321','width':'300','height':'100'}` |
......
......@@ -2,6 +2,7 @@ import type { GetServerSideProps } from 'next';
import config from 'configs/app';
const rollupFeature = config.features.rollup;
const adBannerFeature = config.features.adsBanner;
export type Props = {
cookies: string;
......@@ -12,9 +13,22 @@ export type Props = {
number: string;
q: string;
name: string;
adBannerProvider?: string;
}
export const base: GetServerSideProps<Props> = async({ req, query }) => {
const adBannerProvider = (() => {
if (adBannerFeature.isEnabled) {
if ('additionalProvider' in adBannerFeature && adBannerFeature.additionalProvider) {
// we need to get a random ad provider on the server side to keep it consistent with the client side
const randomIndex = Math.round(Math.random());
return [ adBannerFeature.provider, adBannerFeature.additionalProvider ][randomIndex];
} else {
return adBannerFeature.provider;
}
}
})();
return {
props: {
cookies: req.headers.cookie || '',
......@@ -25,6 +39,7 @@ export const base: GetServerSideProps<Props> = async({ req, query }) => {
number: query.number?.toString() || '',
q: query.q?.toString() || '',
name: query.name?.toString() || '',
adBannerProvider,
},
};
};
......
......@@ -3,5 +3,8 @@ import type { ArrayElement } from 'types/utils';
export const SUPPORTED_AD_BANNER_PROVIDERS = [ 'slise', 'adbutler', 'coinzilla', 'hype', 'getit', 'none' ] as const;
export type AdBannerProviders = ArrayElement<typeof SUPPORTED_AD_BANNER_PROVIDERS>;
export const SUPPORTED_AD_BANNER_ADDITIONAL_PROVIDERS = [ 'adbutler' ] as const;
export type AdBannerAdditionalProviders = ArrayElement<typeof SUPPORTED_AD_BANNER_ADDITIONAL_PROVIDERS>;
export const SUPPORTED_AD_TEXT_PROVIDERS = [ 'coinzilla', 'none' ] as const;
export type AdTextProviders = ArrayElement<typeof SUPPORTED_AD_TEXT_PROVIDERS>;
......@@ -14,14 +14,16 @@ import SliseBanner from './SliseBanner';
const feature = config.features.adsBanner;
const AdBanner = ({ className, isLoading }: { className?: string; isLoading?: boolean }) => {
const provider = useAppContext().adBannerProvider;
const hasAdblockCookie = cookies.get(cookies.NAMES.ADBLOCK_DETECTED, useAppContext().cookies);
if (!feature.isEnabled || hasAdblockCookie) {
if (!feature.isEnabled || hasAdblockCookie || !provider) {
return null;
}
const content = (() => {
switch (feature.provider) {
switch (provider) {
case 'adbutler':
return <AdbutlerBanner/>;
case 'coinzilla':
......@@ -40,7 +42,7 @@ const AdBanner = ({ className, isLoading }: { className?: string; isLoading?: bo
className={ className }
isLoaded={ !isLoading }
borderRadius="none"
maxW={ feature.provider === 'adbutler' ? feature.adButler.config.desktop.width : '728px' }
maxW={ ('adButler' in feature && feature.adButler) ? feature.adButler.config.desktop.width : '728px' }
w="100%"
>
{ content }
......
......@@ -13,8 +13,9 @@ const feature = config.features.adsBanner;
const AdbutlerBanner = ({ className }: { className?: string }) => {
const router = useRouter();
const isMobile = useIsMobile();
React.useEffect(() => {
if (!feature.isEnabled || feature.provider !== 'adbutler') {
if (!('adButler' in feature)) {
return;
}
......
......@@ -8,7 +8,7 @@ export const connectAdbutler = `if (!window.AdButler){(function(){var s = docume
export const placeAd = (() => {
const feature = config.features.adsBanner;
if (!feature.isEnabled || feature.provider !== 'adbutler') {
if (!('adButler' in feature)) {
return;
}
......
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