Compare commits

...

181 Commits

Author SHA1 Message Date
Imran
7da631e429 Merge pull request #2094 from ImranR98/dev
- Attempt to fix "double download" bug (#2073)
- Avoid JSON corruption when storage full (#2089)
- Fix error when GitLab repo is in a subgroup (#2079)
- Update screenshots in README
2025-01-27 21:13:54 -05:00
Imran Remtulla
66c08f0bfd Updated screenshots 2025-01-27 21:12:35 -05:00
Imran Remtulla
79a2484d68 Don't show debug banner in development 2025-01-27 20:29:34 -05:00
Imran Remtulla
c3c7c844dc Update Flutter submodule 2025-01-27 20:21:44 -05:00
Imran Remtulla
075d0a0854 Enable Korean, update Flutter + packages, increment version 2025-01-27 20:20:37 -05:00
Imran Remtulla
cc0416e344 Merge remote-tracking branch 'origin/main' into dev 2025-01-27 20:16:04 -05:00
Imran
af7088b754 Merge pull request #2090 from ColorfulRhino/patch-2
Fix and improve German translation
2025-01-27 20:14:53 -05:00
Imran Remtulla
ba21137da7 Fix error when GitLab repo is in a subgroup (#2079) 2025-01-27 20:14:11 -05:00
Imran Remtulla
a7a5749d4f Avoid JSON corruption when storage full (#2089) 2025-01-27 19:55:12 -05:00
Imran Remtulla
fcf3c8b635 Attempt to fix "double download" bug (#2073) 2025-01-27 19:51:02 -05:00
Imran
69f578652c Merge pull request #2080 from tkgo11/main
Added Korean translation.
2025-01-26 23:46:47 -05:00
ColorfulRhino
7593af25b9 Improve German translation
- Increase consistency for certain terms
- Address concerns for the translation of _author_ containing a colon by using a different wording
- Minor improvements
2025-01-26 13:32:35 +00:00
ColorfulRhino
1e8fd33469 Restore two lines in de.json accidentally removed during merge conflict
Two lines were accidentally reverted in #2057 due to a merge conflict.
2025-01-26 13:13:41 +00:00
tkgo11
3f948ae73c Create ko.json 2025-01-20 13:53:32 +09:00
Imran
de2e881e82 Merge pull request #2075 from ImranR98/dev
- Fix categories UI bug (#2064)
- Fix how changelog quotes look in dark theme (#2065)
2025-01-14 17:38:54 +03:00
Imran Remtulla
9af3aaa82a Increment version 2025-01-14 17:37:46 +03:00
Imran Remtulla
3a5157ced0 Fix how changelog quotes look in dark theme (#2065) 2025-01-14 17:36:14 +03:00
Imran Remtulla
e16320f995 Fix categories UI bug (#2064) 2025-01-14 17:23:49 +03:00
Imran Remtulla
aac01885f1 Update Flutter version 2025-01-14 16:54:35 +03:00
Imran
7d330cd074 Merge pull request #2062 from ImranR98/dev
Update Flutter submodule
2025-01-11 22:19:15 +02:00
Imran Remtulla
8b0e2aaef1 Update Flutter submodule 2025-01-11 23:18:27 +03:00
Imran
5db53d9c71 Merge pull request #2044 from ArcticFoxPro/main
feat(i18n): Add Tencent App Store zh-Hans translations and add zh-Hans version of Obtainium badge
2025-01-11 22:03:44 +02:00
Imran
ff5bba933b Merge branch 'main' into main 2025-01-11 22:03:36 +02:00
Imran
2b48ee81b7 Merge pull request #2048 from mxhdee/main
Update fa.json
2025-01-11 22:02:10 +02:00
Imran
fe6d0040c4 Merge pull request #2050 from Kevinr99089/main
Update fr.json
2025-01-11 22:01:59 +02:00
Imran
17d32cd1c6 Merge pull request #2057 from DwainZwerg/patch-2
Update de.json
2025-01-11 22:01:50 +02:00
Imran
c6a62fe15a Merge branch 'main' into patch-2 2025-01-11 22:01:41 +02:00
Imran
2b22de585e Merge pull request #2059 from ColorfulRhino/patch-1
Improve German translation
2025-01-11 22:00:53 +02:00
Imran
346c670488 Merge pull request #2061 from ImranR98/dev
- Upgrade to latest Flutter version (fix errors that were preventing this)
- Fix button highlight visibility on black theme (#2039)
2025-01-11 22:00:30 +02:00
Imran Remtulla
2137335e56 Increment version 2025-01-11 22:59:29 +03:00
Imran Remtulla
cea96275b7 Fix button highlight visibility on black theme (#2039) 2025-01-11 22:54:47 +03:00
Imran Remtulla
9954b68332 Upgrade to latest Flutter version (fix Gradle and other errors) 2025-01-11 22:35:40 +03:00
ColorfulRhino
974a822b29 Improve German translation 2025-01-10 12:32:56 +00:00
DwainZwerg
48b89335fa Update de.json
Hopefully more understandable
2025-01-09 10:31:06 +01:00
Kévin
e834630688 Update fr.json
- Correction of some translations (French)
- Line: 94, 97
2025-01-01 03:42:04 +01:00
Kévin
3dd1ef076f Update fr.json
- Correction of some translations (French)
- Line: 28, 32, 63, 81, 102, 316
2025-01-01 03:29:31 +01:00
Mxhdee
e70edae831 Update fa.json 2024-12-29 02:31:39 +01:00
有鲫雪狐
d9b2d18d85 feat: Add Simplified Chinese version of Obtainium badge
- Add an image of the Obtainium badge in Simplified Chinese
- File path: assets/graphics/badge_obtainium_i18n/badge_obtainium_zh-Hans.png
- Font used from Noto Sans CJK
2024-12-22 16:03:52 +08:00
有鲫雪狐
96b260e431 feat(i18n): Add Tencent App Store zh-Hans translations
- Add zh-Hans translations for Tencent App Store(腾讯应用宝) in the multilingual files
- Update the display name for Tencent App Store to use localized translations
2024-12-21 17:46:46 +08:00
Imran
18ccd01186 Merge pull request #2043 from ImranR98/dev
APKPure bugfix, Restore "Telegram App" source (#2025)
2024-12-20 19:13:02 +03:00
Imran Remtulla
c84f51b6ce Update packages, increment version 2024-12-20 19:11:34 +03:00
Imran Remtulla
48958748f6 Minor bugfix 2024-12-20 19:08:41 +03:00
Imran Remtulla
966b1ee6e3 Revert "Removed Telegram App"
This reverts commit 29bb5cc8cd.
2024-12-20 19:00:26 +03:00
Imran Remtulla
7432ee867f APKPure bugfix 2024-12-20 18:58:31 +03:00
Imran
3ebbd2a4a5 Merge pull request #2033 from ImranR98/dev
Bugfix: GitHub fallback option was broken (#2032)
2024-12-12 11:05:30 -05:00
Imran Remtulla
82207a1b3b Increment version 2024-12-12 11:04:46 -05:00
Imran Remtulla
2ec5c7db11 Bugfix: GitHub fallback option was broken (#2032) 2024-12-12 11:04:31 -05:00
Imran
ab949af700 Merge pull request #2031 from ImranR98/dev
Hardcode Flutter version in GitHub action for now (until new Flutter works)
2024-12-12 04:02:41 -05:00
Imran Remtulla
5c9a35c4f0 Hardcode Flutter version in GitHub action for now (until new Flutter works) 2024-12-12 04:01:59 -05:00
Imran
8651f58744 Merge pull request #2030 from ImranR98/dev
- Avoid OS version reconciliation for pseudo-versioned apps (#2023)
- When importing configs via link, don't show dialog twice
- GitHub - do not use filtered asset release dates (#2012)
2024-12-12 03:53:27 -05:00
Imran Remtulla
d93798a8df Increment version 2024-12-12 03:52:10 -05:00
Imran Remtulla
0822f991ff Remove unused function 2024-12-12 03:34:47 -05:00
Imran Remtulla
fde63a0f05 GitHub - do not use filtered asset release dates (#2012) 2024-12-12 03:27:17 -05:00
Imran Remtulla
523e1151b2 When importing configs via link, don't show dialog twice 2024-12-12 02:58:01 -05:00
Imran Remtulla
d5d6825ed9 Avoid OS version reconciliation for pseudo-versioned apps (#2023) 2024-12-12 02:40:04 -05:00
Imran
79c4d3b9fe Merge pull request #2026 from summoner001/main
Update hu.json
2024-12-12 02:21:19 -05:00
Imran Remtulla
d6b99b903f Prevent pseudo-versioning method from changing on load (#2022) 2024-12-12 02:20:56 -05:00
summoner001
335752ee7c Update hu.json
Correcting hungarian translation
2024-12-10 15:55:12 +01:00
Imran
e5afe75213 Merge pull request #2021 from ImranR98/dev
Catch errors when running JSON compat mods - app breaking bug (#2015, #2019)
2024-12-09 17:21:40 -05:00
Imran Remtulla
0df1c1c512 Increment version 2024-12-09 17:21:00 -05:00
Imran Remtulla
bd2ac73b9f Catch errors when running JSON compat mods (#2015, #2019) 2024-12-09 17:18:25 -05:00
Imran Remtulla
26b5a2d976 Catch errors when running JSON compat mods (#2015, #2019) 2024-12-09 17:04:49 -05:00
Imran
c0968e8991 Merge pull request #2008 from ImranR98/dev
- Fix broken "Download Asset" function for HTML source (#1998)
- Add "refresh before download" (#1943)
- Remove WhatsApp, VLC, and Telegram App sources - no longer needed as HTML source sufficient (#1943)
2024-12-08 16:41:24 -05:00
Imran Remtulla
243b1eb2ac Update packages, increment version 2024-12-08 16:39:26 -05:00
Imran Remtulla
c6c61d1c83 Merge remote-tracking branch 'origin/main' into dev 2024-12-08 16:37:08 -05:00
Imran
f207967411 Merge pull request #1995 from ygxbnet/patch-2
Update zh.json
2024-12-08 16:36:56 -05:00
Imran Remtulla
29bb5cc8cd Removed Telegram App 2024-12-08 16:36:46 -05:00
Imran Remtulla
dbbc2ff19c Removed VLC (#1943) 2024-12-08 16:21:36 -05:00
Imran Remtulla
c012b016f9 Add "refresh before download" + remove WhatsApp (#1943) 2024-12-08 15:58:44 -05:00
Imran Remtulla
22815b8209 Minor bug 2024-12-08 14:53:31 -05:00
Imran Remtulla
619d4f1a51 Fix broken "Download Asset" function for HTML source (#1998) 2024-12-08 13:47:32 -05:00
YGXB_net
50e8929763 Update zh.json 2024-11-30 21:49:58 +08:00
Imran
0e2a0b65ec Merge pull request #1990 from ImranR98/dev
- Improved XAPK Support (#682)
- Custom user-agent for APKMirror (as per feedback in #1973)
- Minor change to German translation (#1986)
2024-11-23 16:31:46 -05:00
Imran Remtulla
5b79f399d1 Minor change to German translation (#1986) 2024-11-23 16:29:10 -05:00
Imran Remtulla
2961d5ac17 Merge remote-tracking branch 'origin/main' into dev 2024-11-23 16:27:21 -05:00
Imran Remtulla
4af4160aaa Increment version 2024-11-23 16:27:11 -05:00
Imran Remtulla
327f73cc9e More changes for XAPK support (#682) 2024-11-23 16:26:11 -05:00
Imran Remtulla
e82170fec6 Improved XAPK Support (#682) 2024-11-23 16:05:02 -05:00
Imran Remtulla
8922b1c048 Custom user-agent for APKMirror (as per feedback in #1973) 2024-11-23 15:26:58 -05:00
Imran
e9550c6ff0 Merge pull request #1980 from Hamster45105/wiki-links
Update wiki links
2024-11-23 01:53:07 -05:00
Hamish
890c3682c4 Update wiki links 2024-11-23 17:17:04 +11:00
Imran
a2c38968e1 Merge pull request #1977 from summoner001/main
Update hu.json
2024-11-15 13:14:29 -05:00
summoner001
a9c3ee4c54 Update hu.json
Correcting translation.
2024-11-15 14:34:01 +01:00
Imran Remtulla
36db226024 README updates
Signed-off-by: Imran Remtulla <contact@imranr.dev>
2024-11-14 21:42:25 -05:00
Imran
6fbdf62afa Merge pull request #1975 from ImranR98/dev
Bugfixes for the "download release assets" button (#1968)
2024-11-14 21:34:36 -05:00
Imran Remtulla
9344ebbb06 Upgrade Flutter + packages, increment version 2024-11-14 21:31:47 -05:00
Imran Remtulla
51b66ab983 Merge remote-tracking branch 'origin/main' into dev 2024-11-14 21:31:17 -05:00
Imran Remtulla
7f2a9b6fa5 Bugfix for "download release assets" (#1968) 2024-11-14 21:21:32 -05:00
Imran Remtulla
ac6bc4d786 Bugfix in "download release assets" button (#1968) 2024-11-14 20:50:06 -05:00
Imran
acd30b516c Merge pull request #1972 from DwainZwerg/patch-1
Update README.md
2024-11-14 20:23:41 -05:00
Imran
5bc9234101 Merge pull request #1965 from bluefly000/japanese-translation
Update ja.json
2024-11-14 20:23:28 -05:00
Imran
80d15f5232 Merge pull request #1964 from summoner001/main
update hu.json
2024-11-14 20:23:15 -05:00
DwainZwerg
eb7c2a9fc4 Update README.md 2024-11-14 15:04:14 +01:00
DwainZwerg
40175468b2 Update README.md
Add list of all repositories
2024-11-14 15:01:48 +01:00
bluefly000
814b5a71bd Update ja.json 2024-11-11 14:47:17 +09:00
bluefly000
38a1e43116 Update ja.json 2024-11-11 14:27:20 +09:00
summoner001
5064b78c79 update hu.json 2024-11-10 18:42:08 +01:00
summoner001
767350e4e3 update hu.json 2024-11-10 18:39:41 +01:00
Imran
4caae51904 Merge pull request #1962 from ImranR98/dev
- Uptodown - fix broken web scraping logic (#1956)
- Add signature info to README (#1957)
2024-11-10 02:49:22 -05:00
Imran Remtulla
83616b7a79 Upgrade packages, increment version 2024-11-10 02:46:25 -05:00
Imran Remtulla
52b2d0868c Add signature info to README (#1957) 2024-11-10 02:42:26 -05:00
Imran Remtulla
94f629859e Merge remote-tracking branch 'origin/main' into dev 2024-11-10 02:27:37 -05:00
Imran Remtulla
773d3455ae Uptodown - fix broken web scraping logic (#1956) 2024-11-10 02:27:00 -05:00
Imran
919ab16528 Merge pull request #1948 from CertainBot/main
Update es.json
2024-11-09 14:55:53 -05:00
Imran
268b89eaf6 Merge pull request #1945 from Kevinr99089/main
Correction of long translations (French)
2024-11-09 14:55:43 -05:00
CertainBot
9c9a264e39 Update es.json
- Minor changes

- Cambios menores
2024-11-03 13:06:48 +00:00
Kévin
e1e612455a Correction of long translations (French)
- The previous correction was still too long, so I corrected it again.
- Line 317: "Configuration d'applis communautaire" changed by "Appli communautaires"
- translation suggested by @peternmuller
2024-11-02 23:26:29 +01:00
Imran
e191d75300 Merge pull request #1942 from ImranR98/dev
Correct issue w/ Signal migration
2024-11-01 14:34:41 -04:00
Imran Remtulla
fce2a2f15c Correct issue w/ Signal migration 2024-11-01 14:34:19 -04:00
Imran
dd8acd9451 Merge pull request #1941 from ImranR98/dev
Fix PathAccessException on secondary profiles (#1754), Log installs (#1924), APKPure URL parsing bugfix (#1926), Remove Signal source (HTML is enough) (#1928), F-Droid URL parsing bugfix (#1933), HTML link extraction bugfix (#1937)
2024-11-01 14:24:33 -04:00
Imran Remtulla
2d5676f13d Increment version 2024-11-01 14:24:18 -04:00
Imran Remtulla
dfbf9e925c Log installs (#1924) 2024-11-01 14:19:55 -04:00
Imran Remtulla
e44f77a68a Remove unused classes and translations (related to Steam Mobile and Signal) 2024-11-01 14:12:55 -04:00
Imran Remtulla
cc373c8d7f Remove Signal source (HTML is enough) (#1928) 2024-11-01 14:09:38 -04:00
Imran Remtulla
2ad88bf3ca Fix PathAccessException on secondary profiles (#1754) 2024-11-01 13:28:10 -04:00
Imran Remtulla
b1f9375bb1 APKPure URL parsing bugfix (#1926) 2024-11-01 13:17:19 -04:00
Imran Remtulla
0e14e17236 F-Droid URL parsing bugfix (#1933) 2024-11-01 13:07:45 -04:00
Imran Remtulla
fc541837ef HTML link extraction bugfix (#1937) 2024-11-01 12:52:32 -04:00
Imran
da0b1d0684 Merge pull request #1938 from catsnote/main
Updated a few strings - assets/translations/da.json
2024-11-01 11:27:11 -04:00
Imran
3fd89e8567 Merge pull request #1940 from ImranR98/dev
Translation fix, Flutter/package updates, GitHub action security improvement
2024-11-01 11:26:53 -04:00
Imran Remtulla
8cab348eed Build online but do not sign 2024-11-01 11:24:51 -04:00
Imran Remtulla
6bd821985f Merge remote-tracking branch 'origin/main' into dev 2024-11-01 11:18:47 -04:00
Imran
1f2efe435f Testing GitHub action changes 2024-11-01 10:41:11 -04:00
Imran Remtulla
8276a809a5 Update packages, Flutter 2024-10-31 19:50:04 -04:00
cat
5fe1a8a370 update assets/translations/da.json 2024-10-31 02:27:27 +01:00
Imran Remtulla
58710093ba Add an exception to the translations/standardize.js 2024-10-25 18:02:53 -04:00
Imran Remtulla
ac6f8c456d Sort pl.json entries 2024-10-25 17:59:26 -04:00
Imran Remtulla
905461c242 Update a field label 2024-10-25 17:54:34 -04:00
Imran
e3fcf6e0b5 Merge pull request #1915 from InfiniteCoder06/main
Add Custom app ID
2024-10-25 17:52:10 -04:00
Imran
903fad5158 Merge pull request #1929 from Daviteusz/translate
Update Polish translation
2024-10-25 17:44:48 -04:00
Imran
1de93e827a Merge pull request #1918 from Kevinr99089/main
Correction of last French modifications (too long)
2024-10-25 17:36:04 -04:00
Daviteusz
a5040aa0c1 Update Polish translation 2024-10-24 12:33:10 +02:00
Praveen Kumar
9f7c4e23d5 Change behaviour of Custom App ID 2024-10-21 21:52:40 +05:30
Kévin
876f67aacb Correction of last French modifications (too long) 2024-10-20 23:32:39 +02:00
Imran
2ed2c2c5f9 Merge pull request #1917 from summoner001/main
Update hungarian translation - hu.json
2024-10-20 14:22:10 -04:00
summoner001
7f35589d49 Fix auto translated strings. 2024-10-20 19:28:13 +02:00
Praveen Kumar
9d5ce75e27 Fixed a Bug, Added Validation 2024-10-20 22:47:13 +05:30
Imran
09f1f27fa8 Merge pull request #1916 from ImranR98/dev
- APKPure: Fix issue with characters in URLs (#1912)
- APKPure: Fix bug with versionCode not found
- Optional "when charging only" toggle for BG updates (#1914)
2024-10-20 12:53:52 -04:00
Imran Remtulla
ea239ffa3a Optional "when charging only" toggle for BG updates (#1914) 2024-10-20 12:51:07 -04:00
Imran Remtulla
07ef86ae75 Update packages, increment version 2024-10-20 12:35:29 -04:00
Imran Remtulla
c670fce652 Merge remote-tracking branch 'origin/main' into dev 2024-10-20 12:29:48 -04:00
Imran
ba8ef7e5b0 Merge pull request #1906 from mintsoft/debug-build
Allow installation of the debug build
2024-10-20 12:29:37 -04:00
Imran
0ec3fb0064 Merge pull request #1907 from Kevinr99089/main
Correction of French translations
2024-10-20 12:29:20 -04:00
Praveen Kumar
c1c06b3f9c Make appId Assignable only once 2024-10-20 21:46:13 +05:30
Imran Remtulla
d121463bad APKPure: Fix bug with versionCode not found 2024-10-20 12:10:11 -04:00
Imran Remtulla
862e85f882 APKPure: Fix issue with characters in URLs (#1912) 2024-10-20 12:02:44 -04:00
Praveen Kumar
5e0333c4c8 Add Custom app ID 2024-10-20 19:56:19 +05:30
Kévin
efb75afb9b French Translation correction for "Community App Sources".
- Corrected to "Configurations d'applications par la communauté (à utiliser à vos risques et périls)" line 317, and "Configurations d'applications par la communauté" line 318
2024-10-16 22:46:33 +02:00
Kévin
b4510e10a7 Merge branch 'ImranR98:main' into main 2024-10-16 22:32:15 +02:00
Rob Emery
25233f3259 App is now called debug so its easier to spot 2024-10-16 01:30:18 +01:00
Rob Emery
cff6b86997 App debug builds can now be installed side-by-side with non-debug 2024-10-16 01:22:57 +01:00
Imran
344a6efbf6 Merge pull request #1905 from ImranR98/dev
Add some logs to troubleshoot #1550
2024-10-15 16:02:01 -04:00
Imran Remtulla
59a4b88a88 Update packages, increment version 2024-10-15 16:01:53 -04:00
Imran Remtulla
cf7c41bf4c Merge remote-tracking branch 'origin/main' into dev 2024-10-15 16:00:34 -04:00
Imran
d32543b5d0 Merge pull request #1902 from summoner001/main
Update hu.json
2024-10-15 16:00:10 -04:00
Imran Remtulla
892a3b3c30 Add some logs to troubleshoot #1550 2024-10-15 15:56:19 -04:00
summoner001
56c791d3e5 Update hu.json
Fixing coherence
2024-10-14 15:45:41 +02:00
Kévin
e4103c8352 Merge branch 'ImranR98:main' into main 2024-10-13 03:14:07 +02:00
Imran
672bc159cc Merge pull request #1894 from summoner001/main
Update hu.json
2024-10-12 13:36:07 -04:00
Imran
ee5d121bf0 Merge pull request #1889 from strugee/patch-1
Fix typo
2024-10-12 13:35:54 -04:00
Imran
e5d1fafc13 Merge pull request #1882 from Erengun/develop
Add "Community App Sources" translation and button to Add App Screen
2024-10-12 13:35:38 -04:00
summoner001
8bb4f46209 Update hu.json
More fixes
2024-10-09 15:21:10 +02:00
summoner001
504e1d551b Update hu.json
Fix translation
2024-10-09 15:07:03 +02:00
AJ Jordan
5e7e143bba Fix typo 2024-10-06 18:52:16 -04:00
Eren GUN
91a82af418 Refactor translations to use shorter label for crowdsourced app configurations 2024-10-03 12:13:24 +03:00
Eren GUN
7af2145e9a Refactor translations to use shorter label for crowdsourced app configurations 2024-10-03 11:00:00 +03:00
Eren GUN
74b9de3516 Replace the "Community App Sources" button with a text link in the AddAppPage for a cleaner UI.
improving interface consistency.
2024-10-03 10:59:44 +03:00
Eren GUN
f5b540dd8b Add "Community App Sources" button to AddAppPage 2024-10-02 19:19:23 +03:00
Eren GUN
01d701d8cd Add "Community App Sources" translation 2024-10-02 19:16:42 +03:00
Imran
4017253470 Merge pull request #1878 from ImranR98/dev
Add "title as version" option for GitHub (#1875)
2024-10-01 20:05:16 -04:00
Imran Remtulla
b0b6ddb8fd Merge remote-tracking branch 'origin/main' into dev 2024-10-01 20:04:30 -04:00
Imran Remtulla
192b7fc6ce Add "title as version" option for GitHub (#1875) 2024-10-01 20:04:10 -04:00
Imran
b74dbb973c Merge pull request #1870 from robifr/main
Fix indonesian translation
2024-10-01 19:23:26 -04:00
Imran
46ccf8478b Merge pull request #1874 from ImranR98/dev
- App-wide "pretend to be GPlay" option (#1859)
- UI bugfixes on add app page (#1866)
- UI tweaks (#1871, #1872)
- Added "skip latest" option to APKPure (also fallback toggle)
2024-10-01 16:20:55 -05:00
Imran Remtulla
9a354ecf0e Increment version, upgrade package 2024-10-01 17:12:10 -04:00
Imran Remtulla
738dd5649f App-wide "pretend to be GPlay" option (#1859) 2024-10-01 17:07:11 -04:00
Imran Remtulla
9f50d8db2d UI bugfixes on add app page (#1866) 2024-10-01 16:59:28 -04:00
Imran Remtulla
eeb57dbe35 UI tweaks (#1871, #1872) 2024-10-01 15:57:18 -04:00
Imran Remtulla
cbcc8c4eaf Added "skip latest" option to APKPure (also fallback toggle) 2024-10-01 15:49:00 -04:00
robi
f4d27c8494 Fix indonesian translation
Co-authored-by: Kuching Neko <kuchingneko28@gmail.com>
2024-10-02 01:10:31 +07:00
Kévin
87c66b4d09 Modification of 2 translations (fr.json)
- Suggested by [peternmuller](https://github.com/peternmuller)
2024-09-08 22:20:52 +02:00
76 changed files with 1727 additions and 1022 deletions

View File

@@ -6,9 +6,6 @@ on:
beta:
type: boolean
description: Is beta?
draft:
type: boolean
description: Is draft?
jobs:
build:
@@ -18,6 +15,8 @@ jobs:
- uses: actions/checkout@v3
- uses: subosito/flutter-action@v2
with:
channel: stable
- uses: actions/setup-java@v4
with:
distribution: 'temurin' # See 'Supported distributions' for available options
@@ -27,13 +26,6 @@ jobs:
id: flutter_doctor
run: |
flutter doctor -v
- 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: Check submodule
id: check_submodule
@@ -57,24 +49,13 @@ jobs:
for file in build/app/outputs/flutter-apk/app-*normal*.apk*; do mv "$file" "${file//-normal/}"; done
flutter build apk --flavor fdroid -t lib/main_fdroid.dart && flutter build apk --split-per-abi --flavor fdroid -t lib/main_fdroid.dart
rm ./build/app/outputs/flutter-apk/*.sha1
cp ./sign.sh ./build/app/outputs/flutter-apk/
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/$(ls ${ANDROID_HOME}/build-tools/ | tail -1)/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: Save Unsigned APKs as Action Artifacts
uses: actions/upload-artifact@v4
with:
path: build/app/outputs/flutter-apk/*
- name: Create Tag
uses: mathieudutour/github-tag-action@v6.1
@@ -83,12 +64,11 @@ jobs:
custom_tag: "${{ steps.extract_version.outputs.tag }}"
tag_prefix: ""
- name: Create Release And Upload APKs
- name: Create Draft Release
uses: ncipollo/release-action@v1
with:
token: ${{ secrets.GH_ACCESS_TOKEN }}
tag: "${{ steps.extract_version.outputs.tag }}"
prerelease: "${{ steps.extract_version.outputs.beta }}"
draft: "${{ inputs.draft }}"
artifacts: ./build/app/outputs/flutter-apk/*-release*.apk*
draft: "true"
generateReleaseNotes: true

2
.gitignore vendored
View File

@@ -5,9 +5,11 @@
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
.vscode/

View File

@@ -1,11 +1,11 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled.
# This file should be version controlled and should not be manually edited.
version:
revision: 543dac2f35de563fcb6905e9146bdce712c44000
channel: master
revision: "17025dd88227cd9532c33fa78f5250d548d87e9a"
channel: "stable"
project_type: app
@@ -13,14 +13,26 @@ project_type: app
migration:
platforms:
- platform: root
create_revision: 543dac2f35de563fcb6905e9146bdce712c44000
base_revision: 543dac2f35de563fcb6905e9146bdce712c44000
create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
- platform: android
create_revision: 543dac2f35de563fcb6905e9146bdce712c44000
base_revision: 543dac2f35de563fcb6905e9146bdce712c44000
create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
- platform: ios
create_revision: 543dac2f35de563fcb6905e9146bdce712c44000
base_revision: 543dac2f35de563fcb6905e9146bdce712c44000
create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
- platform: linux
create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
- platform: macos
create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
- platform: web
create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
- platform: windows
create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
# User provided section

View File

@@ -7,10 +7,12 @@ Get Android app updates straight from the source.
Obtainium allows you to install and update apps directly from their releases pages, and receive notifications when new releases are made available.
More info:
- [Obtainium/wiki](https://github.com/ImranR98/Obtainium/wiki)
- [Obtainium Wiki](https://wiki.obtainium.imranr.dev/) ([repository](https://github.com/ImranR98/Obtainium-Wiki))
- [AppVerifier](https://github.com/soupslurpr/AppVerifier) - App verification tool (recommended, integrates with Obtainium)
- [apps.obtainium.imranr.dev](https://apps.obtainium.imranr.dev/) - Crowdsourced app configurations
- [apps.obtainium.imranr.dev](https://apps.obtainium.imranr.dev/) - Crowdsourced app configurations ([repository](https://github.com/ImranR98/apps.obtainium.imranr.dev))
- [Side Of Burritos - You should use this instead of F-Droid | How to use app RSS feed](https://youtu.be/FFz57zNR_M0) - Original motivation for this app
- [Website](https://obtainium.imranr.dev) ([repository](https://github.com/ImranR98/obtainium.imranr.dev))
- [Source code](https://github.com/ImranR98/Obtainium)
Currently supported App sources:
- Open Source - General:
@@ -29,11 +31,7 @@ Currently supported App sources:
- [Tencent App Store](https://sj.qq.com/)
- Jenkins Jobs
- [APKMirror](https://apkmirror.com/) (Track-Only)
- Open Source - App-Specific:
- [Signal](https://signal.org/)
- [VLC](https://videolan.org/)
- Other - App-Specific:
- [WhatsApp](https://whatsapp.com)
- [Telegram App](https://telegram.org)
- [Neutron Code](https://neutroncode.com)
- Direct APK Link
@@ -59,7 +57,11 @@ Or, contribute some configurations to the website by creating a PR at [this repo
alt="Get it on F-Droid"
height="80">](https://f-droid.org/packages/dev.imranr.obtainium.fdroid/)
[PGP Public Key](https://keyserver.ubuntu.com/pks/lookup?search=contact%40imranr.dev&fingerprint=on&op=index)
Verification info:
- Package ID: `dev.imranr.obtainium`
- SHA-256 Hash of Signing Certificate: `B3:53:60:1F:6A:1D:5F:D6:60:3A:E2:F5:0B:E8:0C:F3:01:36:7B:86:B6:AB:8B:1F:66:24:3D:A9:6C:D5:73:62`
- Note: The above signature is also valid for the F-Droid flavour of Obtainium, thanks to [reproducible builds](https://f-droid.org/docs/Reproducible_Builds/).
- [PGP Public Key](https://keyserver.ubuntu.com/pks/lookup?search=contact%40imranr.dev&fingerprint=on&op=index) (to verify APK hashes)
## Limitations
- For some sources, data is gathered using Web scraping and can easily break due to changes in website design. In such cases, more reliable methods may be unavailable.

View File

@@ -13,8 +13,7 @@ linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code

2
android/.gitignore vendored
View File

@@ -7,7 +7,7 @@ gradle-wrapper.jar
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
# See https://flutter.dev/to/reference-keystore
key.properties
**/*.keystore
**/*.jks

View File

@@ -1,6 +1,7 @@
plugins {
id "com.android.application"
id "kotlin-android"
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin"
}
@@ -29,33 +30,30 @@ if (keystorePropertiesFile.exists()) {
}
android {
namespace "dev.imranr.obtainium"
compileSdk flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
namespace = "dev.imranr.obtainium"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
jvmTarget = JavaVersion.VERSION_1_8
}
defaultConfig {
applicationId "dev.imranr.obtainium"
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "dev.imranr.obtainium"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
minSdkVersion 24
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = 24
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
flavorDimensions "flavor"
productFlavors {
@@ -77,19 +75,20 @@ android {
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
debug {
applicationIdSuffix = ".debug"
versionNameSuffix = "-debug"
}
}
}
flutter {
source '../..'
}
repositories {
maven { url 'https://jitpack.io' }
source = "../.."
}
ext.abiCodes = ["x86_64": 1, "armeabi-v7a": 2, "arm64-v8a": 3]

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="label">Obtainium Debug</string>
</resources>

View File

@@ -2,7 +2,7 @@
xmlns:tools="http://schemas.android.com/tools"
package="dev.imranr.obtainium">
<application
android:label="Obtainium"
android:label="@string/label"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:requestLegacyExternalStorage="true"
@@ -12,6 +12,7 @@
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
@@ -21,12 +22,12 @@
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action
@@ -39,7 +40,6 @@
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="obtainium" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
@@ -71,6 +71,17 @@
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29" />\
android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="label">Obtainium</string>
</resources>

View File

@@ -9,12 +9,12 @@ allprojects {
}
}
rootProject.buildDir = '../build'
rootProject.buildDir = "../build"
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
project.evaluationDependsOn(":app")
}
tasks.register("clean", Delete) {

View File

@@ -1,3 +1,3 @@
org.gradle.jvmargs=-Xmx2048M
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true

View File

@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip

View File

@@ -18,8 +18,8 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.4.2" apply false
id "org.jetbrains.kotlin.android" version "1.8.10" apply false
id "com.android.application" version "8.1.0" apply false
id "org.jetbrains.kotlin.android" version "1.8.22" apply false
}
include ":app"

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 KiB

After

Width:  |  Height:  |  Size: 418 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 418 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 KiB

After

Width:  |  Height:  |  Size: 362 KiB

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Nije pronađena aplikacija s tim ID-om ili imenom",
"reposHaveMultipleApps": "Repo-i mogu sadržavati više aplikacija",
"fdroidThirdPartyRepo": "F-Droid Repo treće strane",
"steamMobile": "Steam Mobile",
"steamChat": "Razgovor na Steamu (chat)",
"install": "Instaliraj",
"markInstalled": "Označi kao instalirano",
"update": "Nadogradi",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Deinstaliraj s uređaja",
"onlyWorksWithNonVersionDetectApps": "Radi samo za aplikacije s onemogućenom detekcijom verzije.",
"releaseDateAsVersion": "Koristi datum izdanja kao verziju",
"releaseTitleAsVersion": "Use release title as version string",
"releaseDateAsVersionExplanation": "Ova opcija bi se trebala koristiti samo za aplikacije gdje detekcija verzije ne radi ispravno, ali je datum izdavanja dostupan.",
"changes": "Promjene",
"releaseDate": "Datum izdavanja",
@@ -257,6 +256,7 @@
"intermediateLink": "Intermediate veza",
"exemptFromBackgroundUpdates": "Izuzmi iz ažuriranja u pozadini (ako su uključeni)",
"bgUpdatesOnWiFiOnly": "Isključite ažuriranje u pozadini kada niste na WiFi-ju",
"bgUpdatesWhileChargingOnly": "Disable background updates when not charging",
"autoSelectHighestVersionCode": "Automatski izaberite najveću (verziju) versionCode APK-a",
"versionExtractionRegEx": "RegEx ekstrakcija verzije",
"trimVersionString": "Trim Version String With RegEx",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "Dijeli sa AppVerifier-om, zatim se vratite kada ste spremni.",
"wiki": "Pomoć/Wiki",
"crowdsourcedConfigsLabel": "Konfiguracije aplikacije obezbeđene pomoću velikog broja ljudi (crowdsourcing) (koristite na svoju odgovornost)",
"crowdsourcedConfigsShort": "Crowdsourced App Configs",
"allowInsecure": "Allow insecure HTTP requests",
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Želite li ukloniti aplikaciju?",
"other": "Želite li ukloniti aplikacije?"

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Žádná aplikace s tímto ID nebo názvem nebyla nalezena",
"reposHaveMultipleApps": "Repozitáře mohou obsahovat více aplikací",
"fdroidThirdPartyRepo": "F-Droid repozitář třetí strany",
"steamMobile": "Steam Mobile",
"steamChat": "Steam Chat",
"install": "Nainstalujte",
"markInstalled": "Označit jako nainstalovaný",
"update": "Aktualizovat",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Odinstalovat ze zařízení",
"onlyWorksWithNonVersionDetectApps": "Funguje pouze pro aplikace s vypnutou detekcí verze.",
"releaseDateAsVersion": "Použít datum vydání jako verzi",
"releaseTitleAsVersion": "Použít název verze jako řetězec verze",
"releaseDateAsVersionExplanation": "Tato možnost by měla být použita pouze u aplikace, kde detekce verzí nefunguje správně, ale je k dispozici datum vydání.",
"changes": "Změny",
"releaseDate": "Datum vydání",
@@ -257,6 +256,7 @@
"intermediateLink": "Připojený odkaz",
"exemptFromBackgroundUpdates": "Vyloučit z aktualizací na pozadí (je-li povoleno)",
"bgUpdatesOnWiFiOnly": "Deaktivovat aktualizace na pozadí, pokud není k dispozici Wi-Fi",
"bgUpdatesWhileChargingOnly": "Zakázat aktualizace na pozadí, když se nenabíjí",
"autoSelectHighestVersionCode": "Automaticky vybrat nejvyšší verzi APK",
"versionExtractionRegEx": "Extrakce verze pomocí RegEx",
"trimVersionString": "Oříznutí řetězce verze pomocí příkazu RegEx",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "Sdílejte do aplikace AppVerifier a po dokončení se sem vraťte.",
"wiki": "Nápověda/Wiki",
"crowdsourcedConfigsLabel": "Konfigurace aplikací s využitím crowdsourcingu (použití na vlastní nebezpečí)",
"crowdsourcedConfigsShort": "Konfigurace aplikací s využitím crowdsourcingu",
"allowInsecure": "Povolení nezabezpečených požadavků HTTP",
"stayOneVersionBehind": "Zůstaňte o jednu verzi pozadu za nejnovější",
"refreshBeforeDownload": "Obnovení údajů o aplikaci před stažením",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Odstranit Apku?",
"other": "Odstranit Apky?"

View File

@@ -1,5 +1,5 @@
{
"invalidURLForSource": "Ikke et gyldigt {} App-URL",
"invalidURLForSource": "Ikke et gyldigt {} app-URL",
"noReleaseFound": "Kunne ikke finde en passende udgivelse",
"noVersionFound": "Kunne ikke afgøre udgivelsesversion",
"urlMatchesNoSource": "URL'en matcher ikke en kendt kilde",
@@ -28,7 +28,7 @@
"githubStarredRepos": "Stjernemarkeret GitHub-repos",
"uname": "Brugernavn",
"wrongArgNum": "Forkert antal argumenter angivet",
"xIsTrackOnly": "{} kan kun følges",
"xIsTrackOnly": "{} er 'Følg Kun'",
"source": "Kilde",
"app": "App",
"appsFromSourceAreTrackOnly": "Apps fra denne kilde er 'Følg Kun'.",
@@ -36,14 +36,14 @@
"trackOnlyAppDescription": "Appen tjekkes for opdateringer, men Obtainium kan ikke hente eller installere den.",
"cancelled": "Annulleret",
"appAlreadyAdded": "Appen er allerede tilføjet",
"alreadyUpToDateQuestion": "Appen er allerede opdateret?",
"alreadyUpToDateQuestion": "Er appen allerede opdateret?",
"addApp": "Tilføj app",
"appSourceURL": "URL til app-kilde",
"error": "Fejl",
"add": "Tilføj",
"searchSomeSourcesLabel": "Søg (kun visse kilder)",
"search": "Søg",
"additionalOptsFor": "Yderligere indstillinger for {}",
"additionalOptsFor": "Flere indstillinger for {}",
"supportedSources": "Understøttede kilder",
"trackOnlyInBrackets": "(Følg Kun)",
"searchableInBrackets": "(Kan Søges)",
@@ -51,7 +51,7 @@
"noApps": "Ingen apps",
"noAppsForFilter": "Ingen apps til filter",
"byX": "Af {}",
"percentProgress": "Fremskridt: {}%",
"percentProgress": "Hentning: {}%",
"pleaseWait": "Vent venligst",
"updateAvailable": "Opdatering tilgængelig",
"notInstalled": "Ikke installeret",
@@ -74,14 +74,14 @@
"pinToTop": "Fastgør til toppen",
"unpinFromTop": "Frigør fra toppen",
"resetInstallStatusForSelectedAppsQuestion": "Nulstil installationsstatus for valgte apps?",
"installStatusOfXWillBeResetExplanation": "Installationsstatus for alle valgte apps nulstilles.\n\nDette kan hjælpe, når den app-version, der vises i Obtainium, er forkert grundet mislykkede opdateringer eller andre problemer.",
"installStatusOfXWillBeResetExplanation": "Installationsstatus for alle valgte apps nulstilles.\n\nDette kan hjælpe, når en forkert app-version vises i Obtainium grundet mislykkede opdateringer eller andre problemer.",
"customLinkMessage": "Disse links virker på enheder med Obtainium installeret",
"shareAppConfigLinks": "Del app-konfiguration som HTML-link",
"shareSelectedAppURLs": "Del valgte app-URL'er",
"resetInstallStatus": "Nulstil installationsstatus",
"more": "Mere",
"removeOutdatedFilter": "Fjern forældet app-filter",
"showOutdatedOnly": "Vis kun forældet apps",
"showOutdatedOnly": "Vis kun forældede apps",
"filter": "Filtrer",
"filterApps": "Filtrer Apps",
"appName": "Appnavn",
@@ -114,7 +114,7 @@
"light": "Lys",
"followSystem": "Følg system",
"followSystemThemeExplanation": "Det er kun muligt at følge systemtemaet ved brug af tredjepartsapplikationer",
"useBlackTheme": "Brug rent sort, mørkt tema",
"useBlackTheme": "Brug rent sort mørkt tema",
"appSortBy": "Sortér apps efter:",
"authorName": "Udvikler/Navn",
"nameAuthor": "Navn/Udvikler",
@@ -125,8 +125,8 @@
"bgUpdateCheckInterval": "Kontrolinterval for baggrundsopdatering",
"neverManualOnly": "Aldrig - Kun manuelt",
"appearance": "Udseende",
"showWebInAppView": "Vis kildewebsiden i appvisning",
"pinUpdates": "Fastgør opdateringer til toppen af appvisning",
"showWebInAppView": "Vis kildewebsiden i app-visning",
"pinUpdates": "Fastgør opdateringer øverst i app-visning",
"updates": "Opdateringer",
"sourceSpecific": "Kildespecifik",
"appSource": "App-kilde",
@@ -138,12 +138,12 @@
"obtainiumExportHyphenatedLowercase": "obtainium-eksport",
"pickAnAPK": "Vælg en APK",
"appHasMoreThanOnePackage": "{} har mere end én pakke:",
"deviceSupportsXArch": "Din enhed understøtter {} CPU-arkitekturen.",
"deviceSupportsXArch": "Din enhed understøtter CPU-arkitekturen {}.",
"deviceSupportsFollowingArchs": "Din enhed understøtter følgende CPU-arkitekturer:",
"warning": "Advarsel",
"sourceIsXButPackageFromYPrompt": "App-kilden er '{}', men udgivelsespakken kommer fra '{}'. Fortsæt?",
"updatesAvailable": "Opdateringer tilgængelige",
"updatesAvailableNotifDescription": "Underretter brugeren om, at opdateringer er tilgængelige for en eller flere apps, der spores af Obtainium",
"updatesAvailableNotifDescription": "Underretter brugeren om tilgængelige opdateringer for en eller flere apps, som Obtainium følger",
"noNewUpdates": "Ingen nye opdateringer.",
"xHasAnUpdate": "{} har en opdatering.",
"appsUpdated": "Apps opdateret",
@@ -152,19 +152,19 @@
"xWasUpdatedToY": "{} blev opdateret til {}.",
"xWasNotUpdatedToY": "Kunne ikke opdatere {} til {}.",
"errorCheckingUpdates": "Fejl ved tjek for opdateringer",
"errorCheckingUpdatesNotifDescription": "En meddelelse, der vises, når opdateringstjek i baggrunden mislykkes",
"errorCheckingUpdatesNotifDescription": "En meddelelse, der vises, opdateringstjek i baggrunden mislykkes",
"appsRemoved": "Apps fjernet",
"appsRemovedNotifDescription": "Underretter brugeren om, at en eller flere apps blev fjernet grundet fejl under indlæsning af dem",
"xWasRemovedDueToErrorY": "{} blev fjernet grundet denne fejl: {}",
"completeAppInstallation": "Færdiggør app-installation",
"obtainiumMustBeOpenToInstallApps": "Obtainium skal være åben for at installere apps",
"completeAppInstallationNotifDescription": "Beder brugeren om at vende tilbage til Obtainium for at afslutte installationen af en app",
"completeAppInstallationNotifDescription": "Beder brugeren om at tilbage til Obtainium for at færdiggøre installation af en app",
"checkingForUpdates": "Tjekker for opdateringer",
"checkingForUpdatesNotifDescription": "Kortvarig meddelelse, der vises ved tjek for opdateringer",
"checkingForUpdatesNotifDescription": "Kortvarig meddelelse ved tjek for opdateringer",
"pleaseAllowInstallPerm": "Tillad venligst Obtainium at installere apps",
"trackOnly": "Følg Kun",
"errorWithHttpStatusCode": "Fejl {}",
"versionCorrectionDisabled": "Versionskorrigering deaktiveret (plugin ser ikke ud til at virke)",
"versionCorrectionDisabled": "Versionskorrektion deaktiveret (plugin ser ikke ud til at virke)",
"unknown": "Ukendt",
"none": "Ingen",
"never": "Aldrig",
@@ -174,25 +174,23 @@
"remove": "Fjern",
"yesMarkUpdated": "Ja, markér som opdateret",
"fdroid": "F-Droid Officiel",
"appIdOrName": "App-ID eller navn",
"appIdOrName": "App-ID eller -navn",
"appId": "App-ID",
"appWithIdOrNameNotFound": "Ingen app med det ID eller navn blev fundet",
"reposHaveMultipleApps": "Repos kan indeholde flere apps",
"fdroidThirdPartyRepo": "F-Droid Tredjeparts-repo",
"steamMobile": "Steam Mobil",
"steamChat": "Steam Chat",
"install": "Installer",
"markInstalled": "Markér som installeret",
"update": "Opdater",
"markUpdated": "Markér som opdateret",
"additionalOptions": "Yderligere indstillinger",
"additionalOptions": "Flere indstillinger",
"disableVersionDetection": "Deaktivér versionsregistrering",
"noVersionDetectionExplanation": "Denne indstilling bør kun bruges til apps, hvor versionsregistrering ikke virker korrekt.",
"downloadingX": "Henter {}",
"downloadX": "Hent {}",
"downloadedX": "Hentede {}",
"releaseAsset": "Udgivelsesressource",
"downloadNotifDescription": "Underretter brugeren om fremskridt i hentning af en app",
"downloadNotifDescription": "Underretter brugeren om status på hentning af en app",
"noAPKFound": "Ingen APK fundet",
"noVersionDetection": "Ingen versionsregistrering",
"categorize": "Kategoriser",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Afinstaller fra enhed",
"onlyWorksWithNonVersionDetectApps": "Virker kun for apps med versionsregistrering deaktiveret.",
"releaseDateAsVersion": "Brug udgivelsesdato som versionsstreng",
"releaseTitleAsVersion": "Brug udgivelsestitel som versionsstreng",
"releaseDateAsVersionExplanation": "Denne indstilling bør kun bruges til apps, hvor versionsregistrering ikke virker korrekt, men hvor en udgivelsesdato er tilgængelig.",
"changes": "Ændringer",
"releaseDate": "Udgivelsesdato",
@@ -223,10 +222,10 @@
"groupByCategory": "Gruppér efter kategori",
"autoApkFilterByArch": "Forsøg at filtrere APK'er efter CPU-arkitektur, hvis muligt",
"overrideSource": "Tilsidesæt kilde",
"dontShowAgain": "Vis ikke denne igen",
"dontShowAgain": "Vis ikke igen",
"dontShowTrackOnlyWarnings": "Vis ikke 'Følg Kun'-advarsler",
"dontShowAPKOriginWarnings": "Vis ikke advarsler om APK-oprindelse",
"moveNonInstalledAppsToBottom": "Flyt ikke-installerede apps til bunden af appvisning",
"moveNonInstalledAppsToBottom": "Flyt ikke-installerede apps nederst i app-visning",
"gitlabPATLabel": "GitLab Personlig Adgangstoken",
"about": "Om",
"requiresCredentialsInSettings": "{} kræver yderligere legitimation (i Indstillinger)",
@@ -239,43 +238,44 @@
"reversePageTransitions": "Omvendte sideovergangsanimationer",
"minStarCount": "Minimum antal stjerner",
"addInfoBelow": "Tilføj denne info nedenfor.",
"addInfoInSettings": "Tilføj denne info i indstillingerne.",
"githubSourceNote": "GitHubs hastighedsbegrænsning kan undgås med en API-nøgle.",
"addInfoInSettings": "Tilføj denne info i Indstillinger.",
"githubSourceNote": "GitHub's hastighedsbegrænsning kan undgås med en API-nøgle.",
"sortByLastLinkSegment": "Sortér kun efter det sidste segment af linket",
"filterReleaseNotesByRegEx": "Filtrer udgivelsesnoter efter regulært udtryk",
"customLinkFilterRegex": "Brugerdefineret APK-linkfilter efter regulært udtryk (standard '.apk$')",
"appsPossiblyUpdated": "App-opdateringer forsøgt",
"appsPossiblyUpdatedNotifDescription": "Underretter brugeren om, at opdateringer til en eller flere apps potentielt blev udført i baggrunden",
"appsPossiblyUpdatedNotifDescription": "Underretter brugeren om, at opdateringer til en eller flere apps muligvis blev udført i baggrunden",
"xWasPossiblyUpdatedToY": "{} er muligvis blevet opdateret til {}.",
"enableBackgroundUpdates": "Aktivér baggrundsopdateringer",
"backgroundUpdateReqsExplanation": "Baggrundsopdateringer er muligvis ikke mulige for alle apps.",
"backgroundUpdateLimitsExplanation": "Om en baggrundsinstallation er vellykket, kan kun afgøres, når Obtainium åbnes.",
"backgroundUpdateReqsExplanation": "Baggrundsopdateringer er måske ikke mulige for alle apps.",
"backgroundUpdateLimitsExplanation": "En vellykket baggrundsinstallation kan kun afgøres, når Obtainium åbnes.",
"verifyLatestTag": "Verificer 'seneste'-tagget",
"intermediateLinkRegex": "Filtrer efter et 'mellemliggende' link at besøge",
"filterByLinkText": "Filtrer links efter linktekst",
"intermediateLinkNotFound": "Mellemliggende link ikke fundet",
"intermediateLink": "Mellemliggende link",
"exemptFromBackgroundUpdates": "Undtag fra baggrundsopdateringer (hvis aktiveret)",
"bgUpdatesOnWiFiOnly": "Deaktivér baggrundsopdateringer, når du ikke er på WiFi",
"bgUpdatesOnWiFiOnly": "Deaktiver baggrundsopdateringer, når du ikke er på Wi-Fi",
"bgUpdatesWhileChargingOnly": "Deaktiver baggrundsopdateringer, når du ikke oplader",
"autoSelectHighestVersionCode": "Auto-vælg højeste versionKode af APK",
"versionExtractionRegEx": "RegEx for versionsstrengsudtrækning",
"trimVersionString": "Trim versionsstrengen med RegEx",
"matchGroupToUseForX": "Matchgruppe til brug for \"{}\"",
"matchGroupToUse": "Match gruppe til brug til RegEx for versionsstrengsudtrækning",
"trimVersionString": "Trim versionsstreng med RegEx",
"matchGroupToUseForX": "Match-gruppe til brug for \"{}\"",
"matchGroupToUse": "RegEx-matchgruppe til brug for versionsstrengsudtrækning",
"highlightTouchTargets": "Fremhæv mindre åbenlyse berøringsmål",
"pickExportDir": "Vælg eksportmappe",
"autoExportOnChanges": "Auto-eksport ved ændringer",
"autoExportOnChanges": "Auto-eksportér ved ændringer",
"includeSettings": "Inkluder indstillinger",
"filterVersionsByRegEx": "Filtrer versioner efter regulært udtryk",
"trySelectingSuggestedVersionCode": "Forsøg at vælge den foreslåede versionKode af APK",
"dontSortReleasesList": "Behold udgivelsesordre fra API",
"dontSortReleasesList": "Behold udgivelsesrækkefølge fra API",
"reverseSort": "Omvendt sortering",
"takeFirstLink": "Tag første link",
"skipSort": "Spring sortering over",
"debugMenu": "Fejlfindingsmenu",
"bgTaskStarted": "Baggrundsopgave startet - tjek logfiler.",
"runBgCheckNow": "Kør baggrundsopdateringstjek nu",
"versionExtractWholePage": "Anvend RegEx for versionsstrengsudtrækning for hele siden",
"versionExtractWholePage": "Anvend RegEx til versionsstrengsudtrækning hele siden",
"installing": "Installerer",
"skipUpdateNotifications": "Spring opdateringsmeddelelser over",
"updatesAvailableNotifChannel": "Opdateringer tilgængelige",
@@ -286,7 +286,7 @@
"downloadingXNotifChannel": "Henter {}",
"completeAppInstallationNotifChannel": "Færdiggør app-installation",
"checkingForUpdatesNotifChannel": "Tjekker for opdateringer",
"onlyCheckInstalledOrTrackOnlyApps": "Tjek kun installeret og 'Følg Kun'-apps for opdateringer",
"onlyCheckInstalledOrTrackOnlyApps": "Tjek kun installerede og 'Følg Kun'-apps for opdateringer",
"supportFixedAPKURL": "Understøt fikserede APK-URL'er",
"selectX": "Vælg {}",
"parallelDownloads": "Tillad samtidige overførsler",
@@ -296,8 +296,8 @@
"shizukuOldAndroidWithADB": "Shizuku kører på Android <8.1 med ADB. Opdater Android eller brug Sui i stedet",
"shizukuPretendToBeGooglePlay": "Indstil Google Play som installationskilde (hvis Shizuku bruges)",
"useSystemFont": "Brug systemskrifttype",
"useVersionCodeAsOSVersion": "Brug app versionKode som OS-registreret version",
"requestHeader": "Anmod overskrift",
"useVersionCodeAsOSVersion": "Brug app-versionKode som OS-registreret version",
"requestHeader": "Anmodningsheader",
"useLatestAssetDateAsReleaseDate": "Brug seneste ressourceupload som udgivelsesdato",
"defaultPseudoVersioningMethod": "Standard pseudo-versioneringsmetode",
"partialAPKHash": "Delvis APK-hash",
@@ -311,10 +311,14 @@
"selfHostedNote": "Rullemenuen \"{}\" kan bruges til at nå selvhostede/brugerdefinerede instanser af enhver kilde.",
"badDownload": "APK'en kunne ikke analyseres (inkompatibel eller delvis hentning)",
"beforeNewInstallsShareToAppVerifier": "Del nye apps med AppVerifier (hvis tilgængelig)",
"appVerifierInstructionToast": "Del til AppVerifier, og vend tilbage hertil, når du er klar.",
"appVerifierInstructionToast": "Del til AppVerifier, og vend tilbage, når du er klar.",
"wiki": "Hjælp/Wiki",
"crowdsourcedConfigsLabel": "Crowdsourcede app-konfigurationer (brug på egen risiko)",
"crowdsourcedConfigsShort": "Crowdsourcede app-konfigurationer",
"allowInsecure": "Tillad usikre HTTP-anmodninger",
"stayOneVersionBehind": "Forbliv én version bagud den seneste",
"refreshBeforeDownload": "Opdater app-detaljer før download",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Fjern app?",
"other": "Fjern apps?"
@@ -353,7 +357,7 @@
},
"clearedNLogsBeforeXAfterY": {
"one": "Ryddet {n} log (før = {before}, efter = {after})",
"other": "Ryddet {n} logs (før = {before}, efter = {after})"
"other": "Ryddede {n} logs (før = {before}, efter = {after})"
},
"xAndNMoreUpdatesAvailable": {
"one": "{} og 1 anden app har opdateringer.",

View File

@@ -32,8 +32,8 @@
"source": "Quelle",
"app": "App",
"appsFromSourceAreTrackOnly": "Apps aus dieser Quelle sind nur zur Nachverfolgung.",
"youPickedTrackOnly": "Sie haben die Option „Nur nachverfolgen“ gewählt.",
"trackOnlyAppDescription": "Die App wird auf Aktualisierungen überwacht, aber Obtainium wird sie nicht herunterladen oder installieren.",
"youPickedTrackOnly": "Du hast die Option „Nur nachverfolgen“ gewählt.",
"trackOnlyAppDescription": "Die App wird auf neue verfügbare Versionen überwacht, aber Obtainium wird sie nicht herunterladen oder installieren.",
"cancelled": "Abgebrochen",
"appAlreadyAdded": "App bereits hinzugefügt",
"alreadyUpToDateQuestion": "App bereits auf dem neuesten Stand?",
@@ -85,8 +85,8 @@
"filter": "Filter",
"filterApps": "Apps filtern",
"appName": "App-Name",
"author": "Autor",
"upToDateApps": "Apps mit aktueller Version",
"author": "Herausgebende",
"upToDateApps": "Apps mit aktuellster Version",
"nonInstalledApps": "Nicht installierte Apps",
"importExport": "Import/Export",
"settings": "Einstellungen",
@@ -102,22 +102,22 @@
"searchX": "{} suchen",
"noResults": "Keine Ergebnisse gefunden",
"importX": "{} importieren",
"importedAppsIdDisclaimer": "Importierte Apps werden manchmal fälschlicherweise als „Nicht installiert“ angezeigt. Um dies zu beheben, installieren Sie sie erneut über Obtainium. Dies hat keine Auswirkungen auf App-Daten. Es betrifft nur URL- und Drittanbieter-Importmethoden.",
"importedAppsIdDisclaimer": "Importierte Apps werden manchmal fälschlicherweise als „Nicht installiert“ angezeigt. Um dies zu beheben, installiere sie erneut über Obtainium. Dies hat keine Auswirkungen auf App-Daten. Es betrifft nur URL- und Drittanbieter-Importmethoden.",
"importErrors": "Importfehler",
"importedXOfYApps": "{} von {} Apps importiert.",
"followingURLsHadErrors": "Bei folgenden URLs traten Fehler auf:",
"selectURL": "URL auswählen",
"selectURLs": "URLs auswählen",
"pick": "Auswählen",
"theme": "Theme",
"theme": "Design",
"dark": "Dunkel",
"light": "Hell",
"followSystem": "System folgen",
"followSystemThemeExplanation": "Das Folgen des Systemthemes ist unter Android < 10 nur mit Hilfe von Drittanbieterapps möglich",
"useBlackTheme": "Pure Black Dark Theme verwenden",
"followSystem": "Systemstandard",
"followSystemThemeExplanation": "Das Abrufen des Systemdesigns ist unter Android < 10 nur mit Hilfe von Drittanbieterapps möglich",
"useBlackTheme": "Rein schwarzen Hintergrund verwenden",
"appSortBy": "App sortieren nach",
"authorName": "Autor/Name",
"nameAuthor": "Name/Autor",
"authorName": "Hrsg./Name",
"nameAuthor": "Name/Hrsg.",
"asAdded": "Wie hinzugefügt",
"appSortOrder": "App sortieren nach",
"ascending": "Aufsteigend",
@@ -138,30 +138,30 @@
"obtainiumExportHyphenatedLowercase": "Obtainium-Export",
"pickAnAPK": "APK auswählen",
"appHasMoreThanOnePackage": "{} verfügt über mehr als ein Paket:",
"deviceSupportsXArch": "Ihr Gerät unterstützt die CPU-Architektur {}.",
"deviceSupportsFollowingArchs": "Ihr Gerät unterstützt die folgenden CPU-Architekturen:",
"deviceSupportsXArch": "Dein Gerät unterstützt die CPU-Architektur {}.",
"deviceSupportsFollowingArchs": "Dein Gerät unterstützt die folgenden CPU-Architekturen:",
"warning": "Warnung",
"sourceIsXButPackageFromYPrompt": "Die App-Quelle ist '{}', aber das Release-Paket stammt von '{}'. Fortfahren?",
"updatesAvailable": "Aktualisierungen verfügbar",
"updatesAvailableNotifDescription": "Benachrichtigt den Nutzer, dass Aktualisierungen für eine oder mehrere von Obtainium verfolgte Apps verfügbar sind",
"updatesAvailableNotifDescription": "Benachrichtigt, wenn Aktualisierungen für eine oder mehrere von Obtainium verfolgte Apps verfügbar sind",
"noNewUpdates": "Keine neuen Aktualisierungen.",
"xHasAnUpdate": "{} hat eine Aktualisierung.",
"appsUpdated": "App wurde aktualisiert",
"appsNotUpdated": "Aktualisierung der Apps fehlgeschlagen",
"appsUpdatedNotifDescription": "Benachrichtigt den Benutzer, dass Aktualisierungen für eine oder mehrere Apps im Hintergrund durchgeführt wurden",
"appsUpdatedNotifDescription": "Benachrichtigt, wenn Aktualisierungen für eine oder mehrere Apps im Hintergrund durchgeführt wurden",
"xWasUpdatedToY": "{} wurde auf {} aktualisiert.",
"xWasNotUpdatedToY": "Die Aktualisierung von {} auf {} ist fehlgeschlagen.",
"errorCheckingUpdates": "Fehler beim Prüfen auf Aktualisierungen",
"errorCheckingUpdatesNotifDescription": "Eine Benachrichtigung, die angezeigt wird, wenn die Prüfung der Hintergrundaktualisierung fehlschlägt",
"errorCheckingUpdatesNotifDescription": "Benachrichtigt, wenn die Prüfung der Hintergrundaktualisierung fehlgeschlagen ist",
"appsRemoved": "Apps entfernt",
"appsRemovedNotifDescription": "Benachrichtigt den Benutzer, dass eine oder mehrere Apps aufgrund von Fehlern beim Laden entfernt wurden",
"appsRemovedNotifDescription": "Benachrichtigt, wenn eine oder mehrere Apps aufgrund von Fehlern beim Laden entfernt wurden",
"xWasRemovedDueToErrorY": "{} wurde aufgrund des folgenden Fehlers entfernt: {}",
"completeAppInstallation": "App-Installation abschließen",
"obtainiumMustBeOpenToInstallApps": "Obtainium muss geöffnet sein, um Apps zu installieren",
"completeAppInstallationNotifDescription": "Aufforderung an den Benutzer, zu Obtainium zurückzukehren, um die Installation einer App abzuschließen",
"completeAppInstallationNotifDescription": "Aufforderung zu Obtainium zurückzukehren, um die Installation einer App abzuschließen",
"checkingForUpdates": "Nach Aktualisierungen suchen",
"checkingForUpdatesNotifDescription": "Vorübergehende Benachrichtigung, die bei der Suche nach Aktualisierungen angezeigt wird",
"pleaseAllowInstallPerm": "Bitte erlauben Sie Obtainium die Installation von Apps",
"pleaseAllowInstallPerm": "Bitte erlaube Obtainium die Installation von Apps",
"trackOnly": "Nur nachverfolgen",
"errorWithHttpStatusCode": "Fehler {}",
"versionCorrectionDisabled": "Versionskorrektur deaktiviert (Plugin scheint nicht zu funktionieren)",
@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Es wurde keine App mit dieser ID oder diesem Namen gefunden",
"reposHaveMultipleApps": "Repos können mehrere Apps enthalten",
"fdroidThirdPartyRepo": "F-Droid-Drittanbieter-Repo",
"steamMobile": "Steam Mobile",
"steamChat": "Steam-Chat",
"install": "Installieren",
"markInstalled": "Als installiert markieren",
"update": "Aktualisieren",
@@ -192,7 +190,7 @@
"downloadX": "{} herunterladen",
"downloadedX": "{} heruntergeladen",
"releaseAsset": "Release-Asset",
"downloadNotifDescription": "Benachrichtigt den Nutzer über den Fortschritt beim Herunterladen einer App",
"downloadNotifDescription": "Zeigt den Fortschritt beim Herunterladen einer App",
"noAPKFound": "Keine APK gefunden",
"noVersionDetection": "Keine Versionserkennung",
"categorize": "Kategorisieren",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Vom Gerät deinstallieren",
"onlyWorksWithNonVersionDetectApps": "Funktioniert nur bei Apps mit deaktivierter Versionserkennung.",
"releaseDateAsVersion": "Veröffentlichungsdatum als Version verwenden",
"releaseTitleAsVersion": "Versionstitel als Versionsstring verwenden",
"releaseDateAsVersionExplanation": "Diese Option sollte nur für Apps verwendet werden, bei denen die Versionserkennung nicht korrekt funktioniert, aber ein Veröffentlichungsdatum verfügbar ist.",
"changes": "Änderungen",
"releaseDate": "Veröffentlichungsdatum",
@@ -224,7 +223,7 @@
"autoApkFilterByArch": "Nach Möglichkeit versuchen, APKs nach CPU-Architektur zu filtern",
"overrideSource": "Quelle überschreiben",
"dontShowAgain": "Nicht noch einmal anzeigen",
"dontShowTrackOnlyWarnings": "Warnung für 'Nur nachverfolgen' nicht anzeigen",
"dontShowTrackOnlyWarnings": "Warnung für Nur nachverfolgen nicht anzeigen",
"dontShowAPKOriginWarnings": "Warnung für APK-Herkunft nicht anzeigen",
"moveNonInstalledAppsToBottom": "Nicht installierte Apps ans Ende der App-Ansicht verschieben",
"gitlabPATLabel": "Persönlicher Zugangstoken für GitLab",
@@ -232,7 +231,7 @@
"requiresCredentialsInSettings": "{}: Benötigt zusätzliche Anmeldedaten (in den Einstellungen)",
"checkOnStart": "Einmalig beim Start überprüfen",
"tryInferAppIdFromCode": "Versuchen, die App-ID aus dem Quellcode zu ermitteln",
"removeOnExternalUninstall": "Automatisches Entfernen von extern deinstallierten Apps",
"removeOnExternalUninstall": "Extern deinstallierte Apps automatische entfernen",
"pickHighestVersionCode": "Automatische Auswahl des APK mit höchstem Versionscode",
"checkUpdateOnDetailPage": "Nach Aktualisierungen suchen, wenn eine App-Detailseite geöffnet wird",
"disablePageTransitions": "Animationen für Seitenübergänge deaktivieren",
@@ -242,25 +241,26 @@
"addInfoInSettings": "Diese Information in den Einstellungen hinzufügen.",
"githubSourceNote": "Die GitHub-Ratenbegrenzung kann mit einem API-Schlüssel umgangen werden.",
"sortByLastLinkSegment": "Nur nach dem letzten Teil des Links sortieren",
"filterReleaseNotesByRegEx": "Versionshinweise nach regulärem Ausdruck filtern",
"filterReleaseNotesByRegEx": "Versionshinweise nach regulärem Ausdruck\nfiltern",
"customLinkFilterRegex": "Benutzerdefinierter APK-Linkfilter durch regulären Ausdruck (Standard '.apk$')",
"appsPossiblyUpdated": "App-Aktualisierungen wurden versucht",
"appsPossiblyUpdatedNotifDescription": "Benachrichtigt den Benutzer, dass Aktualisierungen für eine oder mehrere Apps möglicherweise im Hintergrund durchgeführt wurden",
"xWasPossiblyUpdatedToY": "{} wurde möglicherweise aktualisiert auf {}.",
"appsPossiblyUpdatedNotifDescription": "Benachrichtigt, dass möglicherweise eine oder mehrere Apps im Hintergrund aktualisiert wurden",
"xWasPossiblyUpdatedToY": "{} wurde eventuell auf Version {} aktualisiert.",
"enableBackgroundUpdates": "Hintergrundaktualisierungen aktivieren",
"backgroundUpdateReqsExplanation": "Die Hintergrundaktualisierung ist möglicherweise nicht für alle Apps möglich.",
"backgroundUpdateReqsExplanation": "Die Hintergrundaktualisierung ist unter Umständen nicht für alle Apps möglich.",
"backgroundUpdateLimitsExplanation": "Der Erfolg einer Hintergrundinstallation kann nur festgestellt werden, wenn Obtainium geöffnet wird.",
"verifyLatestTag": "„Latest“-Tag überprüfen",
"intermediateLinkRegex": "Filter für einen „Zwischen“-Link, der zuerst besucht werden soll",
"filterByLinkText": "Links durch Linktext filtern",
"intermediateLinkNotFound": "„Zwischen“-Link nicht gefunden",
"intermediateLink": "„Zwischen“-Link",
"exemptFromBackgroundUpdates": "Ausschluss von Hintergrundaktualisierungen (falls aktiviert)",
"bgUpdatesOnWiFiOnly": "Hintergrundaktualisierungen deaktivieren, wenn kein WLAN vorhanden ist",
"exemptFromBackgroundUpdates": "Von Hintergrundaktualisierungen (falls aktiviert) ausschließen",
"bgUpdatesOnWiFiOnly": "Hintergrundaktualisierungen nur im WLAN ausführen",
"bgUpdatesWhileChargingOnly": "Hintergrundaktualisierungen nur ausführen, während das Gerät geladen wird",
"autoSelectHighestVersionCode": "Automatisch höchste APK-Version auswählen",
"versionExtractionRegEx": "Versionsextraktion per RegEx",
"trimVersionString": "Versionszeichenfolge mit RegEx kürzen",
"matchGroupToUseForX": "Zu verwendende Abgleichsgruppe für „{}“",
"matchGroupToUseForX": "Zu verwendende Abgleichsgruppe für\n„{}“",
"matchGroupToUse": "Zu verwendende Gruppe abgleichen",
"highlightTouchTargets": "Weniger offensichtliche Touch-Ziele hervorheben",
"pickExportDir": "Export-Verzeichnis wählen",
@@ -268,7 +268,7 @@
"includeSettings": "Einstellungen einbeziehen",
"filterVersionsByRegEx": "Versionen nach regulären Ausdrücken filtern",
"trySelectingSuggestedVersionCode": "Versuchen, den vorgeschlagenen APK-Versionscode auszuwählen",
"dontSortReleasesList": "Freigaberelease von der API ordern",
"dontSortReleasesList": "Releases-Sortierung der API beibehalten",
"reverseSort": "Umgekehrtes Sortieren",
"takeFirstLink": "Ersten Link verwenden",
"skipSort": "Sortieren überspringen",
@@ -292,12 +292,12 @@
"parallelDownloads": "Parallele Downloads erlauben",
"useShizuku": "Shizuku oder Sui zur Installation verwenden",
"shizukuBinderNotFound": "Kompatibler Shizuku-Dienst wurde nicht gefunden",
"shizukuOld": "Alte Shizuku-Version (< 11) - aktualisieren Sie sie",
"shizukuOldAndroidWithADB": "Shizuku läuft auf Android < 8.1 mit ADB - aktualisieren Sie Android oder verwenden Sie stattdessen Sui",
"shizukuPretendToBeGooglePlay": "Google Play als Installationsquelle festlegen (wenn Shizuku verwendet wird)",
"shizukuOld": "Veraltete Shizuku-Version (< 11) - bitte aktualisiere sie",
"shizukuOldAndroidWithADB": "Shizuku läuft auf Android < 8.1 mit ADB - aktualisiere die Android-Version oder verwende stattdessen Sui",
"shizukuPretendToBeGooglePlay": "(Mittels Shizuku) Google Play als Installationsquelle registrieren",
"useSystemFont": "Systemschriftart verwenden",
"useVersionCodeAsOSVersion": "App-Version als erkannte Version vom Betriebssystem verwenden",
"requestHeader": "Kopfzeile anfordern",
"useVersionCodeAsOSVersion": "Versionscode (versionCode) als erkannte Version vom Betriebssystem verwenden",
"requestHeader": "Kopfzeile („Header“) anfordern",
"useLatestAssetDateAsReleaseDate": "Letzten Asset-Upload als Veröffentlichungsdatum verwenden",
"defaultPseudoVersioningMethod": "Standardmäßiges Verfahren zur Pseudo-Versionierung",
"partialAPKHash": "Partieller APK-Hash",
@@ -309,27 +309,31 @@
"invertRegEx": "Regulären Ausdruck invertieren",
"note": "Hinweis",
"selfHostedNote": "Das „{}“-Drop-down-Menü kann verwendet werden, um selbst gehostete/angepasste Instanzen einer beliebigen Quelle zu erreichen.",
"badDownload": "Die APK konnte nicht geparst werden (inkompatibler oder teilweiser Download)",
"badDownload": "Die APK konnte nicht gelesen werden (inkompatibler oder unfertiger Download)",
"beforeNewInstallsShareToAppVerifier": "Neue Apps mit AppVerifier teilen (falls verfügbar)",
"appVerifierInstructionToast": "Geben Sie die Daten an AppVerifier weiter und kehren Sie dann hierher zurück, wenn Sie fertig sind.",
"appVerifierInstructionToast": "Teile die Daten mit AppVerifier und kehre im Anschluss hierher zurück.",
"wiki": "Hilfe/Wiki",
"crowdsourcedConfigsLabel": "Crowdsourced App-Konfigurationen (Verwendung auf eigene Gefahr)",
"crowdsourcedConfigsShort": "Crowdsourced App-Konfigurationen",
"allowInsecure": "Unsichere HTTP-Anfragen zulassen",
"stayOneVersionBehind": "Eine Version hinter der neuesten Version bleiben",
"refreshBeforeDownload": "App-Details vor dem Download aktualisieren",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "App entfernen?",
"other": "Apps entfernen?"
},
"tooManyRequestsTryAgainInMinutes": {
"one": "Zu viele Anfragen (Rate begrenzt) versuchen Sie es in {} Minute erneut",
"other": "Zu viele Anfragen (Rate begrenzt) versuchen Sie es in {} Minuten erneut"
"one": "Zu viele Anfragen (Rate begrenzt) versuche es in {} Minute erneut",
"other": "Zu viele Anfragen (Rate begrenzt) versuche es in {} Minuten erneut"
},
"bgUpdateGotErrorRetryInMinutes": {
"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"
},
"bgCheckFoundUpdatesWillNotifyIfNeeded": {
"one": "Die Hintergrundaktualisierungsprüfung fand {} Aktualisierung benachrichtigt den Benutzer, falls erforderlich",
"other": "Die Hintergrundaktualisierungsprüfung fand {} Aktualisierungen benachrichtigt den Benutzer, falls erforderlich"
"one": "Die Aktualisierungsprüfung fand {} Aktualisierung benachrichtigt, falls erforderlich",
"other": "Die Aktualisierungsprüfung fand {} Aktualisierungen benachrichtigt, falls erforderlich"
},
"apps": {
"one": "{} App",
@@ -356,8 +360,8 @@
"other": "{n} Logs gelöscht (vorher = {before}, nachher = {after})"
},
"xAndNMoreUpdatesAvailable": {
"one": "{} und 1 weitere App haben Aktualisierungen.",
"other": "{} und {} weitere Apps haben Aktualisierungen."
"one": "{} und 1 weitere App können aktualisiert werden.",
"other": "{} und {} weitere Apps können aktualisiert werden."
},
"xAndNMoreUpdatesInstalled": {
"one": "{} und 1 weitere App wurden aktualisiert.",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Neniu apo estas trovita kun tiu identigilo aŭ nomo",
"reposHaveMultipleApps": "Deponejoj povas enhavi plurajn apojn",
"fdroidThirdPartyRepo": "Tria deponejo de F-Droid",
"steamMobile": "Telefona Steam",
"steamChat": "Steam Babilejo",
"install": "Instali",
"markInstalled": "Marki kiel instalita",
"update": "Ĝisdatigi",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Malinstali el la disponaĵo",
"onlyWorksWithNonVersionDetectApps": "Funkcias nur por apoj kun malaktiva versiodetekto.",
"releaseDateAsVersion": "Uzi eldondato kiel versioĉeno",
"releaseTitleAsVersion": "Use release title as version string",
"releaseDateAsVersionExplanation": "Tiu opcio devas esti uzata nur por apoj, por kiu la versiodetekto ne funkcias ĝuste, sed eldondato estas havebla.",
"changes": "Modifoj",
"releaseDate": "Eldondato",
@@ -257,6 +256,7 @@
"intermediateLink": "Pera ligilo",
"exemptFromBackgroundUpdates": "Escepti el la fonaj ĝisdatigoj (se aktiva)",
"bgUpdatesOnWiFiOnly": "Malaktivigi fonajn ĝisdatigojn se sen vifio",
"bgUpdatesWhileChargingOnly": "Disable background updates when not charging",
"autoSelectHighestVersionCode": "Aŭtomate selekti la plej ĵusan version de la APK-kodo",
"versionExtractionRegEx": "Ekstrakti la versioĉenon per regula esprimo",
"trimVersionString": "Mallongigi la versioĉenon per regula esprimo",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "Diskonigu kun AppVerifier, poste revenu ĉi tie kiam preta.",
"wiki": "Helpo/Vikio",
"crowdsourcedConfigsLabel": "Komunumaj apo-agordoj (uzu kun singardo)",
"crowdsourcedConfigsShort": "Crowdsourced App Configs",
"allowInsecure": "Allow insecure HTTP requests",
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Forigi la aplikaĵon?",
"other": "Forigi la aplikaĵojn?"

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "No App was found with that ID or Name",
"reposHaveMultipleApps": "Repos may contain multiple Apps",
"fdroidThirdPartyRepo": "F-Droid Third-Party Repo",
"steamMobile": "Steam Mobile",
"steamChat": "Steam Chat",
"install": "Install",
"markInstalled": "Mark Installed",
"update": "Update",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Uninstall from Device",
"onlyWorksWithNonVersionDetectApps": "Only works for Apps with version detection disabled.",
"releaseDateAsVersion": "Use release date as version string",
"releaseTitleAsVersion": "Use release title as version string",
"releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.",
"changes": "Changes",
"releaseDate": "Release Date",
@@ -257,6 +256,7 @@
"intermediateLink": "Intermediate link",
"exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)",
"bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi",
"bgUpdatesWhileChargingOnly": "Disable background updates when not charging",
"autoSelectHighestVersionCode": "Auto-select highest versionCode APK",
"versionExtractionRegEx": "Version String Extraction RegEx",
"trimVersionString": "Trim Version String With RegEx",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "Share to AppVerifier, then return here when ready.",
"wiki": "Help/Wiki",
"crowdsourcedConfigsLabel": "Crowdsourced App Configurations (use at your own risk)",
"crowdsourcedConfigsShort": "Crowdsourced App Configs",
"allowInsecure": "Allow insecure HTTP requests",
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Remove App?",
"other": "Remove Apps?"

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "No se han encontrado aplicaciones con ese ID o nombre",
"reposHaveMultipleApps": "Los repositorios pueden contener varias aplicaciones",
"fdroidThirdPartyRepo": "Repositorio de terceros F-Droid",
"steamMobile": "Steam para móviles",
"steamChat": "Chat de Steam",
"install": "Instalar",
"markInstalled": "Marcar como instalada",
"update": "Actualizar",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Desinstalar del dispositivo",
"onlyWorksWithNonVersionDetectApps": "Solo funciona para aplicaciones con la detección de versiones desactivada.",
"releaseDateAsVersion": "Por fecha de publicación",
"releaseTitleAsVersion": "Utilizar el título de la versión como cadena de versión",
"releaseDateAsVersionExplanation": "Esta opción solo se debería usar con aplicaciones en las que la detección de versiones no funciona pero hay disponible una fecha de publicación.",
"changes": "Cambios",
"releaseDate": "Fecha de publicación",
@@ -257,11 +256,12 @@
"intermediateLink": "Enlace intermedio",
"exemptFromBackgroundUpdates": "Exenta de actualizciones en segundo plano (si están habilitadas)",
"bgUpdatesOnWiFiOnly": "Deshabilitar las actualizaciones en segundo plano sin WiFi",
"bgUpdatesWhileChargingOnly": "Desactiva las actualizaciones en segundo plano cuando no estés cargando",
"autoSelectHighestVersionCode": "Auto selección del paquete APK con versión más reciente",
"versionExtractionRegEx": "Versión de extracción regex",
"versionExtractionRegEx": "Versión de extracción RegEx",
"trimVersionString": "Recortar cadena de versión con RegEx",
"matchGroupToUseForX": "Grupo de coincidencia a utilizar para \"{}\"",
"matchGroupToUse": "Grupo a usar para versión de extracción regex",
"matchGroupToUse": "Grupo a usar para versión de extracción RegEx",
"highlightTouchTargets": "Resaltar objetivos menos obvios",
"pickExportDir": "Directorio para exportar",
"autoExportOnChanges": "Auto exportar cuando haya cambios",
@@ -275,7 +275,7 @@
"debugMenu": "Menu Depurar",
"bgTaskStarted": "Iniciada tarea en segundo plano; revise los registros.",
"runBgCheckNow": "Ejecutar verficiación de actualizaciones en segundo plano",
"versionExtractWholePage": "Aplicar la versión de extracción regex a la página entera",
"versionExtractWholePage": "Aplicar la versión de extracción RegEx a la página entera",
"installing": "Instalando",
"skipUpdateNotifications": "No notificar sobre actualizaciones",
"updatesAvailableNotifChannel": "Actualizaciones disponibles",
@@ -310,11 +310,15 @@
"note": "Nota",
"selfHostedNote": "El desplegable «{}» puede usarse para acceder a instancias autoalojadas/personalizadas de cualquier fuente.",
"badDownload": "No se ha podido analizar el APK (incompatible o descarga parcial)",
"beforeNewInstallsShareToAppVerifier": "Compartir aplicaciones nuevas con AppVerifier (si está disponible)",
"appVerifierInstructionToast": "Comparta con AppVerifier y vuelva aquí cuando esté listo.",
"beforeNewInstallsShareToAppVerifier": "Compartir aplicaciones nuevas con AppVerifier (si está instalado)",
"appVerifierInstructionToast": "Compartir con AppVerifier y vuelver aquí cuando esté listo.",
"wiki": "Ayuda/Wiki",
"crowdsourcedConfigsLabel": "Crowdsourced App Configurations (uso bajo su propia responsabilidad)",
"crowdsourcedConfigsLabel": "Crowdsourced App Configurations (use bajo su responsabilidad)",
"crowdsourcedConfigsShort": "Configuración de aplicaciones por crowdsourcing",
"allowInsecure": "Permitir peticiones HTTP inseguras",
"stayOneVersionBehind": "Mantenerse una versión por detrás de la última",
"refreshBeforeDownload": "Actualiza los datos de la aplicación antes de descargarla",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "¿Eliminar aplicación?",
"other": "¿Eliminar aplicaciones?"

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "هیچ برنامه ای با آن شناسه یا نام یافت نشد",
"reposHaveMultipleApps": "مخازن ممکن است شامل چندین برنامه باشد",
"fdroidThirdPartyRepo": "مخازن شخص ثالث F-Droid",
"steamMobile": "استیم موبایل",
"steamChat": "چت استیم",
"install": "نصب",
"markInstalled": "علامت گذاری به عنوان نصب شده",
"update": "به روز رسانی",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "حذف نصب از دستگاه",
"onlyWorksWithNonVersionDetectApps": "فقط برای برنامه‌هایی کار می‌کند که تشخیص نسخه غیرفعال است.",
"releaseDateAsVersion": "از تاریخ انتشار به عنوان نسخه استفاده کنید",
"releaseTitleAsVersion": "از عنوان انتشار به عنوان رشته نسخه استفاده کنید",
"releaseDateAsVersionExplanation": "این گزینه فقط باید برای برنامه هایی استفاده شود که تشخیص نسخه به درستی کار نمی کند، اما تاریخ انتشار در دسترس است.",
"changes": "تغییرات",
"releaseDate": "تاریخ انتشار",
@@ -257,6 +256,7 @@
"intermediateLink": "پیوند میانی",
"exemptFromBackgroundUpdates": "معاف از به‌روزرسانی‌های پس‌زمینه (در صورت فعال بودن)",
"bgUpdatesOnWiFiOnly": "به‌روزرسانی‌های پس‌زمینه را در صورت عدم اتصال به WiFi غیرفعال کنید",
"bgUpdatesWhileChargingOnly": "به‌روزرسانی‌های پس‌زمینه را هنگام شارژ نشدن غیرفعال کنید",
"autoSelectHighestVersionCode": "انتخاب خودکار بالاترین نسخه کد APK",
"versionExtractionRegEx": "نسخه استخراج RegEx",
"trimVersionString": "برش رشته نسخه با RegEx",
@@ -313,8 +313,12 @@
"beforeNewInstallsShareToAppVerifier": "اشتراک‌گذاری برنامه‌های جدید با AppVerifier (در صورت وجود)",
"appVerifierInstructionToast": "در AppVerifier به اشتراک بگذارید، سپس پس از آماده شدن به اینجا برگردید.",
"wiki": "راهنما/ویکی",
"crowdsourcedConfigsLabel": "تنظیمات برنامه Crowdsourced (با مسئولیت خود استفاده کنید)",
"crowdsourcedConfigsLabel": "تنظیمات برنامه های مشارکت جمعی (با مسئولیت خود استفاده کنید)",
"crowdsourcedConfigsShort": "تنظیمات برنامه های مشارکت جمعی",
"allowInsecure": "درخواست های HTTP ناامن را مجاز کنید",
"stayOneVersionBehind": "یک نسخه از آخرین نسخه پشت سر بگذارید",
"refreshBeforeDownload": "قبل از دانلود، جزئیات برنامه را بازخوانی کنید",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "برنامه حذف شود؟",
"other": "برنامه ها حذف شوند؟"

View File

@@ -25,11 +25,11 @@
"standard": "Standard",
"custom": "Personnalisé",
"useMaterialYou": "Utiliser Material You",
"githubStarredRepos": "Dépôts étoilés GitHub",
"githubStarredRepos": "dépôts étoilés GitHub",
"uname": "Nom d'utilisateur",
"wrongArgNum": "Nombre incorrect des arguments fournis",
"xIsTrackOnly": "{} en Suivi uniquement",
"source": "Source",
"source": "source",
"app": "Application",
"appsFromSourceAreTrackOnly": "Les applications de cette source sont en 'Suivi uniquement'.",
"youPickedTrackOnly": "Vous avez sélectionné l'option 'Suivi uniquement'.",
@@ -37,7 +37,7 @@
"cancelled": "Annulé",
"appAlreadyAdded": "Application déjà ajoutée",
"alreadyUpToDateQuestion": "L'application est à jour?",
"addApp": "Ajouter Appli",
"addApp": "Ajouter appli",
"appSourceURL": "URL source de l'application",
"error": "Erreur",
"add": "Ajouter",
@@ -60,7 +60,7 @@
"deselectX": "Déselectionner {}",
"xWillBeRemovedButRemainInstalled": "{} sera supprimée d'Obtainium mais restera installée sur l'appareil.",
"removeSelectedAppsQuestion": "Supprimer les applications sélectionnées ?",
"removeSelectedApps": "Les applications sélectionnées ont été supprimées",
"removeSelectedApps": "Supprimer les applications sélectionnées",
"updateX": "Mettre à jour {}",
"installX": "Installer {}",
"markXTrackOnlyAsUpdated": "Marquer {}\n(Suivi uniquement)\ncomme étant à jour",
@@ -78,7 +78,7 @@
"customLinkMessage": "Ces liens fonctionnent sur les appareils sur lesquels Obtainium est installé",
"shareAppConfigLinks": "Partager la configuration de l'application sous forme de lien HTML",
"shareSelectedAppURLs": "Partager les URL des applications sélectionnées",
"resetInstallStatus": "L'état d'installation des applications a été réinitialisé",
"resetInstallStatus": "Réinitialiser l'état d'installation des applications",
"more": "Plus",
"removeOutdatedFilter": "Supprimer le filtre des applications obsolètes",
"showOutdatedOnly": "Afficher uniquement les applications obsolètes",
@@ -88,18 +88,18 @@
"author": "Auteur",
"upToDateApps": "Applications à jour",
"nonInstalledApps": "Applications non installées",
"importExport": "Importer/Exporter",
"importExport": "Importer/exporter",
"settings": "Paramètres",
"exportedTo": "Exporté vers {}",
"obtainiumExport": "Exporter Obtainium",
"obtainiumExport": "Exporter la configuration d'Obtainium",
"invalidInput": "Entrée invalide",
"importedX": "Importé {}",
"obtainiumImport": "Importer sur Obtainium",
"obtainiumImport": "Importer la configuration sur Obtainium",
"importFromURLList": "Importer depuis une liste d'URL",
"searchQuery": "Requête de recherche",
"appURLList": "Liste d'URL de l'application",
"line": "Ligne",
"searchX": "Rechercher {}",
"searchX": "Sélectionner {}",
"noResults": "Aucun résultat",
"importX": "Importation de {}",
"importedAppsIdDisclaimer": "Les applications importées peuvent s'afficher de manière incorrecte comme étant \"Non installées\".\nPour résoudre ce problème, réinstallez-les via Obtainium.\nCela n'affectera pas les données des applications.\n\nN'affecte que les méthodes d'importation d'URL et par des tiers.",
@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Aucune application n'a été trouvée avec cet identifiant ou ce nom",
"reposHaveMultipleApps": "Les dépôts peuvent contenir plusieurs applications",
"fdroidThirdPartyRepo": "Dépôt tiers F-Droid",
"steamMobile": "Application mobile Steam",
"steamChat": "Steam Chat",
"install": "Installer",
"markInstalled": "Marquer comme étant installé",
"update": "Mettre à jour",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Désinstaller de l'appareil",
"onlyWorksWithNonVersionDetectApps": "Ne fonctionne que pour les applications dont la détection de la version est désactivée.",
"releaseDateAsVersion": "Utiliser la date de sortie comme version",
"releaseTitleAsVersion": "Utiliser le titre de la version comme chaîne de caractères de la version",
"releaseDateAsVersionExplanation": "Cette option ne doit être utilisée que pour les applications pour lesquelles la détection de la version ne fonctionne pas correctement, mais dont une date de sortie est disponible.",
"changes": "Modifications",
"releaseDate": "Date de sortie",
@@ -257,6 +256,7 @@
"intermediateLink": "Lien intermédiaire",
"exemptFromBackgroundUpdates": "Exclure de la mise à jour en arrière-plan (si activé)",
"bgUpdatesOnWiFiOnly": "Désactiver les mises à jour en arrière-plan lorsque vous n'êtes pas en WiFi",
"bgUpdatesWhileChargingOnly": "Désactiver les mises à jour en arrière-plan lorsque le véhicule n'est pas en charge",
"autoSelectHighestVersionCode": "Sélectionner automatiquement la version la plus récente du code APK",
"versionExtractionRegEx": "Extraire la version par Expression régulière",
"trimVersionString": "Découper la version par Expression régulière",
@@ -313,8 +313,12 @@
"beforeNewInstallsShareToAppVerifier": "Partager les nouvelles applications avec AppVerifier (si disponible)",
"appVerifierInstructionToast": "Partagez avec AppVerifier, puis revenez ici lorsque tout est prêt.",
"wiki": "Aide/Wiki",
"crowdsourcedConfigsLabel": "Configurations d'applications par la communauté (à utiliser à vos risques et périls)",
"crowdsourcedConfigsLabel": "Configuration d'applis communautaires (à utiliser à vos risques et périls)",
"crowdsourcedConfigsShort": "Applis communautaires",
"allowInsecure": "Autoriser les requêtes HTTP non sécurisées",
"stayOneVersionBehind": "Rester à une version de la dernière",
"refreshBeforeDownload": "Actualiser les détails de l'application avant de la télécharger",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Supprimer l'application?",
"other": "Supprimer les applications?"

View File

@@ -9,7 +9,7 @@
"placeholder": "Helyőrző",
"someErrors": "Néhány hiba történt",
"unexpectedError": "Váratlan hiba",
"ok": "Rendben",
"ok": "OK",
"and": "és",
"githubPATLabel": "GitHub személyes hozzáférési token (megnöveli a lekérdezés-korlátozást)",
"includePrereleases": "Tartalmazza az előzetes kiadásokat",
@@ -61,10 +61,10 @@
"xWillBeRemovedButRemainInstalled": "A(z) {} el lesz távolítva az Obtainiumból, de továbbra is telepítve marad az eszközön.",
"removeSelectedAppsQuestion": "A kiválasztott alkalmazások eltávolítása?",
"removeSelectedApps": "A kiválasztott alkalmazások eltávolítása",
"updateX": "A(z) {} frissítése",
"installX": "A(z) {} telepítése",
"updateX": "{} frissítése",
"installX": "{} telepítése",
"markXTrackOnlyAsUpdated": "Megjelölés: {}\n(Csak nyomonkövetés)\nFrissítettként",
"changeX": "{} változtatás",
"changeX": "{}-változás",
"installUpdateApps": "Alkalmazások telepítése/frissítése",
"installUpdateSelectedApps": "A kiválasztott alkalmazások telepítése/frissítése",
"markXSelectedAppsAsUpdated": "A(z) {} kiválasztott alkalmazás megjelölése frissítettként?",
@@ -80,7 +80,7 @@
"shareSelectedAppURLs": "A kiválasztott alkalmazás hivatkozásának megosztása",
"resetInstallStatus": "Telepítési állapot visszaállítása",
"more": "További",
"removeOutdatedFilter": "Elavult-alkalmazás szűrő eltávolítása",
"removeOutdatedFilter": "Elavult alkalmazás-szűrő eltávolítása",
"showOutdatedOnly": "Csak az elavult alkalmazások megjelenítése",
"filter": "Szűrő",
"filterApps": "Alkalmazások szűrése",
@@ -115,11 +115,11 @@
"followSystem": "Rendszerbeállítás használata",
"followSystemThemeExplanation": "A következő rendszer téma csak harmadik féltől származó alkalmazások használatával lehetséges",
"useBlackTheme": "Használjon teljesen fekete sötét témát",
"appSortBy": "Elrendezés",
"appSortBy": "Rendezési szempont",
"authorName": "Szerző/Név",
"nameAuthor": "Név/Szerző",
"asAdded": "Hozzáadás dátuma",
"appSortOrder": "Elrendezés sorrendje",
"appSortOrder": "Rendezési sorrend",
"ascending": "Növekvő",
"descending": "Csökkenő",
"bgUpdateCheckInterval": "Időtartam a frissítések háttérellenőrzése között",
@@ -151,20 +151,20 @@
"appsUpdatedNotifDescription": "Értesíti a felhasználót, hogy egy vagy több alkalmazás frissítése a háttérben történt.",
"xWasUpdatedToY": "A(z) {} frissítve lett a következőre: {}.",
"xWasNotUpdatedToY": "Nem sikerült frissíteni a következőt: {}, erre: {}.",
"errorCheckingUpdates": "Hiba a frissítések keresésekor",
"errorCheckingUpdatesNotifDescription": "Értesítés, amely akkor jelenik meg, ha a háttérfrissítés ellenőrzése nem sikerül",
"errorCheckingUpdates": "Hiba a frissítések ellenőrzésekor",
"errorCheckingUpdatesNotifDescription": "Értesítés, amely akkor jelenik meg, amikor a frissítések ellenőrzése a háttérben nem sikerül",
"appsRemoved": "Alkalmazások eltávolítva",
"appsRemovedNotifDescription": "Értesíti a felhasználót, hogy egy vagy több alkalmazás betöltés közbeni hiba miatt eltávolításra került",
"xWasRemovedDueToErrorY": "A(z) {} eltávolításra került a következő hiba miatt: {}",
"completeAppInstallation": "Teljes alkalmazástelepítés",
"obtainiumMustBeOpenToInstallApps": "Az alkalmazások telepítéséhez az Obtainiumnak megnyitva kell lennie",
"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",
"checkingForUpdatesNotifDescription": "Átmeneti értesítés, amely a frissítések keresésekor jelenik meg",
"checkingForUpdates": "Frissítések ellenőrzése",
"checkingForUpdatesNotifDescription": "Átmeneti értesítés, amely a frissítések ellenőrzésekor jelenik meg",
"pleaseAllowInstallPerm": "Engedélyezze az Obtainiumnak az alkalmazások telepítését",
"trackOnly": "Csak nyomonkövetés",
"errorWithHttpStatusCode": "Hiba {}",
"versionCorrectionDisabled": "Verziókorrekció letiltva (úgy tűnik, hogy a bővítmény nem működik)",
"versionCorrectionDisabled": "Verzió-korrekció letiltva (úgy tűnik, hogy a bővítmény nem működik)",
"unknown": "Ismeretlen",
"none": "Semmi",
"never": "Soha",
@@ -179,22 +179,20 @@
"appWithIdOrNameNotFound": "Nem található alkalmazás ezzel az azonosítóval vagy névvel",
"reposHaveMultipleApps": "A tárolók több alkalmazást is tartalmazhatnak",
"fdroidThirdPartyRepo": "F-Droid harmadik féltől származó tároló",
"steamMobile": "Steam Mobil",
"steamChat": "Steam Chat",
"install": "Telepítés",
"markInstalled": "Telepítettnek jelölés",
"update": "Frissítés",
"markUpdated": "Frissítettnek jelölés",
"additionalOptions": "További beállítások",
"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.",
"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.",
"downloadingX": "{} letöltése",
"downloadX": "{} letöltése",
"downloadedX": "{} letöltve",
"releaseAsset": "Kiadási csomag",
"downloadNotifDescription": "Értesíti a felhasználót az alkalmazás letöltésének előrehaladásáról",
"noAPKFound": "Nem található APK",
"noVersionDetection": "Nincs verzióérzékelés",
"noVersionDetection": "Nincs verzió-érzékelés",
"categorize": "Kategorizálás",
"categories": "Kategóriák",
"category": "Kategória",
@@ -211,15 +209,16 @@
"filterAPKsByRegEx": "Az APK-k szűrése reguláris kifejezéssel",
"removeFromObtainium": "Eltávolítás az Obtainiumból",
"uninstallFromDevice": "Eltávolítás az eszközről",
"onlyWorksWithNonVersionDetectApps": "Csak azoknál az alkalmazásoknál működik, amelyeknél a verzióérzékelés le van tiltva.",
"releaseDateAsVersion": "Használja a kiadás dátumát verzióként",
"releaseDateAsVersionExplanation": "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, de elérhető a kiadás dátuma.",
"changes": "Változások",
"onlyWorksWithNonVersionDetectApps": "Csak azoknál az alkalmazásoknál működik, amelyeknél a verzió-érzékelés le van tiltva.",
"releaseDateAsVersion": "Használja a kiadás dátumát verzió-karakterláncként",
"releaseTitleAsVersion": "Használja a kiadás címét verzió-karakterláncként",
"releaseDateAsVersionExplanation": "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, de elérhető a kiadás dátuma.",
"changes": "Változáslista",
"releaseDate": "Kiadás dátuma",
"importFromURLsInFile": "Importálás fájlban található webcímből (pl. OPML)",
"versionDetectionExplanation": "A verziókarakterlánc egyeztetése az rendszer által észlelt verzióval",
"versionDetection": "Verzióérzékelés",
"standardVersionDetection": "Alapértelmezett verzióérzékelés",
"versionDetectionExplanation": "A verzió-karakterlánc egyeztetése az rendszer által érzékelt verzióval",
"versionDetection": "Verzió-érzékelés",
"standardVersionDetection": "Alapértelmezett verzió-érzékelés",
"groupByCategory": "Csoportosítás kategória alapján",
"autoApkFilterByArch": "Ha lehetséges, próbálja CPU architektúra szerint szűrni az APK-kat",
"overrideSource": "Forrás felülírása",
@@ -230,11 +229,11 @@
"gitlabPATLabel": "GitLab személyes hozzáférési token",
"about": "Névjegy",
"requiresCredentialsInSettings": "A(z) {} alkalmazásnak további hitelesítő adatokra van szüksége (a beállításokban)",
"checkOnStart": "Frissítések keresése indításkor",
"checkOnStart": "Frissítések ellenőrzése az alkalmazás megnyitásakor",
"tryInferAppIdFromCode": "Próbálja meg kikövetkeztetni az alkalmazás azonosítóját a forráskódból",
"removeOnExternalUninstall": "A külsőleg eltávolított alkalmazások automatikus eltávolítása",
"pickHighestVersionCode": "A legmagasabb verziószámú APK automatikus kiválasztása",
"checkUpdateOnDetailPage": "Frissítések keresése az alkalmazás részleteit tartalmazó oldal megnyitásakor",
"checkUpdateOnDetailPage": "Frissítések ellenőrzése az alkalmazás részleteit tartalmazó oldal megnyitásakor",
"disablePageTransitions": "Lap áttűnési animációk letiltása",
"reversePageTransitions": "Fordított lap áttűnési animációk",
"minStarCount": "Minimális csillagozási szám",
@@ -256,36 +255,37 @@
"intermediateLinkNotFound": "Köztes hivatkozás nem található",
"intermediateLink": "Köztes hivatkozás",
"exemptFromBackgroundUpdates": "Mentes a háttérben történő frissítések alól (ha engedélyezett)",
"bgUpdatesOnWiFiOnly": "A háttérben futó frissítések letiltása, ha nincs Wi-Fi",
"autoSelectHighestVersionCode": "A legmagasabb verziószámú APK automatikus kiválasztása",
"versionExtractionRegEx": "Verziókarakterlánc-kivonatolása reguláris kifejezéssel",
"trimVersionString": "Verziókarakterlánc levágása reguláris kifejezéssel",
"bgUpdatesOnWiFiOnly": "Háttérfrissítések letiltása, amikor az eszköz nem csatlakozik a Wi-Fi-hez",
"bgUpdatesWhileChargingOnly": "Háttérfrissítések letiltása, amikor az eszköz nincs a töltőn",
"autoSelectHighestVersionCode": "A legmagasabb verziókódú APK automatikus kiválasztása",
"versionExtractionRegEx": "Verzió-karakterlánc kivonatolása reguláris kifejezéssel",
"trimVersionString": "Verzió-karakterlánc levágása reguláris kifejezéssel",
"matchGroupToUseForX": "A(z) „{}” esetén használandó csoport egyeztetése",
"matchGroupToUse": "Verziókarakterlánc-kivonatoláshoz használandó csoport reguláris kifejezéssel való egyeztetése",
"highlightTouchTargets": "A kevésbé nyilvánvaló érintési pontok kiemelése",
"pickExportDir": "Válassza ki a könyvtárat, ahová exportálni szeretne",
"autoExportOnChanges": "Automatikus exportálás a változások után",
"autoExportOnChanges": "Automatikus exportálás a változtatások után",
"includeSettings": "Tartalmazza a beállításokat",
"filterVersionsByRegEx": "Verziók szűrése reguláris kifejezéssel",
"trySelectingSuggestedVersionCode": "Próbálja ki a javasolt verziókódú APK-t",
"trySelectingSuggestedVersionCode": "Próbálja kiválasztani a „Javasolt verziókódú APK-t",
"dontSortReleasesList": "Az API-ból származó kiadási sorrend megőrzése",
"reverseSort": "Fordított elrendezés",
"reverseSort": "Fordított rendezés",
"takeFirstLink": "Vegye az első hivatkozást",
"skipSort": "Rendezés kihagyása",
"debugMenu": "Hibakereső menü",
"bgTaskStarted": "A háttérfeladat elindult ellenőrizze a naplókat.",
"runBgCheckNow": "Frissítések keresése a háttérben",
"versionExtractWholePage": "„Verziókarakterlánc-kivonatolása reguláris kifejezéssel” alkalmazása az egész oldalra",
"runBgCheckNow": "Frissítések ellenőrzése a háttérben most",
"versionExtractWholePage": "„Verzió-karakterlánc kivonatolása reguláris kifejezéssel” alkalmazása az egész oldalra",
"installing": "Telepítés",
"skipUpdateNotifications": "A frissítési értesítések kihagyása",
"updatesAvailableNotifChannel": "Frissítések érhetők el",
"appsUpdatedNotifChannel": "Alkalmazások frissítve",
"appsPossiblyUpdatedNotifChannel": "Megkísérelt alkalmazás-frissítések",
"errorCheckingUpdatesNotifChannel": "Hiba a frissítések keresésekor",
"errorCheckingUpdatesNotifChannel": "Hiba a frissítések ellenőrzésekor",
"appsRemovedNotifChannel": "Eltávolított alkalmazások",
"downloadingXNotifChannel": "A(z) {} letöltése",
"completeAppInstallationNotifChannel": "Teljes alkalmazás telepítés",
"checkingForUpdatesNotifChannel": "Frissítések keresése",
"checkingForUpdatesNotifChannel": "Frissítések ellenőrzése",
"onlyCheckInstalledOrTrackOnlyApps": "Csak a telepített és a csak nyomonkövethető alkalmazások frissítéseinek ellenőrzése",
"supportFixedAPKURL": "Támogatja a rögzített APK webcímeket",
"selectX": "{} kiválasztása",
@@ -296,7 +296,7 @@
"shizukuOldAndroidWithADB": "A Shizuku csak Android < 8.1 ADB-vel fut - frissítse az Androidot vagy használja a Sui-t helyette",
"shizukuPretendToBeGooglePlay": "Állítsa be a Google Playt telepítési forrásként (ha Shizukut használ)",
"useSystemFont": "A rendszer betűtípusának használata",
"useVersionCodeAsOSVersion": "Az alkalmazás verziókódjának használata a rendszer által észlelt verzióként",
"useVersionCodeAsOSVersion": "Az alkalmazás verziókódjának használata a rendszer által érzékelt verzióként",
"requestHeader": "Kérelemfejléc",
"useLatestAssetDateAsReleaseDate": "A kiadás dátumaként használja a legutóbbi csomagfeltöltést",
"defaultPseudoVersioningMethod": "Alapértelmezett pszeudoverziós módszer",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "Ossza meg az AppVerifierrel, majd térjen vissza ide, ha kész.",
"wiki": "Súgó/Wiki",
"crowdsourcedConfigsLabel": "Crowdsource-ből származó alkalmazások beállítása (saját felelősségére használja)",
"crowdsourcedConfigsShort": "Crowdsourced App Configs",
"allowInsecure": "Nem biztonságos HTTP-kérések engedélyezése",
"stayOneVersionBehind": "Maradjon egy verzióval a legújabb mögött",
"refreshBeforeDownload": "Az alkalmazás adatainak frissítése a letöltés előtt",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Eltávolítja az alkalmazást?",
"other": "Eltávolítja az alkalmazásokat?"
@@ -352,8 +356,8 @@
"other": "{} nap"
},
"clearedNLogsBeforeXAfterY": {
"one": "{n} napló törölve lett ({after} után és {before} előtt)",
"other": "{n} napló törölve lett ({after} után és {before} előtt)"
"one": "{n} napló törölve lett ({after} után, és {before} előtt)",
"other": "{n} napló törölve lett ({after} után, és {before} előtt)"
},
"xAndNMoreUpdatesAvailable": {
"one": "A(z) {} és 1 további alkalmazás frissítést kapott.",

View File

@@ -154,7 +154,7 @@
"errorCheckingUpdates": "Kesalahan dalam memeriksa pembaruan",
"errorCheckingUpdatesNotifDescription": "Notifikasi yang ditampilkan saat pemeriksaan pembaruan latar belakang gagal",
"appsRemoved": "Aplikasi dihapus",
"appsRemovedNotifDescription": "Memberi tahu pengguna bahwa aplikasi aplikasi dihapus karena kesalahan saat memuatnya",
"appsRemovedNotifDescription": "Memberi tahu pengguna bahwa aplikasi dihapus karena kesalahan saat memuatnya",
"xWasRemovedDueToErrorY": "{} dihapus karena kesalahan berikut: {}",
"completeAppInstallation": "Selesaikan pemasangan aplikasi",
"obtainiumMustBeOpenToInstallApps": "Obtainium harus terbuka untuk memasang aplikasi",
@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Tidak ada aplikasi yang ditemukan dengan ID atau nama tersebut",
"reposHaveMultipleApps": "Repositori dapat berisi beberapa aplikasi",
"fdroidThirdPartyRepo": "Repositori pihak ketiga F-Droid",
"steamMobile": "Steam Mobile",
"steamChat": "Obrolan Steam",
"install": "Pasang",
"markInstalled": "Tandai terpasang",
"update": "perbarui",
@@ -204,7 +202,7 @@
"categoryDeleteWarning": "Semua aplikasi dalam kategori yang dihapus akan diatur sebagai tidak terkategori.",
"addCategory": "Tambah kategori",
"label": "Label",
"language": "Language",
"language": "Bahasa",
"copiedToClipboard": "Disalin ke papan klip",
"storagePermissionDenied": "Izin penyimpanan ditolak",
"selectedCategorizeWarning": "Ini akan mengganti pengaturan kategori yang ada untuk aplikasi terpilih.",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Copot pemasangan dari perangkat",
"onlyWorksWithNonVersionDetectApps": "Hanya bekerja untuk aplikasi dengan pendeteksi versi yang nonaktif.",
"releaseDateAsVersion": "Gunakan tanggal rilis sebagai versi string",
"releaseTitleAsVersion": "Gunakan judul rilis sebagai string versi",
"releaseDateAsVersionExplanation": "Opsi ini hanya boleh digunakan untuk aplikasi dengan pendeteksi versi yang tidak berfungsi dengan benar, tetapi tanggal rilisnya tersedia.",
"changes": "Perubahan",
"releaseDate": "Tanggal rilis",
@@ -231,8 +230,8 @@
"about": "Tentang",
"requiresCredentialsInSettings": "{} memerlukan kredensial tambahan (dalam pengaturan)",
"checkOnStart": "Periksa pembaruan saat proses memulai",
"tryInferAppIdFromCode": "Coba simpulkan ID aplikasi dari kode sumber",
"removeOnExternalUninstall": "Secara otomatis menghapus aplikasi yang dicopot pemasangannya dari luar",
"tryInferAppIdFromCode": "Coba untuk menebak ID aplikasi dari kode sumber",
"removeOnExternalUninstall": "Hapus otomatis aplikasi yang dicopot pemasangannya dari luar",
"pickHighestVersionCode": "Pilih otomatis APK dengan versi kode tertinggi",
"checkUpdateOnDetailPage": "Periksa pembaruan saat membuka halaman detail aplikasi",
"disablePageTransitions": "Nonaktifkan animasi transisi halaman",
@@ -257,7 +256,8 @@
"intermediateLink": "Tautan perantara",
"exemptFromBackgroundUpdates": "Dikecualikan dari pembaruan latar belakang (jika diaktifkan)",
"bgUpdatesOnWiFiOnly": "Nonaktifkan pembaruan latar belakang saat tidak menggunakan WiFi",
"autoSelectHighestVersionCode": "Secara otomatis pilih APK dengan versi kode tertinggi",
"bgUpdatesWhileChargingOnly": "Menonaktifkan pembaruan latar belakang saat tidak mengisi daya",
"autoSelectHighestVersionCode": "Pilih otomatis APK dengan versi kode tertinggi",
"versionExtractionRegEx": "Reguler ekspresi terkait ekstraksi versi string",
"trimVersionString": "Potong versi string dengan reguler ekspresi",
"matchGroupToUseForX": "Cocokkan grup yang akan digunakan untuk \"{}\"",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "Bagikan ke AppVerifier, lalu kembali ke sini jika sudah siap.",
"wiki": "Bantuan/Wiki",
"crowdsourcedConfigsLabel": "Konfigurasi aplikasi Crowdsourced (risiko penggunaan ditanggung sendiri)",
"crowdsourcedConfigsShort": "Konfigurasi Aplikasi Crowdsourced",
"allowInsecure": "Izinkan permintaan HTTP yang tidak aman",
"stayOneVersionBehind": "Tetap satu versi di belakang versi terbaru",
"refreshBeforeDownload": "Segarkan detail aplikasi sebelum mengunduh",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Hapus aplikasi?",
"other": "Hapus aplikasi?"
@@ -356,8 +360,8 @@
"other": "Menghapus {n} catatan (sebelum = {before}, setelah = {after})"
},
"xAndNMoreUpdatesAvailable": {
"one": "{} dan 1 aplikasi lainnya mendapat pembaruan.",
"other": "{} dan {} aplikasi lainnya mendapat pembaruan."
"one": "{} dan 1 aplikasi lainnya memiliki pembaruan.",
"other": "{} dan {} aplikasi lainnya memiliki pembaruan."
},
"xAndNMoreUpdatesInstalled": {
"one": "{} dan 1 aplikasi lainnya telah diperbarui.",
@@ -375,4 +379,4 @@
"one": "{} APK",
"other": "{} APK"
}
}
}

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Non è stata trovata alcuna app con quell'ID o nome",
"reposHaveMultipleApps": "I repository possono contenere più app",
"fdroidThirdPartyRepo": "Repository F-Droid di terze parti",
"steamMobile": "Mobile a vapore",
"steamChat": "Chat di vapore",
"install": "Installa",
"markInstalled": "Contrassegna come installata",
"update": "Aggiorna",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Disinstalla dal dispositivo",
"onlyWorksWithNonVersionDetectApps": "Funziona solo per le app con il rilevamento della versione disattivato.",
"releaseDateAsVersion": "Usa data di rilascio come versione",
"releaseTitleAsVersion": "Usa il titolo della versione come stringa di versione",
"releaseDateAsVersionExplanation": "Questa opzione dovrebbe essere usata solo per le app in cui il rilevamento della versione non funziona correttamente, ma è disponibile una data di rilascio.",
"changes": "Novità",
"releaseDate": "Data di rilascio",
@@ -257,6 +256,7 @@
"intermediateLink": "Collegamento intermedio",
"exemptFromBackgroundUpdates": "Esente da aggiornamenti in secondo piano (se attivo)",
"bgUpdatesOnWiFiOnly": "Disattiva aggiornamenti in secondo piano quando non si usa il WiFi",
"bgUpdatesWhileChargingOnly": "Disabilita gli aggiornamenti in background quando non è in carica",
"autoSelectHighestVersionCode": "Auto-seleziona APK con versionCode più alto",
"versionExtractionRegEx": "RegEx di estrazione versione",
"trimVersionString": "Tagliare la stringa della versione con RegEx",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "Condividete con AppVerifier, quindi tornate qui quando siete pronti.",
"wiki": "Aiuto/Wiki",
"crowdsourcedConfigsLabel": "Configurazioni di app in crowdsourcing (uso a proprio rischio)",
"crowdsourcedConfigsShort": "Configurazioni di app in crowdsourcing",
"allowInsecure": "Consentire le richieste HTTP non sicure",
"stayOneVersionBehind": "Rimanere una versione indietro rispetto alla più recente",
"refreshBeforeDownload": "Aggiornare i dettagli dell'app prima del download",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Rimuovere l'app?",
"other": "Rimuovere le app?"

View File

@@ -147,21 +147,21 @@
"noNewUpdates": "新しいアップデートはありません",
"xHasAnUpdate": "{} のアップデートが利用可能です。",
"appsUpdated": "アプリをアップデートしました",
"appsNotUpdated": "アプリケーションの更新に失敗",
"appsNotUpdated": "アプリのアップデートに失敗しました",
"appsUpdatedNotifDescription": "1つまたは複数のAppのアップデートがバックグラウンドで適用されたことをユーザーに通知する",
"xWasUpdatedToY": "{} が {} にアップデートされました",
"xWasNotUpdatedToY": "への更新に失敗しました",
"xWasNotUpdatedToY": "{} の {} へのアップデートに失敗しました",
"errorCheckingUpdates": "アップデート確認中のエラー",
"errorCheckingUpdatesNotifDescription": "バックグラウンドでのアップデート確認に失敗した際に表示される通知",
"appsRemoved": "削除されたアプリ",
"appsRemovedNotifDescription": "アプリの読み込み中にエラーが発生したため、1つまたは複数のアプリが削除されたことをユーザーに通知する",
"xWasRemovedDueToErrorY": "このエラーのため、{} は削除されました: {}",
"completeAppInstallation": "アプリのインストールを完了する",
"obtainiumMustBeOpenToInstallApps": "アプリをインストールするにはObtainiumが開いている必要があります",
"obtainiumMustBeOpenToInstallApps": "アプリをインストールするにはObtainiumを開く必要があります",
"completeAppInstallationNotifDescription": "アプリのインストールを完了するために、Obtainiumに戻る必要があります",
"checkingForUpdates": "アップデートを確認中",
"checkingForUpdatesNotifDescription": "アップデートを確認する際に表示される一時的な通知",
"pleaseAllowInstallPerm": "Obtainiumによるアプリのインストールを許可してください",
"pleaseAllowInstallPerm": "Obtainiumによるアプリのインストールを許可してください",
"trackOnly": "追跡のみ",
"errorWithHttpStatusCode": "エラー {}",
"versionCorrectionDisabled": "バージョン補正無効 (プラグインが動作していません)",
@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "そのIDや名前を持つアプリは見つかりませんでした",
"reposHaveMultipleApps": "リポジトリには複数のアプリが含まれることがあります",
"fdroidThirdPartyRepo": "F-Droid サードパーティリポジトリ",
"steamMobile": "Steamモバイル",
"steamChat": "Steamチャット",
"install": "インストール",
"markInstalled": "インストール済みとしてマークする",
"update": "アップデート",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "デバイスからアンインストールする",
"onlyWorksWithNonVersionDetectApps": "バージョン検出を無効にしているアプリにのみ動作します。",
"releaseDateAsVersion": "リリース日をバージョンとして使用する",
"releaseTitleAsVersion": "リリースタイトルをバージョンとして使用する",
"releaseDateAsVersionExplanation": "このオプションは、バージョン検出が正しく機能しないアプリで、リリース日が利用可能な場合にのみ使用する必要があります。",
"changes": "変更点",
"releaseDate": "リリース日",
@@ -257,6 +256,7 @@
"intermediateLink": "中間リンク",
"exemptFromBackgroundUpdates": "バックグラウンドアップデートを行わない (有効な場合)",
"bgUpdatesOnWiFiOnly": "WiFiを使用していない場合、バックグラウンドアップデートを無効にする",
"bgUpdatesWhileChargingOnly": "非充電時にバックグラウンドアップデートを無効にする",
"autoSelectHighestVersionCode": "最も高いバージョンコードのAPKを自動で選択する",
"versionExtractionRegEx": "バージョン抽出の正規表現",
"trimVersionString": "正規表現でバージョン文字列をトリムする",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "AppVerifierに共有し、準備ができたらここに戻ってください。",
"wiki": "ヘルプ/ウィキ",
"crowdsourcedConfigsLabel": "クラウドソーシングによるアプリの設定(利用は自己責任で)",
"crowdsourcedConfigsShort": "クラウドソーシングによるアプリの設定",
"allowInsecure": "安全でないHTTPリクエストを許可する",
"stayOneVersionBehind": "最新のバージョンから1つ前のものを使用する",
"refreshBeforeDownload": "ダウンロード前にアプリの詳細を更新する",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "アプリを削除しますか?",
"other": "アプリを削除しますか?"
@@ -356,23 +360,23 @@
"other": "{n} 個のログをクリアしました (前 = {before}, 後 = {after})"
},
"xAndNMoreUpdatesAvailable": {
"one": "{} とさらに {} 個のアプリのアップデートが利用可能です。",
"one": "{} とさらに 1 個のアプリのアップデートが利用可能です。",
"other": "{} とさらに {} 個のアプリのアップデートが利用可能です。"
},
"xAndNMoreUpdatesInstalled": {
"one": "{} とさらに {} 個のアプリがアップデートされました。",
"one": "{} とさらに 1 個のアプリがアップデートされました。",
"other": "{} とさらに {} 個のアプリがアップデートされました。"
},
"xAndNMoreUpdatesFailed": {
"one": "更新に失敗しました。",
"other": "アプリのアップデートに失敗しました。"
"one": "{} とさらに 1 個のアプリのアップデートに失敗しました。",
"other": "{} とさらに {} 個のアプリのアップデートに失敗しました。"
},
"xAndNMoreUpdatesPossiblyInstalled": {
"one": "{} とさらに 1 個のアプリがアップデートされた可能性があります。",
"other": "{} とさらに {} 個のアプリがアップデートされた可能性があります。"
},
"apk": {
"one": "{}APK",
"other": "{}APK"
"one": "{} APK",
"other": "{} APK"
}
}

382
assets/translations/ko.json Normal file
View File

@@ -0,0 +1,382 @@
{
"invalidURLForSource": "유효한 {} 앱 URL이 아닙니다",
"noReleaseFound": "적절한 릴리스를 찾을 수 없습니다",
"noVersionFound": "릴리스 버전을 결정할 수 없습니다",
"urlMatchesNoSource": "URL이 알려진 소스와 일치하지 않습니다",
"cantInstallOlderVersion": "앱의 이전 버전을 설치할 수 없습니다",
"appIdMismatch": "다운로드된 패키지 ID가 기존 앱 ID와 일치하지 않습니다",
"functionNotImplemented": "이 클래스는 이 기능을 구현하지 않았습니다",
"placeholder": "플레이스홀더",
"someErrors": "일부 오류가 발생했습니다",
"unexpectedError": "예기치 않은 오류",
"ok": "확인",
"and": "그리고",
"githubPATLabel": "GitHub 개인 액세스 토큰 (속도 제한 증가)",
"includePrereleases": "사전 릴리스 포함",
"fallbackToOlderReleases": "이전 릴리스로 대체",
"filterReleaseTitlesByRegEx": "정규 표현식으로 릴리스 제목 필터링",
"invalidRegEx": "잘못된 정규 표현식",
"noDescription": "설명 없음",
"cancel": "취소",
"continue": "계속",
"requiredInBrackets": "(필수)",
"dropdownNoOptsError": "오류: 드롭다운에는 최소 하나의 옵션이 있어야 합니다",
"colour": "색상",
"standard": "표준",
"custom": "사용자 정의",
"useMaterialYou": "Material You 사용",
"githubStarredRepos": "GitHub 즐겨찾기 저장소",
"uname": "사용자 이름",
"wrongArgNum": "잘못된 인수 수 제공",
"xIsTrackOnly": "{}는 추적 전용입니다",
"source": "소스",
"app": "앱",
"appsFromSourceAreTrackOnly": "이 소스의 앱은 '추적 전용'입니다.",
"youPickedTrackOnly": "당신은 '추적 전용' 옵션을 선택했습니다.",
"trackOnlyAppDescription": "앱은 업데이트를 위해 추적되지만 Obtainium은 다운로드하거나 설치할 수 없습니다.",
"cancelled": "취소됨",
"appAlreadyAdded": "앱이 이미 추가되었습니다",
"alreadyUpToDateQuestion": "앱이 이미 최신 상태입니까?",
"addApp": "앱 추가",
"appSourceURL": "앱 소스 URL",
"error": "오류",
"add": "추가",
"searchSomeSourcesLabel": "검색 (일부 소스만)",
"search": "검색",
"additionalOptsFor": "{}에 대한 추가 옵션",
"supportedSources": "지원되는 소스",
"trackOnlyInBrackets": "(추적 전용)",
"searchableInBrackets": "(검색 가능)",
"appsString": "앱",
"noApps": "앱 없음",
"noAppsForFilter": "필터에 대한 앱 없음",
"byX": "{}에 의해",
"percentProgress": "진행률: {}%",
"pleaseWait": "기다려 주세요",
"updateAvailable": "업데이트 가능",
"notInstalled": "설치되지 않음",
"pseudoVersion": "의사 버전",
"selectAll": "모두 선택",
"deselectX": "{} 선택 해제",
"xWillBeRemovedButRemainInstalled": "{}는 Obtainium에서 제거되지만 장치에 설치된 상태로 남아 있습니다.",
"removeSelectedAppsQuestion": "선택한 앱을 제거하시겠습니까?",
"removeSelectedApps": "선택한 앱 제거",
"updateX": "{} 업데이트",
"installX": "{} 설치",
"markXTrackOnlyAsUpdated": "{}\n(추적 전용)\n업데이트됨으로 표시",
"changeX": "{} 변경",
"installUpdateApps": "앱 설치/업데이트",
"installUpdateSelectedApps": "선택한 앱 설치/업데이트",
"markXSelectedAppsAsUpdated": "{} 선택한 앱을 업데이트됨으로 표시하시겠습니까?",
"no": "아니요",
"yes": "예",
"markSelectedAppsUpdated": "선택한 앱을 업데이트됨으로 표시",
"pinToTop": "상단에 고정",
"unpinFromTop": "상단에서 고정 해제",
"resetInstallStatusForSelectedAppsQuestion": "선택한 앱의 설치 상태를 재설정하시겠습니까?",
"installStatusOfXWillBeResetExplanation": "선택한 앱의 설치 상태가 재설정됩니다.\n\n이것은 실패한 업데이트나 기타 문제로 인해 Obtainium에 표시된 앱 버전이 잘못된 경우에 도움이 될 수 있습니다.",
"customLinkMessage": "이 링크는 Obtainium이 설치된 장치에서 작동합니다",
"shareAppConfigLinks": "앱 구성 HTML 링크로 공유",
"shareSelectedAppURLs": "선택한 앱 URL 공유",
"resetInstallStatus": "설치 상태 재설정",
"more": "더보기",
"removeOutdatedFilter": "구식 앱 필터 제거",
"showOutdatedOnly": "구식 앱만 표시",
"filter": "필터",
"filterApps": "앱 필터",
"appName": "앱 이름",
"author": "저자",
"upToDateApps": "최신 상태의 앱",
"nonInstalledApps": "설치되지 않은 앱",
"importExport": "가져오기/내보내기",
"settings": "설정",
"exportedTo": "{}로 내보내기 완료",
"obtainiumExport": "Obtainium 내보내기",
"invalidInput": "잘못된 입력",
"importedX": "{} 가져오기 완료",
"obtainiumImport": "Obtainium 가져오기",
"importFromURLList": "URL 목록에서 가져오기",
"searchQuery": "검색 쿼리",
"appURLList": "앱 URL 목록",
"line": "줄",
"searchX": "{} 검색",
"noResults": "결과가 없습니다",
"importX": "{} 가져오기",
"importedAppsIdDisclaimer": "가져온 앱은 \"설치되지 않음\"으로 잘못 표시될 수 있습니다.\n이를 수정하려면 Obtainium을 통해 다시 설치하십시오.\n앱 데이터에는 영향을 미치지 않습니다.\n\nURL 및 타사 가져오기 방법에만 영향을 미칩니다.",
"importErrors": "가져오기 오류",
"importedXOfYApps": "{}개의 앱 중 {}개 가져오기 완료.",
"followingURLsHadErrors": "다음 URL에 오류가 있었습니다:",
"selectURL": "URL 선택",
"selectURLs": "URL 선택",
"pick": "선택",
"theme": "테마",
"dark": "다크",
"light": "라이트",
"followSystem": "시스템 따르기",
"followSystemThemeExplanation": "시스템 테마를 따르려면 타사 애플리케이션을 사용해야 합니다",
"useBlackTheme": "순수한 검은색 다크 테마 사용",
"appSortBy": "앱 정렬 기준",
"authorName": "저자/이름",
"nameAuthor": "이름/저자",
"asAdded": "추가된 순서대로",
"appSortOrder": "앱 정렬 순서",
"ascending": "오름차순",
"descending": "내림차순",
"bgUpdateCheckInterval": "백그라운드 업데이트 확인 간격",
"neverManualOnly": "절대 - 수동만",
"appearance": "외관",
"showWebInAppView": "앱 보기에서 소스 웹페이지 표시",
"pinUpdates": "앱 보기 상단에 업데이트 고정",
"updates": "업데이트",
"sourceSpecific": "소스별",
"appSource": "앱 소스",
"noLogs": "로그 없음",
"appLogs": "앱 로그",
"close": "닫기",
"share": "공유",
"appNotFound": "앱을 찾을 수 없습니다",
"obtainiumExportHyphenatedLowercase": "obtainium-export",
"pickAnAPK": "APK 선택",
"appHasMoreThanOnePackage": "{}에는 둘 이상의 패키지가 있습니다:",
"deviceSupportsXArch": "장치는 {} CPU 아키텍처를 지원합니다.",
"deviceSupportsFollowingArchs": "장치는 다음 CPU 아키텍처를 지원합니다:",
"warning": "경고",
"sourceIsXButPackageFromYPrompt": "앱 소스는 '{}'이지만 릴리스 패키지는 '{}'에서 제공됩니다. 계속하시겠습니까?",
"updatesAvailable": "업데이트 가능",
"updatesAvailableNotifDescription": "Obtainium이 추적하는 하나 이상의 앱에 대한 업데이트가 있음을 사용자에게 알립니다",
"noNewUpdates": "새로운 업데이트가 없습니다.",
"xHasAnUpdate": "{}에 업데이트가 있습니다.",
"appsUpdated": "앱 업데이트됨",
"appsNotUpdated": "앱 업데이트 실패",
"appsUpdatedNotifDescription": "백그라운드에서 하나 이상의 앱에 대한 업데이트가 적용되었음을 사용자에게 알립니다",
"xWasUpdatedToY": "{}가 {}로 업데이트되었습니다.",
"xWasNotUpdatedToY": "{}를 {}로 업데이트하지 못했습니다.",
"errorCheckingUpdates": "업데이트 확인 오류",
"errorCheckingUpdatesNotifDescription": "백그라운드 업데이트 확인이 실패할 때 표시되는 알림",
"appsRemoved": "앱 제거됨",
"appsRemovedNotifDescription": "로드 중 오류로 인해 하나 이상의 앱이 제거되었음을 사용자에게 알립니다",
"xWasRemovedDueToErrorY": "{}가 다음 오류로 인해 제거되었습니다: {}",
"completeAppInstallation": "앱 설치 완료",
"obtainiumMustBeOpenToInstallApps": "앱을 설치하려면 Obtainium이 열려 있어야 합니다",
"completeAppInstallationNotifDescription": "앱 설치를 완료하려면 Obtainium으로 돌아가도록 사용자에게 요청합니다",
"checkingForUpdates": "업데이트 확인 중",
"checkingForUpdatesNotifDescription": "업데이트 확인 시 나타나는 일시적인 알림",
"pleaseAllowInstallPerm": "Obtainium이 앱을 설치할 수 있도록 허용해 주세요",
"trackOnly": "추적 전용",
"errorWithHttpStatusCode": "오류 {}",
"versionCorrectionDisabled": "버전 수정 비활성화됨 (플러그인이 작동하지 않는 것 같습니다)",
"unknown": "알 수 없음",
"none": "없음",
"never": "절대",
"latestVersionX": "최신: {}",
"installedVersionX": "설치됨: {}",
"lastUpdateCheckX": "마지막 업데이트 확인: {}",
"remove": "제거",
"yesMarkUpdated": "예, 업데이트됨으로 표시",
"fdroid": "F-Droid 공식",
"appIdOrName": "앱 ID 또는 이름",
"appId": "앱 ID",
"appWithIdOrNameNotFound": "해당 ID 또는 이름의 앱을 찾을 수 없습니다",
"reposHaveMultipleApps": "저장소에는 여러 앱이 포함될 수 있습니다",
"fdroidThirdPartyRepo": "F-Droid 타사 저장소",
"install": "설치",
"markInstalled": "설치됨으로 표시",
"update": "업데이트",
"markUpdated": "업데이트됨으로 표시",
"additionalOptions": "추가 옵션",
"disableVersionDetection": "버전 감지 비활성화",
"noVersionDetectionExplanation": "이 옵션은 버전 감지가 올바르게 작동하지 않는 앱에만 사용해야 합니다.",
"downloadingX": "{} 다운로드 중",
"downloadX": "{} 다운로드",
"downloadedX": "{} 다운로드 완료",
"releaseAsset": "릴리스 자산",
"downloadNotifDescription": "앱 다운로드 진행 상황을 사용자에게 알립니다",
"noAPKFound": "APK를 찾을 수 없습니다",
"noVersionDetection": "버전 감지 없음",
"categorize": "분류",
"categories": "카테고리",
"category": "카테고리",
"noCategory": "카테고리 없음",
"noCategories": "카테고리 없음",
"deleteCategoriesQuestion": "카테고리를 삭제하시겠습니까?",
"categoryDeleteWarning": "삭제된 카테고리의 모든 앱은 미분류로 설정됩니다.",
"addCategory": "카테고리 추가",
"label": "레이블",
"language": "언어",
"copiedToClipboard": "클립보드에 복사됨",
"storagePermissionDenied": "저장소 권한 거부됨",
"selectedCategorizeWarning": "이 작업은 선택한 앱의 기존 카테고리 설정을 대체합니다.",
"filterAPKsByRegEx": "정규 표현식으로 APK 필터링",
"removeFromObtainium": "Obtainium에서 제거",
"uninstallFromDevice": "장치에서 제거",
"onlyWorksWithNonVersionDetectApps": "버전 감지가 비활성화된 앱에만 작동합니다.",
"releaseDateAsVersion": "릴리스 날짜를 버전 문자열로 사용",
"releaseTitleAsVersion": "릴리스 제목을 버전 문자열로 사용",
"releaseDateAsVersionExplanation": "이 옵션은 버전 감지가 올바르게 작동하지 않지만 릴리스 날짜가 있는 앱에만 사용해야 합니다.",
"changes": "변경 사항",
"releaseDate": "릴리스 날짜",
"importFromURLsInFile": "파일의 URL에서 가져오기 (OPML과 같은)",
"versionDetectionExplanation": "OS에서 감지된 버전과 버전 문자열 조정",
"versionDetection": "버전 감지",
"standardVersionDetection": "표준 버전 감지",
"groupByCategory": "카테고리별 그룹화",
"autoApkFilterByArch": "가능한 경우 CPU 아키텍처별로 APK 필터링 시도",
"overrideSource": "소스 재정의",
"dontShowAgain": "다시 표시하지 않기",
"dontShowTrackOnlyWarnings": "'추적 전용' 경고 표시 안 함",
"dontShowAPKOriginWarnings": "APK 출처 경고 표시 안 함",
"moveNonInstalledAppsToBottom": "설치되지 않은 앱을 앱 보기 하단으로 이동",
"gitlabPATLabel": "GitLab 개인 액세스 토큰",
"about": "정보",
"requiresCredentialsInSettings": "{}는 추가 자격 증명이 필요합니다 (설정에서)",
"checkOnStart": "시작 시 업데이트 확인",
"tryInferAppIdFromCode": "소스 코드에서 앱 ID 추론 시도",
"removeOnExternalUninstall": "외부에서 제거된 앱 자동 제거",
"pickHighestVersionCode": "가장 높은 버전 코드 APK 자동 선택",
"checkUpdateOnDetailPage": "앱 세부 정보 페이지 열 때 업데이트 확인",
"disablePageTransitions": "페이지 전환 애니메이션 비활성화",
"reversePageTransitions": "페이지 전환 애니메이션 반전",
"minStarCount": "최소 별 개수",
"addInfoBelow": "아래에 이 정보를 추가하십시오.",
"addInfoInSettings": "설정에 이 정보를 추가하십시오.",
"githubSourceNote": "GitHub 속도 제한은 API 키를 사용하여 피할 수 있습니다.",
"sortByLastLinkSegment": "링크의 마지막 세그먼트로만 정렬",
"filterReleaseNotesByRegEx": "정규 표현식으로 릴리스 노트 필터링",
"customLinkFilterRegex": "정규 표현식으로 사용자 정의 APK 링크 필터링 (기본값 '.apk$')",
"appsPossiblyUpdated": "앱 업데이트 시도됨",
"appsPossiblyUpdatedNotifDescription": "백그라운드에서 하나 이상의 앱에 대한 업데이트가 잠재적으로 적용되었음을 사용자에게 알립니다",
"xWasPossiblyUpdatedToY": "{}가 {}로 업데이트되었을 수 있습니다.",
"enableBackgroundUpdates": "백그라운드 업데이트 활성화",
"backgroundUpdateReqsExplanation": "모든 앱에 대해 백그라운드 업데이트가 가능하지 않을 수 있습니다.",
"backgroundUpdateLimitsExplanation": "백그라운드 설치의 성공 여부는 Obtainium이 열릴 때만 확인할 수 있습니다.",
"verifyLatestTag": "'최신' 태그 확인",
"intermediateLinkRegex": "'중간' 링크 방문 필터",
"filterByLinkText": "링크 텍스트로 링크 필터링",
"intermediateLinkNotFound": "중간 링크를 찾을 수 없습니다",
"intermediateLink": "중간 링크",
"exemptFromBackgroundUpdates": "백그라운드 업데이트에서 제외 (활성화된 경우)",
"bgUpdatesOnWiFiOnly": "WiFi가 아닐 때 백그라운드 업데이트 비활성화",
"bgUpdatesWhileChargingOnly": "충전 중이 아닐 때 백그라운드 업데이트 비활성화",
"autoSelectHighestVersionCode": "가장 높은 versionCode APK 자동 선택",
"versionExtractionRegEx": "버전 문자열 추출 정규 표현식",
"trimVersionString": "정규 표현식으로 버전 문자열 자르기",
"matchGroupToUseForX": "\"{}\"에 사용할 일치 그룹",
"matchGroupToUse": "버전 문자열 추출 정규 표현식에 사용할 일치 그룹",
"highlightTouchTargets": "덜 명확한 터치 대상 강조",
"pickExportDir": "내보내기 디렉토리 선택",
"autoExportOnChanges": "변경 시 자동 내보내기",
"includeSettings": "설정 포함",
"filterVersionsByRegEx": "정규 표현식으로 버전 필터링",
"trySelectingSuggestedVersionCode": "제안된 versionCode APK 선택 시도",
"dontSortReleasesList": "API에서 릴리스 순서 유지",
"reverseSort": "정렬 반전",
"takeFirstLink": "첫 번째 링크 선택",
"skipSort": "정렬 건너뛰기",
"debugMenu": "디버그 메뉴",
"bgTaskStarted": "백그라운드 작업 시작됨 - 로그를 확인하세요.",
"runBgCheckNow": "지금 백그라운드 업데이트 확인 실행",
"versionExtractWholePage": "전체 페이지에 버전 문자열 추출 정규 표현식 적용",
"installing": "설치 중",
"skipUpdateNotifications": "업데이트 알림 건너뛰기",
"updatesAvailableNotifChannel": "업데이트 가능",
"appsUpdatedNotifChannel": "앱 업데이트됨",
"appsPossiblyUpdatedNotifChannel": "앱 업데이트 시도됨",
"errorCheckingUpdatesNotifChannel": "업데이트 확인 오류",
"appsRemovedNotifChannel": "앱 제거됨",
"downloadingXNotifChannel": "{} 다운로드 중",
"completeAppInstallationNotifChannel": "앱 설치 완료",
"checkingForUpdatesNotifChannel": "업데이트 확인 중",
"onlyCheckInstalledOrTrackOnlyApps": "설치된 앱과 추적 전용 앱만 업데이트 확인",
"supportFixedAPKURL": "고정 APK URL 지원",
"selectX": "{} 선택",
"parallelDownloads": "병렬 다운로드 허용",
"useShizuku": "Shizuku 또는 Sui를 사용하여 설치",
"shizukuBinderNotFound": "Shizuku 서비스가 실행 중이 아닙니다",
"shizukuOld": "오래된 Shizuku 버전 (<11) - 업데이트 필요",
"shizukuOldAndroidWithADB": "ADB로 Android < 8.1에서 실행 중인 Shizuku - Android를 업데이트하거나 대신 Sui를 사용하세요",
"shizukuPretendToBeGooglePlay": "설치 소스로 Google Play 설정 (Shizuku 사용 시)",
"useSystemFont": "시스템 글꼴 사용",
"useVersionCodeAsOSVersion": "앱 versionCode를 OS에서 감지된 버전으로 사용",
"requestHeader": "요청 헤더",
"useLatestAssetDateAsReleaseDate": "최신 자산 업로드를 릴리스 날짜로 사용",
"defaultPseudoVersioningMethod": "기본 의사 버전 관리 방법",
"partialAPKHash": "부분 APK 해시",
"APKLinkHash": "APK 링크 해시",
"directAPKLink": "직접 APK 링크",
"pseudoVersionInUse": "의사 버전 사용 중",
"installed": "설치됨",
"latest": "최신",
"invertRegEx": "정규 표현식 반전",
"note": "노트",
"selfHostedNote": "\"{}\" 드롭다운을 사용하여 소스의 자체 호스팅/사용자 정의 인스턴스에 도달할 수 있습니다.",
"badDownload": "APK를 구문 분석할 수 없습니다 (호환되지 않거나 부분 다운로드)",
"beforeNewInstallsShareToAppVerifier": "새 앱을 AppVerifier와 공유 (가능한 경우)",
"appVerifierInstructionToast": "AppVerifier에 공유한 후 준비가 되면 여기로 돌아오세요.",
"wiki": "도움말/위키",
"crowdsourcedConfigsLabel": "크라우드소싱 앱 구성 (자신의 책임 하에 사용)",
"crowdsourcedConfigsShort": "크라우드소싱 앱 구성",
"allowInsecure": "안전하지 않은 HTTP 요청 허용",
"stayOneVersionBehind": "최신 버전보다 한 버전 뒤에 머무르기",
"refreshBeforeDownload": "다운로드 전에 앱 세부 정보 새로 고침",
"tencentAppStore": "텐센트 앱 스토어",
"removeAppQuestion": {
"one": "앱을 제거하시겠습니까?",
"other": "앱을 제거하시겠습니까?"
},
"tooManyRequestsTryAgainInMinutes": {
"one": "요청이 너무 많습니다 (속도 제한) - {}분 후에 다시 시도하세요",
"other": "요청이 너무 많습니다 (속도 제한) - {}분 후에 다시 시도하세요"
},
"bgUpdateGotErrorRetryInMinutes": {
"one": "BG 업데이트 확인 중 {} 오류가 발생했습니다. {}분 후에 다시 확인을 예약합니다",
"other": "BG 업데이트 확인 중 {} 오류가 발생했습니다. {}분 후에 다시 확인을 예약합니다"
},
"bgCheckFoundUpdatesWillNotifyIfNeeded": {
"one": "BG 업데이트 확인에서 {}개의 업데이트를 발견했습니다 - 필요 시 사용자에게 알립니다",
"other": "BG 업데이트 확인에서 {}개의 업데이트를 발견했습니다 - 필요 시 사용자에게 알립니다"
},
"apps": {
"one": "{} 앱",
"other": "{} 앱"
},
"url": {
"one": "{} URL",
"other": "{} URL"
},
"minute": {
"one": "{} 분",
"other": "{} 분"
},
"hour": {
"one": "{} 시간",
"other": "{} 시간"
},
"day": {
"one": "{} 일",
"other": "{} 일"
},
"clearedNLogsBeforeXAfterY": {
"one": "{n}개의 로그가 지워졌습니다 (이전 = {before}, 이후 = {after})",
"other": "{n}개의 로그가 지워졌습니다 (이전 = {before}, 이후 = {after})"
},
"xAndNMoreUpdatesAvailable": {
"one": "{} 및 1개의 앱에 업데이트가 있습니다.",
"other": "{} 및 {}개의 앱에 업데이트가 있습니다."
},
"xAndNMoreUpdatesInstalled": {
"one": "{} 및 1개의 앱이 업데이트되었습니다.",
"other": "{} 및 {}개의 앱이 업데이트되었습니다."
},
"xAndNMoreUpdatesFailed": {
"one": "{} 및 1개의 앱 업데이트에 실패했습니다.",
"other": "{} 및 {}개의 앱 업데이트에 실패했습니다."
},
"xAndNMoreUpdatesPossiblyInstalled": {
"one": "{} 및 1개의 앱이 업데이트되었을 수 있습니다.",
"other": "{} 및 {}개의 앱이 업데이트되었을 수 있습니다."
},
"apk": {
"one": "{} APK",
"other": "{} APK"
}
}

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Er is geen app gevonden met dat ID of die naam",
"reposHaveMultipleApps": "Repositories kunnen meerdere apps bevatten",
"fdroidThirdPartyRepo": "F-Droid Repository voor derden",
"steamMobile": "Steam Mobile",
"steamChat": "Steam Chat",
"install": "Installeren",
"markInstalled": "Als geïnstalleerd markeren",
"update": "Bijwerken",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Van apparaat verwijderen",
"onlyWorksWithNonVersionDetectApps": "Werkt alleen voor apps waarbij versieherkenning is uitgeschakeld.",
"releaseDateAsVersion": "Releasedatum als versie gebruiken",
"releaseTitleAsVersion": "Gebruik releasetitel als versiestring",
"releaseDateAsVersionExplanation": "Deze optie moet alleen worden gebruikt voor apps waar versieherkenning niet correct werkt, maar waar wel een releasedatum beschikbaar is.",
"changes": "Aanpassingen",
"releaseDate": "Releasedatum",
@@ -257,6 +256,7 @@
"intermediateLink": "Intermediaire link",
"exemptFromBackgroundUpdates": "Vrijgesteld van achtergrond-updates (indien ingeschakeld)",
"bgUpdatesOnWiFiOnly": "Achtergrond-updates uitschakelen wanneer niet verbonden met WiFi",
"bgUpdatesWhileChargingOnly": "Achtergrondupdates uitschakelen als er niet wordt opgeladen",
"autoSelectHighestVersionCode": "De APK met de hoogste versiecode automatisch selecteren",
"versionExtractionRegEx": "Reguliere expressie voor versie-extractie",
"trimVersionString": "Versie string trimmen met RegEx",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "Deel het met AppVerifier en keer daarna hier terug.",
"wiki": "Help/Wiki",
"crowdsourcedConfigsLabel": "Crowdsourced App-configuraties (gebruik op eigen risico)",
"crowdsourcedConfigsShort": "App-configuraties door menigte",
"allowInsecure": "Onveilige HTTP-verzoeken toestaan",
"stayOneVersionBehind": "Blijf een versie achter op de nieuwste",
"refreshBeforeDownload": "Vernieuw app details voor download",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "App verwijderen?",
"other": "Apps verwijderen?"

View File

@@ -6,7 +6,7 @@
"cantInstallOlderVersion": "Nie można zainstalować starszej wersji aplikacji",
"appIdMismatch": "Pobrane ID pakietu nie pasuje do istniejącego ID aplikacji",
"functionNotImplemented": "Ta klasa nie zaimplementowała tej funkcji",
"placeholder": "Zbiornik",
"placeholder": "Placeholder",
"someErrors": "Wystąpiły pewne błędy",
"unexpectedError": "Nieoczekiwany błąd",
"ok": "Okej",
@@ -22,9 +22,9 @@
"requiredInBrackets": "(Wymagane)",
"dropdownNoOptsError": "BŁĄD: LISTA ROZWIJANA MUSI MIEĆ CO NAJMNIEJ JEDNĄ OPCJĘ",
"colour": "Kolor",
"standard": "Standard",
"custom": "Niestandardowe",
"useMaterialYou": "Używaj materiałów",
"standard": "Domyślny",
"custom": "Własny",
"useMaterialYou": "Material You",
"githubStarredRepos": "Repozytoria GitHub oznaczone gwiazdką",
"uname": "Nazwa użytkownika",
"wrongArgNum": "Nieprawidłowa liczba podanych argumentów",
@@ -55,7 +55,7 @@
"pleaseWait": "Proszę czekać",
"updateAvailable": "Dostępna aktualizacja",
"notInstalled": "Nie zainstalowano",
"pseudoVersion": "pseudowersja",
"pseudoVersion": "pseudo-wersja",
"selectAll": "Zaznacz wszystkie",
"deselectX": "Odznacz {}",
"xWillBeRemovedButRemainInstalled": "{} zostanie usunięty z Obtainium, ale pozostanie zainstalowany na urządzeniu.",
@@ -76,7 +76,7 @@
"resetInstallStatusForSelectedAppsQuestion": "Zresetować status instalacji dla wybranych aplikacji?",
"installStatusOfXWillBeResetExplanation": "Stan instalacji wybranych aplikacji zostanie zresetowany.\n\nMoże być to pomocne, gdy wersja aplikacji wyświetlana w Obtainium jest nieprawidłowa z powodu nieudanych aktualizacji lub innych problemów.",
"customLinkMessage": "Te linki działają na urządzeniach z zainstalowanym Obtainium",
"shareAppConfigLinks": "Udostępnij konfigurację aplikacji jako link HTML",
"shareAppConfigLinks": "Udostępnij konfigurację aplikacji w formie linku",
"shareSelectedAppURLs": "Udostępnij wybrane adresy URL aplikacji",
"resetInstallStatus": "Zresetuj stan instalacji",
"more": "Więcej",
@@ -150,7 +150,7 @@
"appsNotUpdated": "Nie udało się zaktualizować aplikacji",
"appsUpdatedNotifDescription": "Informuje, gdy co najmniej jedna aplikacja została zaktualizowana w tle",
"xWasUpdatedToY": "{} zaktualizowano do {}.",
"xWasNotUpdatedToY": "Nie udało się zaktualizować {} do {}.",
"xWasNotUpdatedToY": "Błąd aktualizacji {} do {}.",
"errorCheckingUpdates": "Błąd sprawdzania aktualizacji",
"errorCheckingUpdatesNotifDescription": "Jest wyświetlane, gdy sprawdzanie aktualizacji w tle nie powiedzie się",
"appsRemoved": "Usunięte aplikacje",
@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Nie znaleziono aplikacji o tym identyfikatorze lub nazwie",
"reposHaveMultipleApps": "Repozytoria mogą zawierać wiele aplikacji",
"fdroidThirdPartyRepo": "Zewnętrzne repo F-Droid",
"steamMobile": "Mobilny Steam",
"steamChat": "Czat Steam",
"install": "Instaluj",
"markInstalled": "Oznacz jako zainstalowane",
"update": "Zaktualizuj",
@@ -191,7 +189,7 @@
"downloadingX": "Pobieranie {}",
"downloadX": "Pobierz {}",
"downloadedX": "Pobrano {}",
"releaseAsset": "Release Asset",
"releaseAsset": "Wydany pakiet",
"downloadNotifDescription": "Informuje o postępach w pobieraniu aplikacji",
"noAPKFound": "Nie znaleziono pakietu APK",
"noVersionDetection": "Bez wykrywania wersji",
@@ -213,11 +211,12 @@
"uninstallFromDevice": "Odinstaluj z urządzenia",
"onlyWorksWithNonVersionDetectApps": "Działa tylko w przypadku aplikacji z wyłączonym wykrywaniem wersji.",
"releaseDateAsVersion": "Użyj daty wydania jako wersji",
"releaseTitleAsVersion": "Używaj nazwy wydania jako ciągu wersji",
"releaseDateAsVersionExplanation": "Opcja ta powinna być używana tylko w przypadku aplikacji, w których wykrywanie wersji nie działa poprawnie, ale dostępna jest data wydania.",
"changes": "Zmiany",
"releaseDate": "Data wydania",
"importFromURLsInFile": "Importuj z adresów URL w pliku (typu OPML)",
"versionDetectionExplanation": "Uzgodnij ciąg wersji z wersją wykrytą w systemie operacyjnym",
"versionDetectionExplanation": "Uzgodnij ciąg wersji z wersją wykrytą przez system operacyjny",
"versionDetection": "Wykrywanie wersji",
"standardVersionDetection": "Standardowe wykrywanie wersji",
"groupByCategory": "Grupuj według kategorii",
@@ -251,15 +250,16 @@
"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.",
"verifyLatestTag": "Zweryfikuj najnowszy tag",
"intermediateLinkRegex": "Filtruj link \"pośredni\" do odwiedzenia",
"intermediateLinkRegex": "Filtr linków \"pośrednich\" do odwiedzenia w pierwszej kolejności",
"filterByLinkText": "Filtruj linki według tekstu linku",
"intermediateLinkNotFound": "Nie znaleziono linku pośredniego",
"intermediateLink": "Łącze pośrednie",
"intermediateLink": "Link pośredni",
"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",
"bgUpdatesWhileChargingOnly": "Wyłącz aktualizacje w tle, gdy urządzenie nie jest ładowane",
"autoSelectHighestVersionCode": "Automatycznie wybierz najwyższy kod wersji APK",
"versionExtractionRegEx": "Wyrażenie regularne wyodrębniające wersję",
"trimVersionString": "Przycinanie łańcucha wersji za pomocą RegEx",
"trimVersionString": "Przytnij ciąg wersji za pomocą RegEx",
"matchGroupToUseForX": "Dopasuj grupę do użycia dla \"{}\"",
"matchGroupToUse": "Dopasuj grupę do użycia dla wyrażenia regularnego wyodrębniania wersji",
"highlightTouchTargets": "Wyróżnij mniej oczywiste elementy dotykowe",
@@ -270,7 +270,7 @@
"trySelectingSuggestedVersionCode": "Spróbuj wybierać sugerowany kod wersji APK",
"dontSortReleasesList": "Utrzymaj kolejność wydań z interfejsu API",
"reverseSort": "Odwrotne sortowanie",
"takeFirstLink": "W pierwszy link",
"takeFirstLink": "Wykorzystaj pierwszy link",
"skipSort": "Pomiń sortowanie",
"debugMenu": "Menu debugowania",
"bgTaskStarted": "Uruchomiono zadanie w tle - sprawdź logi.",
@@ -283,38 +283,42 @@
"appsPossiblyUpdatedNotifChannel": "Informuj o próbach aktualizacji",
"errorCheckingUpdatesNotifChannel": "Błędy sprawdzania aktualizacji",
"appsRemovedNotifChannel": "Usunięte aplikacje",
"downloadingXNotifChannel": "Pobieranie aplikacji",
"downloadingXNotifChannel": "Pobieranie {}",
"completeAppInstallationNotifChannel": "Ukończenie instalacji aplikacji",
"checkingForUpdatesNotifChannel": "Sprawdzanie dostępności aktualizacji",
"onlyCheckInstalledOrTrackOnlyApps": "Sprawdzaj tylko zainstalowane i obserwowane aplikacje pod kątem aktualizacji",
"supportFixedAPKURL": "Obsługuj stałe adresy URL APK",
"selectX": "Wybierz {}",
"parallelDownloads": "Zezwól na pobieranie równoległe",
"parallelDownloads": "Zezwalaj na równoległe pobierania",
"useShizuku": "Użyj Shizuku lub Sui, aby zainstalować",
"shizukuBinderNotFound": "Shizuku is not running",
"shizukuBinderNotFound": "Usługa Shizuku nie działa",
"shizukuOld": "Stara wersja Shizuku (<11) - zaktualizuj ją",
"shizukuOldAndroidWithADB": "Shizuku działa na Androidzie < 8.1 z ADB - zaktualizuj Androida lub użyj zamiast tego Sui",
"shizukuPretendToBeGooglePlay": "Ustaw Google Play jako źródło instalacji (jeśli używana jest aplikacja Shizuku).",
"useSystemFont": "Użyj czcionki systemowej",
"useVersionCodeAsOSVersion": "Użyj kodu wersji aplikacji jako wersji wykrytej przez system operacyjny",
"shizukuOldAndroidWithADB": "Shizuku przez ADB działa na Androidzie 8.1+. Zaktualizuj Androida lub użyj zamiast tego Sui",
"shizukuPretendToBeGooglePlay": "Ustaw Google Play jako źródło instalacji (jeśli używana jest aplikacja Shizuku)",
"useSystemFont": "Czcionka systemowa",
"useVersionCodeAsOSVersion": "Użyj versionCode aplikacji jako wersji wykrytej przez system operacyjny",
"requestHeader": "Nagłówek żądania",
"useLatestAssetDateAsReleaseDate": "Użyj najnowszego przesłanego zasobu jako daty wydania",
"defaultPseudoVersioningMethod": "Domyślna metoda pseudowersji",
"partialAPKHash": "Częściowy skrót APK",
"APKLinkHash": "Skrót łącza APK",
"directAPKLink": "Bezpośredni link APK",
"pseudoVersionInUse": "Pseudowersja jest w użyciu",
"defaultPseudoVersioningMethod": "Domyślna metoda pseudo-wersji",
"partialAPKHash": "Częściowy Hash pliku apk",
"APKLinkHash": "Link Hash pliku apk",
"directAPKLink": "Bezpośredni link do pliku apk",
"pseudoVersionInUse": "Pseudo-wersja jest w użyciu",
"installed": "Zainstalowano",
"latest": "Najnowszy",
"latest": "Najnowsza",
"invertRegEx": "Odwróć wyrażenie regularne",
"note": "Uwaga",
"selfHostedNote": "Lista rozwijana \"{}\" może być używana do uzyskiwania dostępu do samodzielnie hostowanych / niestandardowych instancji dowolnego źródła.",
"badDownload": "Nie można przeanalizować pliku APK (niekompatybilny lub częściowo pobrany).",
"beforeNewInstallsShareToAppVerifier": "Udostępnianie nowych aplikacji za pomocą AppVerifier (jeśli dostępne)",
"appVerifierInstructionToast": "Udostępnij w AppVerifier, a następnie wróć tutaj, gdy będziesz gotowy.",
"selfHostedNote": "Wybierz \"{}\", aby uzyskać dostęp do samodzielnie hostowanych lub niestandardowych instancji dowolnego źródła.",
"badDownload": "Nie można przeanalizować pliku apk (jest niekompatybilny lub częściowo pobrany)",
"beforeNewInstallsShareToAppVerifier": "Udostępnij nowe aplikacje za pomocą weryfikatora aplikacji (jeśli jest dostępny)",
"appVerifierInstructionToast": "Udostępnij do weryfikatora aplikacji, a następnie wróć tutaj.",
"wiki": "Pomoc/Wiki",
"crowdsourcedConfigsLabel": "Konfiguracje aplikacji pochodzące z crowdsourcingu (korzystanie na własne ryzyko)",
"crowdsourcedConfigsLabel": "Baza konfiguracji",
"crowdsourcedConfigsShort": "Baza konfiguracji",
"allowInsecure": "Zezwalaj na niezabezpieczone żądania HTTP",
"stayOneVersionBehind": "Pozostań jedną wersję w tyle za najnowszą",
"refreshBeforeDownload": "Odśwież szczegóły aplikacji przed pobraniem",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Usunąć aplikację?",
"few": "Usunąć aplikacje?",
@@ -388,8 +392,10 @@
"other": "{} i {} inne apki zostały zaktualizowane."
},
"xAndNMoreUpdatesFailed": {
"one": "Nie udało się zaktualizować {} i 1 innej aplikacji.",
"other": "Nie udało się zaktualizować {} i {} więcej aplikacji."
"one": "Błąd aktualizacji {} i 1 innej apki.",
"few": "Błąd aktualizacji {} i {} innych apek.",
"many": "Błąd aktualizacji {} i {} innych apek.",
"other": "Błąd aktualizacji {} i {} innych apek."
},
"xAndNMoreUpdatesPossiblyInstalled": {
"one": "{} i 1 inna apka mogły zostać zaktualizowane.",
@@ -398,7 +404,9 @@
"other": "{} i {} inne apki mogły zostać zaktualizowane."
},
"apk": {
"one": "{} APK",
"other": "{} APK"
"one": "{} apk",
"few": "{} apki",
"many": "{} apek",
"other": "{} apki"
}
}

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Nenhum aplicativo foi encontrado com esse ID ou nome",
"reposHaveMultipleApps": "Repositórios podem conter múltiplos aplicativos",
"fdroidThirdPartyRepo": "Repositórios de terceiros F-Droid",
"steamMobile": "Steam para celular",
"steamChat": "Chat do Steam",
"install": "Instalar",
"markInstalled": "Marcar instalado",
"update": "Atualizar",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Desinstalar do dispositivo",
"onlyWorksWithNonVersionDetectApps": "Apenas funciona para aplicativos com detecção de versão desativada.",
"releaseDateAsVersion": "Usar data de lançamento como versão",
"releaseTitleAsVersion": "Utilizar o título da versão como cadeia de versões",
"releaseDateAsVersionExplanation": "Esta opção só deve ser usada para aplicativos onde a detecção de versão não funciona corretamente, mas há uma data de lançamento disponível.",
"changes": "Alterações",
"releaseDate": "Data de lançamento",
@@ -257,6 +256,7 @@
"intermediateLink": "Link intermediário",
"exemptFromBackgroundUpdates": "Isento de atualizações em segundo-plano (se ativadas)",
"bgUpdatesOnWiFiOnly": "Desative as atualizações em segundo-plano quando não estiver conectado no Wi-Fi",
"bgUpdatesWhileChargingOnly": "Desativar actualizações em segundo plano quando não estiver a carregar",
"autoSelectHighestVersionCode": "Auto-selecionar a versão mais recente",
"versionExtractionRegEx": "Regex de extração de versão",
"trimVersionString": "Cortar a cadeia de caracteres da versão com RegEx",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "Partilhe com o AppVerifier e, em seguida, regresse aqui quando estiver pronto.",
"wiki": "Ajuda/Wiki",
"crowdsourcedConfigsLabel": "Configurações de aplicações de crowdsourcing (utilização por sua conta e risco)",
"crowdsourcedConfigsShort": "Configurações de aplicações com base em crowdsourcing",
"allowInsecure": "Permitir pedidos HTTP inseguros",
"stayOneVersionBehind": "Manter-se uma versão atrás da mais recente",
"refreshBeforeDownload": "Atualizar os detalhes da aplicação antes da transferência",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Remover aplicativo?",
"other": "Remover aplicativos?"

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Приложение с таким ID или названием не было найдено",
"reposHaveMultipleApps": "В хранилище несколько приложений",
"fdroidThirdPartyRepo": "Сторонние репозитории F-Droid",
"steamMobile": "Приложение Steam",
"steamChat": "Steam Chat",
"install": "Установить",
"markInstalled": "Пометить как установленное",
"update": "Обновить",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Удалить с устройства",
"onlyWorksWithNonVersionDetectApps": "Работает только для приложений с отключенным определением версии",
"releaseDateAsVersion": "Дата выпуска вместо версии",
"releaseTitleAsVersion": "Используйте название релиза в качестве строки версии",
"releaseDateAsVersionExplanation": "Этот параметр следует использовать только для приложений, в которых определение версии не работает правильно, но имеется дата выпуска",
"changes": "Изменения",
"releaseDate": "Дата выпуска",
@@ -257,6 +256,7 @@
"intermediateLink": "Промежуточная ссылка",
"exemptFromBackgroundUpdates": "Исключить из фоновых обновлений (если включено)",
"bgUpdatesOnWiFiOnly": "Отключить фоновые обновления, если нет соединения с Wi-Fi",
"bgUpdatesWhileChargingOnly": "Отключение фоновых обновлений при отсутствии зарядки",
"autoSelectHighestVersionCode": "Автоматически выбирать APK с актуальной версией кода",
"versionExtractionRegEx": "Регулярное выражение для извлечения версии",
"trimVersionString": "Обрезка строки версии с помощью RegEx",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "Поделитесь с AppVerifier, а затем вернитесь сюда, когда будете готовы.",
"wiki": "Помощь/Вики",
"crowdsourcedConfigsLabel": "Конфигурации приложений на основе краудсорсинга (используйте на свой страх и риск)",
"crowdsourcedConfigsShort": "Конфиги приложений с помощью краудсорсинга",
"allowInsecure": "Разрешить небезопасные HTTP-запросы",
"stayOneVersionBehind": "Не отставайте от последней версии",
"refreshBeforeDownload": "Обновляйте информацию о приложении перед загрузкой",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Удалить приложение?",
"other": "Удалить приложения?"

View File

@@ -12,7 +12,8 @@ const neverAutoTranslate = {
root: ['*'],
obtainiumExportHyphenatedLowercase: ['*'],
theme: ['de'],
appId: ['de']
appId: ['de'],
placeholder: ['pl']
}
const translateText = async (text, targetLang, authKey) => {

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Ingen App funnen med det namnet eller ID",
"reposHaveMultipleApps": "Förråd kan innehålla flera ApparR",
"fdroidThirdPartyRepo": "F-Droid Tredjeparts Förråd",
"steamMobile": "Steam Mobile",
"steamChat": "Steam Chat",
"install": "Installera",
"markInstalled": "Märk Installerad",
"update": "Uppdatera",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Avinstallera från Enheten",
"onlyWorksWithNonVersionDetectApps": "Fungerar bara för Appar med versionsdetektering inaktiverat..",
"releaseDateAsVersion": "Använd releasedatum som version",
"releaseTitleAsVersion": "Använd release-titel som versionssträng",
"releaseDateAsVersionExplanation": "Det här alternativet bör endast användas för appar där versionsidentifiering inte fungerar korrekt, men ett releasedatum är tillgängligt.",
"changes": "Ändringar",
"releaseDate": "Releasedatum",
@@ -257,6 +256,7 @@
"intermediateLink": "Mellanlänk",
"exemptFromBackgroundUpdates": "Undta från bakgrundsuppdateringar (om aktiverad)",
"bgUpdatesOnWiFiOnly": "Inaktivera Bakgrundsuppdateringar utan WiFi",
"bgUpdatesWhileChargingOnly": "Inaktivera bakgrundsuppdateringar när du inte laddar",
"autoSelectHighestVersionCode": "Välj automatiskt högsta versionskod APK",
"versionExtractionRegEx": "Version Extraction RegEx",
"trimVersionString": "Trimma versionssträng med RegEx",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "Dela till AppVerifier och återvänd sedan hit när du är klar.",
"wiki": "Hjälp/Wiki",
"crowdsourcedConfigsLabel": "Crowdsourcade appkonfigurationer (använd på egen risk)",
"crowdsourcedConfigsShort": "Appkonfigurationer med hjälp av crowdsourcing",
"allowInsecure": "Tillåt osäkra HTTP-förfrågningar",
"stayOneVersionBehind": "Håll dig en version bakom den senaste",
"refreshBeforeDownload": "Uppdatera appdetaljerna före nedladdning",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Ta Bort App?",
"other": "Ta Bort Appar?"

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Bu kimlik veya ada sahip bir uygulama bulunamadı",
"reposHaveMultipleApps": "Depolar birden fazla uygulama içerebilir",
"fdroidThirdPartyRepo": "F-Droid Üçüncü Parti Depo",
"steamMobile": "Steam Mobil",
"steamChat": "Steam Sohbet",
"install": "Yükle",
"markInstalled": "Yüklendi olarak İşaretle",
"update": "Güncelle",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Cihazdan Kaldır",
"onlyWorksWithNonVersionDetectApps": "Yalnızca Sürüm Algılaması Devre Dışı Uygulamalar İçin Çalışır.",
"releaseDateAsVersion": "Sürüm Olarak Yayın Tarihi Kullan",
"releaseTitleAsVersion": "Sürüm dizesi olarak sürüm başlığını kullan",
"releaseDateAsVersionExplanation": "Bu seçenek, sürüm algılamanın doğru çalışmadığı ancak bir sürüm tarihinin mevcut olduğu uygulamalar için kullanılmalıdır.",
"changes": "Değişiklikler",
"releaseDate": "Yayın Tarihi",
@@ -257,6 +256,7 @@
"intermediateLink": "Ara bağlantı",
"exemptFromBackgroundUpdates": "Arka plan güncellemelerinden muaf tut (etkinse)",
"bgUpdatesOnWiFiOnly": "WiFi olmadığında arka plan güncellemelerini devre dışı bırak",
"bgUpdatesWhileChargingOnly": "Şarj olmadığında arka plan güncellemelerini devre dışı bırakma",
"autoSelectHighestVersionCode": "Otomatik olarak en yüksek sürüm kodunu seç",
"versionExtractionRegEx": "Sürüm Çıkarma Düzenli İfade",
"trimVersionString": "RegEx ile Sürüm Dizesini Kırpma",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "AppVerifier ile paylaşın, hazır olduğunuzda buraya dönün.",
"wiki": "Yardım/Wiki",
"crowdsourcedConfigsLabel": "Kitle Kaynaklı Uygulama Yapılandırmaları (riski size ait olmak üzere kullanın)",
"crowdsourcedConfigsShort": "Kitle Kaynaklı Uygulama Yapılandırmaları",
"allowInsecure": "Güvensiz HTTP isteklerine izin ver",
"stayOneVersionBehind": "En son sürümün bir sürüm gerisinde kalın",
"refreshBeforeDownload": "İndirmeden önce uygulama ayrıntılarını yenileyin",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Uygulamayı Kaldır?",
"other": "Uygulamaları Kaldır?"

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Застосунок з таким ідентифікатором або назвою не знайдено",
"reposHaveMultipleApps": "Сховища можуть містити кілька застосунків",
"fdroidThirdPartyRepo": "F-Droid Стороннє сховище",
"steamMobile": "Мобільний Steam",
"steamChat": "Чат Steam",
"install": "Встановити",
"markInstalled": "Позначити як встановлене",
"update": "Оновити",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Видалити з пристрою",
"onlyWorksWithNonVersionDetectApps": "Працює лише з застосунками з вимкненим визначенням версії.",
"releaseDateAsVersion": "Використовувати дату випуску як рядок версії",
"releaseTitleAsVersion": "Використовувати назву випуску як рядок версії",
"releaseDateAsVersionExplanation": "Цю опцію слід використовувати лише для застосунків, де визначення версії працює неправильно, але є дата випуску.",
"changes": "Зміни",
"releaseDate": "Дата випуску",
@@ -257,6 +256,7 @@
"intermediateLink": "Проміжне посилання",
"exemptFromBackgroundUpdates": "Виключено з фонових оновлень (якщо ввімкнено)",
"bgUpdatesOnWiFiOnly": "Вимкнути фонові оновлення поза Wi-Fi",
"bgUpdatesWhileChargingOnly": "Вимкнути фонові оновлення, коли не заряджається",
"autoSelectHighestVersionCode": "Автоматичний вибір APK з найвищим кодом версії",
"versionExtractionRegEx": "Регулярний вираз для вилучення рядка версії",
"trimVersionString": "Обрізати рядок версії за допомогою RegEx",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "Надішліть на AppVerifier, а потім поверніться сюди, коли будете готові.",
"wiki": "Довідка/Вікі",
"crowdsourcedConfigsLabel": "Краудсорсингові конфігурації додатків (використовуйте на свій страх і ризик)",
"crowdsourcedConfigsShort": "Налаштування краудсорсингових додатків",
"allowInsecure": "Дозволити незахищені HTTP-запити",
"stayOneVersionBehind": "Залишайтеся на одну версію актуальнішою",
"refreshBeforeDownload": "Оновіть інформацію про програму перед завантаженням",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Видалити застосунок?",
"other": "Видалити застосунки?"

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Không tìm thấy ứng dụng nào có ID hoặc tên đó",
"reposHaveMultipleApps": "Kho có thể chứa nhiều Ứng dụng",
"fdroidThirdPartyRepo": "Kho lưu trữ bên thứ ba F-Droid",
"steamMobile": "Điện thoại di động hơi nước",
"steamChat": "Trò chuyện hơi nước",
"install": "Cài đặt",
"markInstalled": "Đánh dấu là đã cài đặt",
"update": "Cập nhật",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "Gỡ cài đặt khỏi thiết bị",
"onlyWorksWithNonVersionDetectApps": "Chỉ hoạt động với Ứng dụng đã tắt tính năng phát hiện phiên bản.",
"releaseDateAsVersion": "Sử dụng ngày phát hành làm phiên bản",
"releaseTitleAsVersion": "Use release title as version string",
"releaseDateAsVersionExplanation": "Chỉ nên sử dụng tùy chọn này cho Ứng dụng trong đó tính năng phát hiện phiên bản không hoạt động chính xác nhưng đã có ngày phát hành.",
"changes": "Thay đổi",
"releaseDate": "Ngày phát hành",
@@ -257,6 +256,7 @@
"intermediateLink": "Liên kết trung gian",
"exemptFromBackgroundUpdates": "Miễn cập nhật nền (nếu được bật)",
"bgUpdatesOnWiFiOnly": "Tắt cập nhật nền khi không có WiFi",
"bgUpdatesWhileChargingOnly": "Disable background updates when not charging",
"autoSelectHighestVersionCode": "Tự động chọn APK mã phiên bản cao nhất",
"versionExtractionRegEx": "Trích xuất phiên bản RegEx",
"trimVersionString": "Trim Version String With RegEx",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "Chia sẻ lên AppVerifier, sau đó quay lại đây khi sẵn sàng.",
"wiki": "Trợ giúp/Wiki",
"crowdsourcedConfigsLabel": "Crowdsourced App Configurations (use at your own risk)",
"crowdsourcedConfigsShort": "Crowdsourced App Configs",
"allowInsecure": "Allow insecure HTTP requests",
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"tencentAppStore": "Tencent App Store",
"removeAppQuestion": {
"one": "Gỡ ứng dụng?",
"other": "Gỡ ứng dụng?"

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "找不到具有該 ID 或名稱的應用程式",
"reposHaveMultipleApps": "倉庫可能包含多個應用程式",
"fdroidThirdPartyRepo": "F-Droid 第三方倉庫",
"steamMobile": "Steam 行動版",
"steamChat": "Steam 聊天",
"install": "安裝",
"markInstalled": "標記為已安裝",
"update": "更新",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "從裝置解除安裝",
"onlyWorksWithNonVersionDetectApps": "僅適用於停用版本偵測的應用程式。",
"releaseDateAsVersion": "使用發佈日期作為版本字串",
"releaseTitleAsVersion": "Use release title as version string",
"releaseDateAsVersionExplanation": "此選項僅應用於版本偵測無法正確工作但有發佈日期的應用程式。",
"changes": "變更",
"releaseDate": "發佈日期",
@@ -257,6 +256,7 @@
"intermediateLink": "中間連結",
"exemptFromBackgroundUpdates": "免除背景更新(若已啟用)",
"bgUpdatesOnWiFiOnly": "停用非 WiFi 的背景更新",
"bgUpdatesWhileChargingOnly": "Disable background updates when not charging",
"autoSelectHighestVersionCode": "自動選擇最高 versionCode 的 APK",
"versionExtractionRegEx": "版本字串提取正則表達式",
"trimVersionString": "用正則表達式修剪版本字串",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "分享至 AppVerifier然後準備好時回到此處。",
"wiki": "幫助/維基",
"crowdsourcedConfigsLabel": "群眾外包的應用程式設定(使用風險自負)",
"crowdsourcedConfigsShort": "Crowdsourced App Configs",
"allowInsecure": "Allow insecure HTTP requests",
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"tencentAppStore": "騰訊應用寶",
"removeAppQuestion": {
"one": "移除應用程式?",
"other": "移除應用程式?"

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "未找到符合此 ID 或名称的应用",
"reposHaveMultipleApps": "存储库中可能包含多个应用",
"fdroidThirdPartyRepo": "F-Droid 第三方存储库",
"steamMobile": "Steam Mobile",
"steamChat": "Steam Chat",
"install": "安装",
"markInstalled": "标记为已安装",
"update": "更新",
@@ -188,10 +186,10 @@
"additionalOptions": "附加选项",
"disableVersionDetection": "禁用版本检测",
"noVersionDetectionExplanation": "此选项应该仅用于无法进行版本检测的应用。",
"downloadingX": "正在下载{}",
"downloadingX": "正在下载 {}",
"downloadX": "下载 {}",
"downloadedX": "下载 {}",
"releaseAsset": "发行版附件",
"downloadedX": "下载 {}",
"releaseAsset": "发行件",
"downloadNotifDescription": "提示应用的下载进度",
"noAPKFound": "未找到 APK 文件",
"noVersionDetection": "禁用版本检测",
@@ -213,6 +211,7 @@
"uninstallFromDevice": "从设备中卸载",
"onlyWorksWithNonVersionDetectApps": "仅适用于禁用版本检测的应用。",
"releaseDateAsVersion": "将发行日期作为版本号",
"releaseTitleAsVersion": "使用版本标题作为版本字符串",
"releaseDateAsVersionExplanation": "此选项应该仅用于无法进行版本检测但能够获取发行日期的应用。",
"changes": "更新日志",
"releaseDate": "发行日期",
@@ -257,6 +256,7 @@
"intermediateLink": "中转链接",
"exemptFromBackgroundUpdates": "禁用后台更新(仅此应用生效,即使已启用全局后台更新)",
"bgUpdatesOnWiFiOnly": "未连接 Wi-Fi 时禁用后台更新",
"bgUpdatesWhileChargingOnly": "不充电时禁用后台更新",
"autoSelectHighestVersionCode": "自动选择内部版本号最高的 APK 文件",
"versionExtractionRegEx": "提取版本号的正则表达式",
"trimVersionString": "使用 RegEx 修剪版本字符串",
@@ -314,7 +314,11 @@
"appVerifierInstructionToast": "分享至 AppVerifier完成后返回此处。",
"wiki": "帮助/Wiki",
"crowdsourcedConfigsLabel": "众包应用程序配置(使用风险自负)",
"crowdsourcedConfigsShort": "众包应用程序配置",
"allowInsecure": "允许不安全的 HTTP 请求",
"stayOneVersionBehind": "比最新版本晚一个版本",
"refreshBeforeDownload": "下载前刷新应用程序详细信息",
"tencentAppStore": "腾讯应用宝",
"removeAppQuestion": {
"one": "是否删除应用?",
"other": "是否删除应用?"

View File

@@ -1,5 +1,5 @@
<p>Obtainium allows you to install and update Apps directly from their releases pages, and receive notifications when new releases are made available.</p>
<p>Read the <a href="https://github.com/ImranR98/Obtainium/wiki">Wiki</a></p>
<p>Read the <a href="https://wiki.obtainium.imranr.dev/">Wiki</a></p>
<p>
<b>Currently supported App sources:</b>
</p>

View File

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

View File

@@ -1,5 +1,5 @@
<p>Obtainium позволяет вам устанавливать и обновлять приложения прямо с их объявлений о выпусках и получать уведомления о новых выпусках.</p>
<p>Для деталей читайте <a href="https://github.com/ImranR98/Obtainium/wiki">Вики</a></p>
<p>Для деталей читайте <a href="https://wiki.obtainium.imranr.dev/">Вики</a></p>
<p>
<b>Поддерживаемые источники приложений:</b>
</p>

View File

@@ -5,6 +5,8 @@ import 'package:html/parser.dart';
import 'package:http/http.dart';
import 'package:obtainium/components/generated_form.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/apps_provider.dart';
import 'package:obtainium/providers/settings_provider.dart';
import 'package:obtainium/providers/source_provider.dart';
class APKMirror extends AppSource {
@@ -31,6 +33,16 @@ class APKMirror extends AppSource {
];
}
@override
Future<Map<String, String>?> getRequestHeaders(
Map<String, dynamic> additionalSettings,
{bool forAPKDownload = false}) async {
return {
"User-Agent":
"Obtainium/${(await getInstalledInfo(obtainiumId))?.versionName ?? '1.0.0'}"
};
}
@override
String sourceSpecificStandardizeURL(String url, {bool forSelection = false}) {
RegExp standardUrlRegEx = RegExp(

View File

@@ -2,6 +2,7 @@ import 'package:device_info_plus/device_info_plus.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:html/parser.dart';
import 'package:obtainium/app_sources/html.dart';
import 'package:obtainium/components/generated_form.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/source_provider.dart';
@@ -26,6 +27,16 @@ class APKPure extends AppSource {
allowSubDomains = true;
naiveStandardVersionDetection = true;
showReleaseDateAsVersionToggle = true;
additionalSourceAppSpecificSettingFormItems = [
[
GeneratedFormSwitch('fallbackToOlderReleases',
label: tr('fallbackToOlderReleases'), defaultValue: true)
],
[
GeneratedFormSwitch('stayOneVersionBehind',
label: tr('stayOneVersionBehind'), defaultValue: false)
]
];
}
@override
@@ -54,6 +65,98 @@ class APKPure extends AppSource {
return Uri.parse(standardUrl).pathSegments.last;
}
getDetailsForVersionLink(
String standardUrl,
String appId,
String host,
List<String> supportedArchs,
String link,
Map<String, dynamic> additionalSettings) async {
var res = await sourceRequest(link, additionalSettings);
if (res.statusCode == 200) {
var html = parse(res.body);
var apksDiv =
html.querySelector('#version-list div div.show-more-content');
DateTime? topReleaseDate;
var apkUrls = apksDiv
?.querySelectorAll('div.group-title')
.map((e) {
String architectureString = e.text.trim();
if (architectureString.toLowerCase() == 'unlimited' ||
architectureString.toLowerCase() == 'universal') {
architectureString = '';
}
List<String> architectures = architectureString
.split(',')
.map((e) => e.trim())
.where((e) => e.isNotEmpty)
.toList();
// Only take the first APK for each architecture, ignore others for now, for simplicity
// Unclear why there can even be multiple APKs for the same version and arch
var apkInfo = e.nextElementSibling?.querySelector('div.info');
String? versionCode = RegExp('[0-9]+')
.firstMatch(
apkInfo?.querySelector('div.info-top .code')?.text ??
'')
?.group(0)
?.trim();
var types = apkInfo
?.querySelectorAll('div.info-top span.tag')
.map((e) => e.text.trim())
.map((t) => t == 'APKs' ? 'APK' : t) ??
[];
String type = types.isEmpty ? 'APK' : types.first;
String? dateString = apkInfo
?.querySelector('div.info-bottom span.time')
?.text
.trim();
DateTime? releaseDate = parseDateTimeMMMddCommayyyy(dateString);
if (additionalSettings['autoApkFilterByArch'] == true &&
architectures.isNotEmpty &&
architectures
.where((a) => supportedArchs.contains(a))
.isEmpty) {
return const MapEntry('', '');
}
topReleaseDate ??=
releaseDate; // Just use the release date of the first APK in the list as the release date for this version
return MapEntry(
'$appId-$versionCode-$architectureString.${type.toLowerCase()}',
'https://d.${hosts.contains(host) ? 'cdnpure.com' : host}/b/$type/$appId?versionCode=$versionCode');
})
.where((e) => e.key.isNotEmpty)
.toList() ??
[];
if (apkUrls.isEmpty) {
throw NoAPKError();
}
String version = Uri.parse(link).pathSegments.last;
String? author;
try {
author = html
.querySelector('span.info-sdk')
?.text
.trim()
.substring(version.length + 4) ??
Uri.parse(standardUrl).pathSegments.reversed.last;
} catch (e) {
author = html.querySelector('span.info-sdk')?.text.trim() ??
Uri.parse(standardUrl).pathSegments.reversed.last;
}
String appName =
html.querySelector('h1.info-title')?.text.trim() ?? appId;
String? changeLog = html
.querySelector('div.module.change-log')
?.innerHtml
.trim()
.replaceAll("<br>", " \n");
return APKDetails(version, apkUrls, AppNames(author, appName),
releaseDate: topReleaseDate, changeLog: changeLog);
} else {
throw getObtainiumHttpError(res);
}
}
@override
Future<APKDetails> getLatestAPKDetails(
String standardUrl,
@@ -63,9 +166,15 @@ class APKPure extends AppSource {
String host = Uri.parse(standardUrl).host;
var res0 = await sourceRequest('$standardUrl/versions', additionalSettings);
var decodedStandardUrl = standardUrl;
try {
decodedStandardUrl = Uri.decodeFull(decodedStandardUrl);
} catch (e) {
//
}
var versionLinks = await grabLinksCommon(res0, {
'skipSort': true,
'customLinkFilterRegex': '$standardUrl/download/[^/]+\$'
'customLinkFilterRegex': '$decodedStandardUrl/download/[^/]+\$'
});
var supportedArchs = (await DeviceInfoPlugin().androidInfo).supportedAbis;
@@ -80,88 +189,17 @@ class APKPure extends AppSource {
for (var i = 0; i < versionLinks.length; i++) {
var link = versionLinks[i];
var res = await sourceRequest(link.key, additionalSettings);
if (res.statusCode == 200) {
var html = parse(res.body);
var apksDiv =
html.querySelector('#version-list div div.show-more-content');
DateTime? topReleaseDate;
var apkUrls = apksDiv
?.querySelectorAll('div.group-title')
.map((e) {
String architectureString = e.text.trim();
if (architectureString.toLowerCase() == 'unlimited' ||
architectureString.toLowerCase() == 'universal') {
architectureString = '';
}
List<String> architectures = architectureString
.split(',')
.map((e) => e.trim())
.where((e) => e.isNotEmpty)
.toList();
// Only take the first APK for each architecture, ignore others for now, for simplicity
// Unclear why there can even be multiple APKs for the same version and arch
var apkInfo = e.nextElementSibling?.querySelector('div.info');
String? versionCode = RegExp('[0-9]+')
.firstMatch(apkInfo
?.querySelector('div.info-top span.code')
?.text ??
'')
?.group(0)
?.trim();
var types = apkInfo
?.querySelectorAll('div.info-top span.tag')
.map((e) => e.text.trim())
.map((t) => t == 'APKs' ? 'APK' : t) ??
[];
String type = types.isEmpty
? 'APK'
: types.length == 1
? types.first
: types.last;
String? dateString = apkInfo
?.querySelector('div.info-bottom span.time')
?.text
.trim();
DateTime? releaseDate =
parseDateTimeMMMddCommayyyy(dateString);
if (additionalSettings['autoApkFilterByArch'] == true &&
architectures.isNotEmpty &&
architectures
.where((a) => supportedArchs.contains(a))
.isEmpty) {
return const MapEntry('', '');
}
topReleaseDate ??=
releaseDate; // Just use the release date of the first APK in the list as the release date for this version
return MapEntry(
'$appId-$versionCode-$architectureString.${type.toLowerCase()}',
'https://d.${hosts.contains(host) ? 'cdnpure.com' : host}/b/$type/$appId?versionCode=$versionCode');
})
.where((e) => e.key.isNotEmpty)
.toList() ??
[];
if (apkUrls.isEmpty) {
continue;
try {
if (i == 0 && additionalSettings['stayOneVersionBehind'] == true) {
throw NoReleasesError();
}
return await getDetailsForVersionLink(standardUrl, appId, host,
supportedArchs, link.key, additionalSettings);
} catch (e) {
if (additionalSettings['fallbackToOlderReleases'] != true ||
i == versionLinks.length - 1) {
rethrow;
}
String version = Uri.parse(link.key).pathSegments.last;
String author = html
.querySelector('span.info-sdk')
?.text
.trim()
.substring(version.length + 4) ??
Uri.parse(standardUrl).pathSegments.reversed.last;
String appName =
html.querySelector('h1.info-title')?.text.trim() ?? appId;
String? changeLog = html
.querySelector('div.module.change-log')
?.innerHtml
.trim()
.replaceAll("<br>", " \n");
return APKDetails(version, apkUrls, AppNames(author, appName),
releaseDate: topReleaseDate, changeLog: changeLog);
} else {
throw getObtainiumHttpError(res);
}
}
throw NoAPKError();

View File

@@ -45,7 +45,7 @@ class FDroid extends AppSource {
RegExpMatch? match = standardUrlRegExB.firstMatch(url);
if (match != null) {
url =
'https://${Uri.parse(match.group(0)!).host}/packages/${Uri.parse(url).pathSegments.last}';
'https://${Uri.parse(match.group(0)!).host}/packages/${Uri.parse(url).pathSegments.where((s) => s.trim().isNotEmpty).last}';
}
RegExp standardUrlRegExA = RegExp(
'^https?://(www\\.)?${getSourceRegex(hosts)}/+packages/+[^/]+',

View File

@@ -81,6 +81,10 @@ class GitHub extends AppSource {
[
GeneratedFormSwitch('useLatestAssetDateAsReleaseDate',
label: tr('useLatestAssetDateAsReleaseDate'), defaultValue: false)
],
[
GeneratedFormSwitch('releaseTitleAsVersion',
label: tr('releaseTitleAsVersion'), defaultValue: false)
]
];
@@ -271,14 +275,15 @@ class GitHub extends AppSource {
}
}
List<MapEntry<String, String>> getReleaseAssetUrls(dynamic release) =>
findReleaseAssetUrls(dynamic release) =>
(release['assets'] as List<dynamic>?)?.map((e) {
var url = !e['name'].toString().toLowerCase().endsWith('.apk')
? (e['browser_download_url'] ?? e['url'])
: (e['url'] ?? e['browser_download_url']);
return (e['name'] != null) && (url != null)
e['final_url'] = (e['name'] != null) && (url != null)
? MapEntry(e['name'] as String, url as String)
: const MapEntry('', '');
return e;
}).toList() ??
[];
@@ -289,7 +294,9 @@ class GitHub extends AppSource {
? DateTime.parse(rel['commit']['created'])
: null;
DateTime? getNewestAssetDateFromRelease(dynamic rel) {
var t = (rel['assets'] as List<dynamic>?)
var allAssets = rel['assets'] as List<dynamic>?;
var filteredAssets = rel['filteredAssets'] as List<dynamic>?;
var t = (filteredAssets ?? allAssets)
?.map((e) {
return e?['updated_at'] != null
? DateTime.parse(e['updated_at'])
@@ -383,20 +390,41 @@ class GitHub extends AppSource {
.hasMatch(((releases[i]['body'] as String?) ?? '').trim())) {
continue;
}
var allAssetUrls = getReleaseAssetUrls(releases[i]);
List<MapEntry<String, String>> apkUrls = allAssetUrls
.where((element) => element.key.toLowerCase().endsWith('.apk'))
var allAssetsWithUrls = findReleaseAssetUrls(releases[i]);
List<MapEntry<String, String>> allAssetUrls = allAssetsWithUrls
.map((e) => e['final_url'] as MapEntry<String, String>)
.toList();
var apkAssetsWithUrls = allAssetsWithUrls
.where((element) =>
(element['final_url'] as MapEntry<String, String>)
.key
.toLowerCase()
.endsWith('.apk'))
.toList();
apkUrls = filterApks(apkUrls, additionalSettings['apkFilterRegEx'],
var filteredApkUrls = filterApks(
apkAssetsWithUrls
.map((e) => e['final_url'] as MapEntry<String, String>)
.toList(),
additionalSettings['apkFilterRegEx'],
additionalSettings['invertAPKFilter']);
if (apkUrls.isEmpty && additionalSettings['trackOnly'] != true) {
var filteredApks = apkAssetsWithUrls
.where((e) => filteredApkUrls
.where((e2) =>
e2.key == (e['final_url'] as MapEntry<String, String>).key)
.isNotEmpty)
.toList();
if (filteredApks.isEmpty && additionalSettings['trackOnly'] != true) {
continue;
}
targetRelease = releases[i];
targetRelease['apkUrls'] = apkUrls;
targetRelease['apkUrls'] = filteredApkUrls;
targetRelease['filteredAssets'] = filteredApks;
targetRelease['version'] =
targetRelease['tag_name'] ?? targetRelease['name'];
additionalSettings['releaseTitleAsVersion'] == true
? nameToFilter
: targetRelease['tag_name'] ?? targetRelease['name'];
if (targetRelease['tarball_url'] != null) {
allAssetUrls.add(MapEntry(
(targetRelease['version'] ?? 'source') + '.tar.gz',
@@ -414,6 +442,7 @@ class GitHub extends AppSource {
throw NoReleasesError();
}
String? version = targetRelease['version'];
DateTime? releaseDate = getReleaseDateFromRelease(
targetRelease, useLatestAssetDateAsReleaseDate);
if (version == null) {
@@ -472,7 +501,7 @@ class GitHub extends AppSource {
AppNames getAppNames(String standardUrl) {
String temp = standardUrl.substring(standardUrl.indexOf('://') + 3);
List<String> names = temp.substring(temp.indexOf('/') + 1).split('/');
return AppNames(names[0], names[1]);
return AppNames(names[0], names.sublist(1).join('/'));
}
Future<Map<String, List<String>>> searchCommon(

View File

@@ -54,7 +54,7 @@ class GitLab extends AppSource {
@override
String sourceSpecificStandardizeURL(String url, {bool forSelection = false}) {
RegExp standardUrlRegEx = RegExp(
'^https?://(www\\.)?${getSourceRegex(hosts)}/[^/]+/[^/]+',
'^https?://(www\\.)?${getSourceRegex(hosts)}/[^/]+(/[^/]+){1,20}',
caseSensitive: false);
RegExpMatch? match = standardUrlRegEx.firstMatch(url);
if (match == null) {
@@ -126,6 +126,8 @@ class GitLab extends AppSource {
) async {
// Prepare request params
var names = GitHub().getAppNames(standardUrl);
String projectUriComponent =
'${Uri.encodeComponent(names.author)}%2F${Uri.encodeComponent(names.name)}';
String? PAT = await getPATIfAny(hostChanged ? additionalSettings : {});
String optionalAuth = (PAT != null) ? 'private_token=$PAT' : '';
@@ -133,7 +135,7 @@ class GitLab extends AppSource {
// Get project ID
Response res0 = await sourceRequest(
'https://${hosts[0]}/api/v4/projects/${names.author}%2F${names.name}?$optionalAuth',
'https://${hosts[0]}/api/v4/projects/$projectUriComponent?$optionalAuth',
additionalSettings);
if (res0.statusCode != 200) {
throw getObtainiumHttpError(res0);
@@ -145,7 +147,7 @@ class GitLab extends AppSource {
// Request data from REST API
Response res = await sourceRequest(
'https://${hosts[0]}/api/v4/projects/${names.author}%2F${names.name}/${trackOnly ? 'repository/tags' : 'releases'}?$optionalAuth',
'https://${hosts[0]}/api/v4/projects/$projectUriComponent/${trackOnly ? 'repository/tags' : 'releases'}?$optionalAuth',
additionalSettings);
if (res.statusCode != 200) {
throw getObtainiumHttpError(res);
@@ -180,7 +182,7 @@ class GitLab extends AppSource {
return APKDetails(
e['tag_name'] ?? e['name'],
getApkUrlsFromUrls(apkUrlsSet.toList()),
GitHub().getAppNames(standardUrl),
AppNames(names.author, names.name.split('/').last),
releaseDate: releaseDate);
});
if (apkDetailsList.isEmpty) {

View File

@@ -7,6 +7,9 @@ import 'package:obtainium/providers/apps_provider.dart';
import 'package:obtainium/providers/source_provider.dart';
String ensureAbsoluteUrl(String ambiguousUrl, Uri referenceAbsoluteUrl) {
if (ambiguousUrl.startsWith('//')) {
ambiguousUrl = '${referenceAbsoluteUrl.scheme}:$ambiguousUrl';
}
try {
Uri.parse(ambiguousUrl).origin;
return ambiguousUrl;
@@ -18,7 +21,7 @@ String ensureAbsoluteUrl(String ambiguousUrl, Uri referenceAbsoluteUrl) {
.where((element) => element.trim().isNotEmpty)
.toList();
String absoluteUrl;
if (ambiguousUrl.startsWith('/') || currPathSegments.isEmpty) {
if (ambiguousUrl.startsWith('/')) {
absoluteUrl = '${referenceAbsoluteUrl.origin}$ambiguousUrl';
} else if (currPathSegments.isEmpty) {
absoluteUrl = '${referenceAbsoluteUrl.origin}/$ambiguousUrl';
@@ -353,7 +356,12 @@ class HTML extends AppSource {
forAPKDownload: true),
allowInsecure: additionalSettings['allowInsecure'] == true))
.toString();
return APKDetails(version, [rel].map((e) => MapEntry(e, e)).toList(),
return APKDetails(
version,
[rel]
.map((e) =>
MapEntry('${e.hashCode}-${Uri.parse(e).pathSegments.last}', e))
.toList(),
AppNames(uri.host, tr('app')));
}
}

View File

@@ -1,37 +0,0 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/source_provider.dart';
class Signal extends AppSource {
Signal() {
hosts = ['signal.org'];
}
@override
String sourceSpecificStandardizeURL(String url, {bool forSelection = false}) {
return 'https://${hosts[0]}';
}
@override
Future<APKDetails> getLatestAPKDetails(
String standardUrl,
Map<String, dynamic> additionalSettings,
) async {
Response res = await sourceRequest(
'https://updates.${hosts[0]}/android/latest.json', additionalSettings);
if (res.statusCode == 200) {
var json = jsonDecode(res.body);
String? apkUrl = json['url'];
List<String> apkUrls = apkUrl == null ? [] : [apkUrl];
String? version = json['versionName'];
if (version == null) {
throw NoVersionError();
}
return APKDetails(
version, getApkUrlsFromUrls(apkUrls), AppNames(name, 'Signal'));
} else {
throw getObtainiumHttpError(res);
}
}
}

View File

@@ -1,63 +0,0 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:html/parser.dart';
import 'package:http/http.dart';
import 'package:obtainium/components/generated_form.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/source_provider.dart';
class SteamMobile extends AppSource {
SteamMobile() {
hosts = ['store.steampowered.com'];
name = 'Steam';
additionalSourceAppSpecificSettingFormItems = [
[
GeneratedFormDropdown('app', apks.entries.toList(),
label: tr('app'), defaultValue: apks.entries.toList()[0].key)
]
];
}
final apks = {'steam': tr('steamMobile'), 'steam-chat-app': tr('steamChat')};
@override
String sourceSpecificStandardizeURL(String url, {bool forSelection = false}) {
return 'https://${hosts[0]}';
}
@override
Future<APKDetails> getLatestAPKDetails(
String standardUrl,
Map<String, dynamic> additionalSettings,
) async {
Response res =
await sourceRequest('https://${hosts[0]}/mobile', additionalSettings);
if (res.statusCode == 200) {
var apkNamePrefix = additionalSettings['app'] as String?;
if (apkNamePrefix == null) {
throw NoReleasesError();
}
String apkInURLRegexPattern =
'/$apkNamePrefix-([0-9]+\\.)*[0-9]+\\.apk\$';
var links = parse(res.body)
.querySelectorAll('a')
.map((e) => e.attributes['href'] ?? '')
.where((e) => RegExp('https://.*$apkInURLRegexPattern').hasMatch(e))
.toList();
if (links.isEmpty) {
throw NoReleasesError();
}
var versionMatch = RegExp(apkInURLRegexPattern).firstMatch(links[0]);
if (versionMatch == null) {
throw NoVersionError();
}
var version = links[0].substring(
versionMatch.start + apkNamePrefix.length + 2, versionMatch.end - 4);
var apkUrls = [links[0]];
return APKDetails(version, getApkUrlsFromUrls(apkUrls),
AppNames(name, apks[apkNamePrefix]!));
} else {
throw getObtainiumHttpError(res);
}
}
}

View File

@@ -33,7 +33,9 @@ class TelegramApp extends AppSource {
throw NoVersionError();
}
String? apkUrl = 'https://telegram.org/dl/android/apk';
return APKDetails(version, getApkUrlsFromUrls([apkUrl]),
return APKDetails(
version,
[MapEntry<String, String>('telegram-$version.apk', apkUrl)],
AppNames('Telegram', 'Telegram'));
} else {
throw getObtainiumHttpError(res);

View File

@@ -1,11 +1,12 @@
import 'dart:convert';
import 'package:easy_localization/easy_localization.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/source_provider.dart';
class Tencent extends AppSource {
Tencent() {
name = 'Tencent App Store';
name = tr('tencentAppStore');
hosts = ['sj.qq.com'];
naiveStandardVersionDetection = true;
showReleaseDateAsVersionToggle = true;

View File

@@ -42,19 +42,16 @@ class Uptodown extends AppSource {
String? version = html.querySelector('div.version')?.innerHtml;
String? name = html.querySelector('#detail-app-name')?.innerHtml.trim();
String? author = html.querySelector('#author-link')?.innerHtml.trim();
var detailElements = html.querySelectorAll('#technical-information td');
String? appId = (detailElements.elementAtOrNull(2))?.innerHtml.trim();
String? dateStr = (detailElements.elementAtOrNull(29))?.innerHtml.trim();
var detailElements = html
.querySelectorAll('#technical-information td')
.map((e) => e.innerHtml.trim())
.where((e) => !e.startsWith('<'))
.toList();
String? appId = detailElements.elementAtOrNull(0);
String? dateStr = detailElements.elementAtOrNull(6);
String? fileId =
html.querySelector('#detail-app-name')?.attributes['data-file-id'];
String? extension = html
.querySelectorAll('td')
.where((e) => e.text.toLowerCase().trim() == 'file type')
.firstOrNull
?.nextElementSibling
?.text
.toLowerCase()
.trim();
String? extension = detailElements.elementAtOrNull(7)?.toLowerCase();
return Map.fromEntries([
MapEntry('version', version),
MapEntry('appId', appId),

View File

@@ -1,110 +0,0 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:html/parser.dart';
import 'package:http/http.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/source_provider.dart';
class VLC extends AppSource {
VLC() {
hosts = ['videolan.org'];
}
get dwUrlBase => 'https://get.${hosts[0]}/vlc-android/';
@override
Future<Map<String, String>?> getRequestHeaders(
Map<String, dynamic> additionalSettings,
{bool forAPKDownload = false}) async {
return {
"User-Agent":
"Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36"
};
}
@override
String sourceSpecificStandardizeURL(String url, {bool forSelection = false}) {
return 'https://${hosts[0]}';
}
Future<String?> getLatestVersion(
String standardUrl, Map<String, dynamic> additionalSettings) async {
Response res = await sourceRequest(dwUrlBase, additionalSettings);
if (res.statusCode == 200) {
var dwLinks = parse(res.body)
.querySelectorAll('a')
.where((element) => element.attributes['href'] != 'last/')
.map((e) => e.attributes['href']?.split('/')[0])
.toList();
String? version = dwLinks.isNotEmpty ? dwLinks.last : null;
if (version == null) {
throw NoVersionError();
}
return version;
} else {
throw getObtainiumHttpError(res);
}
}
@override
Future<APKDetails> getLatestAPKDetails(
String standardUrl,
Map<String, dynamic> additionalSettings,
) async {
Response res = await get(
Uri.parse('https://www.videolan.org/vlc/download-android.html'));
if (res.statusCode == 200) {
var dwUrlBase = 'get.videolan.org/vlc-android';
var dwLinks = parse(res.body)
.querySelectorAll('a')
.where((element) =>
element.attributes['href']?.contains(dwUrlBase) ?? false)
.toList();
String? version = dwLinks.isNotEmpty
? dwLinks.first.attributes['href']
?.split('/')
.where((s) => s.isNotEmpty)
.last
: null;
if (version == null) {
throw NoVersionError();
}
String? targetUrl = 'https://$dwUrlBase/$version/';
var apkUrls = ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']
.map((e) => '${targetUrl}VLC-Android-$version-$e.apk')
.toList();
return APKDetails(
version, getApkUrlsFromUrls(apkUrls), AppNames('VideoLAN', 'VLC'));
} else {
throw getObtainiumHttpError(res);
}
}
@override
Future<String> apkUrlPrefetchModifier(String apkUrl, String standardUrl,
Map<String, dynamic> additionalSettings) async {
Response res = await sourceRequest(apkUrl, additionalSettings);
if (res.statusCode == 200) {
String? apkUrl =
parse(res.body).querySelector('#alt_link')?.attributes['href'];
if (apkUrl == null) {
throw NoAPKError();
}
return apkUrl;
} else if (res.statusCode == 500 &&
res.body.toLowerCase().indexOf('mirror') > 0) {
var html = parse(res.body);
var err = '';
html.body?.nodes.forEach((element) {
if (element.text != null) {
err += '${element.text}\n';
}
});
err = err.trim();
if (err.isEmpty) {
err = tr('err');
}
throw ObtainiumError(err);
} else {
throw getObtainiumHttpError(res);
}
}
}

View File

@@ -1,55 +0,0 @@
import 'package:html/parser.dart';
import 'package:http/http.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/source_provider.dart';
class WhatsApp extends AppSource {
WhatsApp() {
hosts = ['whatsapp.com'];
versionDetectionDisallowed = true;
}
@override
String sourceSpecificStandardizeURL(String url, {bool forSelection = false}) {
return 'https://${hosts[0]}';
}
@override
Future<String> apkUrlPrefetchModifier(String apkUrl, String standardUrl,
Map<String, dynamic> additionalSettings) async {
Response res =
await sourceRequest('$standardUrl/android', additionalSettings);
if (res.statusCode == 200) {
var targetLinks = parse(res.body)
.querySelectorAll('a')
.map((e) => e.attributes['href'] ?? '')
.where((e) => e.isNotEmpty)
.where((e) => e.contains('WhatsApp.apk'))
.toList();
if (targetLinks.isEmpty) {
throw NoAPKError();
}
return targetLinks[0];
} else {
throw getObtainiumHttpError(res);
}
}
@override
Future<APKDetails> getLatestAPKDetails(
String standardUrl,
Map<String, dynamic> additionalSettings,
) async {
// This is a CDN link that is consistent per version
// But it has query params that change constantly
Uri apkUri = Uri.parse(await apkUrlPrefetchModifier(
standardUrl, standardUrl, additionalSettings));
var unusableApkUrl = '${apkUri.origin}/${apkUri.path}';
// So we use the param-less URL is a pseudo-version to add the app and check for updates
// See #357 for why we can't scrape the version number directly
// But we re-fetch the URL again with its latest query params at the actual download time
String version = unusableApkUrl.hashCode.toString();
return APKDetails(version, getApkUrlsFromUrls([unusableApkUrl]),
AppNames('Meta', 'WhatsApp'));
}
}

View File

@@ -44,7 +44,8 @@ List<MapEntry<Locale, String>> supportedLocales = const [
MapEntry(Locale('da'), 'Dansk'),
MapEntry(Locale('en', 'EO'),
'Esperanto'), // https://github.com/aissat/easy_localization/issues/220#issuecomment-846035493
MapEntry(Locale('in'), 'Bahasa Indonesia')
MapEntry(Locale('in'), 'Bahasa Indonesia'),
MapEntry(Locale('ko'), '한국어'),
];
const fallbackLocale = Locale('en');
const localeDir = 'assets/translations';
@@ -244,6 +245,7 @@ class _ObtainiumState extends State<Obtainium> {
supportedLocales: context.supportedLocales,
locale: context.locale,
navigatorKey: globalNavigatorKey,
debugShowCheckedModeBanner: false,
theme: ThemeData(
useMaterial3: true,
colorScheme: settingsProvider.theme == ThemeSettings.dark

View File

@@ -30,6 +30,7 @@ class AddAppPageState extends State<AddAppPage> {
String userInput = '';
String searchQuery = '';
String? pickedSourceOverride;
String? previousPickedSourceOverride;
AppSource? pickedSource;
Map<String, dynamic> additionalSettings = {};
bool additionalSettingsValid = true;
@@ -58,6 +59,9 @@ class AddAppPageState extends State<AddAppPage> {
if (overrideSource != null) {
pickedSourceOverride = overrideSource;
}
bool overrideChanged =
pickedSourceOverride != previousPickedSourceOverride;
previousPickedSourceOverride = pickedSourceOverride;
if (updateUrlInput) {
urlInputKey++;
}
@@ -69,6 +73,7 @@ class AddAppPageState extends State<AddAppPage> {
overrideSource: pickedSourceOverride)
: null;
if (pickedSource.runtimeType != source.runtimeType ||
overrideChanged ||
(prevHost != null && prevHost != source?.hosts[0])) {
pickedSource = source;
pickedSource?.runOnAddAppInputChange(userInput);
@@ -487,7 +492,8 @@ class AddAppPageState extends State<AddAppPage> {
height: 16,
),
GeneratedForm(
key: Key(pickedSource.runtimeType.toString()),
key: Key(
'${pickedSource.runtimeType.toString()}-${pickedSource?.hostChanged.toString()}-${pickedSource?.hostIdenticalDespiteAnyChange.toString()}'),
items: [
...pickedSource!.combinedAppSpecificSettingFormItems,
...(pickedSourceOverride != null
@@ -532,12 +538,45 @@ class AddAppPageState extends State<AddAppPage> {
});
}
}),
if (pickedSource != null && pickedSource!.enforceTrackOnly)
GeneratedForm(
key: Key(
'${pickedSource.runtimeType.toString()}-${pickedSource?.hostChanged.toString()}-${pickedSource?.hostIdenticalDespiteAnyChange.toString()}-appId'),
items: [
[
GeneratedFormTextField('appId',
label: '${tr('appId')} - ${tr('custom')}',
required: false,
additionalValidators: [
(value) {
if (value == null || value.isEmpty) {
return null;
}
final isValid = RegExp(
r'^([A-Za-z]{1}[A-Za-z\d_]*\.)+[A-Za-z][A-Za-z\d_]*$')
.hasMatch(value);
if (!isValid) {
return tr('invalidInput');
}
return null;
}
]),
]
],
onValueChanges: (values, valid, isBuilding) {
if (!isBuilding) {
setState(() {
additionalSettings['appId'] = values['appId'];
});
}
}),
],
);
Widget getSourcesListWidget() => Padding(
padding: const EdgeInsets.all(16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
onTap: () {
@@ -594,7 +633,20 @@ class AddAppPageState extends State<AddAppPage> {
fontWeight: FontWeight.bold,
decoration: TextDecoration.underline,
fontStyle: FontStyle.italic),
))
)),
GestureDetector(
onTap: () {
launchUrlString('https://apps.obtainium.imranr.dev/',
mode: LaunchMode.externalApplication);
},
child: Text(
tr('crowdsourcedConfigsShort'),
style: const TextStyle(
fontWeight: FontWeight.bold,
decoration: TextDecoration.underline,
fontStyle: FontStyle.italic),
),
),
],
),
);

View File

@@ -182,7 +182,10 @@ class _AppPageState extends State<AppPage> {
Brightness.light
? Theme.of(context).primaryColor
: Theme.of(context).primaryColorLight)
.withAlpha(20)
.withAlpha(Theme.of(context).brightness ==
Brightness.light
? 20
: 40)
: null),
padding: settingsProvider.highlightTouchTargets
? const EdgeInsetsDirectional.fromSTEB(12, 6, 12, 6)
@@ -242,11 +245,11 @@ class _AppPageState extends State<AppPage> {
);
}
getFullInfoColumn() => Column(
getFullInfoColumn({bool small = false}) => Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 20),
SizedBox(height: small ? 5 : 20),
FutureBuilder(
future:
appsProvider.updateAppIcon(app?.app.id, ignoreCache: true),
@@ -261,24 +264,28 @@ class _AppPageState extends State<AppPage> {
: () => pm.openApp(app.app.id),
child: Image.memory(
app!.icon!,
height: 150,
height: small ? 70 : 150,
gaplessPlayback: true,
),
)
])
: Container();
}),
const SizedBox(
height: 25,
SizedBox(
height: small ? 10 : 25,
),
Text(
app?.name ?? tr('app'),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.displayLarge,
style: small
? Theme.of(context).textTheme.displaySmall
: Theme.of(context).textTheme.displayLarge,
),
Text(tr('byX', args: [app?.app.author ?? tr('unknown')]),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headlineMedium),
style: small
? Theme.of(context).textTheme.headlineSmall
: Theme.of(context).textTheme.headlineMedium),
const SizedBox(
height: 24,
),
@@ -496,11 +503,8 @@ class _AppPageState extends State<AppPage> {
builder: (BuildContext ctx) {
return AlertDialog(
scrollable: true,
content: getInfoColumn(),
title: Text(
'${app.name} ${tr('byX', args: [
app.app.author
])}'),
content: getFullInfoColumn(small: true),
title: Text(app.name),
actions: [
TextButton(
onPressed: () {

View File

@@ -60,6 +60,9 @@ showChangeLogDialog(BuildContext context, App app, String? changesUrl,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height - 350,
child: Markdown(
styleSheet: MarkdownStyleSheet(
blockquoteDecoration: BoxDecoration(
color: Theme.of(context).cardColor)),
data: changeLog,
onTapLink: (text, href, title) {
if (href != null) {
@@ -481,7 +484,10 @@ class AppsPageState extends State<AppsPage> {
? (Theme.of(context).brightness == Brightness.light
? Theme.of(context).primaryColor
: Theme.of(context).primaryColorLight)
.withAlpha(20)
.withAlpha(Theme.of(context).brightness ==
Brightness.light
? 20
: 40)
: null),
padding: settingsProvider.highlightTouchTargets
? const EdgeInsetsDirectional.fromSTEB(12, 0, 12, 0)
@@ -521,12 +527,12 @@ class AppsPageState extends State<AppsPage> {
var transparent =
Theme.of(context).colorScheme.surface.withAlpha(0).value;
List<double> stops = [
...listedApps[index].app.categories.asMap().entries.map(
(e) => ((e.key / (listedApps[index].app.categories.length - 1)))),
...listedApps[index].app.categories.asMap().entries.map((e) =>
((e.key / (listedApps[index].app.categories.length - 1)) - 0.0001)),
1
];
if (stops.length == 2) {
stops[0] = 1;
stops[0] = 0.9999;
}
return Container(
decoration: BoxDecoration(
@@ -838,30 +844,6 @@ class AppsPageState extends State<AppsPage> {
Navigator.of(context).pop();
}
resetSelectedAppsInstallStatuses() async {
try {
var values = await showDialog(
context: context,
builder: (BuildContext ctx) {
return GeneratedFormModal(
title: tr('resetInstallStatusForSelectedAppsQuestion'),
items: const [],
initValid: true,
message: tr('installStatusOfXWillBeResetExplanation',
args: [plural('apps', selectedAppIds.length)]),
);
});
if (values != null) {
appsProvider.saveApps(selectedApps.map((e) {
e.installedVersion = null;
return e;
}).toList());
}
} finally {
Navigator.of(context).pop();
}
}
showMoreOptionsDialog() {
return showDialog(
context: context,

View File

@@ -130,13 +130,18 @@ class _HomePageState extends State<HomePage> {
// Check initial link if app was in cold state (terminated)
final appLink = await _appLinks.getInitialLink();
var initLinked = false;
if (appLink != null) {
await interpretLink(appLink);
initLinked = true;
}
// Handle link when app is in warm state (front or background)
_linkSubscription = _appLinks.uriLinkStream.listen((uri) async {
await interpretLink(uri);
if (!initLinked) {
await interpretLink(uri);
} else {
initLinked = false;
}
});
}

View File

@@ -419,6 +419,25 @@ class _SettingsPageState extends State<SettingsPage> {
})
],
),
height16,
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Flexible(
child: Text(tr(
'bgUpdatesWhileChargingOnly'))),
Switch(
value: settingsProvider
.bgUpdatesWhileChargingOnly,
onChanged: (value) {
settingsProvider
.bgUpdatesWhileChargingOnly =
value;
})
],
),
],
),
],
@@ -578,6 +597,22 @@ class _SettingsPageState extends State<SettingsPage> {
})
],
),
height16,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Text(
tr('shizukuPretendToBeGooglePlay'))),
Switch(
value: settingsProvider
.shizukuPretendToBeGooglePlay,
onChanged: (value) {
settingsProvider
.shizukuPretendToBeGooglePlay = value;
})
],
),
height32,
Text(
tr('sourceSpecific'),
@@ -851,7 +886,7 @@ class _SettingsPageState extends State<SettingsPage> {
),
IconButton(
onPressed: () {
launchUrlString('${settingsProvider.sourceUrl}/wiki',
launchUrlString('https://wiki.obtainium.imranr.dev/',
mode: LaunchMode.externalApplication);
},
icon: const Icon(Icons.help_outline_rounded),

View File

@@ -5,6 +5,7 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:battery_plus/battery_plus.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
import 'package:crypto/crypto.dart';
@@ -18,6 +19,8 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/io_client.dart';
import 'package:obtainium/app_sources/directAPKLink.dart';
import 'package:obtainium/app_sources/html.dart';
import 'package:obtainium/components/generated_form.dart';
import 'package:obtainium/components/generated_form_modal.dart';
import 'package:obtainium/custom_errors.dart';
@@ -148,13 +151,15 @@ Future<File> downloadFileWithRetry(String url, String fileName,
{bool useExisting = true,
Map<String, String>? headers,
int retries = 3,
bool allowInsecure = false}) async {
bool allowInsecure = false,
LogsProvider? logs}) async {
try {
return await downloadFile(
url, fileName, fileNameHasExt, onProgress, destDir,
useExisting: useExisting,
headers: headers,
allowInsecure: allowInsecure);
allowInsecure: allowInsecure,
logs: logs);
} catch (e) {
if (retries > 0 && e is ClientException) {
await Future.delayed(const Duration(seconds: 5));
@@ -163,7 +168,8 @@ Future<File> downloadFileWithRetry(String url, String fileName,
useExisting: useExisting,
headers: headers,
retries: (retries - 1),
allowInsecure: allowInsecure);
allowInsecure: allowInsecure,
logs: logs);
} else {
rethrow;
}
@@ -216,7 +222,8 @@ Future<File> downloadFile(String url, String fileName, bool fileNameHasExt,
Function? onProgress, String destDir,
{bool useExisting = true,
Map<String, String>? headers,
bool allowInsecure = false}) async {
bool allowInsecure = false,
LogsProvider? logs}) async {
// Send the initial request but cancel it as soon as you have the headers
var reqHeaders = headers ?? {};
var req = Request('GET', Uri.parse(url));
@@ -277,6 +284,42 @@ Future<File> downloadFile(String url, String fileName, bool fileNameHasExt,
// Download to a '.temp' file (to distinguish btn. complete/incomplete files)
File tempDownloadedFile = File('${downloadedFile.path}.part');
// If there is already a temp file, a download may already be in progress - account for this (see #2073)
bool tempFileExists = tempDownloadedFile.existsSync();
if (tempFileExists && useExisting) {
logs?.add(
'Partial download exists - will wait: ${tempDownloadedFile.uri.pathSegments.last}');
bool isDownloading = true;
int currentTempFileSize = await tempDownloadedFile.length();
bool shouldReturn = false;
while (isDownloading) {
await Future.delayed(Duration(seconds: 7));
if (tempDownloadedFile.existsSync()) {
int newTempFileSize = await tempDownloadedFile.length();
if (newTempFileSize > currentTempFileSize) {
currentTempFileSize = newTempFileSize;
logs?.add(
'Existing partial download still in progress: ${tempDownloadedFile.uri.pathSegments.last}');
} else {
logs?.add(
'Ignoring existing partial download: ${tempDownloadedFile.uri.pathSegments.last}');
break;
}
} else {
shouldReturn = downloadedFile.existsSync();
}
}
if (shouldReturn) {
logs?.add(
'Existing partial download completed - not repeating: ${tempDownloadedFile.uri.pathSegments.last}');
client.close();
return downloadedFile;
} else {
logs?.add(
'Existing partial download not in progress: ${tempDownloadedFile.uri.pathSegments.last}');
}
}
// If the range feature is not available (or you need to start a ranged req from 0),
// complete the already-started request, else cancel it and start a ranged request,
// and open the file for writing in the appropriate mode
@@ -416,9 +459,7 @@ class AppsProvider with ChangeNotifier {
// Delete any partial APKs (if safe to do so)
var cutoff = DateTime.now().subtract(const Duration(days: 7));
APKDir.listSync()
.where((element) =>
element.path.endsWith('.part') ||
element.statSync().modified.isBefore(cutoff))
.where((element) => element.statSync().modified.isBefore(cutoff))
.forEach((partialApk) {
if (!areDownloadsRunning()) {
partialApk.delete(recursive: true);
@@ -492,7 +533,8 @@ class AppsProvider with ChangeNotifier {
prevProg = prog;
}, APKDir.path,
useExisting: useExisting,
allowInsecure: app.additionalSettings['allowInsecure'] == true);
allowInsecure: app.additionalSettings['allowInsecure'] == true,
logs: logs);
// Set to 90 for remaining steps, will make null in 'finally'
if (apps[app.id] != null) {
apps[app.id]!.downloadProgress = -1;
@@ -515,11 +557,29 @@ class AppsProvider with ChangeNotifier {
.listSync()
.where((e) => e.path.toLowerCase().endsWith('.apk'))
.toList();
FileSystemEntity? temp;
apks.removeWhere((element) {
bool res = element.uri.pathSegments.last.startsWith(app.id);
if (res) {
temp = element;
}
return res;
});
if (temp != null) {
apks = [
temp!,
...apks,
];
}
for (var i = 0; i < apks.length; i++) {
try {
newInfo = await pm.getPackageArchiveInfo(
archiveFilePath: apks.first.path);
break;
newInfo =
await pm.getPackageArchiveInfo(archiveFilePath: apks[i].path);
if (newInfo != null) {
break;
}
} catch (e) {
if (i == apks.length - 1) {
rethrow;
@@ -565,9 +625,11 @@ class AppsProvider with ChangeNotifier {
return false;
}
if (app.additionalSettings['exemptFromBackgroundUpdates'] == true) {
logs.add('Exempted from BG updates: ${app.id}');
return false;
}
if (app.apkUrls.length > 1) {
logs.add('Multiple APK URLs: ${app.id}');
return false; // Manual API selection means silent install is not possible
}
@@ -579,6 +641,8 @@ class AppsProvider with ChangeNotifier {
?.installingPackageName
: (await pm.getInstallerPackageName(packageName: app.id));
} catch (e) {
logs.add(
'Failed to get installed package details: ${app.id} (${e.toString()})');
return false; // App probably not installed
}
@@ -587,6 +651,7 @@ class AppsProvider with ChangeNotifier {
// The APK should target a new enough API
// https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionParams#setRequireUserAction(int)
if (!(targetSDK != null && targetSDK >= (osInfo.version.sdkInt - 3))) {
logs.add('Multiple APK URLs: ${app.id}');
return false;
}
@@ -601,8 +666,12 @@ class AppsProvider with ChangeNotifier {
// If we did not install the app, silent install is not possible
return false;
}
// The OS must also be new enough
return osInfo.version.sdkInt >= 31;
if (osInfo.version.sdkInt < 31) {
// The OS must also be new enough
logs.add('Android SDK too old: ${osInfo.version.sdkInt}');
return false;
}
return true;
}
Future<void> waitForUserToReturnToForeground(BuildContext context) async {
@@ -634,28 +703,47 @@ class AppsProvider with ChangeNotifier {
var somethingInstalled = false;
try {
MultiAppMultiError errors = MultiAppMultiError();
List<File> APKFiles = [];
for (var file in dir.extracted
.listSync(recursive: true, followLinks: false)
.whereType<File>()) {
if (file.path.toLowerCase().endsWith('.apk')) {
try {
somethingInstalled = somethingInstalled ||
await installApk(
DownloadedApk(dir.appId, file), firstTimeWithContext,
needsBGWorkaround: needsBGWorkaround,
shizukuPretendToBeGooglePlay: shizukuPretendToBeGooglePlay);
} catch (e) {
logs.add(
'Could not install APK from XAPK \'${file.path}\': ${e.toString()}');
errors.add(dir.appId, e, appName: apps[dir.appId]?.name);
}
APKFiles.add(file);
} else if (file.path.toLowerCase().endsWith('.obb')) {
await moveObbFile(file, dir.appId);
}
}
if (somethingInstalled) {
File? temp;
APKFiles.removeWhere((element) {
bool res = element.uri.pathSegments.last.startsWith(dir.appId);
if (res) {
temp = element;
}
return res;
});
if (temp != null) {
APKFiles = [
temp!,
...APKFiles,
];
}
try {
await installApk(
DownloadedApk(dir.appId, APKFiles[0]), firstTimeWithContext,
needsBGWorkaround: needsBGWorkaround,
shizukuPretendToBeGooglePlay: shizukuPretendToBeGooglePlay,
additionalAPKs: APKFiles.sublist(1)
.map((a) => DownloadedApk(dir.appId, a))
.toList());
somethingInstalled = true;
dir.file.delete(recursive: true);
} else if (errors.idsByErrorString.isNotEmpty) {
} catch (e) {
logs.add('Could not install APKs from XAPK: ${e.toString()}');
errors.add(dir.appId, e, appName: apps[dir.appId]?.name);
}
if (errors.idsByErrorString.isNotEmpty) {
throw errors;
}
} finally {
@@ -667,7 +755,8 @@ class AppsProvider with ChangeNotifier {
Future<bool> installApk(
DownloadedApk file, BuildContext? firstTimeWithContext,
{bool needsBGWorkaround = false,
bool shizukuPretendToBeGooglePlay = false}) async {
bool shizukuPretendToBeGooglePlay = false,
List<DownloadedApk> additionalAPKs = const []}) async {
if (firstTimeWithContext != null &&
settingsProvider.beforeNewInstallsShareToAppVerifier &&
(await getInstalledInfo('dev.soupslurpr.appverifier')) != null) {
@@ -683,6 +772,7 @@ class AppsProvider with ChangeNotifier {
if (newInfo == null) {
try {
file.file.deleteSync(recursive: true);
additionalAPKs.forEach((a) => a.file.deleteSync(recursive: true));
} catch (e) {
//
} finally {
@@ -690,6 +780,8 @@ class AppsProvider with ChangeNotifier {
}
}
PackageInfo? appInfo = await getInstalledInfo(apps[file.appId]!.app.id);
logs.add(
'Installing "${newInfo.packageName}" version "${newInfo.versionName}" versionCode "${newInfo.versionCode}"${appInfo != null ? ' (from existing version "${appInfo.versionName}" versionCode "${appInfo.versionCode}")' : ''}');
if (appInfo != null &&
newInfo.versionCode! < appInfo.versionCode! &&
!(await canDowngradeApps())) {
@@ -708,8 +800,10 @@ class AppsProvider with ChangeNotifier {
}
int? code;
if (!settingsProvider.useShizuku) {
code =
await AndroidPackageInstaller.installApk(apkFilePath: file.file.path);
var allAPKs = [file.file.path];
allAPKs.addAll(additionalAPKs.map((a) => a.file.path));
code = await AndroidPackageInstaller.installApk(
apkFilePath: allAPKs.join(','));
} else {
code = await ShizukuApkInstaller.installAPK(file.file.uri.toString(),
shizukuPretendToBeGooglePlay ? "com.android.vending" : "");
@@ -733,6 +827,10 @@ class AppsProvider with ChangeNotifier {
return installed;
}
Future<String> getStorageRootPath() async {
return '/${(await getExternalStorageDirectory())!.uri.pathSegments.sublist(0, 3).join('/')}';
}
Future<void> moveObbFile(File file, String appId) async {
if (!file.path.toLowerCase().endsWith('.obb')) return;
@@ -741,7 +839,7 @@ class AppsProvider with ChangeNotifier {
await Permission.storage.request();
}
String obbDirPath = "/storage/emulated/0/Android/obb/$appId";
String obbDirPath = "${await getStorageRootPath()}/Android/obb/$appId";
Directory(obbDirPath).createSync(recursive: true);
String obbFileName = file.path.split("/").last;
@@ -831,6 +929,11 @@ class AppsProvider with ChangeNotifier {
}
MapEntry<String, String>? apkUrl;
var trackOnly = apps[id]!.app.additionalSettings['trackOnly'] == true;
var refreshBeforeDownload =
apps[id]!.app.additionalSettings['refreshBeforeDownload'] == true;
if (refreshBeforeDownload) {
await checkUpdate(apps[id]!.app.id);
}
if (!trackOnly) {
// ignore: use_build_context_synchronously
apkUrl = await confirmAppFileUrl(apps[id]!.app, context, false);
@@ -879,22 +982,20 @@ class AppsProvider with ChangeNotifier {
apps[id]?.installedInfo == null ? context : null;
bool needBGWorkaround =
willBeSilent && context == null && !settingsProvider.useShizuku;
bool shizukuPretendToBeGooglePlay = settingsProvider
.shizukuPretendToBeGooglePlay ||
apps[id]!.app.additionalSettings['shizukuPretendToBeGooglePlay'] ==
true;
if (downloadedFile != null) {
if (needBGWorkaround) {
// ignore: use_build_context_synchronously
installApk(downloadedFile, contextIfNewInstall,
needsBGWorkaround: true,
shizukuPretendToBeGooglePlay: apps[id]!
.app
.additionalSettings['shizukuPretendToBeGooglePlay'] ==
true);
shizukuPretendToBeGooglePlay: shizukuPretendToBeGooglePlay);
} else {
// ignore: use_build_context_synchronously
sayInstalled = await installApk(downloadedFile, contextIfNewInstall,
shizukuPretendToBeGooglePlay: apps[id]!
.app
.additionalSettings['shizukuPretendToBeGooglePlay'] ==
true);
shizukuPretendToBeGooglePlay: shizukuPretendToBeGooglePlay);
}
} else {
if (needBGWorkaround) {
@@ -905,10 +1006,7 @@ class AppsProvider with ChangeNotifier {
// ignore: use_build_context_synchronously
sayInstalled = await installXApkDir(
downloadedDir!, contextIfNewInstall,
shizukuPretendToBeGooglePlay: apps[id]!
.app
.additionalSettings['shizukuPretendToBeGooglePlay'] ==
true);
shizukuPretendToBeGooglePlay: shizukuPretendToBeGooglePlay);
}
}
if (willBeSilent && context == null) {
@@ -1022,11 +1120,25 @@ class AppsProvider with ChangeNotifier {
throw ObtainiumError(tr('appNotFound'));
}
MapEntry<String, String>? fileUrl;
var refreshBeforeDownload =
apps[id]!.app.additionalSettings['refreshBeforeDownload'] == true;
if (refreshBeforeDownload) {
await checkUpdate(apps[id]!.app.id);
}
if (apps[id]!.app.apkUrls.isNotEmpty ||
apps[id]!.app.otherAssetUrls.isNotEmpty) {
// ignore: use_build_context_synchronously
fileUrl = await confirmAppFileUrl(apps[id]!.app, context, true,
MapEntry<String, String>? tempFileUrl = await confirmAppFileUrl(
apps[id]!.app, context, true,
evenIfSingleChoice: true);
if (tempFileUrl != null) {
fileUrl = MapEntry(
tempFileUrl.key,
await (SourceProvider().getSource(apps[id]!.app.url,
overrideSource: apps[id]!.app.overrideSource))
.apkUrlPrefetchModifier(tempFileUrl.value, apps[id]!.app.url,
apps[id]!.app.additionalSettings));
}
}
if (fileUrl != null) {
filesToDownload.add(MapEntry(fileUrl, apps[id]!.app));
@@ -1039,17 +1151,7 @@ class AppsProvider with ChangeNotifier {
Future<void> downloadFn(MapEntry<String, String> fileUrl, App app) async {
try {
var exportDir = await settingsProvider.getExportDir();
String downloadPath = '/storage/emulated/0/Download';
bool downloadsAccessible = false;
try {
downloadsAccessible = Directory(downloadPath).existsSync();
} catch (e) {
//
}
if (!downloadsAccessible && exportDir != null) {
downloadPath = exportDir.path;
}
String downloadPath = '${await getStorageRootPath()}/Download';
await downloadFile(fileUrl.value, fileUrl.key, true,
(double? progress) {
notificationsProvider
@@ -1061,7 +1163,8 @@ class AppsProvider with ChangeNotifier {
forAPKDownload:
fileUrl.key.endsWith('.apk') ? true : false),
useExisting: false,
allowInsecure: app.additionalSettings['allowInsecure'] == true);
allowInsecure: app.additionalSettings['allowInsecure'] == true,
logs: logs);
notificationsProvider
.notify(DownloadedNotification(fileUrl.key, fileUrl.value));
} catch (e) {
@@ -1098,17 +1201,25 @@ class AppsProvider with ChangeNotifier {
if (app?.app == null) {
return false;
}
var source = SourceProvider()
.getSource(app!.app.url, overrideSource: app.app.overrideSource);
var naiveStandardVersionDetection =
app!.app.additionalSettings['naiveStandardVersionDetection'] == true ||
SourceProvider()
.getSource(app.app.url, overrideSource: app.app.overrideSource)
.naiveStandardVersionDetection;
app.app.additionalSettings['naiveStandardVersionDetection'] == true ||
source.naiveStandardVersionDetection;
String? realInstalledVersion =
app.app.additionalSettings['useVersionCodeAsOSVersion'] == true
? app.installedInfo?.versionCode.toString()
: app.installedInfo?.versionName;
bool isHTMLWithNoVersionDetection =
(source.runtimeType == HTML().runtimeType &&
(app.app.additionalSettings['versionExtractionRegEx'] as String?)
?.isNotEmpty !=
true);
bool isDirectAPKLink = source.runtimeType == DirectAPKLink().runtimeType;
return app.app.additionalSettings['trackOnly'] != true &&
app.app.additionalSettings['releaseDateAsVersion'] != true &&
!isHTMLWithNoVersionDetection &&
!isDirectAPKLink &&
realInstalledVersion != null &&
app.app.installedVersion != null &&
(reconcileVersionDifferences(
@@ -1179,6 +1290,7 @@ class AppsProvider with ChangeNotifier {
!isVersionDetectionPossible(
AppInMemory(app, null, installedInfo, null))) {
app.additionalSettings['versionDetection'] = false;
app.installedVersion = app.latestVersion;
logs.add('Could not reconcile version formats for: ${app.id}');
modded = true;
}
@@ -1342,8 +1454,10 @@ class AppsProvider with ChangeNotifier {
app = getCorrectedInstallStatusAppIfPossible(app, info) ?? app;
}
if (!onlyIfExists || this.apps.containsKey(app.id)) {
File('${(await getAppsDir()).path}/${app.id}.json')
.writeAsStringSync(jsonEncode(app.toJson()));
String filePath = '${(await getAppsDir()).path}/${app.id}.json';
File('$filePath.tmp')
.writeAsStringSync(jsonEncode(app.toJson())); // #2089
File('$filePath.tmp').renameSync(filePath);
}
try {
this.apps.update(app.id,
@@ -1881,10 +1995,20 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
(<List<MapEntry<String, int>>>[]))
];
var networkRestricted = false;
if (appsProvider.settingsProvider.bgUpdatesOnWiFiOnly) {
networkRestricted = !netResult.contains(ConnectivityResult.wifi) &&
!netResult.contains(ConnectivityResult.ethernet);
var networkRestricted = appsProvider.settingsProvider.bgUpdatesOnWiFiOnly &&
!netResult.contains(ConnectivityResult.wifi) &&
!netResult.contains(ConnectivityResult.ethernet);
var chargingRestricted =
appsProvider.settingsProvider.bgUpdatesWhileChargingOnly &&
(await Battery().batteryState) != BatteryState.charging;
if (networkRestricted) {
logs.add('BG update task: Network restriction in effect.');
}
if (chargingRestricted) {
logs.add('BG update task: Charging restriction in effect.');
}
if (toCheck.isNotEmpty) {
@@ -1924,14 +2048,6 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
CheckingUpdatesNotification notif = CheckingUpdatesNotification(
plural('apps', toCheck.length)); // The notif. to show while checking
// Set a bool for when we're no on wifi/wired and the user doesn't want to download apps in that state
var networkRestricted = false;
if (appsProvider.settingsProvider.bgUpdatesOnWiFiOnly) {
var netResult = await (Connectivity().checkConnectivity());
networkRestricted = !netResult.contains(ConnectivityResult.wifi) &&
!netResult.contains(ConnectivityResult.ethernet);
}
try {
// Check for updates
notificationsProvider.notify(notif, cancelExisting: true);
@@ -1979,6 +2095,7 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
// Filter out updates that will be installed silently (the rest go into toNotify)
for (var i = 0; i < updates.length; i++) {
if (networkRestricted ||
chargingRestricted ||
!(await appsProvider.canInstallSilently(updates[i]))) {
if (updates[i].additionalSettings['skipUpdateNotifications'] != true) {
toNotify.add(updates[i]);
@@ -2025,7 +2142,7 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
} else {
// In install mode...
// If you haven't explicitly been given updates to install, grab all available silent updates
if (toInstall.isEmpty && !networkRestricted) {
if (toInstall.isEmpty && !networkRestricted && !chargingRestricted) {
var temp = appsProvider.findExistingUpdates(installedOnly: true);
for (var i = 0; i < temp.length; i++) {
if (await appsProvider

View File

@@ -3,6 +3,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:obtainium/providers/settings_provider.dart';
import 'package:obtainium/providers/source_provider.dart';
class ObtainiumNotification {
@@ -44,23 +45,19 @@ class SilentUpdateNotification extends ObtainiumNotification {
SilentUpdateNotification(List<App> updates, bool succeeded, {int? id})
: super(
id ?? 3,
succeeded
? tr('appsUpdated')
: tr('appsNotUpdated'),
succeeded ? tr('appsUpdated') : tr('appsNotUpdated'),
'',
'APPS_UPDATED',
tr('appsUpdatedNotifChannel'),
tr('appsUpdatedNotifDescription'),
Importance.defaultImportance) {
message = updates.length == 1
? tr(succeeded
? 'xWasUpdatedToY'
: 'xWasNotUpdatedToY',
args: [updates[0].finalName, updates[0].latestVersion])
: plural(succeeded
? 'xAndNMoreUpdatesInstalled'
: "xAndNMoreUpdatesFailed",
updates.length - 1, args: [updates[0].finalName, (updates.length - 1).toString()]);
? tr(succeeded ? 'xWasUpdatedToY' : 'xWasNotUpdatedToY',
args: [updates[0].finalName, updates[0].latestVersion])
: plural(
succeeded ? 'xAndNMoreUpdatesInstalled' : "xAndNMoreUpdatesFailed",
updates.length - 1,
args: [updates[0].finalName, (updates.length - 1).toString()]);
}
}
@@ -214,7 +211,7 @@ class NotificationsProvider {
channelDescription: channelDescription,
importance: importance,
priority: importanceToPriority[importance]!,
groupKey: 'dev.imranr.obtainium.$channelCode',
groupKey: '$obtainiumId.$channelCode',
progress: progPercent ?? 0,
maxProgress: 100,
showProgress: progPercent != null,

View File

@@ -48,7 +48,7 @@ class SettingsProvider with ChangeNotifier {
notifyListeners();
}
bool get useShizuku{
bool get useShizuku {
return prefs?.getBool('useShizuku') ?? false;
}
@@ -69,8 +69,7 @@ class SettingsProvider with ChangeNotifier {
Color get themeColor {
int? colorCode = prefs?.getInt('themeColor');
return (colorCode != null) ?
Color(colorCode) : obtainiumThemeColor;
return (colorCode != null) ? Color(colorCode) : obtainiumThemeColor;
}
set themeColor(Color themeColor) {
@@ -350,6 +349,15 @@ class SettingsProvider with ChangeNotifier {
notifyListeners();
}
bool get bgUpdatesWhileChargingOnly {
return prefs?.getBool('bgUpdatesWhileChargingOnly') ?? false;
}
set bgUpdatesWhileChargingOnly(bool val) {
prefs?.setBool('bgUpdatesWhileChargingOnly', val);
notifyListeners();
}
DateTime get lastCompletedBGCheckTime {
int? temp = prefs?.getInt('lastCompletedBGCheckTime');
return temp != null
@@ -469,4 +477,13 @@ class SettingsProvider with ChangeNotifier {
prefs?.setBool('beforeNewInstallsShareToAppVerifier', val);
notifyListeners();
}
bool get shizukuPretendToBeGooglePlay {
return prefs?.getBool('shizukuPretendToBeGooglePlay') ?? false;
}
set shizukuPretendToBeGooglePlay(bool val) {
prefs?.setBool('shizukuPretendToBeGooglePlay', val);
notifyListeners();
}
}

View File

@@ -23,18 +23,15 @@ import 'package:obtainium/app_sources/izzyondroid.dart';
import 'package:obtainium/app_sources/html.dart';
import 'package:obtainium/app_sources/jenkins.dart';
import 'package:obtainium/app_sources/neutroncode.dart';
import 'package:obtainium/app_sources/signal.dart';
import 'package:obtainium/app_sources/sourceforge.dart';
import 'package:obtainium/app_sources/sourcehut.dart';
import 'package:obtainium/app_sources/steammobile.dart';
import 'package:obtainium/app_sources/telegramapp.dart';
import 'package:obtainium/app_sources/tencent.dart';
import 'package:obtainium/app_sources/uptodown.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/custom_errors.dart';
import 'package:obtainium/mass_app_sources/githubstars.dart';
import 'package:obtainium/providers/logs_provider.dart';
import 'package:obtainium/providers/settings_provider.dart';
class AppNames {
@@ -155,10 +152,6 @@ appJSONCompatibilityModifiers(Map<String, dynamic> json) {
additionalSettings['autoApkFilterByArch'] = false;
}
if (source.runtimeType == HTML().runtimeType) {
// HTML 'fixed URL' support should be disabled if it previously did not exist
if (originalAdditionalSettings['supportFixedAPKURL'] == null) {
additionalSettings['supportFixedAPKURL'] = false;
}
// HTML key rename
if (originalAdditionalSettings['sortByFileNamesNotLinks'] != null) {
additionalSettings['sortByLastLinkSegment'] =
@@ -183,7 +176,7 @@ appJSONCompatibilityModifiers(Map<String, dynamic> json) {
}).toList();
}
// Steam source apps should be converted to HTML (#1244)
var legacySteamSourceApps = SteamMobile().apks.keys;
var legacySteamSourceApps = ['steam', 'steam-chat-app'];
if (legacySteamSourceApps.contains(additionalSettings['app'] ?? '')) {
json['url'] = '${json['url']}/mobile';
var replacementAdditionalSettings = getDefaultValuesFromFormItems(
@@ -200,6 +193,72 @@ appJSONCompatibilityModifiers(Map<String, dynamic> json) {
replacementAdditionalSettings['matchGroupToUse'] = '\$1';
additionalSettings = replacementAdditionalSettings;
}
// Signal apps from before it was removed should be converted to HTML (#1928)
if (json['url'] == 'https://signal.org' &&
json['id'] == 'org.thoughtcrime.securesms' &&
json['author'] == 'Signal' &&
json['name'] == 'Signal' &&
json['overrideSource'] == null &&
additionalSettings['trackOnly'] == false &&
additionalSettings['versionExtractionRegEx'] == '' &&
json['lastUpdateCheck'] != null) {
json['url'] = 'https://updates.signal.org/android/latest.json';
var replacementAdditionalSettings = getDefaultValuesFromFormItems(
HTML().combinedAppSpecificSettingFormItems);
replacementAdditionalSettings['versionExtractionRegEx'] =
'\\d+.\\d+.\\d+';
additionalSettings = replacementAdditionalSettings;
}
// WhatsApp from before it was removed should be converted to HTML (#1943)
if (json['url'] == 'https://whatsapp.com' &&
json['id'] == 'com.whatsapp' &&
json['author'] == 'Meta' &&
json['name'] == 'WhatsApp' &&
json['overrideSource'] == null &&
additionalSettings['trackOnly'] == false &&
additionalSettings['versionExtractionRegEx'] == '' &&
json['lastUpdateCheck'] != null) {
json['url'] = 'https://whatsapp.com/android';
var replacementAdditionalSettings = getDefaultValuesFromFormItems(
HTML().combinedAppSpecificSettingFormItems);
replacementAdditionalSettings['refreshBeforeDownload'] = true;
additionalSettings = replacementAdditionalSettings;
}
// VLC from before it was removed should be converted to HTML (#1943)
if (json['url'] == 'https://videolan.org' &&
json['id'] == 'org.videolan.vlc' &&
json['author'] == 'VideoLAN' &&
json['name'] == 'VLC' &&
json['overrideSource'] == null &&
additionalSettings['trackOnly'] == false &&
additionalSettings['versionExtractionRegEx'] == '' &&
json['lastUpdateCheck'] != null) {
json['url'] = 'https://www.videolan.org/vlc/download-android.html';
var replacementAdditionalSettings = getDefaultValuesFromFormItems(
HTML().combinedAppSpecificSettingFormItems);
replacementAdditionalSettings['refreshBeforeDownload'] = true;
replacementAdditionalSettings['intermediateLink'] =
<Map<String, dynamic>>[
{
'customLinkFilterRegex': 'APK',
'filterByLinkText': true,
'skipSort': false,
'reverseSort': false,
'sortByLastLinkSegment': false
},
{
'customLinkFilterRegex': 'arm64-v8a\\.apk\$',
'filterByLinkText': false,
'skipSort': false,
'reverseSort': false,
'sortByLastLinkSegment': false
}
];
replacementAdditionalSettings['versionExtractionRegEx'] =
'/vlc-android/([^/]+)/';
replacementAdditionalSettings['matchGroupToUse'] = "1";
additionalSettings = replacementAdditionalSettings;
}
}
json['additionalSettings'] = jsonEncode(additionalSettings);
// F-Droid no longer needs cloudflare exception since override can be used - migrate apps appropriately
@@ -226,7 +285,7 @@ class App {
late String name;
String? installedVersion;
late String latestVersion;
List<MapEntry<String, String>> apkUrls = [];
List<MapEntry<String, String>> apkUrls = []; // Key is name, value is URL
List<MapEntry<String, String>> otherAssetUrls = [];
late int preferredApkIndex;
late Map<String, dynamic> additionalSettings;
@@ -290,7 +349,14 @@ class App {
otherAssetUrls: otherAssetUrls);
factory App.fromJson(Map<String, dynamic> json) {
json = appJSONCompatibilityModifiers(json);
Map<String, dynamic> originalJSON = new Map.from(json);
try {
json = appJSONCompatibilityModifiers(json);
} catch (e) {
json = originalJSON;
LogsProvider().add(
'Error running JSON compat modifiers: ${e.toString()}: ${originalJSON.toString()}');
}
return App(
json['id'] as String,
json['url'] as String,
@@ -414,6 +480,7 @@ HttpClient createHttpClient(bool insecure) {
abstract class AppSource {
List<String> hosts = [];
bool hostChanged = false;
bool hostIdenticalDespiteAnyChange = false;
late String name;
bool enforceTrackOnly = false;
bool changeLogIfAnyIsMarkDown = true;
@@ -570,7 +637,11 @@ abstract class AppSource {
GeneratedFormSwitch('skipUpdateNotifications',
label: tr('skipUpdateNotifications'))
],
[GeneratedFormTextField('about', label: tr('about'), required: false)]
[GeneratedFormTextField('about', label: tr('about'), required: false)],
[
GeneratedFormSwitch('refreshBeforeDownload',
label: tr('refreshBeforeDownload'))
]
];
// Previous 2 variables combined into one at runtime for convenient usage
@@ -628,9 +699,10 @@ abstract class AppSource {
SettingsProvider settingsProvider) async {
Map<String, String> results = {};
for (var e in sourceConfigSettingFormItems) {
var val = hostChanged
var val = hostChanged && !hostIdenticalDespiteAnyChange
? additionalSettings[e.key]
: settingsProvider.getSettingString(e.key);
: additionalSettings[e.key] ??
settingsProvider.getSettingString(e.key);
if (val != null) {
results[e.key] = val;
}
@@ -792,9 +864,6 @@ class SourceProvider {
Tencent(),
Jenkins(),
APKMirror(),
Signal(),
VLC(),
WhatsApp(),
TelegramApp(),
NeutronCode(),
DirectAPKLink(),
@@ -813,9 +882,14 @@ class SourceProvider {
throw UnsupportedURLError();
}
var res = srcs.first;
res.hosts = [Uri.parse(url).host];
var originalHosts = res.hosts;
var newHost = Uri.parse(url).host;
res.hosts = [newHost];
res.hostChanged = true;
return srcs.first;
if (originalHosts.contains(newHost)) {
res.hostIdenticalDespiteAnyChange = true;
}
return res;
}
AppSource? source;
for (var s in sources.where((element) => element.hosts.isNotEmpty)) {
@@ -915,6 +989,9 @@ class SourceProvider {
name = name.isNotEmpty ? name : apk.names.name;
App finalApp = App(
currentApp?.id ??
((additionalSettings['appId'] != null)
? additionalSettings['appId']
: null) ??
(!trackOnly &&
(!source.appIdInferIsOptional ||
(source.appIdInferIsOptional && inferAppIdIfOptional))

View File

@@ -5,26 +5,27 @@ packages:
dependency: "direct main"
description:
name: android_intent_plus
sha256: "007703c1b2cac7ca98add3336b98cffa4baa11d5133cc463293dba9daa39cdf6"
sha256: "884b01361fe3756c4abbb56a382a00b16a2519079794a585afa7019a73cc0add"
url: "https://pub.dev"
source: hosted
version: "5.1.0"
version: "5.2.2"
android_package_installer:
dependency: "direct main"
description:
path: "."
ref: main
resolved-ref: ba2aa7a11edc2649d1d80c25ed9291521262f714
resolved-ref: "6109d0b1dc015c016e113ded3dd80ac823f790ab"
url: "https://github.com/ImranR98/android_package_installer"
source: git
version: "0.0.1"
android_package_manager:
dependency: "direct main"
description:
name: android_package_manager
sha256: "2de859fae7226a7de1c1ff9a2308f1967599408800330501a1ce97927c051153"
url: "https://pub.dev"
source: hosted
path: "."
ref: master
resolved-ref: "18231a8a2343747440b0bfe90f7d56ef7f586099"
url: "https://github.com/ImranR98/android_package_manager"
source: git
version: "0.7.1"
android_system_font:
dependency: "direct main"
@@ -47,10 +48,10 @@ packages:
dependency: "direct main"
description:
name: app_links
sha256: ad1a6d598e7e39b46a34f746f9a8b011ee147e4c275d407fa457e7a62f84dd99
sha256: "433df2e61b10519407475d7f69e470789d23d593f28224c38ba1068597be7950"
url: "https://pub.dev"
source: hosted
version: "6.3.2"
version: "6.3.3"
app_links_linux:
dependency: transitive
description:
@@ -79,18 +80,18 @@ packages:
dependency: transitive
description:
name: archive
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
sha256: "6199c74e3db4fbfbd04f66d739e72fe11c8a8957d5f219f1f4482dbde6420b5a"
url: "https://pub.dev"
source: hosted
version: "3.6.1"
version: "4.0.2"
args:
dependency: transitive
description:
name: args
sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
url: "https://pub.dev"
source: hosted
version: "2.5.0"
version: "2.6.0"
async:
dependency: transitive
description:
@@ -107,6 +108,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.7"
battery_plus:
dependency: "direct main"
description:
name: battery_plus
sha256: a0409fe7d21905987eb1348ad57c634f913166f14f0c8936b73d3f5940fac551
url: "https://pub.dev"
source: hosted
version: "6.2.1"
battery_plus_platform_interface:
dependency: transitive
description:
name: battery_plus_platform_interface
sha256: e8342c0f32de4b1dfd0223114b6785e48e579bfc398da9471c9179b907fa4910
url: "https://pub.dev"
source: hosted
version: "2.0.1"
boolean_selector:
dependency: transitive
description:
@@ -135,10 +152,10 @@ packages:
dependency: transitive
description:
name: cli_util
sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19
sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c
url: "https://pub.dev"
source: hosted
version: "0.4.1"
version: "0.4.2"
clock:
dependency: transitive
description:
@@ -151,18 +168,18 @@ packages:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
url: "https://pub.dev"
source: hosted
version: "1.18.0"
version: "1.19.0"
connectivity_plus:
dependency: "direct main"
description:
name: connectivity_plus
sha256: "2056db5241f96cdc0126bd94459fc4cdc13876753768fc7a31c425e50a7177d0"
sha256: "8a68739d3ee113e51ad35583fdf9ab82c55d09d693d3c39da1aebab87c938412"
url: "https://pub.dev"
source: hosted
version: "6.0.5"
version: "6.1.2"
connectivity_plus_platform_interface:
dependency: transitive
description:
@@ -183,18 +200,18 @@ packages:
dependency: "direct main"
description:
name: crypto
sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
version: "3.0.6"
csslib:
dependency: transitive
description:
name: csslib
sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb"
sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
version: "1.0.2"
cupertino_icons:
dependency: "direct main"
description:
@@ -207,26 +224,26 @@ packages:
dependency: transitive
description:
name: dbus
sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c"
url: "https://pub.dev"
source: hosted
version: "0.7.10"
version: "0.7.11"
device_info_plus:
dependency: "direct main"
description:
name: device_info_plus
sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074
sha256: b37d37c2f912ad4e8ec694187de87d05de2a3cb82b465ff1f65f65a2d05de544
url: "https://pub.dev"
source: hosted
version: "10.1.2"
version: "11.2.1"
device_info_plus_platform_interface:
dependency: transitive
description:
name: device_info_plus_platform_interface
sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba"
sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2"
url: "https://pub.dev"
source: hosted
version: "7.0.1"
version: "7.0.2"
dynamic_color:
dependency: "direct main"
description:
@@ -239,10 +256,10 @@ packages:
dependency: "direct main"
description:
name: easy_localization
sha256: fa59bcdbbb911a764aa6acf96bbb6fa7a5cf8234354fc45ec1a43a0349ef0201
sha256: "0f5239c7b8ab06c66440cfb0e9aa4b4640429c6668d5a42fe389c5de42220b12"
url: "https://pub.dev"
source: hosted
version: "3.0.7"
version: "3.0.7+1"
easy_logger:
dependency: transitive
description:
@@ -279,42 +296,42 @@ packages:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
url: "https://pub.dev"
source: hosted
version: "7.0.0"
version: "7.0.1"
file_picker:
dependency: "direct main"
description:
name: file_picker
sha256: "167bb619cdddaa10ef2907609feb8a79c16dfa479d3afaf960f8e223f754bf12"
sha256: c904b4ab56d53385563c7c39d8e9fa9af086f91495dfc48717ad84a42c3cf204
url: "https://pub.dev"
source: hosted
version: "8.1.2"
version: "8.1.7"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
url: "https://pub.dev"
source: hosted
version: "1.1.0"
version: "1.1.1"
flex_color_picker:
dependency: "direct main"
description:
name: flex_color_picker
sha256: "12dc855ae8ef5491f529b1fc52c655f06dcdf4114f1f7fdecafa41eec2ec8d79"
sha256: c083b79f1c57eaeed9f464368be376951230b3cb1876323b784626152a86e480
url: "https://pub.dev"
source: hosted
version: "3.6.0"
version: "3.7.0"
flex_seed_scheme:
dependency: transitive
description:
name: flex_seed_scheme
sha256: "7639d2c86268eff84a909026eb169f008064af0fb3696a651b24b0fa24a40334"
sha256: d3ba3c5c92d2d79d45e94b4c6c71d01fac3c15017da1545880c53864da5dfeb0
url: "https://pub.dev"
source: hosted
version: "3.4.1"
version: "3.5.0"
flutter:
dependency: "direct main"
description: flutter
@@ -388,10 +405,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_launcher_icons
sha256: "619817c4b65b322b5104b6bb6dfe6cda62d9729bd7ad4303ecc8b4e690a67a77"
sha256: bfa04787c85d80ecb3f8777bde5fc10c3de809240c48fa061a2c2bf15ea5211c
url: "https://pub.dev"
source: hosted
version: "0.14.1"
version: "0.14.3"
flutter_lints:
dependency: "direct dev"
description:
@@ -404,26 +421,26 @@ packages:
dependency: "direct main"
description:
name: flutter_local_notifications
sha256: "49eeef364fddb71515bc78d5a8c51435a68bccd6e4d68e25a942c5e47761ae71"
sha256: ef41ae901e7529e52934feba19ed82827b11baa67336829564aeab3129460610
url: "https://pub.dev"
source: hosted
version: "17.2.3"
version: "18.0.1"
flutter_local_notifications_linux:
dependency: transitive
description:
name: flutter_local_notifications_linux
sha256: c49bd06165cad9beeb79090b18cd1eb0296f4bf4b23b84426e37dd7c027fc3af
sha256: "8f685642876742c941b29c32030f6f4f6dacd0e4eaecb3efbb187d6a3812ca01"
url: "https://pub.dev"
source: hosted
version: "4.0.1"
version: "5.0.0"
flutter_local_notifications_platform_interface:
dependency: transitive
description:
name: flutter_local_notifications_platform_interface
sha256: "85f8d07fe708c1bdcf45037f2c0109753b26ae077e9d9e899d55971711a4ea66"
sha256: "6c5b83c86bf819cdb177a9247a3722067dd8cc6313827ce7c77a4b238a26fd52"
url: "https://pub.dev"
source: hosted
version: "7.2.0"
version: "8.0.0"
flutter_localizations:
dependency: transitive
description: flutter
@@ -433,18 +450,18 @@ packages:
dependency: "direct main"
description:
name: flutter_markdown
sha256: e17575ca576a34b46c58c91f9948891117a1bd97815d2e661813c7f90c647a78
sha256: e37f4c69a07b07bb92622ef6b131a53c9aae48f64b176340af9e8e5238718487
url: "https://pub.dev"
source: hosted
version: "0.7.3+2"
version: "0.7.5"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "9ee02950848f61c4129af3d6ec84a1cfc0e47931abc746b03e7a3bc3e8ff6eda"
sha256: "615a505aef59b151b46bbeef55b36ce2b6ed299d160c51d84281946f0aa0ce0e"
url: "https://pub.dev"
source: hosted
version: "2.0.22"
version: "2.0.24"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -467,18 +484,18 @@ packages:
dependency: "direct main"
description:
name: fluttertoast
sha256: "95f349437aeebe524ef7d6c9bde3e6b4772717cf46a0eb6a3ceaddc740b297cc"
sha256: "24467dc20bbe49fd63e57d8e190798c4d22cbbdac30e54209d153a15273721d1"
url: "https://pub.dev"
source: hosted
version: "8.2.8"
version: "8.2.10"
fraction:
dependency: transitive
description:
name: fraction
sha256: ac0d9904bb8211eb28606bdf623ff9f222c53240d8e9b927a07c149d356eddc2
sha256: "7804c9a73d26bd3d5ccf52b7225eecd0af4e33b310729726dc8f8bb14c217716"
url: "https://pub.dev"
source: hosted
version: "5.0.3"
version: "5.0.4"
gtk:
dependency: transitive
description:
@@ -499,34 +516,34 @@ packages:
dependency: "direct main"
description:
name: html
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec"
url: "https://pub.dev"
source: hosted
version: "0.15.4"
version: "0.15.5"
http:
dependency: "direct main"
description:
name: http
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f
url: "https://pub.dev"
source: hosted
version: "1.2.2"
version: "1.3.0"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
version: "4.1.2"
image:
dependency: transitive
description:
name: image
sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8"
sha256: "8346ad4b5173924b5ddddab782fc7d8a6300178c8b1dc427775405a01701c4a6"
url: "https://pub.dev"
source: hosted
version: "4.2.0"
version: "4.5.2"
intl:
dependency: transitive
description:
@@ -547,18 +564,18 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
url: "https://pub.dev"
source: hosted
version: "10.0.5"
version: "10.0.7"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
version: "3.0.8"
leak_tracker_testing:
dependency: transitive
description:
@@ -571,18 +588,18 @@ packages:
dependency: transitive
description:
name: lints
sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413"
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
url: "https://pub.dev"
source: hosted
version: "5.0.0"
version: "5.1.1"
markdown:
dependency: "direct main"
description:
name: markdown
sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051
sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1"
url: "https://pub.dev"
source: hosted
version: "7.2.2"
version: "7.3.0"
matcher:
dependency: transitive
description:
@@ -611,10 +628,10 @@ packages:
dependency: transitive
description:
name: mime
sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
url: "https://pub.dev"
source: hosted
version: "1.0.6"
version: "2.0.0"
nested:
dependency: transitive
description:
@@ -643,26 +660,26 @@ packages:
dependency: "direct main"
description:
name: path_provider
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "2.1.5"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: "6f01f8e37ec30b07bc424b4deabac37cacb1bc7e2e515ad74486039918a37eb7"
sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2"
url: "https://pub.dev"
source: hosted
version: "2.2.10"
version: "2.2.15"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
version: "2.4.1"
path_provider_linux:
dependency: transitive
description:
@@ -699,10 +716,10 @@ packages:
dependency: transitive
description:
name: permission_handler_android
sha256: "76e4ab092c1b240d31177bb64d2b0bea43f43d0e23541ec866151b9f7b2490fa"
sha256: "71bbecfee799e65aff7c744761a57e817e73b738fedf62ab7afd5593da21f9f1"
url: "https://pub.dev"
source: hosted
version: "12.0.12"
version: "12.0.13"
permission_handler_apple:
dependency: transitive
description:
@@ -715,10 +732,10 @@ packages:
dependency: transitive
description:
name: permission_handler_html
sha256: af26edbbb1f2674af65a8f4b56e1a6f526156bc273d0e65dd8075fab51c78851
sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
url: "https://pub.dev"
source: hosted
version: "0.1.3+2"
version: "0.1.3+5"
permission_handler_platform_interface:
dependency: transitive
description:
@@ -747,10 +764,10 @@ packages:
dependency: transitive
description:
name: platform
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
url: "https://pub.dev"
source: hosted
version: "3.1.5"
version: "3.1.6"
plugin_platform_interface:
dependency: transitive
description:
@@ -791,6 +808,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.10.2+1"
posix:
dependency: transitive
description:
name: posix
sha256: a0117dc2167805aa9125b82eee515cc891819bac2f538c83646d355b16f58b9a
url: "https://pub.dev"
source: hosted
version: "6.0.1"
provider:
dependency: "direct main"
description:
@@ -803,42 +828,42 @@ packages:
dependency: "direct main"
description:
name: share_plus
sha256: "468c43f285207c84bcabf5737f33b914ceb8eb38398b91e5e3ad1698d1b72a52"
sha256: fce43200aa03ea87b91ce4c3ac79f0cecd52e2a7a56c7a4185023c271fbfa6da
url: "https://pub.dev"
source: hosted
version: "10.0.2"
version: "10.1.4"
share_plus_platform_interface:
dependency: transitive
description:
name: share_plus_platform_interface
sha256: "6ababf341050edff57da8b6990f11f4e99eaba837865e2e6defe16d039619db5"
sha256: cc012a23fc2d479854e6c80150696c4a5f5bb62cb89af4de1c505cf78d0a5d0b
url: "https://pub.dev"
source: hosted
version: "5.0.0"
version: "5.0.2"
shared_preferences:
dependency: "direct main"
description:
name: shared_preferences
sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051"
sha256: c59819dacc6669a1165d54d2735a9543f136f9b3cec94ca65cea6ab8dffc422e
url: "https://pub.dev"
source: hosted
version: "2.3.2"
version: "2.4.0"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: "480ba4345773f56acda9abf5f50bd966f581dac5d514e5fc4a18c62976bbba7e"
sha256: "650584dcc0a39856f369782874e562efd002a9c94aec032412c9eb81419cce1f"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
version: "2.4.4"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: c4b35f6cb8f63c147312c054ce7c2254c8066745125264f0c88739c417fc9d9f
sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
url: "https://pub.dev"
source: hosted
version: "2.5.2"
version: "2.5.4"
shared_preferences_linux:
dependency: transitive
description:
@@ -874,11 +899,12 @@ packages:
shared_storage:
dependency: "direct main"
description:
name: shared_storage
sha256: cf20428d06af065311b71e09cbfbbfe431e979a3bf9180001c1952129b7c708f
url: "https://pub.dev"
source: hosted
version: "0.8.1"
path: "."
ref: master
resolved-ref: "8784c39b909324df8913dd30fa416b8a50d55f49"
url: "https://github.com/AlexBacich/shared-storage"
source: git
version: "0.7.0"
shizuku_apk_installer:
dependency: "direct main"
description:
@@ -892,7 +918,7 @@ packages:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
version: "0.0.0"
source_span:
dependency: transitive
description:
@@ -913,26 +939,50 @@ packages:
dependency: "direct main"
description:
name: sqflite
sha256: ff5a2436ef8ebdfda748fbfe957f9981524cb5ff11e7bafa8c42771840e8a788
sha256: "2d7299468485dca85efeeadf5d38986909c5eb0cd71fd3db2c2f000e6c9454bb"
url: "https://pub.dev"
source: hosted
version: "2.3.3+2"
version: "2.4.1"
sqflite_android:
dependency: transitive
description:
name: sqflite_android
sha256: "78f489aab276260cdd26676d2169446c7ecd3484bbd5fead4ca14f3ed4dd9ee3"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
sha256: "2d8e607db72e9cb7748c9c6e739e2c9618320a5517de693d5a24609c4671b1a4"
sha256: "761b9740ecbd4d3e66b8916d784e581861fd3c3553eda85e167bc49fdb68f709"
url: "https://pub.dev"
source: hosted
version: "2.5.4+4"
version: "2.5.4+6"
sqflite_darwin:
dependency: transitive
description:
name: sqflite_darwin
sha256: "22adfd9a2c7d634041e96d6241e6e1c8138ca6817018afc5d443fef91dcefa9c"
url: "https://pub.dev"
source: hosted
version: "2.4.1+1"
sqflite_platform_interface:
dependency: transitive
description:
name: sqflite_platform_interface
sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
version: "1.12.0"
stream_channel:
dependency: transitive
description:
@@ -945,10 +995,10 @@ packages:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
version: "1.3.0"
synchronized:
dependency: transitive
description:
@@ -969,66 +1019,74 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
url: "https://pub.dev"
source: hosted
version: "0.7.2"
version: "0.7.3"
timezone:
dependency: transitive
description:
name: timezone
sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d"
sha256: ffc9d5f4d1193534ef051f9254063fa53d588609418c84299956c3db9383587d
url: "https://pub.dev"
source: hosted
version: "0.9.4"
version: "0.10.0"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
url: "https://pub.dev"
source: hosted
version: "1.3.2"
version: "1.4.0"
upower:
dependency: transitive
description:
name: upower
sha256: cf042403154751180affa1d15614db7fa50234bc2373cd21c3db666c38543ebf
url: "https://pub.dev"
source: hosted
version: "0.7.0"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
url: "https://pub.dev"
source: hosted
version: "6.3.0"
version: "6.3.1"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: e35a698ac302dd68e41f73250bd9517fe3ab5fa4f18fe4647a0872db61bacbab
sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193"
url: "https://pub.dev"
source: hosted
version: "6.3.10"
version: "6.3.14"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e
sha256: "16a513b6c12bb419304e72ea0ae2ab4fed569920d1c7cb850263fe3acc824626"
url: "https://pub.dev"
source: hosted
version: "6.3.1"
version: "6.3.2"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af
sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
url: "https://pub.dev"
source: hosted
version: "3.2.0"
version: "3.2.1"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "769549c999acdb42b8bcfa7c43d72bf79a382ca7441ab18a808e101149daf672"
sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2"
url: "https://pub.dev"
source: hosted
version: "3.2.1"
version: "3.2.2"
url_launcher_platform_interface:
dependency: transitive
description:
@@ -1041,18 +1099,18 @@ packages:
dependency: transitive
description:
name: url_launcher_web
sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
sha256: "3ba963161bd0fe395917ba881d320b9c4f6dd3c4a233da62ab18a5025c85f1e9"
url: "https://pub.dev"
source: hosted
version: "2.3.3"
version: "2.4.0"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185"
sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
version: "3.1.4"
uuid:
dependency: transitive
description:
@@ -1073,10 +1131,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
url: "https://pub.dev"
source: hosted
version: "14.2.5"
version: "14.3.0"
web:
dependency: transitive
description:
@@ -1089,18 +1147,18 @@ packages:
dependency: "direct main"
description:
name: webview_flutter
sha256: ec81f57aa1611f8ebecf1d2259da4ef052281cb5ad624131c93546c79ccc7736
sha256: "889a0a678e7c793c308c68739996227c9661590605e70b1f6cf6b9a6634f7aec"
url: "https://pub.dev"
source: hosted
version: "4.9.0"
version: "4.10.0"
webview_flutter_android:
dependency: transitive
description:
name: webview_flutter_android
sha256: "6e64fcb1c19d92024da8f33503aaeeda35825d77142c01d0ea2aa32edc79fdc8"
sha256: "5568f17a9c25c0fdd0737900fa1c2d1fee2d780bc212d9aec10c2d1f48ef0f59"
url: "https://pub.dev"
source: hosted
version: "3.16.7"
version: "4.3.1"
webview_flutter_platform_interface:
dependency: transitive
description:
@@ -1113,18 +1171,18 @@ packages:
dependency: transitive
description:
name: webview_flutter_wkwebview
sha256: "1942a12224ab31e9508cf00c0c6347b931b023b8a4f0811e5dec3b06f94f117d"
sha256: "8e0593559bfecd35eb1757d6907ed6b995a41ef82607d6113df897c2805ce6be"
url: "https://pub.dev"
source: hosted
version: "3.15.0"
version: "3.18.0"
win32:
dependency: transitive
description:
name: win32
sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a"
sha256: daf97c9d80197ed7b619040e86c8ab9a9dad285e7671ee7390f9180cc828a51e
url: "https://pub.dev"
source: hosted
version: "5.5.4"
version: "5.10.1"
win32_registry:
dependency: transitive
description:
@@ -1137,10 +1195,10 @@ packages:
dependency: transitive
description:
name: xdg_directories
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
url: "https://pub.dev"
source: hosted
version: "1.0.4"
version: "1.1.0"
xml:
dependency: transitive
description:
@@ -1153,10 +1211,10 @@ packages:
dependency: transitive
description:
name: yaml
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
url: "https://pub.dev"
source: hosted
version: "3.1.2"
version: "3.1.3"
sdks:
dart: ">=3.5.0 <4.0.0"
flutter: ">=3.24.0"
dart: ">=3.6.0 <4.0.0"
flutter: ">=3.27.0"

View File

@@ -1,6 +1,5 @@
name: obtainium
description: Get Android app updates straight from the source.
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
@@ -17,10 +16,10 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.1.25+2282
version: 1.1.40+2297
environment:
sdk: '>=3.0.0 <4.0.0'
sdk: ^3.6.0
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
@@ -32,13 +31,12 @@ dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.5
path_provider: ^2.0.11
flutter_fgbg: ^0.6.0
flutter_local_notifications: ^17.0.0
flutter_local_notifications: ^18.0.0
provider: ^6.0.3
http: ^1.0.0
webview_flutter: ^4.0.0
@@ -48,14 +46,17 @@ dependencies:
url_launcher: ^6.1.5
permission_handler: ^11.0.0
fluttertoast: ^8.0.9
device_info_plus: ^10.0.1
device_info_plus: ^11.0.0
file_picker: ^8.0.0+1
animations: ^2.0.4
android_package_installer:
android_package_installer: # TODO: See if PR will be accepted (dev may not be active), else remove this comment
git:
url: https://github.com/ImranR98/android_package_installer
ref: main
android_package_manager: ^0.7.0
android_package_manager: # TODO: Make PR and switch to upstream
git:
url: https://github.com/ImranR98/android_package_manager
ref: master
share_plus: ^10.0.0
sqflite: ^2.2.0+3
easy_localization: ^3.0.1
@@ -64,7 +65,10 @@ dependencies:
flutter_archive: ^6.0.0
hsluv: ^1.1.3
connectivity_plus: ^6.0.1
shared_storage: ^0.8.0
shared_storage: # TODO: Is this maintained?
git:
url: https://github.com/AlexBacich/shared-storage
ref: master
crypto: ^3.0.3
app_links: ^6.0.1
background_fetch: ^1.2.1
@@ -81,6 +85,7 @@ dependencies:
markdown: any
flutter_typeahead: ^5.2.0
battery_plus: ^6.1.0
dev_dependencies:
flutter_test:
sdk: flutter
@@ -109,20 +114,20 @@ flutter:
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# - assets:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
assets:
- assets/translations/
- assets/graphics/
- assets/ca/
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# https://flutter.dev/to/resolution-aware-images
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# https://flutter.dev/to/asset-from-package
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
@@ -142,7 +147,7 @@ flutter:
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
# see https://flutter.dev/to/font-from-package
fonts:
- family: Wix-Madefor-Display

38
sign.sh Executable file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
set -e
# Script to sign unsigned APKs
# Assumptions:
# 1. Your PGP key is already imported on the locally running agent
# 2. An Android SDK is located at $ANDROID_HOME (or ~/Android/Sdk as fallback)
usage() {
echo "sign.sh <PATH_TO_KEYSTORE> <PATH_TO_BUILD_DIR>"
exit 1
}
if [ -z "$1" ] || [ -z "$2" ] || [ ! -f "$1" ] || [ ! -d "$2" ]; then
usage
fi
KEYSTORE_LOCATION="$1"
BUILD_DIR="$2"
read -s -p "Enter your keystore password: " KEYSTORE_PASSWORD
if [ -z "$ANDROID_HOME" ]; then
ANDROID_HOME=~/Android/Sdk
fi
if [ ! -d "$ANDROID_HOME" ]; then
echo "Could not find Android SDK!" >&2
exit 1
fi
for apk in "$BUILD_DIR"/*-release*.apk; do
unsignedApk=${apk/-release/-unsigned}
mv "$apk" "$unsignedApk"
${ANDROID_HOME}/build-tools/$(ls ${ANDROID_HOME}/build-tools/ | tail -1)/apksigner sign --ks "$KEYSTORE_LOCATION" --ks-pass pass:"${KEYSTORE_PASSWORD}" --out "${apk}" "${unsignedApk}"
sha256sum ${apk} | cut -d " " -f 1 >"$apk".sha256
gpg --batch --sign --detach-sig "$apk".sha256
rm "$unsignedApk"
done