/// Real Adsgram SDK interface using JavaScript interop
///
/// This provides a Dart interface to the Adsgram JavaScript SDK.
/// The SDK is loaded via script tag in web/index.html:
///
///
/// The JavaScript bridge functions are defined in web/foos.js
library;
import 'dart:developer' as developer;
import 'dart:js_util' as js_util;
/// Configuration for Adsgram ad display
class AdsgramAd {
/// Adsgram block ID (required)
final String blockId;
/// Reward amount (for tracking purposes)
final int rewardAmount;
/// Callback invoked when ad completes successfully
final void Function()? onReward;
/// Callback invoked when ad fails or is closed early
final void Function(String error)? onError;
const AdsgramAd({
required this.blockId,
required this.rewardAmount,
this.onReward,
this.onError,
});
}
/// Adsgram SDK interface for showing rewarded ads
class Adsgram {
static final Adsgram _instance = Adsgram._internal();
static Adsgram get instance => _instance;
Adsgram._internal();
/// Check if Adsgram SDK is available in the JavaScript environment
bool get isAvailable {
try {
final adsgram = js_util.getProperty(js_util.globalThis, 'Adsgram');
return adsgram != null;
} catch (e) {
return false;
}
}
/// Show a rewarded ad using the Adsgram JavaScript SDK
///
/// This method:
/// 1. Validates the ad configuration
/// 2. Checks SDK availability
/// 3. Sets up JavaScript callbacks for reward/error events
/// 4. Calls the JavaScript showAdWithBlockId() function
/// 5. Handles ad lifecycle events via callbacks
///
/// Throws [Exception] if SDK is not available or ad fails to show
/// Throws [ArgumentError] if ad configuration is invalid
Future showRewardedAd(AdsgramAd adConfig) async {
// Validate block ID
if (adConfig.blockId.trim().isEmpty) {
final error = 'Block ID is required and cannot be empty';
developer.log(error, name: 'Adsgram');
adConfig.onError?.call(error);
throw ArgumentError.value(
adConfig.blockId,
'blockId',
error,
);
}
// Check SDK availability
if (!isAvailable) {
final error = 'Adsgram SDK not available. Make sure sad.min.js is loaded.';
developer.log(error, name: 'Adsgram');
adConfig.onError?.call(error);
throw Exception(error);
}
// Validate that JavaScript bridge functions exist
try {
final showAdFunction = js_util.getProperty(
js_util.globalThis,
'showAdWithBlockId',
);
if (showAdFunction == null) {
final error = 'JavaScript bridge function showAdWithBlockId not found. Make sure foos.js is loaded.';
developer.log(error, name: 'Adsgram');
adConfig.onError?.call(error);
throw Exception(error);
}
} catch (e) {
final error = 'Failed to access JavaScript bridge: $e';
developer.log(error, name: 'Adsgram');
adConfig.onError?.call(error);
throw Exception(error);
}
try {
developer.log(
'Showing rewarded ad with block ID: ${adConfig.blockId}',
name: 'Adsgram',
);
// Set up callbacks in JavaScript before showing ad
await _setupCallbacks(adConfig);
// Call the JavaScript showAdWithBlockId function
// The function is defined in web/foos.js and handles the Adsgram SDK
await js_util.promiseToFuture(
js_util.callMethod(
js_util.globalThis,
'showAdWithBlockId',