Store APK names with URLs (#432)

This commit is contained in:
Imran Remtulla
2023-04-05 18:50:19 -04:00
parent 361a3e1bc2
commit 202ce4f0d5
18 changed files with 65 additions and 41 deletions

View File

@@ -169,7 +169,7 @@ class AppsProvider with ChangeNotifier {
'${app.id}-${app.latestVersion}-${app.preferredApkIndex}.apk';
String downloadUrl = await SourceProvider()
.getSource(app.url)
.apkUrlPrefetchModifier(app.apkUrls[app.preferredApkIndex]);
.apkUrlPrefetchModifier(app.apkUrls[app.preferredApkIndex].value);
var notif = DownloadNotification(app.name, 100);
notificationsProvider?.cancel(notif.id);
int? prevProg;
@@ -296,9 +296,10 @@ class AppsProvider with ChangeNotifier {
await intent.launch();
}
Future<String?> confirmApkUrl(App app, BuildContext? context) async {
Future<MapEntry<String, String>?> confirmApkUrl(
App app, BuildContext? context) async {
// If the App has more than one APK, the user should pick one (if context provided)
String? apkUrl = app.apkUrls[app.preferredApkIndex];
MapEntry<String, String>? apkUrl = app.apkUrls[app.preferredApkIndex];
// get device supported architecture
List<String> archs = (await DeviceInfoPlugin().androidInfo).supportedAbis;
@@ -321,14 +322,14 @@ class AppsProvider with ChangeNotifier {
// If the picked APK comes from an origin different from the source, get user confirmation (if context provided)
if (apkUrl != null &&
getHost(apkUrl) != getHost(app.url) &&
getHost(apkUrl.value) != getHost(app.url) &&
context != null) {
// ignore: use_build_context_synchronously
if (await showDialog(
context: context,
builder: (BuildContext ctx) {
return APKOriginWarningDialog(
sourceUrl: app.url, apkUrl: apkUrl!);
sourceUrl: app.url, apkUrl: apkUrl!.value);
}) !=
true) {
apkUrl = null;
@@ -353,7 +354,7 @@ class AppsProvider with ChangeNotifier {
if (apps[id] == null) {
throw ObtainiumError(tr('appNotFound'));
}
String? apkUrl;
MapEntry<String, String>? apkUrl;
var trackOnly = apps[id]!.app.additionalSettings['trackOnly'] == true;
if (!trackOnly) {
apkUrl = await confirmApkUrl(apps[id]!.app, context);
@@ -923,7 +924,7 @@ class APKPicker extends StatefulWidget {
const APKPicker({super.key, required this.app, this.initVal, this.archs});
final App app;
final String? initVal;
final MapEntry<String, String>? initVal;
final List<String>? archs;
@override
@@ -931,7 +932,7 @@ class APKPicker extends StatefulWidget {
}
class _APKPickerState extends State<APKPicker> {
String? apkUrl;
MapEntry<String, String>? apkUrl;
@override
Widget build(BuildContext context) {
@@ -944,15 +945,13 @@ class _APKPickerState extends State<APKPicker> {
const SizedBox(height: 16),
...widget.app.apkUrls.map(
(u) => RadioListTile<String>(
title: Text(Uri.parse(u)
.pathSegments
.where((element) => element.isNotEmpty)
.last),
value: u,
groupValue: apkUrl,
title: Text(u.key),
value: u.value,
groupValue: apkUrl!.value,
onChanged: (String? val) {
setState(() {
apkUrl = val;
apkUrl =
widget.app.apkUrls.where((e) => e.value == val).first;
});
}),
),

View File

@@ -34,7 +34,7 @@ class AppNames {
class APKDetails {
late String version;
late List<String> apkUrls;
late List<MapEntry<String, String>> apkUrls;
late AppNames names;
late DateTime? releaseDate;
late String? changeLog;
@@ -50,7 +50,7 @@ class App {
late String name;
String? installedVersion;
late String latestVersion;
List<String> apkUrls = [];
List<MapEntry<String, String>> apkUrls = [];
late int preferredApkIndex;
late Map<String, dynamic> additionalSettings;
late DateTime? lastUpdateCheck;
@@ -134,6 +134,18 @@ class App {
if (preferredApkIndex < 0) {
preferredApkIndex = 0;
}
// apkUrls can either be old list or new named list apkUrls
List<MapEntry<String, String>> apkUrls = [];
if (json['apkUrls'] != null) {
var apkUrlJson = jsonDecode(json['apkUrls']);
try {
apkUrls = getApkUrlsFromUrls(List<String>.from(apkUrlJson));
} catch (e) {
apkUrls = List<dynamic>.from(apkUrlJson)
.map((e) => MapEntry(e[0] as String, e[1] as String))
.toList();
}
}
return App(
json['id'] as String,
json['url'] as String,
@@ -143,9 +155,7 @@ class App {
? null
: json['installedVersion'] as String,
json['latestVersion'] as String,
json['apkUrls'] == null
? []
: List<String>.from(jsonDecode(json['apkUrls'])),
apkUrls,
preferredApkIndex,
additionalSettings,
json['lastUpdateCheck'] == null
@@ -173,7 +183,7 @@ class App {
'name': name,
'installedVersion': installedVersion,
'latestVersion': latestVersion,
'apkUrls': jsonEncode(apkUrls),
'apkUrls': jsonEncode(apkUrls.map((e) => [e.key, e.value]).toList()),
'preferredApkIndex': preferredApkIndex,
'additionalSettings': jsonEncode(additionalSettings),
'lastUpdateCheck': lastUpdateCheck?.microsecondsSinceEpoch,
@@ -225,6 +235,11 @@ Map<String, dynamic> getDefaultValuesFromFormItems(
.reduce((value, element) => [...value, ...element]));
}
getApkUrlsFromUrls(List<String> urls) => urls
.map((e) =>
MapEntry(e.split('/').where((el) => el.trim().isNotEmpty).last, e))
.toList();
class AppSource {
String? host;
late String name;
@@ -422,7 +437,7 @@ class SourceProvider {
if (additionalSettings['apkFilterRegEx'] != null) {
var reg = RegExp(additionalSettings['apkFilterRegEx']);
apk.apkUrls =
apk.apkUrls.where((element) => reg.hasMatch(element)).toList();
apk.apkUrls.where((element) => reg.hasMatch(element.key)).toList();
}
if (apk.apkUrls.isEmpty && !trackOnly) {
throw NoAPKError();