add project

This commit is contained in:
2022-10-04 15:43:14 +07:00
commit 470fe91813
82 changed files with 2695 additions and 0 deletions

View 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
View 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,
);
},
);
}
}
}

View 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,
],
);
}
}

View 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,
),
],
),
);
}
}