Compare commits

...

35 Commits

Author SHA1 Message Date
Imran
3af185b0f8 Merge pull request #2552 from aminosred25/aminosred25-patch-1
Try to handle response body as a JSON first before handling it as a p…
2025-09-21 16:56:50 -04:00
aminosred25
bfbb2710b6 Try to handle response body as a JSON first before handling it as a plain text 2025-09-21 22:33:57 +02:00
Imran
c81c3c5ea7 Merge pull request #2551 from ImranR98/dev
- Add 'sky22333/hubproxy' support for GitHub (#2513)
- Fix error in Vivo Store search when no result found (#2494)
- Correct a log string (#2519)
- Loose auto-filtering for farsroid.com (#2441)
- Re-enable auto-filtering for farsroid.com w/ toggle to disable it (#2441)
- Enable long-press and double-tap gestures on app icon in apps list (#2444, #2448)
2025-09-21 14:14:37 -04:00
Imran Remtulla
7391e9a94d Upgrade Flutter + packages, increment version 2025-09-21 14:11:40 -04:00
Imran Remtulla
04633131e7 Enable long-press and double-tap gestures on app icon in apps list (#2444, #2448) 2025-09-21 13:37:57 -04:00
Imran Remtulla
7bc818fbfa Re-enable auto-filtering for farsroid.com w/ toggle to disable it (#2441) 2025-09-21 13:01:59 -04:00
Imran Remtulla
4afcd92510 Loose auto-filtering for farsroid.com (#2441) 2025-09-21 12:51:06 -04:00
Imran Remtulla
0784f83792 Correct a log string (#2519) 2025-09-21 12:34:07 -04:00
Imran Remtulla
a6608f1461 Fix error in Vivo Store search when no result found (#2494) 2025-09-21 12:28:02 -04:00
Imran Remtulla
08d9c4daaa Add 'sky22333/hubproxy' support for GitHub (#2513) 2025-09-21 12:16:58 -04:00
Imran
225362d351 Merge pull request #2539 from neardaniel-pls/main
Refined translation terms
2025-09-19 23:13:36 -04:00
Imran
089bf97ff2 Merge pull request #2545 from kvak54/rustore-patch
Restore RuStore support through replace URL of API.
2025-09-19 23:13:24 -04:00
kvak54
123cd5b130 Restore RuStore support through replace URL of API.
If the application is published as an AAB,
then the old one produced an unusable file (one of split files).
The new one provide a monolithic file.
2025-09-14 21:07:32 +07:00
Near
bc24f008fa fixed spacing 2025-09-13 22:41:20 +01:00
Near
472ec4e400 refine translation terms 2025-09-13 22:37:19 +01:00
Imran
a56069e881 Merge pull request #2537 from ImranR98/dev
Fix versionCode issue (#2505) + Flutter upgrades
2025-09-12 15:16:01 -04:00
Imran Remtulla
a34e45363b Fix versionCode issue (#2505) + Flutter upgrades 2025-09-12 15:13:20 -04:00
Imran
e1a89f5f67 Merge pull request #2531 from ar-lex/feature/3rd-party-fdroid-per-app-author
Add per-application author parsing for third-party F-Droid repos (#2527)
2025-09-12 14:44:10 -04:00
Imran
f7f6e0cde7 Merge pull request #2532 from ar-lex/feature/3rd-party-fdroid-changelog
Support changelog field for third-party F-Droid repos (#2528)
2025-09-12 14:44:04 -04:00
Alexey Arutyunov
5a58522bf6 Support changelog field for third-party F-Droid repos (#2528) 2025-09-12 20:39:23 +02:00
Alexey Arutyunov
9347af2090 Add per-application author parsing for third-party F-Droid repos (#2527) 2025-09-12 20:33:49 +02:00
Imran
b294e57367 Merge pull request #2530 from ar-lex/feature/3rd-party-fdroid-suggested-version
Implement suggested version code for third-party F-Droid repos (#2524)
2025-09-12 14:23:30 -04:00
Imran
4234e16432 Merge pull request #2533 from solokot/main
Translation: update ru.json
2025-09-12 14:21:10 -04:00
Imran
a64f2e1af7 Merge pull request #2522 from bluefly000/japanese-translation
Update ja.json
2025-09-12 14:20:50 -04:00
solokot
926462407c Translation: update ru.json
Fix machine translation
2025-09-12 09:57:50 +03:00
Alexey Arutyunov
1b499700fd Implement suggested version code for third-party F-Droid repos (#2524)
Enable it by default for both official and third-party F-Droid sources.

Reuse trySelectingSuggestedVersionCode label from official F-Droid repository source.
2025-09-11 23:34:28 +02:00
bluefly000
930a4b411e Update ja.json 2025-09-06 18:54:11 +09:00
Imran
b9931e00e7 Merge pull request #2508 from summoner001/main
Translation: Update hu.json
2025-08-31 21:38:05 -04:00
summoner
2337e04ee1 Translation: Update hu.json
Translate new string.
Fix sentence.
2025-08-31 12:40:02 +02:00
Imran
2fc8dafc9e Merge pull request #2503 from ImranR98/dev
- Added LiteAPKs as a source (#1799)
- Remove unnecessary permission (#2467)
2025-08-31 00:49:01 -04:00
Imran Remtulla
0603c6a1d3 Translation updates 2025-08-31 00:47:15 -04:00
Imran Remtulla
555284d2cb Update Flutter + packages, increment version 2025-08-31 00:08:08 -04:00
Imran
357e2b8a89 Merge pull request #2497 from UlyssesZh/match-links-outside-a-tags
feat: add option to match links outside <a> tags even if links in <a> tags are found
2025-08-31 00:00:20 -04:00
Imran Remtulla
5b147b82e0 Added LiteAPKs as a source (#1799) 2025-08-30 23:59:21 -04:00
Ulysses Zhan
87ef762eec feat: add option to match links outside <a> tags even if links in <a> tags are found 2025-08-27 00:59:48 -07:00
50 changed files with 577 additions and 201 deletions

View File

@@ -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")
} }

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "التحقق من علامة 'الأحدث'", "verifyLatestTag": "التحقق من علامة 'الأحدث'",
"intermediateLinkRegex": "تصفية للوصول إلى رابط 'وسيط'", "intermediateLinkRegex": "تصفية للوصول إلى رابط 'وسيط'",
"filterByLinkText": "تصفية الروابط حسب نص الرابط", "filterByLinkText": "تصفية الروابط حسب نص الرابط",
"matchLinksOutsideATags": "تطابق الروابط خارج علامات <a>",
"intermediateLinkNotFound": "لم يتم العثور على رابط وسيط", "intermediateLinkNotFound": "لم يتم العثور على رابط وسيط",
"intermediateLink": "رابط وسيط", "intermediateLink": "رابط وسيط",
"exemptFromBackgroundUpdates": "إعفاء من التحديثات في الخلفية (إذا تم تمكينها)", "exemptFromBackgroundUpdates": "إعفاء من التحديثات في الخلفية (إذا تم تمكينها)",
@@ -335,6 +336,7 @@
"foregroundServiceExplanation": "استخدام خدمة مقدمة للتحقق من التحديثات (أكثر موثوقية وتستهلك طاقة أكبر)", "foregroundServiceExplanation": "استخدام خدمة مقدمة للتحقق من التحديثات (أكثر موثوقية وتستهلك طاقة أكبر)",
"fgServiceNotice": "هذا الإشعار مطلوب للتحقق من التحديث في الخلفية (يمكن إخفاؤه في إعدادات نظام التشغيل)", "fgServiceNotice": "هذا الإشعار مطلوب للتحقق من التحديث في الخلفية (يمكن إخفاؤه في إعدادات نظام التشغيل)",
"excludeSecrets": "استبعاد الأسرار", "excludeSecrets": "استبعاد الأسرار",
"GHReqPrefix": "مثيل \"sky22333/hubproxy\" لطلبات GitHub",
"removeAppQuestion": { "removeAppQuestion": {
"one": "إزالة التطبيق؟", "one": "إزالة التطبيق؟",
"other": "إزالة التطبيقات؟" "other": "إزالة التطبيقات؟"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Želite li ukloniti aplikaciju?", "one": "Želite li ukloniti aplikaciju?",
"other": "Želite li ukloniti aplikacije?" "other": "Želite li ukloniti aplikacije?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "¿Suprimeixo l'aplicació?", "one": "¿Suprimeixo l'aplicació?",
"other": "¿Suprimeixo les aplicacions?" "other": "¿Suprimeixo les aplicacions?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Odstranit aplikaci?", "one": "Odstranit aplikaci?",
"other": "Odstranit aplikace?" "other": "Odstranit aplikace?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Fjern app?", "one": "Fjern app?",
"other": "Fjern apps?" "other": "Fjern apps?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "App entfernen?", "one": "App entfernen?",
"other": "Apps entfernen?" "other": "Apps entfernen?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Forigi la aplikaĵon?", "one": "Forigi la aplikaĵon?",
"other": "Forigi la aplikaĵojn?" "other": "Forigi la aplikaĵojn?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Remove app?", "one": "Remove app?",
"other": "Remove apps?" "other": "Remove apps?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "¿Eliminar aplicación?", "one": "¿Eliminar aplicación?",
"other": "¿Eliminar aplicaciones?" "other": "¿Eliminar aplicaciones?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "برنامه حذف شود؟", "one": "برنامه حذف شود؟",
"other": "برنامه ها حذف شوند؟" "other": "برنامه ها حذف شوند؟"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Supprimer l'application ?", "one": "Supprimer l'application ?",
"other": "Supprimer les applications ?" "other": "Supprimer les applications ?"

View File

@@ -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,7 @@
"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 kérésekhez",
"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?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Hapus aplikasi?", "one": "Hapus aplikasi?",
"other": "Hapus aplikasi?" "other": "Hapus aplikasi?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Rimuovere l'app?", "one": "Rimuovere l'app?",
"other": "Rimuovere le app?" "other": "Rimuovere le app?"

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "'latest'タグを確認する", "verifyLatestTag": "'latest'タグを確認する",
"intermediateLinkRegex": "訪問する「中間」リンクのフィルター", "intermediateLinkRegex": "訪問する「中間」リンクのフィルター",
"filterByLinkText": "テキストでリンクをフィルタリングする", "filterByLinkText": "テキストでリンクをフィルタリングする",
"matchLinksOutsideATags": "<a>タグの外にあるリンクに一致させる",
"intermediateLinkNotFound": "中間リンクが見つかりませんでした", "intermediateLinkNotFound": "中間リンクが見つかりませんでした",
"intermediateLink": "中間リンク", "intermediateLink": "中間リンク",
"exemptFromBackgroundUpdates": "バックグラウンドアップデートを行わない (有効な場合)", "exemptFromBackgroundUpdates": "バックグラウンドアップデートを行わない (有効な場合)",
@@ -334,7 +335,8 @@
"foregroundService": "Obtainium フォアグラウンドサービス", "foregroundService": "Obtainium フォアグラウンドサービス",
"foregroundServiceExplanation": "アップデート確認にフォアグラウンドサービスを使用する(より信頼性が高いが、より電力を消費する)", "foregroundServiceExplanation": "アップデート確認にフォアグラウンドサービスを使用する(より信頼性が高いが、より電力を消費する)",
"fgServiceNotice": "この通知は、バックグラウンドでアップデートを確認するために必要ですOSの設定で非表示にできます。", "fgServiceNotice": "この通知は、バックグラウンドでアップデートを確認するために必要ですOSの設定で非表示にできます。",
"excludeSecrets": "秘密を除く", "excludeSecrets": "シークレットを除く",
"GHReqPrefix": "GitHub リクエスト用の 'sky22333/hubproxy' インスタンス",
"removeAppQuestion": { "removeAppQuestion": {
"one": "アプリを削除しますか?", "one": "アプリを削除しますか?",
"other": "アプリを削除しますか?" "other": "アプリを削除しますか?"

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "'최신' 태그 확인", "verifyLatestTag": "'최신' 태그 확인",
"intermediateLinkRegex": "'중간' 링크 방문 필터", "intermediateLinkRegex": "'중간' 링크 방문 필터",
"filterByLinkText": "링크 텍스트로 링크 필터링", "filterByLinkText": "링크 텍스트로 링크 필터링",
"matchLinksOutsideATags": "<> 태그 외부의 링크 일치",
"intermediateLinkNotFound": "중간 링크를 찾을 수 없습니다", "intermediateLinkNotFound": "중간 링크를 찾을 수 없습니다",
"intermediateLink": "중간 링크", "intermediateLink": "중간 링크",
"exemptFromBackgroundUpdates": "백그라운드 업데이트에서 제외 (활성화된 경우)", "exemptFromBackgroundUpdates": "백그라운드 업데이트에서 제외 (활성화된 경우)",
@@ -335,6 +336,7 @@
"foregroundServiceExplanation": "업데이트 확인을 위해 포그라운드 서비스 사용(안정성 향상, 전력 소비량 증가)", "foregroundServiceExplanation": "업데이트 확인을 위해 포그라운드 서비스 사용(안정성 향상, 전력 소비량 증가)",
"fgServiceNotice": "이 알림은 백그라운드 업데이트 확인에 필요합니다(OS 설정에서 숨길 수 있음).", "fgServiceNotice": "이 알림은 백그라운드 업데이트 확인에 필요합니다(OS 설정에서 숨길 수 있음).",
"excludeSecrets": "비밀 제외", "excludeSecrets": "비밀 제외",
"GHReqPrefix": "GitHub 요청을 위한 'sky22333/hubproxy' 인스턴스",
"removeAppQuestion": { "removeAppQuestion": {
"one": "앱을 제거하시겠습니까?", "one": "앱을 제거하시겠습니까?",
"other": "앱을 제거하시겠습니까?" "other": "앱을 제거하시겠습니까?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "ആപ്പ് നീക്കം ചെയ്യണോ?", "one": "ആപ്പ് നീക്കം ചെയ്യണോ?",
"other": "ആപ്പുകൾ നീക്കം ചെയ്യണോ?" "other": "ആപ്പുകൾ നീക്കം ചെയ്യണോ?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "App verwijderen?", "one": "App verwijderen?",
"other": "Apps verwijderen?" "other": "Apps verwijderen?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Usunąć aplikację?", "one": "Usunąć aplikację?",
"few": "Usunąć aplikacje?", "few": "Usunąć aplikacje?",

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Remover app?", "one": "Remover app?",
"other": "Remover apps?" "other": "Remover apps?"

View File

@@ -254,6 +254,7 @@
"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)",
@@ -335,25 +336,26 @@
"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",
"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 +378,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",

View File

@@ -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,7 @@
"foregroundServiceExplanation": "Использовать приоритетную службу для проверки обновлений (надёжнее, энергозатратнее)", "foregroundServiceExplanation": "Использовать приоритетную службу для проверки обновлений (надёжнее, энергозатратнее)",
"fgServiceNotice": "Это уведомление необходимо для фоновой проверки обновлений (оно может быть скрыто в настройках ОС)", "fgServiceNotice": "Это уведомление необходимо для фоновой проверки обновлений (оно может быть скрыто в настройках ОС)",
"excludeSecrets": "Исключить секреты", "excludeSecrets": "Исключить секреты",
"GHReqPrefix": "Экземпляр 'sky22333/hubproxy' для запросов на GitHub",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Удалить приложение?", "one": "Удалить приложение?",
"other": "Удалить приложения?" "other": "Удалить приложения?"

View File

@@ -21,6 +21,7 @@ const neverAutoTranslate = {
obtainiumImport: ['nl'], obtainiumImport: ['nl'],
appLogs: ['nl'], appLogs: ['nl'],
apks: ['vi'], apks: ['vi'],
minute: ['fr'],
tencentAppStore: ['*'] tencentAppStore: ['*']
} }

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Ta Bort App?", "one": "Ta Bort App?",
"other": "Ta Bort Appar?" "other": "Ta Bort Appar?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Uygulamayı Kaldır?", "one": "Uygulamayı Kaldır?",
"other": "Uygulamaları Kaldır?" "other": "Uygulamaları Kaldır?"

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Перевірити тег 'latest'", "verifyLatestTag": "Перевірити тег 'latest'",
"intermediateLinkRegex": "Фільтр для 'Проміжного' Посилання для Відвідування", "intermediateLinkRegex": "Фільтр для 'Проміжного' Посилання для Відвідування",
"filterByLinkText": "Фільтрувати посилання за текстом посилання", "filterByLinkText": "Фільтрувати посилання за текстом посилання",
"matchLinksOutsideATags": "Зіставлення посилань поза тегами <a>",
"intermediateLinkNotFound": "Проміжне посилання не знайдено", "intermediateLinkNotFound": "Проміжне посилання не знайдено",
"intermediateLink": "Проміжне посилання", "intermediateLink": "Проміжне посилання",
"exemptFromBackgroundUpdates": "Виключено з фонових оновлень (якщо ввімкнено)", "exemptFromBackgroundUpdates": "Виключено з фонових оновлень (якщо ввімкнено)",
@@ -335,6 +336,7 @@
"foregroundServiceExplanation": "Використовуйте службу переднього плану для перевірки оновлень (надійніша, споживає більше енергії)", "foregroundServiceExplanation": "Використовуйте службу переднього плану для перевірки оновлень (надійніша, споживає більше енергії)",
"fgServiceNotice": "Це сповіщення необхідне для фонової перевірки оновлень (його можна приховати в налаштуваннях ОС)", "fgServiceNotice": "Це сповіщення необхідне для фонової перевірки оновлень (його можна приховати в налаштуваннях ОС)",
"excludeSecrets": "Виключити секрети", "excludeSecrets": "Виключити секрети",
"GHReqPrefix": "екземпляр 'sky22333/hubproxy' для запитів на GitHub",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Видалити застосунок?", "one": "Видалити застосунок?",
"other": "Видалити застосунки?" "other": "Видалити застосунки?"

View File

@@ -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,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Gỡ ứng dụng?", "one": "Gỡ ứng dụng?",
"other": "Gỡ ứng dụng?" "other": "Gỡ ứng dụng?"

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "驗證「最新」標籤", "verifyLatestTag": "驗證「最新」標籤",
"intermediateLinkRegex": "過濾要存取的「中間」連結", "intermediateLinkRegex": "過濾要存取的「中間」連結",
"filterByLinkText": "按連結文字過濾連結", "filterByLinkText": "按連結文字過濾連結",
"matchLinksOutsideATags": "匹配 <a> 標籤外的連結",
"intermediateLinkNotFound": "沒有找到中間連結", "intermediateLinkNotFound": "沒有找到中間連結",
"intermediateLink": "中間連結", "intermediateLink": "中間連結",
"exemptFromBackgroundUpdates": "免除背景更新(若已啟用)", "exemptFromBackgroundUpdates": "免除背景更新(若已啟用)",
@@ -335,6 +336,7 @@
"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",
"removeAppQuestion": { "removeAppQuestion": {
"one": "移除應用程式?", "one": "移除應用程式?",
"other": "移除應用程式?" "other": "移除應用程式?"

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "验证“Latest”标签", "verifyLatestTag": "验证“Latest”标签",
"intermediateLinkRegex": "筛选中转链接的正则表达式", "intermediateLinkRegex": "筛选中转链接的正则表达式",
"filterByLinkText": "根据链接文本进行筛选", "filterByLinkText": "根据链接文本进行筛选",
"matchLinksOutsideATags": "匹配 <a> 标签外的链接",
"intermediateLinkNotFound": "未找到中转链接", "intermediateLinkNotFound": "未找到中转链接",
"intermediateLink": "中转链接", "intermediateLink": "中转链接",
"exemptFromBackgroundUpdates": "禁用后台更新(仅此应用生效,即使已启用全局后台更新)", "exemptFromBackgroundUpdates": "禁用后台更新(仅此应用生效,即使已启用全局后台更新)",
@@ -335,6 +336,7 @@
"foregroundServiceExplanation": "使用前台服务检查更新(更稳定,但也更耗电)", "foregroundServiceExplanation": "使用前台服务检查更新(更稳定,但也更耗电)",
"fgServiceNotice": "后台检查更新时需要此通知(可在操作系统设置中隐藏)", "fgServiceNotice": "后台检查更新时需要此通知(可在操作系统设置中隐藏)",
"excludeSecrets": "排除机密", "excludeSecrets": "排除机密",
"GHReqPrefix": "用于 GitHub 请求的 \"sky22333/hubproxy \"实例",
"removeAppQuestion": { "removeAppQuestion": {
"one": "是否删除应用?", "one": "是否删除应用?",
"other": "是否删除应用?" "other": "是否删除应用?"

View File

@@ -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;

View File

@@ -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,
.where( additionalSettings,
(l) => l.key.toLowerCase().startsWith( )).map((l) => MapEntry(Uri.parse(l.key).pathSegments.last, l.key)).toList();
'$appName-$version'.toLowerCase(),
), if (additionalSettings['useFirstApkOfVersion'] == true) {
) apkLinks = apkLinks
.toList(); .where(
(l) => l.key.toLowerCase().startsWith(
'$appName-$version'.toLowerCase(),
),
)
.toList();
}
if (apkLinks.isEmpty) { if (apkLinks.isEmpty) {
throw NoAPKError(); throw NoAPKError();

View File

@@ -32,6 +32,7 @@ class FDroid extends AppSource {
GeneratedFormSwitch( GeneratedFormSwitch(
'trySelectingSuggestedVersionCode', 'trySelectingSuggestedVersionCode',
label: tr('trySelectingSuggestedVersionCode'), label: tr('trySelectingSuggestedVersionCode'),
defaultValue: true,
), ),
], ],
[ [

View File

@@ -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);

View File

@@ -45,6 +45,45 @@ 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 (Uri.parse(
'https://${value}/api.github.com',
).scheme.isNotEmpty) {
throw true;
}
} 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 = [
@@ -270,6 +309,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 +340,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;
@@ -344,6 +401,7 @@ class GitHub extends AppSource {
var url = !e['name'].toString().toLowerCase().endsWith('.apk') var url = !e['name'].toString().toLowerCase().endsWith('.apk')
? (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('', '');
@@ -522,7 +580,10 @@ class GitHub extends AppSource {
allAssetUrls.add( allAssetUrls.add(
MapEntry( MapEntry(
(targetRelease['version'] ?? 'source') + '.tar.gz', (targetRelease['version'] ?? 'source') + '.tar.gz',
targetRelease['tarball_url'], undoGHProxyMod(
targetRelease['tarball_url'],
sourceConfigSettingValues,
),
), ),
); );
} }
@@ -530,7 +591,10 @@ class GitHub extends AppSource {
allAssetUrls.add( allAssetUrls.add(
MapEntry( MapEntry(
(targetRelease['version'] ?? 'source') + '.zip', (targetRelease['version'] ?? 'source') + '.zip',
targetRelease['zipball_url'], undoGHProxyMod(
targetRelease['zipball_url'],
sourceConfigSettingValues,
),
), ),
); );
} }
@@ -652,12 +716,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 +741,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) {

View File

@@ -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

View File

@@ -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'))],
[ [

View 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,
),
);
}
}

View File

@@ -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',
), ),

View File

@@ -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);
} }

View File

@@ -70,12 +70,14 @@ 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'];
for (var item in (resultsJson as List<dynamic>)) { if (resultsJson != null) {
results['$appDetailUrl${item['id']}'] = [ for (var item in (resultsJson as List<dynamic>)) {
item['title_zh'].toString(), results['$appDetailUrl${item['id']}'] = [
item['developer'].toString(), item['title_zh'].toString(),
]; item['developer'].toString(),
];
}
} }
return results; return results;
} }

View File

@@ -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: [

View File

@@ -451,40 +451,57 @@ class AppsPageState extends State<AppsPage> {
} }
getAppIcon(int appIndex) { getAppIcon(int appIndex) {
return FutureBuilder( return GestureDetector(
future: appsProvider.updateAppIcon(listedApps[appIndex].app.id), child: FutureBuilder(
builder: (ctx, val) { future: appsProvider.updateAppIcon(listedApps[appIndex].app.id),
return listedApps[appIndex].icon != null builder: (ctx, val) {
? Image.memory( return listedApps[appIndex].icon != null
listedApps[appIndex].icon!, ? Image.memory(
gaplessPlayback: true, listedApps[appIndex].icon!,
opacity: AlwaysStoppedAnimation( gaplessPlayback: true,
listedApps[appIndex].installedInfo == null ? 0.6 : 1, opacity: AlwaysStoppedAnimation(
), listedApps[appIndex].installedInfo == null ? 0.6 : 1,
) ),
: Row( )
mainAxisSize: MainAxisSize.min, : Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min,
children: [ mainAxisAlignment: MainAxisAlignment.center,
Transform( children: [
alignment: Alignment.center, Transform(
transform: Matrix4.rotationZ(0.31), alignment: Alignment.center,
child: Padding( transform: Matrix4.rotationZ(0.31),
padding: const EdgeInsets.all(15), child: Padding(
child: Image( padding: const EdgeInsets.all(15),
image: const AssetImage( child: Image(
'assets/graphics/icon_small.png', image: const AssetImage(
'assets/graphics/icon_small.png',
),
color:
Theme.of(context).brightness == Brightness.dark
? Colors.white.withOpacity(0.4)
: Colors.white.withOpacity(0.3),
colorBlendMode: BlendMode.modulate,
gaplessPlayback: true,
), ),
color: Theme.of(context).brightness == Brightness.dark
? Colors.white.withOpacity(0.4)
: Colors.white.withOpacity(0.3),
colorBlendMode: BlendMode.modulate,
gaplessPlayback: true,
), ),
), ),
), ],
], );
); },
),
onDoubleTap: () {
pm.openApp(listedApps[appIndex].app.id);
},
onLongPress: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AppPage(
appId: listedApps[appIndex].app.id,
showOppositeOfPreferredView: true,
),
),
);
}, },
); );
} }

View File

@@ -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) {
e.defaultValue = settingsProvider.getSettingString(e.key); if (e is GeneratedFormSwitch) {
e.defaultValue = settingsProvider.getSettingBool(e.key);
} else {
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 ?? '');
}
}); });
} }
}, },

View File

@@ -606,10 +606,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,
...(await source.getSourceConfigValues(
app.additionalSettings,
settingsProvider,
)),
};
String downloadUrl = await source.assetUrlPrefetchModifier(
await source.generalReqPrefetchModifier(
app.apkUrls[app.preferredApkIndex].value,
additionalSettingsPlusSourceConfig,
),
app.url, app.url,
app.additionalSettings, additionalSettingsPlusSourceConfig,
); );
var notif = DownloadNotification(app.finalName, 100); var notif = DownloadNotification(app.finalName, 100);
notificationsProvider?.cancel(notif.id); notificationsProvider?.cancel(notif.id);
@@ -764,10 +774,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;
} }
@@ -1324,15 +1337,26 @@ class AppsProvider with ChangeNotifier {
evenIfSingleChoice: true, evenIfSingleChoice: true,
); );
if (tempFileUrl != null) { if (tempFileUrl != null) {
var s = SourceProvider().getSource(
apps[id]!.app.url,
overrideSource: apps[id]!.app.overrideSource,
);
var additionalSettingsPlusSourceConfig = {
...apps[id]!.app.additionalSettings,
...(await s.getSourceConfigValues(
apps[id]!.app.additionalSettings,
settingsProvider,
)),
};
fileUrl = MapEntry( fileUrl = MapEntry(
tempFileUrl.key, tempFileUrl.key,
await (SourceProvider().getSource( await s.assetUrlPrefetchModifier(
await s.generalReqPrefetchModifier(
tempFileUrl.value,
additionalSettingsPlusSourceConfig,
),
apps[id]!.app.url, apps[id]!.app.url,
overrideSource: apps[id]!.app.overrideSource, additionalSettingsPlusSourceConfig,
)).apkUrlPrefetchModifier(
tempFileUrl.value,
apps[id]!.app.url,
apps[id]!.app.additionalSettings,
), ),
); );
} }

View File

@@ -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') ?? '{}'));

View File

@@ -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';
@@ -685,14 +686,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,
); );
@@ -910,12 +924,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 +1097,7 @@ class SourceProvider {
HuaweiAppGallery(), HuaweiAppGallery(),
Tencent(), Tencent(),
CoolApk(), CoolApk(),
LiteAPKs(),
VivoAppStore(), VivoAppStore(),
Jenkins(), Jenkins(),
APKMirror(), APKMirror(),

View File

@@ -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:
@@ -48,10 +48,10 @@ packages:
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: b0694b7fb1689b0e6cc193b3f1fcac6423c4f93c74fb20b806c6b6f196db0c31
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.28" version: "2.0.30"
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: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.17" version: "2.2.18"
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: a2608114b1ffdcbc9c120eb71a0e207c71da56202852d4aab8a5e30a82269e74
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.10" version: "2.4.12"
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: "199bc33e746088546a39cc5f36bac5a278c5e53b40cb3196f99e7345fdcfae6b"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.16" version: "6.3.22"
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: "3c4eb4fcc252b40c2b5ce7be20d0481428b70f3ff589b0a8b8aaeb64c6bed701"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.8.2" version: "4.10.2"
webview_flutter_platform_interface: webview_flutter_platform_interface:
dependency: transitive dependency: transitive
description: description:
@@ -1171,10 +1171,10 @@ 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:
@@ -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"

View File

@@ -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.5+2321
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