Compare commits

...

67 Commits

Author SHA1 Message Date
188d33199e Merge pull request #1365 from heuwerk/patch-1
Update de.json
2024-02-03 04:29:36 -05:00
24928261bb Merge pull request #1367 from ImranR98/dev
Updated a package
2024-02-03 04:29:26 -05:00
4c7bda8343 Updated a package 2024-02-03 04:24:59 -05:00
d88709c999 Update de.json
Added forgotten translation
2024-02-02 11:30:20 +01:00
29e1481a3b Update de.json
Changed "Update" in translated text to "Aktualisierung", since it is used everywhere else.
2024-02-02 11:24:47 +01:00
9d76359543 Merge pull request #1364 from ImranR98/dev
Add DeepL translations as placeholders
2024-02-01 20:34:46 -05:00
f50e791221 Add DeepL translations as placeholders 2024-02-01 20:34:32 -05:00
7d08e5225c Merge pull request #1363 from ImranR98/dev
Correctly report and auto-delete bad APKs (#1251)
2024-02-01 19:32:15 -05:00
3842c1e2df Update packages, increment version 2024-02-01 19:31:32 -05:00
21b1990991 Merge remote-tracking branch 'origin/main' into dev 2024-02-01 19:31:19 -05:00
e278c9fb5a Correctly report and auto-delete bad APKs (#1251) 2024-02-01 19:26:36 -05:00
bfa29bb7c2 Merge pull request #1361 from DwainZwerg/patch-12
Translation of the Note of the sources window
2024-02-01 19:00:41 -05:00
efa55a9696 Update de.json
Okay → OK because it’s shorter and more common
2024-01-31 14:55:23 +00:00
8888cd6264 Update de.json
Translation of the note of the Sources Menu
2024-01-31 14:51:08 +00:00
34e2c014e3 Merge pull request #1357 from jont4/main
Update pt translation
2024-01-29 18:44:36 -05:00
5d92a6d013 Update pt translation 2024-01-28 22:58:17 -03:00
fb03b2e95c Merge pull request #1356 from ImranR98/dev
Better support for SourceForge (#1352), Remove READ_EXTERNAL_STORAGE again (#1309) + fix typo
2024-01-28 17:00:10 -05:00
5a1e09564c Merge pull request #1350 from gidano/main
Update hu.json
2024-01-28 16:58:53 -05:00
3783eba401 Merge pull request #1351 from unbranched/patch-5
Update it.json
2024-01-28 16:58:39 -05:00
a3530ce6bb Remove READ_EXTERNAL_STORAGE again (#1309) + fix typo 2024-01-28 16:58:09 -05:00
27d8655d58 Better support for SourceForge (#1352) 2024-01-28 16:32:58 -05:00
fb845ce601 Update it.json 2024-01-28 10:59:15 +00:00
dbd433df9d Update hu.json 2024-01-28 09:15:28 +01:00
badf32ff11 Merge pull request #1349 from ImranR98/dev
- Allow existing '/refs' in SourceHut URLs (#1347)
- Revert to showing App URL separately again (#1336)
- F-Droid: Don't pull changelog text if it isn't a raw file from GitHub/GitLab (#1340)
- Add a note on self-hosted instances of sources (#1342)
- versionCode changes
2024-01-27 22:00:54 -05:00
5e40f3264e Merge pull request #1337 from jont4/main
Translation: pt update
2024-01-27 21:58:41 -05:00
71bb6d9410 Merge pull request #1338 from teaminh/main
Update vi.json
2024-01-27 21:58:14 -05:00
731b682fc9 Merge pull request #1339 from DwainZwerg/patch-11
Update de.json
2024-01-27 21:57:03 -05:00
c9751227a5 Flutter upgrade + versionCode changes + increment version 2024-01-27 21:56:26 -05:00
6ef2a26e94 Add a note on self-hosted instances of sources (#1342) 2024-01-27 21:26:32 -05:00
5a8efa2388 F-Droid: Don't pull changelog text if it isn't a raw file from GitHub/GitLab (#1340) 2024-01-27 21:01:44 -05:00
d25895fa28 Revert to showing App URL separately again (#1336) 2024-01-27 20:13:01 -05:00
de09f3ece2 Allow existing '/refs' in SourceHut URLs (#1347) 2024-01-27 20:08:05 -05:00
1135ffb30f Update de.json
Better Translation of "latest"
2024-01-25 13:49:57 +00:00
5379cb31e8 Update vi.json 2024-01-25 18:31:46 +07:00
7d41ab44b7 Minor update 2024-01-24 23:21:42 -03:00
b239f9bd05 Merge pull request #1335 from ImranR98/dev
Don't include prereleases in default app entry
2024-01-24 20:15:35 -05:00
1acc923ec2 Don't include prereleases in default app entry 2024-01-24 20:15:13 -05:00
8d6edfb91f Update release.yml 2024-01-24 20:12:56 -05:00
491b62bb0d Update release.yml 2024-01-24 20:10:02 -05:00
d1413fc478 Update release.yml 2024-01-24 20:05:47 -05:00
761f7039e9 Merge pull request #1334 from ImranR98/dev
- De-emphasize 'reset install status' button to avoid confusion
- Minor bugfix (#1331)
2024-01-24 19:54:16 -05:00
59783a341d Upgrade packages, increment version (1.0.0) 2024-01-24 19:53:31 -05:00
0100fa4236 Merge remote-tracking branch 'origin/main' into dev 2024-01-24 19:52:42 -05:00
f6f9ed68dc Merge pull request #1332 from palopezv/patch-1
Update es.json
2024-01-24 19:50:46 -05:00
8adb5e84d1 Reordered a button for consistency 2024-01-24 19:50:11 -05:00
3940b65156 De-emphasize 'reset install status' button to avoid confusion 2024-01-24 19:49:07 -05:00
98e7f27eab Merge remote-tracking branch 'origin/main' into dev 2024-01-24 19:33:45 -05:00
7cf5cafd75 Minor bugfix (#1331) 2024-01-24 19:28:40 -05:00
d750e35273 Update release.yml 2024-01-24 19:22:56 -05:00
1f12e12130 Update es.json
I'm submitting a revision (call it heartless copy editing :😉:) of the Spanish translation file. This revision corrects several grammatical errors, most are syntactical and semantic, some stylistic in order to correct literal (and intellegible) translations and typos.
2024-01-24 16:11:54 -05:00
4a4fb4716e Merge pull request #1328 from ImranR98/dev
Updated modules
2024-01-23 11:37:29 -05:00
efe6ec0d43 Updated modules 2024-01-23 11:37:08 -05:00
00d605e195 Merge pull request #1325 from ImranR98/dev
Update Flutter submodule and make GitHub actions error out if it doesn't match latest/stable
2024-01-22 12:22:15 -05:00
f06de8d19f Update Flutter submodule and make GitHub actions error out if it doesn't match latest/stable 2024-01-22 12:21:38 -05:00
fac335c849 Merge pull request #1324 from p1gp1g/reproducible-build
Add flutter as a submodule (again)
2024-01-22 12:07:43 -05:00
5bef546ae4 Merge pull request #1323 from DwainZwerg/patch-10
Update de.json
2024-01-21 14:13:07 -05:00
b690cd6a67 Update de.json
Edit german translation
2024-01-21 18:59:22 +00:00
dbee4a2657 Merge pull request #1316 from bluefly000/japanese-translation
Update ja.json
2024-01-21 12:35:30 -05:00
67420f293b Merge pull request #1319 from teaminh/main
Update vi.json
2024-01-21 12:35:23 -05:00
d1d6b0792b Merge pull request #1322 from ygxbnet/patch-1
Update zh.json
2024-01-21 12:35:17 -05:00
2ec039ba0f Update zh.json 2024-01-21 23:38:20 +08:00
4b9b9a10ad Update vi.json 2024-01-21 10:00:00 +07:00
4193d8ada1 Update ja.json 2024-01-21 10:19:35 +09:00
4701b090b0 Update ja.json 2024-01-21 10:18:45 +09:00
8b0c85827c Merge pull request #1315 from ClockGen/fastlane
Added fastlane structure for F-Droid
2024-01-20 19:26:31 -05:00
57e02d1c80 Added initial fastlane structure 2024-01-21 01:51:57 +03:00
sim
7987083555 Add flutter as a submodule 2023-02-02 21:56:32 +01:00
48 changed files with 612 additions and 275 deletions

1
.flutter Submodule

Submodule .flutter added at 41456452f2

View File

@ -23,16 +23,27 @@ jobs:
gpg_private_key: ${{ secrets.PGP_KEY_BASE64 }} gpg_private_key: ${{ secrets.PGP_KEY_BASE64 }}
passphrase: ${{ secrets.PGP_PASSPHRASE }} passphrase: ${{ secrets.PGP_PASSPHRASE }}
- name: Check submodule
id: check_submodule
run: |
SUBMODULE_COMMIT_LONG="$(git submodule status | head -1 | tail -c +2 | awk '{print $1}')"
FLUTTER_COMMIT_SHORT="$(flutter --version | head -2 | tail -1 | awk '{print $4}')"
echo "SUBMODULE_COMMIT_LONG=$SUBMODULE_COMMIT_LONG, FLUTTER_COMMIT_SHORT=$FLUTTER_COMMIT_SHORT"
if ! [[ "$SUBMODULE_COMMIT_LONG" =~ ^$FLUTTER_COMMIT_SHORT ]]; then
echo "Your submodule has not been updated!"
exit 1
fi
- name: Extract Version - name: Extract Version
id: extract_version id: extract_version
run: | run: |
VERSION=$(grep -oP "^version: [^\+]+" pubspec.yaml | tail -c +10) VERSION=$(grep -oP "^version: [^\+]+" pubspec.yaml | tail -c +10)
echo "version=$VERSION" >> $GITHUB_OUTPUT echo "version=$VERSION" >> $GITHUB_OUTPUT
if [ ${{ inputs.beta }} == true ]; then BETA=true; else BETA=false; fi if [ ${{ inputs.beta }} == true ]; then BETA=true; else BETA=false; fi
echo "beta=$BETA" >> $GITHUB_OUTPUT echo "beta=$BETA" >> $GITHUB_OUTPUT
TAG="v$VERSION" TAG="v$VERSION"
if [ $BETA == true ]; then TAG="$TAG"-beta; fi if [ $BETA == true ]; then TAG="$TAG"-beta; fi
echo "tag=$TAG" >> $GITHUB_OUTPUT echo "tag=$TAG" >> $GITHUB_OUTPUT
- name: Build APKs - name: Build APKs
run: | run: |

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule ".flutter"]
path = .flutter
url = https://github.com/flutter/flutter/

View File

@ -108,3 +108,16 @@ dependencies {
implementation "com.github.topjohnwu.libsu:core:5.2.2" implementation "com.github.topjohnwu.libsu:core:5.2.2"
} }
ext.abiCodes = ["x86_64": 1, "armeabi-v7a": 2, "arm64-v8a": 3]
import com.android.build.OutputFile
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def abiVersionCode = project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))
if (abiVersionCode != null) {
output.versionCodeOverride = variant.versionCode * 10 + abiVersionCode
} else {
output.versionCodeOverride = variant.versionCode * 10
}
}
}

View File

@ -71,5 +71,7 @@
<uses-permission <uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29" /> android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
tools:node="remove" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" /> <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
</manifest> </manifest>

View File

@ -298,6 +298,9 @@
"installed": "Instalirano", "installed": "Instalirano",
"latest": "Najnoviji", "latest": "Najnoviji",
"invertRegEx": "Obrni regularni izraz", "invertRegEx": "Obrni regularni izraz",
"note": "Note",
"selfHostedNote": "The \"{}\" dropdown can be used to reach self-hosted/custom instances of any source.",
"badDownload": "The APK could not be parsed (incompatible or partial download)",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Želite li ukloniti aplikaciju?", "one": "Želite li ukloniti aplikaciju?",
"other": "Želite li ukloniti aplikacije?" "other": "Želite li ukloniti aplikacije?"

View File

@ -292,12 +292,15 @@
"useLatestAssetDateAsReleaseDate": "Použít poslední nahrané dílo jako datum vydání", "useLatestAssetDateAsReleaseDate": "Použít poslední nahrané dílo jako datum vydání",
"defaultPseudoVersioningMethod": "Výchozí metoda pseudoverze", "defaultPseudoVersioningMethod": "Výchozí metoda pseudoverze",
"partialAPKHash": "Částečný hash APK", "partialAPKHash": "Částečný hash APK",
"APKLinkHash": "APK Link Hash", "APKLinkHash": "Odkaz APK Hash",
"directAPKLink": "Přímý odkaz APK", "directAPKLink": "Přímý odkaz APK",
"pseudoVersionInUse": "Pseudoverze se používá", "pseudoVersionInUse": "Pseudoverze se používá",
"installed": "Instalováno", "installed": "Instalováno",
"latest": "Nejnovější", "latest": "Nejnovější",
"invertRegEx": "Invertovat regulární výraz", "invertRegEx": "Invertovat regulární výraz",
"note": "Poznámka",
"selfHostedNote": "Rozbalovací seznam \"{}\" lze použít k dosažení vlastních/obvyklých instancí libovolného zdroje.",
"badDownload": "APK nelze analyzovat (nekompatibilní nebo částečné stažení)",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Odstranit Apku?", "one": "Odstranit Apku?",
"other": "Odstranit Apky?" "other": "Odstranit Apky?"

View File

@ -9,7 +9,7 @@
"placeholder": "Platzhalter", "placeholder": "Platzhalter",
"someErrors": "Es traten einige Fehler auf", "someErrors": "Es traten einige Fehler auf",
"unexpectedError": "Unerwarteter Fehler", "unexpectedError": "Unerwarteter Fehler",
"ok": "Okay", "ok": "OK",
"and": "und", "and": "und",
"githubPATLabel": "GitHub Personal Access Token (Erhöht das Ratenlimit)", "githubPATLabel": "GitHub Personal Access Token (Erhöht das Ratenlimit)",
"includePrereleases": "Vorabversionen einbeziehen", "includePrereleases": "Vorabversionen einbeziehen",
@ -30,7 +30,7 @@
"app": "App", "app": "App",
"appsFromSourceAreTrackOnly": "Apps aus dieser Quelle sind nur zum Nachverfolgen.", "appsFromSourceAreTrackOnly": "Apps aus dieser Quelle sind nur zum Nachverfolgen.",
"youPickedTrackOnly": "Sie haben die Option „Nur Nachverfolgen“ gewählt.", "youPickedTrackOnly": "Sie haben die Option „Nur Nachverfolgen“ gewählt.",
"trackOnlyAppDescription": "Die App wird auf Updates überwacht, aber Obtainium wird sie nicht herunterladen oder installieren.", "trackOnlyAppDescription": "Die App wird auf Aktualisierungen überwacht, aber Obtainium wird sie nicht herunterladen oder installieren.",
"cancelled": "Abgebrochen", "cancelled": "Abgebrochen",
"appAlreadyAdded": "App bereits hinzugefügt", "appAlreadyAdded": "App bereits hinzugefügt",
"alreadyUpToDateQuestion": "App bereits auf dem neuesten Stand?", "alreadyUpToDateQuestion": "App bereits auf dem neuesten Stand?",
@ -86,7 +86,7 @@
"author": "Autor", "author": "Autor",
"upToDateApps": "Apps mit aktueller Version", "upToDateApps": "Apps mit aktueller Version",
"nonInstalledApps": "Nicht installierte Apps", "nonInstalledApps": "Nicht installierte Apps",
"importExport": "Import Export", "importExport": "Import/Export",
"settings": "Einstellungen", "settings": "Einstellungen",
"exportedTo": "Exportiert zu {}", "exportedTo": "Exportiert zu {}",
"obtainiumExport": "Obtainium-Export", "obtainiumExport": "Obtainium-Export",
@ -107,7 +107,7 @@
"selectURL": "URL auswählen", "selectURL": "URL auswählen",
"selectURLs": "URLs auswählen", "selectURLs": "URLs auswählen",
"pick": "Auswählen", "pick": "Auswählen",
"theme": "Thema", "theme": "Theme",
"dark": "Dunkel", "dark": "Dunkel",
"light": "Hell", "light": "Hell",
"followSystem": "System folgen", "followSystem": "System folgen",
@ -170,7 +170,7 @@
"yesMarkUpdated": "Ja, als aktualisiert markieren", "yesMarkUpdated": "Ja, als aktualisiert markieren",
"fdroid": "offizielles F-Droid-Repo", "fdroid": "offizielles F-Droid-Repo",
"appIdOrName": "App ID oder Name", "appIdOrName": "App ID oder Name",
"appId": "App-ID", "appId": "App ID",
"appWithIdOrNameNotFound": "Es wurde keine App mit dieser ID oder diesem Namen gefunden", "appWithIdOrNameNotFound": "Es wurde keine App mit dieser ID oder diesem Namen gefunden",
"reposHaveMultipleApps": "Repos können mehrere Apps enthalten", "reposHaveMultipleApps": "Repos können mehrere Apps enthalten",
"fdroidThirdPartyRepo": "F-Droid Drittparteienrepo", "fdroidThirdPartyRepo": "F-Droid Drittparteienrepo",
@ -209,7 +209,7 @@
"changes": "Änderungen", "changes": "Änderungen",
"releaseDate": "Veröffentlichungsdatum", "releaseDate": "Veröffentlichungsdatum",
"importFromURLsInFile": "Importieren von URLs aus Datei (z. B. OPML)", "importFromURLsInFile": "Importieren von URLs aus Datei (z. B. OPML)",
"versionDetectionExplanation": "Versionszeichenfolge mit der vom Betriebssystem erkannten Version abgleichen", "versionDetectionExplanation": "Abgleich der Versionsnummer mit der vom Betriebssystem erkannten Version",
"versionDetection": "Versionserkennung", "versionDetection": "Versionserkennung",
"standardVersionDetection": "Standardversionserkennung", "standardVersionDetection": "Standardversionserkennung",
"groupByCategory": "Nach Kategorie gruppieren", "groupByCategory": "Nach Kategorie gruppieren",
@ -226,7 +226,7 @@
"tryInferAppIdFromCode": "Versuche, die App-ID aus dem Quellcode zu ermitteln", "tryInferAppIdFromCode": "Versuche, die App-ID aus dem Quellcode zu ermitteln",
"removeOnExternalUninstall": "Automatisches Entfernen von extern deinstallierten Apps", "removeOnExternalUninstall": "Automatisches Entfernen von extern deinstallierten Apps",
"pickHighestVersionCode": "Automatische Auswahl des APK mit höchstem Versionscode", "pickHighestVersionCode": "Automatische Auswahl des APK mit höchstem Versionscode",
"checkUpdateOnDetailPage": "Nach Updates suchen, wenn eine App-Detailseite geöffnet wird", "checkUpdateOnDetailPage": "Nach Aktualisierungen suchen, wenn eine App-Detailseite geöffnet wird",
"disablePageTransitions": "Animationen für Seitenübergänge deaktivieren", "disablePageTransitions": "Animationen für Seitenübergänge deaktivieren",
"reversePageTransitions": "Umgekehrte Animationen für Seitenübergänge", "reversePageTransitions": "Umgekehrte Animationen für Seitenübergänge",
"minStarCount": "Minimale Anzahl von Sternen", "minStarCount": "Minimale Anzahl von Sternen",
@ -238,7 +238,7 @@
"filterReleaseNotesByRegEx": "Versionshinweise nach regulärem Ausdruck filtern", "filterReleaseNotesByRegEx": "Versionshinweise nach regulärem Ausdruck filtern",
"customLinkFilterRegex": "Benutzerdefinierter APK Link Filter nach Regulärem Ausdruck (Standard '.apk$')", "customLinkFilterRegex": "Benutzerdefinierter APK Link Filter nach Regulärem Ausdruck (Standard '.apk$')",
"appsPossiblyUpdated": "App Aktualisierungen wurden versucht", "appsPossiblyUpdated": "App Aktualisierungen wurden versucht",
"appsPossiblyUpdatedNotifDescription": "Benachrichtigt den Benutzer, dass Updates für eine oder mehrere Apps möglicherweise im Hintergrund durchgeführt wurden", "appsPossiblyUpdatedNotifDescription": "Benachrichtigt den Benutzer, dass Aktualisierungen für eine oder mehrere Apps möglicherweise im Hintergrund durchgeführt wurden",
"xWasPossiblyUpdatedToY": "{} wurde möglicherweise aktualisiert auf {}.", "xWasPossiblyUpdatedToY": "{} wurde möglicherweise aktualisiert auf {}.",
"enableBackgroundUpdates": "Aktiviere Hintergrundaktualisierungen", "enableBackgroundUpdates": "Aktiviere Hintergrundaktualisierungen",
"backgroundUpdateReqsExplanation": "Die Hintergrundaktualisierung ist möglicherweise nicht für alle Apps möglich.", "backgroundUpdateReqsExplanation": "Die Hintergrundaktualisierung ist möglicherweise nicht für alle Apps möglich.",
@ -268,7 +268,7 @@
"runBgCheckNow": "Hintergrundaktualisierungsprüfung jetzt durchführen", "runBgCheckNow": "Hintergrundaktualisierungsprüfung jetzt durchführen",
"versionExtractWholePage": "Versions-Extraktion per RegEx auf die gesamte Seite anwenden", "versionExtractWholePage": "Versions-Extraktion per RegEx auf die gesamte Seite anwenden",
"installing": "Installiere", "installing": "Installiere",
"skipUpdateNotifications": "Keine Benachrichtigung zu App-Updates geben", "skipUpdateNotifications": "Keine Benachrichtigung zu App-Aktualisierungen geben",
"updatesAvailableNotifChannel": "Aktualisierungen verfügbar", "updatesAvailableNotifChannel": "Aktualisierungen verfügbar",
"appsUpdatedNotifChannel": "Apps aktualisiert", "appsUpdatedNotifChannel": "Apps aktualisiert",
"appsPossiblyUpdatedNotifChannel": "App Aktualisierungen wurden versucht", "appsPossiblyUpdatedNotifChannel": "App Aktualisierungen wurden versucht",
@ -283,28 +283,31 @@
"parallelDownloads": "Erlaube parallele Downloads", "parallelDownloads": "Erlaube parallele Downloads",
"installMethod": "Installationsmethode", "installMethod": "Installationsmethode",
"normal": "Normal", "normal": "Normal",
"root": "Wurzel", "root": "Root",
"shizukuBinderNotFound": "Kompatibler Shizukudienst wurde nicht gefunden", "shizukuBinderNotFound": "Kompatibler Shizukudienst wurde nicht gefunden",
"useSystemFont": "Verwende die Systemschriftart", "useSystemFont": "Verwende die Systemschriftart",
"systemFontError": "Fehler beim Laden der Systemschriftart: {}", "systemFontError": "Fehler beim Laden der Systemschriftart: {}",
"useVersionCodeAsOSVersion": "Verwende die Appversion als erkannte Version vom Betriebssystem", "useVersionCodeAsOSVersion": "Verwende die Appversion als erkannte Version vom Betriebssystem",
"requestHeader": "Request Header", "requestHeader": "Request Header",
"useLatestAssetDateAsReleaseDate": "Den letzten Asset-Upload als Veröffentlichungsdatum verwenden", "useLatestAssetDateAsReleaseDate": "Den letzten Asset-Upload als Veröffentlichungsdatum verwenden",
"defaultPseudoVersioningMethod": "Standard-Pseudoversionierungsmethode", "defaultPseudoVersioningMethod": "Standardmäßiges Verfahren zur Pseudo-Versionierung",
"partialAPKHash": "Teilweiser APK-Hash", "partialAPKHash": "partieller APK-Hash",
"APKLinkHash": "APK-Link-Hash", "APKLinkHash": "APK-Link-Hash",
"directAPKLink": "Direkter APK-Link", "directAPKLink": "Direkter APK-Link",
"pseudoVersionInUse": "Eine Pseudoversion ist im Einsatz", "pseudoVersionInUse": "Es werden Pseudoversionen verwendet",
"installed": "Eingerichtet", "installed": "Installiert",
"latest": "Neueste", "latest": "Neueste Version",
"invertRegEx": "Regulären Ausdruck umkehren", "invertRegEx": "Regulären Ausdruck invertieren",
"note": "Hinweis",
"selfHostedNote": "Das „{}“-Dropdown-Menü kann verwendet werden, um selbst gehostete/angepasste Instanzen einer beliebigen Quelle zu erreichen.",
"badDownload": "Die APK konnte nicht geparst werden (inkompatibler oder teilweiser Download)",
"removeAppQuestion": { "removeAppQuestion": {
"one": "App entfernen?", "one": "App entfernen?",
"other": "Apps entfernen?" "other": "Apps entfernen?"
}, },
"tooManyRequestsTryAgainInMinutes": { "tooManyRequestsTryAgainInMinutes": {
"one": "Zu viele Anfragen (Rate begrenzt) versuchen Sie es in {} Minute erneut", "one": "Zu viele Anfragen (Rate begrenzt) versuche es in {} Minute erneut",
"other": "Zu viele Anfragen (Rate begrenzt) versuchen Sie es in {} Minuten erneut" "other": "Zu viele Anfragen (Rate begrenzt) versuche es in {} Minuten erneut"
}, },
"bgUpdateGotErrorRetryInMinutes": { "bgUpdateGotErrorRetryInMinutes": {
"one": "Bei der Aktualisierungsprüfung im Hintergrund wurde ein {} festgestellt, eine erneute Prüfung wird in {} Minute geplant", "one": "Bei der Aktualisierungsprüfung im Hintergrund wurde ein {} festgestellt, eine erneute Prüfung wird in {} Minute geplant",

View File

@ -80,7 +80,6 @@
"removeOutdatedFilter": "Remove Out-of-Date App Filter", "removeOutdatedFilter": "Remove Out-of-Date App Filter",
"showOutdatedOnly": "Show Out-of-Date Apps Only", "showOutdatedOnly": "Show Out-of-Date Apps Only",
"filter": "Filter", "filter": "Filter",
"filterActive": "Filter *",
"filterApps": "Filter Apps", "filterApps": "Filter Apps",
"appName": "App Name", "appName": "App Name",
"author": "Author", "author": "Author",
@ -298,6 +297,9 @@
"installed": "Installed", "installed": "Installed",
"latest": "Latest", "latest": "Latest",
"invertRegEx": "Invert regular expression", "invertRegEx": "Invert regular expression",
"note": "Note",
"selfHostedNote": "The \"{}\" dropdown can be used to reach self-hosted/custom instances of any source.",
"badDownload": "The APK could not be parsed (incompatible or partial download)",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Remove App?", "one": "Remove App?",
"other": "Remove Apps?" "other": "Remove Apps?"

View File

@ -1,7 +1,7 @@
{ {
"invalidURLForSource": "URL de la aplicación {} no válida", "invalidURLForSource": "URL de la aplicación {} no es válida",
"noReleaseFound": "No se ha podido encontrar una versión válida", "noReleaseFound": "No se ha podido encontrar una versión válida",
"noVersionFound": "No se ha podido determinar la versión de la publicación", "noVersionFound": "No se ha podido determinar la versión",
"urlMatchesNoSource": "La URL no coincide con ninguna fuente conocida", "urlMatchesNoSource": "La URL no coincide con ninguna fuente conocida",
"cantInstallOlderVersion": "No se puede instalar una versión previa de la aplicación", "cantInstallOlderVersion": "No se puede instalar una versión previa de la aplicación",
"appIdMismatch": "La ID del paquete descargado no coincide con la ID de la aplicación instalada", "appIdMismatch": "La ID del paquete descargado no coincide con la ID de la aplicación instalada",
@ -11,7 +11,7 @@
"unexpectedError": "Error inesperado", "unexpectedError": "Error inesperado",
"ok": "OK", "ok": "OK",
"and": "y", "and": "y",
"githubPATLabel": "Token GitHub de acceso personal\n(reduce tiempos de espera)", "githubPATLabel": "Token de acceso personal a GitHub\n(reduce tiempos de espera)",
"includePrereleases": "Incluir versiones preliminares", "includePrereleases": "Incluir versiones preliminares",
"fallbackToOlderReleases": "Retroceder a versiones previas", "fallbackToOlderReleases": "Retroceder a versiones previas",
"filterReleaseTitlesByRegEx": "Filtrar por título de versión", "filterReleaseTitlesByRegEx": "Filtrar por título de versión",
@ -22,20 +22,20 @@
"requiredInBrackets": "(Requerido)", "requiredInBrackets": "(Requerido)",
"dropdownNoOptsError": "ERROR: EL DESPLEGABLE DEBE TENER AL MENOS UNA OPCIÓN", "dropdownNoOptsError": "ERROR: EL DESPLEGABLE DEBE TENER AL MENOS UNA OPCIÓN",
"colour": "Color", "colour": "Color",
"githubStarredRepos": "Repositorios favoritos GitHub", "githubStarredRepos": "Repositorios favoritos en GitHub",
"uname": "Nombre de usuario", "uname": "Nombre de usuario",
"wrongArgNum": "Número de argumentos provistos inválido", "wrongArgNum": "Número de argumentos provistos inválido",
"xIsTrackOnly": "{} es de 'Sólo seguimiento'", "xIsTrackOnly": "{} es de 'sólo seguimiento'",
"source": "Origen", "source": "Origen",
"app": "Aplicación", "app": "Aplicación",
"appsFromSourceAreTrackOnly": "Las aplicaciones de este origen son de 'solo seguimiento'.", "appsFromSourceAreTrackOnly": "Las aplicaciones de este origen son de 'solo seguimiento'.",
"youPickedTrackOnly": "Debe seleccionar la opción de 'solo seguimiento'.", "youPickedTrackOnly": "Debe seleccionar la opción de 'solo seguimiento'.",
"trackOnlyAppDescription": "Se hará el seguimiento de actualizaciones para la aplicación, pero Obtainium no será capaz de descargarla o actalizarla.", "trackOnlyAppDescription": "Se hará el seguimiento de actualizaciones para la aplicación, pero Obtainium no será capaz de descargar o actualizarla.",
"cancelled": "Cancelado", "cancelled": "Cancelado",
"appAlreadyAdded": "Aplicación ya añadida", "appAlreadyAdded": "Aplicación añadida anteriormente",
"alreadyUpToDateQuestion": "¿Aplicación ya actualizada?", "alreadyUpToDateQuestion": "¿Aplicación actualizada previamente?",
"addApp": "Añadir Aplicación", "addApp": "Añadir Aplicación",
"appSourceURL": "URL de Origen de la Aplicación", "appSourceURL": "URL de origen de la aplicación",
"error": "Error", "error": "Error",
"add": "Añadir", "add": "Añadir",
"searchSomeSourcesLabel": "Buscar (solo algunas fuentes)", "searchSomeSourcesLabel": "Buscar (solo algunas fuentes)",
@ -71,11 +71,11 @@
"pinToTop": "Fijar arriba", "pinToTop": "Fijar arriba",
"unpinFromTop": "Desfijar de arriba", "unpinFromTop": "Desfijar de arriba",
"resetInstallStatusForSelectedAppsQuestion": "¿Restuarar estado de instalación para las aplicaciones seleccionadas?", "resetInstallStatusForSelectedAppsQuestion": "¿Restuarar estado de instalación para las aplicaciones seleccionadas?",
"installStatusOfXWillBeResetExplanation": "El estado de instalación de las aplicaciones seleccionadas será restaurado.\n\nEsto puede ser de útil cuando la versión de la aplicación mostrada en Obtainium es incorrecta por actualizaciones fallidas u otros motivos.", "installStatusOfXWillBeResetExplanation": "Se restaurará el estado de instalación de las aplicaciones seleccionadas.\n\nEsto puede ser de útil cuando la versión de la aplicación mostrada en Obtainium es incorrecta por actualizaciones fallidas u otros motivos.",
"customLinkMessage": "Estos enlaces funcionan en dispositivos con Obtainium instalado", "customLinkMessage": "Estos enlaces funcionan en dispositivos con Obtainium instalado",
"shareAppConfigLinks": "Compartir la configuración de la aplicación como enlace HTML", "shareAppConfigLinks": "Compartir la configuración de la aplicación como enlace HTML",
"shareSelectedAppURLs": "Compartir URLs de las aplicaciones seleccionadas", "shareSelectedAppURLs": "Compartir URLs de las aplicaciones seleccionadas",
"resetInstallStatus": "Restaurar Estado de Instalación", "resetInstallStatus": "Restaurar estado de instalación",
"more": "Más", "more": "Más",
"removeOutdatedFilter": "Elimiar filtro de aplicaciones desactualizado", "removeOutdatedFilter": "Elimiar filtro de aplicaciones desactualizado",
"showOutdatedOnly": "Mostrar solo aplicaciones desactualizadas", "showOutdatedOnly": "Mostrar solo aplicaciones desactualizadas",
@ -123,7 +123,7 @@
"neverManualOnly": "Nunca, solo manual", "neverManualOnly": "Nunca, solo manual",
"appearance": "Apariencia", "appearance": "Apariencia",
"showWebInAppView": "Mostrar vista de la web de origen", "showWebInAppView": "Mostrar vista de la web de origen",
"pinUpdates": "Fijar Actualizaciones al principio", "pinUpdates": "Fijar actualizaciones al principio",
"updates": "Actualizaciones", "updates": "Actualizaciones",
"sourceSpecific": "Fuente Específica", "sourceSpecific": "Fuente Específica",
"appSource": "Obtainium en GitHub", "appSource": "Obtainium en GitHub",
@ -140,77 +140,77 @@
"warning": "Aviso", "warning": "Aviso",
"sourceIsXButPackageFromYPrompt": "La fuente de la aplicación es '{}' pero el paquete de la actualización viene de '{}'. ¿Desea continuar?", "sourceIsXButPackageFromYPrompt": "La fuente de la aplicación es '{}' pero el paquete de la actualización viene de '{}'. ¿Desea continuar?",
"updatesAvailable": "Actualizaciones Disponibles", "updatesAvailable": "Actualizaciones Disponibles",
"updatesAvailableNotifDescription": "Notifica al usuario de que hay actualizaciones para una o más aplicaciones monitorizadas por Obtainium", "updatesAvailableNotifDescription": "Notifica al usuario de que hay actualizaciones para una o más aplicaciones monitoreadas por Obtainium",
"noNewUpdates": "No hay nuevas actualizaciones.", "noNewUpdates": "No hay nuevas actualizaciones.",
"xHasAnUpdate": "{} tiene una actualización.", "xHasAnUpdate": "{} tiene una actualización.",
"appsUpdated": "Aplicaciones Actualizadas", "appsUpdated": "Aplicaciones actualizadas",
"appsUpdatedNotifDescription": "Notifica al usuario de que una o más aplicaciones han sido actualizadas en segundo plano", "appsUpdatedNotifDescription": "Notifica al usuario de que una o más aplicaciones han sido actualizadas en segundo plano",
"xWasUpdatedToY": "{} ha sido actualizada a {}.", "xWasUpdatedToY": "{} ha sido actualizada a {}.",
"errorCheckingUpdates": "Error Buscando Actualizaciones", "errorCheckingUpdates": "Error buscando ectualizaciones",
"errorCheckingUpdatesNotifDescription": "Una notificación que muestra cuándo la comprobación de actualizaciones en segundo plano falla", "errorCheckingUpdatesNotifDescription": "Una notificación que muestra cuándo la comprobación de actualizaciones en segundo plano falla",
"appsRemoved": "Aplicaciones Eliminadas", "appsRemoved": "Aplicaciones eliminadas",
"appsRemovedNotifDescription": "Notifica al usuario que una o más aplicaciones fueron eliminadas por problemas al cargarlas", "appsRemovedNotifDescription": "Notifica al usuario que una o más aplicaciones fueron eliminadas por problemas al cargarlas",
"xWasRemovedDueToErrorY": "{} ha sido eliminada por: {}", "xWasRemovedDueToErrorY": "{} ha sido eliminada por: {}",
"completeAppInstallation": "Instalación Completa de la Aplicación", "completeAppInstallation": "Instalación completa de la aplicación",
"obtainiumMustBeOpenToInstallApps": "Obtainium debe estar abierto para instalar aplicaciones", "obtainiumMustBeOpenToInstallApps": "Obtainium debe estar abierto para instalar aplicaciones",
"completeAppInstallationNotifDescription": "Pide al usuario volver a Obtainium para terminar de instalar una aplicación", "completeAppInstallationNotifDescription": "Pide al usuario volver a Obtainium para terminar de instalar una aplicación",
"checkingForUpdates": "Buscando Actualizaciones", "checkingForUpdates": "Buscando actualizaciones...",
"checkingForUpdatesNotifDescription": "Notificación temporal que aparece al buscar actualizaciones", "checkingForUpdatesNotifDescription": "Notificación temporal que aparece al buscar actualizaciones",
"pleaseAllowInstallPerm": "Por favor, permita que Obtainium instale aplicaciones", "pleaseAllowInstallPerm": "Por favor, permita que Obtainium instale aplicaciones",
"trackOnly": "Solo Seguimiento", "trackOnly": "Solo para seguimiento",
"errorWithHttpStatusCode": "Error {}", "errorWithHttpStatusCode": "Error {}",
"versionCorrectionDisabled": "Corrección de versiones desactivada (el plugin parece no funcionar)", "versionCorrectionDisabled": "Corrección de versiones desactivada (el plugin parece no funcionar)",
"unknown": "Desconocido", "unknown": "Desconocido",
"none": "Ninguno", "none": "Ninguno",
"never": "Nunca", "never": "Nunca",
"latestVersionX": "Última Versión: {}", "latestVersionX": "Última versión: {}",
"installedVersionX": "Versión Instalada: {}", "installedVersionX": "Versión instalada: {}",
"lastUpdateCheckX": "Última Comprobación: {}", "lastUpdateCheckX": "Última comprobación: {}",
"remove": "Eliminar", "remove": "Eliminar",
"yesMarkUpdated": "Sí, Marcar como Actualizada", "yesMarkUpdated": "Sí, marcar como actualizada",
"fdroid": "Repositorio oficial F-Droid", "fdroid": "Repositorio oficial F-Droid",
"appIdOrName": "ID o Nombre de la Aplicación", "appIdOrName": "ID o Nombre de la Aplicación",
"appId": "ID de la Aplicación", "appId": "ID de la Aplicación",
"appWithIdOrNameNotFound": "No se han encontrado aplicaciones con esa ID o nombre", "appWithIdOrNameNotFound": "No se han encontrado aplicaciones con esa ID o nombre",
"reposHaveMultipleApps": "Los repositorios pueden contener varias aplicaciones", "reposHaveMultipleApps": "Los repositorios pueden contener varias aplicaciones",
"fdroidThirdPartyRepo": "Rpositorios de terceros F-Droid", "fdroidThirdPartyRepo": "Repositorio de tercera parte F-Droid",
"steamMobile": "Móvil de vapor", "steamMobile": "Móvil de vapor",
"steamChat": "Chat de vapor", "steamChat": "Chat de vapor",
"install": "Instalar", "install": "Instalar",
"markInstalled": "Marcar como Instalada", "markInstalled": "Marcar como instalada",
"update": "Actualizar", "update": "Actualizar",
"markUpdated": "Marcar como Actualizada", "markUpdated": "Marcar como actualizada",
"additionalOptions": "Opciones Adicionales", "additionalOptions": "Opciones adicionales",
"disableVersionDetection": "Descativar Detección de Versiones", "disableVersionDetection": "Desactivar la detección de versiones",
"noVersionDetectionExplanation": "Esta opción solo se debe usar en aplicaciones en las que la deteción de versiones pueda no funcionar correctamente.", "noVersionDetectionExplanation": "Esta opción solo se debe usar en aplicaciones en las que la deteción de versiones pueda que no funcionar correctamente.",
"downloadingX": "Descargando {}", "downloadingX": "Descargando {}",
"downloadNotifDescription": "Notifica al usuario del progreso de descarga de una aplicación", "downloadNotifDescription": "Notifica al usuario del progreso de descarga de una aplicación",
"noAPKFound": "APK no encontrada", "noAPKFound": "No se encontró el paquete de instalación APK",
"noVersionDetection": "Sin detección de versiones", "noVersionDetection": "Sin detección de versiones",
"categorize": "Catogorizar", "categorize": "Catogorizar",
"categories": "Categorías", "categories": "Categorías",
"category": "Categoría", "category": "Categoría",
"noCategory": "Sin Categoría", "noCategory": "Sin categoría",
"noCategories": "Sin Categorías", "noCategories": "Sin categorías",
"deleteCategoriesQuestion": "¿Eliminar Categorías?", "deleteCategoriesQuestion": "¿Eliminar categorías?",
"categoryDeleteWarning": "Todas las aplicaciones en las categorías eliminadas serán marcadas como 'Sin Categoría'.", "categoryDeleteWarning": "Todas las aplicaciones en las categorías eliminadas serán marcadas como 'Sin categoría'.",
"addCategory": "Añadir Categoría", "addCategory": "Añadir categoría",
"label": "Nombre", "label": "Nombre",
"language": "Idioma", "language": "Idioma",
"copiedToClipboard": "Copiado al Portapapeles", "copiedToClipboard": "Copiado al portapapeles",
"storagePermissionDenied": "Permiso de Almacenamiento rechazado", "storagePermissionDenied": "Permiso de almacenamiento rechazado",
"selectedCategorizeWarning": "Esto reemplazará cualquier ajuste de categoría para las aplicaciones seleccionadas.", "selectedCategorizeWarning": "Esto reemplazará cualquier ajuste de categoría para las aplicaciones seleccionadas.",
"filterAPKsByRegEx": "Filtrar por APKs", "filterAPKsByRegEx": "Filtrar por APKs",
"removeFromObtainium": "Eliminar de Obtainium", "removeFromObtainium": "Eliminar de Obtainium",
"uninstallFromDevice": "Desinstalar del Dispositivo", "uninstallFromDevice": "Desinstalar del dispositivo",
"onlyWorksWithNonVersionDetectApps": "Solo funciona para aplicaciones con la detección de versiones desactivada.", "onlyWorksWithNonVersionDetectApps": "Solo funciona para aplicaciones con la detección de versiones desactivada.",
"releaseDateAsVersion": "Por fecha de publicación", "releaseDateAsVersion": "Por fecha de publicación",
"releaseDateAsVersionExplanation": "Esta opción solo se debería usar con aplicaciones en las que la detección de versiones no funciona pero hay disponible una fecha de publicación.", "releaseDateAsVersionExplanation": "Esta opción solo se debería usar con aplicaciones en las que la detección de versiones no funciona pero hay disponible una fecha de publicación.",
"changes": "Cambios", "changes": "Cambios",
"releaseDate": "Fecha de Publicación", "releaseDate": "Fecha de publicación",
"importFromURLsInFile": "Importar URLs desde archivo (como OPML)", "importFromURLsInFile": "Importar URLs desde archivo (como OPML)",
"versionDetectionExplanation": "Conciliar la cadena de versión con la versión detectada desde el sistema operativo", "versionDetectionExplanation": "Conciliar la cadena de versión con la versión detectada desde el sistema operativo",
"versionDetection": "Detección de Versiones", "versionDetection": "Detección de versiones",
"standardVersionDetection": "Por versión", "standardVersionDetection": "Por versión",
"groupByCategory": "Agrupar por categoría", "groupByCategory": "Agrupar por categoría",
"autoApkFilterByArch": "Filtrar APKs por arquitectura del procesador (si es posible)", "autoApkFilterByArch": "Filtrar APKs por arquitectura del procesador (si es posible)",
@ -219,25 +219,25 @@
"dontShowTrackOnlyWarnings": "No mostrar avisos sobre apps en 'solo seguimiento'", "dontShowTrackOnlyWarnings": "No mostrar avisos sobre apps en 'solo seguimiento'",
"dontShowAPKOriginWarnings": "No mostrar avisos sobre las fuentes de las APKs", "dontShowAPKOriginWarnings": "No mostrar avisos sobre las fuentes de las APKs",
"moveNonInstalledAppsToBottom": "Mover Apps no instaladas al final", "moveNonInstalledAppsToBottom": "Mover Apps no instaladas al final",
"gitlabPATLabel": "Token GitLab de acceso personal\n(habilita la búsqueda y mejor detección de APKs)", "gitlabPATLabel": "Token de acceso personal a GitLab\n(habilita la búsqueda y mejor detección de APKs)",
"about": "Acerca", "about": "Acerca",
"requiresCredentialsInSettings": "{}: Esto requiere credenciales adicionales (en ajustes)", "requiresCredentialsInSettings": "{}: Esto requiere credenciales adicionales (en ajustes)",
"checkOnStart": "Comprobar actualizaciones al inicio", "checkOnStart": "Comprobar actualizaciones al inicio",
"tryInferAppIdFromCode": "Intentar deducir la ID de la app por el código fuente", "tryInferAppIdFromCode": "Intentar deducir la ID de la app por el código fuente",
"removeOnExternalUninstall": "Auto eliminar apps desinstaladas externamente", "removeOnExternalUninstall": "Auto eliminar apps desinstaladas externamente",
"pickHighestVersionCode": "Auto selección versión superior del código APK", "pickHighestVersionCode": "Auto selección de versión superior del paquete APK",
"checkUpdateOnDetailPage": "Comprobar actualizaciones al abrir detalles de la app", "checkUpdateOnDetailPage": "Comprobar actualizaciones al abrir detalles de la app",
"disablePageTransitions": "Deshabilitar animaciones de transición", "disablePageTransitions": "Deshabilitar animaciones de transición",
"reversePageTransitions": "Invertir animaciones de transición", "reversePageTransitions": "Invertir animaciones de transición",
"minStarCount": "Número Mínimo de Estrellas", "minStarCount": "Número Mínimo de Estrellas",
"addInfoBelow": "Añadir esta información debajo.", "addInfoBelow": "Añadir esta información debajo.",
"addInfoInSettings": "Puede añadir esta información en Ajustes.", "addInfoInSettings": "Puede añadir esta información en Ajustes.",
"githubSourceNote": "La limitación de velocidad de GitHub puede evitarse con una clave API.", "githubSourceNote": "La limitación de velocidad de GitHub puede evitarse con un 'token de acceso personal'.",
"gitlabSourceNote": "La extracción de APK de GitLab podría no funcionar sin una clave API.", "gitlabSourceNote": "La extracción de APK de GitLab podría no funcionar sin un 'token de acceso personal'.",
"sortByLastLinkSegment": "Ordenar sólo por el último segmento del enlace", "sortByLastLinkSegment": "Ordenar sólo por el último segmento del enlace",
"filterReleaseNotesByRegEx": "Filtrar por notas de versión (release notes)", "filterReleaseNotesByRegEx": "Filtrar por notas de versión (release notes)",
"customLinkFilterRegex": "Filtro personalizado de Enlace APK (por defecto '.apk$')", "customLinkFilterRegex": "Filtro personalizado de enlace APK (por defecto '.apk$')",
"appsPossiblyUpdated": "Actualización de Apps intentada", "appsPossiblyUpdated": "Actualización de apps intentada",
"appsPossiblyUpdatedNotifDescription": "Notifica al usuario que las actualizaciones en segundo plano podrían haberse realizado para una o más aplicaciones", "appsPossiblyUpdatedNotifDescription": "Notifica al usuario que las actualizaciones en segundo plano podrían haberse realizado para una o más aplicaciones",
"xWasPossiblyUpdatedToY": "{} podría estar actualizada a {}.", "xWasPossiblyUpdatedToY": "{} podría estar actualizada a {}.",
"enableBackgroundUpdates": "Habilitar actualizaciones en segundo plano", "enableBackgroundUpdates": "Habilitar actualizaciones en segundo plano",
@ -250,16 +250,16 @@
"intermediateLink": "Enlace intermedio", "intermediateLink": "Enlace intermedio",
"exemptFromBackgroundUpdates": "Exenta de actualizciones en segundo plano (si están habilitadas)", "exemptFromBackgroundUpdates": "Exenta de actualizciones en segundo plano (si están habilitadas)",
"bgUpdatesOnWiFiOnly": "Deshabilitar las actualizaciones en segundo plano sin WiFi", "bgUpdatesOnWiFiOnly": "Deshabilitar las actualizaciones en segundo plano sin WiFi",
"autoSelectHighestVersionCode": "Auto Selección de la versionCode APK superior", "autoSelectHighestVersionCode": "Auto selección del paquete APK con versión más reciente",
"versionExtractionRegEx": "Versión de extracción regex", "versionExtractionRegEx": "Versión de extracción regex",
"matchGroupToUse": "Grupo a usar para versión de extracción regex", "matchGroupToUse": "Grupo a usar para versión de extracción regex",
"highlightTouchTargets": "Resaltar objetivos menos obvios", "highlightTouchTargets": "Resaltar objetivos menos obvios",
"pickExportDir": "Directorio para Exportar", "pickExportDir": "Directorio para exportar",
"autoExportOnChanges": "Auto Exportar cuando haya cambios", "autoExportOnChanges": "Auto exportar cuando haya cambios",
"includeSettings": "Incluir ajustes", "includeSettings": "Incluir ajustes",
"filterVersionsByRegEx": "Filtrar por Versiones", "filterVersionsByRegEx": "Filtrar por versiones",
"trySelectingSuggestedVersionCode": "Pruebe seleccionando la versionCode APK sugerida", "trySelectingSuggestedVersionCode": "Pruebe seleccionando la versión del paquete APK sugerida",
"dontSortReleasesList": "Mantener el order de publicación desde API", "dontSortReleasesList": "Mantener el order de publicación de la fuente original",
"reverseSort": "Orden inverso", "reverseSort": "Orden inverso",
"takeFirstLink": "Usar primer enlace", "takeFirstLink": "Usar primer enlace",
"skipSort": "Omitir orden", "skipSort": "Omitir orden",
@ -284,10 +284,10 @@
"installMethod": "Método de instalación", "installMethod": "Método de instalación",
"normal": "Normal", "normal": "Normal",
"root": "Raíz", "root": "Raíz",
"shizukuBinderNotFound": "Shizuku no está operativo", "shizukuBinderNotFound": "Shizuku no funciona",
"useSystemFont": "Usar la fuente del sistema", "useSystemFont": "Usar la fuente de impresión del sistema",
"systemFontError": "Error al cargar la fuente del sistema: {}", "systemFontError": "Error al cargar la fuente de impresión del sistema: {}",
"useVersionCodeAsOSVersion": "Usar el código de versión de la aplicación como versión detectada por el sistema operativo", "useVersionCodeAsOSVersion": "Usar la versión de la aplicación como versión detectada por el sistema operativo",
"requestHeader": "Encabezado de solicitud", "requestHeader": "Encabezado de solicitud",
"useLatestAssetDateAsReleaseDate": "Usar la última carga de recursos como fecha de lanzamiento", "useLatestAssetDateAsReleaseDate": "Usar la última carga de recursos como fecha de lanzamiento",
"defaultPseudoVersioningMethod": "Método de pseudoversionado predeterminado", "defaultPseudoVersioningMethod": "Método de pseudoversionado predeterminado",
@ -296,8 +296,11 @@
"directAPKLink": "Enlace APK directo", "directAPKLink": "Enlace APK directo",
"pseudoVersionInUse": "Se está utilizando una pseudoversión", "pseudoVersionInUse": "Se está utilizando una pseudoversión",
"installed": "Instalado", "installed": "Instalado",
"latest": "El último", "latest": "Versión más reciente",
"invertRegEx": "Invertir expresión regular", "invertRegEx": "Invertir expresión regular",
"note": "Nota",
"selfHostedNote": "El desplegable \"{}\" puede utilizarse para acceder a instancias autoalojadas/personalizadas de cualquier fuente.",
"badDownload": "No se ha podido analizar el APK (incompatible o descarga parcial)",
"removeAppQuestion": { "removeAppQuestion": {
"one": "¿Eliminar Aplicación?", "one": "¿Eliminar Aplicación?",
"other": "¿Eliminar Aplicaciones?" "other": "¿Eliminar Aplicaciones?"

View File

@ -298,6 +298,9 @@
"installed": "نصب شده است", "installed": "نصب شده است",
"latest": "آخرین", "latest": "آخرین",
"invertRegEx": "معکوس کردن عبارت منظم", "invertRegEx": "معکوس کردن عبارت منظم",
"note": "Note",
"selfHostedNote": "The \"{}\" dropdown can be used to reach self-hosted/custom instances of any source.",
"badDownload": "The APK could not be parsed (incompatible or partial download)",
"removeAppQuestion": { "removeAppQuestion": {
"one": "برنامه حذف شود؟", "one": "برنامه حذف شود؟",
"other": "برنامه ها حذف شوند؟" "other": "برنامه ها حذف شوند؟"

View File

@ -298,6 +298,9 @@
"installed": "Installée", "installed": "Installée",
"latest": "Dernier", "latest": "Dernier",
"invertRegEx": "Inverser l'expression régulière", "invertRegEx": "Inverser l'expression régulière",
"note": "Note",
"selfHostedNote": "La liste déroulante \"{}\" peut être utilisée pour accéder aux instances auto-hébergées/personnalisées de n'importe quelle source.",
"badDownload": "L'APK n'a pas pu être analysé (téléchargement incompatible ou partiel)",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Supprimer l'application ?", "one": "Supprimer l'application ?",
"other": "Supprimer les applications ?" "other": "Supprimer les applications ?"

View File

@ -287,7 +287,7 @@
"shizukuBinderNotFound": "A Shizuku nem fut", "shizukuBinderNotFound": "A Shizuku nem fut",
"useSystemFont": "Használja a rendszer betűtípusát", "useSystemFont": "Használja a rendszer betűtípusát",
"systemFontError": "Hiba a rendszer betűtípusának betöltésekor: {}", "systemFontError": "Hiba a rendszer betűtípusának betöltésekor: {}",
"useVersionCodeAsOSVersion": "Az app versionCode használata a rendszer által észlelt verzióként", "useVersionCodeAsOSVersion": "Az app verziókód használata a rendszer által észlelt verzióként",
"requestHeader": "Kérelem fejléc", "requestHeader": "Kérelem fejléc",
"useLatestAssetDateAsReleaseDate": "Használja a legújabb tartalomfeltöltést megjelenési dátumként", "useLatestAssetDateAsReleaseDate": "Használja a legújabb tartalomfeltöltést megjelenési dátumként",
"defaultPseudoVersioningMethod": "Alapértelmezett álversziós módszer", "defaultPseudoVersioningMethod": "Alapértelmezett álversziós módszer",
@ -298,6 +298,9 @@
"installed": "Telepített", "installed": "Telepített",
"latest": "Legújabb", "latest": "Legújabb",
"invertRegEx": "Invertált reguláris kifejezés", "invertRegEx": "Invertált reguláris kifejezés",
"note": "Megjegyzés:",
"selfHostedNote": "A \"{}\" legördülő menü használható bármely forrás saját üzemeltetésű/egyéni példányainak eléréséhez.",
"badDownload": "Az APK-t nem lehetett elemezni (inkompatibilis vagy részleges letöltés)",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Eltávolítja az alkalmazást?", "one": "Eltávolítja az alkalmazást?",
"other": "Eltávolítja az alkalmazást?" "other": "Eltávolítja az alkalmazást?"

View File

@ -111,7 +111,7 @@
"dark": "Scuro", "dark": "Scuro",
"light": "Chiaro", "light": "Chiaro",
"followSystem": "Segui il sistema", "followSystem": "Segui il sistema",
"useBlackTheme": "Usa il tema Nero puro", "useBlackTheme": "Usa il tema nero puro",
"appSortBy": "App ordinate per", "appSortBy": "App ordinate per",
"authorName": "Autore/Nome", "authorName": "Autore/Nome",
"nameAuthor": "Nome/Autore", "nameAuthor": "Nome/Autore",
@ -283,13 +283,13 @@
"parallelDownloads": "Permetti download paralleli", "parallelDownloads": "Permetti download paralleli",
"installMethod": "Metodo d'installazione", "installMethod": "Metodo d'installazione",
"normal": "Normale", "normal": "Normale",
"root": "Radice", "root": "Root",
"shizukuBinderNotFound": "Shizuku non è in esecuzione", "shizukuBinderNotFound": "Shizuku non è in esecuzione",
"useSystemFont": "Utilizza il carattere di sistema", "useSystemFont": "Usa i caratteri di sistema",
"systemFontError": "Errore durante il caricamento del carattere di sistema: {}", "systemFontError": "Errore durante il caricamento dei caratteri di sistema: {}",
"useVersionCodeAsOSVersion": "Utilizza il codice versione dell'app come versione rilevata dal sistema operativo", "useVersionCodeAsOSVersion": "Usa il codice versione dell'app come versione rilevata dal sistema operativo",
"requestHeader": "Intestazione della richiesta", "requestHeader": "Intestazione della richiesta",
"useLatestAssetDateAsReleaseDate": "Utilizza l'ultimo caricamento della risorsa come data di rilascio", "useLatestAssetDateAsReleaseDate": "Usa l'ultimo caricamento della risorsa come data di rilascio",
"defaultPseudoVersioningMethod": "Metodo di pseudoversione predefinito", "defaultPseudoVersioningMethod": "Metodo di pseudoversione predefinito",
"partialAPKHash": "Hash APK parziale", "partialAPKHash": "Hash APK parziale",
"APKLinkHash": "Hash collegamento APK", "APKLinkHash": "Hash collegamento APK",
@ -298,6 +298,9 @@
"installed": "Installato", "installed": "Installato",
"latest": "Ultimo", "latest": "Ultimo",
"invertRegEx": "Inverti espressione regolare", "invertRegEx": "Inverti espressione regolare",
"note": "Nota",
"selfHostedNote": "Il menu a tendina \"{}\" può essere usato per raggiungere istanze autogestite/personali di qualsiasi fonte.",
"badDownload": "Non è stato possibile analizzare l'APK (download incompatibile o parziale).",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Rimuovere l'app?", "one": "Rimuovere l'app?",
"other": "Rimuovere le app?" "other": "Rimuovere le app?"

View File

@ -168,14 +168,14 @@
"lastUpdateCheckX": "最終アップデート確認: {}", "lastUpdateCheckX": "最終アップデート確認: {}",
"remove": "削除", "remove": "削除",
"yesMarkUpdated": "はい、アップデート済みとしてマークします", "yesMarkUpdated": "はい、アップデート済みとしてマークします",
"fdroid": "F-ドロイドオフィシャル", "fdroid": "F-Droid公式",
"appIdOrName": "アプリのIDまたは名前", "appIdOrName": "アプリのIDまたは名前",
"appId": "アプリID", "appId": "アプリID",
"appWithIdOrNameNotFound": "そのIDや名前を持つアプリは見つかりませんでした", "appWithIdOrNameNotFound": "そのIDや名前を持つアプリは見つかりませんでした",
"reposHaveMultipleApps": "リポジトリには複数のアプリが含まれることがあります", "reposHaveMultipleApps": "リポジトリには複数のアプリが含まれることがあります",
"fdroidThirdPartyRepo": "F-Droid サードパーティリポジトリ", "fdroidThirdPartyRepo": "F-Droid サードパーティリポジトリ",
"steamMobile": "スチームモバイル", "steamMobile": "Steamモバイル",
"steamChat": "スチームチャット", "steamChat": "Steamチャット",
"install": "インストール", "install": "インストール",
"markInstalled": "インストール済みとしてマークする", "markInstalled": "インストール済みとしてマークする",
"update": "アップデート", "update": "アップデート",
@ -209,7 +209,7 @@
"changes": "変更点", "changes": "変更点",
"releaseDate": "リリース日", "releaseDate": "リリース日",
"importFromURLsInFile": "ファイルOPMLなど内のURLからインポート", "importFromURLsInFile": "ファイルOPMLなど内のURLからインポート",
"versionDetectionExplanation": "バージョン文字列とOSから検出されたバージョンを一致させます", "versionDetectionExplanation": "バージョン文字列とOSから検出されたバージョンを照合する",
"versionDetection": "バージョン検出", "versionDetection": "バージョン検出",
"standardVersionDetection": "標準のバージョン検出", "standardVersionDetection": "標準のバージョン検出",
"groupByCategory": "カテゴリ別にグループ化する", "groupByCategory": "カテゴリ別にグループ化する",
@ -283,21 +283,24 @@
"parallelDownloads": "並行ダウンロードを許可する", "parallelDownloads": "並行ダウンロードを許可する",
"installMethod": "インストール方法", "installMethod": "インストール方法",
"normal": "通常", "normal": "通常",
"root": "", "root": "Root",
"shizukuBinderNotFound": "Shizukuが起動していません", "shizukuBinderNotFound": "Shizukuが起動していません",
"useSystemFont": "システムフォントを使用する", "useSystemFont": "システムフォントを使用する",
"systemFontError": "システムフォントの読み込みエラー: {}", "systemFontError": "システムフォントの読み込みエラー: {}",
"useVersionCodeAsOSVersion": "アプリの versionCode を OS で検出されたバージョンとして使用する", "useVersionCodeAsOSVersion": "アプリのバージョンコードをOSで検出されたバージョンとして使用する",
"requestHeader": "リクエストヘッダー", "requestHeader": "リクエストヘッダー",
"useLatestAssetDateAsReleaseDate": "最新のアセットアップロードをリリース日として使用", "useLatestAssetDateAsReleaseDate": "最新のアセットアップロードをリリース日として使用する",
"defaultPseudoVersioningMethod": "デフォルトの疑似バージョン管理方法", "defaultPseudoVersioningMethod": "デフォルトの疑似バージョン管理方法",
"partialAPKHash": "部分的なAPKハッシュ", "partialAPKHash": "部分的なAPKハッシュ",
"APKLinkHash": "APKリンクハッシュ", "APKLinkHash": "APKリンクハッシュ",
"directAPKLink": "APK ダイレクトリンク", "directAPKLink": "APKダイレクトリンク",
"pseudoVersionInUse": "疑似バージョンが使用されています", "pseudoVersionInUse": "疑似バージョンが使用されています",
"installed": "インストールされました", "installed": "インストール済み",
"latest": "最新", "latest": "最新",
"invertRegEx": "正規表現を反転", "invertRegEx": "正規表現を反転",
"note": "注",
"selfHostedNote": "ドロップダウン\"{}\"を使用すると、あらゆるソースのセルフホスト/カスタムインスタンスにアクセスできます。",
"badDownload": "APK を解析できませんでした(互換性がないか、部分的にダウンロードされています)。",
"removeAppQuestion": { "removeAppQuestion": {
"one": "アプリを削除しますか?", "one": "アプリを削除しますか?",
"other": "アプリを削除しますか?" "other": "アプリを削除しますか?"

View File

@ -298,6 +298,9 @@
"installed": "Geïnstalleerd", "installed": "Geïnstalleerd",
"latest": "Laatste", "latest": "Laatste",
"invertRegEx": "Reguliere expressie omkeren", "invertRegEx": "Reguliere expressie omkeren",
"note": "Opmerking",
"selfHostedNote": "De \"{}\" dropdown kan gebruikt worden om zelf gehoste/aangepaste instanties van elke bron te bereiken.",
"badDownload": "De APK kon niet worden verwerkt (incompatibele of gedeeltelijke download)",
"removeAppQuestion": { "removeAppQuestion": {
"one": "App verwijderen?", "one": "App verwijderen?",
"other": "Apps verwijderen?" "other": "Apps verwijderen?"

View File

@ -298,6 +298,9 @@
"installed": "Zainstalowano", "installed": "Zainstalowano",
"latest": "Najnowszy", "latest": "Najnowszy",
"invertRegEx": "Odwróć wyrażenie regularne", "invertRegEx": "Odwróć wyrażenie regularne",
"note": "Uwaga",
"selfHostedNote": "Lista rozwijana \"{}\" może być używana do uzyskiwania dostępu do samodzielnie hostowanych / niestandardowych instancji dowolnego źródła.",
"badDownload": "Nie można przeanalizować pliku APK (niekompatybilny lub częściowo pobrany).",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Usunąć aplikację?", "one": "Usunąć aplikację?",
"few": "Usunąć aplikacje?", "few": "Usunąć aplikacje?",

View File

@ -2,7 +2,7 @@
"invalidURLForSource": "URL {} inválida", "invalidURLForSource": "URL {} inválida",
"noReleaseFound": "Não foi possível encontrar uma versão adequada", "noReleaseFound": "Não foi possível encontrar uma versão adequada",
"noVersionFound": "Não foi possível encontrar uma versão", "noVersionFound": "Não foi possível encontrar uma versão",
"urlMatchesNoSource": "URL não corresponde a uma fonte conhecida", "urlMatchesNoSource": "A URL não corresponde a uma fonte conhecida",
"cantInstallOlderVersion": "Não é permitido instalar uma versão anterior de um aplicativo", "cantInstallOlderVersion": "Não é permitido instalar uma versão anterior de um aplicativo",
"appIdMismatch": "ID do pacote baixado não é igual ao ID do aplicativo instalado", "appIdMismatch": "ID do pacote baixado não é igual ao ID do aplicativo instalado",
"functionNotImplemented": "Esta classe não implementou essa função", "functionNotImplemented": "Esta classe não implementou essa função",
@ -11,10 +11,10 @@
"unexpectedError": "Erro inesperado", "unexpectedError": "Erro inesperado",
"ok": "OK", "ok": "OK",
"and": "e", "and": "e",
"githubPATLabel": "Token de acesso pessoal do GitHub (Reduz tempos de espera)", "githubPATLabel": "Token de acesso pessoal do GitHub\n(Reduz tempos de espera)",
"includePrereleases": "Incluir pré-lançamentos", "includePrereleases": "Incluir pré-lançamentos",
"fallbackToOlderReleases": "Retornar para versões anteriores", "fallbackToOlderReleases": "Retornar para versões anteriores",
"filterReleaseTitlesByRegEx": "Filtrar títulos de versões por expressão regular", "filterReleaseTitlesByRegEx": "Filtrar títulos de versões usando expressão regular",
"invalidRegEx": "Expressão regular inválida", "invalidRegEx": "Expressão regular inválida",
"noDescription": "Sem descrição", "noDescription": "Sem descrição",
"cancel": "Cancelar", "cancel": "Cancelar",
@ -22,7 +22,7 @@
"requiredInBrackets": "(Necessário)", "requiredInBrackets": "(Necessário)",
"dropdownNoOptsError": "ERRO: O DROPDOWN DEVE TER PELO MENOS UMA OPÇÃO", "dropdownNoOptsError": "ERRO: O DROPDOWN DEVE TER PELO MENOS UMA OPÇÃO",
"colour": "Cor", "colour": "Cor",
"githubStarredRepos": "Favoritados no GitHub", "githubStarredRepos": "repositórios favoritos no GitHub",
"uname": "Nome de usuário", "uname": "Nome de usuário",
"wrongArgNum": "Número de argumentos errado", "wrongArgNum": "Número de argumentos errado",
"xIsTrackOnly": "{} é 'Apenas monitorar'", "xIsTrackOnly": "{} é 'Apenas monitorar'",
@ -38,12 +38,12 @@
"appSourceURL": "URL de origem do aplicativo", "appSourceURL": "URL de origem do aplicativo",
"error": "Erro", "error": "Erro",
"add": "Adicionar", "add": "Adicionar",
"searchSomeSourcesLabel": "Procurar (Apenas algumas fontes)", "searchSomeSourcesLabel": "Procurar (apenas algumas fontes)",
"search": "Procurar", "search": "Procurar",
"additionalOptsFor": "Opções adicionais para {}", "additionalOptsFor": "Opções adicionais para {}",
"supportedSources": "Fontes compatíveis", "supportedSources": "Fontes compatíveis",
"trackOnlyInBrackets": "(Apenas monitorar)", "trackOnlyInBrackets": "(apenas monitorar)",
"searchableInBrackets": "(Pesquisável)", "searchableInBrackets": "(pesquisável)",
"appsString": "Aplicativos", "appsString": "Aplicativos",
"noApps": "Não há aplicativos", "noApps": "Não há aplicativos",
"noAppsForFilter": "Sem aplicativos para filtrar", "noAppsForFilter": "Sem aplicativos para filtrar",
@ -70,12 +70,12 @@
"markSelectedAppsUpdated": "Marcar aplicativos selecionados como Atualizados", "markSelectedAppsUpdated": "Marcar aplicativos selecionados como Atualizados",
"pinToTop": "Fixar no topo", "pinToTop": "Fixar no topo",
"unpinFromTop": "Desafixar do topo", "unpinFromTop": "Desafixar do topo",
"resetInstallStatusForSelectedAppsQuestion": "Reiniciar status de instalação para aplicativos selecionados?", "resetInstallStatusForSelectedAppsQuestion": "Reiniciar status de instalação nos aplicativos selecionados?",
"installStatusOfXWillBeResetExplanation": "O status de instalação de qualquer aplicativo selecionado será reiniciado.\n\nIsso pode ajudar quando uma versão de um aplicativo mostrada no Obtainium é incorreta devido a falhas ao atualizar ou outros problemas.", "installStatusOfXWillBeResetExplanation": "O status de instalação de todos os aplicativos selecionados será reiniciado.\n\nIsso pode ajudar quando uma versão de um aplicativo mostrada no Obtainium é incorreta devido a falhas ao atualizar ou outros problemas.",
"customLinkMessage": "Esses links funcionam em dispositivos com o Obtainium instalado", "customLinkMessage": "Esses links funcionam em dispositivos com o Obtainium instalado",
"shareAppConfigLinks": "Compartilhar configuração do aplicativo como link HTML", "shareAppConfigLinks": "Compartilhar configuração do aplicativo como link HTML",
"shareSelectedAppURLs": "Compartilhar URLs de aplicativos selecionados", "shareSelectedAppURLs": "Compartilhar URLs de aplicativos selecionados",
"resetInstallStatus": "Reiniciar status de Iistalação", "resetInstallStatus": "Reiniciar status de instalação",
"more": "Mais", "more": "Mais",
"removeOutdatedFilter": "Remover filtro de aplicativos desatualizados", "removeOutdatedFilter": "Remover filtro de aplicativos desatualizados",
"showOutdatedOnly": "Mostrar apenas aplicativos desatualizados", "showOutdatedOnly": "Mostrar apenas aplicativos desatualizados",
@ -84,20 +84,20 @@
"filterApps": "Filtrar aplicativos", "filterApps": "Filtrar aplicativos",
"appName": "Nome do aplicativo", "appName": "Nome do aplicativo",
"author": "Autor", "author": "Autor",
"upToDateApps": "Aplicativos tualizados", "upToDateApps": "Aplicativos atualizados",
"nonInstalledApps": "Aplicativos não instalados", "nonInstalledApps": "Aplicativos não instalados",
"importExport": "Importar/Exportar", "importExport": "Importar/Exportar",
"settings": "Configurações", "settings": "Configurações",
"exportedTo": "Exportado para {}", "exportedTo": "Exportado para {}",
"obtainiumExport": "Exportar Obtainium", "obtainiumExport": "Exportar dados do Obtainium",
"invalidInput": "Input Inválido", "invalidInput": "Entrada inválida",
"importedX": "Importado {}", "importedX": "Importado {}",
"obtainiumImport": "Importar Obtainium", "obtainiumImport": "Importar dados do Obtainium",
"importFromURLList": "Importar de lista de URLs", "importFromURLList": "Importar de lista de URLs",
"searchQuery": "Pesquisa", "searchQuery": "Pesquisa",
"appURLList": "Lista de URLs de aplicativos", "appURLList": "Lista de URLs de aplicativos",
"line": "Linha", "line": "Linha",
"searchX": "Pesquisa {}", "searchX": "Pesquisar na/o {}",
"noResults": "Nenhum resultado encontrado", "noResults": "Nenhum resultado encontrado",
"importX": "Importar {}", "importX": "Importar {}",
"importedAppsIdDisclaimer": "Aplicativos Importados podem ser mostrados incorretamente como \"Não Instalado\".\nPara consertar, reinstale-os usando o Obtainium.\nIsso não deve afetar dados do aplicativo.\n\nAfeta apenas métodos de importação de URL e de terceiros.", "importedAppsIdDisclaimer": "Aplicativos Importados podem ser mostrados incorretamente como \"Não Instalado\".\nPara consertar, reinstale-os usando o Obtainium.\nIsso não deve afetar dados do aplicativo.\n\nAfeta apenas métodos de importação de URL e de terceiros.",
@ -110,8 +110,8 @@
"theme": "Tema", "theme": "Tema",
"dark": "Escuro", "dark": "Escuro",
"light": "Claro", "light": "Claro",
"followSystem": "Seguir o sistema", "followSystem": "Padrão do sistema",
"useBlackTheme": "Usar tema preto completamente escuro", "useBlackTheme": "Usar tema preto AMOLED",
"appSortBy": "Classificar aplicativo por", "appSortBy": "Classificar aplicativo por",
"authorName": "Autor/Nome", "authorName": "Autor/Nome",
"nameAuthor": "Nome/Autor", "nameAuthor": "Nome/Autor",
@ -122,10 +122,10 @@
"bgUpdateCheckInterval": "Intervalo de verificação de atualizações em segundo-plano", "bgUpdateCheckInterval": "Intervalo de verificação de atualizações em segundo-plano",
"neverManualOnly": "Nunca - apenas manual", "neverManualOnly": "Nunca - apenas manual",
"appearance": "Aparência", "appearance": "Aparência",
"showWebInAppView": "Mostrar página da internet em informações do aplicativo", "showWebInAppView": "Mostrar página web do aplicativo em informações do aplicativo",
"pinUpdates": "Fixar atualizações no topo da janela de aplicativos", "pinUpdates": "Fixar atualizações no topo da janela de aplicativos",
"updates": "Atualizações", "updates": "Atualizações",
"sourceSpecific": "Específico a fonte", "sourceSpecific": "Token de acesso",
"appSource": "Fonte do aplicativo", "appSource": "Fonte do aplicativo",
"noLogs": "Sem logs", "noLogs": "Sem logs",
"appLogs": "Logs do aplicativo", "appLogs": "Logs do aplicativo",
@ -151,7 +151,7 @@
"appsRemoved": "Aplicativos removidos", "appsRemoved": "Aplicativos removidos",
"appsRemovedNotifDescription": "Notifica o usuário quando um ou mais aplicativos foram removidos devido a erros de carregamento", "appsRemovedNotifDescription": "Notifica o usuário quando um ou mais aplicativos foram removidos devido a erros de carregamento",
"xWasRemovedDueToErrorY": "{} foi removido devido a este erro: {}", "xWasRemovedDueToErrorY": "{} foi removido devido a este erro: {}",
"completeAppInstallation": "Instalação do aplicativo completa", "completeAppInstallation": "Instalação do aplicativo concluída",
"obtainiumMustBeOpenToInstallApps": "Obtainium deve estar aberto para instalar os aplicativos", "obtainiumMustBeOpenToInstallApps": "Obtainium deve estar aberto para instalar os aplicativos",
"completeAppInstallationNotifDescription": "Pede ao usuário que retorne ao Obtainium para finalizar a instalação de um aplicativo", "completeAppInstallationNotifDescription": "Pede ao usuário que retorne ao Obtainium para finalizar a instalação de um aplicativo",
"checkingForUpdates": "Verificando atualizações", "checkingForUpdates": "Verificando atualizações",
@ -167,15 +167,15 @@
"installedVersionX": "Versão instalada: {}", "installedVersionX": "Versão instalada: {}",
"lastUpdateCheckX": "Última verificação de atualizações: {}", "lastUpdateCheckX": "Última verificação de atualizações: {}",
"remove": "Remover", "remove": "Remover",
"yesMarkUpdated": "Sim, marcar como Atualizado", "yesMarkUpdated": "Sim, marcar como atualizado",
"fdroid": "Oficial F-Droid", "fdroid": "Oficial F-Droid",
"appIdOrName": "ID do aplicativo ou nome", "appIdOrName": "ID do aplicativo ou nome",
"appId": "ID do aplicativo", "appId": "ID do aplicativo",
"appWithIdOrNameNotFound": "Nenhum aplicativo foi encontrado com esse ID ou nome", "appWithIdOrNameNotFound": "Nenhum aplicativo foi encontrado com esse ID ou nome",
"reposHaveMultipleApps": "Repositórios podem conter multiplos aplicativos", "reposHaveMultipleApps": "Repositórios podem conter múltiplos aplicativos",
"fdroidThirdPartyRepo": "Repositórios de terceiros F-Droid", "fdroidThirdPartyRepo": "Repositórios de terceiros F-Droid",
"steamMobile": "Vapor Móvel", "steamMobile": "Steam para celular",
"steamChat": "Bate-papo Steam", "steamChat": "Chat do Steam",
"install": "Instalar", "install": "Instalar",
"markInstalled": "Marcar instalado", "markInstalled": "Marcar instalado",
"update": "Atualizar", "update": "Atualizar",
@ -191,7 +191,7 @@
"categories": "Categorias", "categories": "Categorias",
"category": "Categoria", "category": "Categoria",
"noCategory": "Sem categoria", "noCategory": "Sem categoria",
"noCategories": "Sem categoria", "noCategories": "Sem categorias",
"deleteCategoriesQuestion": "Deletar categorias?", "deleteCategoriesQuestion": "Deletar categorias?",
"categoryDeleteWarning": "Todos os aplicativos em categorias removidas serão descategorizados.", "categoryDeleteWarning": "Todos os aplicativos em categorias removidas serão descategorizados.",
"addCategory": "Adicionar categoria", "addCategory": "Adicionar categoria",
@ -200,15 +200,15 @@
"copiedToClipboard": "Copiado para a área de transferência", "copiedToClipboard": "Copiado para a área de transferência",
"storagePermissionDenied": "Permissão de armazenamento negada", "storagePermissionDenied": "Permissão de armazenamento negada",
"selectedCategorizeWarning": "Isso vai substituir qualquer configuração de categoria para os aplicativos selecionados.", "selectedCategorizeWarning": "Isso vai substituir qualquer configuração de categoria para os aplicativos selecionados.",
"filterAPKsByRegEx": "Filtrar APKs por expressão regular", "filterAPKsByRegEx": "Filtrar APKs usando expressão regular",
"removeFromObtainium": "Remover do Obtainium", "removeFromObtainium": "Remover do Obtainium",
"uninstallFromDevice": "Desinstalar do dispositivo", "uninstallFromDevice": "Desinstalar do dispositivo",
"onlyWorksWithNonVersionDetectApps": "Apenas funciona para aplicativos com detecção de versão desativada.", "onlyWorksWithNonVersionDetectApps": "Apenas funciona para aplicativos com detecção de versão desativada.",
"releaseDateAsVersion": "Usar data de lançamento como versão", "releaseDateAsVersion": "Usar data de lançamento como versão",
"releaseDateAsVersionExplanation": "Esta opção só deve ser usada para aplicativos onde a detecção de versão não funciona corretamente, mas há uma data de lançamento disponível.", "releaseDateAsVersionExplanation": "Esta opção só deve ser usada para aplicativos onde a detecção de versão não funciona corretamente, mas há uma data de lançamento disponível.",
"changes": "Mudanças", "changes": "Alterações",
"releaseDate": "Data de lançamento", "releaseDate": "Data de lançamento",
"importFromURLsInFile": "Importar de URLs em arquivo (como OPML)", "importFromURLsInFile": "Importar de URLs em arquivo (formato OPML)",
"versionDetectionExplanation": "Reconciliar string de versão com versão detectada no sistema operacional", "versionDetectionExplanation": "Reconciliar string de versão com versão detectada no sistema operacional",
"versionDetection": "Detecção de versão", "versionDetection": "Detecção de versão",
"standardVersionDetection": "Detecção de versão padrão", "standardVersionDetection": "Detecção de versão padrão",
@ -216,10 +216,10 @@
"autoApkFilterByArch": "Tente filtrar APKs por arquitetura de CPU, se possível", "autoApkFilterByArch": "Tente filtrar APKs por arquitetura de CPU, se possível",
"overrideSource": "Substituir fonte", "overrideSource": "Substituir fonte",
"dontShowAgain": "Não mostrar isso novamente", "dontShowAgain": "Não mostrar isso novamente",
"dontShowTrackOnlyWarnings": "Não mostrar avisos 'Apenas Monitorar'", "dontShowTrackOnlyWarnings": "Não mostrar avisos 'Apenas monitorar'",
"dontShowAPKOriginWarnings": "Não mostrar avisos de origem da APK", "dontShowAPKOriginWarnings": "Não mostrar avisos de origem da APK",
"moveNonInstalledAppsToBottom": "Mover aplicativos não instalados para o fundo da lista de aplicativos", "moveNonInstalledAppsToBottom": "Mover aplicativos não instalados para o fundo da lista de aplicativos",
"gitlabPATLabel": "Token de Acesso Pessoal do Gitlab\n(Ativa pesquisa e melhora a descoberta de APKs)", "gitlabPATLabel": "Token de acesso pessoal do Gitlab\n(Ativa pesquisa e melhora a descoberta de APKs)",
"about": "Sobre", "about": "Sobre",
"requiresCredentialsInSettings": "{}: Isso requer credenciais adicionais (em Configurações)", "requiresCredentialsInSettings": "{}: Isso requer credenciais adicionais (em Configurações)",
"checkOnStart": "Verificar se há atualizações ao iniciar", "checkOnStart": "Verificar se há atualizações ao iniciar",
@ -228,7 +228,7 @@
"pickHighestVersionCode": "Auto-selecionar o maior número de versão do APK", "pickHighestVersionCode": "Auto-selecionar o maior número de versão do APK",
"checkUpdateOnDetailPage": "Checar por atualizações ao abrir a página de detalhes de um aplicativo", "checkUpdateOnDetailPage": "Checar por atualizações ao abrir a página de detalhes de um aplicativo",
"disablePageTransitions": "Desativar animações de transição de página", "disablePageTransitions": "Desativar animações de transição de página",
"reversePageTransitions": "Reverter animações de transição de página", "reversePageTransitions": "Animações de transição de página invertidas",
"minStarCount": "Contagem mínima de estrelas", "minStarCount": "Contagem mínima de estrelas",
"addInfoBelow": "Adicionar essa informação abaixo.", "addInfoBelow": "Adicionar essa informação abaixo.",
"addInfoInSettings": "Adicionar essa informação nas configurações.", "addInfoInSettings": "Adicionar essa informação nas configurações.",
@ -254,7 +254,7 @@
"versionExtractionRegEx": "Regex de extração de versão", "versionExtractionRegEx": "Regex de extração de versão",
"matchGroupToUse": "Grupo correspondente a ser usado no Regex de extração de versão", "matchGroupToUse": "Grupo correspondente a ser usado no Regex de extração de versão",
"highlightTouchTargets": "Realçar áreas sensíveis ao toque que são menos óbvias", "highlightTouchTargets": "Realçar áreas sensíveis ao toque que são menos óbvias",
"pickExportDir": "Escolher diretório para a exportação", "pickExportDir": "Escolher diretório para exportação",
"autoExportOnChanges": "Auto-exportar em mudanças", "autoExportOnChanges": "Auto-exportar em mudanças",
"includeSettings": "Incluir configurações", "includeSettings": "Incluir configurações",
"filterVersionsByRegEx": "Filtrar versões por expressão regular", "filterVersionsByRegEx": "Filtrar versões por expressão regular",
@ -272,18 +272,18 @@
"updatesAvailableNotifChannel": "Atualizações disponíveis", "updatesAvailableNotifChannel": "Atualizações disponíveis",
"appsUpdatedNotifChannel": "Aplicativos atualizados", "appsUpdatedNotifChannel": "Aplicativos atualizados",
"appsPossiblyUpdatedNotifChannel": "Tentativas de atualização de aplicativos", "appsPossiblyUpdatedNotifChannel": "Tentativas de atualização de aplicativos",
"errorCheckingUpdatesNotifChannel": "Erro ao Procurar por Atualizações", "errorCheckingUpdatesNotifChannel": "Erro ao procurar por atualizações",
"appsRemovedNotifChannel": "Aplicativos removidos", "appsRemovedNotifChannel": "Aplicativos removidos",
"downloadingXNotifChannel": "Baixando {}", "downloadingXNotifChannel": "Baixando {}",
"completeAppInstallationNotifChannel": "Instalação completa do aplicativo", "completeAppInstallationNotifChannel": "Instalação completa do aplicativo",
"checkingForUpdatesNotifChannel": "Checando por Atualizações", "checkingForUpdatesNotifChannel": "Checando por atualizações",
"onlyCheckInstalledOrTrackOnlyApps": "Apenas checar aplicativos instalados e 'Apenas Seguir' por updates", "onlyCheckInstalledOrTrackOnlyApps": "Apenas verificar atualizações de aplicativos instalados e 'Apenas monitorar'",
"supportFixedAPKURL": "Suporte a APK com URLs fixas", "supportFixedAPKURL": "Suporte a APK com URLs fixas",
"selectX": "Selecionar {}", "selectX": "Selecionar {}",
"parallelDownloads": "Permitir downloads paralelos", "parallelDownloads": "Permitir downloads paralelos",
"installMethod": "Método de instalação", "installMethod": "Método de instalação",
"normal": "Normal", "normal": "Normal",
"root": "Raiz", "root": "Root",
"shizukuBinderNotFound": "O Shizuku não está rodando", "shizukuBinderNotFound": "O Shizuku não está rodando",
"useSystemFont": "Usar fonte padrão do sistema", "useSystemFont": "Usar fonte padrão do sistema",
"systemFontError": "Erro ao carregar a fonte do sistema: {}", "systemFontError": "Erro ao carregar a fonte do sistema: {}",
@ -298,6 +298,9 @@
"installed": "Instalado", "installed": "Instalado",
"latest": "Mais recente", "latest": "Mais recente",
"invertRegEx": "Inverter expressão regular", "invertRegEx": "Inverter expressão regular",
"note": "Nota",
"selfHostedNote": "O menu suspenso \"{}\" pode ser usado para acessar instâncias auto-hospedadas/personalizadas de qualquer fonte.",
"badDownload": "Não foi possível analisar o APK (transferência incompatível ou parcial)",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Remover aplicativo?", "one": "Remover aplicativo?",
"other": "Remover aplicativos?" "other": "Remover aplicativos?"
@ -339,15 +342,15 @@
"other": "Foram limpos {n} logs (antes = {antes}, depois = {depois})" "other": "Foram limpos {n} logs (antes = {antes}, depois = {depois})"
}, },
"xAndNMoreUpdatesAvailable": { "xAndNMoreUpdatesAvailable": {
"one": "{} e 1 outro aplicativo possui atualizações.", "one": "{} e um outro aplicativo possui atualizações.",
"other": "{} e {} outros aplicativo possuem atualizações." "other": "{} e {} outros aplicativo possuem atualizações."
}, },
"xAndNMoreUpdatesInstalled": { "xAndNMoreUpdatesInstalled": {
"one": "{} e um outro aplicativo foi atualizado.", "one": "{} e um outro aplicativo foram atualizado.",
"other": "{} e {} outros aplicativos foram atualizados." "other": "{} e {} outros aplicativos foram atualizados."
}, },
"xAndNMoreUpdatesPossiblyInstalled": { "xAndNMoreUpdatesPossiblyInstalled": {
"one": "{} e 1 outro aplicativo pode ter sido atualizado.", "one": "{} e um outro aplicativo podem ter sido atualizados.",
"other": "{} e {} outros aplicativos podem ter sido atualizados." "other": "{} e {} outros aplicativos podem ter sido atualizados."
} }
} }

View File

@ -298,6 +298,9 @@
"installed": "Установлен", "installed": "Установлен",
"latest": "Последний", "latest": "Последний",
"invertRegEx": "Инвертировать регулярное выражение", "invertRegEx": "Инвертировать регулярное выражение",
"note": "Примечание",
"selfHostedNote": "Выпадающий список \"{}\" можно использовать для доступа к самостоятельно размещенным/настроенным экземплярам любого источника.",
"badDownload": "APK не удалось разобрать (несовместимая или неполная загрузка)",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Удалить приложение?", "one": "Удалить приложение?",
"other": "Удалить приложения?" "other": "Удалить приложения?"

View File

@ -1,30 +1,119 @@
// Take one (hardcoded) translation file and ensure that all other translation files have the same keys in the same order // Take one (hardcoded) translation file and ensure that all other translation files have the same keys in the same order
// Then report which other translation files have identical items // Then report which other translation files have identical items (or auto-translate them if a DeepL API key is provided)
const fs = require('fs') const fs = require('fs')
const https = require('https')
const translationsDir = __dirname const deeplAPIKey = process.argv[2]
const templateFile = `${translationsDir}/en.json`
const otherFiles = fs.readdirSync(translationsDir).map(f => {
return `${translationsDir}/${f}`
}).filter(f => f.endsWith('.json') && f != templateFile)
const templateTranslation = require(templateFile) const neverAutoTranslate = {
steamMobile: ['*'],
steamChat: ['*'],
root: ['*'],
obtainiumExportHyphenatedLowercase: ['*'],
theme: ['de'],
appId: ['de']
}
otherFiles.forEach(file => { const translateText = async (text, targetLang, authKey) => {
const thisTranslationOriginal = require(file) return new Promise((resolve, reject) => {
const thisTranslationNew = {} const postData = `text=${encodeURIComponent(text)}&target_lang=${encodeURIComponent(targetLang)}&source_lang=EN`
Object.keys(templateTranslation).forEach(k => { const options = {
thisTranslationNew[k] = thisTranslationOriginal[k] || templateTranslation[k] hostname: 'api-free.deepl.com',
}) port: 443,
fs.writeFileSync(file, `${JSON.stringify(thisTranslationNew, null, ' ')}\n`) path: '/v2/translate',
}); method: 'POST',
headers: {
otherFiles.forEach(file => { 'Authorization': `DeepL-Auth-Key ${authKey}`,
const thisTranslation = require(file) 'Content-Type': 'application/x-www-form-urlencoded',
Object.keys(templateTranslation).forEach(k => { 'Content-Length': Buffer.byteLength(postData)
if (JSON.stringify(thisTranslation[k]) == JSON.stringify(templateTranslation[k])) { }
console.log(`${file} :::: ${k} :::: ${JSON.stringify(thisTranslation[k])}`)
} }
const req = https.request(options, (res) => {
let responseData = ''
res.on('data', (chunk) => {
responseData += chunk
})
res.on('end', () => {
try {
const jsonResponse = JSON.parse(responseData)
resolve(jsonResponse)
} catch (error) {
reject(error)
}
})
})
req.on('error', (error) => {
reject(error)
})
req.write(postData)
req.end()
}) })
}); }
const main = async () => {
const translationsDir = __dirname
const templateFile = `${translationsDir}/en.json`
const otherFiles = fs.readdirSync(translationsDir).map(f => {
return `${translationsDir}/${f}`
}).filter(f => f.endsWith('.json') && f != templateFile)
const templateTranslation = require(templateFile)
otherFiles.forEach(file => {
const thisTranslationOriginal = require(file)
const thisTranslationNew = {}
Object.keys(templateTranslation).forEach(k => {
thisTranslationNew[k] = thisTranslationOriginal[k] || templateTranslation[k]
})
fs.writeFileSync(file, `${JSON.stringify(thisTranslationNew, null, ' ')}\n`)
})
for (let i in otherFiles) {
const file = otherFiles[i]
const thisTranslation = require(file)
const translationKeys = Object.keys(templateTranslation)
for (let j in translationKeys) {
const k = translationKeys[j]
if (JSON.stringify(thisTranslation[k]) == JSON.stringify(templateTranslation[k])) {
const lang = file.split('/').pop().split('.')[0]
if (!neverAutoTranslate[k] || (neverAutoTranslate[k].indexOf('*') < 0 && neverAutoTranslate[k].indexOf(lang) < 0)) {
const reportLine = `${file} :::: ${k} :::: ${JSON.stringify(thisTranslation[k])}`
if (deeplAPIKey) {
const translateFunc = async (str) => {
const response = await translateText(str, lang, deeplAPIKey)
if (response.translations) {
return response.translations[0].text
} else {
throw JSON.stringify(response)
}
}
try {
if (typeof templateTranslation[k] == 'string') {
thisTranslation[k] = await translateFunc(thisTranslation[k])
} else {
const subKeys = Object.keys(templateTranslation[k])
for (let n in subKeys) {
const kk = subKeys[n]
thisTranslation[k][kk] = await translateFunc(thisTranslation[k][kk])
}
}
} catch (e) {
if (typeof e == 'string') {
console.log(`${reportLine} :::: ${e}`)
} else {
throw e
}
}
} else {
console.log(reportLine)
}
}
}
}
fs.writeFileSync(file, `${JSON.stringify(thisTranslation, null, ' ')}\n`)
}
}
main().catch(e => console.error)

View File

@ -288,16 +288,19 @@
"useSystemFont": "Använd systemteckensnittet", "useSystemFont": "Använd systemteckensnittet",
"systemFontError": "Fel vid laddning av systemteckensnittet: {}", "systemFontError": "Fel vid laddning av systemteckensnittet: {}",
"useVersionCodeAsOSVersion": "Använd appversionskoden som OS-upptäckt version", "useVersionCodeAsOSVersion": "Använd appversionskoden som OS-upptäckt version",
"requestHeader": "Request header", "requestHeader": "Rubrik för begäran",
"useLatestAssetDateAsReleaseDate": "Använd senaste tillgångsuppladdning som releasedatum", "useLatestAssetDateAsReleaseDate": "Använd senaste tillgångsuppladdning som releasedatum",
"defaultPseudoVersioningMethod": "Standard pseudoversionsmetod", "defaultPseudoVersioningMethod": "Standard pseudoversionsmetod",
"partialAPKHash": "Delvis APK-hash", "partialAPKHash": "Delvis APK-hash",
"APKLinkHash": "APK Link Hash", "APKLinkHash": "APK-länk Hash",
"directAPKLink": "Direkt APK-länk", "directAPKLink": "Direkt APK-länk",
"pseudoVersionInUse": "En pseudoversion används", "pseudoVersionInUse": "En pseudoversion används",
"installed": "Installerad", "installed": "Installerad",
"latest": "Senast", "latest": "Senast",
"invertRegEx": "Invertera reguljärt uttryck", "invertRegEx": "Invertera reguljärt uttryck",
"note": "Anmärkning",
"selfHostedNote": "Rullgardinsmenyn \"{}\" kan användas för att nå självhostade/anpassade instanser av valfri källa.",
"badDownload": "APK kunde inte analyseras (inkompatibel eller partiell nedladdning)",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Ta Bort App?", "one": "Ta Bort App?",
"other": "Ta Bort Appar?" "other": "Ta Bort Appar?"

View File

@ -298,6 +298,9 @@
"installed": "Kurulmuş", "installed": "Kurulmuş",
"latest": "En sonuncu", "latest": "En sonuncu",
"invertRegEx": "Normal ifadeyi ters çevir", "invertRegEx": "Normal ifadeyi ters çevir",
"note": "Not",
"selfHostedNote": "\"{}\" açılır menüsü, herhangi bir kaynağın kendi kendine barındırılan/özel örneklerine ulaşmak için kullanılabilir.",
"badDownload": "APK ayrıştırılamadı (uyumsuz veya kısmi indirme)",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Uygulamayı Kaldır?", "one": "Uygulamayı Kaldır?",
"other": "Uygulamaları Kaldır?" "other": "Uygulamaları Kaldır?"

View File

@ -25,11 +25,11 @@
"githubStarredRepos": "Kho lưu trữ có gắn dấu sao GitHub", "githubStarredRepos": "Kho lưu trữ có gắn dấu sao GitHub",
"uname": "Tên người dùng", "uname": "Tên người dùng",
"wrongArgNum": "Số lượng đối số được cung cấp sai", "wrongArgNum": "Số lượng đối số được cung cấp sai",
"xIsTrackOnly": "{}là Chỉ-Theo dõi", "xIsTrackOnly": "{} là Chỉ theo dõi",
"source": "Nguồn", "source": "Nguồn",
"app": "Ứng dụng", "app": "Ứng dụng",
"appsFromSourceAreTrackOnly": "Các ứng dụng từ nguồn này là 'Chỉ-Theo dõi'.", "appsFromSourceAreTrackOnly": "Các ứng dụng từ nguồn này là 'Chỉ theo dõi'.",
"youPickedTrackOnly": "Bạn đã chọn tùy chọn 'Chỉ-Theo dõi'.", "youPickedTrackOnly": "Bạn đã chọn tùy chọn 'Chỉ theo dõi'.",
"trackOnlyAppDescription": "Ứng dụng sẽ được theo dõi để cập nhật, nhưng Obtainium sẽ không thể tải xuống hoặc cài đặt nó.", "trackOnlyAppDescription": "Ứng dụng sẽ được theo dõi để cập nhật, nhưng Obtainium sẽ không thể tải xuống hoặc cài đặt nó.",
"cancelled": "Đã hủy", "cancelled": "Đã hủy",
"appAlreadyAdded": "Ứng dụng được thêm rồi", "appAlreadyAdded": "Ứng dụng được thêm rồi",
@ -42,7 +42,7 @@
"search": "Tìm kiếm", "search": "Tìm kiếm",
"additionalOptsFor": "Tùy chọn bổ sung cho {}", "additionalOptsFor": "Tùy chọn bổ sung cho {}",
"supportedSources": "Nguồn được hỗ trợ", "supportedSources": "Nguồn được hỗ trợ",
"trackOnlyInBrackets": "(Chỉ-Theo dõi)", "trackOnlyInBrackets": "(Chỉ theo dõi)",
"searchableInBrackets": "(Có thể tìm kiếm)", "searchableInBrackets": "(Có thể tìm kiếm)",
"appsString": "Ứng dụng", "appsString": "Ứng dụng",
"noApps": "Không có ứng dụng", "noApps": "Không có ứng dụng",
@ -60,7 +60,7 @@
"removeSelectedApps": "Xóa ứng dụng đã chọn", "removeSelectedApps": "Xóa ứng dụng đã chọn",
"updateX": "Cập nhật {}", "updateX": "Cập nhật {}",
"installX": "Cài đặt {}", "installX": "Cài đặt {}",
"markXTrackOnlyAsUpdated": "Đánh dấu {}\n(Chỉ-Theo dõi)\nnhư là đã cập nhật", "markXTrackOnlyAsUpdated": "Đánh dấu {}\n(Chỉ theo dõi)\nnhư là đã cập nhật",
"changeX": "Thay đổi {}", "changeX": "Thay đổi {}",
"installUpdateApps": "Cài đặt/Cập nhật ứng dụng", "installUpdateApps": "Cài đặt/Cập nhật ứng dụng",
"installUpdateSelectedApps": "Cài đặt/Cập nhật ứng dụng đã chọn", "installUpdateSelectedApps": "Cài đặt/Cập nhật ứng dụng đã chọn",
@ -157,7 +157,7 @@
"checkingForUpdates": "Đang kiểm tra cập nhật", "checkingForUpdates": "Đang kiểm tra cập nhật",
"checkingForUpdatesNotifDescription": "Thông báo tạm thời xuất hiện khi kiểm tra bản cập nhật", "checkingForUpdatesNotifDescription": "Thông báo tạm thời xuất hiện khi kiểm tra bản cập nhật",
"pleaseAllowInstallPerm": "Vui lòng cho phép Obtainium cài đặt Ứng dụng", "pleaseAllowInstallPerm": "Vui lòng cho phép Obtainium cài đặt Ứng dụng",
"trackOnly": "Chỉ-Theo dõi", "trackOnly": "Chỉ theo dõi",
"errorWithHttpStatusCode": "Lỗi {}", "errorWithHttpStatusCode": "Lỗi {}",
"versionCorrectionDisabled": "Tính năng sửa phiên bản bị vô hiệu hóa (plugin dường như không hoạt động)", "versionCorrectionDisabled": "Tính năng sửa phiên bản bị vô hiệu hóa (plugin dường như không hoạt động)",
"unknown": "Không xác định", "unknown": "Không xác định",
@ -216,7 +216,7 @@
"autoApkFilterByArch": "Cố gắng lọc APK theo kiến trúc CPU nếu có thể", "autoApkFilterByArch": "Cố gắng lọc APK theo kiến trúc CPU nếu có thể",
"overrideSource": "Ghi đè nguồn", "overrideSource": "Ghi đè nguồn",
"dontShowAgain": "Đừng hiển thị thông tin này nữa", "dontShowAgain": "Đừng hiển thị thông tin này nữa",
"dontShowTrackOnlyWarnings": "Không hiển thị cảnh báo 'Chỉ-Theo dõi'", "dontShowTrackOnlyWarnings": "Không hiển thị cảnh báo 'Chỉ theo dõi'",
"dontShowAPKOriginWarnings": "Không hiển thị cảnh báo nguồn gốc APK", "dontShowAPKOriginWarnings": "Không hiển thị cảnh báo nguồn gốc APK",
"moveNonInstalledAppsToBottom": "Chuyển Ứng dụng chưa được cài đặt xuống cuối danh sách", "moveNonInstalledAppsToBottom": "Chuyển Ứng dụng chưa được cài đặt xuống cuối danh sách",
"gitlabPATLabel": "GitLab Token\n(Cho phép tìm kiếm và lọc APK tốt hơn)", "gitlabPATLabel": "GitLab Token\n(Cho phép tìm kiếm và lọc APK tốt hơn)",
@ -277,13 +277,13 @@
"downloadingXNotifChannel": "Đang tải xuống {}", "downloadingXNotifChannel": "Đang tải xuống {}",
"completeAppInstallationNotifChannel": "Hoàn tất cài đặt ứng dụng", "completeAppInstallationNotifChannel": "Hoàn tất cài đặt ứng dụng",
"checkingForUpdatesNotifChannel": "Đang kiểm tra cập nhật", "checkingForUpdatesNotifChannel": "Đang kiểm tra cập nhật",
"onlyCheckInstalledOrTrackOnlyApps": "Chỉ kiểm tra cập nhật các ứng dụng đã cài đặt và Chỉ-Theo dõi", "onlyCheckInstalledOrTrackOnlyApps": "Chỉ kiểm tra cập nhật các ứng dụng đã cài đặt và Chỉ theo dõi",
"supportFixedAPKURL": "Hỗ trợ URL APK cố định", "supportFixedAPKURL": "Hỗ trợ URL APK cố định",
"selectX": "Lựa chọn {}", "selectX": "Lựa chọn {}",
"parallelDownloads": "Cho phép tải đa luồng", "parallelDownloads": "Cho phép tải đa luồng",
"installMethod": "Phương thức cài đặt", "installMethod": "Phương thức cài đặt",
"normal": "Mặc định", "normal": "Mặc định",
"root": "Nguồn gốc", "root": "Root",
"shizukuBinderNotFound": "Shizuku chưa khởi động", "shizukuBinderNotFound": "Shizuku chưa khởi động",
"useSystemFont": "Sử dụng phông chữ hệ thống", "useSystemFont": "Sử dụng phông chữ hệ thống",
"systemFontError": "Lỗi tải phông chữ hệ thống: {}", "systemFontError": "Lỗi tải phông chữ hệ thống: {}",
@ -295,9 +295,12 @@
"APKLinkHash": "Băm liên kết APK", "APKLinkHash": "Băm liên kết APK",
"directAPKLink": "Liên kết APK trực tiếp", "directAPKLink": "Liên kết APK trực tiếp",
"pseudoVersionInUse": "Phiên bản giả đang được sử dụng", "pseudoVersionInUse": "Phiên bản giả đang được sử dụng",
"installed": "Cài đặt", "installed": "Đã cài đặt",
"latest": "Muộn nhất", "latest": "Mới nhất",
"invertRegEx": "Đảo ngược biểu thức chính quy", "invertRegEx": "Đảo ngược biểu thức chính quy",
"note": "Note",
"selfHostedNote": "The \"{}\" dropdown can be used to reach self-hosted/custom instances of any source.",
"badDownload": "The APK could not be parsed (incompatible or partial download)",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Gỡ ứng dụng?", "one": "Gỡ ứng dụng?",
"other": "Gỡ ứng dụng?" "other": "Gỡ ứng dụng?"

View File

@ -283,7 +283,7 @@
"parallelDownloads": "启用并行下载", "parallelDownloads": "启用并行下载",
"installMethod": "安装方式", "installMethod": "安装方式",
"normal": "常规", "normal": "常规",
"root": "", "root": "root",
"shizukuBinderNotFound": "未发现兼容的 Shizuku 服务", "shizukuBinderNotFound": "未发现兼容的 Shizuku 服务",
"useSystemFont": "使用系统字体", "useSystemFont": "使用系统字体",
"systemFontError": "加载系统字体出错:{}", "systemFontError": "加载系统字体出错:{}",
@ -298,6 +298,9 @@
"installed": "已安装", "installed": "已安装",
"latest": "最新的", "latest": "最新的",
"invertRegEx": "反转正则表达式", "invertRegEx": "反转正则表达式",
"note": "备注",
"selfHostedNote": "{}\"下拉菜单可用于访问任何来源的自托管/自定义实例。",
"badDownload": "无法解析 APK不兼容或部分下载",
"removeAppQuestion": { "removeAppQuestion": {
"one": "是否删除应用?", "one": "是否删除应用?",
"other": "是否删除应用?" "other": "是否删除应用?"

View File

@ -7,6 +7,10 @@ trap "cd "$CURR_DIR"" EXIT
if [ -z "$1" ]; then if [ -z "$1" ]; then
git fetch && git merge origin/main && git push # Typically run after a PR to main, so bring dev up to date git fetch && git merge origin/main && git push # Typically run after a PR to main, so bring dev up to date
fi fi
cd .flutter
git fetch
git checkout "$(flutter --version | head -2 | tail -1 | awk '{print $4}')" # Ensure included Flutter submodule version equals my environment
cd ..
rm ./build/app/outputs/flutter-apk/* 2>/dev/null # Get rid of older builds if any rm ./build/app/outputs/flutter-apk/* 2>/dev/null # Get rid of older builds if any
flutter build apk --flavor normal && flutter build apk --split-per-abi --flavor normal # Build (both split and combined APKs) flutter build apk --flavor normal && flutter build apk --split-per-abi --flavor normal # Build (both split and combined APKs)
for file in ./build/app/outputs/flutter-apk/app-*normal*.apk*; do mv "$file" "${file//-normal/}"; done for file in ./build/app/outputs/flutter-apk/app-*normal*.apk*; do mv "$file" "${file//-normal/}"; done

View File

@ -0,0 +1,54 @@
<p>Obtainium allows you to install and update Apps directly from their releases pages, and receive notifications when new releases are made available.</p>
<p>Read the <a href="https://github.com/ImranR98/Obtainium/wiki">Wiki</a></p>
<p>
<b>Currently supported App sources:</b>
</p>
<ul>
<li>
<p>Open Source - General:</p>
<ul>
<li>GitHub</li>
<li>GitLab</li>
<li>Codeberg</li>
<li>F-Droid</li>
<li>Third Party F-Droid Repos</li>
<li>IzzyOnDroid</li>
<li>SourceForge</li>
<li>SourceHut</li>
</ul>
</li>
<li>
<p>Other - General:</p>
<ul>
<li>APKPure</li>
<li>Aptoide</li>
<li>Uptodowng</li>
<li>APKMirror (Track-Only)</li>
<li>Huawei AppGallery</li>
<li>Jenkins Jobs</li>
</ul>
</li>
<li>
<p>Open Source - App-Specific:</p>
<ul>
<li>Mullvad</li>
<li>Signal</li>
<li>VLC</li>
</ul>
</li>
<li>
<p>Other - App-Specific:</p>
<ul>
<li>WhatsApp</li>
<li>Telegram App</li>
<li>Neutron Code</li>
</ul>
</li>
<li><p>"HTML" (Fallback): Any other URL that returns an HTML page with links to APK files</p></li>
</ul>
<p>
<b>Limitations:</b>
</p>
<p>
For some sources, data is gathered using Web scraping and can easily break due to changes in website design. In such cases, more reliable methods may be unavailable.
</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

View File

@ -0,0 +1 @@
Get android app updates directly from the source

View File

@ -0,0 +1 @@
Obtainium

View File

@ -3,6 +3,8 @@ import 'dart:convert';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:html/parser.dart'; import 'package:html/parser.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:obtainium/app_sources/github.dart';
import 'package:obtainium/app_sources/gitlab.dart';
import 'package:obtainium/components/generated_form.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';
@ -95,17 +97,32 @@ class FDroid extends AppSource {
details.names.author = details.names.author =
authorLines.first.split(': ').sublist(1).join(': '); authorLines.first.split(': ').sublist(1).join(': ');
} }
var changelogUrls = lines.where((l) => l.startsWith('Changelog: ')); var changelogUrls = lines
.where((l) => l.startsWith('Changelog: '))
.map((e) => e.split(' ').sublist(1).join(' '));
if (changelogUrls.isNotEmpty) { if (changelogUrls.isNotEmpty) {
details.changeLog = changelogUrls.first; details.changeLog = changelogUrls.first;
details.changeLog = (await sourceRequest( bool isGitHub = false;
details.changeLog! bool isGitLab = false;
.split(': ') try {
.sublist(1) GitHub().sourceSpecificStandardizeURL(details.changeLog!);
.join(': ') isGitHub = true;
.replaceFirst('/blob/', '/raw/'), } catch (e) {
additionalSettings)) //
.body; }
try {
GitLab().sourceSpecificStandardizeURL(details.changeLog!);
isGitLab = true;
} catch (e) {
//
}
if ((isGitHub || isGitLab) &&
(details.changeLog?.indexOf('/blob/') ?? -1) >= 0) {
details.changeLog = (await sourceRequest(
details.changeLog!.replaceFirst('/blob/', '/raw/'),
additionalSettings))
.body;
}
} }
} catch (e) { } catch (e) {
// Fail silently // Fail silently

View File

@ -319,7 +319,7 @@ class HTML extends AppSource {
version ??= version ??=
additionalSettings['defaultPseudoVersioningMethod'] == 'APKLinkHash' additionalSettings['defaultPseudoVersioningMethod'] == 'APKLinkHash'
? rel.hashCode.toString() ? rel.hashCode.toString()
: (await checkPartialDownloadHashDynamc(rel)).toString(); : (await checkPartialDownloadHashDynamic(rel)).toString();
return APKDetails(version, [rel].map((e) => MapEntry(e, e)).toList(), return APKDetails(version, [rel].map((e) => MapEntry(e, e)).toList(),
AppNames(uri.host, tr('app'))); AppNames(uri.host, tr('app')));
} }

View File

@ -10,16 +10,23 @@ class SourceForge extends AppSource {
@override @override
String sourceSpecificStandardizeURL(String url) { String sourceSpecificStandardizeURL(String url) {
RegExp standardUrlRegExB = RegExp( var sourceRegex = getSourceRegex(hosts);
'^https?://(www\\.)?${getSourceRegex(hosts)}/p/[^/]+', RegExp standardUrlRegExC =
caseSensitive: false); RegExp('^https?://(www\\.)?$sourceRegex/p/.+', caseSensitive: false);
RegExpMatch? match = standardUrlRegExB.firstMatch(url); RegExpMatch? match = standardUrlRegExC.firstMatch(url);
if (match != null) { if (match != null) {
url = url =
'https://${Uri.parse(match.group(0)!).host}/projects/${url.substring(Uri.parse(match.group(0)!).host.length + '/projects/'.length + 1)}'; 'https://${Uri.parse(match.group(0)!).host}/projects/${url.substring(Uri.parse(match.group(0)!).host.length + '/projects/'.length + 1)}';
} }
RegExp standardUrlRegExB = RegExp(
'^https?://(www\\.)?$sourceRegex/projects/[^/]+',
caseSensitive: false);
match = standardUrlRegExB.firstMatch(url);
if (match != null && match.group(0) == url) {
url = '$url/files';
}
RegExp standardUrlRegExA = RegExp( RegExp standardUrlRegExA = RegExp(
'^https?://(www\\.)?${getSourceRegex(hosts)}/projects/[^/]+', '^https?://(www\\.)?$sourceRegex/projects/[^/]+/files(/.+)?',
caseSensitive: false); caseSensitive: false);
match = standardUrlRegExA.firstMatch(url); match = standardUrlRegExA.firstMatch(url);
if (match == null) { if (match == null) {
@ -33,38 +40,79 @@ class SourceForge extends AppSource {
String standardUrl, String standardUrl,
Map<String, dynamic> additionalSettings, Map<String, dynamic> additionalSettings,
) async { ) async {
Response res = var standardUri = Uri.parse(standardUrl);
await sourceRequest('$standardUrl/rss?path=/', additionalSettings); if (standardUri.pathSegments.length == 2) {
standardUrl = '$standardUrl/files';
standardUri = Uri.parse(standardUrl);
}
Response res = await sourceRequest(
'${standardUri.origin}/${standardUri.pathSegments.sublist(0, 2).join('/')}/rss?path=/',
additionalSettings);
if (res.statusCode == 200) { if (res.statusCode == 200) {
var parsedHtml = parse(res.body); var parsedHtml = parse(res.body);
var allDownloadLinks = var allDownloadLinks = parsedHtml
parsedHtml.querySelectorAll('guid').map((e) => e.innerHtml).toList(); .querySelectorAll('guid')
.map((e) => e.innerHtml)
.where((element) => element.startsWith(standardUrl))
.toList();
getVersion(String url) { getVersion(String url) {
try { try {
var tokens = url.split('/'); var segments = url
var fi = tokens.indexOf('files'); .substring(standardUrl.length)
return tokens[tokens[fi + 2] == 'download' ? fi - 1 : fi + 1]; .split('/')
.where((element) => element.isNotEmpty)
.toList()
.reversed
.toList()
.sublist(1)
.reversed
.toList();
segments = segments.length > 1
? segments.reversed.toList().sublist(1).reversed.toList()
: segments;
var version = segments.isNotEmpty ? segments.join('/') : null;
if (version != null) {
try {
var extractedVersion = extractVersion(
additionalSettings['versionExtractionRegEx'] as String?,
additionalSettings['matchGroupToUse'] as String?,
version);
if (extractedVersion != null) {
version = extractedVersion;
}
} catch (e) {
if (e is NoVersionError) {
version = null;
} else {
rethrow;
}
}
}
return version;
} catch (e) { } catch (e) {
return null; return null;
} }
} }
String? version = getVersion(allDownloadLinks[0]); var apkUrlListAllReleases = allDownloadLinks
.where((element) => element.toLowerCase().endsWith('.apk/download'))
.where((element) => getVersion(element) != null)
.toList();
if (apkUrlListAllReleases.isEmpty) {
throw NoReleasesError();
}
String? version = getVersion(apkUrlListAllReleases[0]);
if (version == null) { if (version == null) {
throw NoVersionError(); throw NoVersionError();
} }
var apkUrlListAllReleases = allDownloadLinks
.where((element) => element.toLowerCase().endsWith('.apk/download'))
.toList();
var apkUrlList = var apkUrlList =
apkUrlListAllReleases // This can be used skipped for fallback support later apkUrlListAllReleases // This can be used skipped for fallback support later
.where((element) => getVersion(element) == version) .where((element) => getVersion(element) == version)
.toList(); .toList();
return APKDetails( var segments = standardUrl.split('/');
version, return APKDetails(version, getApkUrlsFromUrls(apkUrlList),
getApkUrlsFromUrls(apkUrlList), AppNames(name, segments[segments.indexOf('files') - 1]));
AppNames(
name, standardUrl.substring(standardUrl.lastIndexOf('/') + 1)));
} else { } else {
throw getObtainiumHttpError(res); throw getObtainiumHttpError(res);
} }

View File

@ -39,6 +39,15 @@ class SourceHut extends AppSource {
String standardUrl, String standardUrl,
Map<String, dynamic> additionalSettings, Map<String, dynamic> additionalSettings,
) async { ) async {
if (standardUrl.endsWith('/refs')) {
standardUrl = standardUrl
.split('/')
.reversed
.toList()
.sublist(1)
.reversed
.join('/');
}
Uri standardUri = Uri.parse(standardUrl); Uri standardUri = Uri.parse(standardUrl);
String appName = standardUri.pathSegments.last; String appName = standardUri.pathSegments.last;
bool fallbackToOlderReleases = bool fallbackToOlderReleases =

View File

@ -184,7 +184,6 @@ class _ObtainiumState extends State<Obtainium> {
[], [],
0, 0,
{ {
'includePrereleases': true,
'versionDetection': true, 'versionDetection': true,
'apkFilterRegEx': 'fdroid', 'apkFilterRegEx': 'fdroid',
'invertAPKFilter': true 'invertAPKFilter': true

View File

@ -530,7 +530,20 @@ class AddAppPageState extends State<AddAppPage> {
? TextDecoration.underline ? TextDecoration.underline
: TextDecoration.none), : TextDecoration.none),
))), ))),
) ),
const SizedBox(
height: 16,
),
Text(
'${tr('note')}:',
style:
const TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(
height: 4,
),
Text(tr('selfHostedNote',
args: [tr('overrideSource')])),
], ],
); );
}, },

View File

@ -205,6 +205,12 @@ class _AppPageState extends State<AppPage> {
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: Theme.of(context).textTheme.displayLarge, style: Theme.of(context).textTheme.displayLarge,
), ),
Text(tr('byX', args: [app?.app.author ?? tr('unknown')]),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headlineMedium),
const SizedBox(
height: 24,
),
GestureDetector( GestureDetector(
onTap: () { onTap: () {
if (app?.app.url != null) { if (app?.app.url != null) {
@ -219,15 +225,12 @@ class _AppPageState extends State<AppPage> {
)); ));
}, },
child: Text( child: Text(
tr('byX', args: [app?.app.author ?? tr('unknown')]), app?.app.url ?? '',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headlineMedium!.copyWith( style: Theme.of(context).textTheme.labelSmall!.copyWith(
decoration: TextDecoration.underline, decoration: TextDecoration.underline,
fontStyle: FontStyle.italic), fontStyle: FontStyle.italic),
)), )),
const SizedBox(
height: 8,
),
Text( Text(
app?.app.id ?? '', app?.app.id ?? '',
textAlign: TextAlign.center, textAlign: TextAlign.center,
@ -347,18 +350,6 @@ class _AppPageState extends State<AppPage> {
} }
} }
getResetInstallStatusButton() => TextButton(
onPressed: app?.app == null || updating
? null
: () {
app!.app.installedVersion = null;
appsProvider.saveApps([app.app]);
},
child: Text(
tr('resetInstallStatus'),
textAlign: TextAlign.center,
));
getInstallOrUpdateButton() => TextButton( getInstallOrUpdateButton() => TextButton(
onPressed: !updating && onPressed: !updating &&
(app?.app.installedVersion == null || (app?.app.installedVersion == null ||
@ -403,16 +394,6 @@ class _AppPageState extends State<AppPage> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
if (app?.app.installedVersion != null &&
app?.app.installedVersion != app?.app.latestVersion &&
!isVersionDetectionStandard &&
!trackOnly)
IconButton(
onPressed: app?.downloadProgress != null || updating
? null
: showMarkUpdatedDialog,
tooltip: tr('markUpdated'),
icon: const Icon(Icons.done)),
if (source != null && if (source != null &&
source.combinedAppSpecificSettingFormItems.isNotEmpty) source.combinedAppSpecificSettingFormItems.isNotEmpty)
IconButton( IconButton(
@ -458,14 +439,30 @@ class _AppPageState extends State<AppPage> {
}, },
icon: const Icon(Icons.more_horiz), icon: const Icon(Icons.more_horiz),
tooltip: tr('more')), tooltip: tr('more')),
if (app?.app.installedVersion != null &&
app?.app.installedVersion != app?.app.latestVersion &&
!isVersionDetectionStandard &&
!trackOnly)
IconButton(
onPressed: app?.downloadProgress != null || updating
? null
: showMarkUpdatedDialog,
tooltip: tr('markUpdated'),
icon: const Icon(Icons.done)),
if ((!isVersionDetectionStandard || trackOnly) &&
app?.app.installedVersion != null &&
app?.app.installedVersion == app?.app.latestVersion)
IconButton(
onPressed: app?.app == null || updating
? null
: () {
app!.app.installedVersion = null;
appsProvider.saveApps([app.app]);
},
icon: const Icon(Icons.restore_rounded),
tooltip: tr('resetInstallStatus')),
const SizedBox(width: 16.0), const SizedBox(width: 16.0),
Expanded( Expanded(child: getInstallOrUpdateButton()),
child: (!isVersionDetectionStandard || trackOnly) &&
app?.app.installedVersion != null &&
app?.app.installedVersion ==
app?.app.latestVersion
? getResetInstallStatusButton()
: getInstallOrUpdateButton()),
const SizedBox(width: 16.0), const SizedBox(width: 16.0),
IconButton( IconButton(
onPressed: app?.downloadProgress != null || updating onPressed: app?.downloadProgress != null || updating

View File

@ -358,6 +358,16 @@ class AppsPageState extends State<AppsPage> {
String? changesUrl = String? changesUrl =
appSource.changeLogPageFromStandardUrl(listedApps[appIndex].app.url); appSource.changeLogPageFromStandardUrl(listedApps[appIndex].app.url);
String? changeLog = listedApps[appIndex].app.changeLog; String? changeLog = listedApps[appIndex].app.changeLog;
if (changeLog?.split('\n').length == 1) {
if (RegExp(
'(http|ftp|https)://([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?')
.hasMatch(changeLog!)) {
if (changesUrl == null) {
changesUrl = changeLog;
changeLog = null;
}
}
}
return (changeLog == null && changesUrl == null) return (changeLog == null && changesUrl == null)
? null ? null
: () { : () {
@ -1028,7 +1038,7 @@ class AppsPageState extends State<AppsPage> {
IconButton( IconButton(
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
style: const ButtonStyle(visualDensity: VisualDensity.compact), style: const ButtonStyle(visualDensity: VisualDensity.compact),
tooltip: isFilterOff ? tr('filter') : tr('filterActive'), tooltip: '${tr('filter')}${isFilterOff ? '' : ' *'}',
onPressed: isFilterOff onPressed: isFilterOff
? showFilterDialog ? showFilterDialog
: () { : () {

View File

@ -167,7 +167,7 @@ String hashListOfLists(List<List<int>> data) {
return hash.hashCode.toString(); return hash.hashCode.toString();
} }
Future<String> checkPartialDownloadHashDynamc(String url, Future<String> checkPartialDownloadHashDynamic(String url,
{int startingSize = 1024, {int startingSize = 1024,
int lowerLimit = 128, int lowerLimit = 128,
Map<String, String>? headers}) async { Map<String, String>? headers}) async {
@ -243,7 +243,9 @@ Future<File> downloadFile(
tempDownloadedFile.deleteSync(recursive: true); tempDownloadedFile.deleteSync(recursive: true);
throw response.reasonPhrase ?? tr('unexpectedError'); throw response.reasonPhrase ?? tr('unexpectedError');
} }
tempDownloadedFile.renameSync(downloadedFile.path); if (tempDownloadedFile.existsSync()) {
tempDownloadedFile.renameSync(downloadedFile.path);
}
} else { } else {
client.close(); client.close();
} }
@ -530,9 +532,18 @@ class AppsProvider with ChangeNotifier {
{bool needsBGWorkaround = false}) async { {bool needsBGWorkaround = false}) async {
var newInfo = var newInfo =
await pm.getPackageArchiveInfo(archiveFilePath: file.file.path); await pm.getPackageArchiveInfo(archiveFilePath: file.file.path);
if (newInfo == null) {
try {
file.file.deleteSync(recursive: true);
} catch (e) {
//
} finally {
throw ObtainiumError(tr('badDownload'));
}
}
PackageInfo? appInfo = await getInstalledInfo(apps[file.appId]!.app.id); PackageInfo? appInfo = await getInstalledInfo(apps[file.appId]!.app.id);
if (appInfo != null && if (appInfo != null &&
newInfo!.versionCode! < appInfo.versionCode! && newInfo.versionCode! < appInfo.versionCode! &&
!(await canDowngradeApps())) { !(await canDowngradeApps())) {
throw DowngradeError(); throw DowngradeError();
} }

View File

@ -829,8 +829,9 @@ class SourceProvider {
APKDetails apk = APKDetails apk =
await source.getLatestAPKDetails(standardUrl, additionalSettings); await source.getLatestAPKDetails(standardUrl, additionalSettings);
if (source.runtimeType != HTML().runtimeType) { if (source.runtimeType !=
// HTML does it separately HTML().runtimeType && // Some sources do it separately
source.runtimeType != SourceForge().runtimeType) {
String? extractedVersion = extractVersion( String? extractedVersion = extractVersion(
additionalSettings['versionExtractionRegEx'] as String?, additionalSettings['versionExtractionRegEx'] as String?,
additionalSettings['matchGroupToUse'] as String?, additionalSettings['matchGroupToUse'] as String?,

View File

@ -22,10 +22,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: android_package_manager name: android_package_manager
sha256: e52ca607b9f19f95d5dae4211ed8fa93e67093f22ac570db47489c5bca512940 sha256: "2de859fae7226a7de1c1ff9a2308f1967599408800330501a1ce97927c051153"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.0" version: "0.7.1"
animations: animations:
dependency: "direct main" dependency: "direct main"
description: description:
@ -190,10 +190,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: device_info_plus name: device_info_plus
sha256: "0042cb3b2a76413ea5f8a2b40cec2a33e01d0c937e91f0f7c211fde4f7739ba6" sha256: "77f757b789ff68e4eaf9c56d1752309bd9f7ad557cb105b938a7f8eb89e59110"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "9.1.1" version: "9.1.2"
device_info_plus_platform_interface: device_info_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -307,10 +307,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_local_notifications name: flutter_local_notifications
sha256: "66cc2fe16bf4bca71d795939763ad3f1830ad85772dc3b1561613c501859826d" sha256: c18f1de98fe0bb9dd5ba91e1330d4febc8b6a7de6aae3ffe475ef423723e72f3
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "16.3.1+1" version: "16.3.2"
flutter_local_notifications_linux: flutter_local_notifications_linux:
dependency: transitive dependency: transitive
description: description:
@ -410,10 +410,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: image name: image
sha256: "004a2e90ce080f8627b5a04aecb4cdfac87d2c3f3b520aa291260be5a32c033d" sha256: "49a0d4b0c12402853d3f227fe7c315601b238d126aa4caa5dbb2dcf99421aa4a"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.1.4" version: "4.1.6"
intl: intl:
dependency: transitive dependency: transitive
description: description:
@ -482,10 +482,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: mime name: mime
sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.4" version: "1.0.5"
nested: nested:
dependency: transitive dependency: transitive
description: description:
@ -650,10 +650,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: share_plus name: share_plus
sha256: f74fc3f1cbd99f39760182e176802f693fa0ec9625c045561cfad54681ea93dd sha256: "3ef39599b00059db0990ca2e30fca0a29d8b37aae924d60063f8e0184cf20900"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.2.1" version: "7.2.2"
share_plus_platform_interface: share_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -751,18 +751,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: sqflite name: sqflite
sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a" sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.0" version: "2.3.2"
sqflite_common: sqflite_common:
dependency: transitive dependency: transitive
description: description:
name: sqflite_common name: sqflite_common
sha256: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6 sha256: "28d8c66baee4968519fb8bd6cdbedad982d6e53359091f0b74544a9f32ec72d5"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.5.0+2" version: "2.5.3"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -831,10 +831,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: url_launcher name: url_launcher
sha256: d25bb0ca00432a5e1ee40e69c36c85863addf7cc45e433769d61bed3fe81fd96 sha256: c512655380d241a337521703af62d2c122bf7b77a46ff7dd750092aa9433499c
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.2.3" version: "6.2.4"
url_launcher_android: url_launcher_android:
dependency: transitive dependency: transitive
description: description:
@ -919,26 +919,26 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: webview_flutter name: webview_flutter
sha256: "71e1bfaef41016c8d5954291df5e9f8c6172f1f6ff3af01b5656456ddb11f94c" sha256: d81b68e88cc353e546afb93fb38958e3717282c5ac6e5d3be4a4aef9fc3c1413
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.4.4" version: "4.5.0"
webview_flutter_android: webview_flutter_android:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_android name: webview_flutter_android
sha256: "161af93c2abaf94ef2192bffb53a3658b2d721a3bf99b69aa1e47814ee18cc96" sha256: "4ea3c4e1b8ed590162b15b8a61b41b1ef3ff179a314627c16ce40c086d94b8af"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.13.2" version: "3.14.0"
webview_flutter_platform_interface: webview_flutter_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_platform_interface name: webview_flutter_platform_interface
sha256: "80b40ae4fb959957eef9fa8970b6c9accda9f49fc45c2b75154696a8e8996cfe" sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.9.1" version: "2.10.0"
webview_flutter_wkwebview: webview_flutter_wkwebview:
dependency: transitive dependency: transitive
description: description:

View File

@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # 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: 0.16.1+249 # When changing this, update the tag in main() accordingly version: 1.0.2+252 # When changing this, update the tag in main() accordingly
environment: environment:
sdk: '>=3.0.0 <4.0.0' sdk: '>=3.0.0 <4.0.0'