Skip to content

Commit

Permalink
Added support for enforceUpgrade.
Browse files Browse the repository at this point in the history
When set to true this will enforce an upgrade based on the Upgrader.minAppVersion version.
  • Loading branch information
twklessor committed Oct 23, 2024
1 parent ad550cb commit 76d8d79
Show file tree
Hide file tree
Showing 3 changed files with 424 additions and 43 deletions.
191 changes: 150 additions & 41 deletions lib/src/upgrade_announcer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,55 @@ import 'package:upgrader/upgrader.dart';

typedef UpgradeAnnouncerBottomSheetBuilder = Widget Function(
BuildContext context, VoidCallback goToAppStore, String? releaseNotes);
typedef UpgradeAnnouncerEnforceUpgradeBuilder = Widget Function(
BuildContext context, VoidCallback goToAppStore);

class UpgradeAnnouncer extends StatefulWidget {
final GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey;
final Upgrader? upgrader;
final UpgradeAnnouncerBottomSheetBuilder? bottomSheetBuilder;
final Color? backgroundColor;
final double bottomSheetHeightFactor;
final Color? bottomSheetBackgroundColor;
final UpgradeAnnouncerBottomSheetBuilder? bottomSheetBuilder;
final TextStyle? bottomSheetTitleTextStyle;
final TextStyle? bottomSheetReleaseNotesTextStyle;
final UpgradeAnnouncerEnforceUpgradeBuilder? enforceUpgradeBuilder;
final Color? enforceUpgradeBackgroundColor;
final TextStyle? enforceUpgradeTextStyle;
final TextStyle? titleTextStyle;
final IconData? infoIcon;
final Color? infoIconColor;
final IconData? downloadIcon;
final Color? downloadIconColor;
final bool forceShow;

/// When set to true this will enforce an upgrade based on the
/// [Upgrader.minAppVersion] version
final bool enforceUpgrade;
final bool debugEnforceUpgrade;
final bool debugUpgrade;
final Widget child;

const UpgradeAnnouncer({
super.key,
required this.scaffoldMessengerKey,
this.upgrader,
this.backgroundColor,
this.bottomSheetBuilder,
this.bottomSheetHeightFactor = .6,
this.bottomSheetBackgroundColor,
this.bottomSheetBuilder,
this.bottomSheetTitleTextStyle,
this.bottomSheetReleaseNotesTextStyle,
this.enforceUpgradeBuilder,
this.enforceUpgradeBackgroundColor,
this.enforceUpgradeTextStyle,
this.titleTextStyle,
this.infoIcon,
this.infoIconColor,
this.downloadIcon,
this.downloadIconColor,
this.forceShow = false,
this.enforceUpgrade = false,
this.debugEnforceUpgrade = false,
this.debugUpgrade = false,
required this.child,
});

Expand All @@ -47,6 +62,8 @@ class UpgradeAnnouncer extends StatefulWidget {
class _UpgradeAnnouncer extends State<UpgradeAnnouncer> {
late final _upgrader = widget.upgrader ?? Upgrader();

bool _shouldEnforceUpgrade = false;

@override
void initState() {
_checkForUpgrade();
Expand All @@ -60,61 +77,153 @@ class _UpgradeAnnouncer extends State<UpgradeAnnouncer> {

@override
Widget build(BuildContext context) {
return widget.child;
return Stack(
children: [
AbsorbPointer(absorbing: _shouldEnforceUpgrade, child: widget.child),
if (_shouldEnforceUpgrade)
Container(
color: Colors.black.withOpacity(.5),
),
if (_shouldEnforceUpgrade)
Material(
color: Colors.transparent,
child: widget.enforceUpgradeBuilder
?.call(context, _upgrader.sendUserToAppStore) ??
Center(
child: Padding(
padding: const EdgeInsets.all(50.0),
child: Container(
decoration: BoxDecoration(
color: widget.enforceUpgradeBackgroundColor ??
Theme.of(context).canvasColor,
borderRadius: BorderRadius.circular(16)),
child: Padding(
padding: const EdgeInsets.all(32.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Icon(widget.infoIcon ?? Icons.info_outline,
color: widget.infoIconColor),
const SizedBox(width: 8),
Expanded(
child: Text(
UpgraderMessages().upgradeEnforce,
style: widget.enforceUpgradeTextStyle ??
const TextStyle(
fontSize: 14,
),
),
),
],
),
const Padding(padding: EdgeInsets.all(16)),
Material(
child: InkWell(
borderRadius: BorderRadius.circular(16),
onTap: _upgrader.sendUserToAppStore,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
UpgraderMessages().buttonTitleUpdate,
style: widget.enforceUpgradeTextStyle ??
const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600),
),
const Padding(padding: EdgeInsets.all(2)),
Icon(
widget.downloadIcon ?? Icons.download,
color: widget.downloadIconColor),
],
),
),
),
)
],
),
),
),
),
),
)
],
);
}

_checkForUpgrade({bool dismissMaterialBanners = false}) {
void _checkForUpgrade({bool dismissMaterialBanners = false}) {
_upgrader.initialize().then((initialized) async {
final versionInfo = await _upgrader.updateVersionInfo();
final appStoreVersion = versionInfo?.appStoreVersion;
final installedVersion = versionInfo?.installedVersion;
final releaseNotes = versionInfo?.releaseNotes;
final minAppVersion = _upgrader.versionInfo?.minAppVersion;

if (versionInfo != null &&
appStoreVersion != null &&
installedVersion != null) {
if (appStoreVersion > installedVersion || widget.forceShow) {
if (dismissMaterialBanners) {
widget.scaffoldMessengerKey.currentState?.clearMaterialBanners();
if (appStoreVersion > installedVersion ||
(widget.debugUpgrade || widget.debugEnforceUpgrade)) {
if (widget.enforceUpgrade || widget.debugEnforceUpgrade) {
setState(() {
_shouldEnforceUpgrade =
minAppVersion != null && minAppVersion > installedVersion ||
widget.debugEnforceUpgrade;
});
}

widget.scaffoldMessengerKey.currentState?.showMaterialBanner(
MaterialBanner(
content: Builder(
builder: (context) => TextButton(
onPressed: mounted
? () => _showBottomSheet(context, releaseNotes, _upgrader)
: null,
child: Row(
children: [
Icon(widget.infoIcon ?? Icons.info_outline,
color: widget.infoIconColor ?? Colors.white),
const SizedBox(width: 8),
Text(
UpgraderMessages().upgradeAvailable,
style: widget.titleTextStyle ??
const TextStyle(color: Colors.white),
),
],
),
),
),
backgroundColor: widget.backgroundColor ?? Colors.green,
actions: <Widget>[
IconButton(
onPressed: _upgrader.sendUserToAppStore,
icon: Icon(widget.downloadIcon ?? Icons.download,
color: widget.downloadIconColor ?? Colors.white),
),
],
),
);
_showMaterialBanner(dismissMaterialBanners, releaseNotes);
}
}
});
}

_showBottomSheet(
void _showMaterialBanner(bool dismissMaterialBanners, String? releaseNotes) {
if (!_shouldEnforceUpgrade) {
if (dismissMaterialBanners) {
widget.scaffoldMessengerKey.currentState?.clearMaterialBanners();
}

widget.scaffoldMessengerKey.currentState?.showMaterialBanner(
MaterialBanner(
content: Builder(
builder: (context) => TextButton(
onPressed: mounted
? () => _showBottomSheet(context, releaseNotes, _upgrader)
: null,
child: Row(
children: [
Icon(widget.infoIcon ?? Icons.info_outline,
color: widget.infoIconColor ?? Colors.white),
const SizedBox(width: 8),
Text(
UpgraderMessages().upgradeAvailable,
style: widget.titleTextStyle ??
const TextStyle(color: Colors.white),
),
],
),
),
),
backgroundColor: widget.backgroundColor ?? Colors.green,
actions: <Widget>[
IconButton(
onPressed: _upgrader.sendUserToAppStore,
icon: Icon(widget.downloadIcon ?? Icons.download,
color: widget.downloadIconColor ?? Colors.white),
),
],
),
);
}
}

void _showBottomSheet(
BuildContext context, String? releaseNotes, Upgrader upgrader) {
showModalBottomSheet(
backgroundColor: widget.bottomSheetBackgroundColor,
Expand Down
5 changes: 5 additions & 0 deletions lib/src/upgrade_messages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ class UpgraderMessages {
_ => 'No available release notes',
};

String get upgradeEnforce => switch (languageCode) {
'da' => 'En opdatering er påkrævet før at du kan benytte app\'en',
_ => 'An update is required before you can use the app.',
};

/// The body of the upgrade message. This string supports mustache style
/// template variables:
/// {{appName}}
Expand Down
Loading

0 comments on commit 76d8d79

Please sign in to comment.