Enable auto update checks

This commit is contained in:
Vishnu Mohandas 2021-05-22 21:16:04 +05:30
parent cdb9a11f3d
commit 31de45bf1c
5 changed files with 231 additions and 0 deletions

View file

@ -0,0 +1,61 @@
import 'dart:io';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:photos/core/network.dart';
class UpdateService {
UpdateService._privateConstructor();
static final UpdateService instance = UpdateService._privateConstructor();
LatestVersionInfo _latestVersion;
Future<bool> shouldUpdate() async {
if (Platform.isIOS) {
return false;
}
_latestVersion = await _getLatestVersionInfo();
final currentVersionCode =
int.parse((await PackageInfo.fromPlatform()).buildNumber);
return currentVersionCode < _latestVersion.code;
}
LatestVersionInfo getLatestVersionInfo() {
return _latestVersion;
}
Future<LatestVersionInfo> _getLatestVersionInfo() async {
final response = await Network.instance
.getDio()
.get("https://android.ente.io/release-info.json");
return LatestVersionInfo.fromMap(response.data["latestVersion"]);
}
}
class LatestVersionInfo {
final String name;
final int code;
final List<String> changelog;
final bool shouldForceUpdate;
final String url;
final int size;
LatestVersionInfo(
this.name,
this.code,
this.changelog,
this.shouldForceUpdate,
this.url,
this.size,
);
factory LatestVersionInfo.fromMap(Map<String, dynamic> map) {
return LatestVersionInfo(
map['name'],
map['code'],
List<String>.from(map['changelog']),
map['shouldForceUpdate'],
map['url'],
map['size'],
);
}
}

View file

@ -0,0 +1,148 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:logging/logging.dart';
import 'package:open_file/open_file.dart';
import 'package:photos/core/configuration.dart';
import 'package:photos/core/network.dart';
import 'package:photos/services/update_service.dart';
import 'package:photos/ui/common_elements.dart';
import 'package:photos/utils/dialog_util.dart';
class AppUpdateDialog extends StatefulWidget {
final LatestVersionInfo latestVersionInfo;
AppUpdateDialog(this.latestVersionInfo, {Key key}) : super(key: key);
@override
_AppUpdateDialogState createState() => _AppUpdateDialogState();
}
class _AppUpdateDialogState extends State<AppUpdateDialog> {
@override
Widget build(BuildContext context) {
final List<Widget> changelog = [];
for (final log in widget.latestVersionInfo.changelog) {
changelog.add(Padding(
padding: const EdgeInsets.fromLTRB(8, 4, 0, 4),
child: Text("- " + log,
style: TextStyle(
fontSize: 14,
color: Colors.white.withOpacity(0.7),
)),
));
}
final content = Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
widget.latestVersionInfo.name,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Padding(padding: EdgeInsets.all(8)),
Text("changelog",
style: TextStyle(
fontSize: 18,
)),
Padding(padding: EdgeInsets.all(4)),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: changelog,
),
Padding(padding: EdgeInsets.all(8)),
Container(
width: double.infinity,
height: 64,
padding: const EdgeInsets.fromLTRB(64, 0, 64, 0),
child: button(
"update",
fontSize: 16,
onPressed: () async {
Navigator.pop(context);
showDialog(
context: context,
builder: (BuildContext context) {
return ApkDownloaderDialog(widget.latestVersionInfo);
},
barrierDismissible: false,
);
},
),
),
],
);
return WillPopScope(
onWillPop: () async => !widget.latestVersionInfo.shouldForceUpdate,
child: AlertDialog(
title: Text("update available"),
content: content,
),
);
}
}
class ApkDownloaderDialog extends StatefulWidget {
final LatestVersionInfo versionInfo;
ApkDownloaderDialog(this.versionInfo, {Key key}) : super(key: key);
@override
_ApkDownloaderDialogState createState() => _ApkDownloaderDialogState();
}
class _ApkDownloaderDialogState extends State<ApkDownloaderDialog> {
String _saveUrl;
double _downloadProgress;
@override
void initState() {
super.initState();
_saveUrl = Configuration.instance.getTempDirectory() +
"ente-" +
widget.versionInfo.name +
".apk";
_downloadApk();
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: AlertDialog(
title: Text(
"downloading...",
style: TextStyle(
fontSize: 16,
),
textAlign: TextAlign.center,
),
content: LinearProgressIndicator(
value: _downloadProgress,
valueColor:
AlwaysStoppedAnimation<Color>(Theme.of(context).buttonColor),
),
),
);
}
Future<void> _downloadApk() async {
try {
await Network.instance.getDio().download(widget.versionInfo.url, _saveUrl,
onReceiveProgress: (count, _) {
setState(() {
_downloadProgress = count / widget.versionInfo.size;
});
});
} catch (e) {
Logger("ApkDownloader").severe(e);
Navigator.pop(context);
showGenericErrorDialog(context);
return;
}
Navigator.pop(context);
OpenFile.open(_saveUrl);
}
}

View file

@ -17,6 +17,8 @@ import 'package:photos/events/trigger_logout_event.dart';
import 'package:photos/events/user_logged_out_event.dart';
import 'package:photos/models/selected_files.dart';
import 'package:photos/services/sync_service.dart';
import 'package:photos/services/update_service.dart';
import 'package:photos/ui/app_update_dialog.dart';
import 'package:photos/ui/backup_folder_selection_page.dart';
import 'package:photos/ui/collections_gallery_widget.dart';
import 'package:photos/ui/extents_page_view.dart';
@ -126,6 +128,18 @@ class _HomeWidgetState extends State<HomeWidget> {
setState(() {});
});
_initDeepLinks();
UpdateService.instance.shouldUpdate().then((shouldUpdate) {
if (shouldUpdate) {
Future.delayed(Duration.zero, () {
showDialog(
context: context,
builder: (BuildContext context) {
return AppUpdateDialog(
UpdateService.instance.getLatestVersionInfo());
});
});
}
});
super.initState();
}

View file

@ -478,6 +478,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0+1"
open_file:
dependency: "direct main"
description:
name: open_file
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.1"
package_info_plus:
dependency: "direct main"
description:

View file

@ -79,6 +79,7 @@ dependencies:
loading_animations: ^2.1.0
dots_indicator: ^2.0.0
flutter_local_notifications: ^5.0.0+4
open_file: ^3.2.1
dev_dependencies:
flutter_test: