Releases: blessedzulu/nativephp-admob
v1.0.0-beta
First beta - feature-complete and API-stable. All five ad formats + UMP consent + iOS ATT + the JavaScript API (Admob module + Web Component) + x-admob::banner Blade component + built-in test page + banner offset + auto safe-area inset + frequency caps + ADMOB_ENABLED kill-switch + ADMOB_DEBUG. 82 tests green. Android device-verified; iOS implemented but not yet hardware-tested - verify on iOS before shipping iOS production ads. No API changes expected before 1.0.0.
v0.13.1-alpha — test page polish
Built-in test page: full-screen Show buttons now reflect real ad readiness (disabled/muted until AdLoaded, green when ready, reset on dismiss/fail) instead of always looking green; clear-log button repositioned with balanced spacing.
v0.13.0-alpha — banner auto safe-area inset
The banner now auto-insets past the OS system bars by default so a bottom banner isn't clipped behind the gesture/nav bar (and a top banner isn't under the status bar) - matching iOS. Android reads WindowInsets; the per-position offset stacks on top. Toggle with ADMOB_BANNER_SAFE_AREA=false for edge-to-edge. NativePHP's --inset-* CSS vars are for WebView content, not native overlays, so this is handled natively. 82 tests green.
v0.12.0-alpha — banner offset (clear the bottom-nav)
The banner is a screen-edge native overlay, so it could sit on top of chrome like a native bottom-nav. You can now lift it off the edge with an offset (dp): config('admob.banner.offset.{top,bottom}'), ->show('bottom', 56), , or <x-admob::banner offset="56">. Applied as a native margin (Android) / safe-area constraint (iOS). Device-verified: a bottom banner with offset clears the native bottom-nav. The built-in test page now also shows Google demo ads in test_mode (forces canRequestAds). 81 tests green.
v0.11.1-alpha — serialized JS API calls (no concurrent-POST 422s)
Fixes intermittent 422s when several JS-API calls fire at once (e.g. two banners mounting together). All callers now chain requests through one shared queue (window.__admobCallQueue), so they go out one at a time and never race NativePHP's URL-keyed POST-body capture. Multi-banner screens are race-free. 78 tests green.
v0.11.0-alpha — built-in test page + banner reload fix
Adds a generic, self-contained AdMob test/debug page served at /_admob/test (no Livewire/Inertia/CSRF dependency; drives the JS API + streams a live event log; default on outside production). Fixes the <x-admob::banner> reload-on-every-render loop - it now loads+shows once on init via /_admob/call and hides on navigation. Also converts stacked // comment blocks to /* */ (esp. config). 78 tests green. See CHANGELOG.
v0.10.0-alpha — JavaScript API + <admob-banner> Web Component
Makes the plugin usable from JavaScript (Inertia / Vue / React / vanilla), not just PHP. Ships a JS module (Admob.banner('slot').show(), interstitial/rewarded/appOpen, ump/att, Events + .d.ts) and a framework-agnostic <admob-banner> Web Component, both backed by a thin /_admob/call endpoint that runs the PHP facade so slot resolution + consent + frequency caps + the kill-switch all apply server-side. Also: ADMOB_ENABLED is now a real kill-switch, and banner auto-hide listens on both window and document (Inertia-aware) with cleanup. 76 tests green. See CHANGELOG.
v0.9.0-alpha — Phase 9 polish
Polish pass before Marketplace/v1.0: <x-admob::banner> Blade component (no Livewire dependency), per-format/per-slot frequency caps (+ AdShowThrottled event), platform-aware App Open test ad unit, bridge-failure logging + ADMOB_DEBUG tracing, and a package-agnostic config/slot story (no env-key convention). 64 tests green. See CHANGELOG for details.
v0.8.0-alpha — UMP consent + iOS ATT
Phases 7 + 8: real UMP consent flow (Android + iOS) and real iOS App Tracking Transparency. Every previously-stubbed bridge function is now real; only iOS device verification remains. Removes the need for the Admob::setCanRequestAds(true) test bypass. See CHANGELOG for full details.
v0.7.1-alpha - Fix: AppOpen auto-show after fullscreen dismiss
Bug fix on top of v0.7.0-alpha. Caught immediately after Phase 6 ship.
Symptom
Dismissing any full-screen ad (interstitial, rewarded, rewarded interstitial) caused the cached App Open ad to auto-show immediately after - producing a back-to-back ad UX that no app should ever ship.
Root cause
MainActivity.onResume (Android) and UIApplication.didBecomeActiveNotification (iOS) BOTH fire when the SDK's full-screen activity / view controller tears down at dismiss time. From the lifecycle observer's perspective this looks identical to a real background→foreground transition, so it auto-showed the cached App Open ad.
Fix
New FullScreenAdState singleton on both platforms:
- Each
FullScreenContentCallback(Android) /FullScreenContentDelegate(iOS) callsFullScreenAdState.markDismissed()on dismiss + on failed-show. Covers all four full-screen formats: interstitial, rewarded, rewarded interstitial, app open. AppOpenLifecycle.onResume/didBecomeActiveobserver checksFullScreenAdState.recentlyDismissed()(true if within 1500ms) and suppresses auto-show.
The 1500ms grace window is generous - the resume event follows dismiss by tens to a few hundred ms in practice; this absorbs slower devices and emulator scheduling jitter.
Verified
Android emulator end-to-end: rewarded ad shown → dismissed → logcat shows:
AppOpenLifecycle: onResume callback fired (..., recentlyDismissed=true)
AppOpenLifecycle: suppressing auto-show: another full-screen ad dismissed within 1500ms
App Open is NOT auto-shown. User returns to the host app screen.