koah_flutter 0.1.3
koah_flutter: ^0.1.3 copied to clipboard
A Flutter package for integrating Koah ads into your application to display relevant, contextual advertising content.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:koah_flutter/koah_flutter.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
// Initialize the Koah SDK once, before any KoahCard is built.
// Replace with the publisher ID from your Koah dashboard.
Koah.instance(publisherId: 'YOUR_PUBLISHER_ID');
runApp(const KoahExampleApp());
}
class KoahExampleApp extends StatelessWidget {
const KoahExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Koah Example',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const ChatScreen(),
);
}
}
/// One question/answer exchange in the demo chat.
class _ChatTurn {
const _ChatTurn({
required this.id,
required this.question,
required this.answer,
});
final String id;
final String question;
final String answer;
}
class ChatScreen extends StatefulWidget {
const ChatScreen({super.key});
@override
State<ChatScreen> createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
final TextEditingController _controller = TextEditingController();
final List<_ChatTurn> _turns = [];
void _send(String text) {
if (text.trim().isEmpty) return;
_controller.clear();
setState(() {
_turns.add(
_ChatTurn(
id: 'turn-${DateTime.now().millisecondsSinceEpoch}',
question: text,
answer: 'This is a demo reply to "$text".',
),
);
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Koah Example')),
body: Column(
children: [
Expanded(
child: ListView.builder(
padding: const EdgeInsets.all(12),
itemCount: _turns.length,
itemBuilder: (context, index) {
final turn = _turns[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
_Bubble(text: turn.question, isUser: true),
_Bubble(text: turn.answer, isUser: false),
// Contextual ad below the assistant's answer. Fetches on
// mount and renders nothing when there is no fill.
Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: KoahCard.withContext(
adContext: KoahAdContext.conversation(
question: turn.question,
answer: turn.answer,
),
cacheKey: turn.id,
),
),
],
);
},
),
),
const Divider(height: 1),
SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
child: Row(
children: [
Expanded(
child: TextField(
controller: _controller,
onSubmitted: _send,
decoration: const InputDecoration(
hintText: 'Ask something',
border: InputBorder.none,
),
),
),
IconButton(
icon: const Icon(Icons.send),
onPressed: () => _send(_controller.text),
),
],
),
),
),
],
),
);
}
}
class _Bubble extends StatelessWidget {
const _Bubble({required this.text, required this.isUser});
final String text;
final bool isUser;
@override
Widget build(BuildContext context) {
final colors = Theme.of(context).colorScheme;
return Align(
alignment: isUser ? Alignment.centerRight : Alignment.centerLeft,
child: Container(
margin: const EdgeInsets.symmetric(vertical: 4),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
decoration: BoxDecoration(
color: isUser ? colors.primary : colors.surfaceContainerHighest,
borderRadius: BorderRadius.circular(16),
),
child: Text(
text,
style: TextStyle(
color: isUser ? colors.onPrimary : colors.onSurfaceVariant,
),
),
),
);
}
}