Merge pull request #504 from ImranR98/dev

Less restrictive install permission requests (#495)
Add toggles to disable warnings (#495 
Fix a breaking bug on Add App page from the previous PR
This commit is contained in:
Imran Remtulla
2023-04-30 01:04:04 -04:00
committed by GitHub
16 changed files with 162 additions and 60 deletions

View File

@@ -224,6 +224,10 @@
"standardVersionDetection": "Standardversionserkennung",
"groupByCategory": "Nach Kategorie gruppieren",
"autoApkFilterByArch": "Nach Möglichkeit versuchen, APKs nach CPU-Architektur zu filtern",
"overrideSource": "Override Source",
"dontShowAgain": "Don't show this again",
"dontShowTrackOnlyWarnings": "Don't Show the 'Track-Only' Warning",
"dontShowAPKOriginWarnings": "Don't Show APK Origin Warnings",
"removeAppQuestion": {
"one": "App entfernen?",
"other": "Apps entfernen?"

View File

@@ -225,6 +225,9 @@
"groupByCategory": "Group by Category",
"autoApkFilterByArch": "Attempt to filter APKs by CPU architecture if possible",
"overrideSource": "Override Source",
"dontShowAgain": "Don't show this again",
"dontShowTrackOnlyWarnings": "Don't Show 'Track-Only' Warnings",
"dontShowAPKOriginWarnings": "Don't Show APK Origin Warnings",
"removeAppQuestion": {
"one": "Remove App?",
"other": "Remove Apps?"

View File

@@ -224,6 +224,10 @@
"standardVersionDetection": "تشخیص نسخه استاندارد",
"groupByCategory": "گروه بر اساس دسته",
"autoApkFilterByArch": "در صورت امکان سعی کنید APKها را بر اساس معماری CPU فیلتر کنید",
"overrideSource": "Override Source",
"dontShowAgain": "Don't show this again",
"dontShowTrackOnlyWarnings": "Don't Show the 'Track-Only' Warning",
"dontShowAPKOriginWarnings": "Don't Show APK Origin Warnings",
"removeAppQuestion": {
"one": "برنامه حذف شود؟",
"other": "برنامه ها حذف شوند؟"

View File

@@ -224,6 +224,10 @@
"standardVersionDetection": "Détection de version standard",
"groupByCategory": "Group by Category",
"autoApkFilterByArch": "Attempt to filter APKs by CPU architecture if possible",
"overrideSource": "Override Source",
"dontShowAgain": "Don't show this again",
"dontShowTrackOnlyWarnings": "Don't Show the 'Track-Only' Warning",
"dontShowAPKOriginWarnings": "Don't Show APK Origin Warnings",
"removeAppQuestion": {
"one": "Supprimer l'application ?",
"other": "Supprimer les applications ?"

View File

@@ -223,6 +223,10 @@
"standardVersionDetection": "Alapért. verzió érzékelés",
"groupByCategory": "Csoportosítás Kategória alapján",
"autoApkFilterByArch": "Ha lehetséges, próbálja CPU architektúra szerint szűrni az APK-kat",
"overrideSource": "Override Source",
"dontShowAgain": "Don't show this again",
"dontShowTrackOnlyWarnings": "Don't Show the 'Track-Only' Warning",
"dontShowAPKOriginWarnings": "Don't Show APK Origin Warnings",
"removeAppQuestion": {
"one": "Eltávolítja az alkalmazást?",
"other": "Eltávolítja az alkalmazást?"

View File

@@ -224,6 +224,10 @@
"standardVersionDetection": "Rilevamento di versione standard",
"groupByCategory": "Raggruppa per categoria",
"autoApkFilterByArch": "Tenta di filtrare gli APK in base all'architettura della CPU, se possibile",
"overrideSource": "Override Source",
"dontShowAgain": "Don't show this again",
"dontShowTrackOnlyWarnings": "Don't Show the 'Track-Only' Warning",
"dontShowAPKOriginWarnings": "Don't Show APK Origin Warnings",
"removeAppQuestion": {
"one": "Rimuovere l'App?",
"other": "Rimuovere le App?"

View File

@@ -224,6 +224,10 @@
"standardVersionDetection": "標準のバージョン検出",
"groupByCategory": "カテゴリ別にグループ化する",
"autoApkFilterByArch": "可能であればCPUアーキテクチャによるAPKのフィルタリングを試みる",
"overrideSource": "Override Source",
"dontShowAgain": "Don't show this again",
"dontShowTrackOnlyWarnings": "Don't Show the 'Track-Only' Warning",
"dontShowAPKOriginWarnings": "Don't Show APK Origin Warnings",
"removeAppQuestion": {
"one": "アプリを削除しますか?",
"other": "アプリを削除しますか?"

View File

@@ -224,6 +224,10 @@
"standardVersionDetection": "常规版本检测",
"groupByCategory": "按类别分组显示",
"autoApkFilterByArch": "如果可能,尝试按 CPU 架构筛选 APK 文件",
"overrideSource": "Override Source",
"dontShowAgain": "Don't show this again",
"dontShowTrackOnlyWarnings": "Don't Show the 'Track-Only' Warning",
"dontShowAPKOriginWarnings": "Don't Show APK Origin Warnings",
"removeAppQuestion": {
"one": "是否删除应用?",
"other": "是否删除应用?"

View File

@@ -52,6 +52,18 @@ class _AddAppPageState extends State<AddAppPage> {
searchnum++;
}
var prevHost = pickedSource?.host;
try {
var naturalSource =
valid ? sourceProvider.getSource(userInput) : null;
if (naturalSource != null &&
naturalSource.runtimeType.toString() !=
HTML().runtimeType.toString()) {
// If input has changed to match a regular source, reset the override
pickedSourceOverride = null;
}
} catch (e) {
// ignore
}
var source = valid
? sourceProvider.getSource(userInput,
overrideSource: pickedSourceOverride)
@@ -71,24 +83,35 @@ class _AddAppPageState extends State<AddAppPage> {
}
}
getTrackOnlyConfirmationIfNeeded(bool userPickedTrackOnly) async {
return (!((userPickedTrackOnly || pickedSource!.enforceTrackOnly) &&
// ignore: use_build_context_synchronously
await showDialog(
context: context,
builder: (BuildContext ctx) {
return GeneratedFormModal(
title: tr('xIsTrackOnly', args: [
pickedSource!.enforceTrackOnly
? tr('source')
: tr('app')
]),
items: const [],
message:
'${pickedSource!.enforceTrackOnly ? tr('appsFromSourceAreTrackOnly') : tr('youPickedTrackOnly')}\n\n${tr('trackOnlyAppDescription')}',
);
}) ==
null));
Future<bool> getTrackOnlyConfirmationIfNeeded(
bool userPickedTrackOnly, SettingsProvider settingsProvider,
{bool ignoreHideSetting = false}) async {
var useTrackOnly = userPickedTrackOnly || pickedSource!.enforceTrackOnly;
if (useTrackOnly &&
(!settingsProvider.hideTrackOnlyWarning || ignoreHideSetting)) {
// ignore: use_build_context_synchronously
var values = await showDialog(
context: context,
builder: (BuildContext ctx) {
return GeneratedFormModal(
initValid: true,
title: tr('xIsTrackOnly', args: [
pickedSource!.enforceTrackOnly ? tr('source') : tr('app')
]),
items: [
[GeneratedFormSwitch('hide', label: tr('dontShowAgain'))]
],
message:
'${pickedSource!.enforceTrackOnly ? tr('appsFromSourceAreTrackOnly') : tr('youPickedTrackOnly')}\n\n${tr('trackOnlyAppDescription')}',
);
});
if (values != null) {
settingsProvider.hideTrackOnlyWarning = values['hide'] == true;
}
return useTrackOnly && values != null;
} else {
return true;
}
}
getReleaseDateAsVersionConfirmationIfNeeded(
@@ -116,7 +139,8 @@ class _AddAppPageState extends State<AddAppPage> {
var settingsProvider = context.read<SettingsProvider>();
var userPickedTrackOnly = additionalSettings['trackOnly'] == true;
App? app;
if ((await getTrackOnlyConfirmationIfNeeded(userPickedTrackOnly)) &&
if ((await getTrackOnlyConfirmationIfNeeded(
userPickedTrackOnly, settingsProvider)) &&
(await getReleaseDateAsVersionConfirmationIfNeeded(
userPickedTrackOnly))) {
var trackOnly = pickedSource!.enforceTrackOnly || userPickedTrackOnly;
@@ -124,9 +148,6 @@ class _AddAppPageState extends State<AddAppPage> {
pickedSource!, userInput, additionalSettings,
trackOnlyOverride: trackOnly,
overrideSource: pickedSourceOverride);
if (!trackOnly) {
await settingsProvider.getInstallPermission();
}
// Only download the APK here if you need to for the package ID
if (sourceProvider.isTempId(app) &&
app.additionalSettings['trackOnly'] != true) {

View File

@@ -327,9 +327,6 @@ class _AppPageState extends State<AppPage> {
? () async {
try {
HapticFeedback.heavyImpact();
if (app?.app.additionalSettings['trackOnly'] != true) {
await settingsProvider.getInstallPermission();
}
var res = await appsProvider.downloadAndInstallLatestApps(
[app!.app.id], globalNavigatorKey.currentContext);
if (res.isNotEmpty && mounted) {

View File

@@ -615,7 +615,7 @@ class AppsPageState extends State<AppsPage> {
items: formItems.map((e) => [e]).toList(),
initValid: true,
);
}).then((values) {
}).then((values) async {
if (values != null) {
if (values.isEmpty) {
values = getDefaultValuesFromFormItems([formItems]);
@@ -623,28 +623,22 @@ class AppsPageState extends State<AppsPage> {
bool shouldInstallUpdates = values['updates'] == true;
bool shouldInstallNew = values['installs'] == true;
bool shouldMarkTrackOnlies = values['trackonlies'] == true;
(() async {
if (shouldInstallNew || shouldInstallUpdates) {
await settingsProvider.getInstallPermission();
}
})()
.then((_) {
List<String> toInstall = [];
if (shouldInstallUpdates) {
toInstall.addAll(existingUpdateIdsAllOrSelected);
}
if (shouldInstallNew) {
toInstall.addAll(newInstallIdsAllOrSelected);
}
if (shouldMarkTrackOnlies) {
toInstall.addAll(trackOnlyUpdateIdsAllOrSelected);
}
appsProvider
.downloadAndInstallLatestApps(
toInstall, globalNavigatorKey.currentContext)
.catchError((e) {
showError(e, context);
});
List<String> toInstall = [];
if (shouldInstallUpdates) {
toInstall.addAll(existingUpdateIdsAllOrSelected);
}
if (shouldInstallNew) {
toInstall.addAll(newInstallIdsAllOrSelected);
}
if (shouldMarkTrackOnlies) {
toInstall.addAll(trackOnlyUpdateIdsAllOrSelected);
}
appsProvider
.downloadAndInstallLatestApps(
toInstall, globalNavigatorKey.currentContext,
settingsProvider: settingsProvider)
.catchError((e) {
showError(e, context);
});
}
});

View File

@@ -286,6 +286,34 @@ class _SettingsPageState extends State<SettingsPage> {
})
],
),
height16,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(tr('dontShowTrackOnlyWarnings')),
Switch(
value:
settingsProvider.hideTrackOnlyWarning,
onChanged: (value) {
settingsProvider.hideTrackOnlyWarning =
value;
})
],
),
height16,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(tr('dontShowAPKOriginWarnings')),
Switch(
value:
settingsProvider.hideAPKOriginWarning,
onChanged: (value) {
settingsProvider.hideAPKOriginWarning =
value;
})
],
),
const Divider(
height: 16,
),

View File

@@ -332,13 +332,16 @@ class AppsProvider with ChangeNotifier {
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!.value);
}) !=
true) {
var settingsProvider = context.read<SettingsProvider>();
if (!(settingsProvider.hideAPKOriginWarning) &&
// ignore: use_build_context_synchronously
await showDialog(
context: context,
builder: (BuildContext ctx) {
return APKOriginWarningDialog(
sourceUrl: app.url, apkUrl: apkUrl!.value);
}) !=
true) {
apkUrl = null;
}
}
@@ -351,7 +354,8 @@ class AppsProvider with ChangeNotifier {
// If user input is needed and the App is in the background, a notification is sent to get the user's attention
// Returns an array of Ids for Apps that were successfully downloaded, regardless of installation result
Future<List<String>> downloadAndInstallLatestApps(
List<String> appIds, BuildContext? context) async {
List<String> appIds, BuildContext? context,
{SettingsProvider? settingsProvider}) async {
List<String> appsToInstall = [];
List<String> trackOnlyAppsToUpdate = [];
// For all specified Apps, filter out those for which:
@@ -440,6 +444,11 @@ class AppsProvider with ChangeNotifier {
silentUpdates = moveObtainiumToStart(silentUpdates);
regularInstalls = moveObtainiumToStart(regularInstalls);
if (!(await settingsProvider?.getInstallPermission(enforce: false) ??
true)) {
throw ObtainiumError(tr('cancelled'));
}
// // Install silent updates (uncomment when it works - TODO)
// for (var u in silentUpdates) {
// await installApk(u, silent: true); // Would need to add silent option

View File

@@ -120,16 +120,20 @@ class SettingsProvider with ChangeNotifier {
return result;
}
Future<void> getInstallPermission() async {
Future<bool> getInstallPermission({bool enforce = false}) async {
while (!(await Permission.requestInstallPackages.isGranted)) {
// Explicit request as InstallPlugin request sometimes bugged
Fluttertoast.showToast(
msg: tr('pleaseAllowInstallPerm'), toastLength: Toast.LENGTH_LONG);
if ((await Permission.requestInstallPackages.request()) ==
PermissionStatus.granted) {
break;
return true;
}
if (!enforce) {
return false;
}
}
return true;
}
bool get showAppWebpage {
@@ -159,6 +163,24 @@ class SettingsProvider with ChangeNotifier {
notifyListeners();
}
bool get hideTrackOnlyWarning {
return prefs?.getBool('hideTrackOnlyWarning') ?? false;
}
set hideTrackOnlyWarning(bool show) {
prefs?.setBool('hideTrackOnlyWarning', show);
notifyListeners();
}
bool get hideAPKOriginWarning {
return prefs?.getBool('hideAPKOriginWarning') ?? false;
}
set hideAPKOriginWarning(bool show) {
prefs?.setBool('hideAPKOriginWarning', show);
notifyListeners();
}
String? getSettingString(String settingId) {
return prefs?.getString(settingId);
}

View File

@@ -470,7 +470,7 @@ class SourceProvider {
}
AppSource? source;
for (var s in sources.where((element) => element.host != null)) {
if (RegExp('://${s.host}').hasMatch(url)) {
if (RegExp('://${s.host}(/|\\z)?').hasMatch(url)) {
source = s;
break;
}

View File

@@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 0.12.0+159 # When changing this, update the tag in main() accordingly
version: 0.12.0+160 # When changing this, update the tag in main() accordingly
environment:
sdk: '>=2.18.2 <3.0.0'