mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-08-01 21:30:16 +02:00
Added external APK support (GitLab only for now)
This commit is contained in:
@@ -108,6 +108,7 @@ class AppsProvider with ChangeNotifier {
|
||||
if (apps[id] == null) {
|
||||
throw 'App not found';
|
||||
}
|
||||
// If the App has more than one APK, the user should pick one
|
||||
String? apkUrl = apps[id]!.app.apkUrls[apps[id]!.app.preferredApkIndex];
|
||||
if (apps[id]!.app.apkUrls.length > 1) {
|
||||
apkUrl = await showDialog(
|
||||
@@ -116,6 +117,19 @@ class AppsProvider with ChangeNotifier {
|
||||
return APKPicker(app: apps[id]!.app, initVal: apkUrl);
|
||||
});
|
||||
}
|
||||
// If the picked APK comes from an origin different from the source, get user confirmation
|
||||
if (apkUrl != null &&
|
||||
!apkUrl.toLowerCase().startsWith(apps[id]!.app.url.toLowerCase())) {
|
||||
if (await showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext ctx) {
|
||||
return APKOriginWarningDialog(
|
||||
sourceUrl: apps[id]!.app.url, apkUrl: apkUrl!);
|
||||
}) !=
|
||||
true) {
|
||||
apkUrl = null;
|
||||
}
|
||||
}
|
||||
if (apkUrl != null) {
|
||||
int urlInd = apps[id]!.app.apkUrls.indexOf(apkUrl);
|
||||
if (urlInd != apps[id]!.app.preferredApkIndex) {
|
||||
@@ -331,7 +345,7 @@ class _APKPickerState extends State<APKPicker> {
|
||||
child: const Text('Cancel')),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
HapticFeedback.mediumImpact();
|
||||
HapticFeedback.heavyImpact();
|
||||
Navigator.of(context).pop(apkUrl);
|
||||
},
|
||||
child: const Text('Continue'))
|
||||
@@ -339,3 +353,40 @@ class _APKPickerState extends State<APKPicker> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class APKOriginWarningDialog extends StatefulWidget {
|
||||
const APKOriginWarningDialog(
|
||||
{super.key, required this.sourceUrl, required this.apkUrl});
|
||||
|
||||
final String sourceUrl;
|
||||
final String apkUrl;
|
||||
|
||||
@override
|
||||
State<APKOriginWarningDialog> createState() => _APKOriginWarningDialogState();
|
||||
}
|
||||
|
||||
class _APKOriginWarningDialogState extends State<APKOriginWarningDialog> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
scrollable: true,
|
||||
title: const Text('Warning'),
|
||||
content: Text(
|
||||
'The App source is \'${Uri.parse(widget.sourceUrl).host}\' but the release package comes from \'${Uri.parse(widget.apkUrl).host}\'. Continue?'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
HapticFeedback.lightImpact();
|
||||
Navigator.of(context).pop(null);
|
||||
},
|
||||
child: const Text('Cancel')),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
HapticFeedback.heavyImpact();
|
||||
Navigator.of(context).pop(true);
|
||||
},
|
||||
child: const Text('Continue'))
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -170,12 +170,19 @@ class GitLab implements AppSource {
|
||||
var entry = parsedHtml.querySelector('entry');
|
||||
var entryContent =
|
||||
parse(parseFragment(entry?.querySelector('content')!.innerHtml).text);
|
||||
var apkUrlList = getLinksFromParsedHTML(
|
||||
var apkUrlList = [
|
||||
...getLinksFromParsedHTML(
|
||||
entryContent,
|
||||
RegExp(
|
||||
'^${escapeRegEx(standardUri.path)}/uploads/[^/]+/[^/]+\\.apk\$',
|
||||
caseSensitive: false),
|
||||
standardUri.origin);
|
||||
standardUri.origin),
|
||||
// GitLab releases may contain links to externally hosted APKs
|
||||
...getLinksFromParsedHTML(entryContent,
|
||||
RegExp('/[^/]+\\.apk\$', caseSensitive: false), '')
|
||||
.where((element) => Uri.parse(element).host != '')
|
||||
.toList()
|
||||
];
|
||||
if (apkUrlList.isEmpty) {
|
||||
throw 'No APK found';
|
||||
}
|
||||
|
Reference in New Issue
Block a user