ayet_sdk_v2 1.0.0 copy "ayet_sdk_v2: ^1.0.0" to clipboard
ayet_sdk_v2: ^1.0.0 copied to clipboard

Flutter plugin for ayetstudios SDK v2 - offerwall, surveywall, and reward status integration.

example/lib/main.dart

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:ayet_sdk_v2/ayet_sdk_v2.dart';

import 'ayet_config.dart';

// ==================== Colors ====================

class AyetColors {
  static const Color navy = Color(0xFF233649);
  static const Color orange = Color(0xFFF58F00);
  static const Color purple = Color(0xFF635DFF);

  // Light theme
  static const Color backgroundLight = Color(0xFFF8F9FA);
  static const Color surfaceLight = Color(0xFFFFFFFF);
  static const Color surfaceVariantLight = Color(0xFFF0F2F5);

  // Dark theme
  static const Color primaryDark = Color(0xFF8B9CAD);
  static const Color secondaryDark = Color(0xFFFFB74D);
  static const Color tertiaryDark = Color(0xFF9C98FF);
  static const Color backgroundDark = Color(0xFF121820);
  static const Color surfaceDark = Color(0xFF1E2530);
  static const Color surfaceVariantDark = Color(0xFF2A3441);
}

// ==================== Theme ====================

ThemeData buildLightTheme() {
  return ThemeData(
    useMaterial3: true,
    brightness: Brightness.light,
    colorScheme: const ColorScheme.light(
      primary: AyetColors.navy,
      secondary: AyetColors.orange,
      tertiary: AyetColors.purple,
      surface: AyetColors.surfaceLight,
      surfaceContainerHighest: AyetColors.surfaceVariantLight,
    ),
    scaffoldBackgroundColor: AyetColors.backgroundLight,
  );
}

ThemeData buildDarkTheme() {
  return ThemeData(
    useMaterial3: true,
    brightness: Brightness.dark,
    colorScheme: const ColorScheme.dark(
      primary: AyetColors.primaryDark,
      secondary: AyetColors.secondaryDark,
      tertiary: AyetColors.tertiaryDark,
      surface: AyetColors.surfaceDark,
      surfaceContainerHighest: AyetColors.surfaceVariantDark,
    ),
    scaffoldBackgroundColor: AyetColors.backgroundDark,
  );
}

// ==================== Main App ====================

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Ayet SDK Demo',
      debugShowCheckedModeBanner: false,
      theme: buildLightTheme(),
      darkTheme: buildDarkTheme(),
      home: const AyetDemoApp(),
    );
  }
}

class AyetDemoApp extends StatefulWidget {
  const AyetDemoApp({super.key});

  @override
  State<AyetDemoApp> createState() => _AyetDemoAppState();
}

class _AyetDemoAppState extends State<AyetDemoApp> {
  final _ayetSdk = AyetSdkV2();
  String _externalId = '';
  bool _isInitialized = false;
  bool _isLoading = true;

  @override
  void initState() {
    super.initState();
    _loadExternalId();
  }

  Future<void> _loadExternalId() async {
    final prefs = await SharedPreferences.getInstance();
    String? savedId = prefs.getString('external_id');

    if (savedId == null) {
      savedId = 'user_${Random().nextInt(900000) + 100000}';
      await prefs.setString('external_id', savedId);
    }

    setState(() {
      _externalId = savedId!;
      _isLoading = false;
    });

    _initializeSdk();
  }

  Future<void> _initializeSdk() async {
    if (_isInitialized) return;

    await _ayetSdk.setDebug(true);
    await _ayetSdk.setFullscreenMode(true);
    await _ayetSdk.init(
      placementId: AyetConfig.placementId,
      externalIdentifier: _externalId,
    );
    await _ayetSdk.setGender(AyetConfig.defaultGender);
    await _ayetSdk.setAge(AyetConfig.defaultAge);
    await _ayetSdk.setTrackingCustom1(AyetConfig.defaultCustom1);

    _isInitialized = true;
  }

  Future<void> _updateExternalId(String newId) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('external_id', newId);

    setState(() {
      _externalId = newId;
    });

    // Re-initialize SDK with new ID
    await _ayetSdk.init(
      placementId: AyetConfig.placementId,
      externalIdentifier: newId,
    );
    await _ayetSdk.setGender(AyetConfig.defaultGender);
    await _ayetSdk.setAge(AyetConfig.defaultAge);
    await _ayetSdk.setTrackingCustom1(AyetConfig.defaultCustom1);

    if (mounted) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(const SnackBar(content: Text('External ID updated')));
    }
  }

  void _showEditDialog() {
    final controller = TextEditingController(text: _externalId);

    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
        title: const Text(
          'Edit External ID',
          style: TextStyle(fontWeight: FontWeight.w600),
        ),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'The SDK will be re-initialized with the new identifier.',
              style: TextStyle(
                fontSize: 12,
                color: Theme.of(context).colorScheme.onSurface.withAlpha(153),
              ),
            ),
            const SizedBox(height: 16),
            TextField(
              controller: controller,
              decoration: InputDecoration(
                labelText: 'External Identifier',
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(12),
                ),
              ),
              textInputAction: TextInputAction.done,
            ),
          ],
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text('Cancel'),
          ),
          FilledButton(
            onPressed: () {
              final newId = controller.text.trim();
              if (newId.isNotEmpty) {
                Navigator.pop(context);
                _updateExternalId(newId);
              }
            },
            style: FilledButton.styleFrom(
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(12),
              ),
            ),
            child: const Text('Save'),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    if (_isLoading) {
      return const Scaffold(body: Center(child: CircularProgressIndicator()));
    }

    return Scaffold(
      body: SafeArea(
        top: false,
        child: SingleChildScrollView(
          child: Column(
            children: [
              // Header Section
              _HeaderSection(),

              const SizedBox(height: 24),

              // External ID Card
              _ExternalIdCard(
                externalId: _externalId,
                onEditTap: _showEditDialog,
              ),

              const SizedBox(height: 24),

              // Action Buttons
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 24),
                child: Column(
                  children: [
                    _ActionButton(
                      text: 'Show Offerwall',
                      icon: Icons.list,
                      color: AyetColors.orange,
                      onTap: () =>
                          _ayetSdk.showOfferwall(AyetConfig.adslotOfferwall),
                    ),
                    const SizedBox(height: 16),
                    _ActionButton(
                      text: 'Show Surveywall',
                      icon: Icons.check_circle,
                      color: AyetColors.purple,
                      onTap: () =>
                          _ayetSdk.showSurveywall(AyetConfig.adslotSurveywall),
                    ),
                    const SizedBox(height: 16),
                    _ActionButton(
                      text: 'Reward Status',
                      icon: Icons.star,
                      color: Theme.of(context).colorScheme.primary,
                      onTap: () => _ayetSdk.showRewardStatus(),
                    ),
                    const SizedBox(height: 24),
                    _GetOffersButton(ayetSdk: _ayetSdk),
                  ],
                ),
              ),

              const SizedBox(height: 32),

              // Footer Info
              _FooterInfo(),

              const SizedBox(height: 24),
            ],
          ),
        ),
      ),
    );
  }
}

// ==================== Widgets ====================

class _HeaderSection extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: 200,
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          colors: [
            Theme.of(context).colorScheme.primary,
            Theme.of(context).colorScheme.primary.withAlpha(204),
          ],
        ),
        borderRadius: const BorderRadius.only(
          bottomLeft: Radius.circular(32),
          bottomRight: Radius.circular(32),
        ),
      ),
      child: SafeArea(
        bottom: false,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.asset(
              'assets/logo.png',
              width: 140,
              height: 70,
              fit: BoxFit.contain,
            ),
            const SizedBox(height: 16),
            Text(
              'SDK Demo',
              style: Theme.of(context).textTheme.headlineMedium?.copyWith(
                color: Colors.white,
                fontWeight: FontWeight.w300,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _ExternalIdCard extends StatelessWidget {
  final String externalId;
  final VoidCallback onEditTap;

  const _ExternalIdCard({required this.externalId, required this.onEditTap});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 24),
      child: Card(
        elevation: 4,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
        child: Padding(
          padding: const EdgeInsets.all(20),
          child: Row(
            children: [
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'External Identifier',
                      style: Theme.of(context).textTheme.labelMedium?.copyWith(
                        color: Theme.of(
                          context,
                        ).colorScheme.onSurface.withAlpha(153),
                      ),
                    ),
                    const SizedBox(height: 4),
                    Text(
                      externalId,
                      style: Theme.of(context).textTheme.bodyLarge?.copyWith(
                        fontWeight: FontWeight.w500,
                      ),
                    ),
                  ],
                ),
              ),
              IconButton(
                onPressed: onEditTap,
                icon: Icon(
                  Icons.edit,
                  color: Theme.of(context).colorScheme.secondary,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _ActionButton extends StatelessWidget {
  final String text;
  final IconData icon;
  final Color color;
  final VoidCallback onTap;

  const _ActionButton({
    required this.text,
    required this.icon,
    required this.color,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: double.infinity,
      height: 60,
      child: ElevatedButton(
        onPressed: onTap,
        style: ElevatedButton.styleFrom(
          backgroundColor: color,
          foregroundColor: Colors.white,
          elevation: 4,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(16),
          ),
        ),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(icon, size: 24),
            const SizedBox(width: 12),
            Text(
              text,
              style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
            ),
          ],
        ),
      ),
    );
  }
}

class _GetOffersButton extends StatefulWidget {
  final AyetSdkV2 ayetSdk;

  const _GetOffersButton({required this.ayetSdk});

  @override
  State<_GetOffersButton> createState() => _GetOffersButtonState();
}

class _GetOffersButtonState extends State<_GetOffersButton> {
  bool _isLoading = false;

  Future<void> _getOffers() async {
    setState(() => _isLoading = true);

    try {
      final offersJson = await widget.ayetSdk.getOffers(AyetConfig.adslotFeed);

      if (!mounted) return;

      if (offersJson != null) {
        debugPrint('Offers received: $offersJson');
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('Offers received! Check debug console for details'),
            duration: Duration(seconds: 3),
          ),
        );
      } else {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('Failed to get offers')));
      }
    } finally {
      if (mounted) {
        setState(() => _isLoading = false);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: double.infinity,
      height: 52,
      child: ElevatedButton(
        onPressed: _isLoading ? null : _getOffers,
        style: ElevatedButton.styleFrom(
          backgroundColor: Theme.of(
            context,
          ).colorScheme.surfaceContainerHighest,
          foregroundColor: Theme.of(context).colorScheme.onSurface,
          elevation: 2,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(12),
          ),
        ),
        child: AnimatedSwitcher(
          duration: const Duration(milliseconds: 200),
          child: _isLoading
              ? const Text(
                  'Loading...',
                  key: ValueKey('loading'),
                  style: TextStyle(fontWeight: FontWeight.w500),
                )
              : const Text(
                  'Get Offers (API)',
                  key: ValueKey('idle'),
                  style: TextStyle(fontWeight: FontWeight.w500),
                ),
        ),
      ),
    );
  }
}

class _FooterInfo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final genderText = switch (AyetConfig.defaultGender) {
      AyetGender.male => 'Male',
      AyetGender.female => 'Female',
      AyetGender.nonBinary => 'Non-Binary',
    };

    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 32),
      child: Text(
        'Gender: $genderText • Age: ${AyetConfig.defaultAge}',
        style: Theme.of(context).textTheme.bodySmall?.copyWith(
          color: Theme.of(context).colorScheme.onSurface.withAlpha(102),
        ),
        textAlign: TextAlign.center,
      ),
    );
  }
}
1
likes
150
points
163
downloads

Publisher

unverified uploader

Weekly Downloads

Flutter plugin for ayetstudios SDK v2 - offerwall, surveywall, and reward status integration.

Homepage

Documentation

API reference

License

unknown (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on ayet_sdk_v2

Packages that implement ayet_sdk_v2