new_version_plus 1.0.1
new_version_plus: ^1.0.1 copied to clipboard
Check if your user has the most recent version of your Flutter app.
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),
),
);
}
}
}