admesh_flutter_ui_sdk 0.2.0
admesh_flutter_ui_sdk: ^0.2.0 copied to clipboard
Flutter SDK for AdMesh recommendations with native widgets, tracking, and theming.
example/lib/main.dart
import 'package:admesh_flutter_ui_sdk/admesh_flutter_ui_sdk.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const ExampleApp());
}
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) {
final sessionId = AdMeshSdk.createSession();
return MaterialApp(
title: 'AdMesh Flutter UI SDK',
theme: ThemeData(
useMaterial3: true,
extensions: <ThemeExtension<dynamic>>[
AdMeshThemeData.light(),
],
),
home: AdMeshProvider(
config: const AdMeshSdkConfig(apiKey: 'replace-me'),
sessionId: sessionId,
theme: AdMeshThemeData.light(),
child: ExampleHome(sessionId: sessionId),
),
);
}
}
class ExampleHome extends StatefulWidget {
const ExampleHome({super.key, required this.sessionId});
final String sessionId;
@override
State<ExampleHome> createState() => _ExampleHomeState();
}
class _ExampleHomeState extends State<ExampleHome> {
String _executedQuery = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('AdMesh Flutter UI SDK')),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
TextField(
readOnly: true,
decoration: InputDecoration(
labelText: 'Bridge destination',
hintText: 'Bridge format now links to the landing page directly',
border: const OutlineInputBorder(),
),
),
const SizedBox(height: 12),
Text(
_executedQuery.isEmpty
? 'Sponsored follow-up not executed yet'
: 'Executed follow-up: $_executedQuery',
),
const SizedBox(height: 24),
const Text('Static ecommerce sample'),
const SizedBox(height: 12),
AdMeshRecommendations(
recommendation: _sampleProductCard(widget.sessionId),
onOpenLink: (url) async => debugPrint('Open link: $url'),
),
const SizedBox(height: 24),
const Text('Bridge + follow-up sample'),
const SizedBox(height: 12),
AdMeshRecommendations(
recommendation: _sampleBridge(widget.sessionId),
onExecuteQuery: (query) async {
setState(() {
_executedQuery = query;
});
},
onOpenLink: (url) async => debugPrint('Open link: $url'),
),
const SizedBox(height: 24),
const Text('Manual fetch sample'),
const SizedBox(height: 12),
ElevatedButton(
onPressed: () async {
final sdk = AdMeshScope.of(context).sdk;
final options = ShowRecommendationsOptions(
query: 'best CRM for small business',
sessionId: widget.sessionId,
messageId: AdMeshSdk.createMessageId(widget.sessionId),
);
try {
final recommendation = await sdk.showRecommendations(options);
if (!context.mounted) return;
showDialog<void>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Fetched recommendation'),
content: Text(recommendation.title),
),
);
} catch (error) {
if (!context.mounted) return;
showDialog<void>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Fetch failed'),
content: Text('$error'),
),
);
}
},
child: const Text('Fetch from /aip/context'),
),
],
),
);
}
}
PlatformResponse _sampleProductCard(String sessionId) {
return PlatformResponse.fromJson({
'spec_version': '1.0',
'recommendation_id': 'rec_product',
'timestamp': DateTime.now().toUtc().toIso8601String(),
'status': 'generated',
'ttl_ms': 30000,
'recommendation': {
'format': 'product_card',
'disclosure': 'Ad',
'creative': {
'brand_name': 'Acme',
'headline': 'Acme CRM',
'description': 'CRM and pipeline automation for small teams.',
'cta_text': 'Start free',
'landing_page_url': 'https://example.com/crm',
'logo_url': 'https://example.com/logo.png',
'products': [
{
'product_id': 'starter',
'product_name': 'Starter',
'product_description': 'Basic CRM for early stage teams',
'product_price': 29,
'product_cta_label': 'Start free',
'product_link': 'https://example.com/starter'
},
{
'product_id': 'growth',
'product_name': 'Growth',
'product_description': 'Sales automation and forecasting',
'product_price': 79,
'product_cta_label': 'See plans',
'product_link': 'https://example.com/growth'
}
]
}
},
'tracking': {
'exposure_url': 'https://example.com/exposure',
'click_url': 'https://example.com/click',
}
});
}
PlatformResponse _sampleBridge(String sessionId) {
return PlatformResponse.fromJson({
'spec_version': '1.0',
'recommendation_id': 'rec_bridge',
'timestamp': DateTime.now().toUtc().toIso8601String(),
'status': 'generated',
'ttl_ms': 30000,
'recommendation': {
'format': 'bridge',
'disclosure': 'Ad',
'creative': {
'brand_name': 'Stripe',
'headline': 'Stripe for AI apps',
'description': 'Launch billing, invoicing, and tax support for your product.',
'cta_text': 'Explore Stripe',
'landing_page_url': 'https://example.com/stripe',
'logo_url': 'https://example.com/stripe-logo.png',
'follow_up_suggestion':
'How would Stripe compare to Lemon Squeezy for this stack?'
}
},
'tracking': {
'exposure_url': 'https://example.com/exposure-bridge',
'click_url': 'https://example.com/click-bridge',
'followup_engagement_url': 'https://example.com/followup-engagement',
'followup_exposure_url': 'https://example.com/followup-exposure',
}
});
}