diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 6de00b03..91263606 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -46,6 +46,15 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lib/modules/more/about/providers/check_for_update.dart b/lib/modules/more/about/providers/check_for_update.dart
index e2592cf7..1c7db29e 100644
--- a/lib/modules/more/about/providers/check_for_update.dart
+++ b/lib/modules/more/about/providers/check_for_update.dart
@@ -1,9 +1,9 @@
import 'dart:convert';
import 'dart:developer';
-import 'dart:io';
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
+import 'package:mangayomi/modules/more/about/providers/download_file_screen.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/services/fetch_sources_list.dart';
import 'package:mangayomi/services/http/m_client.dart';
@@ -11,8 +11,6 @@ import 'package:mangayomi/utils/extensions/string_extensions.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:url_launcher/url_launcher.dart';
-import 'package:device_info_plus/device_info_plus.dart';
part 'check_for_update.g.dart';
@riverpod
@@ -30,14 +28,8 @@ Future checkForUpdate(
if (kDebugMode) {
log(info.data.toString());
}
- if (Platform.isAndroid) {
- final deviceInfo = DeviceInfoPlugin();
- final androidInfo = await deviceInfo.androidInfo;
- print("DEBUG");
- print(androidInfo.supportedAbis.join(", ")); // x86_64, arm64-v8a
- }
final updateAvailable = await _checkUpdate();
- if (compareVersions(info.version, updateAvailable.$1) < 0) {
+ if (compareVersions(info.version, updateAvailable.$1) < 0 || true) {
if (manualUpdate) {
BotToast.showText(text: l10n.new_update_available);
await Future.delayed(const Duration(seconds: 1));
@@ -46,32 +38,7 @@ Future checkForUpdate(
showDialog(
context: context,
builder: (context) {
- return AlertDialog(
- title: Text(l10n.new_update_available),
- content: Text(
- "${l10n.app_version(updateAvailable.$1)}\n\n${updateAvailable.$2}",
- ),
- actions: [
- Row(
- mainAxisAlignment: MainAxisAlignment.end,
- children: [
- TextButton(
- onPressed: () {
- Navigator.pop(context);
- },
- child: Text(l10n.cancel),
- ),
- const SizedBox(width: 15),
- ElevatedButton(
- onPressed: () async {
- _launchInBrowser(Uri.parse(updateAvailable.$3));
- },
- child: Text(l10n.download),
- ),
- ],
- ),
- ],
- );
+ return DownloadFileScreen(updateAvailable: updateAvailable);
},
);
}
@@ -82,13 +49,7 @@ Future checkForUpdate(
}
}
-Future _launchInBrowser(Uri url) async {
- if (!await launchUrl(url, mode: LaunchMode.externalApplication)) {
- throw 'Could not launch $url';
- }
-}
-
-Future<(String, String, String)> _checkUpdate() async {
+Future<(String, String, String, List)> _checkUpdate() async {
final http = MClient.init(reqcopyWith: {'useDartHttpClient': true});
try {
final res = await http.get(
@@ -104,6 +65,10 @@ Future<(String, String, String)> _checkUpdate() async {
.substringBefore('-'),
resListJson.first["body"].toString(),
resListJson.first["html_url"].toString(),
+ (resListJson.first["assets"] as List)
+ .map((asset) => asset["browser_download_url"])
+ .toList()
+ as List,
);
} catch (e) {
rethrow;
diff --git a/lib/modules/more/about/providers/download_file_screen.dart b/lib/modules/more/about/providers/download_file_screen.dart
new file mode 100644
index 00000000..4cac9118
--- /dev/null
+++ b/lib/modules/more/about/providers/download_file_screen.dart
@@ -0,0 +1,119 @@
+import 'dart:io';
+
+import 'package:device_info_plus/device_info_plus.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_app_installer/flutter_app_installer.dart';
+import 'package:flutter_qjs/quickjs/ffi.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:http/http.dart' as http;
+import 'package:mangayomi/providers/l10n_providers.dart';
+import 'package:path_provider/path_provider.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+class DownloadFileScreen extends ConsumerStatefulWidget {
+ final (String, String, String, List) updateAvailable;
+ const DownloadFileScreen({required this.updateAvailable, super.key});
+
+ @override
+ ConsumerState createState() => _DownloadFileScreenState();
+}
+
+class _DownloadFileScreenState extends ConsumerState {
+ int _total = 0;
+ int _received = 0;
+ late http.StreamedResponse _response;
+ final List _bytes = [];
+
+ @override
+ Widget build(BuildContext context) {
+ final l10n = l10nLocalizations(context)!;
+ final updateAvailable = widget.updateAvailable;
+ return AlertDialog(
+ title: Text(l10n.new_update_available),
+ content: Text(
+ "${l10n.app_version(updateAvailable.$1)}\n\n${updateAvailable.$2}",
+ ),
+ actions: [
+ _total > 0
+ ? Row(
+ children: [
+ LinearProgressIndicator(
+ value: _received > 0 ? _total / _received : 0,
+ ),
+ Text('${_received ~/ 1024}/${_total ~/ 1024} KB'),
+ ],
+ )
+ : SizedBox.shrink(),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ TextButton(
+ onPressed: () {
+ Navigator.pop(context);
+ },
+ child: Text(l10n.cancel),
+ ),
+ const SizedBox(width: 15),
+ ElevatedButton(
+ onPressed: () async {
+ if (Platform.isAndroid) {
+ final deviceInfo = DeviceInfoPlugin();
+ final androidInfo = await deviceInfo.androidInfo;
+ String apkUrl = "";
+ for (String abi in androidInfo.supportedAbis) {
+ final url = updateAvailable.$4.firstWhereOrNull(
+ (apk) => apk.contains(abi),
+ );
+ if (url != null) {
+ apkUrl = url;
+ break;
+ }
+ }
+ await _downloadApk(apkUrl);
+ print("DEBUG");
+ print(
+ androidInfo.supportedAbis.join(", "),
+ ); // x86_64, arm64-v8a, armeabi-v7a
+ } else {
+ _launchInBrowser(Uri.parse(updateAvailable.$3));
+ }
+ },
+ child: Text(l10n.download),
+ ),
+ ],
+ ),
+ ],
+ );
+ }
+
+ Future _downloadApk(String url) async {
+ _response = await http.Client().send(http.Request('GET', Uri.parse(url)));
+ _total = _response.contentLength ?? 0;
+
+ _response.stream
+ .listen((value) {
+ setState(() {
+ _bytes.addAll(value);
+ _received += value.length;
+ });
+ })
+ .onDone(() async {
+ final file = File(
+ '${(await getApplicationDocumentsDirectory()).path}/${url.split("/").lastOrNull ?? "Mangayomi.apk"}',
+ );
+ await file.writeAsBytes(_bytes);
+ final FlutterAppInstaller appInstaller = FlutterAppInstaller();
+ await appInstaller.installApk(filePath: file.path);
+ await file.delete();
+ if (context.mounted) {
+ Navigator.pop(context);
+ }
+ });
+ }
+
+ Future _launchInBrowser(Uri url) async {
+ if (!await launchUrl(url, mode: LaunchMode.externalApplication)) {
+ throw 'Could not launch $url';
+ }
+ }
+}
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index 038396d6..596d9721 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -5,7 +5,6 @@
import FlutterMacOS
import Foundation
-import app_installer
import app_links
import audio_session
import connectivity_plus
@@ -32,7 +31,6 @@ import window_manager
import window_to_front
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
- AppInstallerPlugin.register(with: registry.registrar(forPlugin: "AppInstallerPlugin"))
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
diff --git a/pubspec.lock b/pubspec.lock
index 483f763c..739cd5a7 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -38,14 +38,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.13.2"
- app_installer:
- dependency: "direct main"
- description:
- name: app_installer
- sha256: "4c3a9268b53ead9a915ef79cd3988e28c72719fb78143867f9fed4bd4d8c1cfd"
- url: "https://pub.dev"
- source: hosted
- version: "1.3.1"
app_links:
dependency: "direct main"
description:
@@ -556,6 +548,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
+ flutter_app_installer:
+ dependency: "direct main"
+ description:
+ name: flutter_app_installer
+ sha256: b71f7c3f6c5712b6f9bdcde798bbb8a0c4047cab47c4364f7252de8c95d67358
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.0"
flutter_cache_manager:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index cf5cdf8b..d92f68ee 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -83,8 +83,8 @@ dependencies:
app_links: ^6.4.0
win32: ^5.10.1
protobuf: ^3.1.0
- app_installer: ^1.3.1
device_info_plus: ^11.3.3
+ flutter_app_installer: ^1.0.0
dependency_overrides:
http: ^1.2.2