new_version_plus 1.0.1 copy "new_version_plus: ^1.0.1" to clipboard
new_version_plus: ^1.0.1 copied to clipboard

Check if your user has the most recent version of your Flutter app.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:new_version_plus/new_version_plus.dart';
import 'package:new_version_plus/strategies/api_version_source.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'New Version Plus Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String release = "";
  String statusMessage = "Select a method to check for updates";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("New Version Plus Example"),
      ),
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              Text(
                statusMessage,
                style: const TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.bold,
                ),
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: 20),
              const Text(
                "Traditional App Store Check",
                style: TextStyle(
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 10),
              ElevatedButton(
                onPressed: () => _basicStatusCheck(),
                child: const Text("Basic Check (Auto Dialog)"),
              ),
              const SizedBox(height: 10),
              ElevatedButton(
                onPressed: () => _advancedStatusCheck(),
                child: const Text("Advanced Check (Custom Dialog)"),
              ),
              const SizedBox(height: 10),
              ElevatedButton(
                onPressed: () => _testDialog(),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.orange,
                ),
                child: const Text("Test Dialog (Force Show)"),
              ),
              const SizedBox(height: 30),
              const Text(
                "Relva API Integration (Beta)",
                style: TextStyle(
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 10),
              ElevatedButton(
                onPressed: () => _relvaApiCheck(),
                child: const Text("Relva API Check (Modern Dialog)"),
              ),
              const SizedBox(height: 10),
              ElevatedButton(
                onPressed: () => _relvaApiManualCheck(),
                child: const Text("Relva API Manual Check"),
              ),
              const SizedBox(height: 20),
              if (release.isNotEmpty) ...[
                const Divider(),
                const Text(
                  "Release Notes:",
                  style: TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                const SizedBox(height: 10),
                Expanded(
                  child: SingleChildScrollView(
                    child: Html(data: release),
                  ),
                ),
              ],
            ],
          ),
        ),
      ),
    );
  }

  /// Basic status check using traditional App Store method
  /// Shows automatic platform-specific dialog
  Future<void> _basicStatusCheck() async {
    setState(() {
      statusMessage = "Checking for updates (Basic)...";
      release = "";
    });

    // Instantiate NewVersion manager object (Using Disney+ app as example)
    final newVersion = NewVersionPlus(
      iOSId: 'com.disney.disneyplus',
      androidId: 'com.disney.disneyplus',
      androidPlayStoreCountry: "es_ES",
      androidHtmlReleaseNotes: true,
    );

    // Get version status
    final version = await newVersion.getVersionStatus();
    if (version != null) {
      setState(() {
        release = version.releaseNotes ?? "";
        statusMessage = "Update available: ${version.storeVersion}";
      });
    } else {
      setState(() {
        statusMessage = "No update available";
      });
    }

    // Show automatic alert if necessary
    // This will only show if canUpdate is true
    if (mounted) {
      newVersion.showAlertIfNecessary(
        context: context,
        launchModeVersion: LaunchModeVersion.external,
      );
      
      // Show feedback
      if (version != null && version.canUpdate) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('Dialog shown (if update available)'),
            duration: Duration(seconds: 2),
          ),
        );
      } else {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('No update available - dialog not shown'),
            duration: Duration(seconds: 2),
          ),
        );
      }
    }
  }

  /// Advanced status check using traditional App Store method
  /// Shows custom dialog with more control
  Future<void> _advancedStatusCheck() async {
    setState(() {
      statusMessage = "Checking for updates (Advanced)...";
      release = "";
    });

    final newVersion = NewVersionPlus(
      iOSId: 'com.disney.disneyplus',
      androidId: 'com.disney.disneyplus',
      androidPlayStoreCountry: "es_ES",
      androidHtmlReleaseNotes: true,
    );

    final status = await newVersion.getVersionStatus();
    if (status != null) {
      setState(() {
        release = status.releaseNotes ?? "";
        statusMessage = "Update available: ${status.storeVersion}";
      });

      debugPrint('Release Notes: ${status.releaseNotes}');
      debugPrint('App Store Link: ${status.appStoreLink}');
      debugPrint('Local Version: ${status.localVersion}');
      debugPrint('Store Version: ${status.storeVersion}');
      debugPrint('Can Update: ${status.canUpdate}');

      if (mounted) {
        // Always show dialog if status is not null (even if canUpdate is false)
        newVersion.showUpdateDialog(
          context: context,
          versionStatus: status,
          dialogTitle: 'Custom Title',
          dialogText: 'Custom Text - Update from ${status.localVersion} to ${status.storeVersion}',
          launchModeVersion: LaunchModeVersion.external,
          allowDismissal: false,
        );
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('Custom dialog shown'),
            duration: Duration(seconds: 2),
          ),
        );
      }
    } else {
      setState(() {
        statusMessage = "No update available";
      });
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('No update available - cannot show dialog'),
            duration: Duration(seconds: 2),
          ),
        );
      }
    }
  }

  /// Relva API check using modern dialog
  /// Shows automatic modern dialog if update is available
  Future<void> _relvaApiCheck() async {
    setState(() {
      statusMessage = "Checking for updates via Relva API...";
      release = "";
    });

    // Configure Relva API integration
    // NOTE: Replace 'YOUR_API_KEY' with your actual Relva API Key
    final newVersion = NewVersionPlus(
      versionSource: ApiVersionSource(
        apiKey: 'nv_1766da2f0c0da24693fdd88371f23260dacf6a248bed6bbff62607704422f1f8', // Replace with your actual API Key
        useNewApiFormat: true,
      ),
    );

    try {
      if (mounted) {
        await newVersion.showModernUpdateDialogIfNecessary(
          context: context,
        );
        setState(() {
          statusMessage = "Relva API check completed - Dialog shown if update available";
        });
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('Check completed - Dialog shown if update available and in rollout'),
            duration: Duration(seconds: 2),
          ),
        );
      }
    } catch (e) {
      setState(() {
        statusMessage = "Error: $e";
      });
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Error checking updates: $e'),
            backgroundColor: Colors.red,
          ),
        );
      }
    }
  }

  /// Relva API manual check
  /// Get response and handle manually
  Future<void> _relvaApiManualCheck() async {
    setState(() {
      statusMessage = "Checking for updates via Relva API (Manual)...";
      release = "";
    });

    // Configure Relva API integration
    // NOTE: Replace with your actual Relva API Key
    final newVersion = NewVersionPlus(
      versionSource: ApiVersionSource(
        apiKey: 'nv_1766da2f0c0da24693fdd88371f23260dacf6a248bed6bbff62607704422f1f8', // Replace with your actual API Key
        useNewApiFormat: true,
      ),
    );

    try {
      final response = await newVersion.getVersionCheckResponse();

      if (response != null && response.hasUpdate) {
        setState(() {
          release = response.releaseNotes ?? "";
          statusMessage = "Update available: ${response.versionCode} (Force: ${response.isForceUpdate})";
        });

        debugPrint('Has Update: ${response.hasUpdate}');
        debugPrint('Force Update: ${response.isForceUpdate}');
        debugPrint('Version Code: ${response.versionCode}');
        debugPrint('Build Number: ${response.buildNumber}');
        debugPrint('Release Notes: ${response.releaseNotes}');
        debugPrint('Is In Rollout: ${response.isInRollout}');
        debugPrint('Rollout Percentage: ${response.rolloutPercentage}');

        if (mounted) {
          newVersion.showModernUpdateDialog(
            context: context,
            response: response,
            launchModeVersion: LaunchModeVersion.external,
          );
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text('Modern dialog shown'),
              backgroundColor: Colors.green,
              duration: Duration(seconds: 2),
            ),
          );
        }
      } else {
        setState(() {
          statusMessage = "No update available or not in rollout";
        });
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text('No update available or not in rollout - Dialog not shown'),
              duration: Duration(seconds: 2),
            ),
          );
        }
      }
    } catch (e) {
      setState(() {
        statusMessage = "Error: $e";
      });
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Error checking updates: $e'),
            backgroundColor: Colors.red,
          ),
        );
      }
    }
  }

  /// Test dialog - Force show dialog for testing purposes
  /// This uses forceAppVersion to always show the dialog
  Future<void> _testDialog() async {
    setState(() {
      statusMessage = "Showing test dialog...";
      release = "";
    });

    // Force a version to always show the dialog
    final newVersion = NewVersionPlus(
      iOSId: 'com.disney.disneyplus',
      androidId: 'com.disney.disneyplus',
      forceAppVersion: '999.999.999', // Force a very high version
      androidPlayStoreCountry: "es_ES",
      androidHtmlReleaseNotes: true,
    );

    final status = await newVersion.getVersionStatus();
    if (status != null && mounted) {
      setState(() {
        release = status.releaseNotes ?? "Test release notes";
        statusMessage = "Test dialog - Store version: ${status.storeVersion}";
      });

      newVersion.showUpdateDialog(
        context: context,
        versionStatus: status,
        dialogTitle: 'Test Update Dialog',
        dialogText: 'This is a test dialog to demonstrate the update UI.\n\nLocal: ${status.localVersion}\nStore: ${status.storeVersion}',
        updateButtonText: 'Update Now',
        dismissButtonText: 'Maybe Later',
        launchModeVersion: LaunchModeVersion.external,
        allowDismissal: true,
      );

      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Test dialog shown (forced)'),
          backgroundColor: Colors.green,
          duration: Duration(seconds: 2),
        ),
      );
    }
  }
}
181
likes
140
points
30.3k
downloads

Publisher

verified publishercodesfirst.com

Weekly Downloads

Check if your user has the most recent version of your Flutter app.

Repository (GitHub)
View/report issues

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

device_info_plus, flutter, http, package_info_plus, url_launcher

More

Packages that depend on new_version_plus