mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00

* Admob will now initialize 2 seconds after the app loads, giving more control to when it starts. This is particularily helpful for App Store validations, with Tracking Authorization message. * New conditions are available to know AdMob initialization status: "AdMob initializing" and "AdMob Initialized". * New action to stop the auto-initialization: "Prevent AdMob auto initialization" and new action to trigger the initialization: "Initialize AdMob manually". * Typically, you'd prevent the initialization at the beginning of the scene, and trigger it manually when a user interacts with a button or something, so you can control when they'll see the consent messages.
825 lines
26 KiB
TypeScript
825 lines
26 KiB
TypeScript
namespace gdjs {
|
|
declare var admob: any;
|
|
declare var cordova: any;
|
|
declare var consent: any;
|
|
|
|
export namespace adMob {
|
|
const logger = new gdjs.Logger('AdMob');
|
|
|
|
const testAdIds = {
|
|
appOpen: {
|
|
android: 'ca-app-pub-3940256099942544/9257395921',
|
|
ios: 'ca-app-pub-3940256099942544/5575463023',
|
|
},
|
|
banner: {
|
|
android: 'ca-app-pub-3940256099942544/6300978111',
|
|
ios: 'ca-app-pub-3940256099942544/2934735716',
|
|
},
|
|
interstitial: {
|
|
android: 'ca-app-pub-3940256099942544/1033173712',
|
|
ios: 'ca-app-pub-3940256099942544/4411468910',
|
|
},
|
|
interstitialVideo: {
|
|
android: 'ca-app-pub-3940256099942544/8691691433',
|
|
ios: 'ca-app-pub-3940256099942544/5135589807',
|
|
},
|
|
rewarded: {
|
|
android: 'ca-app-pub-3940256099942544/5224354917',
|
|
ios: 'ca-app-pub-3940256099942544/1712485313',
|
|
},
|
|
rewardedInterstitial: {
|
|
android: 'ca-app-pub-3940256099942544/5354046379',
|
|
ios: 'ca-app-pub-3940256099942544/6978759866',
|
|
},
|
|
native: {
|
|
android: 'ca-app-pub-3940256099942544/2247696110',
|
|
ios: 'ca-app-pub-3940256099942544/3986624511',
|
|
},
|
|
nativeVideo: {
|
|
android: 'ca-app-pub-3940256099942544/1044960115',
|
|
ios: 'ca-app-pub-3940256099942544/2521693316',
|
|
},
|
|
};
|
|
|
|
enum AdSizeType {
|
|
BANNER,
|
|
LARGE_BANNER,
|
|
MEDIUM_RECTANGLE,
|
|
FULL_BANNER,
|
|
LEADERBOARD,
|
|
SMART_BANNER,
|
|
}
|
|
|
|
const adSizeTypes = {
|
|
BANNER: AdSizeType.BANNER,
|
|
LARGE_BANNER: AdSizeType.LARGE_BANNER,
|
|
MEDIUM_RECTANGLE: AdSizeType.MEDIUM_RECTANGLE,
|
|
FULL_BANNER: AdSizeType.FULL_BANNER,
|
|
LEADERBOARD: AdSizeType.LEADERBOARD,
|
|
SMART_BANNER: AdSizeType.SMART_BANNER,
|
|
};
|
|
|
|
enum AppOpenAdOrientation {
|
|
Portrait = 1,
|
|
PortraitUpsideDown = 2,
|
|
LandscapeRight = 3,
|
|
LandscapeLeft = 4,
|
|
}
|
|
|
|
// Admob does not initialize automatically, so we store a flag to know if it's initialized.
|
|
let admobStarted = false;
|
|
let isStarting = false;
|
|
let isUsingTestAds = false;
|
|
|
|
// Banner
|
|
let banner;
|
|
let bannerRequestedAdSizeType: AdSizeType = AdSizeType.SMART_BANNER;
|
|
let bannerConfigured = false; // Becomes true when the user configures the ad id and the position of the banner.
|
|
let bannerLoaded = false; // Becomes true when the banner is loaded by loaded.
|
|
let bannerShowing = false; // Becomes true when loaded or when the user shows/hides the banner.
|
|
let bannerErrored = false; // Becomes true when the banner fails to load.
|
|
|
|
// Interstitial
|
|
let interstitial;
|
|
let interstitialLoading = false; // Becomes true when the interstitial is loading.
|
|
let interstitialReady = false; // Becomes true when the interstitial is loaded and ready to be shown.
|
|
let interstitialShowing = false; // Becomes true when the interstitial is showing.
|
|
let interstitialErrored = false; // Becomes true when the interstitial fails to load.
|
|
|
|
// App Open
|
|
let appOpen;
|
|
let appOpenLoading = false; // Becomes true when the appOpen is loading.
|
|
let appOpenReady = false; // Becomes true when the appOpen is loaded and ready to be shown.
|
|
let appOpenShowing = false; // Becomes true when the appOpen is showing.
|
|
let appOpenErrored = false; // Becomes true when the appOpen fails to load.
|
|
|
|
// Rewarded interstitial
|
|
let rewardedInterstitial;
|
|
let rewardedInterstitialLoading = false; // Becomes true when the interstitial is loading.
|
|
let rewardedInterstitialReady = false; // Becomes true when the interstitial is loaded and ready to be shown.
|
|
let rewardedInterstitialShowing = false; // Becomes true when the interstitial is showing.
|
|
let rewardedInterstitialRewardReceived = false; // Becomes true when the interstitial is closed and the reward is received.
|
|
let rewardedInterstitialErrored = false; // Becomes true when the interstitial fails to load.
|
|
|
|
// Rewarded video
|
|
let rewardedVideo;
|
|
let rewardedVideoLoading = false; // Becomes true when the video is loading.
|
|
let rewardedVideoReady = false; // Becomes true when the video is loaded and ready to be shown.
|
|
let rewardedVideoShowing = false; // Becomes true when the video is showing.
|
|
let rewardedVideoRewardReceived = false; // Becomes true when the video is closed and the reward is received.
|
|
let rewardedVideoErrored = false; // Becomes true when the video fails to load.
|
|
|
|
let npaValue = '0'; // 0 means that the user has consented to personalized ads, 1 means that the user has not consented to personalized ads.
|
|
|
|
let setupTimeoutId: NodeJS.Timeout | null = null;
|
|
|
|
const askForConsentAndInitializeAdmob = async () => {
|
|
if (admobStarted) {
|
|
logger.warn('AdMob is already started.');
|
|
return;
|
|
}
|
|
|
|
if (isStarting) {
|
|
logger.warn('AdMob is already starting.');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
logger.info('Starting AdMob.');
|
|
isStarting = true;
|
|
|
|
if (cordova.platformId === 'ios') {
|
|
try {
|
|
/*
|
|
trackingStatus:
|
|
0 = notDetermined
|
|
1 = restricted
|
|
2 = denied
|
|
3 = authorized
|
|
*/
|
|
let trackingStatus = await consent.trackingAuthorizationStatus();
|
|
|
|
// If tracking is not determined, we ask the user for tracking authorization.
|
|
if (trackingStatus === 0) {
|
|
trackingStatus = await consent.requestTrackingAuthorization();
|
|
}
|
|
|
|
// If tracking is restricted or denied, we set npaValue to 1.
|
|
if (trackingStatus === 1 || trackingStatus === 2) {
|
|
npaValue = '1';
|
|
}
|
|
|
|
// otherwise, we set npaValue to 0.
|
|
npaValue = '0';
|
|
} catch (error) {
|
|
logger.error(
|
|
'Error while asking for tracking authorization, continuing:',
|
|
error
|
|
);
|
|
}
|
|
}
|
|
|
|
try {
|
|
// ConsentStatus:
|
|
// Unknown = 0,
|
|
// Required = 1,
|
|
// NotRequired = 2,
|
|
// Obtained = 3,
|
|
const consentStatus = await consent.getConsentStatus();
|
|
if (consentStatus === consent.ConsentStatus.Required) {
|
|
await consent.requestInfoUpdate();
|
|
}
|
|
await consent.loadAndShowIfRequired();
|
|
} catch (error) {
|
|
logger.error('Error while asking for consent, continuing:', error);
|
|
}
|
|
|
|
// We should be looking at canRequestAds to know if we can request ads or not.
|
|
// But as we want to be able to test ads in debug or if the consent didn't work,
|
|
// we ignore this value for now.
|
|
// const canRequestAds = await consent.canRequestAds();
|
|
if (true) {
|
|
await admob.start();
|
|
|
|
logger.info('AdMob successfully started.');
|
|
isStarting = false;
|
|
admobStarted = true;
|
|
}
|
|
} catch (error) {
|
|
logger.error('Error while starting AdMob:', error);
|
|
isStarting = false;
|
|
admobStarted = false;
|
|
}
|
|
};
|
|
|
|
// Admob initialization listener
|
|
document.addEventListener(
|
|
'deviceready',
|
|
async () => {
|
|
isStarting = true;
|
|
setupTimeoutId = setTimeout(async () => {
|
|
isStarting = false; // Reset to false, as it will be set to true in askForConsentAndInitializeAdmob.
|
|
await askForConsentAndInitializeAdmob();
|
|
// Wait a bit before starting admob, to avoid the consent appearing too soon.
|
|
}, 2000);
|
|
},
|
|
false
|
|
);
|
|
|
|
export const preventAdmobAutoInitialization = () => {
|
|
if (setupTimeoutId) {
|
|
isStarting = false;
|
|
clearTimeout(setupTimeoutId);
|
|
setupTimeoutId = null;
|
|
}
|
|
};
|
|
|
|
export const initializeAdmob = async () => {
|
|
preventAdmobAutoInitialization();
|
|
await askForConsentAndInitializeAdmob();
|
|
};
|
|
|
|
export const isAdmobInitialized = () => admobStarted;
|
|
export const isAdmobInitializing = () => isStarting;
|
|
|
|
/**
|
|
* Helper to know if we are on mobile and admob is correctly initialized.
|
|
*/
|
|
const checkIfAdMobIsAvailable = async () => {
|
|
if (typeof cordova === 'undefined') {
|
|
logger.warn('We are not on mobile, AdMob will not be available.');
|
|
return false;
|
|
}
|
|
if (typeof admob === 'undefined') {
|
|
logger.warn('AdMob has not been configured properly.');
|
|
return false;
|
|
}
|
|
|
|
if (!admobStarted) {
|
|
if (isStarting) {
|
|
// Delay the call until AdMob is started, up to 5 seconds.
|
|
let time = 0;
|
|
while (!admobStarted && time < 5000) {
|
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
time += 100;
|
|
}
|
|
}
|
|
|
|
if (!admobStarted) {
|
|
logger.warn('AdMob is not started.');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* Helper to get the correct ad id depending on the platform. Android and iOS use different ids.
|
|
*/
|
|
const getAdUnitId = (androidAdUnitId, iosAdUnitId, type) => {
|
|
if (typeof cordova === 'undefined') {
|
|
logger.warn('Cordova is not available.');
|
|
return;
|
|
}
|
|
if (cordova.platformId === 'android') {
|
|
return isUsingTestAds ? testAdIds[type].android : androidAdUnitId;
|
|
} else if (cordova.platformId === 'ios') {
|
|
return isUsingTestAds ? testAdIds[type].ios : iosAdUnitId;
|
|
}
|
|
|
|
logger.error('Unsupported platform: ', cordova.platformId);
|
|
return null;
|
|
};
|
|
|
|
/**
|
|
* Activate or deactivate the test mode ("development" mode).
|
|
* When activated, tests ads will be served instead of real ones.
|
|
*
|
|
* It is important to enable test ads during development so that you can click on them without
|
|
* charging advertisers. If you click on too many ads without being in test mode, you risk your
|
|
* account being flagged for invalid activity.
|
|
*/
|
|
export const setTestMode = async (enable: boolean) => {
|
|
if (!(await checkIfAdMobIsAvailable())) return;
|
|
|
|
logger.info('Setting AdMob test mode to:', enable);
|
|
|
|
isUsingTestAds = enable;
|
|
};
|
|
|
|
// -------------------
|
|
// ---- App Open -----
|
|
// -------------------
|
|
export const isAppOpenLoading = () => appOpenLoading;
|
|
export const isAppOpenReady = () => appOpenReady;
|
|
export const isAppOpenShowing = () => appOpenShowing;
|
|
export const isAppOpenErrored = () => appOpenErrored;
|
|
|
|
/** Load an AppOpen. */
|
|
export const loadAppOpen = async (
|
|
androidAdUnitId,
|
|
iosAdUnitId,
|
|
displayLandscape,
|
|
displayWhenLoaded
|
|
) => {
|
|
if (!(await checkIfAdMobIsAvailable())) return;
|
|
// If an appOpen is already loading or showing, we don't stop it.
|
|
if (appOpenLoading || appOpenShowing) {
|
|
return;
|
|
}
|
|
|
|
const adUnitId = getAdUnitId(androidAdUnitId, iosAdUnitId, 'appOpen');
|
|
if (!adUnitId) return;
|
|
|
|
appOpenLoading = true;
|
|
appOpenReady = false;
|
|
appOpenErrored = false;
|
|
|
|
appOpen = new admob.AppOpenAd({
|
|
adUnitId,
|
|
orientation: displayLandscape
|
|
? AppOpenAdOrientation.LandscapeLeft
|
|
: AppOpenAdOrientation.Portrait,
|
|
});
|
|
|
|
appOpen.on('load', () => {
|
|
appOpenReady = true;
|
|
appOpenLoading = false;
|
|
});
|
|
appOpen.on('loadfail', () => {
|
|
appOpenLoading = false;
|
|
appOpenErrored = true;
|
|
});
|
|
appOpen.on('show', () => {
|
|
appOpenShowing = true;
|
|
appOpenReady = false;
|
|
});
|
|
appOpen.on('showfail', () => {
|
|
appOpenShowing = false;
|
|
appOpenErrored = true;
|
|
});
|
|
appOpen.on('dismiss', () => {
|
|
appOpenShowing = false;
|
|
});
|
|
|
|
try {
|
|
logger.info('Loading Admob App Open.');
|
|
await appOpen.load();
|
|
logger.info('AdMob App Open successfully loaded.');
|
|
appOpenLoading = false;
|
|
appOpenReady = true;
|
|
if (displayWhenLoaded) showAppOpen();
|
|
} catch (error) {
|
|
logger.error('Error while loading an App Open:', error);
|
|
appOpenLoading = false;
|
|
appOpenReady = false;
|
|
appOpenErrored = true;
|
|
}
|
|
};
|
|
|
|
/** Show the loaded appOpen. */
|
|
export const showAppOpen = async () => {
|
|
if (!(await checkIfAdMobIsAvailable())) return;
|
|
|
|
if (!appOpen) {
|
|
logger.warn('App Open has not been set up, call loadAppOpen first.');
|
|
return;
|
|
}
|
|
if (!appOpenReady) {
|
|
logger.info('App Open not loaded yet, cannot display it.');
|
|
return;
|
|
}
|
|
appOpenErrored = false;
|
|
|
|
try {
|
|
logger.info('Showing AdMob App Open.');
|
|
await appOpen.show();
|
|
// AppOpen will be shown and
|
|
// `appOpenShowing` will be updated thanks to events
|
|
// (but it's too early to change it now).
|
|
} catch (error) {
|
|
logger.error('Error while showing an AdMob App Open:', error);
|
|
appOpenShowing = false;
|
|
appOpenErrored = true;
|
|
}
|
|
};
|
|
|
|
// -----------------
|
|
// ---- Banner -----
|
|
// -----------------
|
|
export const isBannerConfigured = () => bannerConfigured;
|
|
export const isBannerLoaded = () => bannerLoaded;
|
|
export const isBannerShowing = () => bannerShowing;
|
|
export const isBannerErrored = () => bannerErrored;
|
|
|
|
export const setBannerAdSizeType = (
|
|
bannerAdSizeType:
|
|
| 'BANNER'
|
|
| 'LARGE_BANNER'
|
|
| 'MEDIUM_RECTANGLE'
|
|
| 'FULL_BANNER'
|
|
| 'LEADERBOARD'
|
|
| 'SMART_BANNER'
|
|
) => {
|
|
bannerRequestedAdSizeType =
|
|
adSizeTypes[bannerAdSizeType] || AdSizeType.SMART_BANNER;
|
|
};
|
|
|
|
/**
|
|
* Set up a banner that can then be displayed by calling `showBanner`.
|
|
* If a banner is already set up, it will be hidden and replaced by the new one.
|
|
*/
|
|
export const setupBanner = async (androidAdUnitId, iosAdUnitId, atTop) => {
|
|
if (!(await checkIfAdMobIsAvailable())) return;
|
|
const adUnitId = getAdUnitId(androidAdUnitId, iosAdUnitId, 'banner');
|
|
if (!adUnitId) return;
|
|
|
|
if (banner && bannerShowing) {
|
|
logger.info('Banner already visible, hiding it to display new one.');
|
|
await hideBanner();
|
|
}
|
|
|
|
bannerConfigured = false;
|
|
bannerLoaded = false;
|
|
|
|
banner = new admob.BannerAd({
|
|
adUnitId,
|
|
position: atTop ? 'top' : 'bottom',
|
|
size: bannerRequestedAdSizeType,
|
|
offset: 0,
|
|
npa: npaValue,
|
|
});
|
|
|
|
banner.on('load', () => {
|
|
bannerShowing = true;
|
|
bannerLoaded = true;
|
|
});
|
|
banner.on('loadfail', () => {
|
|
bannerShowing = false;
|
|
bannerLoaded = false;
|
|
bannerErrored = true;
|
|
});
|
|
|
|
bannerConfigured = true;
|
|
};
|
|
|
|
/**
|
|
* Display a banner that was set up with `setupBanner` (and `setBannerAdSizeType`).
|
|
*/
|
|
export const showBanner = async () => {
|
|
if (!banner) {
|
|
logger.info('Banner not configured, use setupBanner first.');
|
|
return;
|
|
}
|
|
if (bannerShowing) {
|
|
logger.info('Banner already visible. Ignoring.');
|
|
return;
|
|
}
|
|
bannerErrored = false;
|
|
|
|
try {
|
|
logger.info('Showing AdMob banner.');
|
|
await banner.show();
|
|
if (bannerLoaded) {
|
|
// Banner is already loaded, so it will be shown immediately.
|
|
bannerShowing = true;
|
|
}
|
|
} catch (error) {
|
|
bannerShowing = false;
|
|
bannerErrored = true;
|
|
logger.error('Error while showing an AdMob banner:', error);
|
|
}
|
|
};
|
|
|
|
/** Hide the banner shown on screen. */
|
|
export const hideBanner = async () => {
|
|
if (!(await checkIfAdMobIsAvailable())) return;
|
|
|
|
if (!banner || !bannerShowing) {
|
|
logger.warn('No banner is being shown.');
|
|
return;
|
|
}
|
|
|
|
await banner.hide();
|
|
bannerShowing = false;
|
|
// Note that the banner is still loaded, which is why bannerLoaded is not set to false.
|
|
// We hide the banner, but keep it configured to display it again if needed.
|
|
};
|
|
|
|
// -----------------------
|
|
// ---- Interstitial -----
|
|
// -----------------------
|
|
export const isInterstitialLoading = () => interstitialLoading;
|
|
export const isInterstitialReady = () => interstitialReady;
|
|
export const isInterstitialShowing = () => interstitialShowing;
|
|
export const isInterstitialErrored = () => interstitialErrored;
|
|
|
|
/** Load an interstitial. */
|
|
export const loadInterstitial = async (
|
|
androidAdUnitId,
|
|
iosAdUnitId,
|
|
displayWhenLoaded
|
|
) => {
|
|
if (!(await checkIfAdMobIsAvailable())) return;
|
|
// If an interstitial is already loading or showing, we don't stop it.
|
|
if (interstitialLoading || interstitialShowing) {
|
|
return;
|
|
}
|
|
|
|
const adUnitId = getAdUnitId(
|
|
androidAdUnitId,
|
|
iosAdUnitId,
|
|
'interstitial'
|
|
);
|
|
if (!adUnitId) return;
|
|
|
|
interstitialLoading = true;
|
|
interstitialReady = false;
|
|
interstitialErrored = false;
|
|
|
|
interstitial = new admob.InterstitialAd({
|
|
adUnitId,
|
|
npa: npaValue,
|
|
});
|
|
|
|
interstitial.on('load', () => {
|
|
interstitialReady = true;
|
|
interstitialLoading = false;
|
|
});
|
|
interstitial.on('loadfail', () => {
|
|
interstitialLoading = false;
|
|
interstitialErrored = true;
|
|
});
|
|
interstitial.on('show', () => {
|
|
interstitialShowing = true;
|
|
interstitialReady = false;
|
|
});
|
|
interstitial.on('showfail', () => {
|
|
interstitialShowing = false;
|
|
interstitialErrored = true;
|
|
});
|
|
interstitial.on('dismiss', () => {
|
|
interstitialShowing = false;
|
|
});
|
|
|
|
try {
|
|
logger.info('Loading Admob interstitial.');
|
|
await interstitial.load();
|
|
logger.info('AdMob interstitial successfully loaded.');
|
|
interstitialLoading = false;
|
|
interstitialReady = true;
|
|
if (displayWhenLoaded) showInterstitial();
|
|
} catch (error) {
|
|
logger.error('Error while loading a interstitial:', error);
|
|
interstitialLoading = false;
|
|
interstitialReady = false;
|
|
interstitialErrored = true;
|
|
}
|
|
};
|
|
|
|
/** Show the loaded interstitial. */
|
|
export const showInterstitial = async () => {
|
|
if (!(await checkIfAdMobIsAvailable())) return;
|
|
|
|
if (!interstitial) {
|
|
logger.warn(
|
|
'Interstitial has not been set up, call loadInterstitial first.'
|
|
);
|
|
return;
|
|
}
|
|
if (!interstitialReady) {
|
|
logger.info('Interstitial not loaded yet, cannot display it.');
|
|
return;
|
|
}
|
|
interstitialErrored = false;
|
|
|
|
try {
|
|
logger.info('Showing AdMob interstitial.');
|
|
await interstitial.show();
|
|
// Interstitial will be shown and
|
|
// `interstitialShowing` will be updated thanks to events
|
|
// (but it's too early to change it now).
|
|
} catch (error) {
|
|
logger.error('Error while showing an AdMob interstitial:', error);
|
|
interstitialShowing = false;
|
|
interstitialErrored = true;
|
|
}
|
|
};
|
|
|
|
// --------------------------------
|
|
// ---- Rewarded Interstitial -----
|
|
// --------------------------------
|
|
export const isRewardedInterstitialLoading = () =>
|
|
rewardedInterstitialLoading;
|
|
export const isRewardedInterstitialReady = () => rewardedInterstitialReady;
|
|
export const isRewardedInterstitialShowing = () =>
|
|
rewardedInterstitialShowing;
|
|
export const isRewardedInterstitialErrored = () =>
|
|
rewardedInterstitialErrored;
|
|
|
|
/** Check if the reward of the rewarded interstitial was received. */
|
|
export const wasRewardedInterstitialRewardReceived = function (
|
|
markAsClaimed
|
|
) {
|
|
const reward = rewardedInterstitialRewardReceived;
|
|
if (markAsClaimed) {
|
|
rewardedInterstitialRewardReceived = false;
|
|
}
|
|
return reward;
|
|
};
|
|
|
|
/** Load a rewarded interstitial. */
|
|
export const loadRewardedInterstitial = async (
|
|
androidAdUnitID,
|
|
iosAdUnitID,
|
|
displayWhenLoaded
|
|
) => {
|
|
if (!(await checkIfAdMobIsAvailable())) return;
|
|
if (rewardedInterstitialLoading || rewardedInterstitialShowing) {
|
|
return;
|
|
}
|
|
|
|
const adUnitId = getAdUnitId(
|
|
androidAdUnitID,
|
|
iosAdUnitID,
|
|
'rewardedInterstitial'
|
|
);
|
|
if (!adUnitId) return;
|
|
|
|
rewardedInterstitialLoading = true;
|
|
rewardedInterstitialReady = false;
|
|
rewardedInterstitialErrored = false;
|
|
|
|
rewardedInterstitial = new admob.RewardedInterstitialAd({
|
|
adUnitId,
|
|
npa: npaValue,
|
|
});
|
|
|
|
// Rewarded video event listeners
|
|
rewardedInterstitial.on('load', () => {
|
|
rewardedInterstitialReady = true;
|
|
rewardedInterstitialLoading = false;
|
|
});
|
|
rewardedInterstitial.on('loadfail', () => {
|
|
rewardedInterstitialLoading = false;
|
|
rewardedInterstitialErrored = true;
|
|
});
|
|
rewardedInterstitial.on('show', () => {
|
|
rewardedInterstitialShowing = true;
|
|
rewardedInterstitialReady = false;
|
|
});
|
|
rewardedInterstitial.on('showfail', () => {
|
|
rewardedInterstitialShowing = false;
|
|
rewardedInterstitialErrored = true;
|
|
});
|
|
rewardedInterstitial.on('dismiss', () => {
|
|
rewardedInterstitialShowing = false;
|
|
});
|
|
rewardedInterstitial.on('reward', () => {
|
|
rewardedInterstitialRewardReceived = true;
|
|
});
|
|
|
|
try {
|
|
logger.info('Loading AdMob rewarded interstitial.');
|
|
await rewardedInterstitial.load();
|
|
logger.info('AdMob rewarded interstitial successfully loaded.');
|
|
rewardedInterstitialLoading = false;
|
|
rewardedInterstitialReady = true;
|
|
if (displayWhenLoaded) showRewardedInterstitial();
|
|
} catch (error) {
|
|
rewardedInterstitialLoading = false;
|
|
rewardedInterstitialReady = false;
|
|
rewardedInterstitialErrored = true;
|
|
logger.error('Error while loading a rewarded interstitial:', error);
|
|
}
|
|
};
|
|
|
|
/** Show the loaded reward interstitial. */
|
|
export const showRewardedInterstitial = async () => {
|
|
if (!(await checkIfAdMobIsAvailable())) return;
|
|
|
|
if (!rewardedInterstitial) {
|
|
logger.warn(
|
|
'interstitial has not been set up, call loadRewardedInterstitial first.'
|
|
);
|
|
return;
|
|
}
|
|
if (!rewardedInterstitialReady) {
|
|
logger.info('Rewarded interstitial not loaded yet, cannot display it.');
|
|
}
|
|
rewardedInterstitialErrored = false;
|
|
|
|
try {
|
|
logger.info('Showing AdMob rewarded interstitial.');
|
|
await rewardedInterstitial.show();
|
|
// Rewarded interstitial will be shown and
|
|
// `rewardedInterstitialShowing` will be updated thanks to events
|
|
// (but it's too early to change it now).
|
|
} catch (error) {
|
|
logger.error(
|
|
'Error while showing an AdMob rewarded interstitial:',
|
|
error
|
|
);
|
|
rewardedInterstitialShowing = false;
|
|
rewardedInterstitialErrored = true;
|
|
}
|
|
};
|
|
|
|
/** Mark the reward of the interstitial as claimed. */
|
|
export const markRewardedInterstitialRewardAsClaimed = () => {
|
|
rewardedInterstitialRewardReceived = false;
|
|
};
|
|
|
|
// -------------------------
|
|
// ---- Rewarded Video -----
|
|
// -------------------------
|
|
export const isRewardedVideoLoading = () => rewardedVideoLoading;
|
|
export const isRewardedVideoReady = () => rewardedVideoReady;
|
|
export const isRewardedVideoShowing = () => rewardedVideoShowing;
|
|
export const isRewardedVideoErrored = () => rewardedVideoErrored;
|
|
|
|
/** Check if the reward of the rewarded video was received. */
|
|
export const wasRewardedVideoRewardReceived = function (markAsClaimed) {
|
|
const reward = rewardedVideoRewardReceived;
|
|
if (markAsClaimed) {
|
|
rewardedVideoRewardReceived = false;
|
|
}
|
|
return reward;
|
|
};
|
|
|
|
/** Load a rewarded video. */
|
|
export const loadRewardedVideo = async (
|
|
androidAdUnitID,
|
|
iosAdUnitID,
|
|
displayWhenLoaded
|
|
) => {
|
|
if (!(await checkIfAdMobIsAvailable())) return;
|
|
if (rewardedVideoLoading || rewardedVideoShowing) {
|
|
return;
|
|
}
|
|
|
|
const adUnitId = getAdUnitId(androidAdUnitID, iosAdUnitID, 'rewarded');
|
|
if (!adUnitId) return;
|
|
|
|
rewardedVideoLoading = true;
|
|
rewardedVideoReady = false;
|
|
rewardedVideoErrored = false;
|
|
|
|
rewardedVideo = new admob.RewardedAd({
|
|
adUnitId,
|
|
npa: npaValue,
|
|
});
|
|
|
|
// Rewarded video event listeners
|
|
rewardedVideo.on('load', () => {
|
|
rewardedVideoReady = true;
|
|
rewardedVideoLoading = false;
|
|
});
|
|
rewardedVideo.on('loadfail', () => {
|
|
rewardedVideoLoading = false;
|
|
rewardedVideoErrored = true;
|
|
});
|
|
rewardedVideo.on('show', () => {
|
|
rewardedVideoShowing = true;
|
|
rewardedVideoReady = false;
|
|
});
|
|
rewardedVideo.on('showfail', () => {
|
|
rewardedVideoShowing = false;
|
|
rewardedVideoErrored = true;
|
|
});
|
|
rewardedVideo.on('dismiss', () => {
|
|
rewardedVideoShowing = false;
|
|
});
|
|
rewardedVideo.on('reward', () => {
|
|
rewardedVideoRewardReceived = true;
|
|
});
|
|
|
|
try {
|
|
logger.info('Loading AdMob rewarded video.');
|
|
await rewardedVideo.load();
|
|
logger.info('AdMob rewarded video successfully loaded.');
|
|
rewardedVideoLoading = false;
|
|
rewardedVideoReady = true;
|
|
if (displayWhenLoaded) showRewardedVideo();
|
|
} catch (error) {
|
|
rewardedVideoLoading = false;
|
|
rewardedVideoReady = false;
|
|
rewardedVideoErrored = true;
|
|
logger.error('Error while loading a rewarded video:', error);
|
|
}
|
|
};
|
|
|
|
/** Show the loaded reward video. */
|
|
export const showRewardedVideo = async () => {
|
|
if (!(await checkIfAdMobIsAvailable())) return;
|
|
|
|
if (!rewardedVideo) {
|
|
logger.warn('Video has not been set up, call loadRewardedVideo first.');
|
|
return;
|
|
}
|
|
if (!rewardedVideoReady) {
|
|
logger.info('Rewarded video not loaded yet, cannot display it.');
|
|
}
|
|
rewardedVideoErrored = false;
|
|
|
|
try {
|
|
logger.info('Showing AdMob rewarded video.');
|
|
await rewardedVideo.show();
|
|
// Rewarded video will be shown and
|
|
// `rewardedVideoShowing` will be updated thanks to events
|
|
// (but it's too early to change it now).
|
|
} catch (error) {
|
|
logger.error('Error while showing an AdMob rewarded video:', error);
|
|
rewardedVideoShowing = false;
|
|
rewardedVideoErrored = true;
|
|
}
|
|
};
|
|
|
|
/** Mark the reward of the video as claimed. */
|
|
export const markRewardedVideoRewardAsClaimed = () => {
|
|
rewardedVideoRewardReceived = false;
|
|
};
|
|
}
|
|
}
|