From d43e0a5d6224e61436bf439413f1c65d1bb2e34e Mon Sep 17 00:00:00 2001 From: Bram Willem van der Kuip Date: Thu, 30 Jan 2020 10:16:43 +0100 Subject: [PATCH 1/7] Added gamedockSDK provider --- src/Providers/cordova-gamedock.ts | 107 ++++++++++++++++++++++++++++++ src/h5-ad-wrapper.ts | 1 + vendor/cordova-gamedock.d.ts | 25 +++++++ 3 files changed, 133 insertions(+) create mode 100644 src/Providers/cordova-gamedock.ts create mode 100644 vendor/cordova-gamedock.d.ts diff --git a/src/Providers/cordova-gamedock.ts b/src/Providers/cordova-gamedock.ts new file mode 100644 index 0000000..9da3d7b --- /dev/null +++ b/src/Providers/cordova-gamedock.ts @@ -0,0 +1,107 @@ +/// + +import { IProvider } from './ad-provider' +import { AdType, AdEvents, H5AdWrapper } from '../h5-ad-wrapper' + +/** + * The cordova gamedock ad provider requires the gamedock-sdk-cordova plugin to be setup within your cordova app. + */ +export class CordovaGamedock implements IProvider { + public adManager!: H5AdWrapper + public adsEnabled: boolean = false + + constructor() { + if (typeof gamedockSDK === 'undefined') { + return + } + + let withAgeGate: boolean = false + let ageGateOptions: IAgeGateOptions = { shouldBlock: true, requiredAge: 12 } + let withPrivacyPolicy: boolean = true + let environment: string = 'PRODUCTION' + let externalIds: any[] = [] + + gamedockSDK.initialise( + withAgeGate, + ageGateOptions, + withPrivacyPolicy, + environment, + externalIds + ) + + const resume: () => void = () => this.resumeGameplay() + gamedockSDK.on('AdFinished', resume) + gamedockSDK.on('AdNotAvailable', resume) + } + + public setManager(manager: H5AdWrapper): void { + this.adManager = manager + } + + public showAd(adType: AdType = AdType.interstitial): void { + if (typeof gamedockSDK === 'undefined') { + return + } + + switch (adType) { + case AdType.interstitial: + this.adManager.emit(AdEvents.CONTENT_PAUSED) + gamedockSDK.playInterstitial() + break + case AdType.rewarded: + if (!this.adAvailable(AdType.rewarded)) { + this.resumeGameplay() + break + } + this.adManager.emit(AdEvents.CONTENT_PAUSED) + gamedockSDK.playRewardVideo() + break + default: + this.resumeGameplay() + break + } + } + + private resumeGameplay(): void { + this.adManager.emit(AdEvents.CONTENT_RESUMED) + } + + public preloadAd(adType: AdType = AdType.interstitial): void { + if (typeof gamedockSDK === 'undefined') { + return + } + + switch (adType) { + case AdType.interstitial: + gamedockSDK.requestInterstitial() + break + case AdType.rewarded: + gamedockSDK.requestRewardVideo() + break + } + } + + public destroyAd(): void { + return + } + + public hideAd(): void { + return + } + + public adAvailable(adType: AdType): boolean { + if (typeof gamedockSDK === 'undefined') { + return false + } + + return gamedockSDK.isAdAvailable( + adType === AdType.interstitial + ? GamedockAdType.interstitial + : adType === AdType.rewarded + ? GamedockAdType.rewardVideo + : adType === AdType.banner + ? GamedockAdType.banner + : GamedockAdType.interstitial + ) + } +} diff --git a/src/h5-ad-wrapper.ts b/src/h5-ad-wrapper.ts index c80e311..5a40616 100644 --- a/src/h5-ad-wrapper.ts +++ b/src/h5-ad-wrapper.ts @@ -2,6 +2,7 @@ import EventEmitter from 'eventemitter3' export { CocoonAds } from './Providers/cocoon' export { CordovaGamedistribution } from './Providers/cordova-gamedistribution' +export { CordovaGamedock } from './Providers/cordova-gamedock' export { CordovaHeyzap } from './Providers/cordova-heyzap' export { CordovaIronSource } from './Providers/cordova-ironsource' export { diff --git a/vendor/cordova-gamedock.d.ts b/vendor/cordova-gamedock.d.ts new file mode 100644 index 0000000..8f85e5d --- /dev/null +++ b/vendor/cordova-gamedock.d.ts @@ -0,0 +1,25 @@ +declare interface IAgeGateOptions { + shouldBlock: boolean; + requiredAge: number; +} + +declare enum GamedockAdType { + "banner", + "interstitial", + "rewardVideo" +} + +declare interface IGamedockSDK { + on(event: string, callback: Function): void; + initialise(withAgeGate: boolean, ageGateOptions: IAgeGateOptions, withPrivacyPolicy: boolean, environment: string, externalIds: any[]): void; + + requestInterstitial(): void + requestRewardVideo(): void + + playInterstitial(): void; + playRewardVideo(): void; + + isAdAvailable(adType: GamedockAdType): boolean; +} + +declare var gamedockSDK: IGamedockSDK | undefined; From 160f234735463d76f3606a951f3052260926bbe4 Mon Sep 17 00:00:00 2001 From: Bram Willem van der Kuip Date: Thu, 30 Jan 2020 10:19:23 +0100 Subject: [PATCH 2/7] Version bump to 0.6.0 --- CHANGELOG.md | 4 ++++ package-lock.json | 2 +- package.json | 6 +++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4efba2e..1d54921 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +# [0.6.0] - 2020-01-30 +### Added +- Gamedock cordova ad provider + ## [0.5.1] - 2019-12-19 ### Fixed - Banner offset when scaling and aligning diff --git a/package-lock.json b/package-lock.json index 6c12f66..fba170d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@azerion/h5-ad-wrapper", - "version": "0.5.1", + "version": "0.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 9d96bd8..d93b4b9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@azerion/h5-ad-wrapper", "author": "Azerion", - "version": "0.5.1", + "version": "0.6.0", "description": "Advertisement provider wrapper, similar to @azerion/phaser-ads but not tied into Phaser :)", "contributors": [ { @@ -15,6 +15,10 @@ { "name": "Floris de Haan", "email": "f.dehaan@azerion.com" + }, + { + "name": "Bram Willem van der Kuip", + "email": "bw.vanderkuip@azerion.com" } ], "main": "dist/h5-ad-wrapper.umd.js", From a91a9ada57cadfdfe11500b1cfffc745178ff7ab Mon Sep 17 00:00:00 2001 From: Bram Willem van der Kuip Date: Tue, 4 Feb 2020 17:11:31 +0100 Subject: [PATCH 3/7] Added request ad setup --- src/Providers/cordova-gamedock.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/Providers/cordova-gamedock.ts b/src/Providers/cordova-gamedock.ts index 9da3d7b..f2c8b1a 100644 --- a/src/Providers/cordova-gamedock.ts +++ b/src/Providers/cordova-gamedock.ts @@ -10,6 +10,8 @@ export class CordovaGamedock implements IProvider { public adManager!: H5AdWrapper public adsEnabled: boolean = false + public interstitialLoaded: boolean = false + constructor() { if (typeof gamedockSDK === 'undefined') { return @@ -29,9 +31,17 @@ export class CordovaGamedock implements IProvider { externalIds ) + gamedockSDK.on('AdAvailable', (data: any) => { + if (data.type === 'interstitial') { + this.interstitialChanged(true) + } + }) + const resume: () => void = () => this.resumeGameplay() gamedockSDK.on('AdFinished', resume) gamedockSDK.on('AdNotAvailable', resume) + + gamedockSDK.requestInterstitial() } public setManager(manager: H5AdWrapper): void { @@ -45,8 +55,16 @@ export class CordovaGamedock implements IProvider { switch (adType) { case AdType.interstitial: + if (!this.interstitialLoaded) { + this.resumeGameplay() + break + } + this.adManager.emit(AdEvents.CONTENT_PAUSED) gamedockSDK.playInterstitial() + this.interstitialChanged(false) + + gamedockSDK.requestInterstitial() break case AdType.rewarded: if (!this.adAvailable(AdType.rewarded)) { @@ -104,4 +122,8 @@ export class CordovaGamedock implements IProvider { : GamedockAdType.interstitial ) } + + private interstitialChanged(available: boolean): void { + this.interstitialLoaded = available + } } From efc182cb16103e8bde7eba718d8f782c45ffde7f Mon Sep 17 00:00:00 2001 From: Bram Willem van der Kuip Date: Fri, 7 Feb 2020 15:14:01 +0100 Subject: [PATCH 4/7] Updated requested gamedock ad setup --- src/Providers/cordova-gamedock.ts | 76 +++++++++++++++++-------------- vendor/cordova-gamedock.d.ts | 8 +--- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/src/Providers/cordova-gamedock.ts b/src/Providers/cordova-gamedock.ts index f2c8b1a..473eba2 100644 --- a/src/Providers/cordova-gamedock.ts +++ b/src/Providers/cordova-gamedock.ts @@ -10,7 +10,7 @@ export class CordovaGamedock implements IProvider { public adManager!: H5AdWrapper public adsEnabled: boolean = false - public interstitialLoaded: boolean = false + private requestedInterstitial: boolean = false constructor() { if (typeof gamedockSDK === 'undefined') { @@ -32,16 +32,31 @@ export class CordovaGamedock implements IProvider { ) gamedockSDK.on('AdAvailable', (data: any) => { - if (data.type === 'interstitial') { - this.interstitialChanged(true) + switch (data.type) { + case 'interstitial': + this.interstitalAvailable() + break + case 'rewardVideo': + throw new Error('Not yet implemented.') + case 'banner': + throw new Error('Not yet implemented.') + } + }) + + gamedockSDK.on('AdNotAvailable', (data: any) => { + switch (data.type) { + case 'interstitial': + this.interstitalNotAvailable() + break + case 'rewardVideo': + throw new Error('Not yet implemented.') + case 'banner': + throw new Error('Not yet implemented.') } }) const resume: () => void = () => this.resumeGameplay() gamedockSDK.on('AdFinished', resume) - gamedockSDK.on('AdNotAvailable', resume) - - gamedockSDK.requestInterstitial() } public setManager(manager: H5AdWrapper): void { @@ -55,15 +70,8 @@ export class CordovaGamedock implements IProvider { switch (adType) { case AdType.interstitial: - if (!this.interstitialLoaded) { - this.resumeGameplay() - break - } - this.adManager.emit(AdEvents.CONTENT_PAUSED) - gamedockSDK.playInterstitial() - this.interstitialChanged(false) - + this.requestedInterstitial = true gamedockSDK.requestInterstitial() break case AdType.rewarded: @@ -80,25 +88,29 @@ export class CordovaGamedock implements IProvider { } } - private resumeGameplay(): void { - this.adManager.emit(AdEvents.CONTENT_RESUMED) - } - - public preloadAd(adType: AdType = AdType.interstitial): void { + private interstitalAvailable(): void { if (typeof gamedockSDK === 'undefined') { return } - switch (adType) { - case AdType.interstitial: - gamedockSDK.requestInterstitial() - break - case AdType.rewarded: - gamedockSDK.requestRewardVideo() - break + if (this.requestedInterstitial) { + gamedockSDK.playInterstitial() + this.requestedInterstitial = false } } + private interstitalNotAvailable(): void { + this.resumeGameplay() + } + + private resumeGameplay(): void { + this.adManager.emit(AdEvents.CONTENT_RESUMED) + } + + public preloadAd(adType: AdType = AdType.interstitial): void { + return + } + public destroyAd(): void { return } @@ -114,16 +126,12 @@ export class CordovaGamedock implements IProvider { return gamedockSDK.isAdAvailable( adType === AdType.interstitial - ? GamedockAdType.interstitial + ? 'interstitial' : adType === AdType.rewarded - ? GamedockAdType.rewardVideo + ? 'rewardVideo' : adType === AdType.banner - ? GamedockAdType.banner - : GamedockAdType.interstitial + ? 'banner' + : 'interstitial' ) } - - private interstitialChanged(available: boolean): void { - this.interstitialLoaded = available - } } diff --git a/vendor/cordova-gamedock.d.ts b/vendor/cordova-gamedock.d.ts index 8f85e5d..911c4c5 100644 --- a/vendor/cordova-gamedock.d.ts +++ b/vendor/cordova-gamedock.d.ts @@ -3,12 +3,6 @@ declare interface IAgeGateOptions { requiredAge: number; } -declare enum GamedockAdType { - "banner", - "interstitial", - "rewardVideo" -} - declare interface IGamedockSDK { on(event: string, callback: Function): void; initialise(withAgeGate: boolean, ageGateOptions: IAgeGateOptions, withPrivacyPolicy: boolean, environment: string, externalIds: any[]): void; @@ -19,7 +13,7 @@ declare interface IGamedockSDK { playInterstitial(): void; playRewardVideo(): void; - isAdAvailable(adType: GamedockAdType): boolean; + isAdAvailable(adType: string): boolean; } declare var gamedockSDK: IGamedockSDK | undefined; From 99049183d8e9f3edf9a33497874a690a595200fd Mon Sep 17 00:00:00 2001 From: Bram Willem van der Kuip Date: Mon, 10 Feb 2020 12:14:14 +0100 Subject: [PATCH 5/7] Added AD_PROVIDER_LOADED to PrivacyPolicyStatus accept --- src/Providers/cordova-gamedock.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Providers/cordova-gamedock.ts b/src/Providers/cordova-gamedock.ts index 473eba2..67c9bdf 100644 --- a/src/Providers/cordova-gamedock.ts +++ b/src/Providers/cordova-gamedock.ts @@ -23,6 +23,12 @@ export class CordovaGamedock implements IProvider { let environment: string = 'PRODUCTION' let externalIds: any[] = [] + gamedockSDK.on('PrivacyPolicyStatus', (data: any) => { + if (data.accepted) { + this.adManager.emit(AdEvents.AD_PROVIDER_LOADED) + } + }) + gamedockSDK.initialise( withAgeGate, ageGateOptions, From 411a5b72f35926e23b321c631b3a4f85833369fa Mon Sep 17 00:00:00 2001 From: Bram Willem van der Kuip Date: Wed, 12 Feb 2020 14:39:50 +0100 Subject: [PATCH 6/7] Removed requestedInterstitial flag and added rewarded ads --- src/Providers/cordova-gamedock.ts | 73 ++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/src/Providers/cordova-gamedock.ts b/src/Providers/cordova-gamedock.ts index 67c9bdf..a94e13d 100644 --- a/src/Providers/cordova-gamedock.ts +++ b/src/Providers/cordova-gamedock.ts @@ -10,7 +10,7 @@ export class CordovaGamedock implements IProvider { public adManager!: H5AdWrapper public adsEnabled: boolean = false - private requestedInterstitial: boolean = false + private rewardedLoaded: boolean = false constructor() { if (typeof gamedockSDK === 'undefined') { @@ -43,7 +43,8 @@ export class CordovaGamedock implements IProvider { this.interstitalAvailable() break case 'rewardVideo': - throw new Error('Not yet implemented.') + this.rewardedChanged(true) + break case 'banner': throw new Error('Not yet implemented.') } @@ -52,17 +53,28 @@ export class CordovaGamedock implements IProvider { gamedockSDK.on('AdNotAvailable', (data: any) => { switch (data.type) { case 'interstitial': - this.interstitalNotAvailable() + this.resumeGameplay() break case 'rewardVideo': - throw new Error('Not yet implemented.') + this.resumeGameplay() + break case 'banner': throw new Error('Not yet implemented.') } }) - const resume: () => void = () => this.resumeGameplay() - gamedockSDK.on('AdFinished', resume) + gamedockSDK.on('AdFinished', (data: any) => { + switch (data.type) { + case 'interstitial': + this.resumeGameplay() + break + case 'rewardVideo': + this.rewardVideoFinished(data.reason) + break + case 'banner': + throw new Error('Not yet implemented.') + } + }) } public setManager(manager: H5AdWrapper): void { @@ -77,7 +89,6 @@ export class CordovaGamedock implements IProvider { switch (adType) { case AdType.interstitial: this.adManager.emit(AdEvents.CONTENT_PAUSED) - this.requestedInterstitial = true gamedockSDK.requestInterstitial() break case AdType.rewarded: @@ -86,6 +97,7 @@ export class CordovaGamedock implements IProvider { break } this.adManager.emit(AdEvents.CONTENT_PAUSED) + this.rewardedChanged(false) gamedockSDK.playRewardVideo() break default: @@ -99,14 +111,18 @@ export class CordovaGamedock implements IProvider { return } - if (this.requestedInterstitial) { - gamedockSDK.playInterstitial() - this.requestedInterstitial = false - } + gamedockSDK.playInterstitial() } - private interstitalNotAvailable(): void { - this.resumeGameplay() + private rewardVideoFinished(reason: string): void { + switch (reason) { + case 'dismiss': + this.resumeGameplay() + break + case 'close': + this.adManager.emit(AdEvents.AD_REWARDED) + break + } } private resumeGameplay(): void { @@ -114,7 +130,18 @@ export class CordovaGamedock implements IProvider { } public preloadAd(adType: AdType = AdType.interstitial): void { - return + if (typeof gamedockSDK === 'undefined') { + return + } + + switch (adType) { + case AdType.rewarded: + if (this.rewardedLoaded) { + return + } + gamedockSDK.requestRewardVideo() + break + } } public destroyAd(): void { @@ -126,18 +153,14 @@ export class CordovaGamedock implements IProvider { } public adAvailable(adType: AdType): boolean { - if (typeof gamedockSDK === 'undefined') { - return false + switch (adType) { + case AdType.rewarded: + return this.rewardedLoaded } + return false + } - return gamedockSDK.isAdAvailable( - adType === AdType.interstitial - ? 'interstitial' - : adType === AdType.rewarded - ? 'rewardVideo' - : adType === AdType.banner - ? 'banner' - : 'interstitial' - ) + private rewardedChanged(available: boolean): void { + this.rewardedLoaded = available } } From 76c0f79a04ad44f5550217d762148d4f939ed440 Mon Sep 17 00:00:00 2001 From: Bram Willem van der Kuip Date: Thu, 13 Feb 2020 14:21:09 +0100 Subject: [PATCH 7/7] Added documentation for cordova gamedock provider --- src/Providers/cordova-gamedock.ts | 49 +++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/src/Providers/cordova-gamedock.ts b/src/Providers/cordova-gamedock.ts index a94e13d..90f9f49 100644 --- a/src/Providers/cordova-gamedock.ts +++ b/src/Providers/cordova-gamedock.ts @@ -10,25 +10,33 @@ export class CordovaGamedock implements IProvider { public adManager!: H5AdWrapper public adsEnabled: boolean = false + /** + * Flag for if an rewarded ad is loaded or not. + */ private rewardedLoaded: boolean = false + /** + * Creates an instance of CordovaGamedock. + * Initializes the gamedockSDK and adds listeners for events. + */ constructor() { if (typeof gamedockSDK === 'undefined') { return } + // Variables the gamedockSDK requires to be initialized. let withAgeGate: boolean = false let ageGateOptions: IAgeGateOptions = { shouldBlock: true, requiredAge: 12 } let withPrivacyPolicy: boolean = true let environment: string = 'PRODUCTION' let externalIds: any[] = [] + // Calls AD_PROVIDER_LOADED on PrivacyPolicyStatus with flag accepted. gamedockSDK.on('PrivacyPolicyStatus', (data: any) => { - if (data.accepted) { - this.adManager.emit(AdEvents.AD_PROVIDER_LOADED) - } + this.adManager.emit(AdEvents.AD_PROVIDER_LOADED, data.accepted) }) + // Initialize the gamedockSDK. gamedockSDK.initialise( withAgeGate, ageGateOptions, @@ -37,6 +45,7 @@ export class CordovaGamedock implements IProvider { externalIds ) + // Called whenever there is an ad available via the requestInterstitial and reqeuestRewardVideo methods. gamedockSDK.on('AdAvailable', (data: any) => { switch (data.type) { case 'interstitial': @@ -50,6 +59,7 @@ export class CordovaGamedock implements IProvider { } }) + // Called whenever there is no ad available (for now just resumes gameplay). gamedockSDK.on('AdNotAvailable', (data: any) => { switch (data.type) { case 'interstitial': @@ -63,6 +73,7 @@ export class CordovaGamedock implements IProvider { } }) + // Called whenever the shown ad is finished or closed for given reason. gamedockSDK.on('AdFinished', (data: any) => { switch (data.type) { case 'interstitial': @@ -81,6 +92,10 @@ export class CordovaGamedock implements IProvider { this.adManager = manager } + /** + * Show ad of type AdType + * @param {AdType} [adType=AdType.interstitial] + */ public showAd(adType: AdType = AdType.interstitial): void { if (typeof gamedockSDK === 'undefined') { return @@ -89,6 +104,8 @@ export class CordovaGamedock implements IProvider { switch (adType) { case AdType.interstitial: this.adManager.emit(AdEvents.CONTENT_PAUSED) + // requestInterstitial is called because playInstestitial will not check ad timeout. + // playInstestitial will be called on AdAvailable. gamedockSDK.requestInterstitial() break case AdType.rewarded: @@ -106,6 +123,9 @@ export class CordovaGamedock implements IProvider { } } + /** + * Called when the gamedockSDK event AdAvailable is called with typeof interstitial. + */ private interstitalAvailable(): void { if (typeof gamedockSDK === 'undefined') { return @@ -114,21 +134,35 @@ export class CordovaGamedock implements IProvider { gamedockSDK.playInterstitial() } + /** + * Called when the gamedockSDK event AdFinished is called with typeof rewardVideo. + * Will handle dismiss and close reason. + * @param {string} reason + */ private rewardVideoFinished(reason: string): void { switch (reason) { case 'dismiss': + // If rewardVideo is dismissed (closed before finished), resume the gameplay. this.resumeGameplay() break case 'close': + // If rewardVideo is closed (player saw video until end), emit AD_REWARDED event. this.adManager.emit(AdEvents.AD_REWARDED) break } } + /** + * Emits event CONTENT_RESUMED + */ private resumeGameplay(): void { this.adManager.emit(AdEvents.CONTENT_RESUMED) } + /** + * Preloads ad of type AdType + * @param {AdType} [adType=AdType.interstitial] + */ public preloadAd(adType: AdType = AdType.interstitial): void { if (typeof gamedockSDK === 'undefined') { return @@ -152,6 +186,11 @@ export class CordovaGamedock implements IProvider { return } + /** + * Returns if ad is available of type AdType + * @param {AdType} adType + * @returns {boolean} + */ public adAvailable(adType: AdType): boolean { switch (adType) { case AdType.rewarded: @@ -160,6 +199,10 @@ export class CordovaGamedock implements IProvider { return false } + /** + * Sets the rewardedLoaded flag to given boolean "available". + * @param {boolean} available + */ private rewardedChanged(available: boolean): void { this.rewardedLoaded = available }