From bb07000280f1a7e4f868445320a342c85d4d045b Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Thu, 18 Jan 2024 20:45:06 -0500 Subject: [PATCH 01/16] Better partial APK hash as pseudo-version (related to #1101) --- lib/app_sources/html.dart | 2 +- lib/providers/apps_provider.dart | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/app_sources/html.dart b/lib/app_sources/html.dart index 106be54..7492051 100644 --- a/lib/app_sources/html.dart +++ b/lib/app_sources/html.dart @@ -310,7 +310,7 @@ class HTML extends AppSource { : rel); version ??= additionalSettings['supportFixedAPKURL'] != true ? rel.hashCode.toString() - : (await checkDownloadHash(rel)).toString(); + : (await checkPartialDownloadHashDynamc(rel)).toString(); return APKDetails(version, [rel].map((e) => MapEntry(e, e)).toList(), AppNames(uri.host, tr('app'))); } diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index 38f6417..035d5c1 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -167,8 +167,25 @@ String hashListOfLists(List> data) { return hash.hashCode.toString(); } -Future checkDownloadHash(String url, - {int bytesToGrab = 1024, Map? headers}) async { +Future checkPartialDownloadHashDynamc(String url, + {int startingSize = 1024, + int lowerLimit = 128, + Map? headers}) async { + for (int i = startingSize; i >= lowerLimit; i -= 256) { + List ab = await Future.wait([ + checkPartialDownloadHash(url, i, headers: headers), + checkPartialDownloadHash(url, i, headers: headers) + ]); + if (ab[0] == ab[1]) { + print(i); + return ab[0]; + } + } + throw NoVersionError(); +} + +Future checkPartialDownloadHash(String url, int bytesToGrab, + {Map? headers}) async { var req = Request('GET', Uri.parse(url)); if (headers != null) { req.headers.addAll(headers); From 2da9a8cd59f2b7bb0e0629dd8ec29689ac4345af Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Thu, 18 Jan 2024 20:45:34 -0500 Subject: [PATCH 02/16] Remove unnecessary print() --- lib/providers/apps_provider.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index 035d5c1..31178f2 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -177,7 +177,6 @@ Future checkPartialDownloadHashDynamc(String url, checkPartialDownloadHash(url, i, headers: headers) ]); if (ab[0] == ab[1]) { - print(i); return ab[0]; } } From 183fb269883f4c34117db8a8cdc2b490f12115f5 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Thu, 18 Jan 2024 23:46:23 -0500 Subject: [PATCH 03/16] Clearer version detection settings --- lib/app_sources/apkcombo.dart | 1 + lib/app_sources/apkmirror.dart | 1 + lib/app_sources/apkpure.dart | 1 + lib/app_sources/aptoide.dart | 1 + lib/app_sources/fdroidrepo.dart | 1 + lib/app_sources/github.dart | 1 + lib/app_sources/gitlab.dart | 1 + lib/app_sources/html.dart | 2 - lib/app_sources/huaweiappgallery.dart | 4 +- lib/app_sources/jenkins.dart | 4 +- lib/app_sources/neutroncode.dart | 1 + lib/app_sources/sourcehut.dart | 1 + lib/app_sources/uptodown.dart | 1 + lib/app_sources/whatsapp.dart | 3 +- lib/components/generated_form.dart | 19 ++++-- lib/main.dart | 5 +- lib/pages/add_app.dart | 6 +- lib/pages/app.dart | 34 ++--------- lib/providers/apps_provider.dart | 8 +-- lib/providers/source_provider.dart | 84 ++++++++++++++++++--------- 20 files changed, 94 insertions(+), 85 deletions(-) diff --git a/lib/app_sources/apkcombo.dart b/lib/app_sources/apkcombo.dart index 1a58847..3a1ae49 100644 --- a/lib/app_sources/apkcombo.dart +++ b/lib/app_sources/apkcombo.dart @@ -6,6 +6,7 @@ import 'package:obtainium/providers/source_provider.dart'; class APKCombo extends AppSource { APKCombo() { hosts = ['apkcombo.com']; + showReleaseDateAsVersionToggle = true; } @override diff --git a/lib/app_sources/apkmirror.dart b/lib/app_sources/apkmirror.dart index 4e3cd1f..236a300 100644 --- a/lib/app_sources/apkmirror.dart +++ b/lib/app_sources/apkmirror.dart @@ -11,6 +11,7 @@ class APKMirror extends AppSource { APKMirror() { hosts = ['apkmirror.com']; enforceTrackOnly = true; + showReleaseDateAsVersionToggle = true; additionalSourceAppSpecificSettingFormItems = [ [ diff --git a/lib/app_sources/apkpure.dart b/lib/app_sources/apkpure.dart index f4c0026..715a8d3 100644 --- a/lib/app_sources/apkpure.dart +++ b/lib/app_sources/apkpure.dart @@ -23,6 +23,7 @@ class APKPure extends AppSource { hosts = ['apkpure.net', 'apkpure.com']; allowSubDomains = true; naiveStandardVersionDetection = true; + showReleaseDateAsVersionToggle = true; } @override diff --git a/lib/app_sources/aptoide.dart b/lib/app_sources/aptoide.dart index a2795d6..9daf57b 100644 --- a/lib/app_sources/aptoide.dart +++ b/lib/app_sources/aptoide.dart @@ -10,6 +10,7 @@ class Aptoide extends AppSource { name = 'Aptoide'; allowSubDomains = true; naiveStandardVersionDetection = true; + showReleaseDateAsVersionToggle = true; } @override diff --git a/lib/app_sources/fdroidrepo.dart b/lib/app_sources/fdroidrepo.dart index a1c571b..7722d9f 100644 --- a/lib/app_sources/fdroidrepo.dart +++ b/lib/app_sources/fdroidrepo.dart @@ -10,6 +10,7 @@ class FDroidRepo extends AppSource { canSearch = true; excludeFromMassSearch = true; neverAutoSelect = true; + showReleaseDateAsVersionToggle = true; additionalSourceAppSpecificSettingFormItems = [ [ diff --git a/lib/app_sources/github.dart b/lib/app_sources/github.dart index c08ae5a..e510014 100644 --- a/lib/app_sources/github.dart +++ b/lib/app_sources/github.dart @@ -16,6 +16,7 @@ class GitHub extends AppSource { GitHub() { hosts = ['github.com']; appIdInferIsOptional = true; + showReleaseDateAsVersionToggle = true; sourceConfigSettingFormItems = [ GeneratedFormTextField('github-creds', diff --git a/lib/app_sources/gitlab.dart b/lib/app_sources/gitlab.dart index 0b7776f..3e1e701 100644 --- a/lib/app_sources/gitlab.dart +++ b/lib/app_sources/gitlab.dart @@ -15,6 +15,7 @@ class GitLab extends AppSource { GitLab() { hosts = ['gitlab.com']; canSearch = true; + showReleaseDateAsVersionToggle = true; sourceConfigSettingFormItems = [ GeneratedFormTextField('gitlab-creds', diff --git a/lib/app_sources/html.dart b/lib/app_sources/html.dart index 7492051..d13653a 100644 --- a/lib/app_sources/html.dart +++ b/lib/app_sources/html.dart @@ -174,8 +174,6 @@ class HTML extends AppSource { ]) ] ]; - overrideVersionDetectionFormDefault('noVersionDetection', - disableStandard: false, disableRelDate: true); } @override diff --git a/lib/app_sources/huaweiappgallery.dart b/lib/app_sources/huaweiappgallery.dart index 54ab2ec..2c4d480 100644 --- a/lib/app_sources/huaweiappgallery.dart +++ b/lib/app_sources/huaweiappgallery.dart @@ -7,8 +7,8 @@ class HuaweiAppGallery extends AppSource { HuaweiAppGallery() { name = 'Huawei AppGallery'; hosts = ['appgallery.huawei.com']; - overrideVersionDetectionFormDefault('releaseDateAsVersion', - disableStandard: true); + versionDetectionDisallowed = true; + showReleaseDateAsVersionToggle = true; } @override diff --git a/lib/app_sources/jenkins.dart b/lib/app_sources/jenkins.dart index 8e817db..39a4f79 100644 --- a/lib/app_sources/jenkins.dart +++ b/lib/app_sources/jenkins.dart @@ -6,9 +6,9 @@ import 'package:obtainium/providers/source_provider.dart'; class Jenkins extends AppSource { Jenkins() { - overrideVersionDetectionFormDefault('releaseDateAsVersion', - disableStandard: true); + versionDetectionDisallowed = true; neverAutoSelect = true; + showReleaseDateAsVersionToggle = true; } String trimJobUrl(String url) { diff --git a/lib/app_sources/neutroncode.dart b/lib/app_sources/neutroncode.dart index b0f2d93..0429718 100644 --- a/lib/app_sources/neutroncode.dart +++ b/lib/app_sources/neutroncode.dart @@ -6,6 +6,7 @@ import 'package:obtainium/providers/source_provider.dart'; class NeutronCode extends AppSource { NeutronCode() { hosts = ['neutroncode.com']; + showReleaseDateAsVersionToggle = true; } @override diff --git a/lib/app_sources/sourcehut.dart b/lib/app_sources/sourcehut.dart index bb19b96..0c691c4 100644 --- a/lib/app_sources/sourcehut.dart +++ b/lib/app_sources/sourcehut.dart @@ -9,6 +9,7 @@ import 'package:easy_localization/easy_localization.dart'; class SourceHut extends AppSource { SourceHut() { hosts = ['git.sr.ht']; + showReleaseDateAsVersionToggle = true; additionalSourceAppSpecificSettingFormItems = [ [ diff --git a/lib/app_sources/uptodown.dart b/lib/app_sources/uptodown.dart index fe3d589..00de36c 100644 --- a/lib/app_sources/uptodown.dart +++ b/lib/app_sources/uptodown.dart @@ -9,6 +9,7 @@ class Uptodown extends AppSource { hosts = ['uptodown.com']; allowSubDomains = true; naiveStandardVersionDetection = true; + showReleaseDateAsVersionToggle = true; } @override diff --git a/lib/app_sources/whatsapp.dart b/lib/app_sources/whatsapp.dart index e9ad7c5..94b26d1 100644 --- a/lib/app_sources/whatsapp.dart +++ b/lib/app_sources/whatsapp.dart @@ -6,8 +6,7 @@ import 'package:obtainium/providers/source_provider.dart'; class WhatsApp extends AppSource { WhatsApp() { hosts = ['whatsapp.com']; - overrideVersionDetectionFormDefault('noVersionDetection', - disableStandard: true, disableRelDate: true); + versionDetectionDisallowed = true; } @override diff --git a/lib/components/generated_form.dart b/lib/components/generated_form.dart index 8c36b3f..0882f45 100644 --- a/lib/components/generated_form.dart +++ b/lib/components/generated_form.dart @@ -96,11 +96,14 @@ class GeneratedFormDropdown extends GeneratedFormItem { } class GeneratedFormSwitch extends GeneratedFormItem { + bool disabled = false; + GeneratedFormSwitch( super.key, { super.label, super.belowWidgets, bool super.defaultValue = false, + bool disabled = false, List super.additionalValidators = const [], }); @@ -115,6 +118,7 @@ class GeneratedFormSwitch extends GeneratedFormItem { label: label, belowWidgets: belowWidgets, defaultValue: defaultValue, + disabled: false, additionalValidators: List.from(additionalValidators)); } } @@ -368,12 +372,15 @@ class _GeneratedFormState extends State { ), Switch( value: values[fieldKey], - onChanged: (value) { - setState(() { - values[fieldKey] = value; - someValueChanged(); - }); - }) + onChanged: + (widget.items[r][e] as GeneratedFormSwitch).disabled + ? null + : (value) { + setState(() { + values[fieldKey] = value; + someValueChanged(); + }); + }) ], ); } else if (widget.items[r][e] is GeneratedFormTagInput) { diff --git a/lib/main.dart b/lib/main.dart index c965ce2..683db9c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -183,10 +183,7 @@ class _ObtainiumState extends State { value.versionName!, [], 0, - { - 'includePrereleases': true, - 'versionDetection': 'standardVersionDetection' - }, + {'includePrereleases': true, 'versionDetection': true}, null, false) ], onlyIfExists: false); diff --git a/lib/pages/add_app.dart b/lib/pages/add_app.dart index 41deae2..d504901 100644 --- a/lib/pages/add_app.dart +++ b/lib/pages/add_app.dart @@ -135,8 +135,7 @@ class AddAppPageState extends State { getReleaseDateAsVersionConfirmationIfNeeded( bool userPickedTrackOnly) async { - return (!(additionalSettings['versionDetection'] == - 'releaseDateAsVersion' && + return (!(additionalSettings['releaseDateAsVersion'] == true && // ignore: use_build_context_synchronously await showDialog( context: context, @@ -192,8 +191,7 @@ class AddAppPageState extends State { throw ObtainiumError(tr('appAlreadyAdded')); } if (app.additionalSettings['trackOnly'] == true || - app.additionalSettings['versionDetection'] != - 'standardVersionDetection') { + app.additionalSettings['versionDetection'] != true) { app.installedVersion = app.latestVersion; } app.categories = pickedCategories; diff --git a/lib/pages/app.dart b/lib/pages/app.dart index 18bd1fe..dc60b9f 100644 --- a/lib/pages/app.dart +++ b/lib/pages/app.dart @@ -1,7 +1,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:obtainium/components/generated_form.dart'; import 'package:obtainium/components/generated_form_modal.dart'; import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/main.dart'; @@ -54,13 +53,11 @@ class _AppPageState extends State { var trackOnly = app?.app.additionalSettings['trackOnly'] == true; bool isVersionDetectionStandard = - app?.app.additionalSettings['versionDetection'] == - 'standardVersionDetection'; + app?.app.additionalSettings['versionDetection'] == true; bool installedVersionIsEstimate = trackOnly || (app?.app.installedVersion != null && - app?.app.additionalSettings['versionDetection'] == - 'noVersionDetection'); + app?.app.additionalSettings['versionDetection'] != true); getInfoColumn() => Column( mainAxisAlignment: MainAxisAlignment.center, @@ -287,25 +284,6 @@ class _AppPageState extends State { return row; }).toList(); - items = items.map((row) { - row = row.map((e) { - if (e.key == 'versionDetection' && e is GeneratedFormDropdown) { - e.disabledOptKeys ??= []; - if (app?.app.installedVersion != null && - app?.app.additionalSettings['versionDetection'] != - 'releaseDateAsVersion' && - !appsProvider.isVersionDetectionPossible(app)) { - e.disabledOptKeys!.add('standardVersionDetection'); - } - if (app?.app.releaseDate == null) { - e.disabledOptKeys!.add('releaseDateAsVersion'); - } - } - return e; - }).toList(); - return row; - }).toList(); - return GeneratedFormModal( title: tr('additionalOptions'), items: items); }); @@ -320,9 +298,8 @@ class _AppPageState extends State { // ignore: use_build_context_synchronously showMessage(tr('appsFromSourceAreTrackOnly'), context); } - if (app.app.additionalSettings['versionDetection'] == - 'releaseDateAsVersion') { - if (originalSettings['versionDetection'] != 'releaseDateAsVersion') { + if (app.app.additionalSettings['releaseDateAsVersion'] == true) { + if (originalSettings['releaseDateAsVersion'] != true) { if (app.app.releaseDate != null) { bool isUpdated = app.app.installedVersion == app.app.latestVersion; @@ -333,8 +310,7 @@ class _AppPageState extends State { } } } - } else if (originalSettings['versionDetection'] == - 'releaseDateAsVersion') { + } else if (originalSettings['releaseDateAsVersion'] == true) { app.app.installedVersion = app.installedInfo?.versionName ?? app.app.installedVersion; } diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index 31178f2..c3fa50a 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -820,8 +820,7 @@ class AppsProvider with ChangeNotifier { ? app.installedInfo?.versionCode.toString() : app.installedInfo?.versionName; return app.app.additionalSettings['trackOnly'] != true && - app.app.additionalSettings['versionDetection'] != - 'releaseDateAsVersion' && + app.app.additionalSettings['releaseDateAsVersion'] != true && realInstalledVersion != null && app.app.installedVersion != null && (reconcileVersionDifferences( @@ -837,8 +836,7 @@ class AppsProvider with ChangeNotifier { var modded = false; var trackOnly = app.additionalSettings['trackOnly'] == true; var versionDetectionIsStandard = - app.additionalSettings['versionDetection'] == - 'standardVersionDetection'; + app.additionalSettings['versionDetection'] == true; var naiveStandardVersionDetection = app.additionalSettings['naiveStandardVersionDetection'] == true || SourceProvider() @@ -892,7 +890,7 @@ class AppsProvider with ChangeNotifier { versionDetectionIsStandard && !isVersionDetectionPossible( AppInMemory(app, null, installedInfo, null))) { - app.additionalSettings['versionDetection'] = 'noVersionDetection'; + app.additionalSettings['versionDetection'] = false; logs.add('Could not reconcile version formats for: ${app.id}'); modded = true; } diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index c66b1d3..2c55e00 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -103,6 +103,15 @@ appJSONCompatibilityModifiers(Map json) { additionalSettings.remove('releaseDateAsVersion'); } } + // Convert dropdown style version detection options back into bool style + if (additionalSettings['versionDetection'] == 'standardVersionDetection') { + additionalSettings['versionDetection'] = true; + } else if (additionalSettings['versionDetection'] == 'noVersionDetection') { + additionalSettings['versionDetection'] = false; + } else if (additionalSettings['versionDetection'] == 'releaseDateAsVersion') { + additionalSettings['versionDetection'] = false; + additionalSettings['releaseDateAsVersion'] = true; + } // Ensure additionalSettings are correctly typed for (var item in formItems) { if (additionalSettings[item.key] != null) { @@ -380,28 +389,23 @@ abstract class AppSource { bool allowSubDomains = false; bool naiveStandardVersionDetection = false; bool neverAutoSelect = false; + bool showReleaseDateAsVersionToggle = false; + bool versionDetectionDisallowed = false; AppSource() { name = runtimeType.toString(); } - overrideVersionDetectionFormDefault(String vd, - {bool disableStandard = false, bool disableRelDate = false}) { - additionalAppSpecificSourceAgnosticSettingFormItems = - additionalAppSpecificSourceAgnosticSettingFormItems.map((e) { + overrideAdditionalAppSpecificSourceAgnosticSettingSwitch(String key, + {bool disabled = true, bool defaultValue = true}) { + additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly = + additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly + .map((e) { return e.map((e2) { - if (e2.key == 'versionDetection') { - var item = e2 as GeneratedFormDropdown; - item.defaultValue = vd; - item.disabledOptKeys = []; - if (disableStandard) { - item.disabledOptKeys?.add('standardVersionDetection'); - } - if (disableRelDate) { - item.disabledOptKeys?.add('releaseDateAsVersion'); - } - item.disabledOptKeys = - item.disabledOptKeys?.where((element) => element != vd).toList(); + if (e2.key == key) { + var item = e2 as GeneratedFormSwitch; + item.disabled = disabled; + item.defaultValue = defaultValue; } return e2; }).toList(); @@ -457,7 +461,7 @@ abstract class AppSource { // Some additional data may be needed for Apps regardless of Source List> - additionalAppSpecificSourceAgnosticSettingFormItems = [ + additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly = [ [ GeneratedFormSwitch( 'trackOnly', @@ -475,16 +479,8 @@ abstract class AppSource { label: tr('matchGroupToUse'), required: false, hint: '\$0') ], [ - GeneratedFormDropdown( - 'versionDetection', - [ - MapEntry( - 'standardVersionDetection', tr('standardVersionDetection')), - MapEntry('releaseDateAsVersion', tr('releaseDateAsVersion')), - MapEntry('noVersionDetection', tr('noVersionDetection')) - ], - label: tr('versionDetection'), - defaultValue: 'standardVersionDetection') + GeneratedFormSwitch('versionDetection', + label: tr('versionDetection'), defaultValue: true) ], [ GeneratedFormSwitch('useVersionCodeAsOSVersion', @@ -518,9 +514,39 @@ abstract class AppSource { // Previous 2 variables combined into one at runtime for convenient usage List> get combinedAppSpecificSettingFormItems { + if (showReleaseDateAsVersionToggle == true) { + if (additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly + .indexWhere((List e) => + e.indexWhere((GeneratedFormItem i) => + i.key == 'releaseDateAsVersion') >= + 0) < + 0) { + additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly.insert( + additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly + .indexWhere((List e) => + e.indexWhere((GeneratedFormItem i) => + i.key == 'versionDetection') >= + 0) + + 1, + [ + GeneratedFormSwitch('releaseDateAsVersion', + label: tr('releaseDateAsVersion'), defaultValue: false) + ]); + } + } + if (versionDetectionDisallowed) { + overrideAdditionalAppSpecificSourceAgnosticSettingSwitch( + 'versionDetection', + disabled: true, + defaultValue: false); + overrideAdditionalAppSpecificSourceAgnosticSettingSwitch( + 'useVersionCodeAsOSVersion', + disabled: true, + defaultValue: false); + } return [ ...additionalSourceAppSpecificSettingFormItems, - ...additionalAppSpecificSourceAgnosticSettingFormItems + ...additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly ]; } @@ -773,7 +799,7 @@ class SourceProvider { } } - if (additionalSettings['versionDetection'] == 'releaseDateAsVersion' && + if (additionalSettings['releaseDateAsVersion'] == true && apk.releaseDate != null) { apk.version = apk.releaseDate!.microsecondsSinceEpoch.toString(); } From 15a34e53bfccb16ec0a54152ae5649ec7e620bad Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 19 Jan 2024 00:00:47 -0500 Subject: [PATCH 04/16] Bugfix in automatic source selection for URL input --- lib/providers/source_provider.dart | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index 2c55e00..249111c 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -734,11 +734,15 @@ class SourceProvider { } AppSource? source; for (var s in sources.where((element) => element.hosts.isNotEmpty)) { - if (RegExp( - '://${s.allowSubDomains ? '([^\\.]+\\.)*' : '(www\\.)?'}(${getSourceRegex(s.hosts)})(/|\\z)?') - .hasMatch(url)) { - source = s; - break; + try { + if (RegExp( + '^${s.allowSubDomains ? '([^\\.]+\\.)*' : '(www\\.)?'}(${getSourceRegex(s.hosts)})\$') + .hasMatch(Uri.parse(url).host)) { + source = s; + break; + } + } catch (e) { + // Ignore } } if (source == null) { From b173b1300a97c52d659f8df4159ec468000eaafd Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 19 Jan 2024 00:12:43 -0500 Subject: [PATCH 05/16] Clearer wording --- assets/translations/bs.json | 4 ++-- assets/translations/cs.json | 4 ++-- assets/translations/de.json | 4 ++-- assets/translations/en.json | 16 ++++++++-------- assets/translations/es.json | 4 ++-- assets/translations/fa.json | 4 ++-- assets/translations/fr.json | 4 ++-- assets/translations/hu.json | 4 ++-- assets/translations/it.json | 4 ++-- assets/translations/ja.json | 4 ++-- assets/translations/nl.json | 4 ++-- assets/translations/pl.json | 4 ++-- assets/translations/pt.json | 4 ++-- assets/translations/ru.json | 4 ++-- assets/translations/sv.json | 4 ++-- assets/translations/tr.json | 4 ++-- assets/translations/vi.json | 4 ++-- assets/translations/zh.json | 4 ++-- lib/pages/app.dart | 2 +- lib/pages/apps.dart | 2 +- lib/providers/source_provider.dart | 2 +- 21 files changed, 45 insertions(+), 45 deletions(-) diff --git a/assets/translations/bs.json b/assets/translations/bs.json index 9dc697d..6b8011f 100644 --- a/assets/translations/bs.json +++ b/assets/translations/bs.json @@ -51,9 +51,8 @@ "percentProgress": "Napredak: {}%", "pleaseWait": "Molimo sačekajte", "updateAvailable": "Ažuriranje dostupno", - "estimateInBracketsShort": "(Procjena)", "notInstalled": "Nije instalirano", - "estimateInBrackets": "(Procjena)", + "pseudoVersion": "Pseudo-version", "selectAll": "Označi sve", "deselectX": "Poništi odabir {}", "xWillBeRemovedButRemainInstalled": "{} će biti uklonjen iz Obtainiuma, ali će ostati instaliran na uređaju.", @@ -213,6 +212,7 @@ "changes": "Promjene", "releaseDate": "Datum izdavanja", "importFromURLsInFile": "Uvoz iz URL-ova u datoteci (kao što je OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Otkrivanje verzije", "standardVersionDetection": "Detekcija standardne verzije", "groupByCategory": "Grupiši po kategoriji", diff --git a/assets/translations/cs.json b/assets/translations/cs.json index cd4378c..0bf9e70 100644 --- a/assets/translations/cs.json +++ b/assets/translations/cs.json @@ -51,9 +51,8 @@ "percentProgress": "Pokrok: {}%", "pleaseWait": "Počkejte prosím", "updateAvailable": "Aktualizace je k dispozici", - "estimateInBracketsShort": "(approx.)", "notInstalled": "Není nainstalováno", - "estimateInBrackets": "(přibližně)", + "pseudoVersion": "Pseudo-version", "selectAll": "Vybrat vše", "deselectX": "{} deselected", "xWillBeRemovedButRemainInstalled": "{} bude odstraněn z Obtainium, ale zůstane nainstalován v zařízení.", @@ -213,6 +212,7 @@ "changes": "Změny", "releaseDate": "Datum vydání", "importFromURLsInFile": "Importovat adresy URL ze souboru (např. OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Detekce verze", "standardVersionDetection": "Standardní detekce verze", "groupByCategory": "Seskupit podle kategorie", diff --git a/assets/translations/de.json b/assets/translations/de.json index a7028c4..ca62001 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -51,9 +51,8 @@ "percentProgress": "Fortschritt: {}%", "pleaseWait": "Bitte warten", "updateAvailable": "Aktualisierung verfügbar", - "estimateInBracketsShort": "(ca.)", "notInstalled": "Nicht installiert", - "estimateInBrackets": "(Ungefähr)", + "pseudoVersion": "Pseudo-version", "selectAll": "Alle auswählen", "deselectX": "{} abgewählt", "xWillBeRemovedButRemainInstalled": "{} wird aus Obtainium entfernt, bleibt aber auf dem Gerät installiert.", @@ -213,6 +212,7 @@ "changes": "Änderungen", "releaseDate": "Veröffentlichungsdatum", "importFromURLsInFile": "Importieren von URLs aus Datei (z. B. OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Versionserkennung", "standardVersionDetection": "Standardversionserkennung", "groupByCategory": "Nach Kategorie gruppieren", diff --git a/assets/translations/en.json b/assets/translations/en.json index 74a25d7..b436782 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -51,9 +51,8 @@ "percentProgress": "Progress: {}%", "pleaseWait": "Please Wait", "updateAvailable": "Update Available", - "estimateInBracketsShort": "(Est.)", "notInstalled": "Not Installed", - "estimateInBrackets": "(Estimate)", + "pseudoVersion": "Pseudo-version", "selectAll": "Select All", "deselectX": "Deselect {}", "xWillBeRemovedButRemainInstalled": "{} will be removed from Obtainium but remain installed on device.", @@ -166,8 +165,8 @@ "unknown": "Unknown", "none": "None", "never": "Never", - "latestVersionX": "Latest Version: {}", - "installedVersionX": "Installed Version: {}", + "latestVersionX": "Latest: {}", + "installedVersionX": "Installed: {}", "lastUpdateCheckX": "Last Update Check: {}", "remove": "Remove", "yesMarkUpdated": "Yes, Mark as Updated", @@ -208,11 +207,12 @@ "removeFromObtainium": "Remove from Obtainium", "uninstallFromDevice": "Uninstall from Device", "onlyWorksWithNonVersionDetectApps": "Only works for Apps with version detection disabled.", - "releaseDateAsVersion": "Use Release Date as Version", + "releaseDateAsVersion": "Use release date as version string", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.", "changes": "Changes", "releaseDate": "Release Date", "importFromURLsInFile": "Import from URLs in File (like OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Version Detection", "standardVersionDetection": "Standard version detection", "groupByCategory": "Group by Category", @@ -254,8 +254,8 @@ "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", "autoSelectHighestVersionCode": "Auto-select highest versionCode APK", - "versionExtractionRegEx": "Version Extraction RegEx", - "matchGroupToUse": "Match Group to Use for Version Extraction Regex", + "versionExtractionRegEx": "Version String Extraction RegEx", + "matchGroupToUse": "Match Group to Use for Version String Extraction Regex", "highlightTouchTargets": "Highlight less obvious touch targets", "pickExportDir": "Pick Export Directory", "autoExportOnChanges": "Auto-export on changes", @@ -269,7 +269,7 @@ "debugMenu": "Debug Menu", "bgTaskStarted": "Background task started - check logs.", "runBgCheckNow": "Run Background Update Check Now", - "versionExtractWholePage": "Apply Version Extraction Regex to Entire Page", + "versionExtractWholePage": "Apply version string extraction Regex to entire page", "installing": "Installing", "skipUpdateNotifications": "Skip update notifications", "updatesAvailableNotifChannel": "Updates Available", diff --git a/assets/translations/es.json b/assets/translations/es.json index b02120a..c9f4462 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -51,9 +51,8 @@ "percentProgress": "Progreso: {}%", "pleaseWait": "Por favor, espere", "updateAvailable": "Actualización Disponible", - "estimateInBracketsShort": "(Aprox.)", "notInstalled": "No Instalado", - "estimateInBrackets": "(Aproximado)", + "pseudoVersion": "Pseudo-version", "selectAll": "Seleccionar Todo", "deselectX": "Deseleccionar {}", "xWillBeRemovedButRemainInstalled": "{} será eliminada de Obtainium pero continuará instalada en el dispositivo.", @@ -213,6 +212,7 @@ "changes": "Cambios", "releaseDate": "Fecha de Publicación", "importFromURLsInFile": "Importar URLs desde archivo (como OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Detección de Versiones", "standardVersionDetection": "Por versión", "groupByCategory": "Agrupar por categoría", diff --git a/assets/translations/fa.json b/assets/translations/fa.json index 30c9881..e9f6438 100644 --- a/assets/translations/fa.json +++ b/assets/translations/fa.json @@ -51,9 +51,8 @@ "percentProgress": "پیش رفتن: {}%", "pleaseWait": "لطفا صبر کنید", "updateAvailable": "بروزرسانی در دسترس", - "estimateInBracketsShort": "(تخمین)", "notInstalled": "نصب نشده", - "estimateInBrackets": "(تخمین زدن)", + "pseudoVersion": "Pseudo-version", "selectAll": "انتخاب همه", "deselectX": "لغو انتخاب {}", "xWillBeRemovedButRemainInstalled": "{} از Obtainium حذف می‌شود اما روی دستگاه نصب می‌ماند.", @@ -213,6 +212,7 @@ "changes": "تغییرات", "releaseDate": "تاریخ انتشار", "importFromURLsInFile": "درون ریزی از آدرس های اینترنتی موجود در فایل (مانند OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "تشخیص نسخه", "standardVersionDetection": "تشخیص نسخه استاندارد", "groupByCategory": "گروه بر اساس دسته", diff --git a/assets/translations/fr.json b/assets/translations/fr.json index 3a3fa7e..fff2767 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -51,9 +51,8 @@ "percentProgress": "Progrès: {}%", "pleaseWait": "Veuillez patienter", "updateAvailable": "Mise à jour disponible", - "estimateInBracketsShort": "(Est.)", "notInstalled": "Pas installé", - "estimateInBrackets": "(Estimation)", + "pseudoVersion": "Pseudo-version", "selectAll": "Tout sélectionner", "deselectX": "Déselectionner {}", "xWillBeRemovedButRemainInstalled": "{} sera supprimé d'Obtainium mais restera installé sur l'appareil.", @@ -213,6 +212,7 @@ "changes": "Changements", "releaseDate": "Date de sortie", "importFromURLsInFile": "Importer à partir d'URL dans un fichier (comme OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Détection des versions", "standardVersionDetection": "Détection de version standard", "groupByCategory": "Group by Category", diff --git a/assets/translations/hu.json b/assets/translations/hu.json index ecf9bf2..80a771b 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -51,9 +51,8 @@ "percentProgress": "Folyamat: {}%", "pleaseWait": "Kis türelmet", "updateAvailable": "Frissítés érhető el", - "estimateInBracketsShort": "(Becsült)", "notInstalled": "Nem telepített", - "estimateInBrackets": "(Becslés)", + "pseudoVersion": "Pseudo-version", "selectAll": "Mindet kiválaszt", "deselectX": "Törölje {} kijelölését", "xWillBeRemovedButRemainInstalled": "A(z) {} el lesz távolítva az Obtainiumból, de továbbra is telepítve marad az eszközön.", @@ -213,6 +212,7 @@ "changes": "Változtatások", "releaseDate": "Kiadás dátuma", "importFromURLsInFile": "Importálás fájlban található URL-ből (mint pl. OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Verzió érzékelés", "standardVersionDetection": "Alapért. verzió érzékelés", "groupByCategory": "Csoportosítás Kategória alapján", diff --git a/assets/translations/it.json b/assets/translations/it.json index 48dfc9b..a5cd2da 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -51,9 +51,8 @@ "percentProgress": "Avanzamento: {}%", "pleaseWait": "In attesa", "updateAvailable": "Aggiornamento disponibile", - "estimateInBracketsShort": "(stim.)", "notInstalled": "Non installato", - "estimateInBrackets": "(stimato)", + "pseudoVersion": "Pseudo-version", "selectAll": "Seleziona tutto", "deselectX": "Deseleziona {}", "xWillBeRemovedButRemainInstalled": "Verà effettuata la rimozione di {}, ma non la disinstallazione.", @@ -213,6 +212,7 @@ "changes": "Novità", "releaseDate": "Data di rilascio", "importFromURLsInFile": "Importa da URL in file (come OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Rilevamento di versione", "standardVersionDetection": "Rilevamento di versione standard", "groupByCategory": "Raggruppa per categoria", diff --git a/assets/translations/ja.json b/assets/translations/ja.json index 0cfbf76..b276a85 100644 --- a/assets/translations/ja.json +++ b/assets/translations/ja.json @@ -51,9 +51,8 @@ "percentProgress": "ダウンロード中: {}%", "pleaseWait": "しばらくお待ちください", "updateAvailable": "アップデートが利用可能", - "estimateInBracketsShort": "(推定)", "notInstalled": "未インストール", - "estimateInBrackets": "(推定)", + "pseudoVersion": "Pseudo-version", "selectAll": "すべて選択", "deselectX": "{}件の選択を解除", "xWillBeRemovedButRemainInstalled": "{} はObtainiumから削除されますが、デバイスにはインストールされたままです。", @@ -213,6 +212,7 @@ "changes": "変更点", "releaseDate": "リリース日", "importFromURLsInFile": "ファイル(OPMLなど)内のURLからインポート", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "バージョン検出", "standardVersionDetection": "標準のバージョン検出", "groupByCategory": "カテゴリ別にグループ化する", diff --git a/assets/translations/nl.json b/assets/translations/nl.json index af5610e..2744d85 100644 --- a/assets/translations/nl.json +++ b/assets/translations/nl.json @@ -51,9 +51,8 @@ "percentProgress": "Vooruitgang: {}%", "pleaseWait": "Even geduld", "updateAvailable": "Update beschikbaar", - "estimateInBracketsShort": "(Ong.)", "notInstalled": "Niet geinstalleerd", - "estimateInBrackets": "(Ongeveer)", + "pseudoVersion": "Pseudo-version", "selectAll": "Selecteer alles", "deselectX": "Deselecteer {}", "xWillBeRemovedButRemainInstalled": "{} zal worden verwijderd uit Obtainium, maar blijft geïnstalleerd op het apparaat.", @@ -213,6 +212,7 @@ "changes": "Veranderingen", "releaseDate": "Releasedatum", "importFromURLsInFile": "Importeren vanaf URL's in een bestand (zoals OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Versieherkenning", "standardVersionDetection": "Standaard versieherkenning", "groupByCategory": "Groepeer op categorie", diff --git a/assets/translations/pl.json b/assets/translations/pl.json index 574cc79..7667c6b 100644 --- a/assets/translations/pl.json +++ b/assets/translations/pl.json @@ -51,9 +51,8 @@ "percentProgress": "Postęp: {}%", "pleaseWait": "Proszę czekać", "updateAvailable": "Dostępna aktualizacja", - "estimateInBracketsShort": "(Szac.)", "notInstalled": "Nie zainstalowano", - "estimateInBrackets": "(Szacunkowo)", + "pseudoVersion": "Pseudo-version", "selectAll": "Zaznacz wszystkie", "deselectX": "Odznacz {}", "xWillBeRemovedButRemainInstalled": "{} zostanie usunięty z Obtainium, ale pozostanie zainstalowany na urządzeniu.", @@ -213,6 +212,7 @@ "changes": "Zmiany", "releaseDate": "Data wydania", "importFromURLsInFile": "Importuj z adresów URL w pliku (typu OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Wykrywanie wersji", "standardVersionDetection": "Standardowe wykrywanie wersji", "groupByCategory": "Grupuj według kategorii", diff --git a/assets/translations/pt.json b/assets/translations/pt.json index cdb38fe..78d3e4c 100644 --- a/assets/translations/pt.json +++ b/assets/translations/pt.json @@ -51,9 +51,8 @@ "percentProgress": "Progresso: {}%", "pleaseWait": "Por favor, espere", "updateAvailable": "Atualização disponível", - "estimateInBracketsShort": "(Aprox.)", "notInstalled": "Não instalado", - "estimateInBrackets": "(Aproximado)", + "pseudoVersion": "Pseudo-version", "selectAll": "Selecionar todos", "deselectX": "Deselecionar {}", "xWillBeRemovedButRemainInstalled": "{} será removido do Obtainium mais permanecerá instalado no dispositivo.", @@ -213,6 +212,7 @@ "changes": "Mudanças", "releaseDate": "Data de lançamento", "importFromURLsInFile": "Importar de URLs em arquivo (como OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Detecção de Versão", "standardVersionDetection": "Detecção de versão padrão", "groupByCategory": "Agroupar por categoria", diff --git a/assets/translations/ru.json b/assets/translations/ru.json index dbb281f..4eff7a8 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -51,9 +51,8 @@ "percentProgress": "Прогресс: {}%", "pleaseWait": "Пожалуйста, подождите", "updateAvailable": "Доступно обновление", - "estimateInBracketsShort": "(Оценка)", "notInstalled": "Не установлено", - "estimateInBrackets": "(Оценка)", + "pseudoVersion": "Pseudo-version", "selectAll": "Выбрать всё", "deselectX": "Отменить выбор {}", "xWillBeRemovedButRemainInstalled": "{} будет удалено из Obtainium, но останется на устройстве", @@ -213,6 +212,7 @@ "changes": "Изменения", "releaseDate": "Дата выпуска", "importFromURLsInFile": "Импорт из файла URL-адресов (например: OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Определение версии", "standardVersionDetection": "Стандартное", "groupByCategory": "Группировать по категориям", diff --git a/assets/translations/sv.json b/assets/translations/sv.json index 9c068c7..df0dd43 100644 --- a/assets/translations/sv.json +++ b/assets/translations/sv.json @@ -51,9 +51,8 @@ "percentProgress": "Progress: {}%", "pleaseWait": "Vänta", "updateAvailable": "Uppdatering Tillgänglig", - "estimateInBracketsShort": "(Est.)", "notInstalled": "Inte Installerad", - "estimateInBrackets": "(Uppskattning)", + "pseudoVersion": "Pseudo-version", "selectAll": "Välj Alla", "deselectX": "Avmarkera {}", "xWillBeRemovedButRemainInstalled": "{} kommer tas bort från Obtainium men kommer vara fortsatt installerad på enheten.", @@ -213,6 +212,7 @@ "changes": "Ändringar", "releaseDate": "Releasedatum", "importFromURLsInFile": "Importera från URL:er i fil (som OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Versionsdetektering", "standardVersionDetection": "Standardversionsdetektering", "groupByCategory": "Gruppera via Kategori", diff --git a/assets/translations/tr.json b/assets/translations/tr.json index 1b6ba32..33d8f2b 100644 --- a/assets/translations/tr.json +++ b/assets/translations/tr.json @@ -51,9 +51,8 @@ "percentProgress": "İlerleme: {}%", "pleaseWait": "Lütfen Bekleyin", "updateAvailable": "Güncelleme Var", - "estimateInBracketsShort": "(Est.)", "notInstalled": "Yüklenmedi", - "estimateInBrackets": "(Tahmini)", + "pseudoVersion": "Pseudo-version", "selectAll": "Hepsini Seç", "deselectX": "{}'yi Seçimden Kaldır", "xWillBeRemovedButRemainInstalled": "{} Obtainium'dan kaldırılacak ancak cihazınızda yüklü kalacaktır.", @@ -213,6 +212,7 @@ "changes": "Değişiklikler", "releaseDate": "Yayın Tarihi", "importFromURLsInFile": "Dosyadaki URL'lerden İçe Aktar", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Sürüm Tespiti", "standardVersionDetection": "Standart sürüm tespiti", "groupByCategory": "Kategoriye Göre Grupla", diff --git a/assets/translations/vi.json b/assets/translations/vi.json index 6bbbf1c..2c80eb4 100644 --- a/assets/translations/vi.json +++ b/assets/translations/vi.json @@ -51,9 +51,8 @@ "percentProgress": "Đang tải {}%", "pleaseWait": "Vui lòng chờ", "updateAvailable": "Có sẵn bản cập nhật", - "estimateInBracketsShort": "(Ước lượng.)", "notInstalled": "Chưa cài đặt", - "estimateInBrackets": "(Ước lượng)", + "pseudoVersion": "Pseudo-version", "selectAll": "Chọn tất cả", "deselectX": "Bỏ chọn {}", "xWillBeRemovedButRemainInstalled": "{} sẽ bị xóa khỏi Obtainium nhưng vẫn còn cài đặt trên thiết bị.", @@ -213,6 +212,7 @@ "changes": "Thay đổi", "releaseDate": "Ngày phát hành", "importFromURLsInFile": "Nhập từ URL trong Tệp (như OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "Phát hiện phiên bản", "standardVersionDetection": "Phát hiện phiên bản tiêu chuẩn", "groupByCategory": "Nhóm theo thể loại", diff --git a/assets/translations/zh.json b/assets/translations/zh.json index 07be631..fb20ed1 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -51,9 +51,8 @@ "percentProgress": "进度:{}%", "pleaseWait": "请稍候", "updateAvailable": "更新可用", - "estimateInBracketsShort": "(推测)", "notInstalled": "未安装", - "estimateInBrackets": "(推测)", + "pseudoVersion": "Pseudo-version", "selectAll": "全选", "deselectX": "取消选择 {}", "xWillBeRemovedButRemainInstalled": "“{}”将从 Obtainium 中删除,但仍安装在您的设备中。", @@ -213,6 +212,7 @@ "changes": "更新日志", "releaseDate": "发行日期", "importFromURLsInFile": "从文件中的 URL 导入(如 OPML)", + "versionDetectionExplanation": "Reconcile version string with version detected from OS", "versionDetection": "版本检测", "standardVersionDetection": "常规版本检测", "groupByCategory": "按类别分组显示", diff --git a/lib/pages/app.dart b/lib/pages/app.dart index dc60b9f..53a8a5d 100644 --- a/lib/pages/app.dart +++ b/lib/pages/app.dart @@ -94,7 +94,7 @@ class _AppPageState extends State { app?.app.latestVersion ?? tr('unknown') ])}\n${tr('installedVersionX', args: [ app?.app.installedVersion ?? tr('none') - ])}${installedVersionIsEstimate ? '\n${tr('estimateInBrackets')}' : ''}', + ])}${installedVersionIsEstimate ? '\n${tr('pseudoVersion')}' : ''}', textAlign: TextAlign.end, style: Theme.of(context).textTheme.bodyLarge!, ), diff --git a/lib/pages/apps.dart b/lib/pages/apps.dart index c5570c0..31adef5 100644 --- a/lib/pages/apps.dart +++ b/lib/pages/apps.dart @@ -421,7 +421,7 @@ class AppsPageState extends State { } getVersionText(int appIndex) { - return '${listedApps[appIndex].app.installedVersion ?? tr('notInstalled')}${listedApps[appIndex].app.additionalSettings['trackOnly'] == true ? ' ${tr('estimateInBrackets')}' : ''}'; + return '${listedApps[appIndex].app.installedVersion ?? tr('notInstalled')}${listedApps[appIndex].app.additionalSettings['trackOnly'] == true ? ' ${tr('pseudoVersion')}' : ''}'; } getChangesButtonString(int appIndex, bool hasChangeLogFn) { diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index 249111c..9144fbf 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -480,7 +480,7 @@ abstract class AppSource { ], [ GeneratedFormSwitch('versionDetection', - label: tr('versionDetection'), defaultValue: true) + label: tr('versionDetectionExplanation'), defaultValue: true) ], [ GeneratedFormSwitch('useVersionCodeAsOSVersion', From f5067d636af5197c8112707f486c195b7e9f9c2d Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 19 Jan 2024 00:21:57 -0500 Subject: [PATCH 06/16] More UI tweaks --- assets/translations/bs.json | 2 +- assets/translations/cs.json | 2 +- assets/translations/de.json | 2 +- assets/translations/en.json | 2 +- assets/translations/es.json | 2 +- assets/translations/fa.json | 2 +- assets/translations/fr.json | 2 +- assets/translations/hu.json | 2 +- assets/translations/it.json | 2 +- assets/translations/ja.json | 2 +- assets/translations/nl.json | 2 +- assets/translations/pl.json | 2 +- assets/translations/pt.json | 2 +- assets/translations/ru.json | 2 +- assets/translations/sv.json | 2 +- assets/translations/tr.json | 2 +- assets/translations/vi.json | 2 +- assets/translations/zh.json | 2 +- lib/pages/app.dart | 6 ++---- lib/providers/source_provider.dart | 4 +++- 20 files changed, 23 insertions(+), 23 deletions(-) diff --git a/assets/translations/bs.json b/assets/translations/bs.json index 6b8011f..a83f1dd 100644 --- a/assets/translations/bs.json +++ b/assets/translations/bs.json @@ -52,7 +52,7 @@ "pleaseWait": "Molimo sačekajte", "updateAvailable": "Ažuriranje dostupno", "notInstalled": "Nije instalirano", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Označi sve", "deselectX": "Poništi odabir {}", "xWillBeRemovedButRemainInstalled": "{} će biti uklonjen iz Obtainiuma, ali će ostati instaliran na uređaju.", diff --git a/assets/translations/cs.json b/assets/translations/cs.json index 0bf9e70..f21663f 100644 --- a/assets/translations/cs.json +++ b/assets/translations/cs.json @@ -52,7 +52,7 @@ "pleaseWait": "Počkejte prosím", "updateAvailable": "Aktualizace je k dispozici", "notInstalled": "Není nainstalováno", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Vybrat vše", "deselectX": "{} deselected", "xWillBeRemovedButRemainInstalled": "{} bude odstraněn z Obtainium, ale zůstane nainstalován v zařízení.", diff --git a/assets/translations/de.json b/assets/translations/de.json index ca62001..119ba9c 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -52,7 +52,7 @@ "pleaseWait": "Bitte warten", "updateAvailable": "Aktualisierung verfügbar", "notInstalled": "Nicht installiert", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Alle auswählen", "deselectX": "{} abgewählt", "xWillBeRemovedButRemainInstalled": "{} wird aus Obtainium entfernt, bleibt aber auf dem Gerät installiert.", diff --git a/assets/translations/en.json b/assets/translations/en.json index b436782..5907ccf 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -52,7 +52,7 @@ "pleaseWait": "Please Wait", "updateAvailable": "Update Available", "notInstalled": "Not Installed", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Select All", "deselectX": "Deselect {}", "xWillBeRemovedButRemainInstalled": "{} will be removed from Obtainium but remain installed on device.", diff --git a/assets/translations/es.json b/assets/translations/es.json index c9f4462..e01f283 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -52,7 +52,7 @@ "pleaseWait": "Por favor, espere", "updateAvailable": "Actualización Disponible", "notInstalled": "No Instalado", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Seleccionar Todo", "deselectX": "Deseleccionar {}", "xWillBeRemovedButRemainInstalled": "{} será eliminada de Obtainium pero continuará instalada en el dispositivo.", diff --git a/assets/translations/fa.json b/assets/translations/fa.json index e9f6438..fd52064 100644 --- a/assets/translations/fa.json +++ b/assets/translations/fa.json @@ -52,7 +52,7 @@ "pleaseWait": "لطفا صبر کنید", "updateAvailable": "بروزرسانی در دسترس", "notInstalled": "نصب نشده", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "انتخاب همه", "deselectX": "لغو انتخاب {}", "xWillBeRemovedButRemainInstalled": "{} از Obtainium حذف می‌شود اما روی دستگاه نصب می‌ماند.", diff --git a/assets/translations/fr.json b/assets/translations/fr.json index fff2767..ee33cf8 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -52,7 +52,7 @@ "pleaseWait": "Veuillez patienter", "updateAvailable": "Mise à jour disponible", "notInstalled": "Pas installé", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Tout sélectionner", "deselectX": "Déselectionner {}", "xWillBeRemovedButRemainInstalled": "{} sera supprimé d'Obtainium mais restera installé sur l'appareil.", diff --git a/assets/translations/hu.json b/assets/translations/hu.json index 80a771b..c6d8c47 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -52,7 +52,7 @@ "pleaseWait": "Kis türelmet", "updateAvailable": "Frissítés érhető el", "notInstalled": "Nem telepített", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Mindet kiválaszt", "deselectX": "Törölje {} kijelölését", "xWillBeRemovedButRemainInstalled": "A(z) {} el lesz távolítva az Obtainiumból, de továbbra is telepítve marad az eszközön.", diff --git a/assets/translations/it.json b/assets/translations/it.json index a5cd2da..ae5b7a9 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -52,7 +52,7 @@ "pleaseWait": "In attesa", "updateAvailable": "Aggiornamento disponibile", "notInstalled": "Non installato", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Seleziona tutto", "deselectX": "Deseleziona {}", "xWillBeRemovedButRemainInstalled": "Verà effettuata la rimozione di {}, ma non la disinstallazione.", diff --git a/assets/translations/ja.json b/assets/translations/ja.json index b276a85..e2b4d38 100644 --- a/assets/translations/ja.json +++ b/assets/translations/ja.json @@ -52,7 +52,7 @@ "pleaseWait": "しばらくお待ちください", "updateAvailable": "アップデートが利用可能", "notInstalled": "未インストール", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "すべて選択", "deselectX": "{}件の選択を解除", "xWillBeRemovedButRemainInstalled": "{} はObtainiumから削除されますが、デバイスにはインストールされたままです。", diff --git a/assets/translations/nl.json b/assets/translations/nl.json index 2744d85..4f788d0 100644 --- a/assets/translations/nl.json +++ b/assets/translations/nl.json @@ -52,7 +52,7 @@ "pleaseWait": "Even geduld", "updateAvailable": "Update beschikbaar", "notInstalled": "Niet geinstalleerd", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Selecteer alles", "deselectX": "Deselecteer {}", "xWillBeRemovedButRemainInstalled": "{} zal worden verwijderd uit Obtainium, maar blijft geïnstalleerd op het apparaat.", diff --git a/assets/translations/pl.json b/assets/translations/pl.json index 7667c6b..44f2f9d 100644 --- a/assets/translations/pl.json +++ b/assets/translations/pl.json @@ -52,7 +52,7 @@ "pleaseWait": "Proszę czekać", "updateAvailable": "Dostępna aktualizacja", "notInstalled": "Nie zainstalowano", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Zaznacz wszystkie", "deselectX": "Odznacz {}", "xWillBeRemovedButRemainInstalled": "{} zostanie usunięty z Obtainium, ale pozostanie zainstalowany na urządzeniu.", diff --git a/assets/translations/pt.json b/assets/translations/pt.json index 78d3e4c..dc2370f 100644 --- a/assets/translations/pt.json +++ b/assets/translations/pt.json @@ -52,7 +52,7 @@ "pleaseWait": "Por favor, espere", "updateAvailable": "Atualização disponível", "notInstalled": "Não instalado", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Selecionar todos", "deselectX": "Deselecionar {}", "xWillBeRemovedButRemainInstalled": "{} será removido do Obtainium mais permanecerá instalado no dispositivo.", diff --git a/assets/translations/ru.json b/assets/translations/ru.json index 4eff7a8..2168990 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -52,7 +52,7 @@ "pleaseWait": "Пожалуйста, подождите", "updateAvailable": "Доступно обновление", "notInstalled": "Не установлено", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Выбрать всё", "deselectX": "Отменить выбор {}", "xWillBeRemovedButRemainInstalled": "{} будет удалено из Obtainium, но останется на устройстве", diff --git a/assets/translations/sv.json b/assets/translations/sv.json index df0dd43..157382f 100644 --- a/assets/translations/sv.json +++ b/assets/translations/sv.json @@ -52,7 +52,7 @@ "pleaseWait": "Vänta", "updateAvailable": "Uppdatering Tillgänglig", "notInstalled": "Inte Installerad", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Välj Alla", "deselectX": "Avmarkera {}", "xWillBeRemovedButRemainInstalled": "{} kommer tas bort från Obtainium men kommer vara fortsatt installerad på enheten.", diff --git a/assets/translations/tr.json b/assets/translations/tr.json index 33d8f2b..5ade2f2 100644 --- a/assets/translations/tr.json +++ b/assets/translations/tr.json @@ -52,7 +52,7 @@ "pleaseWait": "Lütfen Bekleyin", "updateAvailable": "Güncelleme Var", "notInstalled": "Yüklenmedi", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Hepsini Seç", "deselectX": "{}'yi Seçimden Kaldır", "xWillBeRemovedButRemainInstalled": "{} Obtainium'dan kaldırılacak ancak cihazınızda yüklü kalacaktır.", diff --git a/assets/translations/vi.json b/assets/translations/vi.json index 2c80eb4..eb20091 100644 --- a/assets/translations/vi.json +++ b/assets/translations/vi.json @@ -52,7 +52,7 @@ "pleaseWait": "Vui lòng chờ", "updateAvailable": "Có sẵn bản cập nhật", "notInstalled": "Chưa cài đặt", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "Chọn tất cả", "deselectX": "Bỏ chọn {}", "xWillBeRemovedButRemainInstalled": "{} sẽ bị xóa khỏi Obtainium nhưng vẫn còn cài đặt trên thiết bị.", diff --git a/assets/translations/zh.json b/assets/translations/zh.json index fb20ed1..d570125 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -52,7 +52,7 @@ "pleaseWait": "请稍候", "updateAvailable": "更新可用", "notInstalled": "未安装", - "pseudoVersion": "Pseudo-version", + "pseudoVersion": "pseudo-version", "selectAll": "全选", "deselectX": "取消选择 {}", "xWillBeRemovedButRemainInstalled": "“{}”将从 Obtainium 中删除,但仍安装在您的设备中。", diff --git a/lib/pages/app.dart b/lib/pages/app.dart index 53a8a5d..81488ac 100644 --- a/lib/pages/app.dart +++ b/lib/pages/app.dart @@ -94,7 +94,7 @@ class _AppPageState extends State { app?.app.latestVersion ?? tr('unknown') ])}\n${tr('installedVersionX', args: [ app?.app.installedVersion ?? tr('none') - ])}${installedVersionIsEstimate ? '\n${tr('pseudoVersion')}' : ''}', + ])}${installedVersionIsEstimate ? '\n(${tr('pseudoVersion')})' : ''}', textAlign: TextAlign.end, style: Theme.of(context).textTheme.bodyLarge!, ), @@ -108,9 +108,7 @@ class _AppPageState extends State { height: 16, ), Text( - '${trackOnly ? '${tr('xIsTrackOnly', args: [ - tr('app') - ])}\n' : ''}${tr('noVersionDetection')}', + trackOnly ? tr('xIsTrackOnly', args: [tr('app')]) : '', style: Theme.of(context).textTheme.labelSmall, textAlign: TextAlign.center, ) diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index 9144fbf..ac6b284 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -530,7 +530,9 @@ abstract class AppSource { 1, [ GeneratedFormSwitch('releaseDateAsVersion', - label: tr('releaseDateAsVersion'), defaultValue: false) + label: + '${tr('releaseDateAsVersion')} (${tr('pseudoVersion')})', + defaultValue: false) ]); } } From 56052bfd79dd9f6b44f6d38a7be92ff4a56fafc0 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 19 Jan 2024 00:43:02 -0500 Subject: [PATCH 07/16] Bugfix in version detection toggles --- lib/pages/app.dart | 48 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/lib/pages/app.dart b/lib/pages/app.dart index 81488ac..f603e37 100644 --- a/lib/pages/app.dart +++ b/lib/pages/app.dart @@ -28,8 +28,18 @@ class _AppPageState extends State { Widget build(BuildContext context) { var appsProvider = context.watch(); var settingsProvider = context.watch(); - getUpdate(String id) { - appsProvider.checkUpdate(id).catchError((e) { + getUpdate(String id, {bool resetVersion = false}) { + appsProvider.checkUpdate(id).then((e) { + if (resetVersion) { + appsProvider.apps[id]?.app.additionalSettings['versionDetection'] = + true; + if (appsProvider.apps[id]?.app.installedVersion != null) { + appsProvider.apps[id]?.app.installedVersion = + appsProvider.apps[id]?.app.latestVersion; + } + appsProvider.saveApps([appsProvider.apps[id]!.app]); + } + }).catchError((e) { showError(e, context); return null; }); @@ -296,24 +306,34 @@ class _AppPageState extends State { // ignore: use_build_context_synchronously showMessage(tr('appsFromSourceAreTrackOnly'), context); } - if (app.app.additionalSettings['releaseDateAsVersion'] == true) { - if (originalSettings['releaseDateAsVersion'] != true) { - if (app.app.releaseDate != null) { - bool isUpdated = - app.app.installedVersion == app.app.latestVersion; - app.app.latestVersion = - app.app.releaseDate!.microsecondsSinceEpoch.toString(); - if (isUpdated) { - app.app.installedVersion = app.app.latestVersion; - } + var versionDetectionEnabled = + app.app.additionalSettings['versionDetection'] == true && + originalSettings['versionDetection'] != true; + var releaseDateVersionEnabled = + app.app.additionalSettings['releaseDateAsVersion'] == true && + originalSettings['releaseDateAsVersion'] != true; + var releaseDateVersionDisabled = + app.app.additionalSettings['releaseDateAsVersion'] != true && + originalSettings['releaseDateAsVersion'] == true; + if (releaseDateVersionEnabled) { + if (app.app.releaseDate != null) { + bool isUpdated = app.app.installedVersion == app.app.latestVersion; + app.app.latestVersion = + app.app.releaseDate!.microsecondsSinceEpoch.toString(); + if (isUpdated) { + app.app.installedVersion = app.app.latestVersion; } } - } else if (originalSettings['releaseDateAsVersion'] == true) { + } else if (releaseDateVersionDisabled) { app.app.installedVersion = app.installedInfo?.versionName ?? app.app.installedVersion; } + if (versionDetectionEnabled) { + app.app.additionalSettings['versionDetection'] = true; + app.app.additionalSettings['releaseDateAsVersion'] = false; + } appsProvider.saveApps([app.app]).then((value) { - getUpdate(app.app.id); + getUpdate(app.app.id, resetVersion: versionDetectionEnabled); }); } } From dc45334cb986656caa24351ddc2ff25a6fe82674 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 19 Jan 2024 18:54:01 -0500 Subject: [PATCH 08/16] Support Direct APK Links (#1292) --- assets/translations/bs.json | 4 +++ assets/translations/cs.json | 4 +++ assets/translations/de.json | 4 +++ assets/translations/en.json | 4 +++ assets/translations/es.json | 4 +++ assets/translations/fa.json | 4 +++ assets/translations/fr.json | 4 +++ assets/translations/hu.json | 4 +++ assets/translations/it.json | 4 +++ assets/translations/ja.json | 4 +++ assets/translations/nl.json | 4 +++ assets/translations/pl.json | 4 +++ assets/translations/pt.json | 4 +++ assets/translations/ru.json | 4 +++ assets/translations/sv.json | 4 +++ assets/translations/tr.json | 4 +++ assets/translations/vi.json | 4 +++ assets/translations/zh.json | 4 +++ lib/app_sources/directAPKLink.dart | 44 ++++++++++++++++++++++++++ lib/app_sources/html.dart | 51 +++++++++++++++++++----------- lib/providers/source_provider.dart | 16 ++++++++++ 21 files changed, 165 insertions(+), 18 deletions(-) create mode 100644 lib/app_sources/directAPKLink.dart diff --git a/assets/translations/bs.json b/assets/translations/bs.json index a83f1dd..6be1a39 100644 --- a/assets/translations/bs.json +++ b/assets/translations/bs.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Želite li ukloniti aplikaciju?", "other": "Želite li ukloniti aplikacije?" diff --git a/assets/translations/cs.json b/assets/translations/cs.json index f21663f..f4de726 100644 --- a/assets/translations/cs.json +++ b/assets/translations/cs.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Odstranit Apku?", "other": "Odstranit Apky?" diff --git a/assets/translations/de.json b/assets/translations/de.json index 119ba9c..84d148b 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -294,6 +294,10 @@ "useVersionCodeAsOSVersion": "Verwende die Appversion als erkannte Version vom Betriebssystem", "requestHeader": "Request Header", "useLatestAssetDateAsReleaseDate": "Den letzten Asset-Upload als Veröffentlichungsdatum verwenden", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "App entfernen?", "other": "Apps entfernen?" diff --git a/assets/translations/en.json b/assets/translations/en.json index 5907ccf..f6f3811 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -294,6 +294,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Remove App?", "other": "Remove Apps?" diff --git a/assets/translations/es.json b/assets/translations/es.json index e01f283..595e7d6 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "¿Eliminar Aplicación?", "other": "¿Eliminar Aplicaciones?" diff --git a/assets/translations/fa.json b/assets/translations/fa.json index fd52064..46ea68b 100644 --- a/assets/translations/fa.json +++ b/assets/translations/fa.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "استفاده کد نسخه برنامه به جای نسخه شناسایی شده توسط سیستم عامل استفاده کنید", "requestHeader": "درخواست سطر بالایی", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "برنامه حذف شود؟", "other": "برنامه ها حذف شوند؟" diff --git a/assets/translations/fr.json b/assets/translations/fr.json index ee33cf8..ed255e3 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Supprimer l'application ?", "other": "Supprimer les applications ?" diff --git a/assets/translations/hu.json b/assets/translations/hu.json index c6d8c47..c50e2b9 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Az app versionCode használata a rendszer által észlelt verzióként", "requestHeader": "Kérelem fejléc", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Eltávolítja az alkalmazást?", "other": "Eltávolítja az alkalmazást?" diff --git a/assets/translations/it.json b/assets/translations/it.json index ae5b7a9..e9de63c 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Rimuovere l'app?", "other": "Rimuovere le app?" diff --git a/assets/translations/ja.json b/assets/translations/ja.json index e2b4d38..eb459d6 100644 --- a/assets/translations/ja.json +++ b/assets/translations/ja.json @@ -294,6 +294,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "アプリを削除しますか?", "other": "アプリを削除しますか?" diff --git a/assets/translations/nl.json b/assets/translations/nl.json index 4f788d0..e0f4546 100644 --- a/assets/translations/nl.json +++ b/assets/translations/nl.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "App verwijderen?", "other": "Apps verwijderen?" diff --git a/assets/translations/pl.json b/assets/translations/pl.json index 44f2f9d..4fead4e 100644 --- a/assets/translations/pl.json +++ b/assets/translations/pl.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Usunąć aplikację?", "few": "Usunąć aplikacje?", diff --git a/assets/translations/pt.json b/assets/translations/pt.json index dc2370f..405aa74 100644 --- a/assets/translations/pt.json +++ b/assets/translations/pt.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Remover aplicativo?", "other": "Remover aplicativos?" diff --git a/assets/translations/ru.json b/assets/translations/ru.json index 2168990..ce680f7 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -294,6 +294,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Удалить приложение?", "other": "Удалить приложения?" diff --git a/assets/translations/sv.json b/assets/translations/sv.json index 157382f..58f8416 100644 --- a/assets/translations/sv.json +++ b/assets/translations/sv.json @@ -278,6 +278,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Ta Bort App?", "other": "Ta Bort Appar?" diff --git a/assets/translations/tr.json b/assets/translations/tr.json index 5ade2f2..cf655df 100644 --- a/assets/translations/tr.json +++ b/assets/translations/tr.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Uygulamayı Kaldır?", "other": "Uygulamaları Kaldır?" diff --git a/assets/translations/vi.json b/assets/translations/vi.json index eb20091..d3dfea4 100644 --- a/assets/translations/vi.json +++ b/assets/translations/vi.json @@ -290,6 +290,10 @@ "root": "Root", "shizukuBinderNotFound": "Shizuku chưa khởi động", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion":{ "one": "Gỡ ứng dụng?", "other": "Gỡ ứng dụng?" diff --git a/assets/translations/zh.json b/assets/translations/zh.json index d570125..993b130 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -294,6 +294,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "是否删除应用?", "other": "是否删除应用?" diff --git a/lib/app_sources/directAPKLink.dart b/lib/app_sources/directAPKLink.dart new file mode 100644 index 0000000..def21dd --- /dev/null +++ b/lib/app_sources/directAPKLink.dart @@ -0,0 +1,44 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:obtainium/app_sources/html.dart'; +import 'package:obtainium/providers/source_provider.dart'; + +class DirectAPKLink extends AppSource { + HTML html = HTML(); + + DirectAPKLink() { + neverAutoSelect = true; + name = tr('directAPKLink'); + additionalSourceAppSpecificSettingFormItems = html + .additionalSourceAppSpecificSettingFormItems + .where((element) => element + .where((element) => element.key == 'requestHeader') + .isNotEmpty) + .toList(); + excludeCommonSettingKeys = [ + 'versionExtractionRegEx', + 'matchGroupToUse', + 'versionDetection', + 'useVersionCodeAsOSVersion', + 'apkFilterRegEx', + 'autoApkFilterByArch' + ]; + } + + @override + Future getLatestAPKDetails( + String standardUrl, + Map additionalSettings, + ) async { + var additionalSettingsNew = + getDefaultValuesFromFormItems(html.combinedAppSpecificSettingFormItems); + for (var s in additionalSettings.keys) { + if (additionalSettingsNew.containsKey(s)) { + additionalSettingsNew[s] = additionalSettings[s]; + } + } + additionalSettingsNew['defaultPseudoVersioningMethod'] = 'partialAPKHash'; + additionalSettingsNew['directAPKLink'] = true; + additionalSettings['versionDetection'] = false; + return html.getLatestAPKDetails(standardUrl, additionalSettingsNew); + } +} diff --git a/lib/app_sources/html.dart b/lib/app_sources/html.dart index d13653a..fdb94a0 100644 --- a/lib/app_sources/html.dart +++ b/lib/app_sources/html.dart @@ -108,11 +108,7 @@ class HTML extends AppSource { [ GeneratedFormSwitch('versionExtractWholePage', label: tr('versionExtractWholePage')) - ], - [ - GeneratedFormSwitch('supportFixedAPKURL', - defaultValue: true, label: tr('supportFixedAPKURL')), - ], + ] ]; var commonFormItems = [ [GeneratedFormSwitch('filterByLinkText', label: tr('filterByLinkText'))], @@ -172,6 +168,16 @@ class HTML extends AppSource { 'User-Agent: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36' } ]) + ], + [ + GeneratedFormDropdown( + 'defaultPseudoVersioningMethod', + [ + MapEntry('partialAPKHash', tr('partialAPKHash')), + MapEntry('APKLinkHash', tr('APKLinkHash')) + ], + label: tr('defaultPseudoVersioningMethod'), + defaultValue: 'partialAPKHash') ] ]; } @@ -286,17 +292,25 @@ class HTML extends AppSource { currentUrl = intLinks.last.key; } } - var uri = Uri.parse(currentUrl); - Response res = await sourceRequest(currentUrl, additionalSettings); - var links = await grabLinksCommon(res, additionalSettings); + List> links = []; + String versionExtractionWholePageString = currentUrl; + if (additionalSettings['directAPKLink'] != true) { + Response res = await sourceRequest(currentUrl, additionalSettings); + versionExtractionWholePageString = + res.body.split('\r\n').join('\n').split('\n').join('\\n'); + links = await grabLinksCommon(res, additionalSettings); - if ((additionalSettings['apkFilterRegEx'] as String?)?.isNotEmpty == true) { - var reg = RegExp(additionalSettings['apkFilterRegEx']); - links = links.where((element) => reg.hasMatch(element.key)).toList(); - } - if (links.isEmpty) { - throw NoReleasesError(); + if ((additionalSettings['apkFilterRegEx'] as String?)?.isNotEmpty == + true) { + var reg = RegExp(additionalSettings['apkFilterRegEx']); + links = links.where((element) => reg.hasMatch(element.key)).toList(); + } + if (links.isEmpty) { + throw NoReleasesError(); + } + } else { + links = [MapEntry(currentUrl, currentUrl)]; } var rel = links.last.key; String? version; @@ -304,11 +318,12 @@ class HTML extends AppSource { additionalSettings['versionExtractionRegEx'] as String?, additionalSettings['matchGroupToUse'] as String?, additionalSettings['versionExtractWholePage'] == true - ? res.body.split('\r\n').join('\n').split('\n').join('\\n') + ? versionExtractionWholePageString : rel); - version ??= additionalSettings['supportFixedAPKURL'] != true - ? rel.hashCode.toString() - : (await checkPartialDownloadHashDynamc(rel)).toString(); + version ??= + additionalSettings['defaultPseudoVersioningMethod'] == 'APKLinkHash' + ? rel.hashCode.toString() + : (await checkPartialDownloadHashDynamc(rel)).toString(); return APKDetails(version, [rel].map((e) => MapEntry(e, e)).toList(), AppNames(uri.host, tr('app'))); } diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index ac6b284..b1a7242 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -11,6 +11,7 @@ import 'package:obtainium/app_sources/apkmirror.dart'; import 'package:obtainium/app_sources/apkpure.dart'; import 'package:obtainium/app_sources/aptoide.dart'; import 'package:obtainium/app_sources/codeberg.dart'; +import 'package:obtainium/app_sources/directAPKLink.dart'; import 'package:obtainium/app_sources/fdroid.dart'; import 'package:obtainium/app_sources/fdroidrepo.dart'; import 'package:obtainium/app_sources/github.dart'; @@ -112,6 +113,12 @@ appJSONCompatibilityModifiers(Map json) { additionalSettings['versionDetection'] = false; additionalSettings['releaseDateAsVersion'] = true; } + // Convert bool style pseudo version method to dropdown style + if (originalAdditionalSettings['supportFixedAPKURL'] == true) { + additionalSettings['defaultPseudoVersioningMethod'] = 'partialAPKHash'; + } else if (originalAdditionalSettings['supportFixedAPKURL'] == false) { + additionalSettings['defaultPseudoVersioningMethod'] = 'APKLinkHash'; + } // Ensure additionalSettings are correctly typed for (var item in formItems) { if (additionalSettings[item.key] != null) { @@ -391,6 +398,7 @@ abstract class AppSource { bool neverAutoSelect = false; bool showReleaseDateAsVersionToggle = false; bool versionDetectionDisallowed = false; + List excludeCommonSettingKeys = []; AppSource() { name = runtimeType.toString(); @@ -536,6 +544,13 @@ abstract class AppSource { ]); } } + additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly = + additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly + .map((e) => e + .where((ee) => !excludeCommonSettingKeys.contains(ee.key)) + .toList()) + .where((e) => e.isNotEmpty) + .toList(); if (versionDetectionDisallowed) { overrideAdditionalAppSpecificSourceAgnosticSettingSwitch( 'versionDetection', @@ -715,6 +730,7 @@ class SourceProvider { WhatsApp(), TelegramApp(), NeutronCode(), + DirectAPKLink(), HTML() // This should ALWAYS be the last option as they are tried in order ]; From e2761ce28438787fb5b641eac6c9064246a01da7 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 19 Jan 2024 19:57:28 -0500 Subject: [PATCH 09/16] UI improvements on app page --- assets/translations/bs.json | 3 + assets/translations/cs.json | 3 + assets/translations/de.json | 3 + assets/translations/en.json | 3 + assets/translations/es.json | 3 + assets/translations/fa.json | 3 + assets/translations/fr.json | 3 + assets/translations/hu.json | 3 + assets/translations/it.json | 3 + assets/translations/ja.json | 3 + assets/translations/nl.json | 3 + assets/translations/pl.json | 3 + assets/translations/pt.json | 3 + assets/translations/ru.json | 3 + assets/translations/sv.json | 3 + assets/translations/tr.json | 3 + assets/translations/vi.json | 3 + assets/translations/zh.json | 3 + lib/components/generated_form.dart | 112 +++++++------- lib/pages/app.dart | 230 ++++++++++++++--------------- 20 files changed, 230 insertions(+), 166 deletions(-) diff --git a/assets/translations/bs.json b/assets/translations/bs.json index 6be1a39..132c2aa 100644 --- a/assets/translations/bs.json +++ b/assets/translations/bs.json @@ -296,6 +296,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "Želite li ukloniti aplikaciju?", "other": "Želite li ukloniti aplikacije?" diff --git a/assets/translations/cs.json b/assets/translations/cs.json index f4de726..92b5fef 100644 --- a/assets/translations/cs.json +++ b/assets/translations/cs.json @@ -296,6 +296,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "Odstranit Apku?", "other": "Odstranit Apky?" diff --git a/assets/translations/de.json b/assets/translations/de.json index 84d148b..d2abb03 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -298,6 +298,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "App entfernen?", "other": "Apps entfernen?" diff --git a/assets/translations/en.json b/assets/translations/en.json index f6f3811..7f801e1 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -298,6 +298,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "Remove App?", "other": "Remove Apps?" diff --git a/assets/translations/es.json b/assets/translations/es.json index 595e7d6..d8d2d8b 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -296,6 +296,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "¿Eliminar Aplicación?", "other": "¿Eliminar Aplicaciones?" diff --git a/assets/translations/fa.json b/assets/translations/fa.json index 46ea68b..4d35fc9 100644 --- a/assets/translations/fa.json +++ b/assets/translations/fa.json @@ -296,6 +296,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "برنامه حذف شود؟", "other": "برنامه ها حذف شوند؟" diff --git a/assets/translations/fr.json b/assets/translations/fr.json index ed255e3..6d17bd1 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -296,6 +296,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "Supprimer l'application ?", "other": "Supprimer les applications ?" diff --git a/assets/translations/hu.json b/assets/translations/hu.json index c50e2b9..ba7940a 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -296,6 +296,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "Eltávolítja az alkalmazást?", "other": "Eltávolítja az alkalmazást?" diff --git a/assets/translations/it.json b/assets/translations/it.json index e9de63c..1a8205b 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -296,6 +296,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "Rimuovere l'app?", "other": "Rimuovere le app?" diff --git a/assets/translations/ja.json b/assets/translations/ja.json index eb459d6..c15b127 100644 --- a/assets/translations/ja.json +++ b/assets/translations/ja.json @@ -298,6 +298,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "アプリを削除しますか?", "other": "アプリを削除しますか?" diff --git a/assets/translations/nl.json b/assets/translations/nl.json index e0f4546..e8b13cf 100644 --- a/assets/translations/nl.json +++ b/assets/translations/nl.json @@ -296,6 +296,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "App verwijderen?", "other": "Apps verwijderen?" diff --git a/assets/translations/pl.json b/assets/translations/pl.json index 4fead4e..7ed2a48 100644 --- a/assets/translations/pl.json +++ b/assets/translations/pl.json @@ -296,6 +296,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "Usunąć aplikację?", "few": "Usunąć aplikacje?", diff --git a/assets/translations/pt.json b/assets/translations/pt.json index 405aa74..9169f95 100644 --- a/assets/translations/pt.json +++ b/assets/translations/pt.json @@ -296,6 +296,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "Remover aplicativo?", "other": "Remover aplicativos?" diff --git a/assets/translations/ru.json b/assets/translations/ru.json index ce680f7..dbbaaaf 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -298,6 +298,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "Удалить приложение?", "other": "Удалить приложения?" diff --git a/assets/translations/sv.json b/assets/translations/sv.json index 58f8416..eb91710 100644 --- a/assets/translations/sv.json +++ b/assets/translations/sv.json @@ -282,6 +282,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "Ta Bort App?", "other": "Ta Bort Appar?" diff --git a/assets/translations/tr.json b/assets/translations/tr.json index cf655df..1d1720a 100644 --- a/assets/translations/tr.json +++ b/assets/translations/tr.json @@ -296,6 +296,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "Uygulamayı Kaldır?", "other": "Uygulamaları Kaldır?" diff --git a/assets/translations/vi.json b/assets/translations/vi.json index d3dfea4..c8f9c5f 100644 --- a/assets/translations/vi.json +++ b/assets/translations/vi.json @@ -294,6 +294,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion":{ "one": "Gỡ ứng dụng?", "other": "Gỡ ứng dụng?" diff --git a/assets/translations/zh.json b/assets/translations/zh.json index 993b130..2c5470c 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -298,6 +298,9 @@ "partialAPKHash": "Partial APK Hash", "APKLinkHash": "APK Link Hash", "directAPKLink": "Direct APK Link", + "pseudoVersionInUse": "A Pseudo-Version is in Use", + "installed": "Installed", + "latest": "Latest", "removeAppQuestion": { "one": "是否删除应用?", "other": "是否删除应用?" diff --git a/lib/components/generated_form.dart b/lib/components/generated_form.dart index 0882f45..c8d059a 100644 --- a/lib/components/generated_form.dart +++ b/lib/components/generated_form.dart @@ -384,6 +384,39 @@ class _GeneratedFormState extends State { ], ); } else if (widget.items[r][e] is GeneratedFormTagInput) { + onAddPressed() { + showDialog?>( + context: context, + builder: (BuildContext ctx) { + return GeneratedFormModal( + title: widget.items[r][e].label, + items: [ + [GeneratedFormTextField('label', label: tr('label'))] + ]); + }).then((value) { + String? label = value?['label']; + if (label != null) { + setState(() { + var temp = + values[fieldKey] as Map>?; + temp ??= {}; + if (temp[label] == null) { + var singleSelect = + (widget.items[r][e] as GeneratedFormTagInput) + .singleSelect; + var someSelected = temp.entries + .where((element) => element.value.value) + .isNotEmpty; + temp[label] = MapEntry(generateRandomLightColor().value, + !(someSelected && singleSelect)); + values[fieldKey] = temp; + someValueChanged(); + } + }); + } + }); + } + formInputs[r][e] = Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [ if ((values[fieldKey] as Map>?) @@ -409,14 +442,14 @@ class _GeneratedFormState extends State { (widget.items[r][e] as GeneratedFormTagInput).alignment, crossAxisAlignment: WrapCrossAlignment.center, children: [ - (values[fieldKey] as Map>?) - ?.isEmpty == - true - ? Text( - (widget.items[r][e] as GeneratedFormTagInput) - .emptyMessage, - ) - : const SizedBox.shrink(), + // (values[fieldKey] as Map>?) + // ?.isEmpty == + // true + // ? Text( + // (widget.items[r][e] as GeneratedFormTagInput) + // .emptyMessage, + // ) + // : const SizedBox.shrink(), ...(values[fieldKey] as Map>?) ?.entries .map((e2) { @@ -540,49 +573,26 @@ class _GeneratedFormState extends State { tooltip: tr('remove'), )) : const SizedBox.shrink(), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 4), - child: IconButton( - onPressed: () { - showDialog?>( - context: context, - builder: (BuildContext ctx) { - return GeneratedFormModal( - title: widget.items[r][e].label, - items: [ - [ - GeneratedFormTextField('label', - label: tr('label')) - ] - ]); - }).then((value) { - String? label = value?['label']; - if (label != null) { - setState(() { - var temp = values[fieldKey] - as Map>?; - temp ??= {}; - if (temp[label] == null) { - var singleSelect = (widget.items[r][e] - as GeneratedFormTagInput) - .singleSelect; - var someSelected = temp.entries - .where((element) => element.value.value) - .isNotEmpty; - temp[label] = MapEntry( - generateRandomLightColor().value, - !(someSelected && singleSelect)); - values[fieldKey] = temp; - someValueChanged(); - } - }); - } - }); - }, - icon: const Icon(Icons.add), - visualDensity: VisualDensity.compact, - tooltip: tr('add'), - )), + (values[fieldKey] as Map>?) + ?.isEmpty == + true + ? Padding( + padding: const EdgeInsets.symmetric(horizontal: 4), + child: TextButton.icon( + onPressed: onAddPressed, + icon: const Icon(Icons.add), + label: Text( + (widget.items[r][e] as GeneratedFormTagInput) + .label), + )) + : Padding( + padding: const EdgeInsets.symmetric(horizontal: 4), + child: IconButton( + onPressed: onAddPressed, + icon: const Icon(Icons.add), + visualDensity: VisualDensity.compact, + tooltip: tr('add'), + )), ], ) ]); diff --git a/lib/pages/app.dart b/lib/pages/app.dart index f603e37..ab957e7 100644 --- a/lib/pages/app.dart +++ b/lib/pages/app.dart @@ -69,112 +69,107 @@ class _AppPageState extends State { (app?.app.installedVersion != null && app?.app.additionalSettings['versionDetection'] != true); - getInfoColumn() => Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - GestureDetector( - onTap: () { - if (app?.app.url != null) { - launchUrlString(app?.app.url ?? '', - mode: LaunchMode.externalApplication); - } - }, - onLongPress: () { - Clipboard.setData(ClipboardData(text: app?.app.url ?? '')); - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text(tr('copiedToClipboard')), - )); - }, - child: Text( - app?.app.url ?? '', - textAlign: TextAlign.center, - style: const TextStyle( - decoration: TextDecoration.underline, - fontStyle: FontStyle.italic, - fontSize: 12), - )), - const SizedBox( - height: 32, - ), - Column( + getInfoColumn() { + String versionLines = ''; + bool installed = app?.app.installedVersion != null; + bool upToDate = app?.app.installedVersion == app?.app.latestVersion; + if (installed) { + versionLines = '${app?.app.installedVersion} ${tr('installed')}'; + if (upToDate) { + versionLines += '/${tr('latest')}'; + } + } else { + versionLines = tr('notInstalled'); + } + if (!upToDate) { + versionLines += '\n${app?.app.latestVersion} ${tr('latest')}'; + } + String infoLines = tr('lastUpdateCheckX', args: [ + app?.app.lastUpdateCheck == null + ? tr('never') + : '${app?.app.lastUpdateCheck?.toLocal()}' + ]); + if (trackOnly) { + infoLines = '${tr('xIsTrackOnly', args: [tr('app')])}\n$infoLines'; + } + if (installedVersionIsEstimate) { + infoLines = '${tr('pseudoVersionInUse')}\n$infoLines'; + } + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 24), + child: Column( children: [ - Text( - '${tr('latestVersionX', args: [ - app?.app.latestVersion ?? tr('unknown') - ])}\n${tr('installedVersionX', args: [ - app?.app.installedVersion ?? tr('none') - ])}${installedVersionIsEstimate ? '\n(${tr('pseudoVersion')})' : ''}', - textAlign: TextAlign.end, - style: Theme.of(context).textTheme.bodyLarge!, + const SizedBox( + height: 8, + ), + Text(versionLines, + textAlign: TextAlign.start, + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith(fontWeight: FontWeight.bold)), + app?.app.releaseDate == null + ? const SizedBox.shrink() + : Text( + app!.app.releaseDate.toString(), + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.labelSmall, + ), + const SizedBox( + height: 8, ), ], ), - if (app?.app.installedVersion != null && - !isVersionDetectionStandard) - Column( - children: [ - const SizedBox( - height: 16, - ), - Text( - trackOnly ? tr('xIsTrackOnly', args: [tr('app')]) : '', - style: Theme.of(context).textTheme.labelSmall, + ), + Text( + infoLines, + textAlign: TextAlign.center, + style: const TextStyle(fontStyle: FontStyle.italic, fontSize: 12), + ), + const SizedBox( + height: 48, + ), + CategoryEditorSelector( + alignment: WrapAlignment.center, + preselected: app?.app.categories != null + ? app!.app.categories.toSet() + : {}, + onSelected: (categories) { + if (app != null) { + app.app.categories = categories; + appsProvider.saveApps([app.app]); + } + }), + if (app?.app.additionalSettings['about'] is String && + app?.app.additionalSettings['about'].isNotEmpty) + Column( + children: [ + const SizedBox( + height: 48, + ), + GestureDetector( + onLongPress: () { + Clipboard.setData(ClipboardData( + text: app?.app.additionalSettings['about'] ?? '')); + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: Text(tr('copiedToClipboard')), + )); + }, + child: Text( + app?.app.additionalSettings['about'], textAlign: TextAlign.center, - ) - ], - ), - const SizedBox( - height: 32, - ), - Text( - tr('lastUpdateCheckX', args: [ - app?.app.lastUpdateCheck == null - ? tr('never') - : '\n${app?.app.lastUpdateCheck?.toLocal()}' - ]), - textAlign: TextAlign.center, - style: const TextStyle(fontStyle: FontStyle.italic, fontSize: 12), - ), - const SizedBox( - height: 48, - ), - CategoryEditorSelector( - alignment: WrapAlignment.center, - preselected: app?.app.categories != null - ? app!.app.categories.toSet() - : {}, - onSelected: (categories) { - if (app != null) { - app.app.categories = categories; - appsProvider.saveApps([app.app]); - } - }), - if (app?.app.additionalSettings['about'] is String && - app?.app.additionalSettings['about'].isNotEmpty) - Column( - children: [ - const SizedBox( - height: 48, + style: const TextStyle(fontStyle: FontStyle.italic), ), - GestureDetector( - onLongPress: () { - Clipboard.setData(ClipboardData( - text: app?.app.additionalSettings['about'] ?? '')); - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text(tr('copiedToClipboard')), - )); - }, - child: Text( - app?.app.additionalSettings['about'], - textAlign: TextAlign.center, - style: const TextStyle(fontStyle: FontStyle.italic), - ), - ) - ], - ), - ], - ); + ) + ], + ), + ], + ); + } getFullInfoColumn() => Column( mainAxisAlignment: MainAxisAlignment.center, @@ -201,11 +196,26 @@ class _AppPageState extends State { textAlign: TextAlign.center, style: Theme.of(context).textTheme.displayLarge, ), - Text( - tr('byX', args: [app?.app.author ?? tr('unknown')]), - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.headlineMedium, - ), + GestureDetector( + onTap: () { + if (app?.app.url != null) { + launchUrlString(app?.app.url ?? '', + mode: LaunchMode.externalApplication); + } + }, + onLongPress: () { + Clipboard.setData(ClipboardData(text: app?.app.url ?? '')); + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: Text(tr('copiedToClipboard')), + )); + }, + child: Text( + tr('byX', args: [app?.app.author ?? tr('unknown')]), + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.headlineMedium!.copyWith( + decoration: TextDecoration.underline, + fontStyle: FontStyle.italic), + )), const SizedBox( height: 8, ), @@ -214,16 +224,6 @@ class _AppPageState extends State { textAlign: TextAlign.center, style: Theme.of(context).textTheme.labelSmall, ), - app?.app.releaseDate == null - ? const SizedBox.shrink() - : Text( - app!.app.releaseDate.toString(), - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.labelSmall, - ), - const SizedBox( - height: 32, - ), getInfoColumn(), const SizedBox(height: 150) ], From 29a76ac8e63720b6bac976801b083d8d88f9e0fc Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 19 Jan 2024 19:59:30 -0500 Subject: [PATCH 10/16] Removed unused divider and commented code on settings page --- lib/pages/settings.dart | 49 ++++++++++------------------------------- 1 file changed, 12 insertions(+), 37 deletions(-) diff --git a/lib/pages/settings.dart b/lib/pages/settings.dart index 4e0d69b..61fd7d6 100644 --- a/lib/pages/settings.dart +++ b/lib/pages/settings.dart @@ -416,13 +416,17 @@ class _SettingsPageState extends State { value: settingsProvider.useSystemFont, onChanged: (useSystemFont) { if (useSystemFont) { - NativeFeatures.loadSystemFont().then((fontLoadRes) { + NativeFeatures.loadSystemFont() + .then((fontLoadRes) { if (fontLoadRes == 'ok') { - settingsProvider.useSystemFont = true; + settingsProvider.useSystemFont = + true; } else { - showError(ObtainiumError( - tr('systemFontError', args: [fontLoadRes]) - ), context); + showError( + ObtainiumError(tr( + 'systemFontError', + args: [fontLoadRes])), + context); } }); } else { @@ -628,38 +632,9 @@ class _SettingsPageState extends State { label: Text(tr('appLogs'))), ], ), - const Divider( - height: 32, - ), - // Padding( - // padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), - // child: Column(children: [ - // Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // children: [ - // Flexible(child: Text(tr('debugMenu'))), - // Switch( - // value: settingsProvider.showDebugOpts, - // onChanged: (value) { - // settingsProvider.showDebugOpts = value; - // }) - // ], - // ), - // if (settingsProvider.showDebugOpts) - // Column( - // crossAxisAlignment: CrossAxisAlignment.stretch, - // children: [ - // height16, - // TextButton( - // onPressed: () { - // bgUpdateCheck('taskId', null); - // showMessage(tr('bgTaskStarted'), context); - // }, - // child: Text(tr('runBgCheckNow'))) - // ], - // ), - // ]), - // ), + const SizedBox( + height: 16, + ) ], ), ) From 4ab4f58f6544ff8cc3203fea02e5aa7cf0476e28 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 19 Jan 2024 20:35:44 -0500 Subject: [PATCH 11/16] Cleaner 'add app' page --- lib/pages/add_app.dart | 82 ++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/lib/pages/add_app.dart b/lib/pages/add_app.dart index d504901..c756d92 100644 --- a/lib/pages/add_app.dart +++ b/lib/pages/add_app.dart @@ -496,36 +496,59 @@ class AddAppPageState extends State { ], ); - Widget getSourcesListWidget() => Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, + Widget getSourcesListWidget() => Padding( + padding: const EdgeInsets.all(16), + child: Row( children: [ - Text( - tr('supportedSources'), - style: const TextStyle(fontWeight: FontWeight.bold), - ), - const SizedBox( - height: 16, - ), - ...sourceProvider.sources.map((e) => GestureDetector( - onTap: e.hosts.isNotEmpty - ? () { - launchUrlString('https://${e.hosts[0]}', - mode: LaunchMode.externalApplication); - } - : null, + GestureDetector( + onTap: () { + showDialog( + context: context, + builder: (context) { + return GeneratedFormModal( + title: tr('supportedSources'), + items: const [], + additionalWidgets: [ + ...sourceProvider.sources.map( + (e) => Padding( + padding: EdgeInsets.symmetric(vertical: 4), + child: GestureDetector( + onTap: e.hosts.isNotEmpty + ? () { + launchUrlString( + 'https://${e.hosts[0]}', + mode: LaunchMode + .externalApplication); + } + : null, + child: Text( + '${e.name}${e.enforceTrackOnly ? ' ${tr('trackOnlyInBrackets')}' : ''}${e.canSearch ? ' ${tr('searchableInBrackets')}' : ''}', + style: TextStyle( + decoration: e.hosts.isNotEmpty + ? TextDecoration.underline + : TextDecoration.none), + ))), + ) + ], + ); + }, + ); + }, child: Text( - '${e.name}${e.enforceTrackOnly ? ' ${tr('trackOnlyInBrackets')}' : ''}${e.canSearch ? ' ${tr('searchableInBrackets')}' : ''}', - style: TextStyle( - decoration: e.hosts.isNotEmpty - ? TextDecoration.underline - : TextDecoration.none, + tr('supportedSources'), + style: const TextStyle( + fontWeight: FontWeight.bold, + decoration: TextDecoration.underline, fontStyle: FontStyle.italic), - ))) - ]); + )) + ], + ), + ); return Scaffold( backgroundColor: Theme.of(context).colorScheme.surface, + bottomNavigationBar: + pickedSource == null ? getSourcesListWidget() : null, body: CustomScrollView(shrinkWrap: true, slivers: [ CustomAppBar(title: tr('addApp')), SliverToBoxAdapter( @@ -557,18 +580,7 @@ class AddAppPageState extends State { : const SizedBox(); }, future: pickedSource?.getSourceNote()), - SizedBox( - height: pickedSource != null ? 16 : 96, - ), if (pickedSource != null) getAdditionalOptsCol(), - if (pickedSource == null) - const Divider( - height: 48, - ), - if (pickedSource == null) getSourcesListWidget(), - SizedBox( - height: pickedSource != null ? 8 : 2, - ), ])), ) ])); From bf6b3a7da0b21587934da280df8490c2a4494e9b Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 19 Jan 2024 20:36:40 -0500 Subject: [PATCH 12/16] UI bug --- lib/pages/add_app.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/pages/add_app.dart b/lib/pages/add_app.dart index c756d92..820e08d 100644 --- a/lib/pages/add_app.dart +++ b/lib/pages/add_app.dart @@ -506,12 +506,14 @@ class AddAppPageState extends State { context: context, builder: (context) { return GeneratedFormModal( + singleNullReturnButton: tr('ok'), title: tr('supportedSources'), items: const [], additionalWidgets: [ ...sourceProvider.sources.map( (e) => Padding( - padding: EdgeInsets.symmetric(vertical: 4), + padding: + const EdgeInsets.symmetric(vertical: 4), child: GestureDetector( onTap: e.hosts.isNotEmpty ? () { From 99da1f8481c731d0e3295f83744be472173429a1 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 19 Jan 2024 20:41:07 -0500 Subject: [PATCH 13/16] Upgrade packages, increment version --- pubspec.lock | 48 ++++++++++++++++++++++++------------------------ pubspec.yaml | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index aeed1b5..4052d77 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -307,10 +307,10 @@ packages: dependency: "direct main" description: name: flutter_local_notifications - sha256: "892ada16046d641263f30c72e7432397088810a84f34479f6677494802a2b535" + sha256: "66cc2fe16bf4bca71d795939763ad3f1830ad85772dc3b1561613c501859826d" url: "https://pub.dev" source: hosted - version: "16.3.0" + version: "16.3.1+1" flutter_local_notifications_linux: dependency: transitive description: @@ -394,10 +394,10 @@ packages: dependency: "direct main" description: name: http - sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.0" http_parser: dependency: transitive description: @@ -450,10 +450,10 @@ packages: dependency: transitive description: name: markdown - sha256: acf35edccc0463a9d7384e437c015a3535772e09714cf60e07eeef3a15870dcd + sha256: "1b134d9f8ff2da15cb298efe6cd8b7d2a78958c1b00384ebcbdf13fe340a6c90" url: "https://pub.dev" source: hosted - version: "7.1.1" + version: "7.2.1" matcher: dependency: transitive description: @@ -562,50 +562,50 @@ packages: dependency: "direct main" description: name: permission_handler - sha256: "860c6b871c94c78e202dc69546d4d8fd84bd59faeb36f8fb9888668a53ff4f78" + sha256: "45ff3fbcb99040fde55c528d5e3e6ca29171298a85436274d49c6201002087d6" url: "https://pub.dev" source: hosted - version: "11.1.0" + version: "11.2.0" permission_handler_android: dependency: transitive description: name: permission_handler_android - sha256: "2f1bec180ee2f5665c22faada971a8f024761f632e93ddc23310487df52dcfa6" + sha256: "758284a0976772f9c744d6384fc5dc4834aa61e3f7aa40492927f244767374eb" url: "https://pub.dev" source: hosted - version: "12.0.1" + version: "12.0.3" permission_handler_apple: dependency: transitive description: name: permission_handler_apple - sha256: "1a816084338ada8d574b1cb48390e6e8b19305d5120fe3a37c98825bacc78306" + sha256: c6bf440f80acd2a873d3d91a699e4cc770f86e7e6b576dda98759e8b92b39830 url: "https://pub.dev" source: hosted - version: "9.2.0" + version: "9.3.0" permission_handler_html: dependency: transitive description: name: permission_handler_html - sha256: "11b762a8c123dced6461933a88ea1edbbe036078c3f9f41b08886e678e7864df" + sha256: "54bf176b90f6eddd4ece307e2c06cf977fb3973719c35a93b85cc7093eb6070d" url: "https://pub.dev" source: hosted - version: "0.1.0+2" + version: "0.1.1" permission_handler_platform_interface: dependency: transitive description: name: permission_handler_platform_interface - sha256: d87349312f7eaf6ce0adaf668daf700ac5b06af84338bd8b8574dfbd93ffe1a1 + sha256: "5c43148f2bfb6d14c5a8162c0a712afe891f2d847f35fcff29c406b37da43c3c" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.1.0" permission_handler_windows: dependency: transitive description: name: permission_handler_windows - sha256: "1e8640c1e39121128da6b816d236e714d2cf17fac5a105dd6acdd3403a628004" + sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.2.1" petitparser: dependency: transitive description: @@ -634,10 +634,10 @@ packages: dependency: transitive description: name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" url: "https://pub.dev" source: hosted - version: "3.7.3" + version: "3.7.4" provider: dependency: "direct main" description: @@ -943,10 +943,10 @@ packages: dependency: transitive description: name: webview_flutter_wkwebview - sha256: "4d062ad505390ecef1c4bfb6001cd857a51e00912cc9dfb66edb1886a9ebd80c" + sha256: b99ca8d8bae9c6b43d568218691aa537fb0aeae1d7d34eadf112a6aa36d26506 url: "https://pub.dev" source: hosted - version: "3.10.2" + version: "3.11.0" win32: dependency: transitive description: @@ -988,5 +988,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.2.0 <4.0.0" - flutter: ">=3.16.0" + dart: ">=3.2.3 <4.0.0" + flutter: ">=3.16.6" diff --git a/pubspec.yaml b/pubspec.yaml index a4a262b..8bd0278 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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.15.11+247 # When changing this, update the tag in main() accordingly +version: 0.16.0+248 # When changing this, update the tag in main() accordingly environment: sdk: '>=3.0.0 <4.0.0' From c31a1912a5770169dce859df9d294a298593f12f Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 19 Jan 2024 23:22:00 -0500 Subject: [PATCH 14/16] Add invert option to apk filter regex --- assets/translations/bs.json | 1 + assets/translations/cs.json | 1 + assets/translations/de.json | 1 + assets/translations/en.json | 1 + assets/translations/es.json | 1 + assets/translations/fa.json | 1 + assets/translations/fr.json | 1 + assets/translations/hu.json | 1 + assets/translations/it.json | 1 + assets/translations/ja.json | 1 + assets/translations/nl.json | 1 + assets/translations/pl.json | 1 + assets/translations/pt.json | 1 + assets/translations/ru.json | 1 + assets/translations/sv.json | 1 + assets/translations/tr.json | 1 + assets/translations/vi.json | 1 + assets/translations/zh.json | 1 + lib/app_sources/github.dart | 7 ++----- lib/app_sources/html.dart | 8 ++------ lib/providers/source_provider.dart | 26 +++++++++++++++++++++----- 21 files changed, 43 insertions(+), 16 deletions(-) diff --git a/assets/translations/bs.json b/assets/translations/bs.json index 132c2aa..c68ac07 100644 --- a/assets/translations/bs.json +++ b/assets/translations/bs.json @@ -299,6 +299,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "Želite li ukloniti aplikaciju?", "other": "Želite li ukloniti aplikacije?" diff --git a/assets/translations/cs.json b/assets/translations/cs.json index 92b5fef..9dfac99 100644 --- a/assets/translations/cs.json +++ b/assets/translations/cs.json @@ -299,6 +299,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "Odstranit Apku?", "other": "Odstranit Apky?" diff --git a/assets/translations/de.json b/assets/translations/de.json index d2abb03..fe843d4 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -301,6 +301,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "App entfernen?", "other": "Apps entfernen?" diff --git a/assets/translations/en.json b/assets/translations/en.json index 7f801e1..e17fd51 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -301,6 +301,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "Remove App?", "other": "Remove Apps?" diff --git a/assets/translations/es.json b/assets/translations/es.json index d8d2d8b..9b3601e 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -299,6 +299,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "¿Eliminar Aplicación?", "other": "¿Eliminar Aplicaciones?" diff --git a/assets/translations/fa.json b/assets/translations/fa.json index 4d35fc9..439d540 100644 --- a/assets/translations/fa.json +++ b/assets/translations/fa.json @@ -299,6 +299,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "برنامه حذف شود؟", "other": "برنامه ها حذف شوند؟" diff --git a/assets/translations/fr.json b/assets/translations/fr.json index 6d17bd1..2524274 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -299,6 +299,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "Supprimer l'application ?", "other": "Supprimer les applications ?" diff --git a/assets/translations/hu.json b/assets/translations/hu.json index ba7940a..37388f2 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -299,6 +299,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "Eltávolítja az alkalmazást?", "other": "Eltávolítja az alkalmazást?" diff --git a/assets/translations/it.json b/assets/translations/it.json index 1a8205b..179fa00 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -299,6 +299,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "Rimuovere l'app?", "other": "Rimuovere le app?" diff --git a/assets/translations/ja.json b/assets/translations/ja.json index c15b127..375a286 100644 --- a/assets/translations/ja.json +++ b/assets/translations/ja.json @@ -301,6 +301,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "アプリを削除しますか?", "other": "アプリを削除しますか?" diff --git a/assets/translations/nl.json b/assets/translations/nl.json index e8b13cf..25c50ec 100644 --- a/assets/translations/nl.json +++ b/assets/translations/nl.json @@ -299,6 +299,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "App verwijderen?", "other": "Apps verwijderen?" diff --git a/assets/translations/pl.json b/assets/translations/pl.json index 7ed2a48..323a737 100644 --- a/assets/translations/pl.json +++ b/assets/translations/pl.json @@ -299,6 +299,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "Usunąć aplikację?", "few": "Usunąć aplikacje?", diff --git a/assets/translations/pt.json b/assets/translations/pt.json index 9169f95..fcd899f 100644 --- a/assets/translations/pt.json +++ b/assets/translations/pt.json @@ -299,6 +299,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "Remover aplicativo?", "other": "Remover aplicativos?" diff --git a/assets/translations/ru.json b/assets/translations/ru.json index dbbaaaf..3f12321 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -301,6 +301,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "Удалить приложение?", "other": "Удалить приложения?" diff --git a/assets/translations/sv.json b/assets/translations/sv.json index eb91710..404fa9d 100644 --- a/assets/translations/sv.json +++ b/assets/translations/sv.json @@ -285,6 +285,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "Ta Bort App?", "other": "Ta Bort Appar?" diff --git a/assets/translations/tr.json b/assets/translations/tr.json index 1d1720a..debb8cf 100644 --- a/assets/translations/tr.json +++ b/assets/translations/tr.json @@ -299,6 +299,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "Uygulamayı Kaldır?", "other": "Uygulamaları Kaldır?" diff --git a/assets/translations/vi.json b/assets/translations/vi.json index c8f9c5f..eb90c3c 100644 --- a/assets/translations/vi.json +++ b/assets/translations/vi.json @@ -297,6 +297,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion":{ "one": "Gỡ ứng dụng?", "other": "Gỡ ứng dụng?" diff --git a/assets/translations/zh.json b/assets/translations/zh.json index 2c5470c..391c429 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -301,6 +301,7 @@ "pseudoVersionInUse": "A Pseudo-Version is in Use", "installed": "Installed", "latest": "Latest", + "invertRegEx": "Invert regular expression", "removeAppQuestion": { "one": "是否删除应用?", "other": "是否删除应用?" diff --git a/lib/app_sources/github.dart b/lib/app_sources/github.dart index e510014..151e159 100644 --- a/lib/app_sources/github.dart +++ b/lib/app_sources/github.dart @@ -382,11 +382,8 @@ class GitHub extends AppSource { continue; } var apkUrls = getReleaseAPKUrls(releases[i]); - if (additionalSettings['apkFilterRegEx'] != null) { - var reg = RegExp(additionalSettings['apkFilterRegEx']); - apkUrls = - apkUrls.where((element) => reg.hasMatch(element.key)).toList(); - } + apkUrls = filterApks(apkUrls, additionalSettings['apkFilterRegEx'], + additionalSettings['invertAPKFilter']); if (apkUrls.isEmpty && additionalSettings['trackOnly'] != true) { continue; } diff --git a/lib/app_sources/html.dart b/lib/app_sources/html.dart index fdb94a0..db413ec 100644 --- a/lib/app_sources/html.dart +++ b/lib/app_sources/html.dart @@ -300,12 +300,8 @@ class HTML extends AppSource { versionExtractionWholePageString = res.body.split('\r\n').join('\n').split('\n').join('\\n'); links = await grabLinksCommon(res, additionalSettings); - - if ((additionalSettings['apkFilterRegEx'] as String?)?.isNotEmpty == - true) { - var reg = RegExp(additionalSettings['apkFilterRegEx']); - links = links.where((element) => reg.hasMatch(element.key)).toList(); - } + links = filterApks(links, additionalSettings['apkFilterRegEx'], + additionalSettings['invertAPKFilter']); if (links.isEmpty) { throw NoReleasesError(); } diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index b1a7242..7930840 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -504,6 +504,11 @@ abstract class AppSource { } ]) ], + [ + GeneratedFormSwitch('invertAPKFilter', + label: '${tr('invertRegEx')} (${tr('filterAPKsByRegEx')})', + defaultValue: false) + ], [ GeneratedFormSwitch('autoApkFilterByArch', label: tr('autoApkFilterByArch'), defaultValue: true) @@ -708,6 +713,20 @@ String? extractVersion(String? versionExtractionRegEx, String? matchGroupString, } } +List> filterApks( + List> apkUrls, + String? apkFilterRegEx, + bool? invert) { + if (apkFilterRegEx?.isNotEmpty == true) { + var reg = RegExp(apkFilterRegEx!); + apkUrls = apkUrls.where((element) { + var hasMatch = reg.hasMatch(element.key); + return invert == true ? !hasMatch : hasMatch; + }).toList(); + } + return apkUrls; +} + class SourceProvider { // Add more source classes here so they are available via the service List get sources => [ @@ -825,11 +844,8 @@ class SourceProvider { apk.releaseDate != null) { apk.version = apk.releaseDate!.microsecondsSinceEpoch.toString(); } - if (additionalSettings['apkFilterRegEx'] != null) { - var reg = RegExp(additionalSettings['apkFilterRegEx']); - apk.apkUrls = - apk.apkUrls.where((element) => reg.hasMatch(element.key)).toList(); - } + apk.apkUrls = filterApks(apk.apkUrls, additionalSettings['apkFilterRegEx'], + additionalSettings['invertAPKFilter']); if (apk.apkUrls.isEmpty && !trackOnly) { throw NoAPKError(); } From 95c285e1f7eea1afce0b19970490d8432459b880 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 19 Jan 2024 23:25:00 -0500 Subject: [PATCH 15/16] Filter out fdroid APKs from default Obtainium entry --- lib/main.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index 683db9c..52538d4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -183,7 +183,12 @@ class _ObtainiumState extends State { value.versionName!, [], 0, - {'includePrereleases': true, 'versionDetection': true}, + { + 'includePrereleases': true, + 'versionDetection': true, + 'apkFilterRegEx': 'fdroid', + 'invertAPKFilter': true + }, null, false) ], onlyIfExists: false); From ad4cae42887cc14febc347773a0fce0bb72daabd Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 19 Jan 2024 23:29:22 -0500 Subject: [PATCH 16/16] Add F-Droid build to GitHub action --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a3f6101..d3b5a05 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,6 +39,7 @@ jobs: sed -i 's/signingConfig signingConfigs.release//g' android/app/build.gradle flutter build apk --flavor normal && flutter build apk --split-per-abi --flavor normal for file in build/app/outputs/flutter-apk/app-*normal*.apk*; do mv "$file" "${file//-normal/}"; done + flutter build apk --flavor fdroid -t lib/main_fdroid.dart && flutter build apk --split-per-abi --flavor fdroid -t lib/main_fdroid.dart rm ./build/app/outputs/flutter-apk/*.sha1 ls -l ./build/app/outputs/flutter-apk/