mirror of
				https://github.com/ImranR98/Obtainium.git
				synced 2025-11-04 07:13:28 +01:00 
			
		
		
		
	Compare commits
	
		
			16 Commits
		
	
	
		
			v0.14.37-b
			...
			v0.14.39-b
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					13066b3b4a | ||
| 
						 | 
					ccbe9d00c8 | ||
| 
						 | 
					ce291582cb | ||
| 
						 | 
					bb37bc3b51 | ||
| 
						 | 
					5a7747acd1 | ||
| 
						 | 
					1bc2ec9461 | ||
| 
						 | 
					2b977fc2b0 | ||
| 
						 | 
					cc4b016c64 | ||
| 
						 | 
					f64f561d6f | ||
| 
						 | 
					80bddf8a6b | ||
| 
						 | 
					cbaaec961c | ||
| 
						 | 
					5477b3f936 | ||
| 
						 | 
					fd59a93ede | ||
| 
						 | 
					cd316b7138 | ||
| 
						 | 
					d1955192ed | ||
| 
						 | 
					9beb839bf4 | 
							
								
								
									
										1
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							@@ -9,6 +9,7 @@ assignees: ''
 | 
			
		||||
 | 
			
		||||
**Prerequisites**
 | 
			
		||||
<!-- Please ensure your request is not part of an existing issue. -->
 | 
			
		||||
<!-- Please ensure you have checked the Obtainium Wiki. -->
 | 
			
		||||
 | 
			
		||||
**Describe the bug**
 | 
			
		||||
<!-- A clear and concise description of what the bug is. -->
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
								
							@@ -9,6 +9,7 @@ assignees: ''
 | 
			
		||||
 | 
			
		||||
**Prerequisites**
 | 
			
		||||
<!-- Please ensure your request is not part of an existing issue. -->
 | 
			
		||||
<!-- Please ensure you have checked the Obtainium Wiki. -->
 | 
			
		||||
 | 
			
		||||
**Describe the feature**
 | 
			
		||||
<!-- A clear and concise description of what you want to happen.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
 | 
			
		||||
    android:viewportWidth="142.129"
 | 
			
		||||
    android:viewportHeight="142.129"
 | 
			
		||||
    android:width="503.6066dp"
 | 
			
		||||
    android:height="503.6066dp">
 | 
			
		||||
    android:width="108dp"
 | 
			
		||||
    android:height="108dp">
 | 
			
		||||
    <group
 | 
			
		||||
        android:translateX="-30.39437"
 | 
			
		||||
        android:translateY="-54.68043">
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Probajte izabrati preloženu (verziju) versionCode APK-a",
 | 
			
		||||
    "dontSortReleasesList": "Zadrži redosled izdanja iz API-a",
 | 
			
		||||
    "reverseSort": "Obrni redosled",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Meni za otkrivanje grešaka",
 | 
			
		||||
    "bgTaskStarted": "Rad u pozadini pokrenut - provjerite log-ove.",
 | 
			
		||||
    "runBgCheckNow": "Pokrenite pozadinsku provjeru ažuriranja sad",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "Isključivo provjerite ažuriranje za instalirane i aplikacije 'samo za praćenje'",
 | 
			
		||||
    "supportFixedAPKURL": "Podržite fiksne APK URL-ove",
 | 
			
		||||
    "selectX": "Izaberite {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "Želite li ukloniti aplikaciju?",
 | 
			
		||||
        "other": "Želite li ukloniti aplikacije?"
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Zkusit vybrat navrhovaný kód verze APK",
 | 
			
		||||
    "dontSortReleasesList": "Retain release order from API",
 | 
			
		||||
    "reverseSort": "Reverse sorting",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Debug Menu",
 | 
			
		||||
    "bgTaskStarted": "Background task started - check logs.",
 | 
			
		||||
    "runBgCheckNow": "Run Background Update Check Now",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates",
 | 
			
		||||
    "supportFixedAPKURL": "Support fixed APK URLs",
 | 
			
		||||
    "selectX": "Select {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "Odstranit Apku?",
 | 
			
		||||
        "other": "Odstranit Apky?"
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Versuchen, den vorgeschlagenen APK-Versionscode auszuwählen",
 | 
			
		||||
    "dontSortReleasesList": "Freigaberelease von der API ordern",
 | 
			
		||||
    "reverseSort": "Umgekehrtes Sortieren",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Debug-Menü",
 | 
			
		||||
    "bgTaskStarted": "Hintergrundaufgabe gestartet – Logs prüfen.",
 | 
			
		||||
    "runBgCheckNow": "Hintergrundaktualisierungsprüfung jetzt durchführen",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "Überprüfe nur installierte und mit „nur Nachverfolgen“ markierte Apps auf Aktualisierungen",
 | 
			
		||||
    "supportFixedAPKURL": "neuere Version anhand der ersten dreißig Zahlen der Checksumme der APK URL erraten, wenn anderweitig nicht unterstützt",
 | 
			
		||||
    "selectX": "Wähle {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "App entfernen?",
 | 
			
		||||
        "other": "Apps entfernen?"
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK",
 | 
			
		||||
    "dontSortReleasesList": "Retain release order from API",
 | 
			
		||||
    "reverseSort": "Reverse sorting",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Debug Menu",
 | 
			
		||||
    "bgTaskStarted": "Background task started - check logs.",
 | 
			
		||||
    "runBgCheckNow": "Run Background Update Check Now",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates",
 | 
			
		||||
    "supportFixedAPKURL": "Support fixed APK URLs",
 | 
			
		||||
    "selectX": "Select {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "Remove App?",
 | 
			
		||||
        "other": "Remove Apps?"
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Prueba seleccionando la versionCode APK sugerida",
 | 
			
		||||
    "dontSortReleasesList": "Mantener el order de publicación desde API",
 | 
			
		||||
    "reverseSort": "Orden inverso",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Menu Depurar",
 | 
			
		||||
    "bgTaskStarted": "Iniciada tarea en segundo plano - revisa los logs.",
 | 
			
		||||
    "runBgCheckNow": "Ejecutar verficiación de actualizaciones en segundo plano",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates",
 | 
			
		||||
    "supportFixedAPKURL": "Soporte para URLs fijas de APK",
 | 
			
		||||
    "selectX": "Selecciona {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "¿Eliminar Aplicación?",
 | 
			
		||||
        "other": "¿Eliminar Aplicaciones?"
 | 
			
		||||
 
 | 
			
		||||
@@ -245,8 +245,8 @@
 | 
			
		||||
    "enableBackgroundUpdates": "به روز رسانی پس زمینه را فعال کنید",
 | 
			
		||||
    "backgroundUpdateReqsExplanation": "به روز رسانی پس زمینه ممکن است برای همه برنامه ها امکان پذیر نباشد.",
 | 
			
		||||
    "backgroundUpdateLimitsExplanation": "موفقیت نصب پسزمینه تنها زمانی مشخص میشود که Obtainium باز شود.",
 | 
			
		||||
    "verifyLatestTag": "برچسب "آخرین" را تأیید کنید",
 | 
			
		||||
    "intermediateLinkRegex": "برای اولین بار بازدید از لینک "متوسط" را فیلتر کنید",
 | 
			
		||||
    "verifyLatestTag": "برچسب \"آخرین\" را تأیید کنید",
 | 
			
		||||
    "intermediateLinkRegex": "برای اولین بار بازدید از لینک \"متوسط\" را فیلتر کنید",
 | 
			
		||||
    "intermediateLinkNotFound": "لینک میانی پیدا نشد",
 | 
			
		||||
    "exemptFromBackgroundUpdates": "معاف از بهروزرسانیهای پسزمینه (در صورت فعال بودن)",
 | 
			
		||||
    "bgUpdatesOnWiFiOnly": "بهروزرسانیهای پسزمینه را در صورت عدم اتصال به WiFi غیرفعال کنید",
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "نسخه پیشنهادی APK نسخه کد را انتخاب کنید",
 | 
			
		||||
    "dontSortReleasesList": "حفظ سفارش انتشار از API",
 | 
			
		||||
    "reverseSort": "مرتب سازی معکوس",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "منوی اشکال زدایی",
 | 
			
		||||
    "bgTaskStarted": "کار پس زمینه شروع شد - لاگ های مربوط را بررسی کنید.",
 | 
			
		||||
    "runBgCheckNow": "اکنون بهروزرسانی پسزمینه را بررسی کنید",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "فقط برنامه های نصب شده و فقط ردیابی را برای به روز رسانی بررسی کنید",
 | 
			
		||||
    "supportFixedAPKURL": "پشتیبانی از URL های APK ثابت",
 | 
			
		||||
    "selectX": "انتخاب کنید {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "برنامه حذف شود؟",
 | 
			
		||||
        "other": "برنامه ها حذف شوند؟"
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK",
 | 
			
		||||
    "dontSortReleasesList": "Retain release order from API",
 | 
			
		||||
    "reverseSort": "Reverse sorting",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Debug Menu",
 | 
			
		||||
    "bgTaskStarted": "Background task started - check logs.",
 | 
			
		||||
    "runBgCheckNow": "Run Background Update Check Now",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates",
 | 
			
		||||
    "supportFixedAPKURL": "Support fixed APK URLs",
 | 
			
		||||
    "selectX": "Select {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "Supprimer l'application ?",
 | 
			
		||||
        "other": "Supprimer les applications ?"
 | 
			
		||||
 
 | 
			
		||||
@@ -260,6 +260,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Próbálja ki a javasolt verziókódú APK-t",
 | 
			
		||||
    "dontSortReleasesList": "Az API-ból származó kiadási sorrend megőrzése",
 | 
			
		||||
    "reverseSort": "Fordított rendezés",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Hibakereső menü",
 | 
			
		||||
    "bgTaskStarted": "A háttérfeladat elindult – ellenőrizze a naplókat.",
 | 
			
		||||
    "enableBackgroundUpdates": "Frissítések a háttérben",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "Csak a telepített és a csak követhető appokat ellenőrizze frissítésekért",
 | 
			
		||||
    "supportFixedAPKURL": "Támogatja a rögzített APK URL-eket",
 | 
			
		||||
    "selectX": "Kiválaszt {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "Eltávolítja az alkalmazást?",
 | 
			
		||||
        "other": "Eltávolítja az alkalmazást?"
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Prova a selezionare APK con versionCode suggerito",
 | 
			
		||||
    "dontSortReleasesList": "Conserva l'ordine di release da API",
 | 
			
		||||
    "reverseSort": "Ordine inverso",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Menu di debug",
 | 
			
		||||
    "bgTaskStarted": "Attività in secondo piano iniziata - controllo log.",
 | 
			
		||||
    "runBgCheckNow": "Inizia aggiornamento in secondo piano ora",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "Cerca aggiornamenti solo per app installate e app in Solo-Monitoraggio",
 | 
			
		||||
    "supportFixedAPKURL": "Support fixed APK URLs",
 | 
			
		||||
    "selectX": "Select {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "Rimuovere l'app?",
 | 
			
		||||
        "other": "Rimuovere le app?"
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "提案されたバージョンコードのAPKを選択する",
 | 
			
		||||
    "dontSortReleasesList": "APIからのリリース順を保持する",
 | 
			
		||||
    "reverseSort": "逆順ソート",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "デバッグメニュー",
 | 
			
		||||
    "bgTaskStarted": "バックグラウンドタスクが開始されました - ログを確認してください。",
 | 
			
		||||
    "runBgCheckNow": "今すぐバックグラウンドでのアップデート確認を開始する",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "インストール済みのアプリと「追跡のみ」のアプリのアップデートのみを確認する",
 | 
			
		||||
    "supportFixedAPKURL": "Support fixed APK URLs",
 | 
			
		||||
    "selectX": "Select {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "アプリを削除しますか?",
 | 
			
		||||
        "other": "アプリを削除しますか?"
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Probeer de voorgestelde versiecode APK te selecteren",
 | 
			
		||||
    "dontSortReleasesList": "Volgorde van releases behouden vanuit de API",
 | 
			
		||||
    "reverseSort": "Sortering omkeren",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Debug menu",
 | 
			
		||||
    "bgTaskStarted": "Achtergrondtaak gestart - controleer de logs.",
 | 
			
		||||
    "runBgCheckNow": "Voer nu een achtergrondupdatecontrole uit",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "Alleen geïnstalleerde en Track-Only apps controleren op updates",
 | 
			
		||||
    "supportFixedAPKURL": "Support fixed APK URLs",
 | 
			
		||||
    "selectX": "Select {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "App verwijderen?",
 | 
			
		||||
        "other": "Apps verwijderen?"
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Spróbuj wybierać sugerowany kod wersji APK",
 | 
			
		||||
    "dontSortReleasesList": "Utrzymaj kolejność wydań z interfejsu API",
 | 
			
		||||
    "reverseSort": "Odwrotne sortowanie",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Menu debugowania",
 | 
			
		||||
    "bgTaskStarted": "Uruchomiono zadanie w tle - sprawdź logi.",
 | 
			
		||||
    "runBgCheckNow": "Wymuś sprawdzenie aktualizacji w tle",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "Sprawdzaj tylko zainstalowane i obserwowane aplikacje pod kątem aktualizacji",
 | 
			
		||||
    "supportFixedAPKURL": "Obsługuj stałe adresy URL APK",
 | 
			
		||||
    "selectX": "Wybierz {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "Usunąć aplikację?",
 | 
			
		||||
        "few": "Usunąć aplikacje?",
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Tente selecionar a versão sugerida",
 | 
			
		||||
    "dontSortReleasesList": "Reter a ordem de lançamento da API",
 | 
			
		||||
    "reverseSort": "Ordenação reversa",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Menu Debug",
 | 
			
		||||
    "bgTaskStarted": "Tarefa em segundo plano iniciada - verifique os logs.",
 | 
			
		||||
    "runBgCheckNow": "Execute a verificação de atualização em segundo plano agora",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates",
 | 
			
		||||
    "supportFixedAPKURL": "Support fixed APK URLs",
 | 
			
		||||
    "selectX": "Select {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "Remover App?",
 | 
			
		||||
        "other": "Remover Apps?"
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Попробуйте выбрать предложенный код версии APK",
 | 
			
		||||
    "dontSortReleasesList": "Сохранить порядок релизов от API",
 | 
			
		||||
    "reverseSort": "Обратная сортировка",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Меню отладки",
 | 
			
		||||
    "bgTaskStarted": "Фоновая задача начата — проверьте журналы",
 | 
			
		||||
    "runBgCheckNow": "Запустить проверку фонового обновления сейчас",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates",
 | 
			
		||||
    "supportFixedAPKURL": "Support fixed APK URLs",
 | 
			
		||||
    "selectX": "Select {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "Удалить приложение?",
 | 
			
		||||
        "other": "Удалить приложения?"
 | 
			
		||||
 
 | 
			
		||||
@@ -261,9 +261,12 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK",
 | 
			
		||||
    "dontSortReleasesList": "Retain release order from API",
 | 
			
		||||
    "reverseSort": "Omvänd sortering",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Felsökningsmeny",
 | 
			
		||||
    "bgTaskStarted": "Background task started - check logs.",
 | 
			
		||||
    "runBgCheckNow": "Kör Bakgrundsuppdateringskoll Nu",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "Ta Bort App?",
 | 
			
		||||
        "other": "Ta Bort Appar?"
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Önerilen sürüm kodunu seçmeyi dene",
 | 
			
		||||
    "dontSortReleasesList": "API'den sıralama düzenini koru",
 | 
			
		||||
    "reverseSort": "Ters sıralama",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Hata Ayıklama Menüsü",
 | 
			
		||||
    "bgTaskStarted": "Arka plan görevi başladı - günlükleri kontrol et.",
 | 
			
		||||
    "runBgCheckNow": "Arka Plan Güncelleme Kontrolünü Şimdi Çalıştır",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "Yalnızca yüklü ve Yalnızca İzleme Uygulamalarını güncelleme",
 | 
			
		||||
    "supportFixedAPKURL": "Support fixed APK URLs",
 | 
			
		||||
    "selectX": "Select {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "Uygulamayı Kaldır?",
 | 
			
		||||
        "other": "Uygulamaları Kaldır?"
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "Thử chọn APK Mã phiên bản được đề xuất",
 | 
			
		||||
    "dontSortReleasesList": "Giữ lại thứ tự phát hành từ API",
 | 
			
		||||
    "reverseSort": "Sắp xếp ngược",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "Danh sách gỡ lỗi",
 | 
			
		||||
    "bgTaskStarted": "Tác vụ nền đã bắt đầu - kiểm tra nhật ký.",
 | 
			
		||||
    "runBgCheckNow": "Chạy kiểm tra cập nhật nền ngay bây giờ",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "Chỉ kiểm tra các ứng dụng đã cài đặt và Chỉ-Theo dõi để biết các bản cập nhật",
 | 
			
		||||
    "supportFixedAPKURL": "Support fixed APK URLs",
 | 
			
		||||
    "selectX": "Select {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion":{
 | 
			
		||||
        "one": "Gỡ ứng dụng?",
 | 
			
		||||
        "other": "Gỡ ứng dụng?"
 | 
			
		||||
 
 | 
			
		||||
@@ -261,6 +261,8 @@
 | 
			
		||||
    "trySelectingSuggestedVersionCode": "尝试选择推荐版本的 APK 文件",
 | 
			
		||||
    "dontSortReleasesList": "保持来自 API 的发行顺序",
 | 
			
		||||
    "reverseSort": "反转排序",
 | 
			
		||||
    "takeFirstLink": "Take first link",
 | 
			
		||||
    "skipSort": "Skip sorting",
 | 
			
		||||
    "debugMenu": "调试选项",
 | 
			
		||||
    "bgTaskStarted": "后台任务已启动 - 详见日志",
 | 
			
		||||
    "runBgCheckNow": "立即进行后台更新检查",
 | 
			
		||||
@@ -278,6 +280,7 @@
 | 
			
		||||
    "onlyCheckInstalledOrTrackOnlyApps": "只对已安装和“仅追踪”的应用进行更新检查",
 | 
			
		||||
    "supportFixedAPKURL": "Support fixed APK URLs",
 | 
			
		||||
    "selectX": "Select {}",
 | 
			
		||||
    "parallelDownloads": "Allow parallel downloads",
 | 
			
		||||
    "removeAppQuestion": {
 | 
			
		||||
        "one": "是否删除应用?",
 | 
			
		||||
        "other": "是否删除应用?"
 | 
			
		||||
 
 | 
			
		||||
@@ -65,7 +65,7 @@ class FDroid extends AppSource {
 | 
			
		||||
  ) async {
 | 
			
		||||
    String? appId = await tryInferringAppId(standardUrl);
 | 
			
		||||
    String host = Uri.parse(standardUrl).host;
 | 
			
		||||
    return getAPKUrlsFromFDroidPackagesAPIResponse(
 | 
			
		||||
    var details = getAPKUrlsFromFDroidPackagesAPIResponse(
 | 
			
		||||
        await sourceRequest('https://$host/api/v1/packages/$appId'),
 | 
			
		||||
        'https://$host/repo/$appId',
 | 
			
		||||
        standardUrl,
 | 
			
		||||
@@ -80,6 +80,23 @@ class FDroid extends AppSource {
 | 
			
		||||
                    true
 | 
			
		||||
                ? additionalSettings['filterVersionsByRegEx']
 | 
			
		||||
                : null);
 | 
			
		||||
    if (!hostChanged) {
 | 
			
		||||
      try {
 | 
			
		||||
        var res = await sourceRequest(
 | 
			
		||||
            'https://gitlab.com/fdroid/fdroiddata/-/raw/master/metadata/$appId.yml');
 | 
			
		||||
        String author = res.body
 | 
			
		||||
            .split('\n')
 | 
			
		||||
            .where((l) => l.startsWith('AuthorName: '))
 | 
			
		||||
            .first
 | 
			
		||||
            .split(': ')
 | 
			
		||||
            .sublist(1)
 | 
			
		||||
            .join(': ');
 | 
			
		||||
        details.names.author = author;
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        // Fail silently
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return details;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
@@ -111,79 +128,79 @@ class FDroid extends AppSource {
 | 
			
		||||
      throw getObtainiumHttpError(res);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
APKDetails getAPKUrlsFromFDroidPackagesAPIResponse(
 | 
			
		||||
    Response res, String apkUrlPrefix, String standardUrl, String sourceName,
 | 
			
		||||
    {bool autoSelectHighestVersionCode = false,
 | 
			
		||||
    bool trySelectingSuggestedVersionCode = false,
 | 
			
		||||
    String? filterVersionsByRegEx}) {
 | 
			
		||||
  if (res.statusCode == 200) {
 | 
			
		||||
    var response = jsonDecode(res.body);
 | 
			
		||||
    List<dynamic> releases = response['packages'] ?? [];
 | 
			
		||||
    if (releases.isEmpty) {
 | 
			
		||||
      throw NoReleasesError();
 | 
			
		||||
    }
 | 
			
		||||
    String? version;
 | 
			
		||||
    Iterable<dynamic> releaseChoices = [];
 | 
			
		||||
    // Grab the versionCode suggested if the user chose to do that
 | 
			
		||||
    // Only do so at this stage if the user has no release filter
 | 
			
		||||
    if (trySelectingSuggestedVersionCode &&
 | 
			
		||||
        response['suggestedVersionCode'] != null &&
 | 
			
		||||
        filterVersionsByRegEx == null) {
 | 
			
		||||
      var suggestedReleases = releases.where((element) =>
 | 
			
		||||
          element['versionCode'] == response['suggestedVersionCode']);
 | 
			
		||||
      if (suggestedReleases.isNotEmpty) {
 | 
			
		||||
        releaseChoices = suggestedReleases;
 | 
			
		||||
        version = suggestedReleases.first['versionName'];
 | 
			
		||||
  APKDetails getAPKUrlsFromFDroidPackagesAPIResponse(
 | 
			
		||||
      Response res, String apkUrlPrefix, String standardUrl, String sourceName,
 | 
			
		||||
      {bool autoSelectHighestVersionCode = false,
 | 
			
		||||
      bool trySelectingSuggestedVersionCode = false,
 | 
			
		||||
      String? filterVersionsByRegEx}) {
 | 
			
		||||
    if (res.statusCode == 200) {
 | 
			
		||||
      var response = jsonDecode(res.body);
 | 
			
		||||
      List<dynamic> releases = response['packages'] ?? [];
 | 
			
		||||
      if (releases.isEmpty) {
 | 
			
		||||
        throw NoReleasesError();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // Apply the release filter if any
 | 
			
		||||
    if (filterVersionsByRegEx?.isNotEmpty == true) {
 | 
			
		||||
      version = null;
 | 
			
		||||
      releaseChoices = [];
 | 
			
		||||
      for (var i = 0; i < releases.length; i++) {
 | 
			
		||||
        if (RegExp(filterVersionsByRegEx!)
 | 
			
		||||
            .hasMatch(releases[i]['versionName'])) {
 | 
			
		||||
          version = releases[i]['versionName'];
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (version == null) {
 | 
			
		||||
        throw NoVersionError();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // Default to the highest version
 | 
			
		||||
    version ??= releases[0]['versionName'];
 | 
			
		||||
    if (version == null) {
 | 
			
		||||
      throw NoVersionError();
 | 
			
		||||
    }
 | 
			
		||||
    // If a suggested release was not already picked, pick all those with the selected version
 | 
			
		||||
    if (releaseChoices.isEmpty) {
 | 
			
		||||
      releaseChoices =
 | 
			
		||||
          releases.where((element) => element['versionName'] == version);
 | 
			
		||||
    }
 | 
			
		||||
    // For the remaining releases, use the toggles to auto-select one if possible
 | 
			
		||||
    if (releaseChoices.length > 1) {
 | 
			
		||||
      if (autoSelectHighestVersionCode) {
 | 
			
		||||
        releaseChoices = [releaseChoices.first];
 | 
			
		||||
      } else if (trySelectingSuggestedVersionCode &&
 | 
			
		||||
          response['suggestedVersionCode'] != null) {
 | 
			
		||||
        var suggestedReleases = releaseChoices.where((element) =>
 | 
			
		||||
      String? version;
 | 
			
		||||
      Iterable<dynamic> releaseChoices = [];
 | 
			
		||||
      // Grab the versionCode suggested if the user chose to do that
 | 
			
		||||
      // Only do so at this stage if the user has no release filter
 | 
			
		||||
      if (trySelectingSuggestedVersionCode &&
 | 
			
		||||
          response['suggestedVersionCode'] != null &&
 | 
			
		||||
          filterVersionsByRegEx == null) {
 | 
			
		||||
        var suggestedReleases = releases.where((element) =>
 | 
			
		||||
            element['versionCode'] == response['suggestedVersionCode']);
 | 
			
		||||
        if (suggestedReleases.isNotEmpty) {
 | 
			
		||||
          releaseChoices = suggestedReleases;
 | 
			
		||||
          version = suggestedReleases.first['versionName'];
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // Apply the release filter if any
 | 
			
		||||
      if (filterVersionsByRegEx?.isNotEmpty == true) {
 | 
			
		||||
        version = null;
 | 
			
		||||
        releaseChoices = [];
 | 
			
		||||
        for (var i = 0; i < releases.length; i++) {
 | 
			
		||||
          if (RegExp(filterVersionsByRegEx!)
 | 
			
		||||
              .hasMatch(releases[i]['versionName'])) {
 | 
			
		||||
            version = releases[i]['versionName'];
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        if (version == null) {
 | 
			
		||||
          throw NoVersionError();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // Default to the highest version
 | 
			
		||||
      version ??= releases[0]['versionName'];
 | 
			
		||||
      if (version == null) {
 | 
			
		||||
        throw NoVersionError();
 | 
			
		||||
      }
 | 
			
		||||
      // If a suggested release was not already picked, pick all those with the selected version
 | 
			
		||||
      if (releaseChoices.isEmpty) {
 | 
			
		||||
        releaseChoices =
 | 
			
		||||
            releases.where((element) => element['versionName'] == version);
 | 
			
		||||
      }
 | 
			
		||||
      // For the remaining releases, use the toggles to auto-select one if possible
 | 
			
		||||
      if (releaseChoices.length > 1) {
 | 
			
		||||
        if (autoSelectHighestVersionCode) {
 | 
			
		||||
          releaseChoices = [releaseChoices.first];
 | 
			
		||||
        } else if (trySelectingSuggestedVersionCode &&
 | 
			
		||||
            response['suggestedVersionCode'] != null) {
 | 
			
		||||
          var suggestedReleases = releaseChoices.where((element) =>
 | 
			
		||||
              element['versionCode'] == response['suggestedVersionCode']);
 | 
			
		||||
          if (suggestedReleases.isNotEmpty) {
 | 
			
		||||
            releaseChoices = suggestedReleases;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (releaseChoices.isEmpty) {
 | 
			
		||||
        throw NoReleasesError();
 | 
			
		||||
      }
 | 
			
		||||
      List<String> apkUrls = releaseChoices
 | 
			
		||||
          .map((e) => '${apkUrlPrefix}_${e['versionCode']}.apk')
 | 
			
		||||
          .toList();
 | 
			
		||||
      return APKDetails(version, getApkUrlsFromUrls(apkUrls.toSet().toList()),
 | 
			
		||||
          AppNames(sourceName, Uri.parse(standardUrl).pathSegments.last));
 | 
			
		||||
    } else {
 | 
			
		||||
      throw getObtainiumHttpError(res);
 | 
			
		||||
    }
 | 
			
		||||
    if (releaseChoices.isEmpty) {
 | 
			
		||||
      throw NoReleasesError();
 | 
			
		||||
    }
 | 
			
		||||
    List<String> apkUrls = releaseChoices
 | 
			
		||||
        .map((e) => '${apkUrlPrefix}_${e['versionCode']}.apk')
 | 
			
		||||
        .toList();
 | 
			
		||||
    return APKDetails(version, getApkUrlsFromUrls(apkUrls.toSet().toList()),
 | 
			
		||||
        AppNames(sourceName, Uri.parse(standardUrl).pathSegments.last));
 | 
			
		||||
  } else {
 | 
			
		||||
    throw getObtainiumHttpError(res);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -234,7 +234,7 @@ class GitHub extends AppSource {
 | 
			
		||||
    bool verifyLatestTag = additionalSettings['verifyLatestTag'] == true;
 | 
			
		||||
    bool dontSortReleasesList =
 | 
			
		||||
        additionalSettings['dontSortReleasesList'] == true;
 | 
			
		||||
    String? latestTag;
 | 
			
		||||
    dynamic latestRelease;
 | 
			
		||||
    if (verifyLatestTag) {
 | 
			
		||||
      var temp = requestUrl.split('?');
 | 
			
		||||
      Response res = await sourceRequest(
 | 
			
		||||
@@ -245,12 +245,20 @@ class GitHub extends AppSource {
 | 
			
		||||
        }
 | 
			
		||||
        throw getObtainiumHttpError(res);
 | 
			
		||||
      }
 | 
			
		||||
      var jsres = jsonDecode(res.body);
 | 
			
		||||
      latestTag = jsres['tag_name'] ?? jsres['name'];
 | 
			
		||||
      latestRelease = jsonDecode(res.body);
 | 
			
		||||
    }
 | 
			
		||||
    Response res = await sourceRequest(requestUrl);
 | 
			
		||||
    if (res.statusCode == 200) {
 | 
			
		||||
      var releases = jsonDecode(res.body) as List<dynamic>;
 | 
			
		||||
      if (latestRelease != null) {
 | 
			
		||||
        var latestTag = latestRelease['tag_name'] ?? latestRelease['name'];
 | 
			
		||||
        if (releases
 | 
			
		||||
            .where((element) =>
 | 
			
		||||
                (element['tag_name'] ?? element['name']) == latestTag)
 | 
			
		||||
            .isEmpty) {
 | 
			
		||||
          releases = [latestRelease, ...releases];
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      List<MapEntry<String, String>> getReleaseAPKUrls(dynamic release) =>
 | 
			
		||||
          (release['assets'] as List<dynamic>?)
 | 
			
		||||
@@ -299,13 +307,13 @@ class GitHub extends AppSource {
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
      if (latestTag != null &&
 | 
			
		||||
      if (latestRelease != null &&
 | 
			
		||||
          releases.isNotEmpty &&
 | 
			
		||||
          latestTag !=
 | 
			
		||||
          latestRelease !=
 | 
			
		||||
              (releases[releases.length - 1]['tag_name'] ??
 | 
			
		||||
                  releases[0]['name'])) {
 | 
			
		||||
        var ind = releases.indexWhere(
 | 
			
		||||
            (element) => latestTag == (element['tag_name'] ?? element['name']));
 | 
			
		||||
        var ind = releases.indexWhere((element) =>
 | 
			
		||||
            latestRelease == (element['tag_name'] ?? element['name']));
 | 
			
		||||
        if (ind >= 0) {
 | 
			
		||||
          releases.add(releases.removeAt(ind));
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -94,7 +94,8 @@ class HTML extends AppSource {
 | 
			
		||||
        GeneratedFormSwitch('sortByFileNamesNotLinks',
 | 
			
		||||
            label: tr('sortByFileNamesNotLinks'))
 | 
			
		||||
      ],
 | 
			
		||||
      [GeneratedFormSwitch('reverseSort', label: tr('reverseSort'))],
 | 
			
		||||
      [GeneratedFormSwitch('skipSort', label: tr('skipSort'))],
 | 
			
		||||
      [GeneratedFormSwitch('reverseSort', label: tr('takeTopLink'))],
 | 
			
		||||
      [
 | 
			
		||||
        GeneratedFormSwitch('supportFixedAPKURL',
 | 
			
		||||
            defaultValue: true, label: tr('supportFixedAPKURL')),
 | 
			
		||||
@@ -185,12 +186,15 @@ class HTML extends AppSource {
 | 
			
		||||
            .toList();
 | 
			
		||||
      }
 | 
			
		||||
      List<String> links = [];
 | 
			
		||||
      bool skipSort = additionalSettings['skipSort'] == true;
 | 
			
		||||
      if ((additionalSettings['intermediateLinkRegex'] as String?)
 | 
			
		||||
              ?.isNotEmpty ==
 | 
			
		||||
          true) {
 | 
			
		||||
        var reg = RegExp(additionalSettings['intermediateLinkRegex']);
 | 
			
		||||
        links = allLinks.where((element) => reg.hasMatch(element)).toList();
 | 
			
		||||
        links.sort((a, b) => compareAlphaNumeric(a, b));
 | 
			
		||||
        if (!skipSort) {
 | 
			
		||||
          links.sort((a, b) => compareAlphaNumeric(a, b));
 | 
			
		||||
        }
 | 
			
		||||
        if (links.isEmpty) {
 | 
			
		||||
          throw ObtainiumError(tr('intermediateLinkNotFound'));
 | 
			
		||||
        }
 | 
			
		||||
@@ -211,10 +215,14 @@ class HTML extends AppSource {
 | 
			
		||||
                Uri.parse(element).path.toLowerCase().endsWith('.apk'))
 | 
			
		||||
            .toList();
 | 
			
		||||
      }
 | 
			
		||||
      links.sort((a, b) => additionalSettings['sortByFileNamesNotLinks'] == true
 | 
			
		||||
          ? compareAlphaNumeric(a.split('/').where((e) => e.isNotEmpty).last,
 | 
			
		||||
              b.split('/').where((e) => e.isNotEmpty).last)
 | 
			
		||||
          : compareAlphaNumeric(a, b));
 | 
			
		||||
      if (!skipSort) {
 | 
			
		||||
        links.sort((a, b) =>
 | 
			
		||||
            additionalSettings['sortByFileNamesNotLinks'] == true
 | 
			
		||||
                ? compareAlphaNumeric(
 | 
			
		||||
                    a.split('/').where((e) => e.isNotEmpty).last,
 | 
			
		||||
                    b.split('/').where((e) => e.isNotEmpty).last)
 | 
			
		||||
                : compareAlphaNumeric(a, b));
 | 
			
		||||
      }
 | 
			
		||||
      if (additionalSettings['reverseSort'] == true) {
 | 
			
		||||
        links = links.reversed.toList();
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ class IzzyOnDroid extends AppSource {
 | 
			
		||||
    Map<String, dynamic> additionalSettings,
 | 
			
		||||
  ) async {
 | 
			
		||||
    String? appId = await tryInferringAppId(standardUrl);
 | 
			
		||||
    return getAPKUrlsFromFDroidPackagesAPIResponse(
 | 
			
		||||
    return fd.getAPKUrlsFromFDroidPackagesAPIResponse(
 | 
			
		||||
        await sourceRequest(
 | 
			
		||||
            'https://apt.izzysoft.de/fdroid/api/v1/packages/$appId'),
 | 
			
		||||
        'https://android.izzysoft.de/frepo/$appId',
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ import 'package:easy_localization/src/easy_localization_controller.dart';
 | 
			
		||||
// ignore: implementation_imports
 | 
			
		||||
import 'package:easy_localization/src/localization.dart';
 | 
			
		||||
 | 
			
		||||
const String currentVersion = '0.14.37';
 | 
			
		||||
const String currentVersion = '0.14.39';
 | 
			
		||||
const String currentReleaseTag =
 | 
			
		||||
    'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -347,7 +347,8 @@ class _ImportExportPageState extends State<ImportExportPage> {
 | 
			
		||||
                                        : () {
 | 
			
		||||
                                            runObtainiumExport(pickOnly: true);
 | 
			
		||||
                                          },
 | 
			
		||||
                                    child: Text(tr('pickExportDir')),
 | 
			
		||||
                                    child: Text(tr('pickExportDir'),
 | 
			
		||||
                                        textAlign: TextAlign.center),
 | 
			
		||||
                                  )),
 | 
			
		||||
                                  const SizedBox(
 | 
			
		||||
                                    width: 16,
 | 
			
		||||
@@ -360,7 +361,8 @@ class _ImportExportPageState extends State<ImportExportPage> {
 | 
			
		||||
                                            snapshot.data == null
 | 
			
		||||
                                        ? null
 | 
			
		||||
                                        : runObtainiumExport,
 | 
			
		||||
                                    child: Text(tr('obtainiumExport')),
 | 
			
		||||
                                    child: Text(tr('obtainiumExport'),
 | 
			
		||||
                                        textAlign: TextAlign.center),
 | 
			
		||||
                                  )),
 | 
			
		||||
                                ],
 | 
			
		||||
                              ),
 | 
			
		||||
@@ -375,7 +377,8 @@ class _ImportExportPageState extends State<ImportExportPage> {
 | 
			
		||||
                                          onPressed: importInProgress
 | 
			
		||||
                                              ? null
 | 
			
		||||
                                              : runObtainiumImport,
 | 
			
		||||
                                          child: Text(tr('obtainiumImport')))),
 | 
			
		||||
                                          child: Text(tr('obtainiumImport'),
 | 
			
		||||
                                              textAlign: TextAlign.center))),
 | 
			
		||||
                                ],
 | 
			
		||||
                              ),
 | 
			
		||||
                              if (snapshot.data != null)
 | 
			
		||||
 
 | 
			
		||||
@@ -327,6 +327,19 @@ class _SettingsPageState extends State<SettingsPage> {
 | 
			
		||||
                                    })
 | 
			
		||||
                              ],
 | 
			
		||||
                            ),
 | 
			
		||||
                            height16,
 | 
			
		||||
                            Row(
 | 
			
		||||
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
			
		||||
                              children: [
 | 
			
		||||
                                Flexible(child: Text(tr('parallelDownloads'))),
 | 
			
		||||
                                Switch(
 | 
			
		||||
                                    value: settingsProvider.parallelDownloads,
 | 
			
		||||
                                    onChanged: (value) {
 | 
			
		||||
                                      settingsProvider.parallelDownloads =
 | 
			
		||||
                                          value;
 | 
			
		||||
                                    })
 | 
			
		||||
                              ],
 | 
			
		||||
                            ),
 | 
			
		||||
                            height32,
 | 
			
		||||
                            Text(
 | 
			
		||||
                              tr('sourceSpecific'),
 | 
			
		||||
 
 | 
			
		||||
@@ -657,7 +657,7 @@ class AppsProvider with ChangeNotifier {
 | 
			
		||||
    appsToInstall =
 | 
			
		||||
        moveStrToEnd(appsToInstall, obtainiumId, strB: obtainiumTempId);
 | 
			
		||||
 | 
			
		||||
    for (var id in appsToInstall) {
 | 
			
		||||
    Future<void> updateFn(String id, {bool skipInstalls = false}) async {
 | 
			
		||||
      try {
 | 
			
		||||
        var downloadedArtifact =
 | 
			
		||||
            // ignore: use_build_context_synchronously
 | 
			
		||||
@@ -682,24 +682,26 @@ class AppsProvider with ChangeNotifier {
 | 
			
		||||
        apps[id]?.downloadProgress = -1;
 | 
			
		||||
        notifyListeners();
 | 
			
		||||
        try {
 | 
			
		||||
          if (downloadedFile != null) {
 | 
			
		||||
            if (willBeSilent && context == null) {
 | 
			
		||||
              installApk(downloadedFile, needsBGWorkaround: true);
 | 
			
		||||
          if (!skipInstalls) {
 | 
			
		||||
            if (downloadedFile != null) {
 | 
			
		||||
              if (willBeSilent && context == null) {
 | 
			
		||||
                installApk(downloadedFile, needsBGWorkaround: true);
 | 
			
		||||
              } else {
 | 
			
		||||
                await installApk(downloadedFile);
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              await installApk(downloadedFile);
 | 
			
		||||
              if (willBeSilent && context == null) {
 | 
			
		||||
                installXApkDir(downloadedDir!, needsBGWorkaround: true);
 | 
			
		||||
              } else {
 | 
			
		||||
                await installXApkDir(downloadedDir!);
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          } else {
 | 
			
		||||
            if (willBeSilent && context == null) {
 | 
			
		||||
              installXApkDir(downloadedDir!, needsBGWorkaround: true);
 | 
			
		||||
            } else {
 | 
			
		||||
              await installXApkDir(downloadedDir!);
 | 
			
		||||
              notificationsProvider?.notify(SilentUpdateAttemptNotification(
 | 
			
		||||
                  [apps[appId]!.app],
 | 
			
		||||
                  id: appId.hashCode));
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          if (willBeSilent && context == null) {
 | 
			
		||||
            notificationsProvider?.notify(SilentUpdateAttemptNotification(
 | 
			
		||||
                [apps[appId]!.app],
 | 
			
		||||
                id: appId.hashCode));
 | 
			
		||||
          }
 | 
			
		||||
        } finally {
 | 
			
		||||
          apps[id]?.downloadProgress = null;
 | 
			
		||||
          notifyListeners();
 | 
			
		||||
@@ -710,6 +712,18 @@ class AppsProvider with ChangeNotifier {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!settingsProvider.parallelDownloads) {
 | 
			
		||||
      for (var id in appsToInstall) {
 | 
			
		||||
        await updateFn(id);
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      await Future.wait(
 | 
			
		||||
          appsToInstall.map((id) => updateFn(id, skipInstalls: true)));
 | 
			
		||||
      for (var id in appsToInstall) {
 | 
			
		||||
        await updateFn(id);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (errors.idsByErrorString.isNotEmpty) {
 | 
			
		||||
      throw errors;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1230,7 +1244,7 @@ class AppsProvider with ChangeNotifier {
 | 
			
		||||
 | 
			
		||||
  Future<MapEntry<int, bool>> import(String appsJSON) async {
 | 
			
		||||
    var decodedJSON = jsonDecode(appsJSON);
 | 
			
		||||
    var newFormat = !(decodedJSON is List);
 | 
			
		||||
    var newFormat = decodedJSON is! List;
 | 
			
		||||
    List<App> importedApps =
 | 
			
		||||
        ((newFormat ? decodedJSON['apps'] : decodedJSON) as List<dynamic>)
 | 
			
		||||
            .map((e) => App.fromJson(e))
 | 
			
		||||
 
 | 
			
		||||
@@ -425,4 +425,13 @@ class SettingsProvider with ChangeNotifier {
 | 
			
		||||
    prefs?.setBool('exportSettings', val);
 | 
			
		||||
    notifyListeners();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool get parallelDownloads {
 | 
			
		||||
    return prefs?.getBool('parallelDownloads') ?? false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  set parallelDownloads(bool val) {
 | 
			
		||||
    prefs?.setBool('parallelDownloads', val);
 | 
			
		||||
    notifyListeners();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -684,8 +684,9 @@ class SourceProvider {
 | 
			
		||||
    name = name.isNotEmpty ? name : apk.names.name;
 | 
			
		||||
    App finalApp = App(
 | 
			
		||||
        currentApp?.id ??
 | 
			
		||||
            ((!source.appIdInferIsOptional ||
 | 
			
		||||
                    (source.appIdInferIsOptional && inferAppIdIfOptional))
 | 
			
		||||
            (!trackOnly &&
 | 
			
		||||
                    (!source.appIdInferIsOptional ||
 | 
			
		||||
                        (source.appIdInferIsOptional && inferAppIdIfOptional))
 | 
			
		||||
                ? await source.tryInferringAppId(standardUrl,
 | 
			
		||||
                    additionalSettings: additionalSettings)
 | 
			
		||||
                : null) ??
 | 
			
		||||
@@ -705,8 +706,9 @@ class SourceProvider {
 | 
			
		||||
        changeLog: apk.changeLog,
 | 
			
		||||
        overrideSource: overrideSource ?? currentApp?.overrideSource,
 | 
			
		||||
        allowIdChange: currentApp?.allowIdChange ??
 | 
			
		||||
            source.appIdInferIsOptional &&
 | 
			
		||||
                inferAppIdIfOptional // Optional ID inferring may be incorrect - allow correction on first install
 | 
			
		||||
            trackOnly ||
 | 
			
		||||
                (source.appIdInferIsOptional &&
 | 
			
		||||
                    inferAppIdIfOptional) // Optional ID inferring may be incorrect - allow correction on first install
 | 
			
		||||
        );
 | 
			
		||||
    return source.endOfGetAppChanges(finalApp);
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								pubspec.lock
									
									
									
									
									
								
							@@ -206,10 +206,10 @@ packages:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: dynamic_color
 | 
			
		||||
      sha256: "8b8bd1d798bd393e11eddeaa8ae95b12ff028bf7d5998fc5d003488cd5f4ce2f"
 | 
			
		||||
      sha256: a866f1f8947bfdaf674d7928e769eac7230388a2e7a2542824fad4bb5b87be3b
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.6.8"
 | 
			
		||||
    version: "1.6.9"
 | 
			
		||||
  easy_localization:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
@@ -267,10 +267,10 @@ packages:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: flutter_archive
 | 
			
		||||
      sha256: aec85d1da65e5b33a529db00a86df0b8e92bda78088a7cfaeeba5187701d0d85
 | 
			
		||||
      sha256: "004132780d382df5171589ab793e2efc9c3eef570fe72d78b4ccfbfbe52762ae"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "5.0.0"
 | 
			
		||||
    version: "6.0.0"
 | 
			
		||||
  flutter_fgbg:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
@@ -783,10 +783,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: synchronized
 | 
			
		||||
      sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60"
 | 
			
		||||
      sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.1.0"
 | 
			
		||||
    version: "3.1.0+1"
 | 
			
		||||
  term_glyph:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -919,26 +919,26 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: webview_flutter_android
 | 
			
		||||
      sha256: e313dcdf45d4c95bcb8960351ef2389b7f0687b90bc92483f7f7983ae5758456
 | 
			
		||||
      sha256: b54c89fe14a6d26a2a46e24880da0441cdd2bf1f6d01a5b3e1d39558feb1de0b
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.13.0"
 | 
			
		||||
    version: "3.13.1"
 | 
			
		||||
  webview_flutter_platform_interface:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: webview_flutter_platform_interface
 | 
			
		||||
      sha256: "68e86162aa8fc646ae859e1585995c096c95fc2476881fa0c4a8d10f56013a5a"
 | 
			
		||||
      sha256: dbe745ee459a16b6fec296f7565a8ef430d0d681001d8ae521898b9361854943
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.8.0"
 | 
			
		||||
    version: "2.9.0"
 | 
			
		||||
  webview_flutter_wkwebview:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: webview_flutter_wkwebview
 | 
			
		||||
      sha256: accdaaa49a2aca2dc3c3230907988954cdd23fed0a19525d6c9789d380f4dc76
 | 
			
		||||
      sha256: eebfabfa8a115b535b52031b8b26f7a4b58ceceab378bc9db8762b0fb46f7b5d
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.9.4"
 | 
			
		||||
    version: "3.10.0"
 | 
			
		||||
  win32:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
 
 | 
			
		||||
@@ -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.14.37+231 # When changing this, update the tag in main() accordingly
 | 
			
		||||
version: 0.14.39+233 # When changing this, update the tag in main() accordingly
 | 
			
		||||
 | 
			
		||||
environment:
 | 
			
		||||
  sdk: '>=3.0.0 <4.0.0'
 | 
			
		||||
@@ -62,7 +62,7 @@ dependencies:
 | 
			
		||||
  easy_localization: ^3.0.1
 | 
			
		||||
  android_intent_plus: ^4.0.0
 | 
			
		||||
  flutter_markdown: ^0.6.14
 | 
			
		||||
  flutter_archive: ^5.0.0
 | 
			
		||||
  flutter_archive: ^6.0.0
 | 
			
		||||
  hsluv: ^1.1.3
 | 
			
		||||
  connectivity_plus: ^5.0.0
 | 
			
		||||
  shared_storage: ^0.8.0
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user