notik_offerwall 1.3.0
notik_offerwall: ^1.3.0 copied to clipboard
Flutter SDK for the Notik Offerwall. Provides native offer listing, search, sort, categories, offer details, WebView-based offer flow, and postback tracking.
example/lib/main.dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:notik_offerwall/notik_offerwall.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Using 'adb reverse' for Android, so localhost:8000 works on all devices
const baseUrl = 'https://notik.me';
// Initialize the SDK
await NotikOfferwall.init(NotikConfig(
apiKey: 'kahYDyDX5Z9KtolN4Mcgk3C88YYS7Kqi',
internalApiKey: 'base64:NHdrdzV4OXNsaGdjOWM1NGhjcjltOWY2b2xvd2kweDc=',
pubId: 'i3kQ9n',
appId: 'kiBcZY7Qd3',
userId: 'bishal',
baseUrl: baseUrl,
));
// Listen for postback events
NotikOfferwall.onPostback((event) {
debugPrint(
'🎉 Postback received: ${event.offerName} — '
'${event.payout} ${event.rewardName}',
);
});
runApp(const ExampleApp());
}
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Notik Offerwall Example',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFFC67C4E), // Warm Amber palette
brightness: Brightness.light,
),
useMaterial3: true,
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFFC67C4E),
brightness: Brightness.dark,
),
useMaterial3: true,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _selectedThemeIndex = 0;
NotikLayout _selectedLayout = NotikLayout.list;
final List<({String name, NotikTheme theme})> _themes = [
(
name: 'Sunset Amber',
theme: NotikTheme(
appBarTitle: 'Sunset Store',
primaryColor: const Color(0xFFC67C4E),
backgroundColor: const Color(0xFFFFF8F5),
),
),
(
name: 'Indigo Modern',
theme: NotikTheme(
appBarTitle: 'Indigo Offers',
primaryColor: const Color(0xFF3F51B5),
backgroundColor: const Color(0xFFF5F7FF),
),
),
(
name: 'Nature Green',
theme: NotikTheme(
appBarTitle: 'Eco Rewards',
primaryColor: const Color(0xFF2E7D32),
backgroundColor: const Color(0xFFF1F8F1),
),
),
(
name: 'Midnight',
theme: NotikTheme(
appBarTitle: 'Dark Vault',
primaryColor: const Color(0xFF9C27B0),
backgroundColor: const Color(0xFF121212),
onSurfaceColor: Colors.white,
buttonTextColor: Colors.white,
useDarkTheme: true,
),
),
];
Future<void> _reinitSdk() async {
await NotikOfferwall.init(NotikConfig(
apiKey: 'kahYDyDX5Z9KtolN4Mcgk3C88YYS7Kqi',
internalApiKey: 'base64:NHdrdzV4OXNsaGdjOWM1NGhjcjltOWY2b2xvd2kweDc=',
pubId: 'i3kQ9n',
appId: 'kiBcZY7Qd3',
userId: 'bishal',
baseUrl: 'https://notik.me',
theme: _themes[_selectedThemeIndex].theme,
layout: _selectedLayout,
));
}
Future<void> _updateTheme(int index) async {
setState(() => _selectedThemeIndex = index);
await _reinitSdk();
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Theme changed to: ${_themes[index].name}'),
duration: const Duration(seconds: 1),
backgroundColor: _themes[index].theme.primaryColor,
),
);
}
}
Future<void> _toggleLayout() async {
setState(() {
_selectedLayout = _selectedLayout == NotikLayout.list
? NotikLayout.grid
: NotikLayout.list;
});
await _reinitSdk();
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Layout: ${_selectedLayout == NotikLayout.grid ? 'Grid' : 'List'}',
),
duration: const Duration(seconds: 1),
backgroundColor: _themes[_selectedThemeIndex].theme.primaryColor,
),
);
}
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
title: const Text('Notik SDK Demo'),
actions: [
IconButton(
tooltip: _selectedLayout == NotikLayout.list
? 'Switch to grid'
: 'Switch to list',
icon: Icon(
_selectedLayout == NotikLayout.list
? Icons.grid_view_rounded
: Icons.view_list_rounded,
),
onPressed: _toggleLayout,
),
],
),
body: SingleChildScrollView(
padding: const EdgeInsets.symmetric(vertical: 24),
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Customize SDK Theme',
style: theme.textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
// Theme selector cards
SizedBox(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(horizontal: 16),
itemCount: _themes.length,
itemBuilder: (context, index) {
final t = _themes[index];
final isSelected = _selectedThemeIndex == index;
return GestureDetector(
onTap: () => _updateTheme(index),
child: Container(
width: 100,
margin: const EdgeInsets.only(right: 12),
decoration: BoxDecoration(
color: t.theme.backgroundColor,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: isSelected ? t.theme.primaryColor! : Colors.grey.withValues(alpha: 0.2),
width: isSelected ? 3 : 1,
),
boxShadow: [
if (isSelected)
BoxShadow(
color: t.theme.primaryColor!.withValues(alpha: 0.3),
blurRadius: 8,
offset: const Offset(0, 4),
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 24,
height: 24,
decoration: BoxDecoration(
color: t.theme.primaryColor,
shape: BoxShape.circle,
),
),
const SizedBox(height: 8),
Text(
t.name,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 10,
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
color: t.theme.onSurfaceColor ?? Colors.black87,
),
),
],
),
),
);
},
),
),
const SizedBox(height: 48),
// Action Buttons
FilledButton.icon(
onPressed: () => NotikOfferwall.show(context),
icon: const Icon(Icons.local_offer_rounded),
label: const Text('Show Offerwall'),
style: FilledButton.styleFrom(
minimumSize: const Size(220, 52),
backgroundColor: _themes[_selectedThemeIndex].theme.primaryColor,
),
),
const SizedBox(height: 16),
OutlinedButton.icon(
onPressed: () => NotikOfferwall.showAsBottomSheet(context),
icon: const Icon(Icons.expand_less_rounded),
label: const Text('Show as Bottom Sheet'),
style: OutlinedButton.styleFrom(
minimumSize: const Size(220, 52),
side: BorderSide(color: _themes[_selectedThemeIndex].theme.primaryColor!),
foregroundColor: _themes[_selectedThemeIndex].theme.primaryColor,
),
),
const SizedBox(height: 16),
TextButton.icon(
onPressed: () => NotikOfferwall.showRewardHistory(context),
icon: const Icon(Icons.history_rounded),
label: const Text('Reward History'),
style: TextButton.styleFrom(
minimumSize: const Size(220, 52),
foregroundColor: _themes[_selectedThemeIndex].theme.primaryColor,
),
),
const SizedBox(height: 32),
Text(
'SDK v1.0.0',
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurface.withValues(alpha: 0.4),
),
),
],
),
),
),
);
}
}