mirror of
				https://github.com/ImranR98/Obtainium.git
				synced 2025-10-31 13:33:28 +01:00 
			
		
		
		
	Compare commits
	
		
			51 Commits
		
	
	
		
			7e270e036f
			...
			dev
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | d21feaaf74 | ||
|  | c0c0e2a5c5 | ||
|  | 60e7bba5d9 | ||
|  | 6654406c81 | ||
|  | f5cbbfcace | ||
|  | 8bdc0f8d12 | ||
|  | a980b00600 | ||
|  | 7a385843f9 | ||
|  | 7cb9ca128b | ||
|  | ced7b13777 | ||
|  | 41f37f6d32 | ||
|  | fef0120732 | ||
|  | 6830eb64d0 | ||
|  | b4506c4c3f | ||
|  | 3af185b0f8 | ||
|  | bfbb2710b6 | ||
|  | c81c3c5ea7 | ||
|  | 7391e9a94d | ||
|  | 04633131e7 | ||
|  | 7bc818fbfa | ||
|  | 4afcd92510 | ||
|  | 0784f83792 | ||
|  | a6608f1461 | ||
|  | 08d9c4daaa | ||
|  | 225362d351 | ||
|  | 089bf97ff2 | ||
|  | 123cd5b130 | ||
|  | bc24f008fa | ||
|  | 472ec4e400 | ||
|  | a56069e881 | ||
|  | a34e45363b | ||
|  | e1a89f5f67 | ||
|  | f7f6e0cde7 | ||
|  | 5a58522bf6 | ||
|  | 9347af2090 | ||
|  | b294e57367 | ||
|  | 4234e16432 | ||
|  | a64f2e1af7 | ||
|  | 926462407c | ||
|  | 1b499700fd | ||
|  | 930a4b411e | ||
|  | b9931e00e7 | ||
|  | 2337e04ee1 | ||
|  | 2fc8dafc9e | ||
|  | 0603c6a1d3 | ||
|  | 555284d2cb | ||
|  | 357e2b8a89 | ||
|  | 5b147b82e0 | ||
|  | 87ef762eec | ||
|  | 9ac963557e | ||
|  | bad76a1ee7 | 
							
								
								
									
										2
									
								
								.flutter
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								.flutter
									
									
									
									
									
								
							 Submodule .flutter updated: edada7c56e...9f455d2486
									
								
							| @@ -1,6 +1,7 @@ | |||||||
| import java.io.FileInputStream | import java.io.FileInputStream | ||||||
| import java.util.Properties | import java.util.Properties | ||||||
| import com.android.build.api.variant.FilterConfiguration.FilterType.* | import com.android.build.api.variant.FilterConfiguration.FilterType.* | ||||||
|  | import com.android.build.gradle.internal.api.ApkVariantOutputImpl | ||||||
|  |  | ||||||
| plugins { | plugins { | ||||||
|     id("com.android.application") |     id("com.android.application") | ||||||
| @@ -86,18 +87,17 @@ android { | |||||||
|  |  | ||||||
| val abiCodes = mapOf("x86_64" to 1, "armeabi-v7a" to 2, "arm64-v8a" to 3) | val abiCodes = mapOf("x86_64" to 1, "armeabi-v7a" to 2, "arm64-v8a" to 3) | ||||||
|  |  | ||||||
| androidComponents { | android.applicationVariants.configureEach { | ||||||
|     onVariants { variant -> |     val variant = this | ||||||
|     variant.outputs.forEach { output -> |     variant.outputs.forEach { output -> | ||||||
|             val name = output.filters.find { it.filterType == ABI }?.identifier |         val abiVersionCode = abiCodes[output.filters.find { it.filterType == "ABI" }?.identifier] | ||||||
|             val baseAbiCode = abiCodes[name] ?: 0 |         if (abiVersionCode != null) { | ||||||
|             if (baseAbiCode != null) { |             (output as ApkVariantOutputImpl).versionCodeOverride = variant.versionCode * 10 + abiVersionCode | ||||||
|                 output.versionCode.set(baseAbiCode + ((output.versionCode.get() ?: 0) * 10)) |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| dependencies { | dependencies { | ||||||
|     coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5") |     coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5") | ||||||
| } | } | ||||||
|   | |||||||
| @@ -74,7 +74,6 @@ | |||||||
|     <uses-permission android:name="android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION" /> |     <uses-permission android:name="android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION" /> | ||||||
|     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> |     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> | ||||||
|     <uses-permission android:name="android.permission.WAKE_LOCK" /> |     <uses-permission android:name="android.permission.WAKE_LOCK" /> | ||||||
|     <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> |  | ||||||
|     <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" /> |     <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" /> | ||||||
|     <uses-permission android:name="android.permission.ENFORCE_UPDATE_OWNERSHIP"/> |     <uses-permission android:name="android.permission.ENFORCE_UPDATE_OWNERSHIP"/> | ||||||
|     <uses-permission |     <uses-permission | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "التحقق من علامة 'الأحدث'", |     "verifyLatestTag": "التحقق من علامة 'الأحدث'", | ||||||
|     "intermediateLinkRegex": "تصفية للوصول إلى رابط 'وسيط'", |     "intermediateLinkRegex": "تصفية للوصول إلى رابط 'وسيط'", | ||||||
|     "filterByLinkText": "تصفية الروابط حسب نص الرابط", |     "filterByLinkText": "تصفية الروابط حسب نص الرابط", | ||||||
|  |     "matchLinksOutsideATags": "تطابق الروابط خارج علامات <a>", | ||||||
|     "intermediateLinkNotFound": "لم يتم العثور على رابط وسيط", |     "intermediateLinkNotFound": "لم يتم العثور على رابط وسيط", | ||||||
|     "intermediateLink": "رابط وسيط", |     "intermediateLink": "رابط وسيط", | ||||||
|     "exemptFromBackgroundUpdates": "إعفاء من التحديثات في الخلفية (إذا تم تمكينها)", |     "exemptFromBackgroundUpdates": "إعفاء من التحديثات في الخلفية (إذا تم تمكينها)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "استخدام خدمة مقدمة للتحقق من التحديثات (أكثر موثوقية وتستهلك طاقة أكبر)", |     "foregroundServiceExplanation": "استخدام خدمة مقدمة للتحقق من التحديثات (أكثر موثوقية وتستهلك طاقة أكبر)", | ||||||
|     "fgServiceNotice": "هذا الإشعار مطلوب للتحقق من التحديث في الخلفية (يمكن إخفاؤه في إعدادات نظام التشغيل)", |     "fgServiceNotice": "هذا الإشعار مطلوب للتحقق من التحديث في الخلفية (يمكن إخفاؤه في إعدادات نظام التشغيل)", | ||||||
|     "excludeSecrets": "استبعاد الأسرار", |     "excludeSecrets": "استبعاد الأسرار", | ||||||
|  |     "GHReqPrefix": "مثيل \"sky22333/hubproxy\" لطلبات GitHub", | ||||||
|  |     "includeZips": "تضمين ملفات ZIP", | ||||||
|  |     "zippedApkFilterRegEx": "تصفية ملفات APK داخل ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "إزالة التطبيق؟", |         "one": "إزالة التطبيق؟", | ||||||
|         "other": "إزالة التطبيقات؟" |         "other": "إزالة التطبيقات؟" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Provjerite 'posljednu' ('latest') oznaku", |     "verifyLatestTag": "Provjerite 'posljednu' ('latest') oznaku", | ||||||
|     "intermediateLinkRegex": "Filter za 'srednju' vezu za posjetu", |     "intermediateLinkRegex": "Filter za 'srednju' vezu za posjetu", | ||||||
|     "filterByLinkText": "Filtriraj linkove prema tekstu linka", |     "filterByLinkText": "Filtriraj linkove prema tekstu linka", | ||||||
|  |     "matchLinksOutsideATags": "Match links outside <a> tags", | ||||||
|     "intermediateLinkNotFound": "Intermediate veza nije nađena", |     "intermediateLinkNotFound": "Intermediate veza nije nađena", | ||||||
|     "intermediateLink": "Intermediate veza", |     "intermediateLink": "Intermediate veza", | ||||||
|     "exemptFromBackgroundUpdates": "Izuzmi iz ažuriranja u pozadini (ako su uključeni)", |     "exemptFromBackgroundUpdates": "Izuzmi iz ažuriranja u pozadini (ako su uključeni)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)", |     "foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)", | ||||||
|     "fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)", |     "fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)", | ||||||
|     "excludeSecrets": "Exclude secrets", |     "excludeSecrets": "Exclude secrets", | ||||||
|  |     "GHReqPrefix": "'sky22333/hubproxy' instance for GitHub requests", | ||||||
|  |     "includeZips": "Include ZIP files", | ||||||
|  |     "zippedApkFilterRegEx": "Filter APKs inside ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Želite li ukloniti aplikaciju?", |         "one": "Želite li ukloniti aplikaciju?", | ||||||
|         "other": "Želite li ukloniti aplikacije?" |         "other": "Želite li ukloniti aplikacije?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Comprova l'etiqueta 'Latest' (última versió)", |     "verifyLatestTag": "Comprova l'etiqueta 'Latest' (última versió)", | ||||||
|     "intermediateLinkRegex": "Filtra per un enllaç 'intermediari' per anar-hi", |     "intermediateLinkRegex": "Filtra per un enllaç 'intermediari' per anar-hi", | ||||||
|     "filterByLinkText": "Filtra els enllaços pel text de l'enllaç", |     "filterByLinkText": "Filtra els enllaços pel text de l'enllaç", | ||||||
|  |     "matchLinksOutsideATags": "Match links outside <a> tags", | ||||||
|     "intermediateLinkNotFound": "No s'ha trobat l'enllaç intermediari", |     "intermediateLinkNotFound": "No s'ha trobat l'enllaç intermediari", | ||||||
|     "intermediateLink": "Enllaç intermediari", |     "intermediateLink": "Enllaç intermediari", | ||||||
|     "exemptFromBackgroundUpdates": "Exempta d'actualitzacions en segon pla (si han estat habilitades)", |     "exemptFromBackgroundUpdates": "Exempta d'actualitzacions en segon pla (si han estat habilitades)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Usa el servei d'Obtainium en primer pla per comprovar les actualitzacions (és més fiable però consumeix més bateria)", |     "foregroundServiceExplanation": "Usa el servei d'Obtainium en primer pla per comprovar les actualitzacions (és més fiable però consumeix més bateria)", | ||||||
|     "fgServiceNotice": "Aquesta notificació és necessària per comprovar les actualitzacions en segon pla (la pots ocultar als paràmetres del Sistema Operatiu)", |     "fgServiceNotice": "Aquesta notificació és necessària per comprovar les actualitzacions en segon pla (la pots ocultar als paràmetres del Sistema Operatiu)", | ||||||
|     "excludeSecrets": "Exclude secrets", |     "excludeSecrets": "Exclude secrets", | ||||||
|  |     "GHReqPrefix": "'sky22333/hubproxy' instance for GitHub requests", | ||||||
|  |     "includeZips": "Include ZIP files", | ||||||
|  |     "zippedApkFilterRegEx": "Filter APKs inside ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "¿Suprimeixo l'aplicació?", |         "one": "¿Suprimeixo l'aplicació?", | ||||||
|         "other": "¿Suprimeixo les aplicacions?" |         "other": "¿Suprimeixo les aplicacions?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Ověřit značku „latest“", |     "verifyLatestTag": "Ověřit značku „latest“", | ||||||
|     "intermediateLinkRegex": "Filtr pro návštěvu „prostředního“ odkazu", |     "intermediateLinkRegex": "Filtr pro návštěvu „prostředního“ odkazu", | ||||||
|     "filterByLinkText": "Filtrovat odkazy podle textu odkazu", |     "filterByLinkText": "Filtrovat odkazy podle textu odkazu", | ||||||
|  |     "matchLinksOutsideATags": "Shoda odkazů mimo značky <a>", | ||||||
|     "intermediateLinkNotFound": "Připojený odkaz nenalezen", |     "intermediateLinkNotFound": "Připojený odkaz nenalezen", | ||||||
|     "intermediateLink": "Připojený odkaz", |     "intermediateLink": "Připojený odkaz", | ||||||
|     "exemptFromBackgroundUpdates": "Vyloučit z aktualizací na pozadí (je-li povoleno)", |     "exemptFromBackgroundUpdates": "Vyloučit z aktualizací na pozadí (je-li povoleno)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Použít službu v popředí pro kontrolu aktualizací (spolehlivější, spotřebovává více energie)", |     "foregroundServiceExplanation": "Použít službu v popředí pro kontrolu aktualizací (spolehlivější, spotřebovává více energie)", | ||||||
|     "fgServiceNotice": "Toto oznámení je nutné pro kontrolu aktualizací na pozadí (lze jej skrýt v nastavení systému)", |     "fgServiceNotice": "Toto oznámení je nutné pro kontrolu aktualizací na pozadí (lze jej skrýt v nastavení systému)", | ||||||
|     "excludeSecrets": "Vyloučit tajemství", |     "excludeSecrets": "Vyloučit tajemství", | ||||||
|  |     "GHReqPrefix": "instance 'sky22333/hubproxy' pro požadavky GitHubu", | ||||||
|  |     "includeZips": "Zahrnout soubory ZIP", | ||||||
|  |     "zippedApkFilterRegEx": "Filtrování souborů APK uvnitř ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Odstranit aplikaci?", |         "one": "Odstranit aplikaci?", | ||||||
|         "other": "Odstranit aplikace?" |         "other": "Odstranit aplikace?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Verificer 'seneste'-tagget", |     "verifyLatestTag": "Verificer 'seneste'-tagget", | ||||||
|     "intermediateLinkRegex": "Filtrer efter et 'mellemliggende' link at besøge", |     "intermediateLinkRegex": "Filtrer efter et 'mellemliggende' link at besøge", | ||||||
|     "filterByLinkText": "Filtrer links efter linktekst", |     "filterByLinkText": "Filtrer links efter linktekst", | ||||||
|  |     "matchLinksOutsideATags": "Match links uden for <a>-tags", | ||||||
|     "intermediateLinkNotFound": "Mellemliggende link ikke fundet", |     "intermediateLinkNotFound": "Mellemliggende link ikke fundet", | ||||||
|     "intermediateLink": "Mellemliggende link", |     "intermediateLink": "Mellemliggende link", | ||||||
|     "exemptFromBackgroundUpdates": "Undtag fra baggrundsopdateringer (hvis aktiveret)", |     "exemptFromBackgroundUpdates": "Undtag fra baggrundsopdateringer (hvis aktiveret)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Brug en forgrundstjeneste til opdateringskontrol (mere pålidelig, bruger mere strøm)", |     "foregroundServiceExplanation": "Brug en forgrundstjeneste til opdateringskontrol (mere pålidelig, bruger mere strøm)", | ||||||
|     "fgServiceNotice": "Denne meddelelse er nødvendig for baggrundsopdateringskontrol (den kan skjules i OS-indstillingerne).", |     "fgServiceNotice": "Denne meddelelse er nødvendig for baggrundsopdateringskontrol (den kan skjules i OS-indstillingerne).", | ||||||
|     "excludeSecrets": "Udeluk hemmeligheder", |     "excludeSecrets": "Udeluk hemmeligheder", | ||||||
|  |     "GHReqPrefix": "'sky22333/hubproxy'-instans til GitHub-anmodninger", | ||||||
|  |     "includeZips": "Inkluder ZIP-filer", | ||||||
|  |     "zippedApkFilterRegEx": "Filtrer APK'er inde i ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Fjern app?", |         "one": "Fjern app?", | ||||||
|         "other": "Fjern apps?" |         "other": "Fjern apps?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "„Latest“-Tag überprüfen", |     "verifyLatestTag": "„Latest“-Tag überprüfen", | ||||||
|     "intermediateLinkRegex": "Filter für einen „Zwischen“-Link, der zuerst besucht werden soll", |     "intermediateLinkRegex": "Filter für einen „Zwischen“-Link, der zuerst besucht werden soll", | ||||||
|     "filterByLinkText": "Links durch Linktext filtern", |     "filterByLinkText": "Links durch Linktext filtern", | ||||||
|  |     "matchLinksOutsideATags": "Links außerhalb von <a>-Tags anpassen", | ||||||
|     "intermediateLinkNotFound": "„Zwischen“-Link nicht gefunden", |     "intermediateLinkNotFound": "„Zwischen“-Link nicht gefunden", | ||||||
|     "intermediateLink": "„Zwischen“-Link", |     "intermediateLink": "„Zwischen“-Link", | ||||||
|     "exemptFromBackgroundUpdates": "Von Hintergrundaktualisierungen (falls aktiviert) ausschließen", |     "exemptFromBackgroundUpdates": "Von Hintergrundaktualisierungen (falls aktiviert) ausschließen", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Aktualisierungsprüfung im Vordergrund durchführen (zuverlässiger, verbraucht mehr Strom)", |     "foregroundServiceExplanation": "Aktualisierungsprüfung im Vordergrund durchführen (zuverlässiger, verbraucht mehr Strom)", | ||||||
|     "fgServiceNotice": "Diese Benachrichtigung ist für die Prüfung von Updates im Hintergrund erforderlich (sie kann in den Betriebssystemeinstellungen ausgeblendet werden)", |     "fgServiceNotice": "Diese Benachrichtigung ist für die Prüfung von Updates im Hintergrund erforderlich (sie kann in den Betriebssystemeinstellungen ausgeblendet werden)", | ||||||
|     "excludeSecrets": "Geheimnisse ausschließen", |     "excludeSecrets": "Geheimnisse ausschließen", | ||||||
|  |     "GHReqPrefix": "sky22333/hubproxy'-Instanz für GitHub-Anfragen", | ||||||
|  |     "includeZips": "ZIP-Dateien einbeziehen", | ||||||
|  |     "zippedApkFilterRegEx": "APKs in ZIP filtern", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "App entfernen?", |         "one": "App entfernen?", | ||||||
|         "other": "Apps entfernen?" |         "other": "Apps entfernen?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Inspekti la etikedon 'latest'", |     "verifyLatestTag": "Inspekti la etikedon 'latest'", | ||||||
|     "intermediateLinkRegex": "Filtri por 'pera' vizitota ligilo", |     "intermediateLinkRegex": "Filtri por 'pera' vizitota ligilo", | ||||||
|     "filterByLinkText": "Filtri ligilojn laŭ ligiloteksto", |     "filterByLinkText": "Filtri ligilojn laŭ ligiloteksto", | ||||||
|  |     "matchLinksOutsideATags": "Match links outside <a> tags", | ||||||
|     "intermediateLinkNotFound": "Netrovebla pera ligilo", |     "intermediateLinkNotFound": "Netrovebla pera ligilo", | ||||||
|     "intermediateLink": "Pera ligilo", |     "intermediateLink": "Pera ligilo", | ||||||
|     "exemptFromBackgroundUpdates": "Escepti el la fonaj ĝisdatigoj (se aktiva)", |     "exemptFromBackgroundUpdates": "Escepti el la fonaj ĝisdatigoj (se aktiva)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)", |     "foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)", | ||||||
|     "fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)", |     "fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)", | ||||||
|     "excludeSecrets": "Exclude secrets", |     "excludeSecrets": "Exclude secrets", | ||||||
|  |     "GHReqPrefix": "'sky22333/hubproxy' instance for GitHub requests", | ||||||
|  |     "includeZips": "Include ZIP files", | ||||||
|  |     "zippedApkFilterRegEx": "Filter APKs inside ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Forigi la aplikaĵon?", |         "one": "Forigi la aplikaĵon?", | ||||||
|         "other": "Forigi la aplikaĵojn?" |         "other": "Forigi la aplikaĵojn?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Verify the 'latest' tag", |     "verifyLatestTag": "Verify the 'latest' tag", | ||||||
|     "intermediateLinkRegex": "Filter for an 'intermediate' link to visit", |     "intermediateLinkRegex": "Filter for an 'intermediate' link to visit", | ||||||
|     "filterByLinkText": "Filter links by link text", |     "filterByLinkText": "Filter links by link text", | ||||||
|  |     "matchLinksOutsideATags": "Match links outside <a> tags", | ||||||
|     "intermediateLinkNotFound": "Intermediate link not found", |     "intermediateLinkNotFound": "Intermediate link not found", | ||||||
|     "intermediateLink": "Intermediate link", |     "intermediateLink": "Intermediate link", | ||||||
|     "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", |     "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)", |     "foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)", | ||||||
|     "fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)", |     "fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)", | ||||||
|     "excludeSecrets": "Exclude secrets", |     "excludeSecrets": "Exclude secrets", | ||||||
|  |     "GHReqPrefix": "'sky22333/hubproxy' instance for GitHub requests", | ||||||
|  |     "includeZips": "Include ZIP files", | ||||||
|  |     "zippedApkFilterRegEx": "Filter APKs inside ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Remove app?", |         "one": "Remove app?", | ||||||
|         "other": "Remove apps?" |         "other": "Remove apps?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Comprobar etiqueta 'Latest'", |     "verifyLatestTag": "Comprobar etiqueta 'Latest'", | ||||||
|     "intermediateLinkRegex": "Filtrar por enlace 'intermedio' para visitar primero", |     "intermediateLinkRegex": "Filtrar por enlace 'intermedio' para visitar primero", | ||||||
|     "filterByLinkText": "Filtrar enlaces por texto del enlace", |     "filterByLinkText": "Filtrar enlaces por texto del enlace", | ||||||
|  |     "matchLinksOutsideATags": "Enlaces coincidentes fuera de las etiquetas <a>", | ||||||
|     "intermediateLinkNotFound": "Enlace intermedio no encontrado", |     "intermediateLinkNotFound": "Enlace intermedio no encontrado", | ||||||
|     "intermediateLink": "Enlace intermedio", |     "intermediateLink": "Enlace intermedio", | ||||||
|     "exemptFromBackgroundUpdates": "No actualizar en segundo plano (si está habilitado)", |     "exemptFromBackgroundUpdates": "No actualizar en segundo plano (si está habilitado)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Usar un servicio en primer plano para comprobar las actualizaciones (más fiable, consume más energía).", |     "foregroundServiceExplanation": "Usar un servicio en primer plano para comprobar las actualizaciones (más fiable, consume más energía).", | ||||||
|     "fgServiceNotice": "Esta notificación es necesaria para la comprobación de actualizaciones en segundo plano (puede ocultarse en la configuración del sistema operativo).", |     "fgServiceNotice": "Esta notificación es necesaria para la comprobación de actualizaciones en segundo plano (puede ocultarse en la configuración del sistema operativo).", | ||||||
|     "excludeSecrets": "Excluir secretos", |     "excludeSecrets": "Excluir secretos", | ||||||
|  |     "GHReqPrefix": "Instancia \"sky22333/hubproxy\" para las solicitudes de GitHub", | ||||||
|  |     "includeZips": "Incluir archivos ZIP", | ||||||
|  |     "zippedApkFilterRegEx": "Filtrar APKs dentro de ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "¿Eliminar aplicación?", |         "one": "¿Eliminar aplicación?", | ||||||
|         "other": "¿Eliminar aplicaciones?" |         "other": "¿Eliminar aplicaciones?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "برچسب \"آخرین\" را تأیید کنید", |     "verifyLatestTag": "برچسب \"آخرین\" را تأیید کنید", | ||||||
|     "intermediateLinkRegex": "برای بازدید از پیوند «میانگین» فیلتر کنید", |     "intermediateLinkRegex": "برای بازدید از پیوند «میانگین» فیلتر کنید", | ||||||
|     "filterByLinkText": "لینک ها را بر اساس متن پیوند فیلتر کنید", |     "filterByLinkText": "لینک ها را بر اساس متن پیوند فیلتر کنید", | ||||||
|  |     "matchLinksOutsideATags": "Match links outside <a> tags", | ||||||
|     "intermediateLinkNotFound": "لینک میانی پیدا نشد", |     "intermediateLinkNotFound": "لینک میانی پیدا نشد", | ||||||
|     "intermediateLink": "پیوند میانی", |     "intermediateLink": "پیوند میانی", | ||||||
|     "exemptFromBackgroundUpdates": "معاف از بهروزرسانیهای پسزمینه (در صورت فعال بودن)", |     "exemptFromBackgroundUpdates": "معاف از بهروزرسانیهای پسزمینه (در صورت فعال بودن)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)", |     "foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)", | ||||||
|     "fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)", |     "fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)", | ||||||
|     "excludeSecrets": "Exclude secrets", |     "excludeSecrets": "Exclude secrets", | ||||||
|  |     "GHReqPrefix": "'sky22333/hubproxy' instance for GitHub requests", | ||||||
|  |     "includeZips": "Include ZIP files", | ||||||
|  |     "zippedApkFilterRegEx": "Filter APKs inside ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "برنامه حذف شود؟", |         "one": "برنامه حذف شود؟", | ||||||
|         "other": "برنامه ها حذف شوند؟" |         "other": "برنامه ها حذف شوند؟" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Vérifier la balise 'latest'", |     "verifyLatestTag": "Vérifier la balise 'latest'", | ||||||
|     "intermediateLinkRegex": "Filtrer un lien 'intermédiaire' à visiter", |     "intermediateLinkRegex": "Filtrer un lien 'intermédiaire' à visiter", | ||||||
|     "filterByLinkText": "Filtrer les liens par texte du lien", |     "filterByLinkText": "Filtrer les liens par texte du lien", | ||||||
|  |     "matchLinksOutsideATags": "Liens en dehors des balises <a>", | ||||||
|     "intermediateLinkNotFound": "Lien intermédiaire introuvable", |     "intermediateLinkNotFound": "Lien intermédiaire introuvable", | ||||||
|     "intermediateLink": "Lien intermédiaire", |     "intermediateLink": "Lien intermédiaire", | ||||||
|     "exemptFromBackgroundUpdates": "Exclure des mises à jour en arrière-plan (si activées)", |     "exemptFromBackgroundUpdates": "Exclure des mises à jour en arrière-plan (si activées)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Utiliser un service de premier plan pour la vérification des mises à jour (plus fiable, consomme plus d'énergie)", |     "foregroundServiceExplanation": "Utiliser un service de premier plan pour la vérification des mises à jour (plus fiable, consomme plus d'énergie)", | ||||||
|     "fgServiceNotice": "Cette notification est nécessaire pour la vérification des mises à jour en arrière-plan (elle peut être masquée dans les paramètres du système d'exploitation).", |     "fgServiceNotice": "Cette notification est nécessaire pour la vérification des mises à jour en arrière-plan (elle peut être masquée dans les paramètres du système d'exploitation).", | ||||||
|     "excludeSecrets": "Exclure les secrets", |     "excludeSecrets": "Exclure les secrets", | ||||||
|  |     "GHReqPrefix": "instance 'sky22333/hubproxy' pour les requêtes GitHub", | ||||||
|  |     "includeZips": "Inclure les fichiers ZIP", | ||||||
|  |     "zippedApkFilterRegEx": "Filtrer les APK à l'intérieur du ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Supprimer l'application ?", |         "one": "Supprimer l'application ?", | ||||||
|         "other": "Supprimer les applications ?" |         "other": "Supprimer les applications ?" | ||||||
|   | |||||||
| @@ -254,7 +254,8 @@ | |||||||
|     "verifyLatestTag": "Ellenőrizze a „legújabb” címkét", |     "verifyLatestTag": "Ellenőrizze a „legújabb” címkét", | ||||||
|     "intermediateLinkRegex": "Szűrő egy „köztes” hivatkozás felkereséséhez", |     "intermediateLinkRegex": "Szűrő egy „köztes” hivatkozás felkereséséhez", | ||||||
|     "filterByLinkText": "Hivatkozások szűrése hivatkozásszöveg alapján", |     "filterByLinkText": "Hivatkozások szűrése hivatkozásszöveg alapján", | ||||||
|     "intermediateLinkNotFound": "Köztes hivatkozás nem található", |     "matchLinksOutsideATags": "Hivatkozások keresése az <a> címkéken kívül is", | ||||||
|  |     "intermediateLinkNotFound": "Nem található köztes hivatkozás", | ||||||
|     "intermediateLink": "Köztes hivatkozás", |     "intermediateLink": "Köztes hivatkozás", | ||||||
|     "exemptFromBackgroundUpdates": "Mentes a háttérben történő frissítések alól (ha engedélyezett)", |     "exemptFromBackgroundUpdates": "Mentes a háttérben történő frissítések alól (ha engedélyezett)", | ||||||
|     "bgUpdatesOnWiFiOnly": "Háttérfrissítések letiltása, amikor az eszköz nem csatlakozik a Wi-Fi-hez", |     "bgUpdatesOnWiFiOnly": "Háttérfrissítések letiltása, amikor az eszköz nem csatlakozik a Wi-Fi-hez", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Előtér-szolgáltatás használata a frissítések ellenőrzéséhez (megbízhatóbb, de több energiát fogyaszt)", |     "foregroundServiceExplanation": "Előtér-szolgáltatás használata a frissítések ellenőrzéséhez (megbízhatóbb, de több energiát fogyaszt)", | ||||||
|     "fgServiceNotice": "Ez az értesítés a háttérben történő frissítésellenőrzéshez szükséges (a rendszer beállításaiban elrejthető).", |     "fgServiceNotice": "Ez az értesítés a háttérben történő frissítésellenőrzéshez szükséges (a rendszer beállításaiban elrejthető).", | ||||||
|     "excludeSecrets": "Érzékeny adatok (például: személyes hozzáférési tokenek) kihagyása", |     "excludeSecrets": "Érzékeny adatok (például: személyes hozzáférési tokenek) kihagyása", | ||||||
|  |     "GHReqPrefix": "„sky22333/hubproxy” példány a GitHub lekérdezéséhez", | ||||||
|  |     "includeZips": "ZIP fájlok belefoglalása", | ||||||
|  |     "zippedApkFilterRegEx": "APK-k szűrése a ZIP-en belül", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Eltávolítja az alkalmazást?", |         "one": "Eltávolítja az alkalmazást?", | ||||||
|         "other": "Eltávolítja az alkalmazásokat?" |         "other": "Eltávolítja az alkalmazásokat?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Verifikasi label 'terbaru'", |     "verifyLatestTag": "Verifikasi label 'terbaru'", | ||||||
|     "intermediateLinkRegex": "Filter tautan 'perantara' untuk dikunjungi", |     "intermediateLinkRegex": "Filter tautan 'perantara' untuk dikunjungi", | ||||||
|     "filterByLinkText": "Filter tautan berdasarkan teks tautan", |     "filterByLinkText": "Filter tautan berdasarkan teks tautan", | ||||||
|  |     "matchLinksOutsideATags": "Mencocokkan tautan di luar tag <a>", | ||||||
|     "intermediateLinkNotFound": "Tautan perantara tidak ditemukan", |     "intermediateLinkNotFound": "Tautan perantara tidak ditemukan", | ||||||
|     "intermediateLink": "Tautan perantara", |     "intermediateLink": "Tautan perantara", | ||||||
|     "exemptFromBackgroundUpdates": "Dikecualikan dari pembaruan latar belakang (jika diaktifkan)", |     "exemptFromBackgroundUpdates": "Dikecualikan dari pembaruan latar belakang (jika diaktifkan)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Gunakan layanan latar depan untuk pemeriksaan pembaruan (lebih dapat diandalkan, menghabiskan lebih banyak daya)", |     "foregroundServiceExplanation": "Gunakan layanan latar depan untuk pemeriksaan pembaruan (lebih dapat diandalkan, menghabiskan lebih banyak daya)", | ||||||
|     "fgServiceNotice": "Pemberitahuan ini diperlukan untuk pemeriksaan pembaruan latar belakang (dapat disembunyikan dalam pengaturan OS)", |     "fgServiceNotice": "Pemberitahuan ini diperlukan untuk pemeriksaan pembaruan latar belakang (dapat disembunyikan dalam pengaturan OS)", | ||||||
|     "excludeSecrets": "Mengecualikan rahasia", |     "excludeSecrets": "Mengecualikan rahasia", | ||||||
|  |     "GHReqPrefix": "Instance 'sky22333/hubproxy' untuk permintaan GitHub", | ||||||
|  |     "includeZips": "Menyertakan file ZIP", | ||||||
|  |     "zippedApkFilterRegEx": "Saring APK di dalam ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Hapus aplikasi?", |         "one": "Hapus aplikasi?", | ||||||
|         "other": "Hapus aplikasi?" |         "other": "Hapus aplikasi?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Verifica l'etichetta 'Latest'", |     "verifyLatestTag": "Verifica l'etichetta 'Latest'", | ||||||
|     "intermediateLinkRegex": "Filtro per un collegamento 'intermedio' da visitare", |     "intermediateLinkRegex": "Filtro per un collegamento 'intermedio' da visitare", | ||||||
|     "filterByLinkText": "Filtra i collegamenti in base al testo del collegamento", |     "filterByLinkText": "Filtra i collegamenti in base al testo del collegamento", | ||||||
|  |     "matchLinksOutsideATags": "Corrispondenza dei collegamenti al di fuori dei tag <a>", | ||||||
|     "intermediateLinkNotFound": "Link intermedio non trovato", |     "intermediateLinkNotFound": "Link intermedio non trovato", | ||||||
|     "intermediateLink": "Collegamento intermedio", |     "intermediateLink": "Collegamento intermedio", | ||||||
|     "exemptFromBackgroundUpdates": "Esente da aggiornamenti in secondo piano (se attivo)", |     "exemptFromBackgroundUpdates": "Esente da aggiornamenti in secondo piano (se attivo)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Utilizzare un servizio in primo piano per il controllo degli aggiornamenti (più affidabile, consuma più energia)", |     "foregroundServiceExplanation": "Utilizzare un servizio in primo piano per il controllo degli aggiornamenti (più affidabile, consuma più energia)", | ||||||
|     "fgServiceNotice": "Questa notifica è necessaria per il controllo degli aggiornamenti in background (può essere nascosta nelle impostazioni del sistema operativo).", |     "fgServiceNotice": "Questa notifica è necessaria per il controllo degli aggiornamenti in background (può essere nascosta nelle impostazioni del sistema operativo).", | ||||||
|     "excludeSecrets": "Escludere i segreti", |     "excludeSecrets": "Escludere i segreti", | ||||||
|  |     "GHReqPrefix": "istanza 'sky22333/hubproxy' per le richieste a GitHub", | ||||||
|  |     "includeZips": "Includere file ZIP", | ||||||
|  |     "zippedApkFilterRegEx": "Filtrare gli APK all'interno dello ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Rimuovere l'app?", |         "one": "Rimuovere l'app?", | ||||||
|         "other": "Rimuovere le app?" |         "other": "Rimuovere le app?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "'latest'タグを確認する", |     "verifyLatestTag": "'latest'タグを確認する", | ||||||
|     "intermediateLinkRegex": "訪問する「中間」リンクのフィルター", |     "intermediateLinkRegex": "訪問する「中間」リンクのフィルター", | ||||||
|     "filterByLinkText": "テキストでリンクをフィルタリングする", |     "filterByLinkText": "テキストでリンクをフィルタリングする", | ||||||
|  |     "matchLinksOutsideATags": "<a>タグの外にあるリンクに一致させる", | ||||||
|     "intermediateLinkNotFound": "中間リンクが見つかりませんでした", |     "intermediateLinkNotFound": "中間リンクが見つかりませんでした", | ||||||
|     "intermediateLink": "中間リンク", |     "intermediateLink": "中間リンク", | ||||||
|     "exemptFromBackgroundUpdates": "バックグラウンドアップデートを行わない (有効な場合)", |     "exemptFromBackgroundUpdates": "バックグラウンドアップデートを行わない (有効な場合)", | ||||||
| @@ -334,7 +335,10 @@ | |||||||
|     "foregroundService": "Obtainium フォアグラウンドサービス", |     "foregroundService": "Obtainium フォアグラウンドサービス", | ||||||
|     "foregroundServiceExplanation": "アップデート確認にフォアグラウンドサービスを使用する(より信頼性が高いが、より電力を消費する)", |     "foregroundServiceExplanation": "アップデート確認にフォアグラウンドサービスを使用する(より信頼性が高いが、より電力を消費する)", | ||||||
|     "fgServiceNotice": "この通知は、バックグラウンドでアップデートを確認するために必要です(OSの設定で非表示にできます)。", |     "fgServiceNotice": "この通知は、バックグラウンドでアップデートを確認するために必要です(OSの設定で非表示にできます)。", | ||||||
|     "excludeSecrets": "秘密を除く", |     "excludeSecrets": "シークレットを除く", | ||||||
|  |     "GHReqPrefix": "GitHub リクエスト用の 'sky22333/hubproxy' インスタンス", | ||||||
|  |     "includeZips": "ZIPファイルを含む", | ||||||
|  |     "zippedApkFilterRegEx": "ZIP内のAPKをフィルタリングする", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "アプリを削除しますか?", |         "one": "アプリを削除しますか?", | ||||||
|         "other": "アプリを削除しますか?" |         "other": "アプリを削除しますか?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "'최신' 태그 확인", |     "verifyLatestTag": "'최신' 태그 확인", | ||||||
|     "intermediateLinkRegex": "'중간' 링크 방문 필터", |     "intermediateLinkRegex": "'중간' 링크 방문 필터", | ||||||
|     "filterByLinkText": "링크 텍스트로 링크 필터링", |     "filterByLinkText": "링크 텍스트로 링크 필터링", | ||||||
|  |     "matchLinksOutsideATags": "<> 태그 외부의 링크 일치", | ||||||
|     "intermediateLinkNotFound": "중간 링크를 찾을 수 없습니다", |     "intermediateLinkNotFound": "중간 링크를 찾을 수 없습니다", | ||||||
|     "intermediateLink": "중간 링크", |     "intermediateLink": "중간 링크", | ||||||
|     "exemptFromBackgroundUpdates": "백그라운드 업데이트에서 제외 (활성화된 경우)", |     "exemptFromBackgroundUpdates": "백그라운드 업데이트에서 제외 (활성화된 경우)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "업데이트 확인을 위해 포그라운드 서비스 사용(안정성 향상, 전력 소비량 증가)", |     "foregroundServiceExplanation": "업데이트 확인을 위해 포그라운드 서비스 사용(안정성 향상, 전력 소비량 증가)", | ||||||
|     "fgServiceNotice": "이 알림은 백그라운드 업데이트 확인에 필요합니다(OS 설정에서 숨길 수 있음).", |     "fgServiceNotice": "이 알림은 백그라운드 업데이트 확인에 필요합니다(OS 설정에서 숨길 수 있음).", | ||||||
|     "excludeSecrets": "비밀 제외", |     "excludeSecrets": "비밀 제외", | ||||||
|  |     "GHReqPrefix": "GitHub 요청을 위한 'sky22333/hubproxy' 인스턴스", | ||||||
|  |     "includeZips": "ZIP 파일 포함", | ||||||
|  |     "zippedApkFilterRegEx": "ZIP 내 APK 필터링", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "앱을 제거하시겠습니까?", |         "one": "앱을 제거하시겠습니까?", | ||||||
|         "other": "앱을 제거하시겠습니까?" |         "other": "앱을 제거하시겠습니까?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "'ഏറ്റവും പുതിയ' ടാഗ് പരിശോധിക്കുക", |     "verifyLatestTag": "'ഏറ്റവും പുതിയ' ടാഗ് പരിശോധിക്കുക", | ||||||
|     "intermediateLinkRegex": "സന്ദർശിക്കാൻ ഒരു 'ഇന്റർമീഡിയറ്റ്' ലിങ്കിനായി ഫിൽട്ടർ ചെയ്യുക", |     "intermediateLinkRegex": "സന്ദർശിക്കാൻ ഒരു 'ഇന്റർമീഡിയറ്റ്' ലിങ്കിനായി ഫിൽട്ടർ ചെയ്യുക", | ||||||
|     "filterByLinkText": "ലിങ്ക് ടെക്സ്റ്റ് ഉപയോഗിച്ച് ലിങ്കുകൾ ഫിൽട്ടർ ചെയ്യുക", |     "filterByLinkText": "ലിങ്ക് ടെക്സ്റ്റ് ഉപയോഗിച്ച് ലിങ്കുകൾ ഫിൽട്ടർ ചെയ്യുക", | ||||||
|  |     "matchLinksOutsideATags": "Match links outside <a> tags", | ||||||
|     "intermediateLinkNotFound": "ഇന്റർമീഡിയറ്റ് ലിങ്ക് കണ്ടെത്തിയില്ല", |     "intermediateLinkNotFound": "ഇന്റർമീഡിയറ്റ് ലിങ്ക് കണ്ടെത്തിയില്ല", | ||||||
|     "intermediateLink": "ഇന്റർമീഡിയറ്റ് ലിങ്ക്", |     "intermediateLink": "ഇന്റർമീഡിയറ്റ് ലിങ്ക്", | ||||||
|     "exemptFromBackgroundUpdates": "ബാക്ക്ഗ്രൗണ്ട് അപ്ഡേറ്റുകളിൽ നിന്ന് ഒഴിവാക്കുക (പ്രവർത്തനക്ഷമമാക്കിയിട്ടുണ്ടെങ്കിൽ)", |     "exemptFromBackgroundUpdates": "ബാക്ക്ഗ്രൗണ്ട് അപ്ഡേറ്റുകളിൽ നിന്ന് ഒഴിവാക്കുക (പ്രവർത്തനക്ഷമമാക്കിയിട്ടുണ്ടെങ്കിൽ)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)", |     "foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)", | ||||||
|     "fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)", |     "fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)", | ||||||
|     "excludeSecrets": "Exclude secrets", |     "excludeSecrets": "Exclude secrets", | ||||||
|  |     "GHReqPrefix": "'sky22333/hubproxy' instance for GitHub requests", | ||||||
|  |     "includeZips": "Include ZIP files", | ||||||
|  |     "zippedApkFilterRegEx": "Filter APKs inside ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "ആപ്പ് നീക്കം ചെയ്യണോ?", |         "one": "ആപ്പ് നീക്കം ചെയ്യണോ?", | ||||||
|         "other": "ആപ്പുകൾ നീക്കം ചെയ്യണോ?" |         "other": "ആപ്പുകൾ നീക്കം ചെയ്യണോ?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Het label 'Laatste' verifiëren", |     "verifyLatestTag": "Het label 'Laatste' verifiëren", | ||||||
|     "intermediateLinkRegex": "Filteren op een 'Intermediaire' link om te bezoeken", |     "intermediateLinkRegex": "Filteren op een 'Intermediaire' link om te bezoeken", | ||||||
|     "filterByLinkText": "Links filteren op linktekst", |     "filterByLinkText": "Links filteren op linktekst", | ||||||
|  |     "matchLinksOutsideATags": "Koppelingen buiten <a>-tags matchen", | ||||||
|     "intermediateLinkNotFound": "Intermediaire link niet gevonden", |     "intermediateLinkNotFound": "Intermediaire link niet gevonden", | ||||||
|     "intermediateLink": "Intermediaire link", |     "intermediateLink": "Intermediaire link", | ||||||
|     "exemptFromBackgroundUpdates": "Vrijgesteld van achtergrond-updates (indien ingeschakeld)", |     "exemptFromBackgroundUpdates": "Vrijgesteld van achtergrond-updates (indien ingeschakeld)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Gebruik een voorgronddienst voor het controleren van updates (betrouwbaarder, verbruikt meer stroom)", |     "foregroundServiceExplanation": "Gebruik een voorgronddienst voor het controleren van updates (betrouwbaarder, verbruikt meer stroom)", | ||||||
|     "fgServiceNotice": "Deze melding is nodig voor het controleren van updates op de achtergrond (kan worden verborgen in de OS-instellingen)", |     "fgServiceNotice": "Deze melding is nodig voor het controleren van updates op de achtergrond (kan worden verborgen in de OS-instellingen)", | ||||||
|     "excludeSecrets": "Geheimen uitsluiten", |     "excludeSecrets": "Geheimen uitsluiten", | ||||||
|  |     "GHReqPrefix": "'sky22333/hubproxy' instantie voor GitHub verzoeken", | ||||||
|  |     "includeZips": "ZIP-bestanden opnemen", | ||||||
|  |     "zippedApkFilterRegEx": "APK's filteren in ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "App verwijderen?", |         "one": "App verwijderen?", | ||||||
|         "other": "Apps verwijderen?" |         "other": "Apps verwijderen?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Zweryfikuj najnowszy tag", |     "verifyLatestTag": "Zweryfikuj najnowszy tag", | ||||||
|     "intermediateLinkRegex": "Filtr linków \"pośrednich\" do odwiedzenia w pierwszej kolejności", |     "intermediateLinkRegex": "Filtr linków \"pośrednich\" do odwiedzenia w pierwszej kolejności", | ||||||
|     "filterByLinkText": "Filtruj linki według tekstu linku", |     "filterByLinkText": "Filtruj linki według tekstu linku", | ||||||
|  |     "matchLinksOutsideATags": "Dopasowywanie linków poza znacznikami <a>", | ||||||
|     "intermediateLinkNotFound": "Nie znaleziono linku pośredniego", |     "intermediateLinkNotFound": "Nie znaleziono linku pośredniego", | ||||||
|     "intermediateLink": "Link pośredni", |     "intermediateLink": "Link pośredni", | ||||||
|     "exemptFromBackgroundUpdates": "Wyklucz z uaktualnień w tle (jeśli są włączone)", |     "exemptFromBackgroundUpdates": "Wyklucz z uaktualnień w tle (jeśli są włączone)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Używanie usługi pierwszoplanowej do sprawdzania aktualizacji (bardziej niezawodne, zużywa więcej energii)", |     "foregroundServiceExplanation": "Używanie usługi pierwszoplanowej do sprawdzania aktualizacji (bardziej niezawodne, zużywa więcej energii)", | ||||||
|     "fgServiceNotice": "To powiadomienie jest wymagane do sprawdzania aktualizacji w tle (można je ukryć w ustawieniach systemu operacyjnego).", |     "fgServiceNotice": "To powiadomienie jest wymagane do sprawdzania aktualizacji w tle (można je ukryć w ustawieniach systemu operacyjnego).", | ||||||
|     "excludeSecrets": "Wyklucz sekrety", |     "excludeSecrets": "Wyklucz sekrety", | ||||||
|  |     "GHReqPrefix": "Instancja \"sky22333/hubproxy\" dla żądań GitHub", | ||||||
|  |     "includeZips": "Dołączanie plików ZIP", | ||||||
|  |     "zippedApkFilterRegEx": "Filtrowanie plików APK wewnątrz ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Usunąć aplikację?", |         "one": "Usunąć aplikację?", | ||||||
|         "few": "Usunąć aplikacje?", |         "few": "Usunąć aplikacje?", | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Verificar a tag 'mais recente'", |     "verifyLatestTag": "Verificar a tag 'mais recente'", | ||||||
|     "intermediateLinkRegex": "Filtrar por um link 'intermediário' para visitar", |     "intermediateLinkRegex": "Filtrar por um link 'intermediário' para visitar", | ||||||
|     "filterByLinkText": "Filtrar links por texto do link", |     "filterByLinkText": "Filtrar links por texto do link", | ||||||
|  |     "matchLinksOutsideATags": "Corresponder links fora das tags <a>", | ||||||
|     "intermediateLinkNotFound": "Link intermediário não encontrado", |     "intermediateLinkNotFound": "Link intermediário não encontrado", | ||||||
|     "intermediateLink": "Link intermediário", |     "intermediateLink": "Link intermediário", | ||||||
|     "exemptFromBackgroundUpdates": "Isento de atualizações em segundo plano (caso ativadas)", |     "exemptFromBackgroundUpdates": "Isento de atualizações em segundo plano (caso ativadas)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Usar um serviço em primeiro plano para verificação de atualizações (mais confiável, consome mais energia)", |     "foregroundServiceExplanation": "Usar um serviço em primeiro plano para verificação de atualizações (mais confiável, consome mais energia)", | ||||||
|     "fgServiceNotice": "Essa notificação é necessária para a verificação de atualizações em segundo plano (ela pode ser ocultada nas configurações do sistema operacional)", |     "fgServiceNotice": "Essa notificação é necessária para a verificação de atualizações em segundo plano (ela pode ser ocultada nas configurações do sistema operacional)", | ||||||
|     "excludeSecrets": "Excluir segredos", |     "excludeSecrets": "Excluir segredos", | ||||||
|  |     "GHReqPrefix": "Instância \"sky22333/hubproxy\" para solicitações do GitHub", | ||||||
|  |     "includeZips": "Incluir arquivos ZIP", | ||||||
|  |     "zippedApkFilterRegEx": "Filtrar APKs dentro do ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Remover app?", |         "one": "Remover app?", | ||||||
|         "other": "Remover apps?" |         "other": "Remover apps?" | ||||||
|   | |||||||
| @@ -3,8 +3,8 @@ | |||||||
|     "noReleaseFound": "Não foi possível encontrar uma versão adequada", |     "noReleaseFound": "Não foi possível encontrar uma versão adequada", | ||||||
|     "noVersionFound": "Não foi possível encontrar uma versão", |     "noVersionFound": "Não foi possível encontrar uma versão", | ||||||
|     "urlMatchesNoSource": "A URL não corresponde a uma fonte conhecida", |     "urlMatchesNoSource": "A URL não corresponde a uma fonte conhecida", | ||||||
|     "cantInstallOlderVersion": "Não é permitido instalar uma versão anterior de um aplicativo", |     "cantInstallOlderVersion": "Não é permitido instalar uma versão anterior de uma aplicação", | ||||||
|     "appIdMismatch": "ID do pacote baixado não é igual ao ID do aplicativo instalado", |     "appIdMismatch": "O ID do pacote descarregado não é igual ao ID da aplicação instalada", | ||||||
|     "functionNotImplemented": "Esta classe não implementou essa função", |     "functionNotImplemented": "Esta classe não implementou essa função", | ||||||
|     "placeholder": "Espaço reservado", |     "placeholder": "Espaço reservado", | ||||||
|     "someErrors": "Alguns erros ocorreram", |     "someErrors": "Alguns erros ocorreram", | ||||||
| @@ -30,15 +30,15 @@ | |||||||
|     "wrongArgNum": "Número de argumentos errado", |     "wrongArgNum": "Número de argumentos errado", | ||||||
|     "xIsTrackOnly": "{} é 'Apenas monitorar'", |     "xIsTrackOnly": "{} é 'Apenas monitorar'", | ||||||
|     "source": "Fonte", |     "source": "Fonte", | ||||||
|     "app": "Aplicativo", |     "app": "Aplicação", | ||||||
|     "appsFromSourceAreTrackOnly": "Os aplicativos desta fonte são 'Apenas monitorar'.", |     "appsFromSourceAreTrackOnly": "As aplicações desta fonte são 'Apenas monitorar'.", | ||||||
|     "youPickedTrackOnly": "Você selecionou a opção 'Apenas monitorar'.", |     "youPickedTrackOnly": "Você selecionou a opção 'Apenas monitorar'.", | ||||||
|     "trackOnlyAppDescription": "As atualizações desse aplicativo serão monitoradas, mas o Obtainium não poderá baixá-lo ou instalá-lo.", |     "trackOnlyAppDescription": "As atualizações desta aplicação serão monitorizadas, mas o Obtainium não poderá descarregá-la ou instalá-la.", | ||||||
|     "cancelled": "Cancelado", |     "cancelled": "Cancelado", | ||||||
|     "appAlreadyAdded": "Aplicativo já adicionado", |     "appAlreadyAdded": "Aplicação já adicionada", | ||||||
|     "alreadyUpToDateQuestion": "Aplicativo já foi atualizado?", |     "alreadyUpToDateQuestion": "Aplicação já foi atualizada?", | ||||||
|     "addApp": "Adicionar aplicativo", |     "addApp": "Adicionar aplicação", | ||||||
|     "appSourceURL": "URL de origem do aplicativo", |     "appSourceURL": "URL de origem da aplicação", | ||||||
|     "error": "Erro", |     "error": "Erro", | ||||||
|     "add": "Adicionar", |     "add": "Adicionar", | ||||||
|     "searchSomeSourcesLabel": "Procurar (apenas algumas fontes)", |     "searchSomeSourcesLabel": "Procurar (apenas algumas fontes)", | ||||||
| @@ -47,9 +47,9 @@ | |||||||
|     "supportedSources": "Fontes compatíveis", |     "supportedSources": "Fontes compatíveis", | ||||||
|     "trackOnlyInBrackets": "(apenas monitorar)", |     "trackOnlyInBrackets": "(apenas monitorar)", | ||||||
|     "searchableInBrackets": "(pesquisável)", |     "searchableInBrackets": "(pesquisável)", | ||||||
|     "appsString": "Aplicativos", |     "appsString": "Aplicações", | ||||||
|     "noApps": "Não há aplicativos", |     "noApps": "Não há aplicações", | ||||||
|     "noAppsForFilter": "Sem aplicativos para filtrar", |     "noAppsForFilter": "Sem aplicações para filtrar", | ||||||
|     "byX": "Por {}", |     "byX": "Por {}", | ||||||
|     "percentProgress": "Progresso: {}%", |     "percentProgress": "Progresso: {}%", | ||||||
|     "pleaseWait": "Por favor, espere", |     "pleaseWait": "Por favor, espere", | ||||||
| @@ -59,35 +59,35 @@ | |||||||
|     "selectAll": "Selecionar todos", |     "selectAll": "Selecionar todos", | ||||||
|     "deselectX": "Deselecionar {}", |     "deselectX": "Deselecionar {}", | ||||||
|     "xWillBeRemovedButRemainInstalled": "{} será removido do Obtainium mais permanecerá instalado no dispositivo.", |     "xWillBeRemovedButRemainInstalled": "{} será removido do Obtainium mais permanecerá instalado no dispositivo.", | ||||||
|     "removeSelectedAppsQuestion": "Remover aplicativos selecionados?", |     "removeSelectedAppsQuestion": "Remover aplicações selecionadas?", | ||||||
|     "removeSelectedApps": "Remover aplicativos selecionados", |     "removeSelectedApps": "Remover aplicações selecionadas", | ||||||
|     "updateX": "Atualizar {}", |     "updateX": "Atualizar {}", | ||||||
|     "installX": "Instalar {}", |     "installX": "Instalar {}", | ||||||
|     "markXTrackOnlyAsUpdated": "Marcar {}\n(Apenas monitorar)\ncomo Atualizado", |     "markXTrackOnlyAsUpdated": "Marcar {}\n(Apenas monitorar)\ncomo Atualizado", | ||||||
|     "changeX": "Mudar {}", |     "changeX": "Mudar {}", | ||||||
|     "installUpdateApps": "Instalar/Atualizar aplicativos", |     "installUpdateApps": "Instalar/Atualizar aplicações", | ||||||
|     "installUpdateSelectedApps": "Instalar/Atualizar aplicativos selecionados", |     "installUpdateSelectedApps": "Instalar/Atualizar aplicações selecionadas", | ||||||
|     "markXSelectedAppsAsUpdated": "Marcar {} aplicativos selecionados como atualizados?", |     "markXSelectedAppsAsUpdated": "Marcar {} aplicações selecionadas como atualizadas?", | ||||||
|     "no": "Não", |     "no": "Não", | ||||||
|     "yes": "Sim", |     "yes": "Sim", | ||||||
|     "markSelectedAppsUpdated": "Marcar aplicativos selecionados como Atualizados", |     "markSelectedAppsUpdated": "Marcar aplicações selecionadas como Atualizadas", | ||||||
|     "pinToTop": "Fixar no topo", |     "pinToTop": "Fixar no topo", | ||||||
|     "unpinFromTop": "Desafixar do topo", |     "unpinFromTop": "Desafixar do topo", | ||||||
|     "resetInstallStatusForSelectedAppsQuestion": "Reiniciar status de instalação nos aplicativos selecionados?", |     "resetInstallStatusForSelectedAppsQuestion": "Reiniciar o estado de instalação das aplicações selecionadas?", | ||||||
|     "installStatusOfXWillBeResetExplanation": "O status de instalação de todos os aplicativos selecionados será reiniciado.\n\nIsso pode ajudar quando uma versão de um aplicativo mostrada no Obtainium é incorreta devido a falhas ao atualizar ou outros problemas.", |     "installStatusOfXWillBeResetExplanation": "O estado de instalação de todas as aplicações selecionadas será reiniciado.\n\nIsto pode ajudar quando uma versão de uma aplicação mostrada no Obtainium está incorreta devido a falhas na atualização ou outros problemas.", | ||||||
|     "customLinkMessage": "Esses links funcionam em dispositivos com o Obtainium instalado", |     "customLinkMessage": "Esses links funcionam em dispositivos com o Obtainium instalado", | ||||||
|     "shareAppConfigLinks": "Compartilhar configuração do aplicativo como link HTML", |     "shareAppConfigLinks": "Partilhar a configuração da aplicação como um link HTML", | ||||||
|     "shareSelectedAppURLs": "Compartilhar URLs de aplicativos selecionados", |     "shareSelectedAppURLs": "Partilhar URLs de aplicações selecionadas", | ||||||
|     "resetInstallStatus": "Reiniciar status de instalação", |     "resetInstallStatus": "Reiniciar status de instalação", | ||||||
|     "more": "Mais", |     "more": "Mais", | ||||||
|     "removeOutdatedFilter": "Remover filtro de aplicativos desatualizados", |     "removeOutdatedFilter": "Remover filtro de aplicações desatualizadas", | ||||||
|     "showOutdatedOnly": "Mostrar apenas aplicativos desatualizados", |     "showOutdatedOnly": "Mostrar apenas aplicações desatualizadas", | ||||||
|     "filter": "Filtro", |     "filter": "Filtro", | ||||||
|     "filterApps": "Filtrar aplicativos", |     "filterApps": "Filtrar aplicações", | ||||||
|     "appName": "Nome do aplicativo", |     "appName": "Nome da aplicação", | ||||||
|     "author": "Autor", |     "author": "Autor", | ||||||
|     "upToDateApps": "Aplicativos atualizados", |     "upToDateApps": "Aplicações atualizadas", | ||||||
|     "nonInstalledApps": "Aplicativos não instalados", |     "nonInstalledApps": "Aplicações não instaladas", | ||||||
|     "importExport": "Importar/Exportar", |     "importExport": "Importar/Exportar", | ||||||
|     "settings": "Configurações", |     "settings": "Configurações", | ||||||
|     "exportedTo": "Exportado para {}", |     "exportedTo": "Exportado para {}", | ||||||
| @@ -97,14 +97,14 @@ | |||||||
|     "obtainiumImport": "Importar dados do Obtainium", |     "obtainiumImport": "Importar dados do Obtainium", | ||||||
|     "importFromURLList": "Importar de lista de URLs", |     "importFromURLList": "Importar de lista de URLs", | ||||||
|     "searchQuery": "Pesquisa", |     "searchQuery": "Pesquisa", | ||||||
|     "appURLList": "Lista de URLs de aplicativos", |     "appURLList": "Lista de URLs de aplicações", | ||||||
|     "line": "Linha", |     "line": "Linha", | ||||||
|     "searchX": "Pesquisar na/o {}", |     "searchX": "Pesquisar na/o {}", | ||||||
|     "noResults": "Nenhum resultado encontrado", |     "noResults": "Nenhum resultado encontrado", | ||||||
|     "importX": "Importar {}", |     "importX": "Importar {}", | ||||||
|     "importedAppsIdDisclaimer": "Aplicativos Importados podem ser mostrados incorretamente como \"Não Instalado\".\nPara consertar, reinstale-os usando o Obtainium.\nIsso não deve afetar dados do aplicativo.\n\nAfeta apenas métodos de importação de URL e de terceiros.", |     "importedAppsIdDisclaimer": "Aplicações Importadas podem ser mostradas incorretamente como \"Não Instalado\".\nPara corrigir, reinstale-as usando o Obtainium.\nIsto não deve afetar os dados da aplicação.\n\nAfeta apenas os métodos de importação de URL e de terceiros.", | ||||||
|     "importErrors": "Erros de importação", |     "importErrors": "Erros de importação", | ||||||
|     "importedXOfYApps": "{} de {} aplicativos importados.", |     "importedXOfYApps": "{} de {} aplicações importadas.", | ||||||
|     "followingURLsHadErrors": "As seguintes URLs apresentaram erros:", |     "followingURLsHadErrors": "As seguintes URLs apresentaram erros:", | ||||||
|     "selectURL": "Selecionar URL", |     "selectURL": "Selecionar URL", | ||||||
|     "selectURLs": "Selecionar URLs", |     "selectURLs": "Selecionar URLs", | ||||||
| @@ -115,53 +115,53 @@ | |||||||
|     "followSystem": "Padrão do sistema", |     "followSystem": "Padrão do sistema", | ||||||
|     "followSystemThemeExplanation": "O tema do sistema seguinte só é possível através da utilização de aplicações de terceiros", |     "followSystemThemeExplanation": "O tema do sistema seguinte só é possível através da utilização de aplicações de terceiros", | ||||||
|     "useBlackTheme": "Usar tema preto AMOLED", |     "useBlackTheme": "Usar tema preto AMOLED", | ||||||
|     "appSortBy": "Classificar aplicativo por", |     "appSortBy": "Classificar aplicação por", | ||||||
|     "authorName": "Autor/Nome", |     "authorName": "Autor/Nome", | ||||||
|     "nameAuthor": "Nome/Autor", |     "nameAuthor": "Nome/Autor", | ||||||
|     "asAdded": "Como adicionado", |     "asAdded": "Como adicionado", | ||||||
|     "appSortOrder": "Ordem de classificação de aplicativos", |     "appSortOrder": "Ordem de classificação das aplicações", | ||||||
|     "ascending": "Ascendente", |     "ascending": "Ascendente", | ||||||
|     "descending": "Descendente", |     "descending": "Descendente", | ||||||
|     "bgUpdateCheckInterval": "Intervalo de verificação de atualizações em segundo-plano", |     "bgUpdateCheckInterval": "Intervalo de verificação de atualizações em segundo-plano", | ||||||
|     "neverManualOnly": "Nunca - apenas manual", |     "neverManualOnly": "Nunca - apenas manual", | ||||||
|     "appearance": "Aparência", |     "appearance": "Aparência", | ||||||
|     "showWebInAppView": "Mostrar página web do aplicativo em informações do aplicativo", |     "showWebInAppView": "Mostrar a página web da aplicação nas informações da aplicação", | ||||||
|     "pinUpdates": "Fixar atualizações no topo da janela de aplicativos", |     "pinUpdates": "Fixar atualizações no topo da janela das aplicações", | ||||||
|     "updates": "Atualizações", |     "updates": "Atualizações", | ||||||
|     "sourceSpecific": "Token de acesso", |     "sourceSpecific": "Token de acesso", | ||||||
|     "appSource": "Fonte do aplicativo", |     "appSource": "Fonte da aplicação", | ||||||
|     "noLogs": "Sem logs", |     "noLogs": "Sem logs", | ||||||
|     "appLogs": "Logs do aplicativo", |     "appLogs": "Logs da aplicação", | ||||||
|     "close": "Fechar", |     "close": "Fechar", | ||||||
|     "share": "Compartilhar", |     "share": "Compartilhar", | ||||||
|     "appNotFound": "Aplicativo não encontrado", |     "appNotFound": "Aplicação não encontrada", | ||||||
|     "obtainiumExportHyphenatedLowercase": "exportação de obtainium", |     "obtainiumExportHyphenatedLowercase": "exportação de obtainium", | ||||||
|     "pickAnAPK": "Selecionar um APK", |     "pickAnAPK": "Selecionar um APK", | ||||||
|     "appHasMoreThanOnePackage": "{} tem mais de um pacote:", |     "appHasMoreThanOnePackage": "{} tem mais de um pacote:", | ||||||
|     "deviceSupportsXArch": "Seu dispositivo suporta a arquitetura de CPU {}.", |     "deviceSupportsXArch": "Seu dispositivo suporta a arquitetura de CPU {}.", | ||||||
|     "deviceSupportsFollowingArchs": "Seu dispositivo suporta as seguintes arquiteturas de CPU:", |     "deviceSupportsFollowingArchs": "Seu dispositivo suporta as seguintes arquiteturas de CPU:", | ||||||
|     "warning": "Aviso", |     "warning": "Aviso", | ||||||
|     "sourceIsXButPackageFromYPrompt": "A fonte do aplicativo é '{}' mas a origem do pacote é '{}'. Continuar?", |     "sourceIsXButPackageFromYPrompt": "A fonte da aplicação é '{}' mas a origem do pacote é '{}'. Continuar?", | ||||||
|     "updatesAvailable": "Atualizações disponíveis", |     "updatesAvailable": "Atualizações disponíveis", | ||||||
|     "updatesAvailableNotifDescription": "Notifica o usuário quando atualizações de um ou mais aplicativos monitorados pelo Obtainium estão disponíveis", |     "updatesAvailableNotifDescription": "Notifica o utilizador quando as atualizações de uma ou mais aplicações monitorizadas pelo Obtainium estão disponíveis", | ||||||
|     "noNewUpdates": "Sem novas atualizações.", |     "noNewUpdates": "Sem novas atualizações.", | ||||||
|     "xHasAnUpdate": "{} tem uma atualização.", |     "xHasAnUpdate": "{} tem uma atualização.", | ||||||
|     "appsUpdated": "Aplicativos atualizados", |     "appsUpdated": "Aplicações atualizadas", | ||||||
|     "appsNotUpdated": "Falha na atualização das aplicações", |     "appsNotUpdated": "Falha na atualização das aplicações", | ||||||
|     "appsUpdatedNotifDescription": "Notifica o usuário quando atualizações foram aplicadas em segundo-plano para um ou mais aplicativos ", |     "appsUpdatedNotifDescription": "Notifica o utilizador quando as atualizações foram aplicadas em segundo plano para uma ou mais aplicações ", | ||||||
|     "xWasUpdatedToY": "{} foi atualizado para {}.", |     "xWasUpdatedToY": "{} foi atualizado para {}.", | ||||||
|     "xWasNotUpdatedToY": "Falha ao atualizar {} para {}.", |     "xWasNotUpdatedToY": "Falha ao atualizar {} para {}.", | ||||||
|     "errorCheckingUpdates": "Erro ao procurar por atualizações", |     "errorCheckingUpdates": "Erro ao procurar por atualizações", | ||||||
|     "errorCheckingUpdatesNotifDescription": "Uma notificação que mostra quando a checagem por atualizações em segundo-plano falha", |     "errorCheckingUpdatesNotifDescription": "Uma notificação que mostra quando a checagem por atualizações em segundo-plano falha", | ||||||
|     "appsRemoved": "Aplicativos removidos", |     "appsRemoved": "Aplicações removidas", | ||||||
|     "appsRemovedNotifDescription": "Notifica o usuário quando um ou mais aplicativos foram removidos devido a erros de carregamento", |     "appsRemovedNotifDescription": "Notifica o utilizador quando uma ou mais aplicações foram removidas devido a erros de carregamento", | ||||||
|     "xWasRemovedDueToErrorY": "{} foi removido devido a este erro: {}", |     "xWasRemovedDueToErrorY": "{} foi removido devido a este erro: {}", | ||||||
|     "completeAppInstallation": "Instalação do aplicativo concluída", |     "completeAppInstallation": "Instalação da aplicação concluída", | ||||||
|     "obtainiumMustBeOpenToInstallApps": "Obtainium deve estar aberto para instalar os aplicativos", |     "obtainiumMustBeOpenToInstallApps": "O Obtainium deve estar aberto para instalar as aplicações", | ||||||
|     "completeAppInstallationNotifDescription": "Pede ao usuário que retorne ao Obtainium para finalizar a instalação de um aplicativo", |     "completeAppInstallationNotifDescription": "Pede ao usuário que retorne ao Obtainium para finalizar a instalação de uma aplicação", | ||||||
|     "checkingForUpdates": "Verificando atualizações", |     "checkingForUpdates": "Verificando atualizações", | ||||||
|     "checkingForUpdatesNotifDescription": "Notificação transiente que aparece quando o Obtainium está verificando se há atualizações", |     "checkingForUpdatesNotifDescription": "Notificação transiente que aparece quando o Obtainium está verificando se há atualizações", | ||||||
|     "pleaseAllowInstallPerm": "Por favor, permita que o Obtainium possa instalar aplicativos", |     "pleaseAllowInstallPerm": "Por favor, permita que o Obtainium instale aplicações", | ||||||
|     "trackOnly": "Apenas monitorar", |     "trackOnly": "Apenas monitorar", | ||||||
|     "errorWithHttpStatusCode": "Erro {}", |     "errorWithHttpStatusCode": "Erro {}", | ||||||
|     "versionCorrectionDisabled": "Correção de versão desativada (plugin parece não funcionar)", |     "versionCorrectionDisabled": "Correção de versão desativada (plugin parece não funcionar)", | ||||||
| @@ -175,10 +175,10 @@ | |||||||
|     "remove": "Remover", |     "remove": "Remover", | ||||||
|     "yesMarkUpdated": "Sim, marcar como atualizado", |     "yesMarkUpdated": "Sim, marcar como atualizado", | ||||||
|     "fdroid": "Oficial F-Droid", |     "fdroid": "Oficial F-Droid", | ||||||
|     "appIdOrName": "ID do aplicativo ou nome", |     "appIdOrName": "ID da aplicação ou nome", | ||||||
|     "appId": "ID do aplicativo", |     "appId": "ID da aplicação", | ||||||
|     "appWithIdOrNameNotFound": "Nenhum aplicativo foi encontrado com esse ID ou nome", |     "appWithIdOrNameNotFound": "Nenhuma aplicação foi encontrada com esse ID ou nome", | ||||||
|     "reposHaveMultipleApps": "Repositórios podem conter múltiplos aplicativos", |     "reposHaveMultipleApps": "Os repositórios podem conter múltiplas aplicações", | ||||||
|     "fdroidThirdPartyRepo": "Repositórios de terceiros F-Droid", |     "fdroidThirdPartyRepo": "Repositórios de terceiros F-Droid", | ||||||
|     "install": "Instalar", |     "install": "Instalar", | ||||||
|     "markInstalled": "Marcar instalado", |     "markInstalled": "Marcar instalado", | ||||||
| @@ -186,12 +186,12 @@ | |||||||
|     "markUpdated": "Marcar como atualizado", |     "markUpdated": "Marcar como atualizado", | ||||||
|     "additionalOptions": "Opções adicionais", |     "additionalOptions": "Opções adicionais", | ||||||
|     "disableVersionDetection": "Desativar detecção de versão", |     "disableVersionDetection": "Desativar detecção de versão", | ||||||
|     "noVersionDetectionExplanation": "Essa opção deve apenas ser usada por aplicativos onde a detecção de versão não funciona corretamente.", |     "noVersionDetectionExplanation": "Esta opção deve ser usada apenas por aplicações onde a deteção de versão não funciona corretamente.", | ||||||
|     "downloadingX": "Baixando {}", |     "downloadingX": "Baixando {}", | ||||||
|     "downloadX": "Descarregar {}", |     "downloadX": "Descarregar {}", | ||||||
|     "downloadedX": "Descarregado {}", |     "downloadedX": "Descarregado {}", | ||||||
|     "releaseAsset": "Libertação de activos", |     "releaseAsset": "Libertação de activos", | ||||||
|     "downloadNotifDescription": "Notifica o usuário o progresso do download de um aplicativo", |     "downloadNotifDescription": "Notifica o utilizador sobre o progresso do download de uma aplicação", | ||||||
|     "noAPKFound": "APK não encontrado", |     "noAPKFound": "APK não encontrado", | ||||||
|     "noVersionDetection": "Sem detecção de versão", |     "noVersionDetection": "Sem detecção de versão", | ||||||
|     "categorize": "Categorizar", |     "categorize": "Categorizar", | ||||||
| @@ -200,20 +200,20 @@ | |||||||
|     "noCategory": "Sem categoria", |     "noCategory": "Sem categoria", | ||||||
|     "noCategories": "Sem categorias", |     "noCategories": "Sem categorias", | ||||||
|     "deleteCategoriesQuestion": "Deletar  categorias?", |     "deleteCategoriesQuestion": "Deletar  categorias?", | ||||||
|     "categoryDeleteWarning": "Todos os aplicativos em categorias removidas serão descategorizados.", |     "categoryDeleteWarning": "Todas as aplicações em categorias removidas serão descategorizadas.", | ||||||
|     "addCategory": "Adicionar categoria", |     "addCategory": "Adicionar categoria", | ||||||
|     "label": "Etiqueta", |     "label": "Etiqueta", | ||||||
|     "language": "Linguagem", |     "language": "Linguagem", | ||||||
|     "copiedToClipboard": "Copiado para a área de transferência", |     "copiedToClipboard": "Copiado para a área de transferência", | ||||||
|     "storagePermissionDenied": "Permissão de armazenamento negada", |     "storagePermissionDenied": "Permissão de armazenamento negada", | ||||||
|     "selectedCategorizeWarning": "Isso vai substituir qualquer configuração de categoria para os aplicativos selecionados.", |     "selectedCategorizeWarning": "Isto irá substituir qualquer configuração de categoria para as aplicações selecionadas.", | ||||||
|     "filterAPKsByRegEx": "Filtrar APKs usando expressão regular", |     "filterAPKsByRegEx": "Filtrar APKs usando expressão regular", | ||||||
|     "removeFromObtainium": "Remover do Obtainium", |     "removeFromObtainium": "Remover do Obtainium", | ||||||
|     "uninstallFromDevice": "Desinstalar do dispositivo", |     "uninstallFromDevice": "Desinstalar do dispositivo", | ||||||
|     "onlyWorksWithNonVersionDetectApps": "Apenas funciona para aplicativos com detecção de versão desativada.", |     "onlyWorksWithNonVersionDetectApps": "Apenas funciona para aplicações com a deteção de versão desativada.", | ||||||
|     "releaseDateAsVersion": "Usar data de lançamento como versão", |     "releaseDateAsVersion": "Usar data de lançamento como versão", | ||||||
|     "releaseTitleAsVersion": "Utilizar o título da versão como cadeia de versões", |     "releaseTitleAsVersion": "Utilizar o título da versão como cadeia de versões", | ||||||
|     "releaseDateAsVersionExplanation": "Esta opção só deve ser usada para aplicativos onde a detecção de versão não funciona corretamente, mas há uma data de lançamento disponível.", |     "releaseDateAsVersionExplanation": "Esta opção só deve ser usada para aplicações onde a deteção de versão não funciona corretamente, mas existe uma data de lançamento disponível.", | ||||||
|     "changes": "Alterações", |     "changes": "Alterações", | ||||||
|     "releaseDate": "Data de lançamento", |     "releaseDate": "Data de lançamento", | ||||||
|     "importFromURLsInFile": "Importar de URLs em arquivo (formato OPML)", |     "importFromURLsInFile": "Importar de URLs em arquivo (formato OPML)", | ||||||
| @@ -227,15 +227,15 @@ | |||||||
|     "dontShowAgain": "Não mostrar isso novamente", |     "dontShowAgain": "Não mostrar isso novamente", | ||||||
|     "dontShowTrackOnlyWarnings": "Não mostrar avisos 'Apenas monitorar'", |     "dontShowTrackOnlyWarnings": "Não mostrar avisos 'Apenas monitorar'", | ||||||
|     "dontShowAPKOriginWarnings": "Não mostrar avisos de origem da APK", |     "dontShowAPKOriginWarnings": "Não mostrar avisos de origem da APK", | ||||||
|     "moveNonInstalledAppsToBottom": "Mover aplicativos não instalados para o fundo da lista de aplicativos", |     "moveNonInstalledAppsToBottom": "Mover aplicações não instaladas para o fundo da lista de aplicações", | ||||||
|     "gitlabPATLabel": "Token de acesso pessoal do Gitlab", |     "gitlabPATLabel": "Token de acesso pessoal do Gitlab", | ||||||
|     "about": "Sobre", |     "about": "Sobre", | ||||||
|     "requiresCredentialsInSettings": "{}: Isso requer credenciais adicionais (em Configurações)", |     "requiresCredentialsInSettings": "{}: Isso requer credenciais adicionais (em Configurações)", | ||||||
|     "checkOnStart": "Verificar se há atualizações ao iniciar", |     "checkOnStart": "Verificar se há atualizações ao iniciar", | ||||||
|     "tryInferAppIdFromCode": "Tente inferir o ID do aplicativo pelo código-fonte", |     "tryInferAppIdFromCode": "Tentar inferir o ID da aplicação a partir do código-fonte", | ||||||
|     "removeOnExternalUninstall": "Remover automaticamente aplicativos desinstalados externamente", |     "removeOnExternalUninstall": "Remover automaticamente aplicações desinstaladas externamente", | ||||||
|     "pickHighestVersionCode": "Auto-selecionar o maior número de versão do APK", |     "pickHighestVersionCode": "Auto-selecionar o maior número de versão do APK", | ||||||
|     "checkUpdateOnDetailPage": "Checar por atualizações ao abrir a página de detalhes de um aplicativo", |     "checkUpdateOnDetailPage": "Checar por atualizações ao abrir a página de detalhes de uma aplicação", | ||||||
|     "disablePageTransitions": "Desativar animações de transição de página", |     "disablePageTransitions": "Desativar animações de transição de página", | ||||||
|     "reversePageTransitions": "Animações de transição de página invertidas", |     "reversePageTransitions": "Animações de transição de página invertidas", | ||||||
|     "minStarCount": "Contagem mínima de estrelas", |     "minStarCount": "Contagem mínima de estrelas", | ||||||
| @@ -245,15 +245,16 @@ | |||||||
|     "sortByLastLinkSegment": "Ordenar apenas usando o último segmento do link", |     "sortByLastLinkSegment": "Ordenar apenas usando o último segmento do link", | ||||||
|     "filterReleaseNotesByRegEx": "Filtrar notas de versão usando Regex", |     "filterReleaseNotesByRegEx": "Filtrar notas de versão usando Regex", | ||||||
|     "customLinkFilterRegex": "Filtro de link personalizado usando expressão regular (Padrão '.apk$')", |     "customLinkFilterRegex": "Filtro de link personalizado usando expressão regular (Padrão '.apk$')", | ||||||
|     "appsPossiblyUpdated": "Tentativas de atualização de aplicativos", |     "appsPossiblyUpdated": "Aplicações possivelmente atualizadas", | ||||||
|     "appsPossiblyUpdatedNotifDescription": "Notifica o usuário de que atualizações de um ou mais aplicativos foram potencialmente aplicadas em segundo-plano", |     "appsPossiblyUpdatedNotifDescription": "Notifica o utilizador de que as atualizações de uma ou mais aplicações foram potencialmente aplicadas em segundo plano", | ||||||
|     "xWasPossiblyUpdatedToY": "{} pode ter sido atualizado para {}.", |     "xWasPossiblyUpdatedToY": "{} pode ter sido atualizado para {}.", | ||||||
|     "enableBackgroundUpdates": "Ativar atualizações em segundo-plano", |     "enableBackgroundUpdates": "Ativar atualizações em segundo-plano", | ||||||
|     "backgroundUpdateReqsExplanation": "Atualizações em segundo-plano podem não ser possíveis para todos os aplicativos.", |     "backgroundUpdateReqsExplanation": "As atualizações em segundo plano podem não ser possíveis para todas as aplicações.", | ||||||
|     "backgroundUpdateLimitsExplanation": "O sucesso de uma instalação em segundo-plano só pode ser determinado quando o Obtainium é aberto.", |     "backgroundUpdateLimitsExplanation": "O sucesso de uma instalação em segundo-plano só pode ser determinado quando o Obtainium é aberto.", | ||||||
|     "verifyLatestTag": "Verifique a 'última' etiqueta", |     "verifyLatestTag": "Verifique a 'última' etiqueta", | ||||||
|     "intermediateLinkRegex": "Filtrar um link 'intermediário' para visitar", |     "intermediateLinkRegex": "Filtrar um link 'intermediário' para visitar", | ||||||
|     "filterByLinkText": "Filtrar links pelo texto do link", |     "filterByLinkText": "Filtrar links pelo texto do link", | ||||||
|  |     "matchLinksOutsideATags": "Corresponder ligações fora das etiquetas <a>", | ||||||
|     "intermediateLinkNotFound": "Link intermediário não encontrado", |     "intermediateLinkNotFound": "Link intermediário não encontrado", | ||||||
|     "intermediateLink": "Link intermediário", |     "intermediateLink": "Link intermediário", | ||||||
|     "exemptFromBackgroundUpdates": "Isento de atualizações em segundo-plano (se ativadas)", |     "exemptFromBackgroundUpdates": "Isento de atualizações em segundo-plano (se ativadas)", | ||||||
| @@ -281,14 +282,14 @@ | |||||||
|     "installing": "Instalando", |     "installing": "Instalando", | ||||||
|     "skipUpdateNotifications": "Pular notificações de update", |     "skipUpdateNotifications": "Pular notificações de update", | ||||||
|     "updatesAvailableNotifChannel": "Atualizações disponíveis", |     "updatesAvailableNotifChannel": "Atualizações disponíveis", | ||||||
|     "appsUpdatedNotifChannel": "Aplicativos atualizados", |     "appsUpdatedNotifChannel": "Aplicações atualizadas", | ||||||
|     "appsPossiblyUpdatedNotifChannel": "Tentativas de atualização de aplicativos", |     "appsPossiblyUpdatedNotifChannel": "Aplicações possivelmente atualizadas", | ||||||
|     "errorCheckingUpdatesNotifChannel": "Erro ao procurar por atualizações", |     "errorCheckingUpdatesNotifChannel": "Erro ao procurar por atualizações", | ||||||
|     "appsRemovedNotifChannel": "Aplicativos removidos", |     "appsRemovedNotifChannel": "Aplicações removidas", | ||||||
|     "downloadingXNotifChannel": "Baixando {}", |     "downloadingXNotifChannel": "Baixando {}", | ||||||
|     "completeAppInstallationNotifChannel": "Instalação completa do aplicativo", |     "completeAppInstallationNotifChannel": "Instalação da aplicação concluída", | ||||||
|     "checkingForUpdatesNotifChannel": "Checando por atualizações", |     "checkingForUpdatesNotifChannel": "Checando por atualizações", | ||||||
|     "onlyCheckInstalledOrTrackOnlyApps": "Apenas verificar atualizações de aplicativos instalados e 'Apenas monitorar'", |     "onlyCheckInstalledOrTrackOnlyApps": "Apenas verificar atualizações de aplicações instaladas e 'Apenas monitorizar'", | ||||||
|     "supportFixedAPKURL": "Suporte a APK com URLs fixas", |     "supportFixedAPKURL": "Suporte a APK com URLs fixas", | ||||||
|     "selectX": "Selecionar {}", |     "selectX": "Selecionar {}", | ||||||
|     "parallelDownloads": "Permitir downloads paralelos", |     "parallelDownloads": "Permitir downloads paralelos", | ||||||
| @@ -298,7 +299,7 @@ | |||||||
|     "shizukuOldAndroidWithADB": "Shizuku a funcionar no Android < 8.1 com ADB - atualizar o Android ou utilizar o Sui", |     "shizukuOldAndroidWithADB": "Shizuku a funcionar no Android < 8.1 com ADB - atualizar o Android ou utilizar o Sui", | ||||||
|     "shizukuPretendToBeGooglePlay": "Definir o Google Play como fonte de instalação (se for utilizado o Shizuku)", |     "shizukuPretendToBeGooglePlay": "Definir o Google Play como fonte de instalação (se for utilizado o Shizuku)", | ||||||
|     "useSystemFont": "Usar fonte padrão do sistema", |     "useSystemFont": "Usar fonte padrão do sistema", | ||||||
|     "useVersionCodeAsOSVersion": "Usar versionCode do aplicativo como versão detectada pelo sistema operacional", |     "useVersionCodeAsOSVersion": "Usar o versionCode da aplicação como a versão detetada pelo sistema operativo", | ||||||
|     "requestHeader": "Requisitar cabeçalho", |     "requestHeader": "Requisitar cabeçalho", | ||||||
|     "useLatestAssetDateAsReleaseDate": "Use o último upload de recursos como data de lançamento", |     "useLatestAssetDateAsReleaseDate": "Use o último upload de recursos como data de lançamento", | ||||||
|     "defaultPseudoVersioningMethod": "Método de pseudo-versionamento padrão", |     "defaultPseudoVersioningMethod": "Método de pseudo-versionamento padrão", | ||||||
| @@ -335,25 +336,28 @@ | |||||||
|     "foregroundServiceExplanation": "Utilizar um serviço em primeiro plano para verificação de actualizações (mais fiável, consome mais energia)", |     "foregroundServiceExplanation": "Utilizar um serviço em primeiro plano para verificação de actualizações (mais fiável, consome mais energia)", | ||||||
|     "fgServiceNotice": "Esta notificação é necessária para a verificação de actualizações em segundo plano (pode ser ocultada nas definições do SO)", |     "fgServiceNotice": "Esta notificação é necessária para a verificação de actualizações em segundo plano (pode ser ocultada nas definições do SO)", | ||||||
|     "excludeSecrets": "Excluir segredos", |     "excludeSecrets": "Excluir segredos", | ||||||
|  |     "GHReqPrefix": "Instância 'sky22333/hubproxy' para pedidos de GitHub", | ||||||
|  |     "includeZips": "Incluir ficheiros ZIP", | ||||||
|  |     "zippedApkFilterRegEx": "Filtrar APKs dentro do ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Remover aplicativo?", |         "one": "Remover aplicação?", | ||||||
|         "other": "Remover aplicativos?" |         "other": "Remover aplicações?" | ||||||
|     }, |     }, | ||||||
|     "tooManyRequestsTryAgainInMinutes": { |     "tooManyRequestsTryAgainInMinutes": { | ||||||
|         "one": "Muitas solicitações (taxa de solicitações limitada) - tente novamente em {} minuto", |         "one": "Muitos pedidos (taxa de pedidos limitada) - tente novamente em {} minuto", | ||||||
|         "other": "Muitas solicitações (taxa limitada) - tente novamente em {} minutos" |         "other": "Muitos pedidos (taxa limitada) - tente novamente em {} minutos" | ||||||
|     }, |     }, | ||||||
|     "bgUpdateGotErrorRetryInMinutes": { |     "bgUpdateGotErrorRetryInMinutes": { | ||||||
|         "one": "A verificação de atualizações em segundo-plano encontrou um {}, agendada uma nova verificação em {} minuto", |         "one": "A verificação de atualizações em segundo plano encontrou um {}, agendada uma nova verificação em {} minuto", | ||||||
|         "other": "A verificação de atualizações em segundo-plano encontrou um {}, agendada uma nova verificação em {} minutos" |         "other": "A verificação de atualizações em segundo plano encontrou um {}, agendada uma nova verificação em {} minutos" | ||||||
|     }, |     }, | ||||||
|     "bgCheckFoundUpdatesWillNotifyIfNeeded": { |     "bgCheckFoundUpdatesWillNotifyIfNeeded": { | ||||||
|         "one": "A verificação de atualizações em segundo-plano encontrou {} atualização, o usuário sera notificado caso necessário", |         "one": "A verificação de atualizações em segundo plano encontrou {} atualização, o utilizador será notificado caso necessário", | ||||||
|         "other": "A verificação de atualizações em segundo-plano encontrou {} atualizações, o usuário sera notificado caso necessário" |         "other": "A verificação de atualizações em segundo plano encontrou {} atualizações, o utilizador será notificado caso necessário" | ||||||
|     }, |     }, | ||||||
|     "apps": { |     "apps": { | ||||||
|         "one": "{} Aplicativo", |         "one": "{} Aplicação", | ||||||
|         "other": "{} Aplicativos" |         "other": "{} Aplicações" | ||||||
|     }, |     }, | ||||||
|     "url": { |     "url": { | ||||||
|         "one": "{} URL", |         "one": "{} URL", | ||||||
| @@ -376,20 +380,20 @@ | |||||||
|         "other": "Foram limpos {n} logs (antes = {antes}, depois = {depois})" |         "other": "Foram limpos {n} logs (antes = {antes}, depois = {depois})" | ||||||
|     }, |     }, | ||||||
|     "xAndNMoreUpdatesAvailable": { |     "xAndNMoreUpdatesAvailable": { | ||||||
|         "one": "{} e um outro aplicativo possui atualizações.", |         "one": "{} e uma outra aplicação possui atualizações.", | ||||||
|         "other": "{} e {} outros aplicativo possuem atualizações." |         "other": "{} e {} outras aplicações possuem atualizações." | ||||||
|     }, |     }, | ||||||
|     "xAndNMoreUpdatesInstalled": { |     "xAndNMoreUpdatesInstalled": { | ||||||
|         "one": "{} e um outro aplicativo foram atualizado.", |         "one": "{} e uma outra aplicação foram atualizadas.", | ||||||
|         "other": "{} e {} outros aplicativos foram atualizados." |         "other": "{} e {} outras aplicações foram atualizadas." | ||||||
|     }, |     }, | ||||||
|     "xAndNMoreUpdatesFailed": { |     "xAndNMoreUpdatesFailed": { | ||||||
|         "one": "Falha ao atualizar {} e mais 1 aplicação.", |         "one": "Falha ao atualizar {} e mais 1 aplicação.", | ||||||
|         "other": "Falha ao atualizar {} e {} mais aplicações." |         "other": "Falha ao atualizar {} e {} outras aplicações." | ||||||
|     }, |     }, | ||||||
|     "xAndNMoreUpdatesPossiblyInstalled": { |     "xAndNMoreUpdatesPossiblyInstalled": { | ||||||
|         "one": "{} e um outro aplicativo podem ter sido atualizados.", |         "one": "{} e uma outra aplicação podem ter sido atualizadas.", | ||||||
|         "other": "{} e {} outros aplicativos podem ter sido atualizados." |         "other": "{} e {} outras aplicações podem ter sido atualizadas." | ||||||
|     }, |     }, | ||||||
|     "apk": { |     "apk": { | ||||||
|         "one": "{} APK", |         "one": "{} APK", | ||||||
|   | |||||||
| @@ -253,7 +253,8 @@ | |||||||
|     "backgroundUpdateLimitsExplanation": "Успешность фоновой установки можно определить только после открытия Obtainium", |     "backgroundUpdateLimitsExplanation": "Успешность фоновой установки можно определить только после открытия Obtainium", | ||||||
|     "verifyLatestTag": "Проверять метку «latest»", |     "verifyLatestTag": "Проверять метку «latest»", | ||||||
|     "intermediateLinkRegex": "Фильтр для «промежуточной» ссылки для посещения", |     "intermediateLinkRegex": "Фильтр для «промежуточной» ссылки для посещения", | ||||||
|     "filterByLinkText": "Фильтрация ссылок по тексту ссылки", |     "filterByLinkText": "Фильтровать ссылки по тексту ссылки", | ||||||
|  |     "matchLinksOutsideATags": "Сопоставлять ссылки вне тегов <a>", | ||||||
|     "intermediateLinkNotFound": "Промежуточная ссылка не найдена", |     "intermediateLinkNotFound": "Промежуточная ссылка не найдена", | ||||||
|     "intermediateLink": "Промежуточная ссылка", |     "intermediateLink": "Промежуточная ссылка", | ||||||
|     "exemptFromBackgroundUpdates": "Исключить из фоновых обновлений (если включено)", |     "exemptFromBackgroundUpdates": "Исключить из фоновых обновлений (если включено)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Использовать приоритетную службу для проверки обновлений (надёжнее, энергозатратнее)", |     "foregroundServiceExplanation": "Использовать приоритетную службу для проверки обновлений (надёжнее, энергозатратнее)", | ||||||
|     "fgServiceNotice": "Это уведомление необходимо для фоновой проверки обновлений (оно может быть скрыто в настройках ОС)", |     "fgServiceNotice": "Это уведомление необходимо для фоновой проверки обновлений (оно может быть скрыто в настройках ОС)", | ||||||
|     "excludeSecrets": "Исключить секреты", |     "excludeSecrets": "Исключить секреты", | ||||||
|  |     "GHReqPrefix": "Экземпляр 'sky22333/hubproxy' для запросов на GitHub", | ||||||
|  |     "includeZips": "Включить ZIP-файлы", | ||||||
|  |     "zippedApkFilterRegEx": "Фильтр APK внутри ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Удалить приложение?", |         "one": "Удалить приложение?", | ||||||
|         "other": "Удалить приложения?" |         "other": "Удалить приложения?" | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ const neverAutoTranslate = { | |||||||
|     obtainiumImport: ['nl'], |     obtainiumImport: ['nl'], | ||||||
|     appLogs: ['nl'], |     appLogs: ['nl'], | ||||||
|     apks: ['vi'], |     apks: ['vi'], | ||||||
|  |     minute: ['fr'], | ||||||
|     tencentAppStore: ['*'] |     tencentAppStore: ['*'] | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Verifiera 'senaste'-taggen", |     "verifyLatestTag": "Verifiera 'senaste'-taggen", | ||||||
|     "intermediateLinkRegex": "Filtrera för en \"mellanliggande\" länk att besöka", |     "intermediateLinkRegex": "Filtrera för en \"mellanliggande\" länk att besöka", | ||||||
|     "filterByLinkText": "Filtrera länkar efter länktext", |     "filterByLinkText": "Filtrera länkar efter länktext", | ||||||
|  |     "matchLinksOutsideATags": "Matcha länkar utanför <a>-taggar", | ||||||
|     "intermediateLinkNotFound": "Mellanlänk hittades inte", |     "intermediateLinkNotFound": "Mellanlänk hittades inte", | ||||||
|     "intermediateLink": "Mellanlänk", |     "intermediateLink": "Mellanlänk", | ||||||
|     "exemptFromBackgroundUpdates": "Undta från bakgrundsuppdateringar (om aktiverad)", |     "exemptFromBackgroundUpdates": "Undta från bakgrundsuppdateringar (om aktiverad)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Använd en förgrundstjänst för uppdateringskontroll (mer tillförlitlig, förbrukar mer ström)", |     "foregroundServiceExplanation": "Använd en förgrundstjänst för uppdateringskontroll (mer tillförlitlig, förbrukar mer ström)", | ||||||
|     "fgServiceNotice": "Detta meddelande krävs för bakgrundsuppdateringskontroll (det kan döljas i OS-inställningarna)", |     "fgServiceNotice": "Detta meddelande krävs för bakgrundsuppdateringskontroll (det kan döljas i OS-inställningarna)", | ||||||
|     "excludeSecrets": "Utesluta hemligheter", |     "excludeSecrets": "Utesluta hemligheter", | ||||||
|  |     "GHReqPrefix": "Instansen \"sky22333/hubproxy\" för GitHub-förfrågningar", | ||||||
|  |     "includeZips": "Inkludera ZIP-filer", | ||||||
|  |     "zippedApkFilterRegEx": "Filtrera APK:er inuti ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Ta Bort App?", |         "one": "Ta Bort App?", | ||||||
|         "other": "Ta Bort Appar?" |         "other": "Ta Bort Appar?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "'latest' etiketini doğrula", |     "verifyLatestTag": "'latest' etiketini doğrula", | ||||||
|     "intermediateLinkRegex": "Ziyaret Edilecek 'Orta Düzey' Bağlantıyı Filtrele", |     "intermediateLinkRegex": "Ziyaret Edilecek 'Orta Düzey' Bağlantıyı Filtrele", | ||||||
|     "filterByLinkText": "Bağlantıları bağlantı metnine göre filtrele", |     "filterByLinkText": "Bağlantıları bağlantı metnine göre filtrele", | ||||||
|  |     "matchLinksOutsideATags": "<a> etiketleri dışındaki bağlantıları eşleştirin", | ||||||
|     "intermediateLinkNotFound": "Ara bağlantı bulunamadı", |     "intermediateLinkNotFound": "Ara bağlantı bulunamadı", | ||||||
|     "intermediateLink": "Ara bağlantı", |     "intermediateLink": "Ara bağlantı", | ||||||
|     "exemptFromBackgroundUpdates": "Arka plan güncellemelerinden muaf tut (etkinse)", |     "exemptFromBackgroundUpdates": "Arka plan güncellemelerinden muaf tut (etkinse)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Güncelleme denetimi için bir ön plan hizmeti kullanın (daha güvenilir, daha fazla güç tüketir)", |     "foregroundServiceExplanation": "Güncelleme denetimi için bir ön plan hizmeti kullanın (daha güvenilir, daha fazla güç tüketir)", | ||||||
|     "fgServiceNotice": "Bu bildirim arka planda güncelleme kontrolü için gereklidir (işletim sistemi ayarlarından gizlenebilir)", |     "fgServiceNotice": "Bu bildirim arka planda güncelleme kontrolü için gereklidir (işletim sistemi ayarlarından gizlenebilir)", | ||||||
|     "excludeSecrets": "Sırları hariç tut", |     "excludeSecrets": "Sırları hariç tut", | ||||||
|  |     "GHReqPrefix": "GitHub istekleri için 'sky22333/hubproxy' örneği", | ||||||
|  |     "includeZips": "ZIP dosyalarını dahil edin", | ||||||
|  |     "zippedApkFilterRegEx": "ZIP içindeki APK'ları filtreleme", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Uygulamayı Kaldır?", |         "one": "Uygulamayı Kaldır?", | ||||||
|         "other": "Uygulamaları Kaldır?" |         "other": "Uygulamaları Kaldır?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Перевірити тег 'latest'", |     "verifyLatestTag": "Перевірити тег 'latest'", | ||||||
|     "intermediateLinkRegex": "Фільтр для 'Проміжного' Посилання для Відвідування", |     "intermediateLinkRegex": "Фільтр для 'Проміжного' Посилання для Відвідування", | ||||||
|     "filterByLinkText": "Фільтрувати посилання за текстом посилання", |     "filterByLinkText": "Фільтрувати посилання за текстом посилання", | ||||||
|  |     "matchLinksOutsideATags": "Зіставлення посилань поза тегами <a>", | ||||||
|     "intermediateLinkNotFound": "Проміжне посилання не знайдено", |     "intermediateLinkNotFound": "Проміжне посилання не знайдено", | ||||||
|     "intermediateLink": "Проміжне посилання", |     "intermediateLink": "Проміжне посилання", | ||||||
|     "exemptFromBackgroundUpdates": "Виключено з фонових оновлень (якщо ввімкнено)", |     "exemptFromBackgroundUpdates": "Виключено з фонових оновлень (якщо ввімкнено)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Використовуйте службу переднього плану для перевірки оновлень (надійніша, споживає більше енергії)", |     "foregroundServiceExplanation": "Використовуйте службу переднього плану для перевірки оновлень (надійніша, споживає більше енергії)", | ||||||
|     "fgServiceNotice": "Це сповіщення необхідне для фонової перевірки оновлень (його можна приховати в налаштуваннях ОС)", |     "fgServiceNotice": "Це сповіщення необхідне для фонової перевірки оновлень (його можна приховати в налаштуваннях ОС)", | ||||||
|     "excludeSecrets": "Виключити секрети", |     "excludeSecrets": "Виключити секрети", | ||||||
|  |     "GHReqPrefix": "екземпляр 'sky22333/hubproxy' для запитів на GitHub", | ||||||
|  |     "includeZips": "Додайте ZIP-файли", | ||||||
|  |     "zippedApkFilterRegEx": "Фільтруйте APK-файли всередині ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Видалити застосунок?", |         "one": "Видалити застосунок?", | ||||||
|         "other": "Видалити застосунки?" |         "other": "Видалити застосунки?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "Xác minh thẻ 'mới nhất'", |     "verifyLatestTag": "Xác minh thẻ 'mới nhất'", | ||||||
|     "intermediateLinkRegex": "Lọc tìm liên kết 'Trung cấp' để truy cập", |     "intermediateLinkRegex": "Lọc tìm liên kết 'Trung cấp' để truy cập", | ||||||
|     "filterByLinkText": "Lọc liên kết theo văn bản liên kết", |     "filterByLinkText": "Lọc liên kết theo văn bản liên kết", | ||||||
|  |     "matchLinksOutsideATags": "Khớp các liên kết bên ngoài thẻ <a>", | ||||||
|     "intermediateLinkNotFound": "Không tìm thấy liên kết trung gian", |     "intermediateLinkNotFound": "Không tìm thấy liên kết trung gian", | ||||||
|     "intermediateLink": "Liên kết trung gian", |     "intermediateLink": "Liên kết trung gian", | ||||||
|     "exemptFromBackgroundUpdates": "Miễn cập nhật nền (nếu được bật)", |     "exemptFromBackgroundUpdates": "Miễn cập nhật nền (nếu được bật)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Sử dụng dịch vụ nền trước để kiểm tra cập nhật (đáng tin cậy hơn, tiêu tốn nhiều pin hơn)", |     "foregroundServiceExplanation": "Sử dụng dịch vụ nền trước để kiểm tra cập nhật (đáng tin cậy hơn, tiêu tốn nhiều pin hơn)", | ||||||
|     "fgServiceNotice": "Thông báo này là bắt buộc để kiểm tra cập nhật nền (có thể ẩn trong cài đặt hệ điều hành).", |     "fgServiceNotice": "Thông báo này là bắt buộc để kiểm tra cập nhật nền (có thể ẩn trong cài đặt hệ điều hành).", | ||||||
|     "excludeSecrets": "Loại trừ thông tin bí mật", |     "excludeSecrets": "Loại trừ thông tin bí mật", | ||||||
|  |     "GHReqPrefix": "Thực thể 'sky22333/hubproxy' cho các yêu cầu GitHub", | ||||||
|  |     "includeZips": "Ba gồm các tệp ZIP", | ||||||
|  |     "zippedApkFilterRegEx": "Lọc các tệp APK bên trong tệp ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Gỡ ứng dụng?", |         "one": "Gỡ ứng dụng?", | ||||||
|         "other": "Gỡ ứng dụng?" |         "other": "Gỡ ứng dụng?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "驗證「最新」標籤", |     "verifyLatestTag": "驗證「最新」標籤", | ||||||
|     "intermediateLinkRegex": "過濾要存取的「中間」連結", |     "intermediateLinkRegex": "過濾要存取的「中間」連結", | ||||||
|     "filterByLinkText": "按連結文字過濾連結", |     "filterByLinkText": "按連結文字過濾連結", | ||||||
|  |     "matchLinksOutsideATags": "匹配 <a> 標籤外的連結", | ||||||
|     "intermediateLinkNotFound": "沒有找到中間連結", |     "intermediateLinkNotFound": "沒有找到中間連結", | ||||||
|     "intermediateLink": "中間連結", |     "intermediateLink": "中間連結", | ||||||
|     "exemptFromBackgroundUpdates": "免除背景更新(若已啟用)", |     "exemptFromBackgroundUpdates": "免除背景更新(若已啟用)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)", |     "foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)", | ||||||
|     "fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)", |     "fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)", | ||||||
|     "excludeSecrets": "Exclude secrets", |     "excludeSecrets": "Exclude secrets", | ||||||
|  |     "GHReqPrefix": "'sky22333/hubproxy' instance for GitHub requests", | ||||||
|  |     "includeZips": "Include ZIP files", | ||||||
|  |     "zippedApkFilterRegEx": "Filter APKs inside ZIP", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "移除應用程式?", |         "one": "移除應用程式?", | ||||||
|         "other": "移除應用程式?" |         "other": "移除應用程式?" | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ | |||||||
|     "verifyLatestTag": "验证“Latest”标签", |     "verifyLatestTag": "验证“Latest”标签", | ||||||
|     "intermediateLinkRegex": "筛选中转链接的正则表达式", |     "intermediateLinkRegex": "筛选中转链接的正则表达式", | ||||||
|     "filterByLinkText": "根据链接文本进行筛选", |     "filterByLinkText": "根据链接文本进行筛选", | ||||||
|  |     "matchLinksOutsideATags": "匹配 <a> 标签外的链接", | ||||||
|     "intermediateLinkNotFound": "未找到中转链接", |     "intermediateLinkNotFound": "未找到中转链接", | ||||||
|     "intermediateLink": "中转链接", |     "intermediateLink": "中转链接", | ||||||
|     "exemptFromBackgroundUpdates": "禁用后台更新(仅此应用生效,即使已启用全局后台更新)", |     "exemptFromBackgroundUpdates": "禁用后台更新(仅此应用生效,即使已启用全局后台更新)", | ||||||
| @@ -335,6 +336,9 @@ | |||||||
|     "foregroundServiceExplanation": "使用前台服务检查更新(更稳定,但也更耗电)", |     "foregroundServiceExplanation": "使用前台服务检查更新(更稳定,但也更耗电)", | ||||||
|     "fgServiceNotice": "后台检查更新时需要此通知(可在操作系统设置中隐藏)", |     "fgServiceNotice": "后台检查更新时需要此通知(可在操作系统设置中隐藏)", | ||||||
|     "excludeSecrets": "排除机密", |     "excludeSecrets": "排除机密", | ||||||
|  |     "GHReqPrefix": "用于 GitHub 请求的 \"sky22333/hubproxy \"实例", | ||||||
|  |     "includeZips": "包含 ZIP 文件", | ||||||
|  |     "zippedApkFilterRegEx": "过滤 ZIP 内的 APK", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "是否删除应用?", |         "one": "是否删除应用?", | ||||||
|         "other": "是否删除应用?" |         "other": "是否删除应用?" | ||||||
|   | |||||||
| @@ -82,13 +82,13 @@ class APKCombo extends AppSource { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Future<String> apkUrlPrefetchModifier( |   Future<String> assetUrlPrefetchModifier( | ||||||
|     String apkUrl, |     String assetUrl, | ||||||
|     String standardUrl, |     String standardUrl, | ||||||
|     Map<String, dynamic> additionalSettings, |     Map<String, dynamic> additionalSettings, | ||||||
|   ) async { |   ) async { | ||||||
|     var freshURLs = await getApkUrls(standardUrl, additionalSettings); |     var freshURLs = await getApkUrls(standardUrl, additionalSettings); | ||||||
|     var path2Match = Uri.parse(apkUrl).path; |     var path2Match = Uri.parse(assetUrl).path; | ||||||
|     for (var url in freshURLs) { |     for (var url in freshURLs) { | ||||||
|       if (Uri.parse(url.value).path == path2Match) { |       if (Uri.parse(url.value).path == path2Match) { | ||||||
|         return url.value; |         return url.value; | ||||||
|   | |||||||
| @@ -1,7 +1,9 @@ | |||||||
| import 'dart:convert'; | import 'dart:convert'; | ||||||
|  |  | ||||||
|  | import 'package:easy_localization/easy_localization.dart'; | ||||||
| import 'package:html/parser.dart'; | import 'package:html/parser.dart'; | ||||||
| import 'package:obtainium/app_sources/html.dart'; | import 'package:obtainium/app_sources/html.dart'; | ||||||
|  | import 'package:obtainium/components/generated_form.dart'; | ||||||
| import 'package:obtainium/custom_errors.dart'; | import 'package:obtainium/custom_errors.dart'; | ||||||
| import 'package:obtainium/providers/source_provider.dart'; | import 'package:obtainium/providers/source_provider.dart'; | ||||||
|  |  | ||||||
| @@ -9,6 +11,17 @@ class Farsroid extends AppSource { | |||||||
|   Farsroid() { |   Farsroid() { | ||||||
|     hosts = ['farsroid.com']; |     hosts = ['farsroid.com']; | ||||||
|     name = 'Farsroid'; |     name = 'Farsroid'; | ||||||
|  |     naiveStandardVersionDetection = true; | ||||||
|  |  | ||||||
|  |     additionalSourceAppSpecificSettingFormItems = [ | ||||||
|  |       [ | ||||||
|  |         GeneratedFormSwitch( | ||||||
|  |           'useFirstApkOfVersion', | ||||||
|  |           label: tr('useFirstApkOfVersion'), | ||||||
|  |           defaultValue: true, | ||||||
|  |         ), | ||||||
|  |       ], | ||||||
|  |     ]; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
| @@ -57,15 +70,21 @@ class Farsroid extends AppSource { | |||||||
|     if (html2.isEmpty) { |     if (html2.isEmpty) { | ||||||
|       throw NoAPKError(); |       throw NoAPKError(); | ||||||
|     } |     } | ||||||
|     var apkLinks = |     var apkLinks = (await grabLinksCommon( | ||||||
|         (await grabLinksCommon(html2, res2.request!.url, additionalSettings)) |       html2, | ||||||
|             .map((l) => MapEntry(Uri.parse(l.key).pathSegments.last, l.key)) |       res2.request!.url, | ||||||
|  |       additionalSettings, | ||||||
|  |     )).map((l) => MapEntry(Uri.parse(l.key).pathSegments.last, l.key)).toList(); | ||||||
|  |  | ||||||
|  |     if (additionalSettings['useFirstApkOfVersion'] == true) { | ||||||
|  |       apkLinks = apkLinks | ||||||
|           .where( |           .where( | ||||||
|             (l) => l.key.toLowerCase().startsWith( |             (l) => l.key.toLowerCase().startsWith( | ||||||
|               '$appName-$version'.toLowerCase(), |               '$appName-$version'.toLowerCase(), | ||||||
|             ), |             ), | ||||||
|           ) |           ) | ||||||
|           .toList(); |           .toList(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (apkLinks.isEmpty) { |     if (apkLinks.isEmpty) { | ||||||
|       throw NoAPKError(); |       throw NoAPKError(); | ||||||
|   | |||||||
| @@ -32,6 +32,7 @@ class FDroid extends AppSource { | |||||||
|         GeneratedFormSwitch( |         GeneratedFormSwitch( | ||||||
|           'trySelectingSuggestedVersionCode', |           'trySelectingSuggestedVersionCode', | ||||||
|           label: tr('trySelectingSuggestedVersionCode'), |           label: tr('trySelectingSuggestedVersionCode'), | ||||||
|  |           defaultValue: true, | ||||||
|         ), |         ), | ||||||
|       ], |       ], | ||||||
|       [ |       [ | ||||||
|   | |||||||
| @@ -29,6 +29,13 @@ class FDroidRepo extends AppSource { | |||||||
|           defaultValue: false, |           defaultValue: false, | ||||||
|         ), |         ), | ||||||
|       ], |       ], | ||||||
|  |       [ | ||||||
|  |         GeneratedFormSwitch( | ||||||
|  |           'trySelectingSuggestedVersionCode', | ||||||
|  |           label: tr('trySelectingSuggestedVersionCode'), | ||||||
|  |           defaultValue: true, | ||||||
|  |         ), | ||||||
|  |       ], | ||||||
|     ]; |     ]; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -170,6 +177,7 @@ class FDroidRepo extends AppSource { | |||||||
|     } |     } | ||||||
|     standardUrl = removeQueryParamsFromUrl(standardUrl); |     standardUrl = removeQueryParamsFromUrl(standardUrl); | ||||||
|     bool pickHighestVersionCode = additionalSettings['pickHighestVersionCode']; |     bool pickHighestVersionCode = additionalSettings['pickHighestVersionCode']; | ||||||
|  |     bool trySelectingSuggestedVersionCode = additionalSettings['trySelectingSuggestedVersionCode']; | ||||||
|     if (appIdOrName == null) { |     if (appIdOrName == null) { | ||||||
|       throw NoReleasesError(); |       throw NoReleasesError(); | ||||||
|     } |     } | ||||||
| @@ -207,38 +215,58 @@ class FDroidRepo extends AppSource { | |||||||
|       foundApps[0].querySelector('name')?.innerHtml ?? appId; |       foundApps[0].querySelector('name')?.innerHtml ?? appId; | ||||||
|       var appName = foundApps[0].querySelector('name')?.innerHtml ?? appId; |       var appName = foundApps[0].querySelector('name')?.innerHtml ?? appId; | ||||||
|       var releases = foundApps[0].querySelectorAll('package'); |       var releases = foundApps[0].querySelectorAll('package'); | ||||||
|  |       if (releases.isEmpty) { | ||||||
|  |         throw NoReleasesError(); | ||||||
|  |       } | ||||||
|  |       String? changeLog = foundApps[0].querySelector('changelog')?.innerHtml; | ||||||
|       String? latestVersion = releases[0].querySelector('version')?.innerHtml; |       String? latestVersion = releases[0].querySelector('version')?.innerHtml; | ||||||
|       String? added = releases[0].querySelector('added')?.innerHtml; |  | ||||||
|       DateTime? releaseDate = added != null ? DateTime.parse(added) : null; |  | ||||||
|       if (latestVersion == null) { |       if (latestVersion == null) { | ||||||
|         throw NoVersionError(); |         throw NoVersionError(); | ||||||
|       } |       } | ||||||
|       var latestVersionReleases = releases |       String? marketvercodeStr = foundApps[0].querySelector('marketvercode')?.innerHtml; | ||||||
|           .where( |       int? marketvercode = int.tryParse(marketvercodeStr ?? ''); | ||||||
|             (element) => |       List selectedReleases = []; | ||||||
|                 element.querySelector('version')?.innerHtml == latestVersion && |       if (trySelectingSuggestedVersionCode && marketvercode != null) { | ||||||
|                 element.querySelector('apkname') != null, |         selectedReleases = releases.where((e) => | ||||||
|           ) |           int.tryParse(e.querySelector('versioncode')?.innerHtml ?? '') == marketvercode && | ||||||
|           .toList(); |           e.querySelector('apkname') != null | ||||||
|       if (latestVersionReleases.length > 1 && pickHighestVersionCode) { |         ).toList(); | ||||||
|         latestVersionReleases.sort((e1, e2) { |  | ||||||
|           return int.parse( |  | ||||||
|             e2.querySelector('versioncode')!.innerHtml, |  | ||||||
|           ).compareTo(int.parse(e1.querySelector('versioncode')!.innerHtml)); |  | ||||||
|         }); |  | ||||||
|         latestVersionReleases = [latestVersionReleases[0]]; |  | ||||||
|       } |       } | ||||||
|       List<String> apkUrls = latestVersionReleases |       String? appAuthorName = foundApps[0].querySelector('author')?.innerHtml; | ||||||
|  |       if (appAuthorName != null) { | ||||||
|  |         authorName = appAuthorName; | ||||||
|  |       } | ||||||
|  |       if (selectedReleases.isEmpty) { | ||||||
|  |         selectedReleases = releases.where((e) => | ||||||
|  |           e.querySelector('version')?.innerHtml == latestVersion && | ||||||
|  |           e.querySelector('apkname') != null | ||||||
|  |         ).toList(); | ||||||
|  |         if (selectedReleases.length > 1 && pickHighestVersionCode) { | ||||||
|  |           selectedReleases.sort((e1, e2) { | ||||||
|  |             return int.parse(e2.querySelector('versioncode')!.innerHtml) | ||||||
|  |               .compareTo(int.parse(e1.querySelector('versioncode')!.innerHtml)); | ||||||
|  |         }); | ||||||
|  |           selectedReleases = [selectedReleases[0]]; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       String? selectedVersion = selectedReleases[0].querySelector('version')?.innerHtml; | ||||||
|  |       if (selectedVersion == null) { | ||||||
|  |         throw NoVersionError(); | ||||||
|  |       } | ||||||
|  |       String? added = selectedReleases[0].querySelector('added')?.innerHtml; | ||||||
|  |       DateTime? releaseDate = added != null ? DateTime.parse(added) : null; | ||||||
|  |       List<String> apkUrls = selectedReleases | ||||||
|           .map( |           .map( | ||||||
|             (e) => |             (e) => | ||||||
|                 '${res.request!.url.toString().split('/').reversed.toList().sublist(1).reversed.join('/')}/${e.querySelector('apkname')!.innerHtml}', |                 '${res.request!.url.toString().split('/').reversed.toList().sublist(1).reversed.join('/')}/${e.querySelector('apkname')!.innerHtml}', | ||||||
|           ) |           ) | ||||||
|           .toList(); |           .toList(); | ||||||
|       return APKDetails( |       return APKDetails( | ||||||
|         latestVersion, |         selectedVersion, | ||||||
|         getApkUrlsFromUrls(apkUrls), |         getApkUrlsFromUrls(apkUrls), | ||||||
|         AppNames(authorName, appName), |         AppNames(authorName, appName), | ||||||
|         releaseDate: releaseDate, |         releaseDate: releaseDate, | ||||||
|  |         changeLog: changeLog, | ||||||
|       ); |       ); | ||||||
|     } else { |     } else { | ||||||
|       throw getObtainiumHttpError(res); |       throw getObtainiumHttpError(res); | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ class GitHub extends AppSource { | |||||||
|     appIdInferIsOptional = true; |     appIdInferIsOptional = true; | ||||||
|     showReleaseDateAsVersionToggle = true; |     showReleaseDateAsVersionToggle = true; | ||||||
|     this.hostChanged = hostChanged; |     this.hostChanged = hostChanged; | ||||||
|  |     allowIncludeZips = true; | ||||||
|  |  | ||||||
|     sourceConfigSettingFormItems = [ |     sourceConfigSettingFormItems = [ | ||||||
|       GeneratedFormTextField( |       GeneratedFormTextField( | ||||||
| @@ -45,6 +46,46 @@ class GitHub extends AppSource { | |||||||
|           const SizedBox(height: 4), |           const SizedBox(height: 4), | ||||||
|         ], |         ], | ||||||
|       ), |       ), | ||||||
|  |       GeneratedFormTextField( | ||||||
|  |         'GHReqPrefix', | ||||||
|  |         label: tr('GHReqPrefix'), | ||||||
|  |         hint: 'gh-proxy.com', | ||||||
|  |         required: false, | ||||||
|  |         additionalValidators: [ | ||||||
|  |           (value) { | ||||||
|  |             try { | ||||||
|  |               if (value != null && Uri.parse(value).scheme.isNotEmpty) { | ||||||
|  |                 throw true; | ||||||
|  |               } | ||||||
|  |               if (value != null) { | ||||||
|  |                 Uri.parse('https://${value}/api.github.com'); | ||||||
|  |               } | ||||||
|  |             } catch (e) { | ||||||
|  |               return tr('invalidInput'); | ||||||
|  |             } | ||||||
|  |             return null; | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |         belowWidgets: [ | ||||||
|  |           const SizedBox(height: 4), | ||||||
|  |           GestureDetector( | ||||||
|  |             onTap: () { | ||||||
|  |               launchUrlString( | ||||||
|  |                 'https://github.com/sky22333/hubproxy', | ||||||
|  |                 mode: LaunchMode.externalApplication, | ||||||
|  |               ); | ||||||
|  |             }, | ||||||
|  |             child: Text( | ||||||
|  |               tr('about'), | ||||||
|  |               style: const TextStyle( | ||||||
|  |                 decoration: TextDecoration.underline, | ||||||
|  |                 fontSize: 12, | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |           ), | ||||||
|  |           const SizedBox(height: 4), | ||||||
|  |         ], | ||||||
|  |       ), | ||||||
|     ]; |     ]; | ||||||
|  |  | ||||||
|     additionalSourceAppSpecificSettingFormItems = [ |     additionalSourceAppSpecificSettingFormItems = [ | ||||||
| @@ -249,6 +290,9 @@ class GitHub extends AppSource { | |||||||
|       settingsProvider, |       settingsProvider, | ||||||
|     ); |     ); | ||||||
|     String? creds = sourceConfig['github-creds']; |     String? creds = sourceConfig['github-creds']; | ||||||
|  |     if ((additionalSettings['GHReqPrefix'] as String? ?? '').isNotEmpty) { | ||||||
|  |       creds = null; | ||||||
|  |     } | ||||||
|     if (creds != null) { |     if (creds != null) { | ||||||
|       var userNameEndIndex = creds.indexOf(':'); |       var userNameEndIndex = creds.indexOf(':'); | ||||||
|       if (userNameEndIndex > 0) { |       if (userNameEndIndex > 0) { | ||||||
| @@ -270,6 +314,18 @@ class GitHub extends AppSource { | |||||||
|     return null; |     return null; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Future<String> generalReqPrefetchModifier( | ||||||
|  |     String reqUrl, | ||||||
|  |     Map<String, dynamic> additionalSettings, | ||||||
|  |   ) async { | ||||||
|  |     if ((additionalSettings['GHReqPrefix'] as String? ?? '').isNotEmpty) { | ||||||
|  |       var uri = Uri.parse(reqUrl); | ||||||
|  |       return 'https://${additionalSettings['GHReqPrefix']}/${uri.toString().substring('https://'.length)}'; | ||||||
|  |     } | ||||||
|  |     return reqUrl; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   Future<String> getAPIHost(Map<String, dynamic> additionalSettings) async => |   Future<String> getAPIHost(Map<String, dynamic> additionalSettings) async => | ||||||
|       'https://api.${hosts[0]}'; |       'https://api.${hosts[0]}'; | ||||||
|  |  | ||||||
| @@ -289,6 +345,12 @@ class GitHub extends AppSource { | |||||||
|     Map<String, dynamic> additionalSettings, { |     Map<String, dynamic> additionalSettings, { | ||||||
|     Function(Response)? onHttpErrorCode, |     Function(Response)? onHttpErrorCode, | ||||||
|   }) async { |   }) async { | ||||||
|  |     SettingsProvider settingsProvider = SettingsProvider(); | ||||||
|  |     await settingsProvider.initializeSettings(); | ||||||
|  |     var sourceConfigSettingValues = await getSourceConfigValues( | ||||||
|  |       additionalSettings, | ||||||
|  |       settingsProvider, | ||||||
|  |     ); | ||||||
|     bool includePrereleases = additionalSettings['includePrereleases'] == true; |     bool includePrereleases = additionalSettings['includePrereleases'] == true; | ||||||
|     bool fallbackToOlderReleases = |     bool fallbackToOlderReleases = | ||||||
|         additionalSettings['fallbackToOlderReleases'] == true; |         additionalSettings['fallbackToOlderReleases'] == true; | ||||||
| @@ -309,6 +371,7 @@ class GitHub extends AppSource { | |||||||
|         additionalSettings['useLatestAssetDateAsReleaseDate'] == true; |         additionalSettings['useLatestAssetDateAsReleaseDate'] == true; | ||||||
|     String sortMethod = |     String sortMethod = | ||||||
|         additionalSettings['sortMethodChoice'] ?? 'smartname-datefallback'; |         additionalSettings['sortMethodChoice'] ?? 'smartname-datefallback'; | ||||||
|  |     bool includeZips = additionalSettings['includeZips'] == true; | ||||||
|     dynamic latestRelease; |     dynamic latestRelease; | ||||||
|     if (verifyLatestTag) { |     if (verifyLatestTag) { | ||||||
|       var temp = requestUrl.split('?'); |       var temp = requestUrl.split('?'); | ||||||
| @@ -341,9 +404,11 @@ class GitHub extends AppSource { | |||||||
|  |  | ||||||
|       findReleaseAssetUrls(dynamic release) => |       findReleaseAssetUrls(dynamic release) => | ||||||
|           (release['assets'] as List<dynamic>?)?.map((e) { |           (release['assets'] as List<dynamic>?)?.map((e) { | ||||||
|             var url = !e['name'].toString().toLowerCase().endsWith('.apk') |             var ext = e['name'].toString().toLowerCase().split('.').last; | ||||||
|  |             var url = !(ext == 'apk' || (includeZips && ext == 'zip')) | ||||||
|                 ? (e['browser_download_url'] ?? e['url']) |                 ? (e['browser_download_url'] ?? e['url']) | ||||||
|                 : (e['url'] ?? e['browser_download_url']); |                 : (e['url'] ?? e['browser_download_url']); | ||||||
|  |             url = undoGHProxyMod(url, sourceConfigSettingValues); | ||||||
|             e['final_url'] = (e['name'] != null) && (url != null) |             e['final_url'] = (e['name'] != null) && (url != null) | ||||||
|                 ? MapEntry(e['name'] as String, url as String) |                 ? MapEntry(e['name'] as String, url as String) | ||||||
|                 : const MapEntry('', ''); |                 : const MapEntry('', ''); | ||||||
| @@ -480,14 +545,13 @@ class GitHub extends AppSource { | |||||||
|         List<MapEntry<String, String>> allAssetUrls = allAssetsWithUrls |         List<MapEntry<String, String>> allAssetUrls = allAssetsWithUrls | ||||||
|             .map((e) => e['final_url'] as MapEntry<String, String>) |             .map((e) => e['final_url'] as MapEntry<String, String>) | ||||||
|             .toList(); |             .toList(); | ||||||
|         var apkAssetsWithUrls = allAssetsWithUrls |         var apkAssetsWithUrls = allAssetsWithUrls.where((element) { | ||||||
|             .where( |           var ext = (element['final_url'] as MapEntry<String, String>).key | ||||||
|               (element) => (element['final_url'] as MapEntry<String, String>) |  | ||||||
|                   .key |  | ||||||
|               .toLowerCase() |               .toLowerCase() | ||||||
|                   .endsWith('.apk'), |               .split('.') | ||||||
|             ) |               .last; | ||||||
|             .toList(); |           return ext == 'apk' || (includeZips && ext == 'zip'); | ||||||
|  |         }).toList(); | ||||||
|  |  | ||||||
|         var filteredApkUrls = filterApks( |         var filteredApkUrls = filterApks( | ||||||
|           apkAssetsWithUrls |           apkAssetsWithUrls | ||||||
| @@ -522,7 +586,10 @@ class GitHub extends AppSource { | |||||||
|           allAssetUrls.add( |           allAssetUrls.add( | ||||||
|             MapEntry( |             MapEntry( | ||||||
|               (targetRelease['version'] ?? 'source') + '.tar.gz', |               (targetRelease['version'] ?? 'source') + '.tar.gz', | ||||||
|  |               undoGHProxyMod( | ||||||
|                 targetRelease['tarball_url'], |                 targetRelease['tarball_url'], | ||||||
|  |                 sourceConfigSettingValues, | ||||||
|  |               ), | ||||||
|             ), |             ), | ||||||
|           ); |           ); | ||||||
|         } |         } | ||||||
| @@ -530,7 +597,10 @@ class GitHub extends AppSource { | |||||||
|           allAssetUrls.add( |           allAssetUrls.add( | ||||||
|             MapEntry( |             MapEntry( | ||||||
|               (targetRelease['version'] ?? 'source') + '.zip', |               (targetRelease['version'] ?? 'source') + '.zip', | ||||||
|  |               undoGHProxyMod( | ||||||
|                 targetRelease['zipball_url'], |                 targetRelease['zipball_url'], | ||||||
|  |                 sourceConfigSettingValues, | ||||||
|  |               ), | ||||||
|             ), |             ), | ||||||
|           ); |           ); | ||||||
|         } |         } | ||||||
| @@ -652,12 +722,23 @@ class GitHub extends AppSource { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   undoGHProxyMod( | ||||||
|  |     String reqUrl, | ||||||
|  |     Map<String, String> sourceConfigSettingValues, | ||||||
|  |   ) => reqUrl.replaceFirst( | ||||||
|  |     'https://${sourceConfigSettingValues['GHReqPrefix']}/', | ||||||
|  |     '', | ||||||
|  |   ); | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Future<Map<String, List<String>>> search( |   Future<Map<String, List<String>>> search( | ||||||
|     String query, { |     String query, { | ||||||
|     Map<String, dynamic> querySettings = const {}, |     Map<String, dynamic> querySettings = const {}, | ||||||
|   }) async { |   }) async { | ||||||
|     return searchCommon( |     var sp = SettingsProvider(); | ||||||
|  |     await sp.initializeSettings(); | ||||||
|  |     var sourceConfigSettingValues = await getSourceConfigValues({}, sp); | ||||||
|  |     var results = await searchCommon( | ||||||
|       query, |       query, | ||||||
|       '${await getAPIHost({})}/search/repositories?q=${Uri.encodeQueryComponent(query)}&per_page=100', |       '${await getAPIHost({})}/search/repositories?q=${Uri.encodeQueryComponent(query)}&per_page=100', | ||||||
|       'items', |       'items', | ||||||
| @@ -666,6 +747,15 @@ class GitHub extends AppSource { | |||||||
|       }, |       }, | ||||||
|       querySettings: querySettings, |       querySettings: querySettings, | ||||||
|     ); |     ); | ||||||
|  |     if ((sourceConfigSettingValues['GHReqPrefix'] ?? '').isNotEmpty) { | ||||||
|  |       Map<String, List<String>> results2 = {}; | ||||||
|  |       results.forEach((k, v) { | ||||||
|  |         results2[undoGHProxyMod(k, sourceConfigSettingValues)] = v; | ||||||
|  |       }); | ||||||
|  |       return results2; | ||||||
|  |     } else { | ||||||
|  |       return results; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void rateLimitErrorCheck(Response res) { |   void rateLimitErrorCheck(Response res) { | ||||||
|   | |||||||
| @@ -129,14 +129,14 @@ class GitLab extends AppSource { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Future<String> apkUrlPrefetchModifier( |   Future<String> assetUrlPrefetchModifier( | ||||||
|     String apkUrl, |     String assetUrl, | ||||||
|     String standardUrl, |     String standardUrl, | ||||||
|     Map<String, dynamic> additionalSettings, |     Map<String, dynamic> additionalSettings, | ||||||
|   ) async { |   ) async { | ||||||
|     String? PAT = await getPATIfAny(hostChanged ? additionalSettings : {}); |     String? PAT = await getPATIfAny(hostChanged ? additionalSettings : {}); | ||||||
|     String optionalAuth = (PAT != null) ? 'private_token=$PAT' : ''; |     String optionalAuth = (PAT != null) ? 'private_token=$PAT' : ''; | ||||||
|     return '$apkUrl${(Uri.parse(apkUrl).query.isEmpty ? '?' : '&')}$optionalAuth'; |     return '$assetUrl${(Uri.parse(assetUrl).query.isEmpty ? '?' : '&')}$optionalAuth'; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   | |||||||
| @@ -129,6 +129,8 @@ Future<List<MapEntry<String, String>>> grabLinksCommon( | |||||||
|   Uri reqUrl, |   Uri reqUrl, | ||||||
|   Map<String, dynamic> additionalSettings, |   Map<String, dynamic> additionalSettings, | ||||||
| ) async { | ) async { | ||||||
|  |   bool matchLinksOutsideATags = | ||||||
|  |       additionalSettings['matchLinksOutsideATags'] == true; | ||||||
|   var html = parse(rawBody); |   var html = parse(rawBody); | ||||||
|   List<MapEntry<String, String>> allLinks = html |   List<MapEntry<String, String>> allLinks = html | ||||||
|       .querySelectorAll('a') |       .querySelectorAll('a') | ||||||
| @@ -143,11 +145,8 @@ Future<List<MapEntry<String, String>>> grabLinksCommon( | |||||||
|       .where((element) => element.key.isNotEmpty) |       .where((element) => element.key.isNotEmpty) | ||||||
|       .map((e) => MapEntry(ensureAbsoluteUrl(e.key, reqUrl), e.value)) |       .map((e) => MapEntry(ensureAbsoluteUrl(e.key, reqUrl), e.value)) | ||||||
|       .toList(); |       .toList(); | ||||||
|   if (allLinks.isEmpty) { |   if (allLinks.isEmpty || matchLinksOutsideATags) { | ||||||
|     allLinks = getLinksInLines(rawBody); |     // Decode the body if the response is a JSON | ||||||
|   } |  | ||||||
|   if (allLinks.isEmpty) { |  | ||||||
|     // Getting desperate |  | ||||||
|     try { |     try { | ||||||
|       var jsonStrings = collectAllStringsFromJSONObject(jsonDecode(rawBody)); |       var jsonStrings = collectAllStringsFromJSONObject(jsonDecode(rawBody)); | ||||||
|       allLinks = getLinksInLines(jsonStrings.join('\n')); |       allLinks = getLinksInLines(jsonStrings.join('\n')); | ||||||
| @@ -161,7 +160,7 @@ Future<List<MapEntry<String, String>>> grabLinksCommon( | |||||||
|         ); |         ); | ||||||
|       } |       } | ||||||
|     } catch (e) { |     } catch (e) { | ||||||
|       // |       allLinks = getLinksInLines(rawBody); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   List<MapEntry<String, String>> links = []; |   List<MapEntry<String, String>> links = []; | ||||||
| @@ -247,6 +246,12 @@ class HTML extends AppSource { | |||||||
|   ]; |   ]; | ||||||
|   var commonFormItems = [ |   var commonFormItems = [ | ||||||
|     [GeneratedFormSwitch('filterByLinkText', label: tr('filterByLinkText'))], |     [GeneratedFormSwitch('filterByLinkText', label: tr('filterByLinkText'))], | ||||||
|  |     [ | ||||||
|  |       GeneratedFormSwitch( | ||||||
|  |         'matchLinksOutsideATags', | ||||||
|  |         label: tr('matchLinksOutsideATags') | ||||||
|  |       ), | ||||||
|  |     ], | ||||||
|     [GeneratedFormSwitch('skipSort', label: tr('skipSort'))], |     [GeneratedFormSwitch('skipSort', label: tr('skipSort'))], | ||||||
|     [GeneratedFormSwitch('reverseSort', label: tr('takeFirstLink'))], |     [GeneratedFormSwitch('reverseSort', label: tr('takeFirstLink'))], | ||||||
|     [ |     [ | ||||||
|   | |||||||
							
								
								
									
										87
									
								
								lib/app_sources/liteapks.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								lib/app_sources/liteapks.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | |||||||
|  | import 'dart:convert'; | ||||||
|  |  | ||||||
|  | import 'package:http/http.dart'; | ||||||
|  | import 'package:obtainium/custom_errors.dart'; | ||||||
|  | import 'package:obtainium/providers/source_provider.dart'; | ||||||
|  |  | ||||||
|  | class LiteAPKs extends AppSource { | ||||||
|  |   LiteAPKs() { | ||||||
|  |     hosts = ['liteapks.com']; | ||||||
|  |     name = 'LiteAPKs'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   String sourceSpecificStandardizeURL(String url, {bool forSelection = false}) { | ||||||
|  |     RegExp standardUrlRegEx = RegExp( | ||||||
|  |       '^https?://(www\\.)?${getSourceRegex(hosts)}/+[^/]+', | ||||||
|  |       caseSensitive: false, | ||||||
|  |     ); | ||||||
|  |     RegExpMatch? match = standardUrlRegEx.firstMatch(url); | ||||||
|  |     if (match == null) { | ||||||
|  |       throw InvalidURLError(name); | ||||||
|  |     } | ||||||
|  |     return match.group(0)!; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Future<APKDetails> getLatestAPKDetails( | ||||||
|  |     String standardUrl, | ||||||
|  |     Map<String, dynamic> additionalSettings, | ||||||
|  |   ) async { | ||||||
|  |     var standardUri = Uri.parse(standardUrl); | ||||||
|  |     var slug = standardUri.path | ||||||
|  |         .split('.') | ||||||
|  |         .reversed | ||||||
|  |         .toList() | ||||||
|  |         .sublist(1) | ||||||
|  |         .reversed | ||||||
|  |         .join('.'); | ||||||
|  |     Response res1 = await sourceRequest( | ||||||
|  |       '${standardUri.origin}/wp-json/wp/v2/posts?slug=$slug', | ||||||
|  |       additionalSettings, | ||||||
|  |     ); | ||||||
|  |     if (res1.statusCode != 200) { | ||||||
|  |       throw getObtainiumHttpError(res1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     var liteAppId = jsonDecode(res1.body)[0]['id']; | ||||||
|  |     if (liteAppId == null) { | ||||||
|  |       throw NoReleasesError(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Response res2 = await sourceRequest( | ||||||
|  |       '${standardUri.origin}/wp-json/v2/posts/$liteAppId', | ||||||
|  |       additionalSettings, | ||||||
|  |     ); | ||||||
|  |     if (res2.statusCode != 200) { | ||||||
|  |       throw getObtainiumHttpError(res2); | ||||||
|  |     } | ||||||
|  |     var json = jsonDecode(res2.body); | ||||||
|  |  | ||||||
|  |     var appName = json['data']?['title'] as String?; | ||||||
|  |     var author = json['data']?['publisher'] as String?; | ||||||
|  |     var version = json['data']?['versions']?[0]?['version'] as String?; | ||||||
|  |     if (version == null) { | ||||||
|  |       throw NoVersionError(); | ||||||
|  |     } | ||||||
|  |     var apkUrls = | ||||||
|  |         ((json['data']?['versions']?[0]?['version_downloads'] as List<dynamic>?) | ||||||
|  |                     ?.map((l) => l['version_download_link']) ?? | ||||||
|  |                 []) | ||||||
|  |             .map( | ||||||
|  |               (l) => MapEntry<String, String>( | ||||||
|  |                 Uri.decodeComponent(Uri.parse(l).pathSegments.last), | ||||||
|  |                 l, | ||||||
|  |               ), | ||||||
|  |             ) | ||||||
|  |             .toList(); | ||||||
|  |     return APKDetails( | ||||||
|  |       version, | ||||||
|  |       apkUrls, | ||||||
|  |       AppNames( | ||||||
|  |         author ?? Uri.parse(standardUrl).host, | ||||||
|  |         appName ?? standardUrl.split('/').last, | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -80,20 +80,20 @@ class RuStore extends AppSource { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     Response res1 = await sourceRequest( |     Response res1 = await sourceRequest( | ||||||
|       'https://backapi.rustore.ru/applicationData/download-link', |       'https://backapi.rustore.ru/applicationData/v2/download-link', | ||||||
|       additionalSettings, |       additionalSettings, | ||||||
|       followRedirects: false, |       followRedirects: false, | ||||||
|       postBody: {"appId": appDetails['appId'], "firstInstall": true}, |       postBody: {"appId": appDetails['appId'], "firstInstall": true}, | ||||||
|     ); |     ); | ||||||
|     var downloadDetails = (await decodeJsonBody(res1.bodyBytes))['body']; |     var downloadDetails = (await decodeJsonBody(res1.bodyBytes))['body']; | ||||||
|     if (res1.statusCode != 200 || downloadDetails['apkUrl'] == null) { |     if (res1.statusCode != 200 || downloadDetails['downloadUrls'][0]['url'] == null) { | ||||||
|       throw NoAPKError(); |       throw NoAPKError(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return APKDetails( |     return APKDetails( | ||||||
|       version, |       version, | ||||||
|       getApkUrlsFromUrls([ |       getApkUrlsFromUrls([ | ||||||
|         (downloadDetails['apkUrl'] as String).replaceAll( |         (downloadDetails['downloadUrls'][0]['url'] as String).replaceAll( | ||||||
|           RegExp('\\.zip\$'), |           RegExp('\\.zip\$'), | ||||||
|           '.apk', |           '.apk', | ||||||
|         ), |         ), | ||||||
|   | |||||||
| @@ -124,12 +124,12 @@ class Uptodown extends AppSource { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Future<String> apkUrlPrefetchModifier( |   Future<String> assetUrlPrefetchModifier( | ||||||
|     String apkUrl, |     String assetUrl, | ||||||
|     String standardUrl, |     String standardUrl, | ||||||
|     Map<String, dynamic> additionalSettings, |     Map<String, dynamic> additionalSettings, | ||||||
|   ) async { |   ) async { | ||||||
|     var res = await sourceRequest(apkUrl, additionalSettings); |     var res = await sourceRequest(assetUrl, additionalSettings); | ||||||
|     if (res.statusCode != 200) { |     if (res.statusCode != 200) { | ||||||
|       throw getObtainiumHttpError(res); |       throw getObtainiumHttpError(res); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -70,13 +70,15 @@ class VivoAppStore extends AppSource { | |||||||
|       throw NoReleasesError(); |       throw NoReleasesError(); | ||||||
|     } |     } | ||||||
|     Map<String, List<String>> results = {}; |     Map<String, List<String>> results = {}; | ||||||
|     var resultsJson = json['data']['appSearchResponse']['value']; |     var resultsJson = json['data']['appSearchResponse']?['value']; | ||||||
|  |     if (resultsJson != null) { | ||||||
|       for (var item in (resultsJson as List<dynamic>)) { |       for (var item in (resultsJson as List<dynamic>)) { | ||||||
|         results['$appDetailUrl${item['id']}'] = [ |         results['$appDetailUrl${item['id']}'] = [ | ||||||
|           item['title_zh'].toString(), |           item['title_zh'].toString(), | ||||||
|           item['developer'].toString(), |           item['developer'].toString(), | ||||||
|         ]; |         ]; | ||||||
|       } |       } | ||||||
|  |     } | ||||||
|     return results; |     return results; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -203,11 +203,11 @@ class AddAppPageState extends State<AddAppPage> { | |||||||
|               notificationsProvider: notificationsProvider, |               notificationsProvider: notificationsProvider, | ||||||
|             ); |             ); | ||||||
|             DownloadedApk? downloadedFile; |             DownloadedApk? downloadedFile; | ||||||
|             DownloadedXApkDir? downloadedDir; |             DownloadedDir? downloadedDir; | ||||||
|             if (downloadedArtifact is DownloadedApk) { |             if (downloadedArtifact is DownloadedApk) { | ||||||
|               downloadedFile = downloadedArtifact; |               downloadedFile = downloadedArtifact; | ||||||
|             } else { |             } else { | ||||||
|               downloadedDir = downloadedArtifact as DownloadedXApkDir; |               downloadedDir = downloadedArtifact as DownloadedDir; | ||||||
|             } |             } | ||||||
|             app.id = downloadedFile?.appId ?? downloadedDir!.appId; |             app.id = downloadedFile?.appId ?? downloadedDir!.appId; | ||||||
|           } |           } | ||||||
|   | |||||||
| @@ -16,9 +16,14 @@ import 'package:provider/provider.dart'; | |||||||
| import 'package:markdown/markdown.dart' as md; | import 'package:markdown/markdown.dart' as md; | ||||||
|  |  | ||||||
| class AppPage extends StatefulWidget { | class AppPage extends StatefulWidget { | ||||||
|   const AppPage({super.key, required this.appId}); |   const AppPage({ | ||||||
|  |     super.key, | ||||||
|  |     required this.appId, | ||||||
|  |     this.showOppositeOfPreferredView = false, | ||||||
|  |   }); | ||||||
|  |  | ||||||
|   final String appId; |   final String appId; | ||||||
|  |   final bool showOppositeOfPreferredView; | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   State<AppPage> createState() => _AppPageState(); |   State<AppPage> createState() => _AppPageState(); | ||||||
| @@ -60,6 +65,11 @@ class _AppPageState extends State<AppPage> { | |||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     var appsProvider = context.watch<AppsProvider>(); |     var appsProvider = context.watch<AppsProvider>(); | ||||||
|     var settingsProvider = context.watch<SettingsProvider>(); |     var settingsProvider = context.watch<SettingsProvider>(); | ||||||
|  |     var showAppWebpageFinal = | ||||||
|  |         (settingsProvider.showAppWebpage && | ||||||
|  |             !widget.showOppositeOfPreferredView) || | ||||||
|  |         (!settingsProvider.showAppWebpage && | ||||||
|  |             widget.showOppositeOfPreferredView); | ||||||
|     getUpdate(String id, {bool resetVersion = false}) async { |     getUpdate(String id, {bool resetVersion = false}) async { | ||||||
|       try { |       try { | ||||||
|         setState(() { |         setState(() { | ||||||
| @@ -565,7 +575,7 @@ class _AppPageState extends State<AppPage> { | |||||||
|                     icon: const Icon(Icons.settings), |                     icon: const Icon(Icons.settings), | ||||||
|                     tooltip: tr('settings'), |                     tooltip: tr('settings'), | ||||||
|                   ), |                   ), | ||||||
|                 if (app != null && settingsProvider.showAppWebpage) |                 if (app != null && showAppWebpageFinal) | ||||||
|                   IconButton( |                   IconButton( | ||||||
|                     onPressed: () { |                     onPressed: () { | ||||||
|                       showDialog( |                       showDialog( | ||||||
| @@ -661,10 +671,10 @@ class _AppPageState extends State<AppPage> { | |||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     return Scaffold( |     return Scaffold( | ||||||
|       appBar: settingsProvider.showAppWebpage ? AppBar() : appScreenAppBar(), |       appBar: showAppWebpageFinal ? AppBar() : appScreenAppBar(), | ||||||
|       backgroundColor: Theme.of(context).colorScheme.surface, |       backgroundColor: Theme.of(context).colorScheme.surface, | ||||||
|       body: RefreshIndicator( |       body: RefreshIndicator( | ||||||
|         child: settingsProvider.showAppWebpage |         child: showAppWebpageFinal | ||||||
|             ? getAppWebView() |             ? getAppWebView() | ||||||
|             : CustomScrollView( |             : CustomScrollView( | ||||||
|                 slivers: [ |                 slivers: [ | ||||||
|   | |||||||
| @@ -451,7 +451,8 @@ class AppsPageState extends State<AppsPage> { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     getAppIcon(int appIndex) { |     getAppIcon(int appIndex) { | ||||||
|       return FutureBuilder( |       return GestureDetector( | ||||||
|  |         child: FutureBuilder( | ||||||
|           future: appsProvider.updateAppIcon(listedApps[appIndex].app.id), |           future: appsProvider.updateAppIcon(listedApps[appIndex].app.id), | ||||||
|           builder: (ctx, val) { |           builder: (ctx, val) { | ||||||
|             return listedApps[appIndex].icon != null |             return listedApps[appIndex].icon != null | ||||||
| @@ -475,7 +476,8 @@ class AppsPageState extends State<AppsPage> { | |||||||
|                             image: const AssetImage( |                             image: const AssetImage( | ||||||
|                               'assets/graphics/icon_small.png', |                               'assets/graphics/icon_small.png', | ||||||
|                             ), |                             ), | ||||||
|                           color: Theme.of(context).brightness == Brightness.dark |                             color: | ||||||
|  |                                 Theme.of(context).brightness == Brightness.dark | ||||||
|                                 ? Colors.white.withOpacity(0.4) |                                 ? Colors.white.withOpacity(0.4) | ||||||
|                                 : Colors.white.withOpacity(0.3), |                                 : Colors.white.withOpacity(0.3), | ||||||
|                             colorBlendMode: BlendMode.modulate, |                             colorBlendMode: BlendMode.modulate, | ||||||
| @@ -486,6 +488,21 @@ class AppsPageState extends State<AppsPage> { | |||||||
|                     ], |                     ], | ||||||
|                   ); |                   ); | ||||||
|           }, |           }, | ||||||
|  |         ), | ||||||
|  |         onDoubleTap: () { | ||||||
|  |           pm.openApp(listedApps[appIndex].app.id); | ||||||
|  |         }, | ||||||
|  |         onLongPress: () { | ||||||
|  |           Navigator.push( | ||||||
|  |             context, | ||||||
|  |             MaterialPageRoute( | ||||||
|  |               builder: (context) => AppPage( | ||||||
|  |                 appId: listedApps[appIndex].app.id, | ||||||
|  |                 showOppositeOfPreferredView: true, | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |           ); | ||||||
|  |         }, | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -993,6 +1010,7 @@ class AppsPageState extends State<AppsPage> { | |||||||
|                       selectedApps.where((element) => element.pinned).isEmpty |                       selectedApps.where((element) => element.pinned).isEmpty | ||||||
|                           ? tr('pinToTop') |                           ? tr('pinToTop') | ||||||
|                           : tr('unpinFromTop'), |                           : tr('unpinFromTop'), | ||||||
|  |                       textAlign: TextAlign.center, | ||||||
|                     ), |                     ), | ||||||
|                   ), |                   ), | ||||||
|                   const Divider(), |                   const Divider(), | ||||||
| @@ -1009,7 +1027,10 @@ class AppsPageState extends State<AppsPage> { | |||||||
|                       ); |                       ); | ||||||
|                       Navigator.of(context).pop(); |                       Navigator.of(context).pop(); | ||||||
|                     }, |                     }, | ||||||
|                     child: Text(tr('shareSelectedAppURLs')), |                     child: Text( | ||||||
|  |                       tr('shareSelectedAppURLs'), | ||||||
|  |                       textAlign: TextAlign.center, | ||||||
|  |                     ), | ||||||
|                   ), |                   ), | ||||||
|                   const Divider(), |                   const Divider(), | ||||||
|                   TextButton( |                   TextButton( | ||||||
| @@ -1026,7 +1047,10 @@ class AppsPageState extends State<AppsPage> { | |||||||
|                               subject: 'Obtainium - ${tr('appsString')}', |                               subject: 'Obtainium - ${tr('appsString')}', | ||||||
|                             ); |                             ); | ||||||
|                           }, |                           }, | ||||||
|                     child: Text(tr('shareAppConfigLinks')), |                     child: Text( | ||||||
|  |                       tr('shareAppConfigLinks'), | ||||||
|  |                       textAlign: TextAlign.center, | ||||||
|  |                     ), | ||||||
|                   ), |                   ), | ||||||
|                   const Divider(), |                   const Divider(), | ||||||
|                   TextButton( |                   TextButton( | ||||||
| @@ -1052,7 +1076,10 @@ class AppsPageState extends State<AppsPage> { | |||||||
|                               fileNameOverrides: ['$fn.json'], |                               fileNameOverrides: ['$fn.json'], | ||||||
|                             ); |                             ); | ||||||
|                           }, |                           }, | ||||||
|                     child: Text('${tr('share')} - ${tr('obtainiumExport')}'), |                     child: Text( | ||||||
|  |                       '${tr('share')} - ${tr('obtainiumExport')}', | ||||||
|  |                       textAlign: TextAlign.center, | ||||||
|  |                     ), | ||||||
|                   ), |                   ), | ||||||
|                   const Divider(), |                   const Divider(), | ||||||
|                   TextButton( |                   TextButton( | ||||||
| @@ -1076,6 +1103,7 @@ class AppsPageState extends State<AppsPage> { | |||||||
|                         'downloadX', |                         'downloadX', | ||||||
|                         args: [lowerCaseIfEnglish(tr('releaseAsset'))], |                         args: [lowerCaseIfEnglish(tr('releaseAsset'))], | ||||||
|                       ), |                       ), | ||||||
|  |                       textAlign: TextAlign.center, | ||||||
|                     ), |                     ), | ||||||
|                   ), |                   ), | ||||||
|                   const Divider(), |                   const Divider(), | ||||||
| @@ -1083,7 +1111,10 @@ class AppsPageState extends State<AppsPage> { | |||||||
|                     onPressed: appsProvider.areDownloadsRunning() |                     onPressed: appsProvider.areDownloadsRunning() | ||||||
|                         ? null |                         ? null | ||||||
|                         : showMassMarkDialog, |                         : showMassMarkDialog, | ||||||
|                     child: Text(tr('markSelectedAppsUpdated')), |                     child: Text( | ||||||
|  |                       tr('markSelectedAppsUpdated'), | ||||||
|  |                       textAlign: TextAlign.center, | ||||||
|  |                     ), | ||||||
|                   ), |                   ), | ||||||
|                 ], |                 ], | ||||||
|               ), |               ), | ||||||
|   | |||||||
| @@ -319,13 +319,24 @@ class _SettingsPageState extends State<SettingsPage> { | |||||||
|       if (e.sourceConfigSettingFormItems.isNotEmpty) { |       if (e.sourceConfigSettingFormItems.isNotEmpty) { | ||||||
|         return GeneratedForm( |         return GeneratedForm( | ||||||
|           items: e.sourceConfigSettingFormItems.map((e) { |           items: e.sourceConfigSettingFormItems.map((e) { | ||||||
|  |             if (e is GeneratedFormSwitch) { | ||||||
|  |               e.defaultValue = settingsProvider.getSettingBool(e.key); | ||||||
|  |             } else { | ||||||
|               e.defaultValue = settingsProvider.getSettingString(e.key); |               e.defaultValue = settingsProvider.getSettingString(e.key); | ||||||
|  |             } | ||||||
|             return [e]; |             return [e]; | ||||||
|           }).toList(), |           }).toList(), | ||||||
|           onValueChanges: (values, valid, isBuilding) { |           onValueChanges: (values, valid, isBuilding) { | ||||||
|             if (valid && !isBuilding) { |             if (valid && !isBuilding) { | ||||||
|               values.forEach((key, value) { |               values.forEach((key, value) { | ||||||
|                 settingsProvider.setSettingString(key, value); |                 var formItem = e.sourceConfigSettingFormItems | ||||||
|  |                     .where((i) => i.key == key) | ||||||
|  |                     .firstOrNull; | ||||||
|  |                 if (formItem is GeneratedFormSwitch) { | ||||||
|  |                   settingsProvider.setSettingBool(key, value == true); | ||||||
|  |                 } else { | ||||||
|  |                   settingsProvider.setSettingString(key, value ?? ''); | ||||||
|  |                 } | ||||||
|               }); |               }); | ||||||
|             } |             } | ||||||
|           }, |           }, | ||||||
|   | |||||||
| @@ -62,11 +62,14 @@ class DownloadedApk { | |||||||
|   DownloadedApk(this.appId, this.file); |   DownloadedApk(this.appId, this.file); | ||||||
| } | } | ||||||
|  |  | ||||||
| class DownloadedXApkDir { | enum DownloadedDirType { XAPK, ZIP } | ||||||
|  |  | ||||||
|  | class DownloadedDir { | ||||||
|   String appId; |   String appId; | ||||||
|   File file; |   File file; | ||||||
|   Directory extracted; |   Directory extracted; | ||||||
|   DownloadedXApkDir(this.appId, this.file, this.extracted); |   DownloadedDirType type; | ||||||
|  |   DownloadedDir(this.appId, this.file, this.extracted, this.type); | ||||||
| } | } | ||||||
|  |  | ||||||
| List<String> generateStandardVersionRegExStrings() { | List<String> generateStandardVersionRegExStrings() { | ||||||
| @@ -606,10 +609,20 @@ class AppsProvider with ChangeNotifier { | |||||||
|         app.url, |         app.url, | ||||||
|         overrideSource: app.overrideSource, |         overrideSource: app.overrideSource, | ||||||
|       ); |       ); | ||||||
|       String downloadUrl = await source.apkUrlPrefetchModifier( |       var additionalSettingsPlusSourceConfig = { | ||||||
|         app.apkUrls[app.preferredApkIndex].value, |         ...app.additionalSettings, | ||||||
|         app.url, |         ...(await source.getSourceConfigValues( | ||||||
|           app.additionalSettings, |           app.additionalSettings, | ||||||
|  |           settingsProvider, | ||||||
|  |         )), | ||||||
|  |       }; | ||||||
|  |       String downloadUrl = await source.assetUrlPrefetchModifier( | ||||||
|  |         await source.generalReqPrefetchModifier( | ||||||
|  |           app.apkUrls[app.preferredApkIndex].value, | ||||||
|  |           additionalSettingsPlusSourceConfig, | ||||||
|  |         ), | ||||||
|  |         app.url, | ||||||
|  |         additionalSettingsPlusSourceConfig, | ||||||
|       ); |       ); | ||||||
|       var notif = DownloadNotification(app.finalName, 100); |       var notif = DownloadNotification(app.finalName, 100); | ||||||
|       notificationsProvider?.cancel(notif.id); |       notificationsProvider?.cancel(notif.id); | ||||||
| @@ -654,17 +667,18 @@ class AppsProvider with ChangeNotifier { | |||||||
|       } |       } | ||||||
|       PackageInfo? newInfo; |       PackageInfo? newInfo; | ||||||
|       var isAPK = downloadedFile.path.toLowerCase().endsWith('.apk'); |       var isAPK = downloadedFile.path.toLowerCase().endsWith('.apk'); | ||||||
|       Directory? xapkDir; |       var isXAPK = downloadedFile.path.toLowerCase().endsWith('.xapk'); | ||||||
|  |       Directory? apkDir; | ||||||
|       if (isAPK) { |       if (isAPK) { | ||||||
|         newInfo = await pm.getPackageArchiveInfo( |         newInfo = await pm.getPackageArchiveInfo( | ||||||
|           archiveFilePath: downloadedFile.path, |           archiveFilePath: downloadedFile.path, | ||||||
|         ); |         ); | ||||||
|       } else { |       } else { | ||||||
|         // Assume XAPK |         // Assume XAPK or ZIP | ||||||
|         String xapkDirPath = '${downloadedFile.path}-dir'; |         String apkDirPath = '${downloadedFile.path}-dir'; | ||||||
|         await unzipFile(downloadedFile.path, '${downloadedFile.path}-dir'); |         await unzipFile(downloadedFile.path, '${downloadedFile.path}-dir'); | ||||||
|         xapkDir = Directory(xapkDirPath); |         apkDir = Directory(apkDirPath); | ||||||
|         var apks = xapkDir |         var apks = apkDir | ||||||
|             .listSync() |             .listSync() | ||||||
|             .where((e) => e.path.toLowerCase().endsWith('.apk')) |             .where((e) => e.path.toLowerCase().endsWith('.apk')) | ||||||
|             .toList(); |             .toList(); | ||||||
| @@ -681,6 +695,22 @@ class AppsProvider with ChangeNotifier { | |||||||
|           apks = [temp!, ...apks]; |           apks = [temp!, ...apks]; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if (app.additionalSettings['zippedApkFilterRegEx']?.isNotEmpty == | ||||||
|  |             true) { | ||||||
|  |           var reg = RegExp(app.additionalSettings['zippedApkFilterRegEx']); | ||||||
|  |           apks.removeWhere((apk) { | ||||||
|  |             var shouldDelete = !reg.hasMatch(apk.uri.pathSegments.last); | ||||||
|  |             if (shouldDelete) { | ||||||
|  |               apk.delete(); | ||||||
|  |             } | ||||||
|  |             return shouldDelete; | ||||||
|  |           }); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (apks.isEmpty) { | ||||||
|  |           throw NoAPKError(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         for (var i = 0; i < apks.length; i++) { |         for (var i = 0; i < apks.length; i++) { | ||||||
|           try { |           try { | ||||||
|             newInfo = await pm.getPackageArchiveInfo( |             newInfo = await pm.getPackageArchiveInfo( | ||||||
| @@ -718,7 +748,12 @@ class AppsProvider with ChangeNotifier { | |||||||
|       if (isAPK) { |       if (isAPK) { | ||||||
|         return DownloadedApk(app.id, downloadedFile); |         return DownloadedApk(app.id, downloadedFile); | ||||||
|       } else { |       } else { | ||||||
|         return DownloadedXApkDir(app.id, downloadedFile, xapkDir!); |         return DownloadedDir( | ||||||
|  |           app.id, | ||||||
|  |           downloadedFile, | ||||||
|  |           apkDir!, | ||||||
|  |           isXAPK ? DownloadedDirType.XAPK : DownloadedDirType.ZIP, | ||||||
|  |         ); | ||||||
|       } |       } | ||||||
|     } finally { |     } finally { | ||||||
|       notificationsProvider?.cancel(notifId); |       notificationsProvider?.cancel(notifId); | ||||||
| @@ -764,10 +799,13 @@ class AppsProvider with ChangeNotifier { | |||||||
|     int? targetSDK = (await getInstalledInfo( |     int? targetSDK = (await getInstalledInfo( | ||||||
|       app.id, |       app.id, | ||||||
|     ))?.applicationInfo?.targetSdkVersion; |     ))?.applicationInfo?.targetSdkVersion; | ||||||
|  |     int requiredSDK = osInfo.version.sdkInt - 3; | ||||||
|     // The APK should target a new enough API |     // The APK should target a new enough API | ||||||
|     // https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionParams#setRequireUserAction(int) |     // https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionParams#setRequireUserAction(int) | ||||||
|     if (!(targetSDK != null && targetSDK >= (osInfo.version.sdkInt - 3))) { |     if (!(targetSDK != null && targetSDK >= requiredSDK)) { | ||||||
|       logs.add('Multiple APK URLs: ${app.id}'); |       logs.add( | ||||||
|  |         'App currently targets API ${targetSDK} which is too low for background updates (requires API ${requiredSDK}): ${app.id}', | ||||||
|  |       ); | ||||||
|       return false; |       return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -813,15 +851,16 @@ class AppsProvider with ChangeNotifier { | |||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Future<bool> installXApkDir( |   Future<bool> installApkDir( | ||||||
|     DownloadedXApkDir dir, |     DownloadedDir dir, | ||||||
|     BuildContext? firstTimeWithContext, { |     BuildContext? firstTimeWithContext, { | ||||||
|     bool needsBGWorkaround = false, |     bool needsBGWorkaround = false, | ||||||
|     bool shizukuPretendToBeGooglePlay = false, |     bool shizukuPretendToBeGooglePlay = false, | ||||||
|   }) async { |   }) async { | ||||||
|     // We don't know which APKs in an XAPK are supported by the user's device |     // We don't know which APKs in an XAPK or ZIP are supported by the user's device | ||||||
|     // So we try installing all of them and assume success if at least one installed |     // So we try installing all of them and assume success if at least one installed | ||||||
|     // If 0 APKs installed, throw the first install error encountered |     // If 0 APKs installed, throw the first install error encountered | ||||||
|  |     // Obviously this approach is naive and is undesirable in many cases, needs to be improved | ||||||
|     var somethingInstalled = false; |     var somethingInstalled = false; | ||||||
|     try { |     try { | ||||||
|       MultiAppMultiError errors = MultiAppMultiError(); |       MultiAppMultiError errors = MultiAppMultiError(); | ||||||
| @@ -850,7 +889,7 @@ class AppsProvider with ChangeNotifier { | |||||||
|       } |       } | ||||||
|  |  | ||||||
|       try { |       try { | ||||||
|         await installApk( |         var wasInstalled = await installApk( | ||||||
|           DownloadedApk(dir.appId, APKFiles[0]), |           DownloadedApk(dir.appId, APKFiles[0]), | ||||||
|           firstTimeWithContext, |           firstTimeWithContext, | ||||||
|           needsBGWorkaround: needsBGWorkaround, |           needsBGWorkaround: needsBGWorkaround, | ||||||
| @@ -859,10 +898,10 @@ class AppsProvider with ChangeNotifier { | |||||||
|             1, |             1, | ||||||
|           ).map((a) => DownloadedApk(dir.appId, a)).toList(), |           ).map((a) => DownloadedApk(dir.appId, a)).toList(), | ||||||
|         ); |         ); | ||||||
|         somethingInstalled = true; |         somethingInstalled = somethingInstalled || wasInstalled; | ||||||
|         dir.file.delete(recursive: true); |         dir.file.delete(recursive: true); | ||||||
|       } catch (e) { |       } catch (e) { | ||||||
|         logs.add('Could not install APKs from XAPK: ${e.toString()}'); |         logs.add('Could not install APKs from ${dir.type}: ${e.toString()}'); | ||||||
|         errors.add(dir.appId, e, appName: apps[dir.appId]?.name); |         errors.add(dir.appId, e, appName: apps[dir.appId]?.name); | ||||||
|       } |       } | ||||||
|       if (errors.idsByErrorString.isNotEmpty) { |       if (errors.idsByErrorString.isNotEmpty) { | ||||||
| @@ -1135,7 +1174,7 @@ class AppsProvider with ChangeNotifier { | |||||||
|       String id, |       String id, | ||||||
|       bool willBeSilent, |       bool willBeSilent, | ||||||
|       DownloadedApk? downloadedFile, |       DownloadedApk? downloadedFile, | ||||||
|       DownloadedXApkDir? downloadedDir, |       DownloadedDir? downloadedDir, | ||||||
|     ) async { |     ) async { | ||||||
|       apps[id]?.downloadProgress = -1; |       apps[id]?.downloadProgress = -1; | ||||||
|       notifyListeners(); |       notifyListeners(); | ||||||
| @@ -1170,14 +1209,14 @@ class AppsProvider with ChangeNotifier { | |||||||
|         } else { |         } else { | ||||||
|           if (needBGWorkaround) { |           if (needBGWorkaround) { | ||||||
|             // ignore: use_build_context_synchronously |             // ignore: use_build_context_synchronously | ||||||
|             installXApkDir( |             installApkDir( | ||||||
|               downloadedDir!, |               downloadedDir!, | ||||||
|               contextIfNewInstall, |               contextIfNewInstall, | ||||||
|               needsBGWorkaround: true, |               needsBGWorkaround: true, | ||||||
|             ); |             ); | ||||||
|           } else { |           } else { | ||||||
|             // ignore: use_build_context_synchronously |             // ignore: use_build_context_synchronously | ||||||
|             sayInstalled = await installXApkDir( |             sayInstalled = await installApkDir( | ||||||
|               downloadedDir!, |               downloadedDir!, | ||||||
|               contextIfNewInstall, |               contextIfNewInstall, | ||||||
|               shizukuPretendToBeGooglePlay: shizukuPretendToBeGooglePlay, |               shizukuPretendToBeGooglePlay: shizukuPretendToBeGooglePlay, | ||||||
| @@ -1214,7 +1253,7 @@ class AppsProvider with ChangeNotifier { | |||||||
|     }) async { |     }) async { | ||||||
|       bool willBeSilent = false; |       bool willBeSilent = false; | ||||||
|       DownloadedApk? downloadedFile; |       DownloadedApk? downloadedFile; | ||||||
|       DownloadedXApkDir? downloadedDir; |       DownloadedDir? downloadedDir; | ||||||
|       try { |       try { | ||||||
|         var downloadedArtifact = |         var downloadedArtifact = | ||||||
|             // ignore: use_build_context_synchronously |             // ignore: use_build_context_synchronously | ||||||
| @@ -1227,7 +1266,7 @@ class AppsProvider with ChangeNotifier { | |||||||
|         if (downloadedArtifact is DownloadedApk) { |         if (downloadedArtifact is DownloadedApk) { | ||||||
|           downloadedFile = downloadedArtifact; |           downloadedFile = downloadedArtifact; | ||||||
|         } else { |         } else { | ||||||
|           downloadedDir = downloadedArtifact as DownloadedXApkDir; |           downloadedDir = downloadedArtifact as DownloadedDir; | ||||||
|         } |         } | ||||||
|         id = downloadedFile?.appId ?? downloadedDir!.appId; |         id = downloadedFile?.appId ?? downloadedDir!.appId; | ||||||
|         willBeSilent = await canInstallSilently(apps[id]!.app); |         willBeSilent = await canInstallSilently(apps[id]!.app); | ||||||
| @@ -1279,7 +1318,7 @@ class AppsProvider with ChangeNotifier { | |||||||
|             res['id'] as String, |             res['id'] as String, | ||||||
|             res['willBeSilent'] as bool, |             res['willBeSilent'] as bool, | ||||||
|             res['downloadedFile'] as DownloadedApk?, |             res['downloadedFile'] as DownloadedApk?, | ||||||
|             res['downloadedDir'] as DownloadedXApkDir?, |             res['downloadedDir'] as DownloadedDir?, | ||||||
|           ); |           ); | ||||||
|         } catch (e) { |         } catch (e) { | ||||||
|           var id = res['id'] as String; |           var id = res['id'] as String; | ||||||
| @@ -1310,6 +1349,7 @@ class AppsProvider with ChangeNotifier { | |||||||
|       MapEntry<String, String>? fileUrl; |       MapEntry<String, String>? fileUrl; | ||||||
|       var refreshBeforeDownload = |       var refreshBeforeDownload = | ||||||
|           apps[id]!.app.additionalSettings['refreshBeforeDownload'] == true || |           apps[id]!.app.additionalSettings['refreshBeforeDownload'] == true || | ||||||
|  |           apps[id]!.app.apkUrls.isNotEmpty && | ||||||
|               apps[id]!.app.apkUrls.first.value == 'placeholder'; |               apps[id]!.app.apkUrls.first.value == 'placeholder'; | ||||||
|       if (refreshBeforeDownload) { |       if (refreshBeforeDownload) { | ||||||
|         await checkUpdate(apps[id]!.app.id); |         await checkUpdate(apps[id]!.app.id); | ||||||
| @@ -1324,15 +1364,26 @@ class AppsProvider with ChangeNotifier { | |||||||
|           evenIfSingleChoice: true, |           evenIfSingleChoice: true, | ||||||
|         ); |         ); | ||||||
|         if (tempFileUrl != null) { |         if (tempFileUrl != null) { | ||||||
|           fileUrl = MapEntry( |           var s = SourceProvider().getSource( | ||||||
|             tempFileUrl.key, |  | ||||||
|             await (SourceProvider().getSource( |  | ||||||
|             apps[id]!.app.url, |             apps[id]!.app.url, | ||||||
|             overrideSource: apps[id]!.app.overrideSource, |             overrideSource: apps[id]!.app.overrideSource, | ||||||
|             )).apkUrlPrefetchModifier( |           ); | ||||||
|               tempFileUrl.value, |           var additionalSettingsPlusSourceConfig = { | ||||||
|               apps[id]!.app.url, |             ...apps[id]!.app.additionalSettings, | ||||||
|  |             ...(await s.getSourceConfigValues( | ||||||
|               apps[id]!.app.additionalSettings, |               apps[id]!.app.additionalSettings, | ||||||
|  |               settingsProvider, | ||||||
|  |             )), | ||||||
|  |           }; | ||||||
|  |           fileUrl = MapEntry( | ||||||
|  |             tempFileUrl.key, | ||||||
|  |             await s.assetUrlPrefetchModifier( | ||||||
|  |               await s.generalReqPrefetchModifier( | ||||||
|  |                 tempFileUrl.value, | ||||||
|  |                 additionalSettingsPlusSourceConfig, | ||||||
|  |               ), | ||||||
|  |               apps[id]!.app.url, | ||||||
|  |               additionalSettingsPlusSourceConfig, | ||||||
|             ), |             ), | ||||||
|           ); |           ); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -249,6 +249,15 @@ class SettingsProvider with ChangeNotifier { | |||||||
|     notifyListeners(); |     notifyListeners(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   bool? getSettingBool(String settingId) { | ||||||
|  |     return prefs?.getBool(settingId) ?? false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void setSettingBool(String settingId, bool value) { | ||||||
|  |     prefs?.setBool(settingId, value); | ||||||
|  |     notifyListeners(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   Map<String, int> get categories => |   Map<String, int> get categories => | ||||||
|       Map<String, int>.from(jsonDecode(prefs?.getString('categories') ?? '{}')); |       Map<String, int>.from(jsonDecode(prefs?.getString('categories') ?? '{}')); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ import 'package:obtainium/app_sources/huaweiappgallery.dart'; | |||||||
| import 'package:obtainium/app_sources/izzyondroid.dart'; | import 'package:obtainium/app_sources/izzyondroid.dart'; | ||||||
| import 'package:obtainium/app_sources/html.dart'; | import 'package:obtainium/app_sources/html.dart'; | ||||||
| import 'package:obtainium/app_sources/jenkins.dart'; | import 'package:obtainium/app_sources/jenkins.dart'; | ||||||
|  | import 'package:obtainium/app_sources/liteapks.dart'; | ||||||
| import 'package:obtainium/app_sources/neutroncode.dart'; | import 'package:obtainium/app_sources/neutroncode.dart'; | ||||||
| import 'package:obtainium/app_sources/rustore.dart'; | import 'package:obtainium/app_sources/rustore.dart'; | ||||||
| import 'package:obtainium/app_sources/sourceforge.dart'; | import 'package:obtainium/app_sources/sourceforge.dart'; | ||||||
| @@ -635,6 +636,7 @@ abstract class AppSource { | |||||||
|   bool versionDetectionDisallowed = false; |   bool versionDetectionDisallowed = false; | ||||||
|   List<String> excludeCommonSettingKeys = []; |   List<String> excludeCommonSettingKeys = []; | ||||||
|   bool urlsAlwaysHaveExtension = false; |   bool urlsAlwaysHaveExtension = false; | ||||||
|  |   bool allowIncludeZips = false; | ||||||
|  |  | ||||||
|   AppSource() { |   AppSource() { | ||||||
|     name = runtimeType.toString(); |     name = runtimeType.toString(); | ||||||
| @@ -685,14 +687,27 @@ abstract class AppSource { | |||||||
|     bool followRedirects = true, |     bool followRedirects = true, | ||||||
|     Object? postBody, |     Object? postBody, | ||||||
|   }) async { |   }) async { | ||||||
|  |     var sp = SettingsProvider(); | ||||||
|  |     await sp.initializeSettings(); | ||||||
|  |     getSourceConfigValues(additionalSettings, sp); | ||||||
|  |     var additionalSettingsPlusSourceConfig = { | ||||||
|  |       ...additionalSettings, | ||||||
|  |       ...(await getSourceConfigValues(additionalSettings, sp)), | ||||||
|  |     }; | ||||||
|  |     url = await generalReqPrefetchModifier( | ||||||
|  |       url, | ||||||
|  |       additionalSettingsPlusSourceConfig, | ||||||
|  |     ); | ||||||
|     var method = postBody == null ? 'GET' : 'POST'; |     var method = postBody == null ? 'GET' : 'POST'; | ||||||
|     var requestHeaders = await getRequestHeaders(additionalSettings); |     var requestHeaders = await getRequestHeaders( | ||||||
|  |       additionalSettingsPlusSourceConfig, | ||||||
|  |     ); | ||||||
|     var streamedResponseUrlWithResponseAndClient = |     var streamedResponseUrlWithResponseAndClient = | ||||||
|         await sourceRequestStreamResponse( |         await sourceRequestStreamResponse( | ||||||
|           method, |           method, | ||||||
|           url, |           url, | ||||||
|           requestHeaders, |           requestHeaders, | ||||||
|           additionalSettings, |           additionalSettingsPlusSourceConfig, | ||||||
|           followRedirects: followRedirects, |           followRedirects: followRedirects, | ||||||
|           postBody: postBody, |           postBody: postBody, | ||||||
|         ); |         ); | ||||||
| @@ -820,7 +835,7 @@ abstract class AppSource { | |||||||
|     ], |     ], | ||||||
|   ]; |   ]; | ||||||
|  |  | ||||||
|   // Previous 2 variables combined into one at runtime for convenient usage |   // Previous 2 variables combined into one at runtime for convenient usage + additional processing | ||||||
|   List<List<GeneratedFormItem>> get combinedAppSpecificSettingFormItems { |   List<List<GeneratedFormItem>> get combinedAppSpecificSettingFormItems { | ||||||
|     if (showReleaseDateAsVersionToggle == true) { |     if (showReleaseDateAsVersionToggle == true) { | ||||||
|       if (additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly |       if (additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly | ||||||
| @@ -864,6 +879,32 @@ abstract class AppSource { | |||||||
|             ) |             ) | ||||||
|             .where((e) => e.isNotEmpty) |             .where((e) => e.isNotEmpty) | ||||||
|             .toList(); |             .toList(); | ||||||
|  |  | ||||||
|  |     var moreConditionalItems = []; | ||||||
|  |     if (allowIncludeZips) { | ||||||
|  |       moreConditionalItems.addAll([ | ||||||
|  |         [ | ||||||
|  |           GeneratedFormSwitch( | ||||||
|  |             'includeZips', | ||||||
|  |             label: tr('includeZips'), | ||||||
|  |             defaultValue: false, | ||||||
|  |           ), | ||||||
|  |         ], | ||||||
|  |         [ | ||||||
|  |           GeneratedFormTextField( | ||||||
|  |             'zippedApkFilterRegEx', | ||||||
|  |             label: tr('zippedApkFilterRegEx'), | ||||||
|  |             required: false, | ||||||
|  |             additionalValidators: [ | ||||||
|  |               (value) { | ||||||
|  |                 return regExValidator(value); | ||||||
|  |               }, | ||||||
|  |             ], | ||||||
|  |           ), | ||||||
|  |         ], | ||||||
|  |       ]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (versionDetectionDisallowed) { |     if (versionDetectionDisallowed) { | ||||||
|       overrideAdditionalAppSpecificSourceAgnosticSettingSwitch( |       overrideAdditionalAppSpecificSourceAgnosticSettingSwitch( | ||||||
|         'versionDetection', |         'versionDetection', | ||||||
| @@ -879,6 +920,7 @@ abstract class AppSource { | |||||||
|     return [ |     return [ | ||||||
|       ...additionalSourceAppSpecificSettingFormItems, |       ...additionalSourceAppSpecificSettingFormItems, | ||||||
|       ...additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly, |       ...additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly, | ||||||
|  |       ...moreConditionalItems, | ||||||
|     ]; |     ]; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -910,12 +952,19 @@ abstract class AppSource { | |||||||
|     return null; |     return null; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Future<String> apkUrlPrefetchModifier( |   Future<String> assetUrlPrefetchModifier( | ||||||
|     String apkUrl, |     String assetUrl, | ||||||
|     String standardUrl, |     String standardUrl, | ||||||
|     Map<String, dynamic> additionalSettings, |     Map<String, dynamic> additionalSettings, | ||||||
|   ) async { |   ) async { | ||||||
|     return apkUrl; |     return assetUrl; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Future<String> generalReqPrefetchModifier( | ||||||
|  |     String reqUrl, | ||||||
|  |     Map<String, dynamic> additionalSettings, | ||||||
|  |   ) async { | ||||||
|  |     return reqUrl; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   bool canSearch = false; |   bool canSearch = false; | ||||||
| @@ -1076,6 +1125,7 @@ class SourceProvider { | |||||||
|     HuaweiAppGallery(), |     HuaweiAppGallery(), | ||||||
|     Tencent(), |     Tencent(), | ||||||
|     CoolApk(), |     CoolApk(), | ||||||
|  |     LiteAPKs(), | ||||||
|     VivoAppStore(), |     VivoAppStore(), | ||||||
|     Jenkins(), |     Jenkins(), | ||||||
|     APKMirror(), |     APKMirror(), | ||||||
|   | |||||||
							
								
								
									
										124
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								pubspec.lock
									
									
									
									
									
								
							| @@ -5,10 +5,10 @@ packages: | |||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: android_intent_plus |       name: android_intent_plus | ||||||
|       sha256: dfc1fd3a577205ae8f11e990fb4ece8c90cceabbee56fcf48e463ecf0bd6aae3 |       sha256: "14a9f94c5825a528e8c38ee89a33dbeba947efbbf76f066c174f4f3ae4f48feb" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "5.3.0" |     version: "6.0.0" | ||||||
|   android_package_installer: |   android_package_installer: | ||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
| @@ -40,18 +40,18 @@ packages: | |||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: animations |       name: animations | ||||||
|       sha256: d3d6dcfb218225bbe68e87ccf6378bbb2e32a94900722c5f81611dad089911cb |       sha256: a8031b276f0a7986ac907195f10ca7cd04ecf2a8a566bd6dbe03018a9b02b427 | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.0.11" |     version: "2.1.0" | ||||||
|   app_links: |   app_links: | ||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: app_links |       name: app_links | ||||||
|       sha256: "85ed8fc1d25a76475914fff28cc994653bd900bc2c26e4b57a49e097febb54ba" |       sha256: "5f88447519add627fe1cbcab4fd1da3d4fed15b9baf29f28b22535c95ecee3e8" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "6.4.0" |     version: "6.4.1" | ||||||
|   app_links_linux: |   app_links_linux: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -104,10 +104,10 @@ packages: | |||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: battery_plus |       name: battery_plus | ||||||
|       sha256: fb794c34cee2e4ea31005fb17ff15e1d904951ec7f15eedead741021870ee834 |       sha256: ad16fcb55b7384be6b4bbc763d5e2031ac7ea62b2d9b6b661490c7b9741155bf | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "6.2.2" |     version: "7.0.0" | ||||||
|   battery_plus_platform_interface: |   battery_plus_platform_interface: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -160,10 +160,10 @@ packages: | |||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: connectivity_plus |       name: connectivity_plus | ||||||
|       sha256: "051849e2bd7c7b3bc5844ea0d096609ddc3a859890ec3a9ac4a65a2620cc1f99" |       sha256: "33bae12a398f841c6cda09d1064212957265869104c478e5ad51e2fb26c3973c" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "6.1.4" |     version: "7.0.0" | ||||||
|   connectivity_plus_platform_interface: |   connectivity_plus_platform_interface: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -216,10 +216,10 @@ packages: | |||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: device_info_plus |       name: device_info_plus | ||||||
|       sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a" |       sha256: "49413c8ca514dea7633e8def233b25efdf83ec8522955cc2c0e3ad802927e7c6" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "11.5.0" |     version: "12.1.0" | ||||||
|   device_info_plus_platform_interface: |   device_info_plus_platform_interface: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -232,10 +232,10 @@ packages: | |||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: dynamic_color |       name: dynamic_color | ||||||
|       sha256: eae98052fa6e2826bdac3dd2e921c6ce2903be15c6b7f8b6d8a5d49b5086298d |       sha256: "43a5a6679649a7731ab860334a5812f2067c2d9ce6452cf069c5e0c25336c17c" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.7.0" |     version: "1.8.1" | ||||||
|   easy_localization: |   easy_localization: | ||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
| @@ -288,10 +288,10 @@ packages: | |||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: file_picker |       name: file_picker | ||||||
|       sha256: "13ba4e627ef24503a465d1d61b32596ce10eb6b8903678d362a528f9939b4aa8" |       sha256: f2d9f173c2c14635cc0e9b14c143c49ef30b4934e8d1d274d6206fcb0086a06f | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "10.2.1" |     version: "10.3.3" | ||||||
|   fixnum: |   fixnum: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -482,10 +482,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: flutter_plugin_android_lifecycle |       name: flutter_plugin_android_lifecycle | ||||||
|       sha256: f948e346c12f8d5480d2825e03de228d0eb8c3a737e4cdaa122267b89c022b5e |       sha256: c2fe1001710127dfa7da89977a08d591398370d099aacdaa6d44da7eb14b8476 | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.0.28" |     version: "2.0.31" | ||||||
|   flutter_test: |   flutter_test: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: flutter |     description: flutter | ||||||
| @@ -508,10 +508,10 @@ packages: | |||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: fluttertoast |       name: fluttertoast | ||||||
|       sha256: "25e51620424d92d3db3832464774a6143b5053f15e382d8ffbfd40b6e795dcf1" |       sha256: "144ddd74d49c865eba47abe31cbc746c7b311c82d6c32e571fd73c4264b740e2" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "8.2.12" |     version: "9.0.0" | ||||||
|   fraction: |   fraction: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -548,10 +548,10 @@ packages: | |||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: http |       name: http | ||||||
|       sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b" |       sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007 | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.4.0" |     version: "1.5.0" | ||||||
|   http_parser: |   http_parser: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -572,26 +572,26 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: leak_tracker |       name: leak_tracker | ||||||
|       sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" |       sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "10.0.9" |     version: "11.0.2" | ||||||
|   leak_tracker_flutter_testing: |   leak_tracker_flutter_testing: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: leak_tracker_flutter_testing |       name: leak_tracker_flutter_testing | ||||||
|       sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 |       sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "3.0.9" |     version: "3.0.10" | ||||||
|   leak_tracker_testing: |   leak_tracker_testing: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: leak_tracker_testing |       name: leak_tracker_testing | ||||||
|       sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" |       sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "3.0.1" |     version: "3.0.2" | ||||||
|   lints: |   lints: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -676,18 +676,18 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: path_provider_android |       name: path_provider_android | ||||||
|       sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 |       sha256: "3b4c1fc3aa55ddc9cd4aa6759984330d5c8e66aa7702a6223c61540dc6380c37" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.2.17" |     version: "2.2.19" | ||||||
|   path_provider_foundation: |   path_provider_foundation: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: path_provider_foundation |       name: path_provider_foundation | ||||||
|       sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" |       sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.4.1" |     version: "2.4.2" | ||||||
|   path_provider_linux: |   path_provider_linux: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -820,26 +820,26 @@ packages: | |||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: provider |       name: provider | ||||||
|       sha256: "4abbd070a04e9ddc287673bf5a030c7ca8b685ff70218720abab8b092f53dd84" |       sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "6.1.5" |     version: "6.1.5+1" | ||||||
|   share_plus: |   share_plus: | ||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: share_plus |       name: share_plus | ||||||
|       sha256: b2961506569e28948d75ec346c28775bb111986bb69dc6a20754a457e3d97fa0 |       sha256: "3424e9d5c22fd7f7590254ba09465febd6f8827c8b19a44350de4ac31d92d3a6" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "11.0.0" |     version: "12.0.0" | ||||||
|   share_plus_platform_interface: |   share_plus_platform_interface: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: share_plus_platform_interface |       name: share_plus_platform_interface | ||||||
|       sha256: "1032d392bc5d2095a77447a805aa3f804d2ae6a4d5eef5e6ebb3bd94c1bc19ef" |       sha256: "88023e53a13429bd65d8e85e11a9b484f49d4c190abbd96c7932b74d6927cc9a" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "6.0.0" |     version: "6.1.0" | ||||||
|   shared_preferences: |   shared_preferences: | ||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
| @@ -852,10 +852,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: shared_preferences_android |       name: shared_preferences_android | ||||||
|       sha256: "20cbd561f743a342c76c151d6ddb93a9ce6005751e7aa458baad3858bfbfb6ac" |       sha256: "34266009473bf71d748912da4bf62d439185226c03e01e2d9687bc65bbfcb713" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.4.10" |     version: "2.4.15" | ||||||
|   shared_preferences_foundation: |   shared_preferences_foundation: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -947,10 +947,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: sqflite_android |       name: sqflite_android | ||||||
|       sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b" |       sha256: ecd684501ebc2ae9a83536e8b15731642b9570dc8623e0073d227d0ee2bfea88 | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.4.1" |     version: "2.4.2+2" | ||||||
|   sqflite_common: |   sqflite_common: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -1019,10 +1019,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: test_api |       name: test_api | ||||||
|       sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd |       sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "0.7.4" |     version: "0.7.6" | ||||||
|   timezone: |   timezone: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -1059,18 +1059,18 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: url_launcher_android |       name: url_launcher_android | ||||||
|       sha256: "8582d7f6fe14d2652b4c45c9b6c14c0b678c2af2d083a11b604caeba51930d79" |       sha256: "5c8b6c2d89a78f5a1cca70a73d9d5f86c701b36b42f9c9dac7bad592113c28e9" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "6.3.16" |     version: "6.3.24" | ||||||
|   url_launcher_ios: |   url_launcher_ios: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: url_launcher_ios |       name: url_launcher_ios | ||||||
|       sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb" |       sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7 | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "6.3.3" |     version: "6.3.4" | ||||||
|   url_launcher_linux: |   url_launcher_linux: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -1083,10 +1083,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: url_launcher_macos |       name: url_launcher_macos | ||||||
|       sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2" |       sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "3.2.2" |     version: "3.2.3" | ||||||
|   url_launcher_platform_interface: |   url_launcher_platform_interface: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -1123,18 +1123,18 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: vector_math |       name: vector_math | ||||||
|       sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" |       sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.1.4" |     version: "2.2.0" | ||||||
|   vm_service: |   vm_service: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: vm_service |       name: vm_service | ||||||
|       sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 |       sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "15.0.0" |     version: "15.0.2" | ||||||
|   web: |   web: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -1155,10 +1155,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: webview_flutter_android |       name: webview_flutter_android | ||||||
|       sha256: "9573ad97890d199ac3ab32399aa33a5412163b37feb573eb5b0a76b35e9ffe41" |       sha256: e5201c620eb2637dca88a756961fae4a7191bb30b4f2271e08b746405ffdf3fd | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "4.8.2" |     version: "4.10.5" | ||||||
|   webview_flutter_platform_interface: |   webview_flutter_platform_interface: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -1171,18 +1171,18 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: webview_flutter_wkwebview |       name: webview_flutter_wkwebview | ||||||
|       sha256: "71523b9048cf510cfa1fd4e0a3fa5e476a66e0884d5df51d59d5023dba237107" |       sha256: fea63576b3b7e02b2df8b78ba92b48ed66caec2bb041e9a0b1cbd586d5d80bfd | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "3.22.1" |     version: "3.23.1" | ||||||
|   win32: |   win32: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: win32 |       name: win32 | ||||||
|       sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03" |       sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "5.14.0" |     version: "5.15.0" | ||||||
|   win32_registry: |   win32_registry: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -1208,5 +1208,5 @@ packages: | |||||||
|     source: hosted |     source: hosted | ||||||
|     version: "6.3.0" |     version: "6.3.0" | ||||||
| sdks: | sdks: | ||||||
|   dart: ">=3.8.1 <4.0.0" |   dart: ">=3.9.0 <4.0.0" | ||||||
|   flutter: ">=3.29.0" |   flutter: ">=3.35.0" | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								pubspec.yaml
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								pubspec.yaml
									
									
									
									
									
								
							| @@ -16,7 +16,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 | # 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 | # 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. | # of the product and file versions while build-number is used as the build suffix. | ||||||
| version: 1.2.3+2319 | version: 1.2.7+2323 | ||||||
|  |  | ||||||
| environment: | environment: | ||||||
|   sdk: ^3.8.1 |   sdk: ^3.8.1 | ||||||
| @@ -45,8 +45,8 @@ dependencies: | |||||||
|   shared_preferences: ^2.5.3 |   shared_preferences: ^2.5.3 | ||||||
|   url_launcher: ^6.3.1 |   url_launcher: ^6.3.1 | ||||||
|   permission_handler: ^12.0.0+1 |   permission_handler: ^12.0.0+1 | ||||||
|   fluttertoast: ^8.2.12 |   fluttertoast: ^9.0.0 | ||||||
|   device_info_plus: ^11.4.0 |   device_info_plus: ^12.1.0 | ||||||
|   file_picker: ^10.1.9 |   file_picker: ^10.1.9 | ||||||
|   animations: ^2.0.11 |   animations: ^2.0.11 | ||||||
|   android_package_installer: # TODO: See if PR will be accepted (dev may not be active), else remove this comment |   android_package_installer: # TODO: See if PR will be accepted (dev may not be active), else remove this comment | ||||||
| @@ -57,14 +57,14 @@ dependencies: | |||||||
|     git: |     git: | ||||||
|       url: https://github.com/ImranR98/android_package_manager |       url: https://github.com/ImranR98/android_package_manager | ||||||
|       ref: master |       ref: master | ||||||
|   share_plus: ^11.0.0 |   share_plus: ^12.0.0 | ||||||
|   sqflite: ^2.4.2 |   sqflite: ^2.4.2 | ||||||
|   easy_localization: ^3.0.7+1 |   easy_localization: ^3.0.7+1 | ||||||
|   android_intent_plus: ^5.3.0 |   android_intent_plus: ^6.0.0 | ||||||
|   flutter_markdown: ^0.7.7+1 |   flutter_markdown: ^0.7.7+1 | ||||||
|   flutter_archive: ^6.0.3 |   flutter_archive: ^6.0.3 | ||||||
|   hsluv: ^1.1.3 |   hsluv: ^1.1.3 | ||||||
|   connectivity_plus: ^6.1.4 |   connectivity_plus: ^7.0.0 | ||||||
|   shared_storage: # TODO: Is this maintained? |   shared_storage: # TODO: Is this maintained? | ||||||
|     git: |     git: | ||||||
|       url: https://github.com/AlexBacich/shared-storage |       url: https://github.com/AlexBacich/shared-storage | ||||||
| @@ -85,7 +85,7 @@ dependencies: | |||||||
|       ref: master |       ref: master | ||||||
|   markdown: ^7.3.0 |   markdown: ^7.3.0 | ||||||
|   flutter_typeahead: ^5.2.0 |   flutter_typeahead: ^5.2.0 | ||||||
|   battery_plus: ^6.2.1 |   battery_plus: ^7.0.0 | ||||||
|   flutter_charset_detector: ^5.0.0 |   flutter_charset_detector: ^5.0.0 | ||||||
|  |  | ||||||
|   # The "flutter_lints" package below contains a set of recommended lints to |   # The "flutter_lints" package below contains a set of recommended lints to | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user