Compare commits

...

98 Commits

Author SHA1 Message Date
f6c6cd5cb8 Merge pull request #993 from ImranR98/dev
Separate notif channel title translations (#979), Add 'skip update notification' per-app toggle (#980), Better error for some incompatible APK cases (#981), Add whole-page version extraction for HTML (#989), Better relative link resolution (#989), Clearer wording (#991), Fixed issues in some translation files (#992)
2023-10-12 19:54:12 -04:00
67b56cee50 Upgrade packages, increment version 2023-10-12 19:51:55 -04:00
2d7465cca6 Separate notif channel title translations (#979) 2023-10-12 19:51:04 -04:00
d06f20690d Add 'skip update notification' per-app toggle (#980) 2023-10-12 19:33:38 -04:00
e613a494ff Better error for some incompatible APK cases (#981) 2023-10-12 19:24:23 -04:00
503a01675e Clearer wording (#991) 2023-10-12 19:10:02 -04:00
723f7e63e9 Add whole-page version extraction for HTML (#989) 2023-10-12 19:06:59 -04:00
7ff6916e5f Better relative link resolution (#989) 2023-10-12 18:57:47 -04:00
910ed26525 Fixed issues in some translation files 2023-10-12 18:31:31 -04:00
c0fffa6293 Merge pull request #987 from ImranR98/dev
Fix issues with last conflit resolution commit
2023-10-11 21:07:18 -04:00
d800d3ba41 Fix issues with last conflit resolution commit 2023-10-11 21:03:23 -04:00
d267343c64 Merge pull request #986 from ImranR98/dev
Switch back to serial BG installs (#984), Fix UpToDown again (#982)
2023-10-11 21:01:09 -04:00
0f72e37272 Merge branch 'main' into dev 2023-10-11 21:00:37 -04:00
89e44d581f Update packages, increment version 2023-10-11 20:56:26 -04:00
c908a710de Fix UpToDown again (#982) 2023-10-11 20:55:09 -04:00
f0809cde72 Merge pull request #977 from iDazai/main
updated translations
2023-10-11 20:44:12 -04:00
e6da8c1c18 Merge pull request #978 from Daviteusz/weblate-obtainium-translate
locale(pl): Update Polish translation
2023-10-11 20:44:06 -04:00
81ea67afa8 Remove unnecessary log 2023-10-11 20:43:27 -04:00
488049821e Switch back to serial BG installs (#984) 2023-10-11 20:42:33 -04:00
fc7408a8f8 locale(pl): Update Polish translations 2023-10-09 20:14:22 +02:00
6955191fdd Update pl.json
fixed line breaks
2023-10-09 15:22:32 +02:00
ba59693d90 Update pl.json
Changed order of the lines so it's the same order for every language and better to compare
2023-10-09 15:17:52 +02:00
ce6e51128d Update it.json
added three missing lines, no translation
2023-10-09 15:04:45 +02:00
a7a26037ae Update hu.json
added four missing lines, no translation
2023-10-09 15:02:51 +02:00
00854abd1a Update fr.json
added three missing lines, no translation
2023-10-09 14:59:14 +02:00
c26649d5f2 Update fa.json
added three missing lines, no translation
2023-10-09 14:58:42 +02:00
63b76a249f Update es.json
added three missing lines, no translation
2023-10-09 14:57:52 +02:00
95f19208ad Update bs.json
added three missing lines, no translation
2023-10-09 14:54:24 +02:00
f4a902ee47 Update de.json
added three missing lines and translated them, reverted translation of variables so log function can work again.
2023-10-09 14:52:50 +02:00
036823cbb6 Merge remote-tracking branch 'origin/main' into dev 2023-10-08 17:33:12 -04:00
547c2c8c0d Merge pull request #975 from ImranR98/dev
Less notif spam, no check in aeroplane mode (#974)
2023-10-08 17:33:05 -04:00
7453d19d27 Increment version, update packages 2023-10-08 17:32:41 -04:00
2a0b68d637 Less notif spam, no check in aeroplane mode (#974) 2023-10-08 17:30:08 -04:00
02f374fdf0 Merge pull request #969 from ImranR98/dev
Enabled WhatsApp Source (#357)
2023-10-07 13:31:45 -04:00
3536dcd775 Increment version 2023-10-07 13:31:02 -04:00
6fa887e536 Merge pull request #967 from JohnBetaro/main
Better version detection for F-Droid
2023-10-07 13:16:39 -04:00
71755763b9 Enabled WhatsApp Source (#357) 2023-10-07 13:15:22 -04:00
5aabcccfd4 Update fdroid.dart 2023-10-07 09:53:34 +01:00
1e009e2211 Update release.yml 2023-10-07 02:03:18 -04:00
811bc6434b Update release.yml 2023-10-07 02:00:13 -04:00
a5b2d06742 Update release.yml 2023-10-07 01:33:34 -04:00
2c00674835 Update release.yml 2023-10-07 01:20:03 -04:00
9bbff1f436 Update release.yml 2023-10-07 01:08:43 -04:00
c75416f9be Update release.yml 2023-10-07 01:02:53 -04:00
2cb750a7b0 Update release.yml 2023-10-07 00:56:27 -04:00
abfec51964 Update release.yml 2023-10-07 00:40:34 -04:00
e314717a3e Update release.yml 2023-10-07 00:33:50 -04:00
290a78acb5 Update release.yml 2023-10-07 00:30:09 -04:00
b40a4dd243 Update release.yml 2023-10-07 00:09:18 -04:00
b38f6d0581 Update release.yml 2023-10-06 23:58:33 -04:00
5c562a6bdb Update release.yml 2023-10-06 23:45:00 -04:00
238d43f916 Update release.yml 2023-10-06 23:18:25 -04:00
818dc23089 Update release.yml 2023-10-06 22:55:59 -04:00
ddb50940ce Update release.yml 2023-10-06 22:55:50 -04:00
96fb97f4ef Update release.yml 2023-10-06 22:53:13 -04:00
6c0459c2ae Update release.yml 2023-10-06 22:51:30 -04:00
30a9e1ee4b Update release.yml 2023-10-06 22:48:21 -04:00
15a1f1e6e0 Update release.yml 2023-10-06 22:46:11 -04:00
827e2b161c Update release.yml 2023-10-06 22:45:20 -04:00
e95230859e Update release.yml 2023-10-06 22:43:41 -04:00
95cb8ca493 Update release.yml 2023-10-06 22:41:47 -04:00
5735293efb Update release.yml 2023-10-06 22:40:27 -04:00
035df1f338 Update release.yml 2023-10-06 22:38:01 -04:00
36a8b04c4f Update release.yml 2023-10-06 22:35:40 -04:00
3d5411ef28 Update release.yml 2023-10-06 22:32:23 -04:00
df7b74e727 Update release.yml 2023-10-06 22:28:02 -04:00
0138599120 Update release.yml 2023-10-06 22:23:45 -04:00
66446cbffc Update release.yml 2023-10-06 22:16:41 -04:00
ef40f3900f Update release.yml 2023-10-06 22:11:25 -04:00
ce259764a8 Update release.yml 2023-10-06 22:09:33 -04:00
65187cb17b Update release.yml 2023-10-06 22:04:55 -04:00
8f25245ad1 Update release.yml 2023-10-06 21:47:25 -04:00
58b8baa019 Merge pull request #966 from ImranR98/dev
Run GH action manually only
2023-10-06 21:21:44 -04:00
ba1db88c8d Run GH action manually only 2023-10-06 21:21:26 -04:00
c8f2f42a35 Merge pull request #965 from ImranR98/dev
Parallelize Update Checking (#963), Bugfixes (#954, #962)
2023-10-06 21:20:19 -04:00
4e5a9b2af5 Updated GitHub actions 2023-10-06 21:19:46 -04:00
d1ab961c14 Merge remote-tracking branch 'origin/main' into dev 2023-10-06 20:45:02 -04:00
33caf4644e Ran dart fix 2023-10-06 20:43:06 -04:00
f34ffe18a8 Update packages, increment version 2023-10-06 20:42:09 -04:00
4b1c5e111d Merge pull request #958 from JohnBetaro/main
Workflow to build and release
2023-10-06 20:40:48 -04:00
dbd7c296c6 Merge pull request #951 from DwainZwerg/patch-2
Update de.json
2023-10-06 20:38:08 -04:00
df93cbde8f Fix UpToDown (#962) 2023-10-06 20:37:14 -04:00
d8cbc121a7 Merge pull request #964 from ImranR98/963
Parallelize Update Checking (#963)
2023-10-06 20:07:18 -04:00
8163cd5c8f Improvements, bugfixes 2023-10-06 19:58:46 -04:00
e9e9adb174 Tweaks 2023-10-06 19:34:08 -04:00
21fdfc1eef Attempting to parallelize update checks 2023-10-06 19:23:18 -04:00
4304251e1e Remove checking for APKs
This is because I couldn't check for prereleases because I don't know how, maybe you can.
2023-10-05 11:31:42 +01:00
ae0cd74b0e Update android.yml 2023-10-05 11:29:03 +01:00
6935bff244 Update android.yml 2023-10-05 11:22:29 +01:00
102b9da617 Update android.yml 2023-10-05 11:19:46 +01:00
8bd0d185ae Create android.yml 2023-10-05 11:16:42 +01:00
7bfc5ae0a8 Bugfix (#954) 2023-10-03 21:34:24 -04:00
c72a41db9d Update de.json
and small improvements
2023-10-01 12:05:49 +00:00
5fbb1c2e32 Merge pull request #947 from LilligantMatsuri/main
Update Chinese translation
2023-09-30 10:16:52 -04:00
850dd53c69 Merge pull request #949 from ImranR98/dev
"Naive" version detection for some Sources (#946)
2023-09-30 10:16:36 -04:00
e3baf91037 Increment version, upgrade packages 2023-09-30 10:16:10 -04:00
4c811c9c04 "Naive" version detection for some Sources (#946) 2023-09-30 10:12:49 -04:00
4bc9f5826e Update zh.json
- Translate new strings
- Slight improvements

Signed-off-by: Matsuri <matsuri@vmoe.info>
2023-09-30 20:30:00 +08:00
30 changed files with 1216 additions and 872 deletions

70
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,70 @@
name: Build and Release
on:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: subosito/flutter-action@v2
- name: Import GPG key
id: import_pgp_key
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.PGP_KEY_BASE64 }}
passphrase: ${{ secrets.PGP_PASSPHRASE }}
- name: Build APKs
run: |
sed -i 's/signingConfig signingConfigs.release//g' android/app/build.gradle
flutter build apk && flutter build apk --split-per-abi
rm ./build/app/outputs/flutter-apk/*.sha1
ls -l ./build/app/outputs/flutter-apk/
- name: Sign APKs
env:
KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}
run: |
echo "${KEYSTORE_BASE64}" | base64 -d > apksign.keystore
for apk in ./build/app/outputs/flutter-apk/*-release*.apk; do
unsignedFn=${apk/-release/-unsigned}
mv "$apk" "$unsignedFn"
${ANDROID_HOME}/build-tools/30.0.2/apksigner sign --ks apksign.keystore --ks-pass pass:"${KEYSTORE_PASSWORD}" --out "${apk}" "${unsignedFn}"
sha256sum ${apk} | cut -d " " -f 1 > "$apk".sha256
gpg --batch --pinentry-mode loopback --passphrase "${PGP_PASSPHRASE}" --sign --detach-sig "$apk".sha256
done
rm apksign.keystore
PGP_KEY_FINGERPRINT="${{ steps.import_pgp_key.outputs.fingerprint }}"
- name: Extract Version
id: extract_version
run: |
VERSION=$(grep -oP "currentVersion = '\K[^']+" lib/main.dart)
echo "version=$VERSION" >> $GITHUB_OUTPUT
TAG=$(grep -oP "'.*\\\$currentVersion.*'" lib/main.dart | head -c -2 | tail -c +2 | sed "s/\$currentVersion/$VERSION/g")
echo "tag=$TAG" >> $GITHUB_OUTPUT
if [ -n "$(echo $TAG | grep -oP '\-beta$')" ]; then BETA=true; else BETA=false; fi
echo "beta=$BETA" >> $GITHUB_OUTPUT
- name: Create Tag
uses: mathieudutour/github-tag-action@v6.1
with:
github_token: ${{ secrets.GH_ACCESS_TOKEN }}
custom_tag: "${{ steps.extract_version.outputs.tag }}"
tag_prefix: ""
- name: Create Release And Upload APKs
uses: ncipollo/release-action@v1
with:
token: ${{ secrets.GH_ACCESS_TOKEN }}
tag: "${{ steps.extract_version.outputs.tag }}"
prerelease: "${{ steps.extract_version.outputs.beta }}"
artifacts: ./build/app/outputs/flutter-apk/*-release*.apk*
generateReleaseNotes: true

View File

@ -1,315 +1,329 @@
{ {
"invalidURLForSource": "Nije važeći URL aplikacije {}", "invalidURLForSource": "Nije važeći URL aplikacije {}",
"noReleaseFound": "Nije moguće pronaći odgovarajuće izdanje", "noReleaseFound": "Nije moguće pronaći odgovarajuće izdanje",
"noVersionFound": "Nije moguće odrediti verziju izdanja", "noVersionFound": "Nije moguće odrediti verziju izdanja",
"urlMatchesNoSource": "URL se ne podudara s poznatim izvorom", "urlMatchesNoSource": "URL se ne podudara s poznatim izvorom",
"cantInstallOlderVersion": "Nije moguće instalirati stariju verziju aplikacije", "cantInstallOlderVersion": "Nije moguće instalirati stariju verziju aplikacije",
"appIdMismatch": "ID preuzetog paketa se ne podudara s postojećim ID-om aplikacije", "appIdMismatch": "ID preuzetog paketa se ne podudara s postojećim ID-om aplikacije",
"functionNotImplemented": "Ova klasa nije implementirala ovu funkciju", "functionNotImplemented": "Ova klasa nije implementirala ovu funkciju",
"placeholder": "Rezervirano mjesto", "placeholder": "Rezervirano mjesto",
"someErrors": "Došlo je do nekih grešaka", "someErrors": "Došlo je do nekih grešaka",
"unexpectedError": "Neočekivana greška", "unexpectedError": "Neočekivana greška",
"ok": "Dobro", "ok": "Dobro",
"and": "i", "and": "i",
"githubPATLabel": "GitHub token za lični pristup (eng. PAT, povećava ograničenje stope)", "githubPATLabel": "GitHub token za lični pristup (eng. PAT, povećava ograničenje stope)",
"includePrereleases": "Uključi preliminarna izdanja", "includePrereleases": "Uključi preliminarna izdanja",
"fallbackToOlderReleases": "Povratak na starija izdanja", "fallbackToOlderReleases": "Povratak na starija izdanja",
"filterReleaseTitlesByRegEx": "Filtrirajte naslove izdanja prema regularnom izrazu", "filterReleaseTitlesByRegEx": "Filtrirajte naslove izdanja prema regularnom izrazu",
"invalidRegEx": "Nevažeći regularni izraz", "invalidRegEx": "Nevažeći regularni izraz",
"noDescription": "Bez opisa", "noDescription": "Bez opisa",
"cancel": "Otkaži", "cancel": "Otkaži",
"continue": "Nastavite", "continue": "Nastavite",
"requiredInBrackets": "(obavezno)", "requiredInBrackets": "(obavezno)",
"dropdownNoOptsError": "GREŠKA: PADAJUĆI MENI MORA IMATI NAJMANJE JEDNU OPCIJU", "dropdownNoOptsError": "GREŠKA: PADAJUĆI MENI MORA IMATI NAJMANJE JEDNU OPCIJU",
"colour": "Boja", "colour": "Boja",
"githubStarredRepos": "GitHub repo-i sa zvjezdicom", "githubStarredRepos": "GitHub repo-i sa zvjezdicom",
"uname": "Korisničko ime", "uname": "Korisničko ime",
"wrongArgNum": "Naveden je pogrešan broj argumenata", "wrongArgNum": "Naveden je pogrešan broj argumenata",
"xIsTrackOnly": "{} je samo za praćenje", "xIsTrackOnly": "{} je samo za praćenje",
"source": "Izvor", "source": "Izvor",
"app": "Aplikacija. ", "app": "Aplikacija. ",
"appsFromSourceAreTrackOnly": "Aplikacije iz ovog izvora su 'Samo za praćenje'.", "appsFromSourceAreTrackOnly": "Aplikacije iz ovog izvora su 'Samo za praćenje'.",
"youPickedTrackOnly": "Odabrali ste opciju „Samo za praćenje”.", "youPickedTrackOnly": "Odabrali ste opciju „Samo za praćenje”.",
"trackOnlyAppDescription": "Aplikacija će se pratiti radi ažuriranja, ali Obtainium neće moći da je preuzme ili instalira.", "trackOnlyAppDescription": "Aplikacija će se pratiti radi ažuriranja, ali Obtainium neće moći da je preuzme ili instalira.",
"cancelled": "Otkazano", "cancelled": "Otkazano",
"appAlreadyAdded": "Aplikacija je već dodana", "appAlreadyAdded": "Aplikacija je već dodana",
"alreadyUpToDateQuestion": "Aplikacija je već ažurirana?", "alreadyUpToDateQuestion": "Aplikacija je već ažurirana?",
"addApp": "Dodaj aplikaciju", "addApp": "Dodaj aplikaciju",
"appSourceURL": "Izvorni URL aplikacije", "appSourceURL": "Izvorni URL aplikacije",
"error": "Greška", "error": "Greška",
"add": "Dodaj", "add": "Dodaj",
"searchSomeSourcesLabel": "Pretraživanje (samo neki izvori)", "searchSomeSourcesLabel": "Pretraživanje (samo neki izvori)",
"search": "Pretraživanje", "search": "Pretraživanje",
"additionalOptsFor": "Dodatne opcije za {}", "additionalOptsFor": "Dodatne opcije za {}",
"supportedSources": "Podržani izvori", "supportedSources": "Podržani izvori",
"trackOnlyInBrackets": "(Samo za praćenje)", "trackOnlyInBrackets": "(Samo za praćenje)",
"searchableInBrackets": "(Može se pretraživati)", "searchableInBrackets": "(Može se pretraživati)",
"appsString": "Aplikacije", "appsString": "Aplikacije",
"noApps": "Nema aplikacija", "noApps": "Nema aplikacija",
"noAppsForFilter": "Nema aplikacija za filter", "noAppsForFilter": "Nema aplikacija za filter",
"byX": "Autor {}", "byX": "Autor {}",
"percentProgress": "Napredak: {}%", "percentProgress": "Napredak: {}%",
"pleaseWait": "Molimo sačekajte", "pleaseWait": "Molimo sačekajte",
"updateAvailable": "Ažuriranje dostupno", "updateAvailable": "Ažuriranje dostupno",
"estimateInBracketsShort": "(Procjena)", "estimateInBracketsShort": "(Procjena)",
"notInstalled": "Nije instalirano", "notInstalled": "Nije instalirano",
"estimateInBrackets": "(Procjena)", "estimateInBrackets": "(Procjena)",
"selectAll": "Označi sve", "selectAll": "Označi sve",
"deselectN": "Poništi odabir {}", "deselectN": "Poništi odabir {}",
"xWillBeRemovedButRemainInstalled": "{} će biti uklonjen iz Obtainiuma, ali će ostati instaliran na uređaju.", "xWillBeRemovedButRemainInstalled": "{} će biti uklonjen iz Obtainiuma, ali će ostati instaliran na uređaju.",
"removeSelectedAppsQuestion": "Želite li ukloniti odabrane aplikacije?", "removeSelectedAppsQuestion": "Želite li ukloniti odabrane aplikacije?",
"removeSelectedApps": "Ukloni odabrane aplikacije", "removeSelectedApps": "Ukloni odabrane aplikacije",
"updateX": "Nadogradi {}", "updateX": "Nadogradi {}",
"installX": "Instaliraj {}", "installX": "Instaliraj {}",
"markXTrackOnlyAsUpdated": "Označi {}\n(samo za praćenje)\nkao ažurirano", "markXTrackOnlyAsUpdated": "Označi {}\n(samo za praćenje)\nkao ažurirano",
"changeX": "Promjena {}", "changeX": "Promjena {}",
"installUpdateApps": "Instalirajte/ažurirajte aplikacije", "installUpdateApps": "Instalirajte/ažurirajte aplikacije",
"installUpdateSelectedApps": "Instalirajte/ažurirajte odabrane aplikacije", "installUpdateSelectedApps": "Instalirajte/ažurirajte odabrane aplikacije",
"markXSelectedAppsAsUpdated": "Označite {} odabrane aplikacije kao ažurirane?", "markXSelectedAppsAsUpdated": "Označite {} odabrane aplikacije kao ažurirane?",
"no": "Ne", "no": "Ne",
"yes": "Da", "yes": "Da",
"markSelectedAppsUpdated": "Označi odabrane aplikacije kao ažurirane", "markSelectedAppsUpdated": "Označi odabrane aplikacije kao ažurirane",
"pinToTop": "Prikvači na vrh", "pinToTop": "Prikvači na vrh",
"unpinFromTop": "Otkvači sa vrha", "unpinFromTop": "Otkvači sa vrha",
"resetInstallStatusForSelectedAppsQuestion": "Resetujte status instalacije za odabrane aplikacije?", "resetInstallStatusForSelectedAppsQuestion": "Resetujte status instalacije za odabrane aplikacije?",
"installStatusOfXWillBeResetExplanation": "Status instalacije bilo koje odabrane aplikacije će se resetovati.\n\nTo može pomoći kada je verzija aplikacije prikazana u Obtainiumu netačna zbog neuspjelih ažuriranja ili drugih problema.", "installStatusOfXWillBeResetExplanation": "Status instalacije bilo koje odabrane aplikacije će se resetovati.\n\nTo može pomoći kada je verzija aplikacije prikazana u Obtainiumu netačna zbog neuspjelih ažuriranja ili drugih problema.",
"shareSelectedAppURLs": "Podijeli odabrane URL-ove aplikacija", "shareSelectedAppURLs": "Podijeli odabrane URL-ove aplikacija",
"resetInstallStatus": "Resetujte status instalacije", "resetInstallStatus": "Resetujte status instalacije",
"more": "Više", "more": "Više",
"removeOutdatedFilter": "Uklonite zastarjeli filter aplikacija", "removeOutdatedFilter": "Uklonite zastarjeli filter aplikacija",
"showOutdatedOnly": "Prikaži samo zastarjele aplikacije", "showOutdatedOnly": "Prikaži samo zastarjele aplikacije",
"filter": "Filtriranje", "filter": "Filtriranje",
"filterActive": "Filtriranje", "filterActive": "Filtriranje",
"filterApps": "Filtriraj aplikacije", "filterApps": "Filtriraj aplikacije",
"appName": "Naziv aplikacije", "appName": "Naziv aplikacije",
"author": "Autor", "author": "Autor",
"upToDateApps": "Ažurirane aplikacije", "upToDateApps": "Ažurirane aplikacije",
"nonInstalledApps": "Neinstalirane aplikacije", "nonInstalledApps": "Neinstalirane aplikacije",
"importExport": "Uvoz/izvoz", "importExport": "Uvoz/izvoz",
"settings": "Postavke", "settings": "Postavke",
"exportedTo": "Izvezeno u {}", "exportedTo": "Izvezeno u {}",
"obtainiumExport": "Obtainium Export", "obtainiumExport": "Obtainium Export",
"invalidInput": "Neispravan unos.", "invalidInput": "Neispravan unos.",
"importedX": "Uvezeno {}", "importedX": "Uvezeno {}",
"obtainiumImport": "Obtainium uvoz", "obtainiumImport": "Obtainium uvoz",
"importFromURLList": "Uvoz iz URL liste", "importFromURLList": "Uvoz iz URL liste",
"searchQuery": "Pretraga za: ", "searchQuery": "Pretraga za: ",
"appURLList": "Lista URL adresa aplikacija", "appURLList": "Lista URL adresa aplikacija",
"line": "Linija", "line": "Linija",
"searchX": "Pretraživanje {}", "searchX": "Pretraživanje {}",
"noResults": "Nema rezultata", "noResults": "Nema rezultata",
"importX": "Uvoz {}", "importX": "Uvoz {}",
"importedAppsIdDisclaimer": "Uvezene aplikacije mogu se pogrešno prikazati kao „Nije instalirano”.\nDa biste to riješili, ponovo ih instalirajte putem aplikacije Obtainium.\nTo ne bi trebalo uticati na podatke aplikacije.\n\nUtječe samo na URL i metode uvoza treće strane.", "importedAppsIdDisclaimer": "Uvezene aplikacije mogu se pogrešno prikazati kao „Nije instalirano”.\nDa biste to riješili, ponovo ih instalirajte putem aplikacije Obtainium.\nTo ne bi trebalo uticati na podatke aplikacije.\n\nUtječe samo na URL i metode uvoza treće strane.",
"importErrors": "Uvezi greške", "importErrors": "Uvezi greške",
"importedXOfYApps": "{} od {} aplikacija uvezeno.", "importedXOfYApps": "{} od {} aplikacija uvezeno.",
"followingURLsHadErrors": "Sljedeći URL-ovi su imali greške:", "followingURLsHadErrors": "Sljedeći URL-ovi su imali greške:",
"okay": "Dobro", "okay": "Dobro",
"selectURL": "Odaberite URL", "selectURL": "Odaberite URL",
"selectURLs": "Odaberite URL-ove", "selectURLs": "Odaberite URL-ove",
"pick": "Odaberi", "pick": "Odaberi",
"theme": "Tema", "theme": "Tema",
"dark": "Tamna", "dark": "Tamna",
"light": "Svijetla", "light": "Svijetla",
"followSystem": "Pratite sistem", "followSystem": "Pratite sistem",
"obtainium": "Obtainium", "obtainium": "Obtainium",
"materialYou": "Material You", "materialYou": "Material You",
"useBlackTheme": "Koristite čisto crnu tamnu temu", "useBlackTheme": "Koristite čisto crnu tamnu temu",
"appSortBy": "Aplikacije sortirane po", "appSortBy": "Aplikacije sortirane po",
"authorName": "Autor/Ime", "authorName": "Autor/Ime",
"nameAuthor": "Ime/Autor", "nameAuthor": "Ime/Autor",
"asAdded": "Kao što je dodano", "asAdded": "Kao što je dodano",
"appSortOrder": "Redoslijed sortiranja aplikacija", "appSortOrder": "Redoslijed sortiranja aplikacija",
"ascending": "Uzlazno", "ascending": "Uzlazno",
"descending": "Silazno", "descending": "Silazno",
"bgUpdateCheckInterval": "Interval provjere ažuriranja u pozadini", "bgUpdateCheckInterval": "Interval provjere ažuriranja u pozadini",
"neverManualOnly": "Nikada - samo ručno", "neverManualOnly": "Nikada - samo ručno",
"appearance": "Izgled", "appearance": "Izgled",
"showWebInAppView": "Prikaži izvornu web stranicu u prikazu aplikacije", "showWebInAppView": "Prikaži izvornu web stranicu u prikazu aplikacije",
"pinUpdates": "Prikvačite ažuriranja na vrh prikaza aplikacija", "pinUpdates": "Prikvačite ažuriranja na vrh prikaza aplikacija",
"updates": "Nadogradnje", "updates": "Nadogradnje",
"sourceSpecific": "Specifično za izvor", "sourceSpecific": "Specifično za izvor",
"appSource": "Izvor aplikacije", "appSource": "Izvor aplikacije",
"noLogs": "Nema evidencije", "noLogs": "Nema evidencije",
"appLogs": "Evidencije aplikacija", "appLogs": "Evidencije aplikacija",
"close": "Zatvori", "close": "Zatvori",
"share": "Podijeli", "share": "Podijeli",
"appNotFound": "Aplikacija nije pronađena", "appNotFound": "Aplikacija nije pronađena",
"obtainiumExportHyphenatedLowercase": "obtainium-export", "obtainiumExportHyphenatedLowercase": "obtainium-export",
"pickAnAPK": "Odaberite APK", "pickAnAPK": "Odaberite APK",
"appHasMoreThanOnePackage": "{} ima više od jednog paketa:", "appHasMoreThanOnePackage": "{} ima više od jednog paketa:",
"deviceSupportsXArch": "Vaš uređaj podržava {} arhitekturu procesora.", "deviceSupportsXArch": "Vaš uređaj podržava {} arhitekturu procesora.",
"deviceSupportsFollowingArchs": "Vaš uređaj podržava sljedeće arhitekture procesora:", "deviceSupportsFollowingArchs": "Vaš uređaj podržava sljedeće arhitekture procesora:",
"warning": "Upozorenje", "warning": "Upozorenje",
"sourceIsXButPackageFromYPrompt": "Izvor aplikacije je '{}', ali paket za izdavanje dolazi iz '{}'. Želite li nastaviti?", "sourceIsXButPackageFromYPrompt": "Izvor aplikacije je '{}', ali paket za izdavanje dolazi iz '{}'. Želite li nastaviti?",
"updatesAvailable": "Dostupna ažuriranja", "updatesAvailable": "Dostupna ažuriranja",
"updatesAvailableNotifDescription": "Obavještava korisnika da su ažuriranja dostupna za jednu ili više aplikacija koje prati Obtainium", "updatesAvailableNotifDescription": "Obavještava korisnika da su ažuriranja dostupna za jednu ili više aplikacija koje prati Obtainium",
"noNewUpdates": "Nema novih ažuriranja.", "noNewUpdates": "Nema novih ažuriranja.",
"xHasAnUpdate": "{} ima ažuriranje.", "xHasAnUpdate": "{} ima ažuriranje.",
"appsUpdated": "Aplikacije su ažurirane", "appsUpdated": "Aplikacije su ažurirane",
"appsUpdatedNotifDescription": "Obavještava korisnika da su u pozadini primijenjena ažuriranja na jednu ili više aplikacija", "appsUpdatedNotifDescription": "Obavještava korisnika da su u pozadini primijenjena ažuriranja na jednu ili više aplikacija",
"xWasUpdatedToY": "{} je ažuriran na {}.", "xWasUpdatedToY": "{} je ažuriran na {}.",
"errorCheckingUpdates": "Greška pri provjeri ažuriranja", "errorCheckingUpdates": "Greška pri provjeri ažuriranja",
"errorCheckingUpdatesNotifDescription": "Obavijest koja se prikazuje kada provjera sigurnosnog ažuriranja ne uspije", "errorCheckingUpdatesNotifDescription": "Obavijest koja se prikazuje kada provjera sigurnosnog ažuriranja ne uspije",
"appsRemoved": "Aplikacije su uklonjene", "appsRemoved": "Aplikacije su uklonjene",
"appsRemovedNotifDescription": "Obavještava korisnika da je jedna ili više aplikacija uklonjeno zbog grešaka prilikom učitavanja", "appsRemovedNotifDescription": "Obavještava korisnika da je jedna ili više aplikacija uklonjeno zbog grešaka prilikom učitavanja",
"xWasRemovedDueToErrorY": "{} je uklonjen zbog ove greške: {}", "xWasRemovedDueToErrorY": "{} je uklonjen zbog ove greške: {}",
"completeAppInstallation": "Dovršite instalaciju aplikacije", "completeAppInstallation": "Dovršite instalaciju aplikacije",
"obtainiumMustBeOpenToInstallApps": "Obtainium mora biti otvoren za instalaciju aplikacija", "obtainiumMustBeOpenToInstallApps": "Obtainium mora biti otvoren za instalaciju aplikacija",
"completeAppInstallationNotifDescription": "Traži od korisnika da se vrati u Obtainium kako bi dovršio instalaciju aplikacije", "completeAppInstallationNotifDescription": "Traži od korisnika da se vrati u Obtainium kako bi dovršio instalaciju aplikacije",
"checkingForUpdates": "Tražim moguće nadogradnje", "checkingForUpdates": "Tražim moguće nadogradnje",
"checkingForUpdatesNotifDescription": "Privremeno obavještenje koje se pojavljuje prilikom provjere ažuriranja", "checkingForUpdatesNotifDescription": "Privremeno obavještenje koje se pojavljuje prilikom provjere ažuriranja",
"pleaseAllowInstallPerm": "Dozvolite Obtainiumu da instalira aplikacije", "pleaseAllowInstallPerm": "Dozvolite Obtainiumu da instalira aplikacije",
"trackOnly": "Samo za praćenje", "trackOnly": "Samo za praćenje",
"errorWithHttpStatusCode": "Greška {}", "errorWithHttpStatusCode": "Greška {}",
"versionCorrectionDisabled": "Ispravka verzije je onemogućena (izgleda da plugin ne radi)", "versionCorrectionDisabled": "Ispravka verzije je onemogućena (izgleda da plugin ne radi)",
"unknown": "Nepoznato", "unknown": "Nepoznato",
"none": "Ništa", "none": "Ništa",
"never": "Nikad", "never": "Nikad",
"latestVersionX": "Najnovija verzija: {}", "latestVersionX": "Najnovija verzija: {}",
"installedVersionX": "Instalirana verzija: {}", "installedVersionX": "Instalirana verzija: {}",
"lastUpdateCheckX": "Posljednja provjera ažuriranja: {}", "lastUpdateCheckX": "Posljednja provjera ažuriranja: {}",
"remove": "Izbriši", "remove": "Izbriši",
"yesMarkUpdated": "Da, označi kao ažurirano", "yesMarkUpdated": "Da, označi kao ažurirano",
"fdroid": "F-Droid Official", "fdroid": "F-Droid Official",
"appIdOrName": "ID ili ime aplikacije", "appIdOrName": "ID ili ime aplikacije",
"appId": "Apl ID", "appId": "Apl ID",
"appWithIdOrNameNotFound": "Nije pronađena aplikacija s tim ID-om ili imenom", "appWithIdOrNameNotFound": "Nije pronađena aplikacija s tim ID-om ili imenom",
"reposHaveMultipleApps": "Repo-i mogu sadržavati više aplikacija", "reposHaveMultipleApps": "Repo-i mogu sadržavati više aplikacija",
"fdroidThirdPartyRepo": "F-Droid Repo treće strane", "fdroidThirdPartyRepo": "F-Droid Repo treće strane",
"steam": "Steam", "steam": "Steam",
"steamMobile": "Steam Mobile", "steamMobile": "Steam Mobile",
"steamChat": "Razgovor na Steamu (chat)", "steamChat": "Razgovor na Steamu (chat)",
"install": "Instaliraj", "install": "Instaliraj",
"markInstalled": "Označi kao instalirano", "markInstalled": "Označi kao instalirano",
"update": "Nadogradi", "update": "Nadogradi",
"markUpdated": "Označi kao ažurirano", "markUpdated": "Označi kao ažurirano",
"additionalOptions": "Dodatne opcije", "additionalOptions": "Dodatne opcije",
"disableVersionDetection": "Onemogući detekciju verzije", "disableVersionDetection": "Onemogući detekciju verzije",
"noVersionDetectionExplanation": "Ova opcija bi se trebala koristiti samo za aplikacije gdje detekcija verzije ne radi ispravno.", "noVersionDetectionExplanation": "Ova opcija bi se trebala koristiti samo za aplikacije gdje detekcija verzije ne radi ispravno.",
"downloadingX": "Preuzimanje {}", "downloadingX": "Preuzimanje {}",
"downloadNotifDescription": "Obavještava korisnika o napretku u preuzimanju aplikacije", "downloadNotifDescription": "Obavještava korisnika o napretku u preuzimanju aplikacije",
"noAPKFound": "APK nije pronađen", "noAPKFound": "APK nije pronađen",
"noVersionDetection": "Nema detekcije verzije", "noVersionDetection": "Nema detekcije verzije",
"categorize": "Kategoriziraj", "categorize": "Kategoriziraj",
"categories": "Kategorije", "categories": "Kategorije",
"category": "Kategorija", "category": "Kategorija",
"noCategory": "Nema kategorije", "noCategory": "Nema kategorije",
"noCategories": "Nema kategorija", "noCategories": "Nema kategorija",
"deleteCategoriesQuestion": "Želite li izbrisati kategorije?", "deleteCategoriesQuestion": "Želite li izbrisati kategorije?",
"categoryDeleteWarning": "Sve aplikacije u izbrisanim kategorijama će biti postavljene kao nekategorisane.", "categoryDeleteWarning": "Sve aplikacije u izbrisanim kategorijama će biti postavljene kao nekategorisane.",
"addCategory": "Dodaj kategoriju", "addCategory": "Dodaj kategoriju",
"label": "Oznaka", "label": "Oznaka",
"language": "Jezik", "language": "Jezik",
"copiedToClipboard": "Podaci kopirani u međuspremnik", "copiedToClipboard": "Podaci kopirani u međuspremnik",
"storagePermissionDenied": "Dozvola za pohranu je odbijena", "storagePermissionDenied": "Dozvola za pohranu je odbijena",
"selectedCategorizeWarning": "Ovo će zamijeniti sve postojeće postavke kategorije za odabrane aplikacije.", "selectedCategorizeWarning": "Ovo će zamijeniti sve postojeće postavke kategorije za odabrane aplikacije.",
"filterAPKsByRegEx": "Filtrirajte APK-ove prema regularnom izrazu", "filterAPKsByRegEx": "Filtrirajte APK-ove prema regularnom izrazu",
"removeFromObtainium": "Ukloni iz Obtainiuma", "removeFromObtainium": "Ukloni iz Obtainiuma",
"uninstallFromDevice": "Deinstaliraj s uređaja", "uninstallFromDevice": "Deinstaliraj s uređaja",
"onlyWorksWithNonVersionDetectApps": "Radi samo za aplikacije s onemogućenom detekcijom verzije.", "onlyWorksWithNonVersionDetectApps": "Radi samo za aplikacije s onemogućenom detekcijom verzije.",
"releaseDateAsVersion": "Koristi datum izdanja kao verziju", "releaseDateAsVersion": "Koristi datum izdanja kao verziju",
"releaseDateAsVersionExplanation": "Ova opcija bi se trebala koristiti samo za aplikacije gdje detekcija verzije ne radi ispravno, ali je datum izdavanja dostupan.", "releaseDateAsVersionExplanation": "Ova opcija bi se trebala koristiti samo za aplikacije gdje detekcija verzije ne radi ispravno, ali je datum izdavanja dostupan.",
"changes": "Promjene", "changes": "Promjene",
"releaseDate": "Datum izdavanja", "releaseDate": "Datum izdavanja",
"importFromURLsInFile": "Uvoz iz URL-ova u datoteci (kao što je OPML)", "importFromURLsInFile": "Uvoz iz URL-ova u datoteci (kao što je OPML)",
"versionDetection": "Otkrivanje verzije", "versionDetection": "Otkrivanje verzije",
"standardVersionDetection": "Detekcija standardne verzije", "standardVersionDetection": "Detekcija standardne verzije",
"groupByCategory": "Grupiši po kategoriji", "groupByCategory": "Grupiši po kategoriji",
"autoApkFilterByArch": "Pokušajte filtrirati APK-ove po arhitekturi procesora ako je moguće", "autoApkFilterByArch": "Pokušajte filtrirati APK-ove po arhitekturi procesora ako je moguće",
"overrideSource": "Premosti izvor", "overrideSource": "Premosti izvor",
"dontShowAgain": "Ne prikazuj ovo ponovo", "dontShowAgain": "Ne prikazuj ovo ponovo",
"dontShowTrackOnlyWarnings": "Ne prikazuj upozorenja „Samo za praćenje”", "dontShowTrackOnlyWarnings": "Ne prikazuj upozorenja „Samo za praćenje”",
"dontShowAPKOriginWarnings": "Ne prikazuj upozorenja o porijeklu APK-a", "dontShowAPKOriginWarnings": "Ne prikazuj upozorenja o porijeklu APK-a",
"moveNonInstalledAppsToBottom": "Premjesti neinstalirane aplikacije na dno prikaza aplikacija", "moveNonInstalledAppsToBottom": "Premjesti neinstalirane aplikacije na dno prikaza aplikacija",
"gitlabPATLabel": "GitLab token za lični pristup\n(Omogućava pretraživanje i bolje otkrivanje APK-a)", "gitlabPATLabel": "GitLab token za lični pristup\n(Omogućava pretraživanje i bolje otkrivanje APK-a)",
"about": "O nama", "about": "O nama",
"requiresCredentialsInSettings": "Za ovo su potrebni dodatni akreditivi (u Postavkama)", "requiresCredentialsInSettings": "Za ovo su potrebni dodatni akreditivi (u Postavkama)",
"checkOnStart": "Provjerite ima li novosti pri pokretanju", "checkOnStart": "Provjerite ima li novosti pri pokretanju",
"tryInferAppIdFromCode": "Pokušati otkriti ID aplikacije iz izvornog koda", "tryInferAppIdFromCode": "Pokušati otkriti ID aplikacije iz izvornog koda",
"removeOnExternalUninstall": "Automatski ukloni eksterno deinstalirane aplikacije", "removeOnExternalUninstall": "Automatski ukloni eksterno deinstalirane aplikacije",
"pickHighestVersionCode": "Automatski odaberite najviši kôd verzije APK-a", "pickHighestVersionCode": "Automatski odaberite najviši kôd verzije APK-a",
"checkUpdateOnDetailPage": "Provjerite ima li novosti pri otvaranju stranice s detaljima aplikacije", "checkUpdateOnDetailPage": "Provjerite ima li novosti pri otvaranju stranice s detaljima aplikacije",
"disablePageTransitions": "Ugasite animaciju prijelaza stranice", "disablePageTransitions": "Ugasite animaciju prijelaza stranice",
"reversePageTransitions": "Reverzne animacije prijelaza stranice", "reversePageTransitions": "Reverzne animacije prijelaza stranice",
"minStarCount": "Minimum Star Count", "minStarCount": "Minimum Star Count",
"addInfoBelow": "Add this info below.", "addInfoBelow": "Add this info below.",
"addInfoInSettings": "Add this info in the Settings.", "addInfoInSettings": "Add this info in the Settings.",
"githubSourceNote": "GitHub rate limiting can be avoided using an API key.", "githubSourceNote": "GitHub rate limiting can be avoided using an API key.",
"gitlabSourceNote": "GitLab APK extraction may not work without an API key.", "gitlabSourceNote": "GitLab APK extraction may not work without an API key.",
"sortByFileNamesNotLinks": "Sort by file names instead of full links", "sortByFileNamesNotLinks": "Sort by file names instead of full links",
"filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression",
"customLinkFilterRegex": "Custom APK Link Filter by Regular Expression (Default '.apk$')", "customLinkFilterRegex": "Custom APK Link Filter by Regular Expression (Default '.apk$')",
"appsPossiblyUpdated": "App Updates Attempted", "appsPossiblyUpdated": "App Updates Attempted",
"appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background",
"xWasPossiblyUpdatedToY": "{} may have been updated to {}.", "xWasPossiblyUpdatedToY": "{} may have been updated to {}.",
"backgroundUpdateReqsExplanation": "Background updates may not be possible for all apps.", "enableBackgroundUpdates": "Enable background updates",
"backgroundUpdateLimitsExplanation": "The success of a background install can only be determined when Obtainium is opened.", "backgroundUpdateReqsExplanation": "Background updates may not be possible for all apps.",
"verifyLatestTag": "Verify the 'latest' tag", "backgroundUpdateLimitsExplanation": "The success of a background install can only be determined when Obtainium is opened.",
"exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", "verifyLatestTag": "Verify the 'latest' tag",
"bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", "intermediateLinkRegex": "Filter for an 'Intermediate' Link to Visit First",
"autoSelectHighestVersionCode": "Auto-select highest versionCode APK", "intermediateLinkNotFound": "Intermediate link not found",
"versionExtractionRegEx": "Version Extraction RegEx", "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)",
"matchGroupToUse": "Match Group to Use", "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi",
"highlightTouchTargets": "Highlight less obvious touch targets", "autoSelectHighestVersionCode": "Auto-select highest versionCode APK",
"pickExportDir": "Pick Export Directory", "versionExtractionRegEx": "Version Extraction RegEx",
"autoExportOnChanges": "Auto-export on changes", "matchGroupToUse": "Match Group to Use",
"filterVersionsByRegEx": "Filter Versions by Regular Expression", "highlightTouchTargets": "Highlight less obvious touch targets",
"trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", "pickExportDir": "Pick Export Directory",
"dontSortReleasesList": "Retain release order from API", "autoExportOnChanges": "Auto-export on changes",
"reverseSort": "Reverse sorting", "filterVersionsByRegEx": "Filter Versions by Regular Expression",
"debugMenu": "Debug Menu", "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK",
"bgTaskStarted": "Background task started - check logs.", "dontSortReleasesList": "Retain release order from API",
"runBgCheckNow": "Run Background Update Check Now", "reverseSort": "Reverse sorting",
"removeAppQuestion": { "debugMenu": "Debug Menu",
"one": "Želite li ukloniti aplikaciju?", "bgTaskStarted": "Background task started - check logs.",
"other": "Želite li ukloniti aplikacije?" "runBgCheckNow": "Run Background Update Check Now",
}, "versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"tooManyRequestsTryAgainInMinutes": { "installing": "Installing",
"one": "Previše zahtjeva (ograničena broj zahteva) - pokušajte ponovo za {} minutu", "skipUpdateNotifications": "Skip update notifications",
"other": "Previše zahtjeva (ograničena cijena) - pokušajte ponovo za {} min." "updatesAvailableNotifChannel": "Dostupna ažuriranja",
}, "appsUpdatedNotifChannel": "Aplikacije su ažurirane",
"bgUpdateGotErrorRetryInMinutes": { "appsPossiblyUpdatedNotifChannel": "App Updates Attempted",
"one": "Provjera ažuriranja u pozadini naišla je na {}, zakazuje se ponovni pokušaj za {} minutu", "errorCheckingUpdatesNotifChannel": "Greška pri provjeri ažuriranja",
"other": "Provjera ažuriranja u pozadini naišla je na {}, zakazuje se ponovni pokušaj za {} min." "appsRemovedNotifChannel": "Aplikacije su uklonjene",
}, "downloadingXNotifChannel": "Preuzimanje {}",
"bgCheckFoundUpdatesWillNotifyIfNeeded": { "completeAppInstallationNotifChannel": "Dovršite instalaciju aplikacije",
"one": "Provjera ažuriranja u pozadini je pronašla {} ažuriranje - korisnik će biti obavješten ako je to potrebno", "checkingForUpdatesNotifChannel": "Tražim moguće nadogradnje",
"other": "Provjera ažuriranja u pozadini je pronašla {} ažuriranja - korisnik će biti obavješten ako je to potrebno" "removeAppQuestion": {
}, "one": "Želite li ukloniti aplikaciju?",
"apps": { "other": "Želite li ukloniti aplikacije?"
"one": "{} aplikacija", },
"other": "{} aplikacije" "tooManyRequestsTryAgainInMinutes": {
}, "one": "Previše zahtjeva (ograničena broj zahteva) - pokušajte ponovo za {} minutu",
"url": { "other": "Previše zahtjeva (ograničena cijena) - pokušajte ponovo za {} min."
"one": "{} URL", },
"other": "{} URL-ovi" "bgUpdateGotErrorRetryInMinutes": {
}, "one": "Provjera ažuriranja u pozadini naišla je na {}, zakazuje se ponovni pokušaj za {} minutu",
"minute": { "other": "Provjera ažuriranja u pozadini naišla je na {}, zakazuje se ponovni pokušaj za {} min."
"one": "{} minuta", },
"other": "min." "bgCheckFoundUpdatesWillNotifyIfNeeded": {
}, "one": "Provjera ažuriranja u pozadini je pronašla {} ažuriranje - korisnik će biti obavješten ako je to potrebno",
"hour": { "other": "Provjera ažuriranja u pozadini je pronašla {} ažuriranja - korisnik će biti obavješten ako je to potrebno"
"one": "{} sat", },
"other": "{} sat/i" "apps": {
}, "one": "{} aplikacija",
"day": { "other": "{} aplikacije"
"one": "{} dan", },
"other": "{} dana" "url": {
}, "one": "{} URL",
"clearedNLogsBeforeXAfterY": { "other": "{} URL-ovi"
"one": "Izbrisan {n} log (prije = {before}, nakon = {after})", },
"other": "Izbrisano {n} log-ova (prije = {before}, nakon = {after})" "minute": {
}, "one": "{} minuta",
"xAndNMoreUpdatesAvailable": { "other": "min."
"one": "{} i još 1 aplikacija ima ažuriranja.", },
"other": "{} i još {} aplikacija imaju ažuriranja." "hour": {
}, "one": "{} sat",
"xAndNMoreUpdatesInstalled": { "other": "{} sat/i"
"one": "{} i još 1 aplikacija je ažurirana.", },
"other": "{} i još {} aplikacija je ažurirano." "day": {
}, "one": "{} dan",
"xAndNMoreUpdatesPossiblyInstalled": { "other": "{} dana"
"one": "{} and 1 more app may have been updated.", },
"other": "{} and {} more apps may have been updated." "clearedNLogsBeforeXAfterY": {
} "one": "Izbrisan {n} log (prije = {before}, nakon = {after})",
} "other": "Izbrisano {n} log-ova (prije = {before}, nakon = {after})"
},
"xAndNMoreUpdatesAvailable": {
"one": "{} i još 1 aplikacija ima ažuriranja.",
"other": "{} i još {} aplikacija imaju ažuriranja."
},
"xAndNMoreUpdatesInstalled": {
"one": "{} i još 1 aplikacija je ažurirana.",
"other": "{} i još {} aplikacija je ažurirano."
},
"xAndNMoreUpdatesPossiblyInstalled": {
"one": "{} and 1 more app may have been updated.",
"other": "{} and {} more apps may have been updated."
}
}

View File

@ -25,7 +25,7 @@
"githubStarredRepos": "GitHub Starred Repos", "githubStarredRepos": "GitHub Starred Repos",
"uname": "username", "uname": "username",
"wrongArgNum": "Špatný počet předložených argumentů", "wrongArgNum": "Špatný počet předložených argumentů",
"xIsTrackOnly":"{} je určeno pouze pro sledování", "xIsTrackOnly": "{} je určeno pouze pro sledování",
"source": "zdroj", "source": "zdroj",
"app": "App", "app": "App",
"appsFromSourceAreTrackOnly": "Aplikace z tohoto zdroje jsou 'Jen sledovány'.", "appsFromSourceAreTrackOnly": "Aplikace z tohoto zdroje jsou 'Jen sledovány'.",
@ -56,7 +56,7 @@
"estimateInBrackets": "(přibližně)", "estimateInBrackets": "(přibližně)",
"selectAll": "Vybrat Vše", "selectAll": "Vybrat Vše",
"deselectN": "{} deselected", "deselectN": "{} deselected",
"xWillBeRemovedButRemainInstalled":"{} bude odstraněn z Obtainium, ale zůstane nainstalován v zařízení.", "xWillBeRemovedButRemainInstalled": "{} bude odstraněn z Obtainium, ale zůstane nainstalován v zařízení.",
"removeSelectedAppsQuestion": "Odebrat vybrané aplikace?", "removeSelectedAppsQuestion": "Odebrat vybrané aplikace?",
"removeSelectedApps": "Odebrat vybrané aplikace", "removeSelectedApps": "Odebrat vybrané aplikace",
"updateX": "Aktualizovat {}", "updateX": "Aktualizovat {}",
@ -101,7 +101,7 @@
"importX": "Import {}", "importX": "Import {}",
"importedAppsIdDisclaimer": "Importované aplikace mohou být nesprávně zobrazeny jako \"Neinstalované\". Chcete-li to opravit, nainstalujte je znovu prostřednictvím Obtainium. To nemá vliv na data aplikací. Ovlivňuje pouze metody importu URL a třetích stran.", "importedAppsIdDisclaimer": "Importované aplikace mohou být nesprávně zobrazeny jako \"Neinstalované\". Chcete-li to opravit, nainstalujte je znovu prostřednictvím Obtainium. To nemá vliv na data aplikací. Ovlivňuje pouze metody importu URL a třetích stran.",
"importErrors": "Import Errors", "importErrors": "Import Errors",
"importedXOfYApps":"{}importováno {}aplikací.", "importedXOfYApps": "{}importováno {}aplikací.",
"followingURLsHadErrors": "U následujících adres URL došlo k chybám:", "followingURLsHadErrors": "U následujících adres URL došlo k chybám:",
"okay": "Okay", "okay": "Okay",
"selectURL": "Select URL", "selectURL": "Select URL",
@ -136,7 +136,7 @@
"appNotFound": "App not found", "appNotFound": "App not found",
"obtainiumExportHyphenatedLowercase": "obtainium-export", "obtainiumExportHyphenatedLowercase": "obtainium-export",
"pickAnAPK": "Vybrat APK", "pickAnAPK": "Vybrat APK",
"appHasMoreThanOnePackage":"{} má více než jeden balíček:", "appHasMoreThanOnePackage": "{} má více než jeden balíček:",
"deviceSupportsXArch": "Vaše zařízení podporuje architekturu CPU {}.", "deviceSupportsXArch": "Vaše zařízení podporuje architekturu CPU {}.",
"deviceSupportsFollowingArchs": "Vaše zařízení podporuje následující architektury CPU:", "deviceSupportsFollowingArchs": "Vaše zařízení podporuje následující architektury CPU:",
"warning": "Varování", "warning": "Varování",
@ -144,15 +144,15 @@
"updatesAvailable": "dostupné aktualizace", "updatesAvailable": "dostupné aktualizace",
"updatesAvailableNotifDescription": "Upozorňuje uživatele, že jsou k dispozici aktualizace pro jednu nebo více aplikací sledovaných Obtainium", "updatesAvailableNotifDescription": "Upozorňuje uživatele, že jsou k dispozici aktualizace pro jednu nebo více aplikací sledovaných Obtainium",
"noNewUpdates": "Žádné nové aktualizace.", "noNewUpdates": "Žádné nové aktualizace.",
"xHasAnUpdate":"{} má aktualizaci.", "xHasAnUpdate": "{} má aktualizaci.",
"appsUpdated": "Aplikace aktualizovány", "appsUpdated": "Aplikace aktualizovány",
"appsUpdatedNotifDescription": "Upozorňuje uživatele, že byly provedeny aktualizace jedné nebo více aplikací na pozadí", "appsUpdatedNotifDescription": "Upozorňuje uživatele, že byly provedeny aktualizace jedné nebo více aplikací na pozadí",
"xWasUpdatedToY":"{} byl aktualizován na {}", "xWasUpdatedToY": "{} byl aktualizován na {}",
"errorCheckingUpdates": "Chybová kontrola aktualizací", "errorCheckingUpdates": "Chybová kontrola aktualizací",
"errorCheckingUpdatesNotifDescription": "Oznámení zobrazené při neúspěšné kontrole aktualizací na pozadí", "errorCheckingUpdatesNotifDescription": "Oznámení zobrazené při neúspěšné kontrole aktualizací na pozadí",
"appsRemoved": "Odstraněné aplikace", "appsRemoved": "Odstraněné aplikace",
"appsRemovedNotifDescription": "Oznámení uživateli, že jedna nebo více aplikací byly odstraněny z důvodu chyb při načítání", "appsRemovedNotifDescription": "Oznámení uživateli, že jedna nebo více aplikací byly odstraněny z důvodu chyb při načítání",
"xWasRemovedDueToErrorY":"{} byla odstraněna z důvodu následující chyby: {}", "xWasRemovedDueToErrorY": "{} byla odstraněna z důvodu následující chyby: {}",
"completeAppInstallation": "Dokončit instalaci aplikace", "completeAppInstallation": "Dokončit instalaci aplikace",
"obtainiumMustBeOpenToInstallApps": "Obtainium musí být otevřeno, aby bylo možné instalovat aplikace", "obtainiumMustBeOpenToInstallApps": "Obtainium musí být otevřeno, aby bylo možné instalovat aplikace",
"completeAppInstallationNotifDescription": "Vyzvat uživatele k návratu do Obtainium pro dokončení instalace aplikací", "completeAppInstallationNotifDescription": "Vyzvat uživatele k návratu do Obtainium pro dokončení instalace aplikací",
@ -241,7 +241,7 @@
"customLinkFilterRegex": "Vlastní filtr odkazů APK podle regulárního výrazu (výchozí '.apk$')", "customLinkFilterRegex": "Vlastní filtr odkazů APK podle regulárního výrazu (výchozí '.apk$')",
"appsPossiblyUpdated": "Byly provedeny pokusy o aktualizaci aplikací", "appsPossiblyUpdated": "Byly provedeny pokusy o aktualizaci aplikací",
"appsPossiblyUpdatedNotifDescription": "Upozorňuje uživatele, že na pozadí mohly být provedeny aktualizace jedné nebo více aplikací", "appsPossiblyUpdatedNotifDescription": "Upozorňuje uživatele, že na pozadí mohly být provedeny aktualizace jedné nebo více aplikací",
"xWasPossiblyUpdatedToY":"{} mohlo být aktualizováno na {}.", "xWasPossiblyUpdatedToY": "{} mohlo být aktualizováno na {}.",
"enableBackgroundUpdates": "Povolit aktualizace na pozadí", "enableBackgroundUpdates": "Povolit aktualizace na pozadí",
"backgroundUpdateReqsExplanation": "Aktualizace na pozadí nemusí být možné pro všechny aplikace.", "backgroundUpdateReqsExplanation": "Aktualizace na pozadí nemusí být možné pro všechny aplikace.",
"backgroundUpdateLimitsExplanation": "Úspěšnost instalace na pozadí lze určit pouze v případě, že je otevřen Obtainium.", "backgroundUpdateLimitsExplanation": "Úspěšnost instalace na pozadí lze určit pouze v případě, že je otevřen Obtainium.",
@ -263,6 +263,17 @@
"debugMenu": "Debug Menu", "debugMenu": "Debug Menu",
"bgTaskStarted": "Background task started - check logs.", "bgTaskStarted": "Background task started - check logs.",
"runBgCheckNow": "Run Background Update Check Now", "runBgCheckNow": "Run Background Update Check Now",
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"installing": "Installing",
"skipUpdateNotifications": "Skip update notifications",
"updatesAvailableNotifChannel": "dostupné aktualizace",
"appsUpdatedNotifChannel": "Aplikace aktualizovány",
"appsPossiblyUpdatedNotifChannel": "Byly provedeny pokusy o aktualizaci aplikací",
"errorCheckingUpdatesNotifChannel": "Chybová kontrola aktualizací",
"appsRemovedNotifChannel": "Odstraněné aplikace",
"downloadingXNotifChannel": "download {}",
"completeAppInstallationNotifChannel": "Dokončit instalaci aplikace",
"checkingForUpdatesNotifChannel": "Zkontrolovat aktualizace",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Odstranit Apku?", "one": "Odstranit Apku?",
"other": "Odstranit Apky?" "other": "Odstranit Apky?"
@ -280,15 +291,15 @@
"other": "Kontrola aktualizací na pozadí našla {} aktualizací - v případě potřeby upozorní uživatele" "other": "Kontrola aktualizací na pozadí našla {} aktualizací - v případě potřeby upozorní uživatele"
}, },
"apps": { "apps": {
"one":"{} App", "one": "{} App",
"other":"{} apps" "other": "{} apps"
}, },
"url": { "url": {
"jedna": "{} URL", "jedna": "{} URL",
"other": "{} URLs" "other": "{} URLs"
}, },
"minute": { "minute": {
"one":"{} minute", "one": "{} minute",
"other": "{} minutes" "other": "{} minutes"
}, },
"hour": { "hour": {
@ -300,20 +311,19 @@
"other": "{} dny" "other": "{} dny"
}, },
"clearedNLogsBeforeXAfterY": { "clearedNLogsBeforeXAfterY": {
"one":"{n} log vymazán (před = {před}, po = {po})", "one": "{n} log vymazán (před = {před}, po = {po})",
"other": "{n} logů vymazáno (před = {před}, po = {po})" "other": "{n} logů vymazáno (před = {před}, po = {po})"
}, },
"xAndNMoreUpdatesAvailable": { "xAndNMoreUpdatesAvailable": {
"one":"{} a 1 další aplikace mají aktualizace.", "one": "{} a 1 další aplikace mají aktualizace.",
"other":"{} a {} další aplikace mají aktualizace." "other": "{} a {} další aplikace mají aktualizace."
}, },
"xAndNMoreUpdatesInstalled": { "xAndNMoreUpdatesInstalled": {
"one":"{} a {} další aplikace mají aktualizace.", "one": "{} a {} další aplikace mají aktualizace.",
"další":"{} a {} další aplikace byly aktualizovány." "další": "{} a {} další aplikace byly aktualizovány."
}, },
"xAndNMoreUpdatesPossiblyInstalled": { "xAndNMoreUpdatesPossiblyInstalled": {
"one":"{} a {} další aplikace byly možná aktualizovány", "one": "{} a {} další aplikace byly možná aktualizovány",
"other":"{} a {} další aplikace mohly být aktualizovány." "other": "{} a {} další aplikace mohly být aktualizovány."
} }
} }

View File

@ -122,15 +122,15 @@
"ascending": "Aufsteigend", "ascending": "Aufsteigend",
"descending": "Absteigend", "descending": "Absteigend",
"bgUpdateCheckInterval": "Prüfintervall für Hintergrundaktualisierung", "bgUpdateCheckInterval": "Prüfintervall für Hintergrundaktualisierung",
"neverManualOnly": "Nie - nur manuell", "neverManualOnly": "Nie nur manuell",
"appearance": "Aussehen", "appearance": "Aussehen",
"showWebInAppView": "Quellwebseite in der App-Ansicht anzeigen", "showWebInAppView": "Quellwebseite in der App-Ansicht anzeigen",
"pinUpdates": "Apps mit Aktualisierungen oben anheften", "pinUpdates": "Apps mit Aktualisierungen oben anheften",
"updates": "Aktualisierungen", "updates": "Aktualisierungen",
"sourceSpecific": "Quellenspezifisch", "sourceSpecific": "Quellenspezifisch",
"appSource": "App-Quelle", "appSource": "App-Quelle",
"noLogs": "Keine Protokolle", "noLogs": "Keine Logs",
"appLogs": "App Protokolle", "appLogs": "App-Logs",
"close": "Schließen", "close": "Schließen",
"share": "Teilen", "share": "Teilen",
"appNotFound": "App nicht gefunden", "appNotFound": "App nicht gefunden",
@ -242,9 +242,12 @@
"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 Updates 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",
"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.",
"backgroundUpdateLimitsExplanation": "Der Erfolg einer Hintergrundinstallation kann nur festgestellt werden, wenn Obtainium geöffnet wird.", "backgroundUpdateLimitsExplanation": "Der Erfolg einer Hintergrundinstallation kann nur festgestellt werden, wenn Obtainium geöffnet wird.",
"verifyLatestTag": "Überprüfe das „latest“ Tag", "verifyLatestTag": "Überprüfe das „latest“ Tag",
"intermediateLinkRegex": "Filter für einen \"Zwischen\"-Link, der zuerst besucht werden soll",
"intermediateLinkNotFound": "Zwischenlink nicht gefunden",
"exemptFromBackgroundUpdates": "Ausschluss von Hintergrundaktualisierungen (falls aktiviert)", "exemptFromBackgroundUpdates": "Ausschluss von Hintergrundaktualisierungen (falls aktiviert)",
"bgUpdatesOnWiFiOnly": "Hintergrundaktualisierungen deaktivieren, wenn kein WLAN vorhanden ist", "bgUpdatesOnWiFiOnly": "Hintergrundaktualisierungen deaktivieren, wenn kein WLAN vorhanden ist",
"autoSelectHighestVersionCode": "Automatisch höchste APK-Code-Version auswählen", "autoSelectHighestVersionCode": "Automatisch höchste APK-Code-Version auswählen",
@ -256,25 +259,36 @@
"filterVersionsByRegEx": "Versionen nach regulären Ausdrücken filtern", "filterVersionsByRegEx": "Versionen nach regulären Ausdrücken filtern",
"trySelectingSuggestedVersionCode": "Versuchen, die vorgeschlagene APK-Code-Version auszuwählen", "trySelectingSuggestedVersionCode": "Versuchen, die vorgeschlagene APK-Code-Version auszuwählen",
"dontSortReleasesList": "Retain release order from API", "dontSortReleasesList": "Retain release order from API",
"reverseSort": "Reverse sorting", "reverseSort": "Umgekehrtes Sortieren",
"debugMenu": "Debug Menu", "debugMenu": "Debug Menü",
"bgTaskStarted": "Background task started - check logs.", "bgTaskStarted": "Hintergrundaufgabe gestartet Logs prüfen.",
"runBgCheckNow": "Run Background Update Check Now", "runBgCheckNow": "Hintergrundaktualisierungsprüfung jetzt durchführen",
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"installing": "Installing",
"skipUpdateNotifications": "Skip update notifications",
"updatesAvailableNotifChannel": "Aktualisierungen verfügbar",
"appsUpdatedNotifChannel": "Apps aktualisiert",
"appsPossiblyUpdatedNotifChannel": "App Aktualisierungen wurden versucht",
"errorCheckingUpdatesNotifChannel": "Fehler beim Prüfen auf Aktualisierungen",
"appsRemovedNotifChannel": "Apps entfernt",
"downloadingXNotifChannel": "Lade {} herunter",
"completeAppInstallationNotifChannel": "App Installation abschließen",
"checkingForUpdatesNotifChannel": "Nach Aktualisierungen suchen",
"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) versuchen Sie es in {} Minute erneut",
"other": "Zu viele Anfragen (Rate begrenzt) - versuchen Sie es in {} Minuten erneut" "other": "Zu viele Anfragen (Rate begrenzt) versuchen Sie 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",
"other": "Bei der Aktualisierungsprüfung im Hintergrund wurde ein {} festgestellt, eine erneute Prüfung wird in {} Minuten geplant" "other": "Bei der Aktualisierungsprüfung im Hintergrund wurde ein {} festgestellt, eine erneute Prüfung wird in {} Minuten geplant"
}, },
"bgCheckFoundUpdatesWillNotifyIfNeeded": { "bgCheckFoundUpdatesWillNotifyIfNeeded": {
"one": "Hintergrundaktualisierungsprüfung fand {} Aktualisierung - benachrichtigt den Benutzer, falls erforderlich", "one": "Die Hintergrundaktualisierungsprüfung fand {} Aktualisierung benachrichtigt den Benutzer, falls erforderlich",
"other": "Hintergrundaktualisierungsprüfung fand {} Aktualisierungen - benachrichtigt den Benutzer, falls erforderlich" "other": "Die Hintergrundaktualisierungsprüfung fand {} Aktualisierungen benachrichtigt den Benutzer, falls erforderlich"
}, },
"apps": { "apps": {
"one": "{} App", "one": "{} App",
@ -297,8 +311,8 @@
"other": "{} Tage" "other": "{} Tage"
}, },
"clearedNLogsBeforeXAfterY": { "clearedNLogsBeforeXAfterY": {
"one": "{n} Protokoll gelöscht (vorher = {vorher}, nachher = {nachher})", "one": "{n} Log gelöscht (vorher = {before}, nachher = {after})",
"other": "{n} Protokolle gelöscht (vorher = {vorher}, nachher = {nachher})" "other": "{n} Logs gelöscht (vorher = {before}, nachher = {after})"
}, },
"xAndNMoreUpdatesAvailable": { "xAndNMoreUpdatesAvailable": {
"one": "{} und 1 weitere App haben Aktualisierungen.", "one": "{} und 1 weitere App haben Aktualisierungen.",
@ -312,4 +326,4 @@
"one": "{} und 1 weitere Anwendung wurden möglicherweise aktualisiert.", "one": "{} und 1 weitere Anwendung wurden möglicherweise aktualisiert.",
"other": "{} und {} weitere Anwendungen wurden möglicherweise aktualisiert." "other": "{} und {} weitere Anwendungen wurden möglicherweise aktualisiert."
} }
} }

View File

@ -252,7 +252,7 @@
"bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi",
"autoSelectHighestVersionCode": "Auto-select highest versionCode APK", "autoSelectHighestVersionCode": "Auto-select highest versionCode APK",
"versionExtractionRegEx": "Version Extraction RegEx", "versionExtractionRegEx": "Version Extraction RegEx",
"matchGroupToUse": "Match Group to Use", "matchGroupToUse": "Match Group to Use for Version Extraction Regex",
"highlightTouchTargets": "Highlight less obvious touch targets", "highlightTouchTargets": "Highlight less obvious touch targets",
"pickExportDir": "Pick Export Directory", "pickExportDir": "Pick Export Directory",
"autoExportOnChanges": "Auto-export on changes", "autoExportOnChanges": "Auto-export on changes",
@ -263,6 +263,17 @@
"debugMenu": "Debug Menu", "debugMenu": "Debug Menu",
"bgTaskStarted": "Background task started - check logs.", "bgTaskStarted": "Background task started - check logs.",
"runBgCheckNow": "Run Background Update Check Now", "runBgCheckNow": "Run Background Update Check Now",
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"installing": "Installing",
"skipUpdateNotifications": "Skip update notifications",
"updatesAvailableNotifChannel": "Updates Available",
"appsUpdatedNotifChannel": "Apps Updated",
"appsPossiblyUpdatedNotifChannel": "App Updates Attempted",
"errorCheckingUpdatesNotifChannel": "Error Checking for Updates",
"appsRemovedNotifChannel": "Apps Removed",
"downloadingXNotifChannel": "Downloading {}",
"completeAppInstallationNotifChannel": "Complete App Installation",
"checkingForUpdatesNotifChannel": "Checking for Updates",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Remove App?", "one": "Remove App?",
"other": "Remove Apps?" "other": "Remove Apps?"
@ -315,4 +326,4 @@
"one": "{} and 1 more app may have been updated.", "one": "{} and 1 more app may have been updated.",
"other": "{} and {} more apps may have been updated." "other": "{} and {} more apps may have been updated."
} }
} }

View File

@ -242,9 +242,12 @@
"appsPossiblyUpdated": "App Updates Attempted", "appsPossiblyUpdated": "App Updates Attempted",
"appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background",
"xWasPossiblyUpdatedToY": "{} may have been updated to {}.", "xWasPossiblyUpdatedToY": "{} may have been updated to {}.",
"enableBackgroundUpdates": "Enable background updates",
"backgroundUpdateReqsExplanation": "Background updates may not be possible for all apps.", "backgroundUpdateReqsExplanation": "Background updates may not be possible for all apps.",
"backgroundUpdateLimitsExplanation": "The success of a background install can only be determined when Obtainium is opened.", "backgroundUpdateLimitsExplanation": "The success of a background install can only be determined when Obtainium is opened.",
"verifyLatestTag": "Verify the 'latest' tag", "verifyLatestTag": "Verify the 'latest' tag",
"intermediateLinkRegex": "Filter for an 'Intermediate' Link to Visit First",
"intermediateLinkNotFound": "Intermediate link not found",
"exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)",
"bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi",
"autoSelectHighestVersionCode": "Auto-select highest versionCode APK", "autoSelectHighestVersionCode": "Auto-select highest versionCode APK",
@ -260,6 +263,17 @@
"debugMenu": "Debug Menu", "debugMenu": "Debug Menu",
"bgTaskStarted": "Background task started - check logs.", "bgTaskStarted": "Background task started - check logs.",
"runBgCheckNow": "Run Background Update Check Now", "runBgCheckNow": "Run Background Update Check Now",
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"installing": "Installing",
"skipUpdateNotifications": "Skip update notifications",
"updatesAvailableNotifChannel": "Actualizaciones Disponibles",
"appsUpdatedNotifChannel": "Aplicaciones Actualizadas",
"appsPossiblyUpdatedNotifChannel": "App Updates Attempted",
"errorCheckingUpdatesNotifChannel": "Error Buscando Actualizaciones",
"appsRemovedNotifChannel": "Aplicaciones Eliminadas",
"downloadingXNotifChannel": "Descargando {}",
"completeAppInstallationNotifChannel": "Instalación Completa de la Aplicación",
"checkingForUpdatesNotifChannel": "Buscando Actualizaciones",
"removeAppQuestion": { "removeAppQuestion": {
"one": "¿Eliminar Aplicación?", "one": "¿Eliminar Aplicación?",
"other": "¿Eliminar Aplicaciones?" "other": "¿Eliminar Aplicaciones?"
@ -312,4 +326,4 @@
"one": "{} and 1 more app may have been updated.", "one": "{} and 1 more app may have been updated.",
"other": "{} and {} more apps may have been updated." "other": "{} and {} more apps may have been updated."
} }
} }

View File

@ -242,9 +242,12 @@
"appsPossiblyUpdated": "App Updates Attempted", "appsPossiblyUpdated": "App Updates Attempted",
"appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background",
"xWasPossiblyUpdatedToY": "{} may have been updated to {}.", "xWasPossiblyUpdatedToY": "{} may have been updated to {}.",
"enableBackgroundUpdates": "Enable background updates",
"backgroundUpdateReqsExplanation": "Background updates may not be possible for all apps.", "backgroundUpdateReqsExplanation": "Background updates may not be possible for all apps.",
"backgroundUpdateLimitsExplanation": "The success of a background install can only be determined when Obtainium is opened.", "backgroundUpdateLimitsExplanation": "The success of a background install can only be determined when Obtainium is opened.",
"verifyLatestTag": "Verify the 'latest' tag", "verifyLatestTag": "Verify the 'latest' tag",
"intermediateLinkRegex": "Filter for an 'Intermediate' Link to Visit First",
"intermediateLinkNotFound": "Intermediate link not found",
"exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)",
"bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi",
"autoSelectHighestVersionCode": "Auto-select highest versionCode APK", "autoSelectHighestVersionCode": "Auto-select highest versionCode APK",
@ -260,6 +263,17 @@
"debugMenu": "Debug Menu", "debugMenu": "Debug Menu",
"bgTaskStarted": "Background task started - check logs.", "bgTaskStarted": "Background task started - check logs.",
"runBgCheckNow": "Run Background Update Check Now", "runBgCheckNow": "Run Background Update Check Now",
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"installing": "Installing",
"skipUpdateNotifications": "Skip update notifications",
"updatesAvailableNotifChannel": "بروزرسانی در دسترس ",
"appsUpdatedNotifChannel": "برنامه ها به روز شدند",
"appsPossiblyUpdatedNotifChannel": "App Updates Attempted",
"errorCheckingUpdatesNotifChannel": "خطا در بررسی به‌روزرسانی‌ها",
"appsRemovedNotifChannel": "برنامه ها حذف شدند",
"downloadingXNotifChannel": "در حال دانلود {}",
"completeAppInstallationNotifChannel": "نصب کامل برنامه",
"checkingForUpdatesNotifChannel": "بررسی به‌روزرسانی‌ها",
"removeAppQuestion": { "removeAppQuestion": {
"one": "برنامه حذف شود؟", "one": "برنامه حذف شود؟",
"other": "برنامه ها حذف شوند؟" "other": "برنامه ها حذف شوند؟"
@ -312,4 +326,4 @@
"one": "{} and 1 more app may have been updated.", "one": "{} and 1 more app may have been updated.",
"other": "{} and {} more apps may have been updated." "other": "{} and {} more apps may have been updated."
} }
} }

View File

@ -242,9 +242,12 @@
"appsPossiblyUpdated": "App Updates Attempted", "appsPossiblyUpdated": "App Updates Attempted",
"appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background",
"xWasPossiblyUpdatedToY": "{} may have been updated to {}.", "xWasPossiblyUpdatedToY": "{} may have been updated to {}.",
"enableBackgroundUpdates": "Enable background updates",
"backgroundUpdateReqsExplanation": "Background updates may not be possible for all apps.", "backgroundUpdateReqsExplanation": "Background updates may not be possible for all apps.",
"backgroundUpdateLimitsExplanation": "The success of a background install can only be determined when Obtainium is opened.", "backgroundUpdateLimitsExplanation": "The success of a background install can only be determined when Obtainium is opened.",
"verifyLatestTag": "Verify the 'latest' tag", "verifyLatestTag": "Verify the 'latest' tag",
"intermediateLinkRegex": "Filter for an 'Intermediate' Link to Visit First",
"intermediateLinkNotFound": "Intermediate link not found",
"exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)",
"bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi",
"autoSelectHighestVersionCode": "Auto-select highest versionCode APK", "autoSelectHighestVersionCode": "Auto-select highest versionCode APK",
@ -260,6 +263,17 @@
"debugMenu": "Debug Menu", "debugMenu": "Debug Menu",
"bgTaskStarted": "Background task started - check logs.", "bgTaskStarted": "Background task started - check logs.",
"runBgCheckNow": "Run Background Update Check Now", "runBgCheckNow": "Run Background Update Check Now",
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"installing": "Installing",
"skipUpdateNotifications": "Skip update notifications",
"updatesAvailableNotifChannel": "Mises à jour disponibles",
"appsUpdatedNotifChannel": "Applications mises à jour",
"appsPossiblyUpdatedNotifChannel": "App Updates Attempted",
"errorCheckingUpdatesNotifChannel": "Erreur lors de la vérification des mises à jour",
"appsRemovedNotifChannel": "Applications supprimées",
"downloadingXNotifChannel": "Téléchargement {}",
"completeAppInstallationNotifChannel": "Installation complète de l'application",
"checkingForUpdatesNotifChannel": "Vérification des mises à jour",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Supprimer l'application ?", "one": "Supprimer l'application ?",
"other": "Supprimer les applications ?" "other": "Supprimer les applications ?"
@ -312,4 +326,4 @@
"one": "{} and 1 more app may have been updated.", "one": "{} and 1 more app may have been updated.",
"other": "{} and {} more apps may have been updated." "other": "{} and {} more apps may have been updated."
} }
} }

View File

@ -1,315 +1,329 @@
{ {
"invalidURLForSource": "Érvénytelen a(z) {} app URL-je", "invalidURLForSource": "Érvénytelen a(z) {} app URL-je",
"noReleaseFound": "Nem található megfelelő kiadás", "noReleaseFound": "Nem található megfelelő kiadás",
"noVersionFound": "Nem sikerült meghatározni a kiadás verzióját", "noVersionFound": "Nem sikerült meghatározni a kiadás verzióját",
"urlMatchesNoSource": "Az URL nem egyezik ismert forrással", "urlMatchesNoSource": "Az URL nem egyezik ismert forrással",
"cantInstallOlderVersion": "Nem telepíthető egy app régebbi verziója", "cantInstallOlderVersion": "Nem telepíthető egy app régebbi verziója",
"appIdMismatch": "A letöltött csomagazonosító nem egyezik a meglévő app azonosítóval", "appIdMismatch": "A letöltött csomagazonosító nem egyezik a meglévő app azonosítóval",
"functionNotImplemented": "Ez az osztály nem valósította meg ezt a függvényt", "functionNotImplemented": "Ez az osztály nem valósította meg ezt a függvényt",
"placeholder": "Helykitöltő", "placeholder": "Helykitöltő",
"someErrors": "Néhány hiba történt", "someErrors": "Néhány hiba történt",
"unexpectedError": "Váratlan hiba", "unexpectedError": "Váratlan hiba",
"ok": "Oké", "ok": "Oké",
"and": "és", "and": "és",
"githubPATLabel": "GitHub Personal Access Token (megnöveli a díjkorlátot)", "githubPATLabel": "GitHub Personal Access Token (megnöveli a díjkorlátot)",
"includePrereleases": "Tartalmazza az előzetes kiadásokat", "includePrereleases": "Tartalmazza az előzetes kiadásokat",
"fallbackToOlderReleases": "Visszatérés a régebbi kiadásokhoz", "fallbackToOlderReleases": "Visszatérés a régebbi kiadásokhoz",
"filterReleaseTitlesByRegEx": "A kiadás címeinek szűrése reguláris kifejezéssel", "filterReleaseTitlesByRegEx": "A kiadás címeinek szűrése reguláris kifejezéssel",
"invalidRegEx": "Érvénytelen reguláris kifejezés", "invalidRegEx": "Érvénytelen reguláris kifejezés",
"noDescription": "Nincs leírás", "noDescription": "Nincs leírás",
"cancel": "Mégse", "cancel": "Mégse",
"continue": "Tovább", "continue": "Tovább",
"requiredInBrackets": "(Kötelező)", "requiredInBrackets": "(Kötelező)",
"dropdownNoOptsError": "HIBA: A LEDOBÁST LEGALÁBB EGY OPCIÓHOZ KELL RENDELNI", "dropdownNoOptsError": "HIBA: A LEDOBÁST LEGALÁBB EGY OPCIÓHOZ KELL RENDELNI",
"colour": "Szín", "colour": "Szín",
"githubStarredRepos": "GitHub Csillagos Repo-k", "githubStarredRepos": "GitHub Csillagos Repo-k",
"uname": "Felh.név", "uname": "Felh.név",
"wrongArgNum": "Rossz számú argumentumot adott meg", "wrongArgNum": "Rossz számú argumentumot adott meg",
"xIsTrackOnly": "A(z) {} csak nyomonkövethető", "xIsTrackOnly": "A(z) {} csak nyomonkövethető",
"source": "Forrás", "source": "Forrás",
"app": "App", "app": "App",
"appsFromSourceAreTrackOnly": "Az ebből a forrásból származó alkalmazások 'Csak nyomon követhetőek'.", "appsFromSourceAreTrackOnly": "Az ebből a forrásból származó alkalmazások 'Csak nyomon követhetőek'.",
"youPickedTrackOnly": "A 'Csak követés' opciót választotta.", "youPickedTrackOnly": "A 'Csak követés' opciót választotta.",
"trackOnlyAppDescription": "Az alkalmazás frissítéseit nyomon követi, de az Obtainium nem tudja letölteni vagy telepíteni.", "trackOnlyAppDescription": "Az alkalmazás frissítéseit nyomon követi, de az Obtainium nem tudja letölteni vagy telepíteni.",
"cancelled": "Törölve", "cancelled": "Törölve",
"appAlreadyAdded": "Az app már hozzáadva", "appAlreadyAdded": "Az app már hozzáadva",
"alreadyUpToDateQuestion": "Az app már naprakész?", "alreadyUpToDateQuestion": "Az app már naprakész?",
"addApp": "App hozzáadás", "addApp": "App hozzáadás",
"appSourceURL": "App forrás URL", "appSourceURL": "App forrás URL",
"error": "Hiba", "error": "Hiba",
"add": "Hozzáadás", "add": "Hozzáadás",
"searchSomeSourcesLabel": "Keresés (csak egyes források)", "searchSomeSourcesLabel": "Keresés (csak egyes források)",
"search": "Keresés", "search": "Keresés",
"additionalOptsFor": "További lehetőségek a következőhöz: {}", "additionalOptsFor": "További lehetőségek a következőhöz: {}",
"supportedSources": "Támogatott források", "supportedSources": "Támogatott források",
"trackOnlyInBrackets": "(Csak nyomonkövetés)", "trackOnlyInBrackets": "(Csak nyomonkövetés)",
"searchableInBrackets": "(Kereshető)", "searchableInBrackets": "(Kereshető)",
"appsString": "Appok", "appsString": "Appok",
"noApps": "Nincs App", "noApps": "Nincs App",
"noAppsForFilter": "Nincsenek appok a szűrőhöz", "noAppsForFilter": "Nincsenek appok a szűrőhöz",
"byX": "Fejlesztő: {}", "byX": "Fejlesztő: {}",
"percentProgress": "Folyamat: {}%", "percentProgress": "Folyamat: {}%",
"pleaseWait": "Kis türelmet", "pleaseWait": "Kis türelmet",
"updateAvailable": "Frissítés érhető el", "updateAvailable": "Frissítés érhető el",
"estimateInBracketsShort": "(Becsült)", "estimateInBracketsShort": "(Becsült)",
"notInstalled": "Nem telepített", "notInstalled": "Nem telepített",
"estimateInBrackets": "(Becslés)", "estimateInBrackets": "(Becslés)",
"selectAll": "Mindet kiválaszt", "selectAll": "Mindet kiválaszt",
"deselectN": "Törölje {} kijelölését", "deselectN": "Törölje {} kijelölését",
"xWillBeRemovedButRemainInstalled": "A(z) {} el lesz távolítva az Obtainiumból, de továbbra is telepítve marad az eszközön.", "xWillBeRemovedButRemainInstalled": "A(z) {} el lesz távolítva az Obtainiumból, de továbbra is telepítve marad az eszközön.",
"removeSelectedAppsQuestion": "Eltávolítja a kiválasztott appokat?", "removeSelectedAppsQuestion": "Eltávolítja a kiválasztott appokat?",
"removeSelectedApps": "Távolítsa el a kiválasztott appokat", "removeSelectedApps": "Távolítsa el a kiválasztott appokat",
"updateX": "Frissítés: {}", "updateX": "Frissítés: {}",
"installX": "Telepítés: {}", "installX": "Telepítés: {}",
"markXTrackOnlyAsUpdated": "Jelölje meg: {}\n(Csak nyomon követhető)\nmint Frissített", "markXTrackOnlyAsUpdated": "Jelölje meg: {}\n(Csak nyomon követhető)\nmint Frissített",
"changeX": "Változás {}", "changeX": "Változás {}",
"installUpdateApps": "Appok telepítése/frissítése", "installUpdateApps": "Appok telepítése/frissítése",
"installUpdateSelectedApps": "Telepítse/frissítse a kiválasztott appokat", "installUpdateSelectedApps": "Telepítse/frissítse a kiválasztott appokat",
"markXSelectedAppsAsUpdated": "Megjelöl {} kiválasztott alkalmazást frissítettként?", "markXSelectedAppsAsUpdated": "Megjelöl {} kiválasztott alkalmazást frissítettként?",
"no": "Nem", "no": "Nem",
"yes": "Igen", "yes": "Igen",
"markSelectedAppsUpdated": "Jelölje meg a kiválasztott appokat frissítettként", "markSelectedAppsUpdated": "Jelölje meg a kiválasztott appokat frissítettként",
"pinToTop": "Rögzítés felülre", "pinToTop": "Rögzítés felülre",
"unpinFromTop": "Eltávolít felülről", "unpinFromTop": "Eltávolít felülről",
"resetInstallStatusForSelectedAppsQuestion": "Visszaállítja a kiválasztott appok telepítési állapotát?", "resetInstallStatusForSelectedAppsQuestion": "Visszaállítja a kiválasztott appok telepítési állapotát?",
"installStatusOfXWillBeResetExplanation": "A kiválasztott appok telepítési állapota visszaáll.\n\nEz akkor segíthet, ha az Obtainiumban megjelenített app verzió hibás, frissítések vagy egyéb problémák miatt.", "installStatusOfXWillBeResetExplanation": "A kiválasztott appok telepítési állapota visszaáll.\n\nEz akkor segíthet, ha az Obtainiumban megjelenített app verzió hibás, frissítések vagy egyéb problémák miatt.",
"shareSelectedAppURLs": "Ossza meg a kiválasztott app URL címeit", "shareSelectedAppURLs": "Ossza meg a kiválasztott app URL címeit",
"resetInstallStatus": "Telepítési állapot visszaállítása", "resetInstallStatus": "Telepítési állapot visszaállítása",
"more": "További", "more": "További",
"removeOutdatedFilter": "Távolítsa el az elavult app szűrőt", "removeOutdatedFilter": "Távolítsa el az elavult app szűrőt",
"showOutdatedOnly": "Csak az elavult appok megjelenítése", "showOutdatedOnly": "Csak az elavult appok megjelenítése",
"filter": "Szűrő", "filter": "Szűrő",
"filterActive": "Szűrő *", "filterActive": "Szűrő *",
"filterApps": "Appok szűrése", "filterApps": "Appok szűrése",
"appName": "App név", "appName": "App név",
"author": "Szerző", "author": "Szerző",
"upToDateApps": "Naprakész appok", "upToDateApps": "Naprakész appok",
"nonInstalledApps": "Nem telepített appok", "nonInstalledApps": "Nem telepített appok",
"importExport": "Import/Export", "importExport": "Import/Export",
"settings": "Beállítások", "settings": "Beállítások",
"exportedTo": "Exportálva ide {}", "exportedTo": "Exportálva ide {}",
"obtainiumExport": "Obtainium Adat Exportálás", "obtainiumExport": "Obtainium Adat Exportálás",
"invalidInput": "Hibás bemenet", "invalidInput": "Hibás bemenet",
"importedX": "Importálva innen {}", "importedX": "Importálva innen {}",
"obtainiumImport": "Obtainium Adat Importálás", "obtainiumImport": "Obtainium Adat Importálás",
"importFromURLList": "Importálás URL listából", "importFromURLList": "Importálás URL listából",
"searchQuery": "Keresési lekérdezés", "searchQuery": "Keresési lekérdezés",
"appURLList": "App URL lista", "appURLList": "App URL lista",
"line": "Sor", "line": "Sor",
"searchX": "Keresés {}", "searchX": "Keresés {}",
"noResults": "Nincs találat", "noResults": "Nincs találat",
"importX": "Import {}", "importX": "Import {}",
"importedAppsIdDisclaimer": "Előfordulhat, hogy az importált appok helytelenül \"Nincs telepítve\" jelzéssel jelennek meg.\nA probléma megoldásához telepítse újra őket az Obtainiumon keresztül.\nEz nem érinti az alkalmazásadatokat.\n\nCsak az URL-ekre és a harmadik féltől származó importálási módszerekre vonatkozik..", "importedAppsIdDisclaimer": "Előfordulhat, hogy az importált appok helytelenül \"Nincs telepítve\" jelzéssel jelennek meg.\nA probléma megoldásához telepítse újra őket az Obtainiumon keresztül.\nEz nem érinti az alkalmazásadatokat.\n\nCsak az URL-ekre és a harmadik féltől származó importálási módszerekre vonatkozik..",
"importErrors": "Importálási hibák", "importErrors": "Importálási hibák",
"importedXOfYApps": "{}/{} app importálva.", "importedXOfYApps": "{}/{} app importálva.",
"followingURLsHadErrors": "A következő URL-ek hibákat tartalmaztak:", "followingURLsHadErrors": "A következő URL-ek hibákat tartalmaztak:",
"okay": "Oké", "okay": "Oké",
"selectURL": "Válassza ki az URL-t", "selectURL": "Válassza ki az URL-t",
"selectURLs": "Kiválasztott URL-ek", "selectURLs": "Kiválasztott URL-ek",
"pick": "Válasszon", "pick": "Válasszon",
"theme": "Téma", "theme": "Téma",
"dark": "Sötét", "dark": "Sötét",
"light": "Világos", "light": "Világos",
"followSystem": "Rendszer szerint", "followSystem": "Rendszer szerint",
"obtainium": "Obtainium", "obtainium": "Obtainium",
"materialYou": "Material You", "materialYou": "Material You",
"useBlackTheme": "Használjon tiszta fekete sötét témát", "useBlackTheme": "Használjon tiszta fekete sötét témát",
"appSortBy": "App rendezés...", "appSortBy": "App rendezés...",
"authorName": "Szerző/Név", "authorName": "Szerző/Név",
"nameAuthor": "Név/Szerző", "nameAuthor": "Név/Szerző",
"asAdded": "Mint Hozzáadott", "asAdded": "Mint Hozzáadott",
"appSortOrder": "Appok rendezése", "appSortOrder": "Appok rendezése",
"ascending": "Emelkedő", "ascending": "Emelkedő",
"descending": "Csökkenő", "descending": "Csökkenő",
"bgUpdateCheckInterval": "Háttérfrissítés ellenőrzés időköze", "bgUpdateCheckInterval": "Háttérfrissítés ellenőrzés időköze",
"neverManualOnly": "Soha csak manuális", "neverManualOnly": "Soha csak manuális",
"appearance": "Megjelenés", "appearance": "Megjelenés",
"showWebInAppView": "Forrás megjelenítése az Appok nézetben", "showWebInAppView": "Forrás megjelenítése az Appok nézetben",
"pinUpdates": "Frissítések kitűzése az App nézet tetejére", "pinUpdates": "Frissítések kitűzése az App nézet tetejére",
"updates": "Frissítések", "updates": "Frissítések",
"sourceSpecific": "Forrás-specifikus", "sourceSpecific": "Forrás-specifikus",
"appSource": "App forrás", "appSource": "App forrás",
"noLogs": "Nincsenek naplók", "noLogs": "Nincsenek naplók",
"appLogs": "App naplók", "appLogs": "App naplók",
"close": "Bezárás", "close": "Bezárás",
"share": "Megosztás", "share": "Megosztás",
"appNotFound": "App nem található", "appNotFound": "App nem található",
"obtainiumExportHyphenatedLowercase": "obtainium-export", "obtainiumExportHyphenatedLowercase": "obtainium-export",
"pickAnAPK": "Válasszon egy APK-t", "pickAnAPK": "Válasszon egy APK-t",
"appHasMoreThanOnePackage": "A(z) {} egynél több csomaggal rendelkezik:", "appHasMoreThanOnePackage": "A(z) {} egynél több csomaggal rendelkezik:",
"deviceSupportsXArch": "Eszköze támogatja a {} CPU architektúrát.", "deviceSupportsXArch": "Eszköze támogatja a {} CPU architektúrát.",
"deviceSupportsFollowingArchs": "Az eszköze a következő CPU architektúrákat támogatja:", "deviceSupportsFollowingArchs": "Az eszköze a következő CPU architektúrákat támogatja:",
"warning": "Figyelem", "warning": "Figyelem",
"sourceIsXButPackageFromYPrompt": "Az alkalmazás forrása „{}”, de a kiadási csomag innen származik: „{}”. Folytatja?", "sourceIsXButPackageFromYPrompt": "Az alkalmazás forrása „{}”, de a kiadási csomag innen származik: „{}”. Folytatja?",
"updatesAvailable": "Frissítések érhetők el", "updatesAvailable": "Frissítések érhetők el",
"updatesAvailableNotifDescription": "Értesíti a felhasználót, hogy frissítések állnak rendelkezésre egy vagy több, az Obtainium által nyomon követett alkalmazáshoz", "updatesAvailableNotifDescription": "Értesíti a felhasználót, hogy frissítések állnak rendelkezésre egy vagy több, az Obtainium által nyomon követett alkalmazáshoz",
"noNewUpdates": "Nincsenek új frissítések.", "noNewUpdates": "Nincsenek új frissítések.",
"xHasAnUpdate": "A(z) {} frissítést kapott.", "xHasAnUpdate": "A(z) {} frissítést kapott.",
"appsUpdated": "Alkalmazások frissítve", "appsUpdated": "Alkalmazások frissítve",
"appsUpdatedNotifDescription": "Értesíti a felhasználót, hogy egy/több app frissítése megtörtént a háttérben", "appsUpdatedNotifDescription": "Értesíti a felhasználót, hogy egy/több app frissítése megtörtént a háttérben",
"xWasUpdatedToY": "{} frissítve a következőre: {}.", "xWasUpdatedToY": "{} frissítve a következőre: {}.",
"errorCheckingUpdates": "Hiba a frissítések keresésekor", "errorCheckingUpdates": "Hiba a frissítések keresésekor",
"errorCheckingUpdatesNotifDescription": "Értesítés, amely akkor jelenik meg, ha a háttérbeli frissítések ellenőrzése sikertelen", "errorCheckingUpdatesNotifDescription": "Értesítés, amely akkor jelenik meg, ha a háttérbeli frissítések ellenőrzése sikertelen",
"appsRemoved": "Alkalmazások eltávolítva", "appsRemoved": "Alkalmazások eltávolítva",
"appsRemovedNotifDescription": "Értesíti a felhasználót egy vagy több alkalmazás eltávolításáról a betöltésük során fellépő hibák miatt", "appsRemovedNotifDescription": "Értesíti a felhasználót egy vagy több alkalmazás eltávolításáról a betöltésük során fellépő hibák miatt",
"xWasRemovedDueToErrorY": "A(z) {} a következő hiba miatt lett eltávolítva: {}", "xWasRemovedDueToErrorY": "A(z) {} a következő hiba miatt lett eltávolítva: {}",
"completeAppInstallation": "Teljes app telepítés", "completeAppInstallation": "Teljes app telepítés",
"obtainiumMustBeOpenToInstallApps": "Az Obtainiumnak megnyitva kell lennie az alkalmazások telepítéséhez", "obtainiumMustBeOpenToInstallApps": "Az Obtainiumnak megnyitva kell lennie az alkalmazások telepítéséhez",
"completeAppInstallationNotifDescription": "Megkéri a felhasználót, hogy térjen vissza az Obtainiumhoz, hogy befejezze az alkalmazás telepítését", "completeAppInstallationNotifDescription": "Megkéri a felhasználót, hogy térjen vissza az Obtainiumhoz, hogy befejezze az alkalmazás telepítését",
"checkingForUpdates": "Frissítések keresése", "checkingForUpdates": "Frissítések keresése",
"checkingForUpdatesNotifDescription": "Átmeneti értesítés, amely a frissítések keresésekor jelenik meg", "checkingForUpdatesNotifDescription": "Átmeneti értesítés, amely a frissítések keresésekor jelenik meg",
"pleaseAllowInstallPerm": "Kérjük, engedélyezze az Obtainiumnak az alkalmazások telepítését", "pleaseAllowInstallPerm": "Kérjük, engedélyezze az Obtainiumnak az alkalmazások telepítését",
"trackOnly": "Csak követés", "trackOnly": "Csak követés",
"errorWithHttpStatusCode": "Hiba {}", "errorWithHttpStatusCode": "Hiba {}",
"versionCorrectionDisabled": "Verzió korrekció letiltva (úgy tűnik, a beépülő modul nem működik)", "versionCorrectionDisabled": "Verzió korrekció letiltva (úgy tűnik, a beépülő modul nem működik)",
"unknown": "Ismeretlen", "unknown": "Ismeretlen",
"none": "Egyik sem", "none": "Egyik sem",
"never": "Soha", "never": "Soha",
"latestVersionX": "Legújabb verzió: {}", "latestVersionX": "Legújabb verzió: {}",
"installedVersionX": "Telepített verzió: {}", "installedVersionX": "Telepített verzió: {}",
"lastUpdateCheckX": "Frissítés ellenőrizve: {}", "lastUpdateCheckX": "Frissítés ellenőrizve: {}",
"remove": "Eltávolítás", "remove": "Eltávolítás",
"yesMarkUpdated": "Igen, megjelölés frissítettként", "yesMarkUpdated": "Igen, megjelölés frissítettként",
"fdroid": "F-Droid Official", "fdroid": "F-Droid Official",
"appIdOrName": "App ID vagy név", "appIdOrName": "App ID vagy név",
"appId": "App ID", "appId": "App ID",
"appWithIdOrNameNotFound": "Nem található app ezzel az azonosítóval vagy névvel", "appWithIdOrNameNotFound": "Nem található app ezzel az azonosítóval vagy névvel",
"reposHaveMultipleApps": "A repók több alkalmazást is tartalmazhatnak", "reposHaveMultipleApps": "A repók több alkalmazást is tartalmazhatnak",
"fdroidThirdPartyRepo": "F-Droid Harmadik-fél Repo", "fdroidThirdPartyRepo": "F-Droid Harmadik-fél Repo",
"steam": "Steam", "steam": "Steam",
"steamMobile": "Steam Mobile", "steamMobile": "Steam Mobile",
"steamChat": "Steam Chat", "steamChat": "Steam Chat",
"install": "Telepít", "install": "Telepít",
"markInstalled": "Telepítettnek jelöl", "markInstalled": "Telepítettnek jelöl",
"update": "Frissít", "update": "Frissít",
"markUpdated": "Frissítettnek jelöl", "markUpdated": "Frissítettnek jelöl",
"additionalOptions": "További lehetőségek", "additionalOptions": "További lehetőségek",
"disableVersionDetection": "Verzió érzékelés letiltása", "disableVersionDetection": "Verzió érzékelés letiltása",
"noVersionDetectionExplanation": "Ezt a beállítást csak olyan alkalmazásoknál szabad használni, ahol a verzióérzékelés nem működik megfelelően.", "noVersionDetectionExplanation": "Ezt a beállítást csak olyan alkalmazásoknál szabad használni, ahol a verzióérzékelés nem működik megfelelően.",
"downloadingX": "{} letöltés", "downloadingX": "{} letöltés",
"downloadNotifDescription": "Értesíti a felhasználót az app letöltésének előrehaladásáról", "downloadNotifDescription": "Értesíti a felhasználót az app letöltésének előrehaladásáról",
"noAPKFound": "Nem található APK", "noAPKFound": "Nem található APK",
"noVersionDetection": "Nincs verzió érzékelés", "noVersionDetection": "Nincs verzió érzékelés",
"categorize": "Kategorizálás", "categorize": "Kategorizálás",
"categories": "Kategóriák", "categories": "Kategóriák",
"category": "Kategória", "category": "Kategória",
"noCategory": "Nincs kategória", "noCategory": "Nincs kategória",
"deleteCategoryQuestion": "Törli a kategóriát?", "noCategories": "No Categories",
"categoryDeleteWarning": "A(z) {} összes app kategorizálatlan állapotba kerül.", "deleteCategoryQuestion": "Törli a kategóriát?",
"addCategory": "Új kategória", "categoryDeleteWarning": "A(z) {} összes app kategorizálatlan állapotba kerül.",
"label": "Címke", "addCategory": "Új kategória",
"language": "Nyelv", "label": "Címke",
"copiedToClipboard": "Másolva a vágólapra", "language": "Nyelv",
"storagePermissionDenied": "Tárhely engedély megtagadva", "copiedToClipboard": "Másolva a vágólapra",
"selectedCategorizeWarning": "Ez felváltja a kiválasztott alkalmazások meglévő kategória-beállításait.", "storagePermissionDenied": "Tárhely engedély megtagadva",
"filterAPKsByRegEx": "Az APK-k szűrése reguláris kifejezéssel", "selectedCategorizeWarning": "Ez felváltja a kiválasztott alkalmazások meglévő kategória-beállításait.",
"removeFromObtainium": "Eltávolítás az Obtainiumból", "filterAPKsByRegEx": "Az APK-k szűrése reguláris kifejezéssel",
"uninstallFromDevice": "Eltávolítás a készülékről", "removeFromObtainium": "Eltávolítás az Obtainiumból",
"onlyWorksWithNonVersionDetectApps": "Csak azoknál az alkalmazásoknál működik, amelyeknél a verzióérzékelés le van tiltva.", "uninstallFromDevice": "Eltávolítás a készülékről",
"releaseDateAsVersion": "Használja a Kiadás dátumát, mint verziót", "onlyWorksWithNonVersionDetectApps": "Csak azoknál az alkalmazásoknál működik, amelyeknél a verzióérzékelés le van tiltva.",
"releaseDateAsVersionExplanation": "Ezt a beállítást csak olyan alkalmazásoknál szabad használni, ahol a verzió érzékelése nem működik megfelelően, de elérhető a kiadás dátuma.", "releaseDateAsVersion": "Használja a Kiadás dátumát, mint verziót",
"changes": "Változtatások", "releaseDateAsVersionExplanation": "Ezt a beállítást csak olyan alkalmazásoknál szabad használni, ahol a verzió érzékelése nem működik megfelelően, de elérhető a kiadás dátuma.",
"releaseDate": "Kiadás dátuma", "changes": "Változtatások",
"importFromURLsInFile": "Importálás fájlban található URL-ből (mint pl. OPML)", "releaseDate": "Kiadás dátuma",
"versionDetection": "Verzió érzékelés", "importFromURLsInFile": "Importálás fájlban található URL-ből (mint pl. OPML)",
"standardVersionDetection": "Alapért. verzió érzékelés", "versionDetection": "Verzió érzékelés",
"groupByCategory": "Csoportosítás Kategória alapján", "standardVersionDetection": "Alapért. verzió érzékelés",
"autoApkFilterByArch": "Ha lehetséges, próbálja CPU architektúra szerint szűrni az APK-okat", "groupByCategory": "Csoportosítás Kategória alapján",
"overrideSource": "Forrás felülbírálása", "autoApkFilterByArch": "Ha lehetséges, próbálja CPU architektúra szerint szűrni az APK-okat",
"dontShowAgain": "Ne mutassa ezt újra", "overrideSource": "Forrás felülbírálása",
"dontShowTrackOnlyWarnings": "Ne jelenítsen meg 'Csak nyomon követés' figyelmeztetést", "dontShowAgain": "Ne mutassa ezt újra",
"dontShowAPKOriginWarnings": "Ne jelenítsen meg az APK eredetére vonatkozó figyelmeztetéseket", "dontShowTrackOnlyWarnings": "Ne jelenítsen meg 'Csak nyomon követés' figyelmeztetést",
"moveNonInstalledAppsToBottom": "Helyezze át a nem telepített appokat az App nézet aljára", "dontShowAPKOriginWarnings": "Ne jelenítsen meg az APK eredetére vonatkozó figyelmeztetéseket",
"gitlabPATLabel": "GitLab Personal Access Token\n(Engedélyezi a Keresést és jobb APK felfedezés)", "moveNonInstalledAppsToBottom": "Helyezze át a nem telepített appokat az App nézet aljára",
"about": "Rólunk", "gitlabPATLabel": "GitLab Personal Access Token\n(Engedélyezi a Keresést és jobb APK felfedezés)",
"requiresCredentialsInSettings": "Ehhez további hitelesítő adatokra van szükség (a Beállításokban)", "about": "Rólunk",
"checkOnStart": "Egyszer az alkalmazás indításakor is", "requiresCredentialsInSettings": "Ehhez további hitelesítő adatokra van szükség (a Beállításokban)",
"tryInferAppIdFromCode": "Próbálja kikövetkeztetni az app azonosítót a forráskódból", "checkOnStart": "Egyszer az alkalmazás indításakor is",
"removeOnExternalUninstall": "A külsőleg eltávolított appok auto. eltávolítása", "tryInferAppIdFromCode": "Próbálja kikövetkeztetni az app azonosítót a forráskódból",
"pickHighestVersionCode": "A legmagasabb verziószámú APK auto. kiválasztása", "removeOnExternalUninstall": "A külsőleg eltávolított appok auto. eltávolítása",
"checkUpdateOnDetailPage": "Frissítések keresése az app részleteit tartalmazó oldal megnyitásakor", "pickHighestVersionCode": "A legmagasabb verziószámú APK auto. kiválasztása",
"disablePageTransitions": "Lap áttűnési animációk letiltása", "checkUpdateOnDetailPage": "Frissítések keresése az app részleteit tartalmazó oldal megnyitásakor",
"reversePageTransitions": "Fordított lap áttűnési animációk", "disablePageTransitions": "Lap áttűnési animációk letiltása",
"minStarCount": "Minimális csillag szám", "reversePageTransitions": "Fordított lap áttűnési animációk",
"addInfoBelow": "Adja hozzá ezt az infót alább.", "minStarCount": "Minimális csillag szám",
"addInfoInSettings": "Adja hozzá ezt az infót a Beállításokban.", "addInfoBelow": "Adja hozzá ezt az infót alább.",
"githubSourceNote": "A GitHub sebességkorlátos elkerülhető API-kulcs használatával.", "addInfoInSettings": "Adja hozzá ezt az infót a Beállításokban.",
"gitlabSourceNote": "Előfordulhat, hogy a GitLab APK kibontása nem működik API-kulcs nélkül.", "githubSourceNote": "A GitHub sebességkorlátozás elkerülhető API-kulcs használatával.",
"sortByFileNamesNotLinks": "Fájlnevek szerinti elrendezés teljes linkek helyett", "gitlabSourceNote": "Előfordulhat, hogy a GitLab APK kibontása nem működik API-kulcs nélkül.",
"filterReleaseNotesByRegEx": "Kiadási megjegyzések szűrése reguláris kifejezéssel", "sortByFileNamesNotLinks": "Fájlnevek szerinti elrendezés teljes linkek helyett",
"customLinkFilterRegex": "Egyéni APK hivatkozásszűrő reguláris kifejezéssel (Alapérték '.apk$')", "filterReleaseNotesByRegEx": "Kiadási megjegyzések szűrése reguláris kifejezéssel",
"appsPossiblyUpdated": "App frissítési kísérlet", "customLinkFilterRegex": "Egyéni APK hivatkozásszűrő reguláris kifejezéssel (Alapérték '.apk$')",
"appsPossiblyUpdatedNotifDescription": "Értesíti a felhasználót, hogy egy vagy több alkalmazás frissítése lehetséges a háttérben", "appsPossiblyUpdated": "App frissítési kísérlet",
"xWasPossiblyUpdatedToY": "{} frissítve lehet erre {}.", "appsPossiblyUpdatedNotifDescription": "Értesíti a felhasználót, hogy egy vagy több alkalmazás frissítése lehetséges a háttérben",
"backgroundUpdateReqsExplanation": "Előfordulhat, hogy nem minden appnál lehetséges a háttérbeli frissítés.", "xWasPossiblyUpdatedToY": "{} frissítve lehet erre {}.",
"backgroundUpdateLimitsExplanation": "A háttérben történő telepítés sikeressége csak az Obtainium megnyitásakor állapítható meg.", "backgroundUpdateReqsExplanation": "Előfordulhat, hogy nem minden appnál lehetséges a háttérbeli frissítés.",
"verifyLatestTag": "Ellenőrizze a „legújabb” címkét", "backgroundUpdateLimitsExplanation": "A háttérben történő telepítés sikeressége csak az Obtainium megnyitásakor állapítható meg.",
"exemptFromBackgroundUpdates": "Mentes a háttérben történő frissítések alól (ha engedélyezett)", "verifyLatestTag": "Ellenőrizze a „legújabb” címkét",
"bgUpdatesOnWiFiOnly": "Tiltsa le a háttérben frissítéseket, ha nincs Wi-Fi-n", "intermediateLinkRegex": "Filter for an 'Intermediate' Link to Visit First",
"autoSelectHighestVersionCode": "A legmagasabb verziószámú APK auto. kiválasztása", "intermediateLinkNotFound": "Intermediate link not found",
"versionExtractionRegEx": "Verzió kibontása reguláris kifejezéssel", "exemptFromBackgroundUpdates": "Mentes a háttérben történő frissítések alól (ha engedélyezett)",
"matchGroupToUse": "Párosítsa a csoportot a használathoz", "bgUpdatesOnWiFiOnly": "Tiltsa le a háttérben frissítéseket, ha nincs Wi-Fi-n",
"highlightTouchTargets": "Emelje ki a kevésbé nyilvánvaló érintési célokat", "autoSelectHighestVersionCode": "A legmagasabb verziószámú APK auto. kiválasztása",
"pickExportDir": "Válassza az Exportálási könyvtárat", "versionExtractionRegEx": "Verzió kibontása reguláris kifejezéssel",
"autoExportOnChanges": "Auto-exportálás a változások után", "matchGroupToUse": "Párosítsa a csoportot a használathoz",
"filterVersionsByRegEx": "Verziók szűrése reguláris kifejezéssel", "highlightTouchTargets": "Emelje ki a kevésbé nyilvánvaló érintési célokat",
"trySelectingSuggestedVersionCode": "Próbálja ki a javasolt verziókódú APK-t", "pickExportDir": "Válassza az Exportálási könyvtárat",
"dontSortReleasesList": "Az API-ból származó kiadási sorrend megőrzése", "autoExportOnChanges": "Auto-exportálás a változások után",
"reverseSort": "Fordított rendezés", "filterVersionsByRegEx": "Verziók szűrése reguláris kifejezéssel",
"debugMenu": "Hibakereső menü", "trySelectingSuggestedVersionCode": "Próbálja ki a javasolt verziókódú APK-t",
"bgTaskStarted": "A háttérfeladat elindult ellenőrizze a naplókat.", "dontSortReleasesList": "Az API-ból származó kiadási sorrend megőrzése",
"enableBackgroundUpdates": "Frissítések a háttérben", "reverseSort": "Fordított rendezés",
"runBgCheckNow": "Futtassa a Háttérben frissítés ellenőrzését most", "debugMenu": "Hibakereső menü",
"removeAppQuestion": { "bgTaskStarted": "A háttérfeladat elindult ellenőrizze a naplókat.",
"one": "Eltávolítja az alkalmazást?", "enableBackgroundUpdates": "Frissítések a háttérben",
"other": "Eltávolítja az alkalmazást?" "runBgCheckNow": "Futtassa a Háttérben frissítés ellenőrzését most",
}, "versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"tooManyRequestsTryAgainInMinutes": { "installing": "Installing",
"one": "Túl sok kérés (korlátozott arány) próbálja újra {} perc múlva", "skipUpdateNotifications": "Skip update notifications",
"other": "Túl sok kérés (korlátozott arány) próbálja újra {} perc múlva" "updatesAvailableNotifChannel": "Frissítések érhetők el",
}, "appsUpdatedNotifChannel": "Alkalmazások frissítve",
"bgUpdateGotErrorRetryInMinutes": { "appsPossiblyUpdatedNotifChannel": "App frissítési kísérlet",
"one": "A háttérfrissítések ellenőrzése {}-t észlelt, {} perc múlva ütemezi az újrapróbálkozást", "errorCheckingUpdatesNotifChannel": "Hiba a frissítések keresésekor",
"other": "A háttérfrissítések ellenőrzése {}-t észlelt, {} perc múlva ütemezi az újrapróbálkozást" "appsRemovedNotifChannel": "Alkalmazások eltávolítva",
}, "downloadingXNotifChannel": "{} letöltés",
"bgCheckFoundUpdatesWillNotifyIfNeeded": { "completeAppInstallationNotifChannel": "Teljes app telepítés",
"one": "A háttérfrissítés ellenőrzése {} frissítést talált szükség esetén értesíti a felhasználót", "checkingForUpdatesNotifChannel": "Frissítések keresése",
"other": "A háttérfrissítés ellenőrzése {} frissítést talált szükség esetén értesíti a felhasználót" "removeAppQuestion": {
}, "one": "Eltávolítja az alkalmazást?",
"apps": { "other": "Eltávolítja az alkalmazást?"
"one": "{} app", },
"other": "{} app" "tooManyRequestsTryAgainInMinutes": {
}, "one": "Túl sok kérés (korlátozott arány) próbálja újra {} perc múlva",
"url": { "other": "Túl sok kérés (korlátozott arány) próbálja újra {} perc múlva"
"one": "{} URL", },
"other": "{} URL" "bgUpdateGotErrorRetryInMinutes": {
}, "one": "A háttérfrissítések ellenőrzése {}-t észlelt, {} perc múlva ütemezi az újrapróbálkozást",
"minute": { "other": "A háttérfrissítések ellenőrzése {}-t észlelt, {} perc múlva ütemezi az újrapróbálkozást"
"one": "{} perc", },
"other": "{} perc" "bgCheckFoundUpdatesWillNotifyIfNeeded": {
}, "one": "A háttérfrissítés ellenőrzése {} frissítést talált szükség esetén értesíti a felhasználót",
"hour": { "other": "A háttérfrissítés ellenőrzése {} frissítést talált szükség esetén értesíti a felhasználót"
"one": "{} óra", },
"other": "{} óra" "apps": {
}, "one": "{} app",
"day": { "other": "{} app"
"one": "{} nap", },
"other": "{} nap" "url": {
}, "one": "{} URL",
"clearedNLogsBeforeXAfterY": { "other": "{} URL"
"one": "{n} napló törölve (előtte = {előtte}, utána = {utána})", },
"other": "{n} napló törölve (előtte = {előtte}, utána = {utána})" "minute": {
}, "one": "{} perc",
"xAndNMoreUpdatesAvailable": { "other": "{} perc"
"one": "A(z) {} és 1 további alkalmazás frissítéseket kapott.", },
"other": "{} és {} további alkalmazás frissítéseket kapott." "hour": {
}, "one": "{} óra",
"xAndNMoreUpdatesInstalled": { "other": "{} óra"
"one": "A(z) {} és 1 további alkalmazás frissítve.", },
"other": "{} és {} további alkalmazás frissítve." "day": {
}, "one": "{} nap",
"xAndNMoreUpdatesPossiblyInstalled": { "other": "{} nap"
"one": "{} és 1 további alkalmazás is frissült.", },
"other": "{} és {} további alkalmazás is frissült." "clearedNLogsBeforeXAfterY": {
} "one": "{n} napló törölve (előtte = {előtte}, utána = {utána})",
} "other": "{n} napló törölve (előtte = {előtte}, utána = {utána})"
},
"xAndNMoreUpdatesAvailable": {
"one": "A(z) {} és 1 további alkalmazás frissítéseket kapott.",
"other": "{} és {} további alkalmazás frissítéseket kapott."
},
"xAndNMoreUpdatesInstalled": {
"one": "A(z) {} és 1 további alkalmazás frissítve.",
"other": "{} és {} további alkalmazás frissítve."
},
"xAndNMoreUpdatesPossiblyInstalled": {
"one": "{} és 1 további alkalmazás is frissült.",
"other": "{} és {} további alkalmazás is frissült."
}
}

View File

@ -242,9 +242,12 @@
"appsPossiblyUpdated": "App Updates Attempted", "appsPossiblyUpdated": "App Updates Attempted",
"appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background",
"xWasPossiblyUpdatedToY": "{} may have been updated to {}.", "xWasPossiblyUpdatedToY": "{} may have been updated to {}.",
"enableBackgroundUpdates": "Enable background updates",
"backgroundUpdateReqsExplanation": "Background updates may not be possible for all apps.", "backgroundUpdateReqsExplanation": "Background updates may not be possible for all apps.",
"backgroundUpdateLimitsExplanation": "The success of a background install can only be determined when Obtainium is opened.", "backgroundUpdateLimitsExplanation": "The success of a background install can only be determined when Obtainium is opened.",
"verifyLatestTag": "Verify the 'latest' tag", "verifyLatestTag": "Verify the 'latest' tag",
"intermediateLinkRegex": "Filter for an 'Intermediate' Link to Visit First",
"intermediateLinkNotFound": "Intermediate link not found",
"exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)",
"bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi",
"autoSelectHighestVersionCode": "Auto-select highest versionCode APK", "autoSelectHighestVersionCode": "Auto-select highest versionCode APK",
@ -260,6 +263,17 @@
"debugMenu": "Debug Menu", "debugMenu": "Debug Menu",
"bgTaskStarted": "Background task started - check logs.", "bgTaskStarted": "Background task started - check logs.",
"runBgCheckNow": "Run Background Update Check Now", "runBgCheckNow": "Run Background Update Check Now",
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"installing": "Installing",
"skipUpdateNotifications": "Skip update notifications",
"updatesAvailableNotifChannel": "Aggiornamenti disponibili",
"appsUpdatedNotifChannel": "App aggiornate",
"appsPossiblyUpdatedNotifChannel": "App Updates Attempted",
"errorCheckingUpdatesNotifChannel": "Controllo degli errori per gli aggiornamenti",
"appsRemovedNotifChannel": "App rimosse",
"downloadingXNotifChannel": "Scaricamento di {} in corso",
"completeAppInstallationNotifChannel": "Completa l'installazione dell'app",
"checkingForUpdatesNotifChannel": "Controllo degli aggiornamenti in corso",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Rimuovere l'app?", "one": "Rimuovere l'app?",
"other": "Rimuovere le app?" "other": "Rimuovere le app?"
@ -312,4 +326,4 @@
"one": "{} and 1 more app may have been updated.", "one": "{} and 1 more app may have been updated.",
"other": "{} and {} more apps may have been updated." "other": "{} and {} more apps may have been updated."
} }
} }

View File

@ -263,6 +263,17 @@
"debugMenu": "Debug Menu", "debugMenu": "Debug Menu",
"bgTaskStarted": "Background task started - check logs.", "bgTaskStarted": "Background task started - check logs.",
"runBgCheckNow": "Run Background Update Check Now", "runBgCheckNow": "Run Background Update Check Now",
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"installing": "Installing",
"skipUpdateNotifications": "Skip update notifications",
"updatesAvailableNotifChannel": "アップデートが利用可能",
"appsUpdatedNotifChannel": "アプリをアップデートしました",
"appsPossiblyUpdatedNotifChannel": "アプリのアップデートを試行",
"errorCheckingUpdatesNotifChannel": "アップデート確認中のエラー",
"appsRemovedNotifChannel": "削除されたアプリ",
"downloadingXNotifChannel": "{} をダウンロード中",
"completeAppInstallationNotifChannel": "アプリのインストールを完了する",
"checkingForUpdatesNotifChannel": "アップデートを確認中",
"removeAppQuestion": { "removeAppQuestion": {
"one": "アプリを削除しますか?", "one": "アプリを削除しますか?",
"other": "アプリを削除しますか?" "other": "アプリを削除しますか?"
@ -315,4 +326,4 @@
"one": "{} とさらに 1 個のアプリがアップデートされた可能性があります。", "one": "{} とさらに 1 個のアプリがアップデートされた可能性があります。",
"other": "{} とさらに {} 個のアプリがアップデートされた可能性があります。" "other": "{} とさらに {} 個のアプリがアップデートされた可能性があります。"
} }
} }

View File

@ -1,14 +1,4 @@
{ {
"noDescription": "Brak opisu",
"no": "Nie",
"okay": "Okej",
"appId": "ID aplikacji",
"bgUpdateGotErrorRetryInMinutes": {
"one": "Sprawdzanie aktualizacji w tle napotkało {}, zaplanuje ponowne sprawdzenie za {} minutę",
"few": "Sprawdzanie aktualizacji w tle napotkało {}, zaplanuje ponowne sprawdzenie za {} minuty",
"many": "Sprawdzanie aktualizacji w tle napotkało {}, zaplanuje ponowne sprawdzenie za {} minut",
"other": "Sprawdzanie aktualizacji w tle napotkało {}, zaplanuje ponowne sprawdzenie za {} minuty"
},
"invalidURLForSource": "Nieprawidłowy adres URL aplikacji {}", "invalidURLForSource": "Nieprawidłowy adres URL aplikacji {}",
"noReleaseFound": "Nie można znaleźć odpowiedniego wydania", "noReleaseFound": "Nie można znaleźć odpowiedniego wydania",
"noVersionFound": "Nie można określić wersji wydania", "noVersionFound": "Nie można określić wersji wydania",
@ -26,6 +16,7 @@
"fallbackToOlderReleases": "Powracaj do starszych wersji", "fallbackToOlderReleases": "Powracaj do starszych wersji",
"filterReleaseTitlesByRegEx": "Filtruj tytuły wydań wg. wyrażeń regularnych", "filterReleaseTitlesByRegEx": "Filtruj tytuły wydań wg. wyrażeń regularnych",
"invalidRegEx": "Nieprawidłowe wyrażenie regularne", "invalidRegEx": "Nieprawidłowe wyrażenie regularne",
"noDescription": "Brak opisu",
"cancel": "Anuluj", "cancel": "Anuluj",
"continue": "Kontynuuj", "continue": "Kontynuuj",
"requiredInBrackets": "(Wymagane)", "requiredInBrackets": "(Wymagane)",
@ -75,6 +66,7 @@
"installUpdateApps": "Instaluj/aktualizuj aplikacje", "installUpdateApps": "Instaluj/aktualizuj aplikacje",
"installUpdateSelectedApps": "Zainstaluj/zaktualizuj wybrane aplikacje", "installUpdateSelectedApps": "Zainstaluj/zaktualizuj wybrane aplikacje",
"markXSelectedAppsAsUpdated": "Oznaczyć {} wybranych aplikacji jako zaktualizowane?", "markXSelectedAppsAsUpdated": "Oznaczyć {} wybranych aplikacji jako zaktualizowane?",
"no": "Nie",
"yes": "Tak", "yes": "Tak",
"markSelectedAppsUpdated": "Oznacz wybrane aplikacje jako zaktualizowane", "markSelectedAppsUpdated": "Oznacz wybrane aplikacje jako zaktualizowane",
"pinToTop": "Przypnij", "pinToTop": "Przypnij",
@ -111,6 +103,7 @@
"importErrors": "Błędy importowania", "importErrors": "Błędy importowania",
"importedXOfYApps": "Zaimportowano {} z {} aplikacji.", "importedXOfYApps": "Zaimportowano {} z {} aplikacji.",
"followingURLsHadErrors": "Następujące adresy URL zawierały błędy:", "followingURLsHadErrors": "Następujące adresy URL zawierały błędy:",
"okay": "Okej",
"selectURL": "Wybierz adres URL", "selectURL": "Wybierz adres URL",
"selectURLs": "Wybierz adresy URL", "selectURLs": "Wybierz adresy URL",
"pick": "Wybierz", "pick": "Wybierz",
@ -179,6 +172,7 @@
"yesMarkUpdated": "Tak, oznacz jako zaktualizowane", "yesMarkUpdated": "Tak, oznacz jako zaktualizowane",
"fdroid": "Oficjalny F-Droid", "fdroid": "Oficjalny F-Droid",
"appIdOrName": "ID aplikacji lub nazwa", "appIdOrName": "ID aplikacji lub nazwa",
"appId": "ID aplikacji",
"appWithIdOrNameNotFound": "Nie znaleziono aplikacji o tym identyfikatorze lub nazwie", "appWithIdOrNameNotFound": "Nie znaleziono aplikacji o tym identyfikatorze lub nazwie",
"reposHaveMultipleApps": "Repozytoria mogą zawierać wiele aplikacji", "reposHaveMultipleApps": "Repozytoria mogą zawierać wiele aplikacji",
"fdroidThirdPartyRepo": "Zewnętrzne repo F-Droid", "fdroidThirdPartyRepo": "Zewnętrzne repo F-Droid",
@ -245,12 +239,15 @@
"sortByFileNamesNotLinks": "Sortuj wg nazw plików zamiast pełnych linków", "sortByFileNamesNotLinks": "Sortuj wg nazw plików zamiast pełnych linków",
"filterReleaseNotesByRegEx": "Filtruj informacje o wersji według wyrażenia regularnego", "filterReleaseNotesByRegEx": "Filtruj informacje o wersji według wyrażenia regularnego",
"customLinkFilterRegex": "Filtruj linki APK według wyrażenia regularnego (domyślnie \".apk$\")", "customLinkFilterRegex": "Filtruj linki APK według wyrażenia regularnego (domyślnie \".apk$\")",
"appsPossiblyUpdated": "Informuj o próbach aktualizacji", "appsPossiblyUpdated": "Próbowano zaktualizować aplikację",
"appsPossiblyUpdatedNotifDescription": "Powiadamiaj o potencjalnym zastosowaniu w tle aktualizacji jednej lub większej ilości aplikacji", "appsPossiblyUpdatedNotifDescription": "Powiadamiaj o potencjalnym zastosowaniu w tle aktualizacji jednej lub większej ilości aplikacji",
"xWasPossiblyUpdatedToY": "{} być może zaktualizowano do {}.", "xWasPossiblyUpdatedToY": "{} być może zaktualizowano do {}.",
"enableBackgroundUpdates": "Włącz aktualizacje w tle",
"backgroundUpdateReqsExplanation": "Aktualizacje w tle mogą nie być możliwe dla wszystkich aplikacji.", "backgroundUpdateReqsExplanation": "Aktualizacje w tle mogą nie być możliwe dla wszystkich aplikacji.",
"backgroundUpdateLimitsExplanation": "Powodzenie instalacji w tle można określić dopiero po otwarciu Obtainium.", "backgroundUpdateLimitsExplanation": "Powodzenie instalacji w tle można określić dopiero po otwarciu Obtainium.",
"verifyLatestTag": "Zweryfikuj najnowszy tag", "verifyLatestTag": "Zweryfikuj najnowszy tag",
"intermediateLinkRegex": "Filtr linków \"pośrednich\" do odwiedzenia w pierwszej kolejności",
"intermediateLinkNotFound": "Nie znaleziono linku pośredniego",
"exemptFromBackgroundUpdates": "Wyklucz z uaktualnień w tle (jeśli są włączone)", "exemptFromBackgroundUpdates": "Wyklucz z uaktualnień w tle (jeśli są włączone)",
"bgUpdatesOnWiFiOnly": "Wyłącz aktualizacje w tle, gdy nie ma połączenia z Wi-Fi", "bgUpdatesOnWiFiOnly": "Wyłącz aktualizacje w tle, gdy nie ma połączenia z Wi-Fi",
"autoSelectHighestVersionCode": "Automatycznie wybierz najwyższy kod wersji APK", "autoSelectHighestVersionCode": "Automatycznie wybierz najwyższy kod wersji APK",
@ -266,6 +263,17 @@
"debugMenu": "Menu debugowania", "debugMenu": "Menu debugowania",
"bgTaskStarted": "Uruchomiono zadanie w tle - sprawdź logi.", "bgTaskStarted": "Uruchomiono zadanie w tle - sprawdź logi.",
"runBgCheckNow": "Wymuś sprawdzenie aktualizacji w tle", "runBgCheckNow": "Wymuś sprawdzenie aktualizacji w tle",
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"installing": "Installing",
"skipUpdateNotifications": "Skip update notifications",
"updatesAvailableNotifChannel": "Dostępne aktualizacje",
"appsUpdatedNotifChannel": "Zaktualizowane aplikacje",
"appsPossiblyUpdatedNotifChannel": "Informuj o próbach aktualizacji",
"errorCheckingUpdatesNotifChannel": "Sprawdzanie błędów aktualizacji",
"appsRemovedNotifChannel": "Usunięte aplikacje",
"downloadingXNotifChannel": "Pobieranie {}",
"completeAppInstallationNotifChannel": "Ukończenie instalacji aplikacji",
"checkingForUpdatesNotifChannel": "Sprawdzanie aktualizacji",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Usunąć aplikację?", "one": "Usunąć aplikację?",
"few": "Usunąć aplikacje?", "few": "Usunąć aplikacje?",
@ -278,6 +286,12 @@
"many": "Zbyt wiele żądań (ograniczona częstotliwość) - spróbuj ponownie za {} minut", "many": "Zbyt wiele żądań (ograniczona częstotliwość) - spróbuj ponownie za {} minut",
"other": "Zbyt wiele żądań (ograniczona częstotliwość) - spróbuj ponownie za {} minuty" "other": "Zbyt wiele żądań (ograniczona częstotliwość) - spróbuj ponownie za {} minuty"
}, },
"bgUpdateGotErrorRetryInMinutes": {
"one": "Sprawdzanie aktualizacji w tle napotkało {}, zaplanuje ponowne sprawdzenie za {} minutę",
"few": "Sprawdzanie aktualizacji w tle napotkało {}, zaplanuje ponowne sprawdzenie za {} minuty",
"many": "Sprawdzanie aktualizacji w tle napotkało {}, zaplanuje ponowne sprawdzenie za {} minut",
"other": "Sprawdzanie aktualizacji w tle napotkało {}, zaplanuje ponowne sprawdzenie za {} minuty"
},
"bgCheckFoundUpdatesWillNotifyIfNeeded": { "bgCheckFoundUpdatesWillNotifyIfNeeded": {
"one": "W tle znaleziono {} aktualizację - w razie potrzeby użytkownik zostanie o tym powiadomiony", "one": "W tle znaleziono {} aktualizację - w razie potrzeby użytkownik zostanie o tym powiadomiony",
"few": "W tle znaleziono {} aktualizacje - w razie potrzeby użytkownik zostanie o tym powiadomiony", "few": "W tle znaleziono {} aktualizacje - w razie potrzeby użytkownik zostanie o tym powiadomiony",
@ -337,8 +351,5 @@
"few": "{} i {} inne apki mogły zostać zaktualizowane.", "few": "{} i {} inne apki mogły zostać zaktualizowane.",
"many": "{} i {} innych apek mogło zostać zaktualizowanych.", "many": "{} i {} innych apek mogło zostać zaktualizowanych.",
"other": "{} i {} inne apki mogły zostać zaktualizowane." "other": "{} i {} inne apki mogły zostać zaktualizowane."
}, }
"enableBackgroundUpdates": "Włącz aktualizacje w tle",
"intermediateLinkRegex": "Filtr linków \"pośrednich\" do odwiedzenia w pierwszej kolejności",
"intermediateLinkNotFound": "Nie znaleziono linku pośredniego"
} }

View File

@ -263,6 +263,17 @@
"debugMenu": "Menu Debug", "debugMenu": "Menu Debug",
"bgTaskStarted": "Tarefa em segundo plano iniciada - verifique os logs.", "bgTaskStarted": "Tarefa em segundo plano iniciada - verifique os logs.",
"runBgCheckNow": "Execute a verificação de atualização em segundo plano agora", "runBgCheckNow": "Execute a verificação de atualização em segundo plano agora",
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"installing": "Installing",
"skipUpdateNotifications": "Skip update notifications",
"updatesAvailableNotifChannel": "Atualizações Disponíveis",
"appsUpdatedNotifChannel": "Apps Atualizados",
"appsPossiblyUpdatedNotifChannel": "Tentativas de atualização de Apps",
"errorCheckingUpdatesNotifChannel": "Erro ao Procurar por Atualizações",
"appsRemovedNotifChannel": "Apps Removidos",
"downloadingXNotifChannel": "Baixando {}",
"completeAppInstallationNotifChannel": "Instalação completa do App",
"checkingForUpdatesNotifChannel": "Checando por Atualizações",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Remover App?", "one": "Remover App?",
"other": "Remover Apps?" "other": "Remover Apps?"
@ -315,4 +326,4 @@
"one": "{} e 1 outro app pode ter sido atualizado.", "one": "{} e 1 outro app pode ter sido atualizado.",
"other": "{} e {} outros apps podem ter sido atualizados." "other": "{} e {} outros apps podem ter sido atualizados."
} }
} }

View File

@ -263,6 +263,17 @@
"debugMenu": "Меню Отладки", "debugMenu": "Меню Отладки",
"bgTaskStarted": "Фоновая задача начата - проверьте журналы.", "bgTaskStarted": "Фоновая задача начата - проверьте журналы.",
"runBgCheckNow": "Запустить проверку фонового обновления сейчас", "runBgCheckNow": "Запустить проверку фонового обновления сейчас",
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"installing": "Installing",
"skipUpdateNotifications": "Skip update notifications",
"updatesAvailableNotifChannel": "Доступны обновления",
"appsUpdatedNotifChannel": "Приложения обновлены",
"appsPossiblyUpdatedNotifChannel": "Попытки обновления приложений",
"errorCheckingUpdatesNotifChannel": "Ошибка при проверке обновлений",
"appsRemovedNotifChannel": "Приложение удалено",
"downloadingXNotifChannel": "Загрузка {}",
"completeAppInstallationNotifChannel": "Завершение установки приложения",
"checkingForUpdatesNotifChannel": "Проверка обновлений",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Удалить приложение?", "one": "Удалить приложение?",
"other": "Удалить приложения?" "other": "Удалить приложения?"
@ -315,4 +326,4 @@
"one": "{} и ещё 1 приложение могли быть обновлены.", "one": "{} и ещё 1 приложение могли быть обновлены.",
"other": "{} и ещё {} приложений могли быть обновлены." "other": "{} и ещё {} приложений могли быть обновлены."
} }
} }

View File

@ -238,31 +238,42 @@
"gitlabSourceNote": "未使用访问令牌时可能无法从 GitLab 获取 APK 文件。", "gitlabSourceNote": "未使用访问令牌时可能无法从 GitLab 获取 APK 文件。",
"sortByFileNamesNotLinks": "使用文件名代替链接进行排序", "sortByFileNamesNotLinks": "使用文件名代替链接进行排序",
"filterReleaseNotesByRegEx": "使用正则表达式筛选发行说明", "filterReleaseNotesByRegEx": "使用正则表达式筛选发行说明",
"customLinkFilterRegex": "使用正则表达式自定义链接筛选(默认模式为“.apk$”)", "customLinkFilterRegex": "使用正则表达式筛选自定义来源 APK 文件链接\n未填写时默认匹配模式为“.apk$”)",
"appsPossiblyUpdated": "已尝试更新应用", "appsPossiblyUpdated": "已尝试更新应用",
"appsPossiblyUpdatedNotifDescription": "当应用已尝试在后台更新时发送通知", "appsPossiblyUpdatedNotifDescription": "当应用已尝试在后台更新时发送通知",
"xWasPossiblyUpdatedToY": "已尝试将 {} 更新至 {}。", "xWasPossiblyUpdatedToY": "已尝试将{}更新至 {}。",
"enableBackgroundUpdates": "启用后台更新", "enableBackgroundUpdates": "启用后台更新",
"backgroundUpdateReqsExplanation": "后台更新未必适用于所有的应用。", "backgroundUpdateReqsExplanation": "后台更新未必适用于所有的应用。",
"backgroundUpdateLimitsExplanation": "只有在启动 Obtainium 时才能确认安装是否成功。", "backgroundUpdateLimitsExplanation": "只有在启动 Obtainium 时才能确认安装是否成功。",
"verifyLatestTag": "验证“Latest”标签", "verifyLatestTag": "验证“Latest”标签",
"intermediateLinkRegex": "首先访问“中”链接的过滤器", "intermediateLinkRegex": "筛选一个首先访问“中”链接(正则表达式)",
"intermediateLinkNotFound": "中间链接未找到", "intermediateLinkNotFound": "未找到“中转”链接",
"exemptFromBackgroundUpdates": "禁用后台更新(如果全局设置启用)", "exemptFromBackgroundUpdates": "单独禁用后台更新(若已经全局启用)",
"bgUpdatesOnWiFiOnly": "不在连接 WiFi 时禁用后台更新", "bgUpdatesOnWiFiOnly": "连接 Wi-Fi 时禁用后台更新",
"autoSelectHighestVersionCode": "自动选择最高版本号 APK", "autoSelectHighestVersionCode": "自动选择版本号最高的 APK 文件",
"versionExtractionRegEx": "版本提取正则表达式", "versionExtractionRegEx": "获取版本号的正则表达式",
"matchGroupToUse": "匹配要使用的组", "matchGroupToUse": "引用的捕获组",
"highlightTouchTargets": "突出示不明显的触摸目标", "highlightTouchTargets": "突出示不明显的触摸区域",
"pickExportDir": "选择导出目录", "pickExportDir": "选择导出文件夹",
"autoExportOnChanges": "修改时自动导出", "autoExportOnChanges": "数据变更时自动导出",
"filterVersionsByRegEx": "使用正则表达式筛选版本", "filterVersionsByRegEx": "使用正则表达式筛选版本",
"trySelectingSuggestedVersionCode": "尝试选择推荐版本 APK", "trySelectingSuggestedVersionCode": "尝试选择推荐版本 APK 文件",
"dontSortReleasesList": "Retain release order from API", "dontSortReleasesList": "保持来自 API 的发行顺序",
"reverseSort": "Reverse sorting", "reverseSort": "反转排序",
"debugMenu": "Debug Menu", "debugMenu": "调试选项",
"bgTaskStarted": "Background task started - check logs.", "bgTaskStarted": "后台任务已启动 - 详见日志",
"runBgCheckNow": "Run Background Update Check Now", "runBgCheckNow": "立即进行后台更新检查",
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
"installing": "Installing",
"skipUpdateNotifications": "Skip update notifications",
"updatesAvailableNotifChannel": "更新可用",
"appsUpdatedNotifChannel": "应用已更新",
"appsPossiblyUpdatedNotifChannel": "已尝试更新应用",
"errorCheckingUpdatesNotifChannel": "检查更新出错",
"appsRemovedNotifChannel": "应用已删除",
"downloadingXNotifChannel": "正在下载{}",
"completeAppInstallationNotifChannel": "完成应用安装",
"checkingForUpdatesNotifChannel": "正在检查更新",
"removeAppQuestion": { "removeAppQuestion": {
"one": "是否删除应用?", "one": "是否删除应用?",
"other": "是否删除应用?" "other": "是否删除应用?"
@ -315,4 +326,4 @@
"one": "{} 和另外 1 个应用已尝试更新。", "one": "{} 和另外 1 个应用已尝试更新。",
"other": "{} 和另外 {} 个应用已尝试更新。" "other": "{} 和另外 {} 个应用已尝试更新。"
} }
} }

View File

@ -22,6 +22,7 @@ class APKPure extends AppSource {
APKPure() { APKPure() {
host = 'apkpure.com'; host = 'apkpure.com';
allowSubDomains = true; allowSubDomains = true;
naiveStandardVersionDetection = true;
} }
@override @override

View File

@ -9,6 +9,7 @@ class Aptoide extends AppSource {
host = 'aptoide.com'; host = 'aptoide.com';
name = tr('Aptoide'); name = tr('Aptoide');
allowSubDomains = true; allowSubDomains = true;
naiveStandardVersionDetection = true;
} }
@override @override

View File

@ -11,6 +11,7 @@ class FDroid extends AppSource {
FDroid() { FDroid() {
host = 'f-droid.org'; host = 'f-droid.org';
name = tr('fdroid'); name = tr('fdroid');
naiveStandardVersionDetection = true;
canSearch = true; canSearch = true;
additionalSourceAppSpecificSettingFormItems = [ additionalSourceAppSpecificSettingFormItems = [
[ [

View File

@ -22,7 +22,7 @@ String ensureAbsoluteUrl(String ambiguousUrl, Uri referenceAbsoluteUrl) {
} else if (ambiguousUrl.split('/').where((e) => e.isNotEmpty).length == 1) { } else if (ambiguousUrl.split('/').where((e) => e.isNotEmpty).length == 1) {
return '${referenceAbsoluteUrl.origin}/${currPathSegments.join('/')}/$ambiguousUrl'; return '${referenceAbsoluteUrl.origin}/${currPathSegments.join('/')}/$ambiguousUrl';
} else { } else {
return '${referenceAbsoluteUrl.origin}/${currPathSegments.sublist(0, currPathSegments.length - 1).join('/')}/$ambiguousUrl'; return '${referenceAbsoluteUrl.origin}/${currPathSegments.sublist(0, currPathSegments.length - (currPathSegments.last.contains('.') ? 1 : 0)).join('/')}/$ambiguousUrl';
} }
} }
@ -117,20 +117,26 @@ class HTML extends AppSource {
label: tr('versionExtractionRegEx'), label: tr('versionExtractionRegEx'),
required: false, required: false,
additionalValidators: [(value) => regExValidator(value)]), additionalValidators: [(value) => regExValidator(value)]),
],
[
GeneratedFormTextField('matchGroupToUse', GeneratedFormTextField('matchGroupToUse',
label: tr('matchGroupToUse'), label: tr('matchGroupToUse'),
required: false, required: false,
hint: '1', hint: '0',
textInputType: const TextInputType.numberWithOptions(), textInputType: const TextInputType.numberWithOptions(),
additionalValidators: [ additionalValidators: [
(value) { (value) {
if (value?.isEmpty == true) { if (value?.isEmpty == true) {
value = null; value = null;
} }
value ??= '1'; value ??= '0';
return intValidator(value); return intValidator(value);
} }
]) ])
],
[
GeneratedFormSwitch('versionExtractWholePage',
label: tr('versionExtractWholePage'))
] ]
]; ];
overrideVersionDetectionFormDefault('noVersionDetection', overrideVersionDetectionFormDefault('noVersionDetection',
@ -212,12 +218,17 @@ class HTML extends AppSource {
var versionExtractionRegEx = var versionExtractionRegEx =
additionalSettings['versionExtractionRegEx'] as String?; additionalSettings['versionExtractionRegEx'] as String?;
if (versionExtractionRegEx?.isNotEmpty == true) { if (versionExtractionRegEx?.isNotEmpty == true) {
var match = RegExp(versionExtractionRegEx!).allMatches(rel); var match = RegExp(versionExtractionRegEx!).allMatches(
res.body.split('\r\n').join('\n').split('\n').join('\\n'));
if (match.isEmpty) { if (match.isEmpty) {
throw NoVersionError(); throw NoVersionError();
} }
version = match.last String matchGroupString =
.group(int.parse(additionalSettings['matchGroupToUse'] as String)); (additionalSettings['matchGroupToUse'] as String).trim();
if (matchGroupString.isEmpty) {
matchGroupString = "0";
}
version = match.last.group(int.parse(matchGroupString));
if (version?.isEmpty == true) { if (version?.isEmpty == true) {
throw NoVersionError(); throw NoVersionError();
} }

View File

@ -8,6 +8,7 @@ class Uptodown extends AppSource {
Uptodown() { Uptodown() {
host = 'uptodown.com'; host = 'uptodown.com';
allowSubDomains = true; allowSubDomains = true;
naiveStandardVersionDetection = true;
} }
@override @override
@ -34,7 +35,7 @@ class Uptodown extends AppSource {
var html = parse(res.body); var html = parse(res.body);
String? version = html.querySelector('div.version')?.innerHtml; String? version = html.querySelector('div.version')?.innerHtml;
String? apkUrl = String? apkUrl =
html.querySelector('#detail-download-button')?.attributes['data-url']; '${standardUrl.split('/').reversed.toList().sublist(1).reversed.join('/')}/post-download';
String? name = html.querySelector('#detail-app-name')?.innerHtml.trim(); String? name = html.querySelector('#detail-app-name')?.innerHtml.trim();
String? author = html.querySelector('#author-link')?.innerHtml.trim(); String? author = html.querySelector('#author-link')?.innerHtml.trim();
var detailElements = html.querySelectorAll('#technical-information td'); var detailElements = html.querySelectorAll('#technical-information td');
@ -79,4 +80,20 @@ class Uptodown extends AppSource {
version, getApkUrlsFromUrls([apkUrl]), AppNames(author, appName), version, getApkUrlsFromUrls([apkUrl]), AppNames(author, appName),
releaseDate: relDate); releaseDate: relDate);
} }
@override
Future<String> apkUrlPrefetchModifier(
String apkUrl, String standardUrl) async {
var res = await sourceRequest(apkUrl);
if (res.statusCode != 200) {
throw getObtainiumHttpError(res);
}
var html = parse(res.body);
var finalUrl =
(html.querySelector('.post-download')?.attributes['data-url']);
if (finalUrl == null) {
throw NoAPKError();
}
return finalUrl;
}
} }

View File

@ -16,14 +16,13 @@ class WhatsApp extends AppSource {
@override @override
Future<String> apkUrlPrefetchModifier( Future<String> apkUrlPrefetchModifier(
String apkUrl, String standardUrl) async { String apkUrl, String standardUrl) async {
Response res = await sourceRequest('https://www.whatsapp.com/android'); Response res = await sourceRequest('$standardUrl/android');
if (res.statusCode == 200) { if (res.statusCode == 200) {
var targetLinks = parse(res.body) var targetLinks = parse(res.body)
.querySelectorAll('a') .querySelectorAll('a')
.map((e) => e.attributes['href'] ?? '') .map((e) => e.attributes['href'] ?? '')
.where((e) => e.isNotEmpty) .where((e) => e.isNotEmpty)
.where((e) => .where((e) => e.contains('WhatsApp.apk'))
e.contains('content.whatsapp.net') && e.contains('WhatsApp.apk'))
.toList(); .toList();
if (targetLinks.isEmpty) { if (targetLinks.isEmpty) {
throw NoAPKError(); throw NoAPKError();
@ -39,37 +38,16 @@ class WhatsApp extends AppSource {
String standardUrl, String standardUrl,
Map<String, dynamic> additionalSettings, Map<String, dynamic> additionalSettings,
) async { ) async {
Response res = await sourceRequest('https://www.whatsapp.com/android'); // This is a CDN link that is consistent per version
if (res.statusCode == 200) { // But it has query params that change constantly
var targetElements = parse(res.body) Uri apkUri =
.querySelectorAll('p') Uri.parse(await apkUrlPrefetchModifier(standardUrl, standardUrl));
.where((element) => element.innerHtml.contains('Version ')) var unusableApkUrl = '${apkUri.origin}/${apkUri.path}';
.toList(); // So we use the param-less URL is a pseudo-version to add the app and check for updates
if (targetElements.isEmpty) { // See #357 for why we can't scrape the version number directly
throw NoVersionError(); // But we re-fetch the URL again with its latest query params at the actual download time
} String version = unusableApkUrl.hashCode.toString();
var vLines = targetElements[0] return APKDetails(version, getApkUrlsFromUrls([unusableApkUrl]),
.innerHtml AppNames('Meta', 'WhatsApp'));
.split('\n')
.where((element) => element.contains('Version '))
.toList();
if (vLines.isEmpty) {
throw NoVersionError();
}
var versionMatch = RegExp('[0-9]+(\\.[0-9]+)+').firstMatch(vLines[0]);
if (versionMatch == null) {
throw NoVersionError();
}
String version =
vLines[0].substring(versionMatch.start, versionMatch.end);
return APKDetails(
version,
getApkUrlsFromUrls([
'https://www.whatsapp.com/android?v=$version&=thisIsaPlaceholder&a=realURLPrefetchedAtDownloadTime'
]),
AppNames('Meta', 'WhatsApp'));
} else {
throw getObtainiumHttpError(res);
}
} }
} }

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:android_package_installer/android_package_installer.dart'; import 'package:android_package_installer/android_package_installer.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -65,25 +67,38 @@ class NotImplementedError extends ObtainiumError {
} }
class MultiAppMultiError extends ObtainiumError { class MultiAppMultiError extends ObtainiumError {
Map<String, List<String>> content = {}; Map<String, dynamic> rawErrors = {};
Map<String, List<String>> idsByErrorString = {};
Map<String, String> appIdNames = {};
MultiAppMultiError() : super(tr('placeholder'), unexpected: true); MultiAppMultiError() : super(tr('placeholder'), unexpected: true);
add(String appId, String string) { add(String appId, dynamic error, {String? appName}) {
var tempIds = content.remove(string); if (error is SocketException) {
error = error.message;
}
rawErrors[appId] = error;
var string = error.toString();
var tempIds = idsByErrorString.remove(string);
tempIds ??= []; tempIds ??= [];
tempIds.add(appId); tempIds.add(appId);
content.putIfAbsent(string, () => tempIds!); idsByErrorString.putIfAbsent(string, () => tempIds!);
if (appName != null) {
appIdNames[appId] = appName;
}
} }
String errorString(String appId, {bool includeIdsWithNames = false}) =>
'${appIdNames.containsKey(appId) ? '${appIdNames[appId]}${includeIdsWithNames ? ' ($appId)' : ''}' : appId}: ${rawErrors[appId].toString()}';
String errorsAppsString(String errString, List<String> appIds,
{bool includeIdsWithNames = false}) =>
'$errString [${list2FriendlyString(appIds.map((id) => appIdNames.containsKey(id) == true ? '${appIdNames[id]}${includeIdsWithNames ? ' ($id)' : ''}' : id).toList())}]';
@override @override
String toString() { String toString() => idsByErrorString.entries
String finalString = ''; .map((e) => errorsAppsString(e.key, e.value))
for (var e in content.keys) { .join('\n\n');
finalString += '$e: ${content[e].toString()}\n\n';
}
return finalString;
}
} }
showError(dynamic e, BuildContext context) { showError(dynamic e, BuildContext context) {

View File

@ -19,7 +19,7 @@ import 'package:easy_localization/src/easy_localization_controller.dart';
// ignore: implementation_imports // ignore: implementation_imports
import 'package:easy_localization/src/localization.dart'; import 'package:easy_localization/src/localization.dart';
const String currentVersion = '0.14.21'; const String currentVersion = '0.14.27';
const String currentReleaseTag = const String currentReleaseTag =
'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES 'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES

View File

@ -68,7 +68,7 @@ class AppsPageState extends State<AppsPage> {
refreshingSince = DateTime.now(); refreshingSince = DateTime.now();
}); });
return appsProvider.checkUpdates().catchError((e) { return appsProvider.checkUpdates().catchError((e) {
showError(e, context); showError(e is Map ? e['errors'] : e, context);
return <App>[]; return <App>[];
}).whenComplete(() { }).whenComplete(() {
setState(() { setState(() {
@ -566,7 +566,7 @@ class AppsPageState extends State<AppsPage> {
.toInt() .toInt()
.toString() .toString()
]) ])
: tr('pleaseWait'), : tr('installing'),
textAlign: (listedApps[index].downloadProgress! >= 0) textAlign: (listedApps[index].downloadProgress! >= 0)
? TextAlign.start ? TextAlign.start
: TextAlign.end, : TextAlign.end,
@ -833,7 +833,7 @@ class AppsPageState extends State<AppsPage> {
items: const [], items: const [],
initValid: true, initValid: true,
message: tr('installStatusOfXWillBeResetExplanation', message: tr('installStatusOfXWillBeResetExplanation',
args: [plural('app', selectedAppIds.length)]), args: [plural('apps', selectedAppIds.length)]),
); );
}); });
if (values != null) { if (values != null) {

View File

@ -217,7 +217,8 @@ class _ImportExportPageState extends State<ImportExportPage> {
if (errors.isEmpty) { if (errors.isEmpty) {
// ignore: use_build_context_synchronously // ignore: use_build_context_synchronously
showError( showError(
tr('importedX', args: [plural('app', selectedUrls.length)]), tr('importedX',
args: [plural('apps', selectedUrls.length)]),
context); context);
} else { } else {
// ignore: use_build_context_synchronously // ignore: use_build_context_synchronously
@ -274,7 +275,7 @@ class _ImportExportPageState extends State<ImportExportPage> {
if (errors.isEmpty) { if (errors.isEmpty) {
// ignore: use_build_context_synchronously // ignore: use_build_context_synchronously
showError( showError(
tr('importedX', args: [plural('app', selectedUrls.length)]), tr('importedX', args: [plural('apps', selectedUrls.length)]),
context); context);
} else { } else {
// ignore: use_build_context_synchronously // ignore: use_build_context_synchronously

View File

@ -263,25 +263,29 @@ class AppsProvider with ChangeNotifier {
return downloadedFile; return downloadedFile;
} }
Future<File> handleAPKIDChange(App app, PackageInfo newInfo, Future<File> handleAPKIDChange(App app, PackageInfo? newInfo,
File downloadedFile, String downloadUrl) async { File downloadedFile, String downloadUrl) async {
// If the APK package ID is different from the App ID, it is either new (using a placeholder ID) or the ID has changed // If the APK package ID is different from the App ID, it is either new (using a placeholder ID) or the ID has changed
// The former case should be handled (give the App its real ID), the latter is a security issue // The former case should be handled (give the App its real ID), the latter is a security issue
if (app.id != newInfo.packageName) { var isTempId = SourceProvider().isTempId(app);
var isTempId = SourceProvider().isTempId(app); if (newInfo != null) {
if (apps[app.id] != null && !isTempId && !app.allowIdChange) { if (app.id != newInfo.packageName) {
throw IDChangedError(newInfo.packageName!); if (apps[app.id] != null && !isTempId && !app.allowIdChange) {
} throw IDChangedError(newInfo.packageName!);
var idChangeWasAllowed = app.allowIdChange; }
app.allowIdChange = false; var idChangeWasAllowed = app.allowIdChange;
var originalAppId = app.id; app.allowIdChange = false;
app.id = newInfo.packageName!; var originalAppId = app.id;
downloadedFile = downloadedFile.renameSync( app.id = newInfo.packageName!;
'${downloadedFile.parent.path}/${app.id}-${downloadUrl.hashCode}.${downloadedFile.path.split('.').last}'); downloadedFile = downloadedFile.renameSync(
if (apps[originalAppId] != null) { '${downloadedFile.parent.path}/${app.id}-${downloadUrl.hashCode}.${downloadedFile.path.split('.').last}');
await removeApps([originalAppId]); if (apps[originalAppId] != null) {
await saveApps([app], onlyIfExists: !isTempId && !idChangeWasAllowed); await removeApps([originalAppId]);
await saveApps([app], onlyIfExists: !isTempId && !idChangeWasAllowed);
}
} }
} else if (isTempId) {
throw ObtainiumError('Could not get ID from APK');
} }
return downloadedFile; return downloadedFile;
} }
@ -344,7 +348,7 @@ class AppsProvider with ChangeNotifier {
await pm.getPackageArchiveInfo(archiveFilePath: apks.first.path); await pm.getPackageArchiveInfo(archiveFilePath: apks.first.path);
} }
downloadedFile = downloadedFile =
await handleAPKIDChange(app, newInfo!, downloadedFile, downloadUrl); await handleAPKIDChange(app, newInfo, downloadedFile, downloadUrl);
// Delete older versions of the file if any // Delete older versions of the file if any
for (var file in downloadedFile.parent.listSync()) { for (var file in downloadedFile.parent.listSync()) {
var fn = file.path.split('/').last; var fn = file.path.split('/').last;
@ -449,7 +453,7 @@ class AppsProvider with ChangeNotifier {
} catch (e) { } catch (e) {
logs.add( logs.add(
'Could not install APK from XAPK \'${file.path}\': ${e.toString()}'); 'Could not install APK from XAPK \'${file.path}\': ${e.toString()}');
errors.add(dir.appId, e.toString()); errors.add(dir.appId, e, appName: apps[dir.appId]?.name);
} }
} else if (file.path.toLowerCase().endsWith('.obb')) { } else if (file.path.toLowerCase().endsWith('.obb')) {
await moveObbFile(file, dir.appId); await moveObbFile(file, dir.appId);
@ -457,7 +461,7 @@ class AppsProvider with ChangeNotifier {
} }
if (somethingInstalled) { if (somethingInstalled) {
dir.file.delete(recursive: true); dir.file.delete(recursive: true);
} else if (errors.content.isNotEmpty) { } else if (errors.idsByErrorString.isNotEmpty) {
throw errors; throw errors;
} }
} finally { } finally {
@ -677,11 +681,11 @@ class AppsProvider with ChangeNotifier {
} }
installedIds.add(id); installedIds.add(id);
} catch (e) { } catch (e) {
errors.add(id, e.toString()); errors.add(id, e, appName: apps[id]?.name);
} }
} }
if (errors.content.isNotEmpty) { if (errors.idsByErrorString.isNotEmpty) {
throw errors; throw errors;
} }
@ -709,14 +713,21 @@ class AppsProvider with ChangeNotifier {
} }
bool isVersionDetectionPossible(AppInMemory? app) { bool isVersionDetectionPossible(AppInMemory? app) {
return app?.app.additionalSettings['trackOnly'] != true && if (app?.app == null) {
app?.app.additionalSettings['versionDetection'] != return false;
}
var naiveStandardVersionDetection = SourceProvider()
.getSource(app!.app.url, overrideSource: app.app.overrideSource)
.naiveStandardVersionDetection;
return app.app.additionalSettings['trackOnly'] != true &&
app.app.additionalSettings['versionDetection'] !=
'releaseDateAsVersion' && 'releaseDateAsVersion' &&
app?.installedInfo?.versionName != null && app.installedInfo?.versionName != null &&
app?.app.installedVersion != null && app.app.installedVersion != null &&
reconcileVersionDifferences( (reconcileVersionDifferences(app.installedInfo!.versionName!,
app!.installedInfo!.versionName!, app.app.installedVersion!) != app.app.installedVersion!) !=
null; null ||
naiveStandardVersionDetection);
} }
// Given an App and it's on-device info... // Given an App and it's on-device info...
@ -725,8 +736,12 @@ class AppsProvider with ChangeNotifier {
App app, PackageInfo? installedInfo) { App app, PackageInfo? installedInfo) {
var modded = false; var modded = false;
var trackOnly = app.additionalSettings['trackOnly'] == true; var trackOnly = app.additionalSettings['trackOnly'] == true;
var noVersionDetection = app.additionalSettings['versionDetection'] != var versionDetectionIsStandard =
'standardVersionDetection'; app.additionalSettings['versionDetection'] ==
'standardVersionDetection';
var naiveStandardVersionDetection = SourceProvider()
.getSource(app.url, overrideSource: app.overrideSource)
.naiveStandardVersionDetection;
// FIRST, COMPARE THE APP'S REPORTED AND REAL INSTALLED VERSIONS, WHERE ONE IS NULL // FIRST, COMPARE THE APP'S REPORTED AND REAL INSTALLED VERSIONS, WHERE ONE IS NULL
if (installedInfo == null && app.installedVersion != null && !trackOnly) { if (installedInfo == null && app.installedVersion != null && !trackOnly) {
// App says it's installed but isn't really (and isn't track only) - set to not installed // App says it's installed but isn't really (and isn't track only) - set to not installed
@ -741,7 +756,7 @@ class AppsProvider with ChangeNotifier {
// SECOND, RECONCILE DIFFERENCES BETWEEN THE APP'S REPORTED AND REAL INSTALLED VERSIONS, WHERE NEITHER IS NULL // SECOND, RECONCILE DIFFERENCES BETWEEN THE APP'S REPORTED AND REAL INSTALLED VERSIONS, WHERE NEITHER IS NULL
if (installedInfo?.versionName != null && if (installedInfo?.versionName != null &&
installedInfo!.versionName != app.installedVersion && installedInfo!.versionName != app.installedVersion &&
!noVersionDetection) { versionDetectionIsStandard) {
// App's reported version and real version don't match (and it uses standard version detection) // App's reported version and real version don't match (and it uses standard version detection)
// If they share a standard format (and are still different under it), update the reported version accordingly // If they share a standard format (and are still different under it), update the reported version accordingly
var correctedInstalledVersion = reconcileVersionDifferences( var correctedInstalledVersion = reconcileVersionDifferences(
@ -749,12 +764,15 @@ class AppsProvider with ChangeNotifier {
if (correctedInstalledVersion?.key == false) { if (correctedInstalledVersion?.key == false) {
app.installedVersion = correctedInstalledVersion!.value; app.installedVersion = correctedInstalledVersion!.value;
modded = true; modded = true;
} else if (naiveStandardVersionDetection) {
app.installedVersion = installedInfo.versionName;
modded = true;
} }
} }
// THIRD, RECONCILE THE APP'S REPORTED INSTALLED AND LATEST VERSIONS // THIRD, RECONCILE THE APP'S REPORTED INSTALLED AND LATEST VERSIONS
if (app.installedVersion != null && if (app.installedVersion != null &&
app.installedVersion != app.latestVersion && app.installedVersion != app.latestVersion &&
!noVersionDetection) { versionDetectionIsStandard) {
// App's reported installed and latest versions don't match (and it uses standard version detection) // App's reported installed and latest versions don't match (and it uses standard version detection)
// If they share a standard format, make sure the App's reported installed version uses that format // If they share a standard format, make sure the App's reported installed version uses that format
var correctedInstalledVersion = var correctedInstalledVersion =
@ -766,8 +784,7 @@ class AppsProvider with ChangeNotifier {
} }
// FOURTH, DISABLE VERSION DETECTION IF ENABLED AND THE REPORTED/REAL INSTALLED VERSIONS ARE NOT STANDARDIZED // FOURTH, DISABLE VERSION DETECTION IF ENABLED AND THE REPORTED/REAL INSTALLED VERSIONS ARE NOT STANDARDIZED
if (installedInfo != null && if (installedInfo != null &&
app.additionalSettings['versionDetection'] == versionDetectionIsStandard &&
'standardVersionDetection' &&
!isVersionDetectionPossible( !isVersionDetectionPossible(
AppInMemory(app, null, installedInfo, null))) { AppInMemory(app, null, installedInfo, null))) {
app.additionalSettings['versionDetection'] = 'noVersionDetection'; app.additionalSettings['versionDetection'] = 'noVersionDetection';
@ -1055,7 +1072,8 @@ class AppsProvider with ChangeNotifier {
Future<List<App>> checkUpdates( Future<List<App>> checkUpdates(
{DateTime? ignoreAppsCheckedAfter, {DateTime? ignoreAppsCheckedAfter,
bool throwErrorsForRetry = false}) async { bool throwErrorsForRetry = false,
List<String>? specificIds}) async {
List<App> updates = []; List<App> updates = [];
MultiAppMultiError errors = MultiAppMultiError(); MultiAppMultiError errors = MultiAppMultiError();
if (!gettingUpdates) { if (!gettingUpdates) {
@ -1063,27 +1081,33 @@ class AppsProvider with ChangeNotifier {
try { try {
List<String> appIds = getAppsSortedByUpdateCheckTime( List<String> appIds = getAppsSortedByUpdateCheckTime(
ignoreAppsCheckedAfter: ignoreAppsCheckedAfter); ignoreAppsCheckedAfter: ignoreAppsCheckedAfter);
for (int i = 0; i < appIds.length; i++) { if (specificIds != null) {
appIds = appIds.where((aId) => specificIds.contains(aId)).toList();
}
await Future.wait(appIds.map((appId) async {
App? newApp; App? newApp;
try { try {
newApp = await checkUpdate(appIds[i]); newApp = await checkUpdate(appId);
} catch (e) { } catch (e) {
if ((e is RateLimitError || e is SocketException) && if ((e is RateLimitError || e is SocketException) &&
throwErrorsForRetry) { throwErrorsForRetry) {
rethrow; rethrow;
} }
errors.add(appIds[i], e.toString()); errors.add(appId, e, appName: apps[appId]?.name);
} }
if (newApp != null) { if (newApp != null) {
updates.add(newApp); updates.add(newApp);
} }
} }), eagerError: true);
} finally { } finally {
gettingUpdates = false; gettingUpdates = false;
} }
} }
if (errors.content.isNotEmpty) { if (errors.idsByErrorString.isNotEmpty) {
throw errors; var res = <String, dynamic>{};
res['errors'] = errors;
res['updates'] = updates;
throw res;
} }
return updates; return updates;
} }
@ -1116,7 +1140,6 @@ class AppsProvider with ChangeNotifier {
return null; return null;
} }
if (exportDir == null) { if (exportDir == null) {
logs.add('Skipping auto-export as dir is not set.');
return null; return null;
} }
var files = await saf var files = await saf
@ -1300,18 +1323,16 @@ class _APKOriginWarningDialogState extends State<APKOriginWarningDialog> {
/// Background updater function /// Background updater function
/// ///
/// @param List<String>? toCheck: The appIds to check for updates (default to all apps sorted by last update check time) /// @param List<MapEntry<String, int>>? toCheck: The appIds to check for updates (with the number of previous attempts made per appid) (defaults to all apps)
/// ///
/// @param List<String>? toInstall: The appIds to attempt to update (defaults to an empty array) /// @param List<String>? toInstall: The appIds to attempt to update (defaults to an empty array)
/// ///
/// @param int? attemptCount: The number of times the function has failed up to this point (defaults to 0)
///
/// When toCheck is empty, the function is in "install mode" (else it is in "update mode"). /// When toCheck is empty, the function is in "install mode" (else it is in "update mode").
/// In update mode, all apps in toCheck are checked for updates. /// In update mode, all apps in toCheck are checked for updates.
/// If an update is available, the appId is either added to toInstall (if a background update is possible) or the user is notified. /// If an update is available, the appId is either added to toInstall (if a background update is possible) or the user is notified.
/// If there is an error, the function tries to continue after a few minutes (duration depends on the error), up to a maximum of 5 tries. /// If there are errors, the task is run again for the remaining apps after a few minutes (duration depends on the errors), up to a maximum of 5 tries for any app.
/// ///
/// Once all update checks are complete, the function is called again in install mode. /// Once all update checks are complete, the task is run again in install mode.
/// In this mode, all apps in toInstall are downloaded and installed in the background (install result is unknown). /// In this mode, all apps in toInstall are downloaded and installed in the background (install result is unknown).
/// If there is an error, the function tries to continue after a few minutes (duration depends on the error), up to a maximum of 5 tries. /// If there is an error, the function tries to continue after a few minutes (duration depends on the error), up to a maximum of 5 tries.
/// ///
@ -1351,8 +1372,49 @@ Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
(<List<MapEntry<String, int>>>[])) (<List<MapEntry<String, int>>>[]))
]; ];
bool installMode = toCheck.isEmpty && var netResult = await (Connectivity().checkConnectivity());
toInstall.isNotEmpty; // Task is either in update mode or install mode
if (netResult == ConnectivityResult.none) {
var networkBasedRetryInterval = 15;
var nextRegularCheck = appsProvider.settingsProvider.lastBGCheckTime
.add(Duration(minutes: appsProvider.settingsProvider.updateInterval));
var potentialNetworkRetryCheck =
DateTime.now().add(Duration(minutes: networkBasedRetryInterval));
var shouldRetry = potentialNetworkRetryCheck.isBefore(nextRegularCheck);
logs.add(
'BG update task $taskId: No network. Will ${shouldRetry ? 'retry in $networkBasedRetryInterval minutes' : 'not retry'}.');
AndroidAlarmManager.oneShot(
const Duration(minutes: 15), taskId + 1, bgUpdateCheck,
params: {
'toCheck': toCheck
.map((entry) => {'key': entry.key, 'value': entry.value})
.toList(),
'toInstall': toInstall
.map((entry) => {'key': entry.key, 'value': entry.value})
.toList(),
});
return;
}
var networkRestricted = false;
if (appsProvider.settingsProvider.bgUpdatesOnWiFiOnly) {
networkRestricted = (netResult != ConnectivityResult.wifi) &&
(netResult != ConnectivityResult.ethernet);
}
bool installMode =
toCheck.isEmpty; // Task is either in update mode or install mode
// In install mode, grab all available silent updates unless explicitly told otherwise
if (installMode && toInstall.isEmpty && !networkRestricted) {
var temp = appsProvider.findExistingUpdates(installedOnly: true);
for (var i = 0; i < temp.length; i++) {
if (await appsProvider
.canInstallSilently(appsProvider.apps[temp[i]]!.app)) {
toInstall.add(MapEntry(temp[i], 0));
}
}
}
logs.add( logs.add(
'BG ${installMode ? 'install' : 'update'} task $taskId: Started (${installMode ? toInstall.length : toCheck.length}).'); 'BG ${installMode ? 'install' : 'update'} task $taskId: Started (${installMode ? toInstall.length : toCheck.length}).');
@ -1361,12 +1423,6 @@ Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
// If in update mode... // If in update mode...
var didCompleteChecking = false; var didCompleteChecking = false;
CheckingUpdatesNotification? notif; CheckingUpdatesNotification? notif;
var networkRestricted = false;
if (appsProvider.settingsProvider.bgUpdatesOnWiFiOnly) {
var netResult = await (Connectivity().checkConnectivity());
networkRestricted = (netResult != ConnectivityResult.wifi) &&
(netResult != ConnectivityResult.ethernet);
}
// Loop through all updates and check each // Loop through all updates and check each
List<App> toNotify = []; List<App> toNotify = [];
try { try {
@ -1383,9 +1439,10 @@ Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
if (newApp != null) { if (newApp != null) {
if (networkRestricted || if (networkRestricted ||
!(await appsProvider.canInstallSilently(app!.app))) { !(await appsProvider.canInstallSilently(app!.app))) {
toNotify.add(newApp); if (newApp.additionalSettings['skipUpdateNotifications'] !=
} else { true) {
toInstall.add(MapEntry(appId, 0)); toNotify.add(newApp);
}
} }
} }
if (i == (toCheck.length - 1)) { if (i == (toCheck.length - 1)) {
@ -1438,7 +1495,7 @@ Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
} }
} }
// If you're done checking and found some silently installable updates, schedule another task which will run in install mode // If you're done checking and found some silently installable updates, schedule another task which will run in install mode
if (didCompleteChecking && toInstall.isNotEmpty) { if (didCompleteChecking) {
logs.add( logs.add(
'BG update task $taskId: Done. Scheduling install task to run immediately.'); 'BG update task $taskId: Done. Scheduling install task to run immediately.');
AndroidAlarmManager.oneShot( AndroidAlarmManager.oneShot(
@ -1450,7 +1507,7 @@ Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
.toList() .toList()
}); });
} else if (didCompleteChecking) { } else if (didCompleteChecking) {
logs.add('BG install task $taskId: Done.'); logs.add('BG update task $taskId: Done.');
} }
} else { } else {
// If in install mode... // If in install mode...

View File

@ -28,7 +28,7 @@ class UpdateNotification extends ObtainiumNotification {
tr('updatesAvailable'), tr('updatesAvailable'),
'', '',
'UPDATES_AVAILABLE', 'UPDATES_AVAILABLE',
tr('updatesAvailable'), tr('updatesAvailableNotifChannel'),
tr('updatesAvailableNotifDescription'), tr('updatesAvailableNotifDescription'),
Importance.max) { Importance.max) {
message = updates.isEmpty message = updates.isEmpty
@ -42,8 +42,14 @@ class UpdateNotification extends ObtainiumNotification {
class SilentUpdateNotification extends ObtainiumNotification { class SilentUpdateNotification extends ObtainiumNotification {
SilentUpdateNotification(List<App> updates, {int? id}) SilentUpdateNotification(List<App> updates, {int? id})
: super(id ?? 3, tr('appsUpdated'), '', 'APPS_UPDATED', tr('appsUpdated'), : super(
tr('appsUpdatedNotifDescription'), Importance.defaultImportance) { id ?? 3,
tr('appsUpdated'),
'',
'APPS_UPDATED',
tr('appsUpdatedNotifChannel'),
tr('appsUpdatedNotifDescription'),
Importance.defaultImportance) {
message = updates.length == 1 message = updates.length == 1
? tr('xWasUpdatedToY', ? tr('xWasUpdatedToY',
args: [updates[0].finalName, updates[0].latestVersion]) args: [updates[0].finalName, updates[0].latestVersion])
@ -59,7 +65,7 @@ class SilentUpdateAttemptNotification extends ObtainiumNotification {
tr('appsPossiblyUpdated'), tr('appsPossiblyUpdated'),
'', '',
'APPS_POSSIBLY_UPDATED', 'APPS_POSSIBLY_UPDATED',
tr('appsPossiblyUpdated'), tr('appsPossiblyUpdatedNotifChannel'),
tr('appsPossiblyUpdatedNotifDescription'), tr('appsPossiblyUpdatedNotifDescription'),
Importance.defaultImportance) { Importance.defaultImportance) {
message = updates.length == 1 message = updates.length == 1
@ -77,15 +83,21 @@ class ErrorCheckingUpdatesNotification extends ObtainiumNotification {
tr('errorCheckingUpdates'), tr('errorCheckingUpdates'),
error, error,
'BG_UPDATE_CHECK_ERROR', 'BG_UPDATE_CHECK_ERROR',
tr('errorCheckingUpdates'), tr('errorCheckingUpdatesNotifChannel'),
tr('errorCheckingUpdatesNotifDescription'), tr('errorCheckingUpdatesNotifDescription'),
Importance.high); Importance.high);
} }
class AppsRemovedNotification extends ObtainiumNotification { class AppsRemovedNotification extends ObtainiumNotification {
AppsRemovedNotification(List<List<String>> namedReasons) AppsRemovedNotification(List<List<String>> namedReasons)
: super(6, tr('appsRemoved'), '', 'APPS_REMOVED', tr('appsRemoved'), : super(
tr('appsRemovedNotifDescription'), Importance.max) { 6,
tr('appsRemoved'),
'',
'APPS_REMOVED',
tr('appsRemovedNotifChannel'),
tr('appsRemovedNotifDescription'),
Importance.max) {
message = ''; message = '';
for (var r in namedReasons) { for (var r in namedReasons) {
message += '${tr('xWasRemovedDueToErrorY', args: [r[0], r[1]])} \n'; message += '${tr('xWasRemovedDueToErrorY', args: [r[0], r[1]])} \n';
@ -101,7 +113,7 @@ class DownloadNotification extends ObtainiumNotification {
tr('downloadingX', args: [appName]), tr('downloadingX', args: [appName]),
'', '',
'APP_DOWNLOADING', 'APP_DOWNLOADING',
tr('downloadingX', args: [tr('app')]), tr('downloadingXNotifChannel', args: [tr('app')]),
tr('downloadNotifDescription'), tr('downloadNotifDescription'),
Importance.low, Importance.low,
onlyAlertOnce: true, onlyAlertOnce: true,
@ -113,7 +125,7 @@ final completeInstallationNotification = ObtainiumNotification(
tr('completeAppInstallation'), tr('completeAppInstallation'),
tr('obtainiumMustBeOpenToInstallApps'), tr('obtainiumMustBeOpenToInstallApps'),
'COMPLETE_INSTALL', 'COMPLETE_INSTALL',
tr('completeAppInstallation'), tr('completeAppInstallationNotifChannel'),
tr('completeAppInstallationNotifDescription'), tr('completeAppInstallationNotifDescription'),
Importance.max); Importance.max);
@ -124,7 +136,7 @@ class CheckingUpdatesNotification extends ObtainiumNotification {
tr('checkingForUpdates'), tr('checkingForUpdates'),
appName, appName,
'BG_UPDATE_CHECK', 'BG_UPDATE_CHECK',
tr('checkingForUpdates'), tr('checkingForUpdatesNotifChannel'),
tr('checkingForUpdatesNotifDescription'), tr('checkingForUpdatesNotifDescription'),
Importance.min); Importance.min);
} }

View File

@ -28,6 +28,7 @@ import 'package:obtainium/app_sources/steammobile.dart';
import 'package:obtainium/app_sources/telegramapp.dart'; import 'package:obtainium/app_sources/telegramapp.dart';
import 'package:obtainium/app_sources/uptodown.dart'; import 'package:obtainium/app_sources/uptodown.dart';
import 'package:obtainium/app_sources/vlc.dart'; import 'package:obtainium/app_sources/vlc.dart';
import 'package:obtainium/app_sources/whatsapp.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/mass_app_sources/githubstars.dart'; import 'package:obtainium/mass_app_sources/githubstars.dart';
@ -328,6 +329,7 @@ abstract class AppSource {
bool changeLogIfAnyIsMarkDown = true; bool changeLogIfAnyIsMarkDown = true;
bool appIdInferIsOptional = false; bool appIdInferIsOptional = false;
bool allowSubDomains = false; bool allowSubDomains = false;
bool naiveStandardVersionDetection = false;
AppSource() { AppSource() {
name = runtimeType.toString(); name = runtimeType.toString();
@ -440,6 +442,10 @@ abstract class AppSource {
[ [
GeneratedFormSwitch('exemptFromBackgroundUpdates', GeneratedFormSwitch('exemptFromBackgroundUpdates',
label: tr('exemptFromBackgroundUpdates')) label: tr('exemptFromBackgroundUpdates'))
],
[
GeneratedFormSwitch('skipUpdateNotifications',
label: tr('skipUpdateNotifications'))
] ]
]; ];
@ -556,7 +562,7 @@ class SourceProvider {
Mullvad(), Mullvad(),
Signal(), Signal(),
VLC(), VLC(),
// WhatsApp(), // As of 2023-03-20 this is unusable as the version on the webpage is months out of date WhatsApp(), // As of 2023-03-20 this is unusable as the version on the webpage is months out of date
TelegramApp(), TelegramApp(),
SteamMobile(), SteamMobile(),
NeutronCode(), NeutronCode(),

View File

@ -5,18 +5,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: android_alarm_manager_plus name: android_alarm_manager_plus
sha256: c20d91a9096596f66274bf8172321c278f9cba8091638f80205fe66d31587fa5 sha256: "82fb28c867c4b3dd7e9157728e46426b8916362f977dbba46b949210f00099f4"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.2" version: "3.0.3"
android_intent_plus: android_intent_plus:
dependency: "direct main" dependency: "direct main"
description: description:
name: android_intent_plus name: android_intent_plus
sha256: f72ae20bb37108694f442e7ae6acbd28b453ca62ce86842f6787b784355abfe6 sha256: e1c62bb41c90e15083b7fb84dc327fe90396cc9c1445b55ff1082144fabfb4d9
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.2" version: "4.0.3"
android_package_installer: android_package_installer:
dependency: "direct main" dependency: "direct main"
description: description:
@ -46,10 +46,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: archive name: archive
sha256: d4dc11707abb32ef756ab95678c0d6df54003d98277f7c9aeda14c48e7a38c2f sha256: "7e0d52067d05f2e0324268097ba723b71cb41ac8a6a2b24d1edf9c536b987b03"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.4.3" version: "3.4.6"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -118,10 +118,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: connectivity_plus name: connectivity_plus
sha256: "77a180d6938f78ca7d2382d2240eb626c0f6a735d0bfdce227d8ffb80f95c48b" sha256: "94d51c6f1299133a2baa4c5c3d2c11ec7d7fb4768dee5c52a56f7d7522fcf70e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.2" version: "5.0.0"
connectivity_plus_platform_interface: connectivity_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -142,10 +142,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: cross_file name: cross_file
sha256: fd832b5384d0d6da4f6df60b854d33accaaeb63aa9e10e736a87381f08dee2cb sha256: "445db18de832dba8d851e287aff8ccf169bed30d2e94243cb54c7d2f1ed2142c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.3.3+5" version: "0.3.3+6"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
@ -238,10 +238,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: file name: file
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.4" version: "7.0.0"
file_picker: file_picker:
dependency: "direct main" dependency: "direct main"
description: description:
@ -291,10 +291,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_local_notifications name: flutter_local_notifications
sha256: "3002092e5b8ce2f86c3361422e52e6db6776c23ee21e0b2f71b892bf4259ef04" sha256: "6d11ea777496061e583623aaf31923f93a9409ef8fcaeeefdd6cd78bf4fe5bb3"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "15.1.1" version: "16.1.0"
flutter_local_notifications_linux: flutter_local_notifications_linux:
dependency: transitive dependency: transitive
description: description:
@ -320,10 +320,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_markdown name: flutter_markdown
sha256: a10979814c5f4ddbe2b6143fba25d927599e21e3ba65b3862995960606fae78f sha256: "8afc9a6aa6d8e8063523192ba837149dbf3d377a37c0b0fc579149a1fbd4a619"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.17+3" version: "0.6.18"
flutter_plugin_android_lifecycle: flutter_plugin_android_lifecycle:
dependency: transitive dependency: transitive
description: description:
@ -538,10 +538,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: permission_handler name: permission_handler
sha256: ad65ba9af42a3d067203641de3fd9f547ded1410bad3b84400c2b4899faede70 sha256: "284a66179cabdf942f838543e10413246f06424d960c92ba95c84439154fcac8"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "11.0.0" version: "11.0.1"
permission_handler_android: permission_handler_android:
dependency: transitive dependency: transitive
description: description:
@ -562,10 +562,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: permission_handler_platform_interface name: permission_handler_platform_interface
sha256: f2343e9fa9c22ae4fd92d4732755bfe452214e7189afcc097380950cf567b4b2 sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.11.5" version: "3.12.0"
permission_handler_windows: permission_handler_windows:
dependency: transitive dependency: transitive
description: description:
@ -586,10 +586,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: platform name: platform
sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.2" version: "3.1.3"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -634,10 +634,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: shared_preferences name: shared_preferences
sha256: b7f41bad7e521d205998772545de63ff4e6c97714775902c199353f8bf1511ac sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.1" version: "2.2.2"
shared_preferences_android: shared_preferences_android:
dependency: transitive dependency: transitive
description: description:
@ -658,10 +658,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_linux name: shared_preferences_linux
sha256: c2eb5bf57a2fe9ad6988121609e47d3e07bb3bdca5b6f8444e4cf302428a128a sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.1" version: "2.3.2"
shared_preferences_platform_interface: shared_preferences_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -682,10 +682,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_windows name: shared_preferences_windows
sha256: f763a101313bd3be87edffe0560037500967de9c394a714cd598d945517f694f sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.1" version: "2.3.2"
shared_storage: shared_storage:
dependency: "direct main" dependency: "direct main"
description: description:
@ -879,18 +879,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: webview_flutter name: webview_flutter
sha256: "82f6787d5df55907aa01e49bd9644f4ed1cc82af7a8257dd9947815959d2e755" sha256: c1ab9b81090705c6069197d9fdc1625e587b52b8d70cdde2339d177ad0dbb98e
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.2.4" version: "4.4.1"
webview_flutter_android: webview_flutter_android:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_android name: webview_flutter_android
sha256: ddc167c6676f57c8b367d19fcbee267d6dc6adf81bd6c3cb87981d30746e0a6d sha256: b0cd33dd7d3dd8e5f664e11a19e17ba12c352647269921a3b568406b001f1dff
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.10.1" version: "3.12.0"
webview_flutter_platform_interface: webview_flutter_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -903,10 +903,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_wkwebview name: webview_flutter_wkwebview
sha256: "485af05f2c5f83c7f78c20e236b170ad02df7153b299ae9917345be43871d29f" sha256: "30b9af6bdd457b44c08748b9190d23208b5165357cc2eb57914fee1366c42974"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.8.0" version: "3.9.1"
win32: win32:
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.14.21+213 # When changing this, update the tag in main() accordingly version: 0.14.27+219 # 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'
@ -38,7 +38,7 @@ dependencies:
cupertino_icons: ^1.0.5 cupertino_icons: ^1.0.5
path_provider: ^2.0.11 path_provider: ^2.0.11
flutter_fgbg: ^0.3.0 # Try removing reliance on this flutter_fgbg: ^0.3.0 # Try removing reliance on this
flutter_local_notifications: ^15.1.0+1 flutter_local_notifications: ^16.1.0
provider: ^6.0.3 provider: ^6.0.3
http: ^1.0.0 http: ^1.0.0
webview_flutter: ^4.0.0 webview_flutter: ^4.0.0
@ -64,7 +64,7 @@ dependencies:
flutter_markdown: ^0.6.14 flutter_markdown: ^0.6.14
flutter_archive: ^5.0.0 flutter_archive: ^5.0.0
hsluv: ^1.1.3 hsluv: ^1.1.3
connectivity_plus: ^4.0.2 connectivity_plus: ^5.0.0
shared_storage: ^0.8.0 shared_storage: ^0.8.0
dev_dependencies: dev_dependencies: