add project
This commit is contained in:
58
lib/src/error_material_alert.dart
Normal file
58
lib/src/error_material_alert.dart
Normal file
@@ -0,0 +1,58 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ErrorMaterialAlert extends StatelessWidget {
|
||||
final String appName;
|
||||
final String description;
|
||||
final String? errorCloseButtonLabel;
|
||||
final String? errorSubtitle;
|
||||
|
||||
ErrorMaterialAlert({
|
||||
required this.appName,
|
||||
required this.description,
|
||||
this.errorCloseButtonLabel,
|
||||
this.errorSubtitle,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ButtonStyle flatButtonStyle = TextButton.styleFrom(
|
||||
backgroundColor: Colors.green,
|
||||
);
|
||||
|
||||
Widget closeButton = TextButton(
|
||||
child: Text(errorCloseButtonLabel ?? 'CLOSE', style: TextStyle(color: Colors.white)),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
style: flatButtonStyle,
|
||||
);
|
||||
|
||||
return AlertDialog(
|
||||
title: Text(appName),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
errorSubtitle ?? 'Can\'t perform update.',
|
||||
style: TextStyle(color: Colors.grey),
|
||||
),
|
||||
SizedBox(height: 24.0),
|
||||
Text(description),
|
||||
SizedBox(height: 24.0),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
closeButton,
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
Divider(),
|
||||
SizedBox(height: 16.0),
|
||||
Image.asset(
|
||||
'packages/native_updater/images/google_play.png',
|
||||
width: 120.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
138
lib/src/native_updater.dart
Normal file
138
lib/src/native_updater.dart
Normal file
@@ -0,0 +1,138 @@
|
||||
import 'dart:developer' as developer;
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:in_app_update/in_app_update.dart';
|
||||
import 'package:package_info/package_info.dart';
|
||||
|
||||
import 'error_material_alert.dart';
|
||||
import 'update_cupertino_alert.dart';
|
||||
|
||||
class NativeUpdater {
|
||||
late BuildContext _context;
|
||||
late bool _forceUpdate;
|
||||
late String _appName;
|
||||
String? _appStoreUrl;
|
||||
String? _iOSDescription;
|
||||
String? _iOSUpdateButtonLabel;
|
||||
String? _iOSCloseButtonLabel;
|
||||
String? _iOSIgnoreButtonLabel;
|
||||
String? _iOSAlertTitle;
|
||||
String? _requireUpdateText;
|
||||
String? _recommendUpdateText;
|
||||
String? _errorText;
|
||||
String? _errorCloseButtonLabel;
|
||||
String? _errorSubtitle;
|
||||
|
||||
/// Singleton related
|
||||
static final NativeUpdater _nativeUpdaterInstance = NativeUpdater._internal();
|
||||
factory NativeUpdater() => _nativeUpdaterInstance;
|
||||
NativeUpdater._internal();
|
||||
|
||||
/// Displaying update alert
|
||||
static displayUpdateAlert(
|
||||
BuildContext context, {
|
||||
required bool forceUpdate,
|
||||
String? appStoreUrl,
|
||||
String? iOSDescription,
|
||||
String? iOSUpdateButtonLabel,
|
||||
String? iOSCloseButtonLabel,
|
||||
String? iOSIgnoreButtonLabel,
|
||||
String? iOSAlertTitle,
|
||||
String? requireUpdateText,
|
||||
String? recommendUpdateText,
|
||||
String? errorText,
|
||||
String? errorCloseButtonLabel,
|
||||
String? errorSubtitle,
|
||||
}) async {
|
||||
/// Get current installed version of app
|
||||
final PackageInfo info = await PackageInfo.fromPlatform();
|
||||
|
||||
/// Set singleton properties
|
||||
_nativeUpdaterInstance._context = context;
|
||||
_nativeUpdaterInstance._forceUpdate = forceUpdate;
|
||||
_nativeUpdaterInstance._appName = info.appName;
|
||||
_nativeUpdaterInstance._appStoreUrl = appStoreUrl;
|
||||
_nativeUpdaterInstance._iOSDescription = iOSDescription;
|
||||
_nativeUpdaterInstance._iOSUpdateButtonLabel = iOSUpdateButtonLabel;
|
||||
_nativeUpdaterInstance._iOSCloseButtonLabel = iOSCloseButtonLabel;
|
||||
_nativeUpdaterInstance._iOSIgnoreButtonLabel = iOSIgnoreButtonLabel;
|
||||
_nativeUpdaterInstance._iOSAlertTitle = iOSAlertTitle;
|
||||
_nativeUpdaterInstance._requireUpdateText = requireUpdateText ?? 'requires that you update to the latest version. You cannot use this app until it is updated.';
|
||||
_nativeUpdaterInstance._recommendUpdateText = recommendUpdateText ?? 'recommends that you update to the latest version. You can keep using this app while downloading the update.';
|
||||
_nativeUpdaterInstance._errorText = errorText;
|
||||
_nativeUpdaterInstance._errorCloseButtonLabel = errorCloseButtonLabel;
|
||||
_nativeUpdaterInstance._errorSubtitle = errorSubtitle;
|
||||
/// Show the alert based on current platform
|
||||
if (Platform.isIOS) {
|
||||
_nativeUpdaterInstance._showCupertinoAlertDialog();
|
||||
} else {
|
||||
_nativeUpdaterInstance._showMaterialAlertDialog();
|
||||
}
|
||||
}
|
||||
|
||||
void _showCupertinoAlertDialog() {
|
||||
/// Switch description based on whether it is force update or not.
|
||||
String selectedDefaultDescription;
|
||||
|
||||
if (_forceUpdate) {
|
||||
selectedDefaultDescription =
|
||||
'$_appName $_requireUpdateText';
|
||||
} else {
|
||||
selectedDefaultDescription =
|
||||
'$_appName $_recommendUpdateText';
|
||||
}
|
||||
|
||||
Widget alert = UpdateCupertinoAlert(
|
||||
forceUpdate: _forceUpdate,
|
||||
appName: _appName,
|
||||
appStoreUrl: _appStoreUrl!,
|
||||
description: _iOSDescription ?? selectedDefaultDescription,
|
||||
updateButtonLabel: _iOSUpdateButtonLabel ?? 'Update',
|
||||
closeButtonLabel: _iOSCloseButtonLabel ?? 'Close App',
|
||||
ignoreButtonLabel: _iOSIgnoreButtonLabel ?? 'Later',
|
||||
alertTitle: _iOSAlertTitle ?? 'Update Available',
|
||||
);
|
||||
|
||||
showDialog(
|
||||
context: _context,
|
||||
barrierDismissible: _forceUpdate ? false : true,
|
||||
builder: (BuildContext context) {
|
||||
return alert;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _showMaterialAlertDialog() async {
|
||||
/// In App Update Related
|
||||
try {
|
||||
AppUpdateInfo _updateInfo = await InAppUpdate.checkForUpdate();
|
||||
|
||||
if (_updateInfo.updateAvailability == UpdateAvailability.updateAvailable) {
|
||||
if (_forceUpdate == true) {
|
||||
InAppUpdate.performImmediateUpdate()
|
||||
.catchError((e) => developer.log(e.toString()));
|
||||
} else if (_forceUpdate == false) {
|
||||
InAppUpdate.startFlexibleUpdate()
|
||||
.catchError((e) => developer.log(e.toString()));
|
||||
}
|
||||
}
|
||||
} on PlatformException catch (e) {
|
||||
developer.log(e.code.toString());
|
||||
|
||||
showDialog(
|
||||
context: _context,
|
||||
builder: (BuildContext context) {
|
||||
return ErrorMaterialAlert(
|
||||
appName: _appName,
|
||||
description:
|
||||
_errorText ?? 'This version of $_appName was not installed from Google Play Store.',
|
||||
errorCloseButtonLabel:_errorCloseButtonLabel,
|
||||
errorSubtitle: _errorSubtitle,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
58
lib/src/update_cupertino_alert.dart
Normal file
58
lib/src/update_cupertino_alert.dart
Normal file
@@ -0,0 +1,58 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class UpdateCupertinoAlert extends StatelessWidget {
|
||||
final bool forceUpdate;
|
||||
final String appName;
|
||||
final String appStoreUrl;
|
||||
final String description;
|
||||
final String updateButtonLabel;
|
||||
final String closeButtonLabel;
|
||||
final String ignoreButtonLabel;
|
||||
final String alertTitle;
|
||||
|
||||
UpdateCupertinoAlert({
|
||||
required this.forceUpdate,
|
||||
required this.appName,
|
||||
required this.appStoreUrl,
|
||||
required this.description,
|
||||
required this.updateButtonLabel,
|
||||
required this.closeButtonLabel,
|
||||
required this.ignoreButtonLabel,
|
||||
required this.alertTitle,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
/// Set up the Buttons
|
||||
Widget closeAppButton = CupertinoDialogAction(
|
||||
child: Text(closeButtonLabel),
|
||||
onPressed: () => exit(0),
|
||||
);
|
||||
|
||||
Widget ignoreButton = CupertinoDialogAction(
|
||||
child: Text(ignoreButtonLabel),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
);
|
||||
|
||||
Widget updateButton = CupertinoDialogAction(
|
||||
child: Text(updateButtonLabel),
|
||||
onPressed: () => launch(appStoreUrl),
|
||||
);
|
||||
|
||||
return CupertinoAlertDialog(
|
||||
title: Text(alertTitle),
|
||||
content: Padding(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(description),
|
||||
),
|
||||
actions: [
|
||||
forceUpdate ? closeAppButton : ignoreButton,
|
||||
updateButton,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
85
lib/src/update_material_alert.dart
Normal file
85
lib/src/update_material_alert.dart
Normal file
@@ -0,0 +1,85 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class UpdateMaterialAlert extends StatelessWidget {
|
||||
final bool forceUpdate;
|
||||
final String appName;
|
||||
final String playStoreUrl;
|
||||
final String titlePrefix;
|
||||
final String description;
|
||||
final String updateButtonLabel;
|
||||
final String closeButtonLabel;
|
||||
final String ignoreButtonLabel;
|
||||
final String newVersionLabel;
|
||||
|
||||
UpdateMaterialAlert({
|
||||
required this.forceUpdate,
|
||||
required this.appName,
|
||||
required this.playStoreUrl,
|
||||
required this.titlePrefix,
|
||||
required this.description,
|
||||
required this.updateButtonLabel,
|
||||
required this.closeButtonLabel,
|
||||
required this.ignoreButtonLabel,
|
||||
this.newVersionLabel = 'New version available'
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
/// Set up the Buttons
|
||||
Widget closeAppButton = TextButton(
|
||||
child: Text(closeButtonLabel.toUpperCase()),
|
||||
onPressed: () => exit(0),
|
||||
);
|
||||
|
||||
Widget ignoreButton = TextButton(
|
||||
child: Text(ignoreButtonLabel.toUpperCase()),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
);
|
||||
|
||||
final ButtonStyle flatButtonStyle = TextButton.styleFrom(
|
||||
backgroundColor: Colors.blue,
|
||||
);
|
||||
|
||||
Widget updateButton = TextButton(
|
||||
child: Text(updateButtonLabel.toUpperCase(),
|
||||
style: TextStyle(color: Colors.white)),
|
||||
style: flatButtonStyle,
|
||||
onPressed: () => launch(playStoreUrl),
|
||||
);
|
||||
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
forceUpdate ? "$titlePrefix $appName" : "$titlePrefix $appName?"),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
newVersionLabel,
|
||||
style: TextStyle(color: Colors.grey),
|
||||
),
|
||||
SizedBox(height: 24.0),
|
||||
Text(description),
|
||||
SizedBox(height: 24.0),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
forceUpdate ? closeAppButton : ignoreButton,
|
||||
updateButton,
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
Divider(),
|
||||
SizedBox(height: 16.0),
|
||||
Image.asset(
|
||||
'packages/native_updater/images/google_play.png',
|
||||
width: 120.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user