Merge branch 'main' into re7gog

# Conflicts:
#	pubspec.lock
This commit is contained in:
Gregory Velichko
2024-04-19 18:07:51 +03:00
12 changed files with 166 additions and 110 deletions

View File

@@ -4,11 +4,13 @@
Get Android App Updates Directly From the Source.
Obtainium allows you to install and update Apps directly from their releases pages, and receive notifications when new releases are made available.
Obtainium allows you to install and update apps directly from their releases pages, and receive notifications when new releases are made available.
Motivation: [Side Of Burritos - You should use this instead of F-Droid | How to use app RSS feed](https://youtu.be/FFz57zNR_M0)
Read the Wiki: [https://github.com/ImranR98/Obtainium/wiki](https://github.com/ImranR98/Obtainium/wiki)
More info:
- [Obtainium/wiki](https://github.com/ImranR98/Obtainium/wiki)
- [AppVerifier](https://github.com/soupslurpr/AppVerifier) - App verification tool (recommended, integrates with Obtainium)
- [apps.obtainium.imranr.dev](https://apps.obtainium.imranr.dev/) - Crowdsourced app configurations
- [Side Of Burritos - You should use this instead of F-Droid | How to use app RSS feed](https://youtu.be/FFz57zNR_M0) - Original motivation for this app
Currently supported App sources:
- Open Source - General:

View File

@@ -19,7 +19,7 @@
"noDescription": "Keine Beschreibung",
"cancel": "Abbrechen",
"continue": "Weiter",
"requiredInBrackets": "(Benötigt)",
"requiredInBrackets": "(wird benötigt)",
"dropdownNoOptsError": "FEHLER: DROPDOWN MUSS MINDESTENS EINE OPTION HABEN",
"colour": "Farbe",
"githubStarredRepos": "GitHub Starred Repos",
@@ -183,9 +183,9 @@
"disableVersionDetection": "Versionsermittlung deaktivieren",
"noVersionDetectionExplanation": "Diese Option sollte nur für Apps verwendet werden, bei denen die Versionserkennung nicht korrekt funktioniert.",
"downloadingX": "Lade {} herunter",
"downloadX": "Herunterladen {}",
"downloadedX": "Heruntergeladen {}",
"releaseAsset": "Asset freigeben",
"downloadX": "{} herunterladen",
"downloadedX": "{} heruntergeladen",
"releaseAsset": "release Asset",
"downloadNotifDescription": "Benachrichtigt den Nutzer über den Fortschritt beim Herunterladen einer App",
"noAPKFound": "Keine APK gefunden",
"noVersionDetection": "Keine Versionserkennung",

View File

@@ -1,7 +1,7 @@
{
"invalidURLForSource": "URL d'application {} invalide",
"noReleaseFound": "Impossible de trouver une version appropriée",
"noVersionFound": "Impossible de déterminer la version de la version",
"noReleaseFound": "Impossible de trouver une version adaptée",
"noVersionFound": "Impossible de déterminer la variante de la version",
"urlMatchesNoSource": "L'URL ne correspond pas à une source connue",
"cantInstallOlderVersion": "Impossible d'installer une ancienne version d'une application",
"appIdMismatch": "L'ID de paquet téléchargé ne correspond pas à l'ID de l'application existante",
@@ -43,7 +43,7 @@
"additionalOptsFor": "Options supplémentaires pour {}",
"supportedSources": "Sources prises en charge ",
"trackOnlyInBrackets": "(Suivi uniquement)",
"searchableInBrackets": "(Recherchable)",
"searchableInBrackets": "(Intérrogeable)",
"appsString": "Applications",
"noApps": "Aucune application",
"noAppsForFilter": "Aucune application pour le filtre",
@@ -51,7 +51,7 @@
"percentProgress": "Progrès: {}%",
"pleaseWait": "Veuillez patienter",
"updateAvailable": "Mise à jour disponible",
"notInstalled": "Pas installé",
"notInstalled": "Non installé",
"pseudoVersion": "pseudo-version",
"selectAll": "Tout sélectionner",
"deselectX": "Déselectionner {}",
@@ -60,22 +60,22 @@
"removeSelectedApps": "Supprimer les applications sélectionnées",
"updateX": "Mise à jour {}",
"installX": "Installer {}",
"markXTrackOnlyAsUpdated": "Marquer {}\n(Suivi uniquement)\nas mis à jour",
"markXTrackOnlyAsUpdated": "Marquer {}\n(Suivi uniquement)\n comme mis à jour",
"changeX": "Changer {}",
"installUpdateApps": "Installer/Mettre à jour les applications",
"installUpdateSelectedApps": "Installer/Mettre à jour les applications sélectionnées",
"markXSelectedAppsAsUpdated": "Marquer {} les applications sélectionnées comme mises à jour ?",
"markXSelectedAppsAsUpdated": "Marquer {} les applications sélectionnées comme étant à jour ?",
"no": "Non",
"yes": "Oui",
"markSelectedAppsUpdated": "Marquer les applications sélectionnées comme mises à jour",
"markSelectedAppsUpdated": "Marquer les applications sélectionnées comme étant à jour",
"pinToTop": "Épingler en haut",
"unpinFromTop": "Détacher du haut",
"resetInstallStatusForSelectedAppsQuestion": "Réinitialiser ltat d'installation des applications sélectionnées ?",
"installStatusOfXWillBeResetExplanation": "Ltat d'installation de toutes les applications sélectionnées sera réinitialisé.\n\nCela peut aider lorsque la version de l'application affichée dans Obtainium est incorrecte en raison d'échecs de mises à jour ou d'autres problèmes.",
"customLinkMessage": "Ces liens fonctionnent sur les appareils sur lesquels Obtenirium est installé",
"unpinFromTop": "Désépingler du haut",
"resetInstallStatusForSelectedAppsQuestion": "Réinitialiser le statu d'installation des applications sélectionnées ?",
"installStatusOfXWillBeResetExplanation": "Le statu d'installation de toutes les applications sélectionnées sera réinitialisé.\n\nCela peut aider lorsque la version de l'application affichée dans Obtainium est incorrecte en raison d'échecs de mises à jour ou d'autres problèmes.",
"customLinkMessage": "Ces liens fonctionnent sur les appareils sur lesquels Obtainium est installé",
"shareAppConfigLinks": "Partager la configuration de l'application sous forme de lien HTML",
"shareSelectedAppURLs": "Partager les URL d'application sélectionnées",
"resetInstallStatus": "Réinitialiser le statut d'installation",
"resetInstallStatus": "Réinitialiser le statu d'installation",
"more": "Plus",
"removeOutdatedFilter": "Supprimer le filtre d'application obsolète",
"showOutdatedOnly": "Afficher uniquement les applications obsolètes",
@@ -88,12 +88,12 @@
"importExport": "Importer/Exporter",
"settings": "Paramètres",
"exportedTo": "Exporté vers {}",
"obtainiumExport": "Exportation d'Obtainium",
"obtainiumExport": "Exporter d'Obtainium",
"invalidInput": "Entrée invalide",
"importedX": "Importé {}",
"obtainiumImport": "Importation d'Obtainium",
"obtainiumImport": "Importer d'Obtainium",
"importFromURLList": "Importer à partir de la liste d'URL",
"searchQuery": "Requête de recherche",
"searchQuery": "Requête",
"appURLList": "Liste d'URL d'application",
"line": "Queue",
"searchX": "Rechercher {}",
@@ -110,14 +110,14 @@
"dark": "Sombre",
"light": "Clair",
"followSystem": "Suivre le système",
"useBlackTheme": "Utilisez le thème noir pur et sombre",
"useBlackTheme": "Utilisez le thème noir pur",
"appSortBy": "Applications triées par",
"authorName": "Auteur/Nom",
"nameAuthor": "Nom/Auteur",
"asAdded": "Comme ajouté",
"appSortOrder": "Ordre de tri des applications",
"ascending": "Ascendant",
"descending": "Descendanr",
"descending": "Descendant",
"bgUpdateCheckInterval": "Intervalle de vérification des mises à jour en arrière-plan",
"neverManualOnly": "Jamais - Manuel uniquement",
"appearance": "Apparence",
@@ -131,13 +131,13 @@
"close": "Fermer",
"share": "Partager",
"appNotFound": "Application introuvable",
"obtainiumExportHyphenatedLowercase": "exportation d'obtainium",
"obtainiumExportHyphenatedLowercase": "exportation d'Obtainium",
"pickAnAPK": "Choisissez un APK",
"appHasMoreThanOnePackage": "{} a plus d'un paquet :",
"deviceSupportsXArch": "Votre appareil prend en charge l'architecture de processeur {}.",
"deviceSupportsXArch": "Votre appareil prend en charge l'architecture CPU {}.",
"deviceSupportsFollowingArchs": "Votre appareil prend en charge les architectures CPU suivantes :",
"warning": "Avertissement",
"sourceIsXButPackageFromYPrompt": "La source de l'application est '{}' mais le paquet de version provient de '{}'. Continuer?",
"sourceIsXButPackageFromYPrompt": "La source de l'application est '{}' mais la version du paquet provient de '{}'. Continuer?",
"updatesAvailable": "Mises à jour disponibles",
"updatesAvailableNotifDescription": "Avertit l'utilisateur que des mises à jour sont disponibles pour une ou plusieurs applications suivies par Obtainium",
"noNewUpdates": "Aucune nouvelle mise à jour.",
@@ -179,7 +179,7 @@
"markInstalled": "Marquer installée",
"update": "Mettre à jour",
"markUpdated": "Marquer à jour",
"additionalOptions": "Options additionelles",
"additionalOptions": "Options additionnelles",
"disableVersionDetection": "Désactiver la détection de version",
"noVersionDetectionExplanation": "Cette option ne doit être utilisée que pour les applications où la détection de version ne fonctionne pas correctement.",
"downloadingX": "Téléchargement {}",
@@ -188,7 +188,7 @@
"releaseAsset": "Actif libéré",
"downloadNotifDescription": "Avertit l'utilisateur de la progression du téléchargement d'une application",
"noAPKFound": "Aucun APK trouvé",
"noVersionDetection": "Pas de détection de version",
"noVersionDetection": "Aucune de détection de version",
"categorize": "Catégoriser",
"categories": "Catégories",
"category": "Catégorie",
@@ -201,13 +201,13 @@
"language": "Langue",
"copiedToClipboard": "Copié dans le presse-papier",
"storagePermissionDenied": "Autorisation de stockage refusée",
"selectedCategorizeWarning": "Cela remplacera tous les paramètres de catégorie existants pour les applications sélectionnées.",
"selectedCategorizeWarning": "Cela remplacera toutes les catégorie définies pour les applications sélectionnées.",
"filterAPKsByRegEx": "Filtrer les APK par expression régulière",
"removeFromObtainium": "Supprimer d'Obtainium",
"uninstallFromDevice": "Désinstaller de l'appareil",
"onlyWorksWithNonVersionDetectApps": "Fonctionne uniquement pour les applications avec la détection de version désactivée.",
"releaseDateAsVersion": "Utiliser la date de sortie comme version",
"releaseDateAsVersionExplanation": "Cette option ne doit être utilisée que pour les applications où la détection de version ne fonctionne pas correctement, mais une date de sortie est disponible.",
"releaseDateAsVersionExplanation": "Cette option ne doit être utilisée que pour les applications où la détection de version ne fonctionne pas correctement, mais dont une date de sortie est disponible.",
"changes": "Changements",
"releaseDate": "Date de sortie",
"importFromURLsInFile": "Importer à partir d'URL dans un fichier (comme OPML)",
@@ -215,59 +215,59 @@
"versionDetection": "Détection des versions",
"standardVersionDetection": "Détection de version standard",
"groupByCategory": "Regrouper par catégorie",
"autoApkFilterByArch": "Essayez de filtrer les APK par architecture CPU si possible",
"autoApkFilterByArch": "Si possible, essayez de filtrer les APK par architecture CPU",
"overrideSource": "Remplacer la source",
"dontShowAgain": "Ne montre plus ça",
"dontShowTrackOnlyWarnings": "Don't Show the 'Track-Only' Warning",
"dontShowAgain": "Ne plus montrer",
"dontShowTrackOnlyWarnings": "Ne pas afficher l'avertissement 'Track-Only'",
"dontShowAPKOriginWarnings": "Ne pas afficher les avertissements sur l'origine de l'APK",
"moveNonInstalledAppsToBottom": "Déplacer les applications non installées vers le bas de la vue Applications",
"gitlabPATLabel": "Jeton d'accès personnel GitLab",
"about": "À propos de",
"requiresCredentialsInSettings": "{}: This needs additional credentials (in Settings)",
"requiresCredentialsInSettings": "{}: Cela nécessite des identifiants supplémentaires (dans Paramètres)",
"checkOnStart": "Vérifier les mises à jour au démarrage",
"tryInferAppIdFromCode": "Essayez de déduire l'ID de l'application à partir du code source",
"removeOnExternalUninstall": "Supprimer automatiquement les applications désinstallées en externe",
"pickHighestVersionCode": "Sélectionner automatiquement le code APK de la version la plus élevée",
"checkUpdateOnDetailPage": "Vérifier les mises à jour lors de l'ouverture d'une page de détails d'application",
"pickHighestVersionCode": "Sélectionner automatiquement le code de version de l'APK la plus élevée",
"checkUpdateOnDetailPage": "Vérifier les mises à jour lors de l'ouverture de la page détaillée d'une application",
"disablePageTransitions": "Désactiver les animations de transition de page",
"reversePageTransitions": "Animations de transition de page inversée",
"reversePageTransitions": "Inverser les animations de transition de page",
"minStarCount": "Nombre minimum d'étoiles",
"addInfoBelow": "Ajoutez ces informations ci-dessous.",
"addInfoInSettings": "Ajoutez ces informations dans les paramètres.",
"githubSourceNote": "La limitation du débit GitHub peut être évitée à l'aide d'une clé API.",
"githubSourceNote": "La limite de débit GitHub peut être évitée à l'aide d'une clé API.",
"sortByLastLinkSegment": "Trier uniquement sur le dernier segment du lien",
"filterReleaseNotesByRegEx": "Filtrer les notes de version par expression régulière",
"customLinkFilterRegex": "Filtre de lien APK personnalisé par expression régulière (par défaut '.apk$')",
"customLinkFilterRegex": "Filtre du lien APK personnalisé par expression régulière (par défaut '.apk$')",
"appsPossiblyUpdated": "Tentative de mise à jour de l'application",
"appsPossiblyUpdatedNotifDescription": "Avertit l'utilisateur que des mises à jour d'une ou plusieurs applications ont été potentiellement appliquées en arrière-plan",
"xWasPossiblyUpdatedToY": "{} a peut-être été mis à jour vers {}.",
"enableBackgroundUpdates": "Activer les mises à jour en arrière-plan",
"backgroundUpdateReqsExplanation": "Les mises à jour en arrière-plan peuvent ne pas être possibles pour toutes les applications.",
"backgroundUpdateLimitsExplanation": "Le succès d'une installation en arrière-plan ne peut être déterminé qu'à l'ouverture d'Obetium.",
"verifyLatestTag": "Vérifiez la balise 'dernière'",
"backgroundUpdateLimitsExplanation": "Le succès d'une installation en arrière-plan ne peut être déterminé qu'à l'ouverture d'Obtainium.",
"verifyLatestTag": "Vérifiez la balise 'Latest'",
"intermediateLinkRegex": " Filtrer un lien \" intermédiaire \" à visiter ",
"filterByLinkText": "Filtrer les liens par texte de lien",
"filterByLinkText": "Filtrer les liens par le texte du lien",
"intermediateLinkNotFound": "Lien intermédiaire introuvable",
"intermediateLink": "Lien intermédiaire",
"exemptFromBackgroundUpdates": "Exempt des mises à jour en arrière-plan (si activé)",
"exemptFromBackgroundUpdates": "Exempté des mises à jour en arrière-plan (si activé)",
"bgUpdatesOnWiFiOnly": "Désactiver les mises à jour en arrière-plan lorsque vous n'êtes pas connecté au WiFi",
"autoSelectHighestVersionCode": "Sélection automatique de la version la plus élevéeCode APK",
"versionExtractionRegEx": "Version Extraction RegEx",
"matchGroupToUse": "Match Group to Use",
"highlightTouchTargets": "Mettez en évidence les cibles tactiles moins évidentes",
"autoSelectHighestVersionCode": "Sélection automatique du code de version de l'APK la plus élevée",
"versionExtractionRegEx": "Expression régulière d'extraction de version",
"matchGroupToUse": "Groupe de correspondance pour l'expression régulière d'extraction de version",
"highlightTouchTargets": "Mettre en évidence les cibles tactiles moins évidentes",
"pickExportDir": "Choisir le répertoire d'exportation",
"autoExportOnChanges": "Exportation automatique sur modifications",
"autoExportOnChanges": "Exporter automatiquement après modification",
"includeSettings": "Inclure les paramètres",
"filterVersionsByRegEx": "Filtrer les versions par expression régulière",
"trySelectingSuggestedVersionCode": "Essayez de sélectionner la version suggéréeCode APK",
"dontSortReleasesList": "Conserver la commande de version de l'API",
"trySelectingSuggestedVersionCode": "Essayez de sélectionner le code de la version APK suggérée",
"dontSortReleasesList": "Conserver l'ordre des version de l'API",
"reverseSort": "Tri inversé",
"takeFirstLink": "Prendre le premier lien",
"skipSort": "Sauter le tri",
"debugMenu": "Menu de débogage",
"bgTaskStarted": "Tâche en arrière-plan démarrée - vérifier les journaux.",
"runBgCheckNow": "Exécuter la vérification de la mise à jour en arrière-plan maintenant",
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"runBgCheckNow": "Exécuter maintenant la vérification de la mise à jour en arrière-plan",
"versionExtractWholePage": "Appliquer l'expression régulière d'extraction de version sur l'ensemble de la page",
"installing": "Installation",
"skipUpdateNotifications": "Ignorer les notifications de mise à jour",
"updatesAvailableNotifChannel": "Mises à jour disponibles",
@@ -278,19 +278,19 @@
"downloadingXNotifChannel": "Téléchargement {}",
"completeAppInstallationNotifChannel": "Installation complète de l'application",
"checkingForUpdatesNotifChannel": "Vérification des mises à jour",
"onlyCheckInstalledOrTrackOnlyApps": "Vérifiez uniquement les mises à jour des applications installées et de suivi uniquement",
"onlyCheckInstalledOrTrackOnlyApps": "Vérifiez uniquement les mises à jour des applications installées et 'Track-Only'",
"supportFixedAPKURL": "Prise en charge des URL APK fixes",
"selectX": "Sélectionner {}",
"parallelDownloads": "Autoriser les téléchargements parallèles",
"installMethod": "Méthode d'installation",
"normal": "Normale",
"root": "Racine",
"shizukuBinderNotFound": "Shizuku is not running",
"useSystemFont": "Utiliser la police système",
"systemFontError": "Erreur de chargement de la police système : {}",
"shizukuBinderNotFound": "Service Shizuku compatible non trouvé",
"useSystemFont": "Utiliser la police du système",
"systemFontError": "Erreur de chargement de la police du système : {}",
"useVersionCodeAsOSVersion": "Utiliser le code de version de l'application comme version détectée par le système d'exploitation",
"requestHeader": "En-tête de demande",
"useLatestAssetDateAsReleaseDate": "Utiliser le dernier téléchargement d'élément comme date de sortie",
"useLatestAssetDateAsReleaseDate": "Utiliser le dernier élément téléversé comme date de sortie",
"defaultPseudoVersioningMethod": "Méthode de pseudo-version par défaut",
"partialAPKHash": "Hash APK partiel",
"APKLinkHash": "Hash de lien APK",
@@ -313,12 +313,12 @@
"other": "Trop de demandes (taux limité) - réessayez dans {} minutes"
},
"bgUpdateGotErrorRetryInMinutes": {
"one": "La vérification de la mise à jour en arrière-plan a rencontré un {}, planifiera une nouvelle tentative de vérification dans {} minute",
"other": "La vérification de la mise à jour en arrière-plan a rencontré un {}, planifiera une nouvelle tentative de vérification dans {} minutes"
"one": "La vérification de la mise à jour en arrière-plan a rencontré un {}, une nouvelle tentative de vérification sera planifié dans {} minute",
"other": "La vérification de la mise à jour en arrière-plan a rencontré un {}, une nouvelle tentative de vérification sera planifié dans {} minute"
},
"bgCheckFoundUpdatesWillNotifyIfNeeded": {
"one": "La vérification des mises à jour en arrière-plan trouvée {} mise à jour - avertira l'utilisateur si nécessaire",
"other": "La vérification des mises à jour en arrière-plan a trouvé {} mises à jour - avertira l'utilisateur si nécessaire"
"one": "La vérification des mises à jour en arrière-plan a trouvée {} mise à jour - l'utilisateur sera notifié si nécessaire",
"other": "La vérification des mises à jour en arrière-plan a trouvé {} mises à jour - l'utilisateur sera notifié si nécessaire"
},
"apps": {
"one": "{} Application",

View File

@@ -185,7 +185,7 @@
"downloadingX": "{} letöltés",
"downloadX": "Letöltés {}",
"downloadedX": "Letöltés {}",
"releaseAsset": "Release Asset",
"releaseAsset": "Kiadási tartalom",
"downloadNotifDescription": "Értesíti a felhasználót az app letöltésének előrehaladásáról",
"noAPKFound": "Nem található APK",
"noVersionDetection": "Nincs verzió érzékelés",

View File

@@ -364,6 +364,6 @@
},
"apk": {
"one": "{} APK",
"other": "{} APKs"
"other": "{} APKи"
}
}

View File

@@ -0,0 +1,54 @@
<p>Obtainium позволяет вам устанавливать и обновлять приложения прямо с их объявлений о выпусках и получать уведомления о новых выпусках.</p>
<p>Для деталей читайте <a href="https://github.com/ImranR98/Obtainium/wiki">Вики</a></p>
<p>
<b>Поддерживаемые источники приложений:</b>
</p>
<ul>
<li>
<p>Свободное ПО - Общие:</p>
<ul>
<li>GitHub</li>
<li>GitLab</li>
<li>Codeberg</li>
<li>F-Droid</li>
<li>Third Party F-Droid Repos</li>
<li>IzzyOnDroid</li>
<li>SourceForge</li>
<li>SourceHut</li>
</ul>
</li>
<li>
<p>Другие - Общие:</p>
<ul>
<li>APKPure</li>
<li>Aptoide</li>
<li>Uptodowng</li>
<li>APKMirror (Track-Only)</li>
<li>Huawei AppGallery</li>
<li>Jenkins Jobs</li>
</ul>
</li>
<li>
<p>Свободное ПО - Для отдельных приложений:</p>
<ul>
<li>Mullvad</li>
<li>Signal</li>
<li>VLC</li>
</ul>
</li>
<li>
<p>Другие - Для отдельных приложений:</p>
<ul>
<li>WhatsApp</li>
<li>Telegram App</li>
<li>Neutron Code</li>
</ul>
</li>
<li><p>"HTML" (Подстраховка): Любой другой URL-адрес, который возвращает HTML-страницу со ссылками на APK-файлы.</p></li>
</ul>
<p>
<b>Ограничения:</b>
</p>
<p>
Для некоторых источников данные собираются с помощью веб-скрапинга и могут легко сломаться из-за изменений в дизайне веб-сайта. В таких случаях более надежные методы могут быть недоступны.
</p>

View File

@@ -0,0 +1 @@
Получайте обновления приложений прямо из источника

View File

@@ -244,16 +244,17 @@ class HTML extends AppSource {
true) {
var reg = RegExp(additionalSettings['customLinkFilterRegex']);
links = allLinks
.where((element) =>
reg.hasMatch(filterLinkByText ? element.value : element.key))
.where((element) => reg.hasMatch(
filterLinkByText ? element.value : Uri.decodeFull(element.key)))
.toList();
} else {
links = allLinks
.where((element) =>
Uri.parse(filterLinkByText ? element.value : element.key)
.path
.toLowerCase()
.endsWith('.apk'))
.where((element) => Uri.parse(filterLinkByText
? element.value
: Uri.decodeFull(element.key))
.path
.toLowerCase()
.endsWith('.apk'))
.toList();
}
if (!skipSort) {
@@ -315,7 +316,7 @@ class HTML extends AppSource {
additionalSettings['matchGroupToUse'] as String?,
additionalSettings['versionExtractWholePage'] == true
? versionExtractionWholePageString
: rel);
: Uri.decodeFull(rel));
version ??=
additionalSettings['defaultPseudoVersioningMethod'] == 'APKLinkHash'
? rel.hashCode.toString()

View File

@@ -245,8 +245,8 @@ class _GeneratedFormState extends State<GeneratedForm> {
void someValueChanged({bool isBuilding = false, bool forceInvalid = false}) {
Map<String, dynamic> returnValues = values;
var valid = true;
for (int r = 0; r < widget.items.length; r++) {
for (int i = 0; i < widget.items[r].length; i++) {
for (int r = 0; r < formInputs.length; r++) {
for (int i = 0; i < formInputs[r].length; i++) {
if (formInputs[r][i] is TextFormField) {
valid = valid && validateTextField(formInputs[r][i] as TextFormField);
}

View File

@@ -235,8 +235,9 @@ Future<File> downloadFile(
var fullContentLength = response.contentLength;
if (useExisting && downloadedFile.existsSync()) {
var length = downloadedFile.lengthSync();
if (fullContentLength == null) {
// Assume full
if (fullContentLength == null || !rangeFeatureEnabled) {
// If there is no content length reported, assume it the existing file is fully downloaded
// Also if the range feature is not supported, don't trust the content length if any (#1542)
client.close();
return downloadedFile;
} else {
@@ -291,14 +292,11 @@ Future<File> downloadFile(
return s;
}).pipe(sink);
await sink.close();
bool likelyCorruptFile = (progress ?? 0) > 101;
progress = null;
if (onProgress != null) {
onProgress(progress);
}
if (response.statusCode < 200 ||
response.statusCode > 299 ||
likelyCorruptFile) {
if (response.statusCode < 200 || response.statusCode > 299) {
tempDownloadedFile.deleteSync(recursive: true);
throw response.reasonPhrase ?? tr('unexpectedError');
}
@@ -392,30 +390,26 @@ class AppsProvider with ChangeNotifier {
}();
}
Future<File> handleAPKIDChange(App app, PackageInfo? newInfo,
Future<File> handleAPKIDChange(App app, PackageInfo newInfo,
File downloadedFile, String downloadUrl) async {
// If the APK package ID is different from the App ID, it is either new (using a placeholder ID) or the ID has changed
// The former case should be handled (give the App its real ID), the latter is a security issue
var isTempIdBool = isTempId(app);
if (newInfo != null) {
if (app.id != newInfo.packageName) {
if (apps[app.id] != null && !isTempIdBool && !app.allowIdChange) {
throw IDChangedError(newInfo.packageName!);
}
var idChangeWasAllowed = app.allowIdChange;
app.allowIdChange = false;
var originalAppId = app.id;
app.id = newInfo.packageName!;
downloadedFile = downloadedFile.renameSync(
'${downloadedFile.parent.path}/${app.id}-${downloadUrl.hashCode}.${downloadedFile.path.split('.').last}');
if (apps[originalAppId] != null) {
await removeApps([originalAppId]);
await saveApps([app],
onlyIfExists: !isTempIdBool && !idChangeWasAllowed);
}
if (app.id != newInfo.packageName) {
if (apps[app.id] != null && !isTempIdBool && !app.allowIdChange) {
throw IDChangedError(newInfo.packageName!);
}
var idChangeWasAllowed = app.allowIdChange;
app.allowIdChange = false;
var originalAppId = app.id;
app.id = newInfo.packageName!;
downloadedFile = downloadedFile.renameSync(
'${downloadedFile.parent.path}/${app.id}-${downloadUrl.hashCode}.${downloadedFile.path.split('.').last}');
if (apps[originalAppId] != null) {
await removeApps([originalAppId]);
await saveApps([app],
onlyIfExists: !isTempIdBool && !idChangeWasAllowed);
}
} else if (isTempIdBool) {
throw ObtainiumError('Could not get ID from APK');
}
return downloadedFile;
}
@@ -479,6 +473,10 @@ class AppsProvider with ChangeNotifier {
newInfo =
await pm.getPackageArchiveInfo(archiveFilePath: apks.first.path);
}
if (newInfo == null) {
downloadedFile.delete();
throw ObtainiumError('Could not get ID from APK');
}
downloadedFile =
await handleAPKIDChange(app, newInfo, downloadedFile, downloadUrl);
// Delete older versions of the file if any

View File

@@ -292,10 +292,10 @@ packages:
dependency: "direct main"
description:
name: flutter_archive
sha256: "22e931ef6ef764edc922e425e46f4a4f888e864b976f4ecbe54aea9859abc090"
sha256: "5ca235f304c12bf468979235f400f79846d204169d715939e39197106f5fc970"
url: "https://pub.dev"
source: hosted
version: "6.0.2"
version: "6.0.3"
flutter_fgbg:
dependency: "direct main"
description:
@@ -659,10 +659,10 @@ packages:
dependency: transitive
description:
name: petitparser
sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted
version: "5.4.0"
version: "6.0.2"
platform:
dependency: transitive
description:
@@ -937,10 +937,10 @@ packages:
dependency: transitive
description:
name: url_launcher_web
sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d"
sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a"
url: "https://pub.dev"
source: hosted
version: "2.3.0"
version: "2.3.1"
url_launcher_windows:
dependency: transitive
description:
@@ -1041,10 +1041,10 @@ packages:
dependency: transitive
description:
name: xml
sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev"
source: hosted
version: "6.3.0"
version: "6.5.0"
yaml:
dependency: transitive
description:
@@ -1054,5 +1054,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.3.3 <4.0.0"
dart: ">=3.3.0 <4.0.0"
flutter: ">=3.19.0"

View File

@@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.1.2+2259
version: 1.1.4+2261
environment:
sdk: '>=3.0.0 <4.0.0'