promo_carousel 1.1.0 copy "promo_carousel: ^1.1.0" to clipboard
promo_carousel: ^1.1.0 copied to clipboard

A flexible, customizable promotional carousel package for Flutter.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:promo_carousel/promo_carousel.dart';

import 'video_examples_page.dart';

void main() {
  // Enable debug mode for testing
  PromoCarousel.debugMode = true;

  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Promo Carousel Demo',
      theme: ThemeData(colorScheme: .fromSeed(seedColor: Colors.deepPurple)),
      home: const DemoPage(),
    );
  }
}

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

  @override
  State<DemoPage> createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  String _lastAction = 'None';
  int _slidesViewed = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Promo Carousel Demo'),
        actions: [
          IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: () async {
              await PromoCarousel.resetAll();
              if (context.mounted) {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('All slides reset')),
                );
              }
            },
            tooltip: 'Reset all slides',
          ),
          IconButton(
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) {
                    return const VideoExamplesPage();
                  },
                ),
              );
            },
            icon: const Icon(Icons.video_call),
          ),
        ],
      ),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          Text(
            'Last Action: $_lastAction',
            style: Theme.of(context).textTheme.titleMedium,
          ),
          Text('Slides Viewed: $_slidesViewed'),
          const SizedBox(height: 24),

          _buildButton(
            context,
            'Show Standard Carousel',
            () => _showStandardCarousel(context),
          ),

          _buildButton(
            context,
            'Show with Auto-Advance',
            () => _showAutoAdvanceCarousel(context),
          ),

          _buildButton(
            context,
            'Show with Custom Widgets',
            () => _showCustomCarousel(context),
          ),

          _buildButton(
            context,
            'Show Bottom Sheet',
            () => _showBottomSheetCarousel(context),
          ),

          _buildButton(
            context,
            'Show Fullscreen',
            () => _showFullscreenCarousel(context),
          ),

          _buildButton(
            context,
            'Show with Analytics',
            () => _showAnalyticsCarousel(context),
          ),

          _buildButton(
            context,
            'Show from JSON (Remote Config)',
            () => _showJsonCarousel(context),
          ),

          _buildButton(
            context,
            'Preview Mode (All Slides)',
            () => _showPreviewCarousel(context),
          ),
        ],
      ),
    );
  }

  Widget _buildButton(
    BuildContext context,
    String text,
    VoidCallback onPressed,
  ) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 12),
      child: ElevatedButton(
        onPressed: onPressed,
        style: ElevatedButton.styleFrom(padding: const EdgeInsets.all(16)),
        child: Text(text),
      ),
    );
  }

  void _showStandardCarousel(BuildContext context) {
    PromoCarousel.show(
      context: context,
      slides: _getStandardSlides(),
      config: const PromoCarouselConfig(
        showCloseButton: true,
        showDontShowAgain: true,
        enableHaptics: true,
      ),
      onAction: _handleAction,
      onDismiss: () => print('Carousel dismissed'),
    );
  }

  void _showAutoAdvanceCarousel(BuildContext context) {
    PromoCarousel.show(
      context: context,
      slides: _getStandardSlides(),
      config: const PromoCarouselConfig(
        autoAdvance: true,
        autoAdvanceDuration: Duration(seconds: 3),
        pauseOnInteraction: true,
        showProgressBar: true,
        progressBarPosition: ProgressPosition.top,
      ),
      onAction: _handleAction,
    );
  }

  void _showCustomCarousel(BuildContext context) {
    // Simulated user data
    final userZodiacSign = '♋ Cancer';
    final userTopSearch = 'why am I crying at 3am';

    PromoCarousel.show(
      context: context,
      slides: [
        PromoSlide(
          id: 'zodiac_preview',
          title: 'Late-Night Most\nGoogled\nSecrets',
          visualType: PromoVisualType.custom,
          cta: PromoCTA(
            text: 'Face your secrets',
            action: PromoAction.openFeature,
            target: 'zodiac_detail',
          ),
          rules: const PromoRules(showOnce: true),
          customContentBuilder: (context) {
            return _buildZodiacWidget(userZodiacSign, userTopSearch);
          },
        ),
        ..._getStandardSlides().skip(1),
      ],
      config: PromoCarouselConfig.announcement(),
      onAction: _handleAction,
    );
  }

  void _showBottomSheetCarousel(BuildContext context) {
    PromoCarousel.showBottomSheet(
      context: context,
      slides: _getStandardSlides(),
      config: const PromoCarouselConfig(
        showSkipButton: true,
        backdropBlur: 5.0,
      ),
      onAction: _handleAction,
    );
  }

  void _showFullscreenCarousel(BuildContext context) {
    PromoCarousel.showFullscreen(
      context: context,
      slides: _getStandardSlides(),
      config: PromoCarouselConfig.onboarding(),
      onAction: _handleAction,
    );
  }

  void _showAnalyticsCarousel(BuildContext context) {
    PromoCarousel.show(
      context: context,
      slides: _getStandardSlides(),
      analytics: PromoCarouselAnalytics(
        onSlideViewed: (slideId, index) async {
          print('📊 Viewed: $slideId at index $index');
          await Future.delayed(const Duration(milliseconds: 500));
          if (context.mounted) {
            setState(() => _slidesViewed++);
          }
        },
        onSlideSkipped: (slideId, index) {
          print('⏭️ Skipped: $slideId');
        },
        onCTAClicked: (slideId, action, target) {
          print('🔘 CTA Clicked: $slideId - $action -> $target');
        },
        onCarouselCompleted: (viewedSlides) {
          print('✅ Completed! Viewed: $viewedSlides');
        },
        onCarouselDismissed: (lastIndex, viewedSlides) {
          print('❌ Dismissed at $lastIndex. Viewed: $viewedSlides');
        },
        onSkipAll: () {
          print('⏩ Skip all clicked');
        },
      ),
      config: const PromoCarouselConfig(showSkipButton: true),
      onAction: _handleAction,
    );
  }

  void _showJsonCarousel(BuildContext context) {
    // Simulate loading from remote config
    final jsonData = [
      {
        'id': 'remote_promo_1',
        'title': 'New Feature Alert!',
        'subtitle': 'Loaded from remote config',
        'visualType': 'featureHighlight',
        'cta': {
          'text': 'Try Now',
          'action': 'openFeature',
          'target': 'new_feature',
        },
        'rules': {'showOnce': true, 'minAppVersion': '1.0.0'},
      },
    ];

    final slides = PromoCarousel.fromJson(jsonData);

    PromoCarousel.show(
      context: context,
      slides: [...slides, ..._getStandardSlides()],
      onAction: _handleAction,
    );
  }

  void _showPreviewCarousel(BuildContext context) {
    PromoCarousel.showPreview(
      context: context,
      slides: _getStandardSlides(),
      config: const PromoCarouselConfig(showProgressBar: true),
      onAction: _handleAction,
    );
  }

  void _handleAction(PromoAction action, String? target) {
    setState(() {
      _lastAction = '$action -> $target';
    });

    ScaffoldMessenger.of(
      context,
    ).showSnackBar(SnackBar(content: Text('Action: $action → $target')));
  }

  List<PromoSlide> _getStandardSlides() {
    return [
      PromoSlide(
        id: 'welcome',
        title: 'Welcome to Our App!',
        subtitle: 'Discover amazing features',
        visualType: PromoVisualType.featureHighlight,
        cta: PromoCTA(
          text: 'Get Started',
          action: PromoAction.navigate,
          target: '/home',
        ),
        rules: const PromoRules(showOnce: true, showAfterDate: null),
      ),
      PromoSlide(
        id: 'feature_2',
        title: 'Search Made Easy',
        subtitle: 'Find what you need instantly',
        visualType: PromoVisualType.searchBar,
        cta: PromoCTA(
          text: 'Try Search',
          action: PromoAction.openFeature,
          target: 'search',
        ),
        rules: const PromoRules(showOnce: false),
      ),
      PromoSlide(
        id: 'premium_offer',
        title: 'Unlock Premium',
        subtitle: 'Get access to exclusive features',
        visualType: PromoVisualType.featureHighlight,
        cta: PromoCTA(text: 'Upgrade Now', action: PromoAction.openPaywall),
        rules: const PromoRules(showOnce: true, userSegments: ['free_tier']),
      ),
    ];
  }

  Widget _buildZodiacWidget(String sign, String search) {
    return Container(
      height: 200,
      decoration: BoxDecoration(
        color: Colors.grey[900],
        borderRadius: BorderRadius.circular(16),
      ),
      padding: const EdgeInsets.all(24),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
            decoration: BoxDecoration(
              color: Colors.grey[800],
              borderRadius: BorderRadius.circular(24),
            ),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(Icons.search, color: Colors.grey[400], size: 20),
                const SizedBox(width: 8),
                Text(
                  'your search history is loading...',
                  style: TextStyle(color: Colors.grey[400], fontSize: 14),
                ),
              ],
            ),
          ),
          const SizedBox(height: 24),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Icon(Icons.auto_awesome, color: Colors.blue, size: 20),
              const SizedBox(width: 8),
              Flexible(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'The Google searches',
                      style: TextStyle(color: Colors.grey[400], fontSize: 13),
                    ),
                    RichText(
                      text: TextSpan(
                        style: const TextStyle(
                          fontSize: 13,
                          color: Colors.white,
                        ),
                        children: [
                          const TextSpan(text: 'your zodiac sign '),
                          TextSpan(
                            text: sign,
                            style: const TextStyle(fontWeight: FontWeight.bold),
                          ),
                        ],
                      ),
                    ),
                    Text(
                      'hopes that it dies with them',
                      style: TextStyle(color: Colors.grey[400], fontSize: 13),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}
1
likes
0
points
303
downloads

Publisher

verified publisherkyawzayartun.com

Weekly Downloads

A flexible, customizable promotional carousel package for Flutter.

Repository (GitHub)
View/report issues

Topics

#onboarding #promo-content #promo-carousel #utility

License

unknown (license)

Dependencies

flutter, shared_preferences, video_player

More

Packages that depend on promo_carousel