smart_update 1.0.0
smart_update: ^1.0.0 copied to clipboard
Flutter package for checking and prompting app upgrades from app stores
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:smart_update/smart_update.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Smart Update Example',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final UpgradeController _upgradeController = UpgradeController();
VersionInfo? _versionInfo;
bool _isChecking = false;
@override
void initState() {
super.initState();
// Listen to upgrade controller streams
_upgradeController.versionInfoStream.listen((versionInfo) {
setState(() {
_versionInfo = versionInfo;
});
});
_upgradeController.checkingStateStream.listen((isChecking) {
setState(() {
_isChecking = isChecking;
});
});
}
@override
void dispose() {
_upgradeController.dispose();
super.dispose();
}
Future<void> _checkForUpdates() async {
await _upgradeController.checkForUpdates(
config: const UpgradeConfig(
debugMode: true, // Enable debug mode for testing
showReleaseNotes: true,
allowUserToSkip: true,
),
);
}
Future<void> _forceCheck() async {
await _upgradeController.forceCheckForUpdates(
config: const UpgradeConfig(
debugMode: true,
showReleaseNotes: true,
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text('Smart Update Example'),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Basic Usage with UpgradeAlert
const Card(
child: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Basic Usage - UpgradeAlert',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 8),
Text(
'Wrap your widget with UpgradeAlert to automatically check for updates:',
),
SizedBox(height: 16),
UpgradeAlert(
config: UpgradeConfig(
debugMode: true,
showReleaseNotes: true,
),
child: Text('This content is wrapped by UpgradeAlert'),
),
],
),
),
),
const SizedBox(height: 16),
// UpgradeCard Widget
const Text(
'UpgradeCard Widget',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
UpgradeCard(
config: const UpgradeConfig(
debugMode: true,
showReleaseNotes: true,
maxReleaseNotesLength: 200,
),
showOnlyWhenUpdateAvailable: false,
onUserAction: (action) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('User action: ${action.name}')),
);
},
),
const SizedBox(height: 16),
// Manual Controls
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Manual Controls',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: _isChecking ? null : _checkForUpdates,
child: _isChecking
? const Row(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(
strokeWidth: 2,
),
),
SizedBox(width: 8),
Text('Checking...'),
],
)
: const Text('Check for Updates'),
),
),
const SizedBox(width: 8),
Expanded(
child: ElevatedButton(
onPressed: _isChecking ? null : _forceCheck,
child: const Text('Force Check'),
),
),
],
),
if (_versionInfo != null) ...[
const SizedBox(height: 16),
const Divider(),
const SizedBox(height: 16),
Text(
'Version Information',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 8),
_buildInfoRow('Platform', _versionInfo!.platform),
_buildInfoRow(
'Installed Version',
_versionInfo!.installedVersion?.toString() ??
'Unknown'),
_buildInfoRow('Store Version',
_versionInfo!.storeVersion?.toString() ?? 'Unknown'),
_buildInfoRow('Update Available',
_versionInfo!.isUpdateAvailable.toString()),
_buildInfoRow('Force Update',
_versionInfo!.shouldForceUpgrade.toString()),
if (_versionInfo!.storeUrl != null)
_buildInfoRow('Store URL', _versionInfo!.storeUrl!),
if (_versionInfo!.releaseNotes != null) ...[
const SizedBox(height: 8),
Text(
'Release Notes:',
style: Theme.of(context).textTheme.titleSmall,
),
const SizedBox(height: 4),
Container(
width: double.infinity,
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(4),
),
child: Text(
_versionInfo!.releaseNotes!.length > 200
? '${_versionInfo!.releaseNotes!.substring(0, 200)}...'
: _versionInfo!.releaseNotes!,
style: const TextStyle(fontSize: 12),
),
),
],
],
],
),
),
),
const SizedBox(height: 16),
// Configuration Examples
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Configuration Examples',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
const Text('Different configurations you can use:',
style: TextStyle(fontWeight: FontWeight.w500)),
const SizedBox(height: 8),
_buildConfigExample('Debug Mode', 'debugMode: true'),
_buildConfigExample('Country Code', 'countryCode: "US"'),
_buildConfigExample('Min Days', 'minDays: 7'),
_buildConfigExample(
'Custom Store URL', 'appStoreUrl: "https://..."'),
_buildConfigExample(
'Show Release Notes', 'showReleaseNotes: true'),
_buildConfigExample('Allow Skip', 'allowUserToSkip: false'),
],
),
),
),
],
),
),
);
}
Widget _buildInfoRow(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 2),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 120,
child: Text(
'$label:',
style: const TextStyle(fontWeight: FontWeight.w500),
),
),
Expanded(
child: Text(
value,
style: const TextStyle(fontSize: 12),
),
),
],
),
);
}
Widget _buildConfigExample(String title, String code) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 2),
child: Row(
children: [
SizedBox(
width: 100,
child: Text(
title,
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
),
),
Expanded(
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(4),
),
child: Text(
code,
style: const TextStyle(
fontSize: 11,
fontFamily: 'monospace',
),
),
),
),
],
),
);
}
}