Compare commits

..

901 Commits

Author SHA1 Message Date
Jobobby04 a8e3d105f1 Release v1.8.1 2022-02-01 17:13:02 -05:00
arkon 2f22f56b32 Temporarily revert some things for stable release
(cherry picked from commit b88f8ae9d2)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2022-02-01 17:12:34 -05:00
Jobobby04 1dd010e733 Minor cleanup 2022-02-01 17:09:41 -05:00
Jobobby04 2eef81c468 Add Mangadex blocked groups and uploaders extension preference support 2022-02-01 17:09:20 -05:00
Jobobby04 ffcb5f6954 Improve collection and string utils 2022-02-01 17:07:57 -05:00
Jobobby04 375455d4a6 Fix renamed manga delete after read 2022-02-01 10:20:15 -05:00
arkon f089991e0b Use default bottom nav height
(cherry picked from commit 836a2649d3)
2022-01-31 18:44:20 -05:00
Jobobby04 26a8b9acc4 Revert "Disable update/download warnings for stable release"
This reverts commit d46879260f.
2022-01-31 18:43:51 -05:00
Jobobby04 0d83026ac3 Release v1.8.0 2022-01-31 18:41:45 -05:00
arkon d46879260f Disable update/download warnings for stable release
(cherry picked from commit 3da8677e32)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2022-01-31 18:35:53 -05:00
Jozef Hollý d8c2c5520e Weblate translations (#6494)
Co-authored-by: Ahmad Azwar Annas <ahmadazw2@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Allen Sam <allenaizen@pm.me>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: DatTran MLL <tranthanhdat1142003@gmail.com>
Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: Eugene <e.shlyapkin99@gmail.com>
Co-authored-by: FateXBlood <zecrofelix@gmail.com>
Co-authored-by: Garutmaan Garuda <garutmaangaruda@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jendrej <ejjendrej@gmail.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Paulo Pinho <kebrus@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: altinat <poiiiii4yy@gmail.com>
Co-authored-by: jdkdklsls dkdkdk <accshared420@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/cs/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ja/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ml/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ne/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sa/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/te/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/th/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/vi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/
Translation: Tachiyomi/Tachiyomi 0.x

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Ahmad Azwar Annas <ahmadazw2@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Allen Sam <allenaizen@pm.me>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: DatTran MLL <tranthanhdat1142003@gmail.com>
Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: Eugene <e.shlyapkin99@gmail.com>
Co-authored-by: FateXBlood <zecrofelix@gmail.com>
Co-authored-by: Garutmaan Garuda <garutmaangaruda@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jendrej <ejjendrej@gmail.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Paulo Pinho <kebrus@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: altinat <poiiiii4yy@gmail.com>
Co-authored-by: jdkdklsls dkdkdk <accshared420@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
(cherry picked from commit 4d0d7d5ad6)
2022-01-31 18:34:50 -05:00
arkon dc97ae13eb Fix selection state appearance in clear database list (fixes #6526)
(cherry picked from commit 8c4ece4b2d)
2022-01-31 18:34:43 -05:00
Jobobby04 3d22ab93be Disable comikey support 2022-01-31 18:34:22 -05:00
Román 846c0f18fa Russian translations (#512)
* Russian translations

* [RU] Translations
2022-01-30 21:31:30 -05:00
joseph619 4c4d6de245 adding new sites and removed old ones (#513) 2022-01-30 21:31:13 -05:00
arkon 8dc4005779 Remove more formatting span types in SearchView (maybe fixes #6495)
(cherry picked from commit bf3bb8a378)
2022-01-30 21:30:19 -05:00
Ivan Iskandar 3c216e0cb9 MangaSummaryView: Fix incomplete description on tablet ui (#6518)
(cherry picked from commit cf5e60f8eb)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
2022-01-30 21:30:10 -05:00
arkon efe70499ac Avoid invalid unset default browser (fixes #6520)
(cherry picked from commit 7de707c60a)
2022-01-30 21:28:21 -05:00
Ivan Iskandar 2003f6843d Fix bottom nav showing on resume when action mode is active (#6514)
(cherry picked from commit 5cd11ad8c3)
2022-01-29 20:10:22 -05:00
arkon 454edf3ea2 Always try to use default browser when opening custom tabs on all Android versions
(cherry picked from commit 6bba52a2b6)
2022-01-29 20:10:11 -05:00
arkon e33a270e4d [skip ci] add note about issue taking in contribution guide
(cherry picked from commit 54b476df4e)
2022-01-29 20:10:03 -05:00
Ivan Iskandar 2d26b1d775 TachiyomiAppBarLayout: Use insetter to handle inset (#6506)
This requires adding the status bar foreground drawing logic since the parent
class wouldn't know the inset changes anymore.

(cherry picked from commit a68f123594)
2022-01-29 20:09:54 -05:00
Riztard Lanthorn dcb8cd9ef6 Tweaked Yin & Yang theme a little (#6507)
(cherry picked from commit 08ad4f96b9)
2022-01-29 20:09:48 -05:00
Rajat af4bc345de Fix search inputs accepting formatted text (#6501)
* Fix Global and extension search input accepts formatted text #6495

* Code change as requested because of performance issue

* code changes as requested

* minor code changes

(cherry picked from commit 77a3acf5cc)
2022-01-29 20:09:39 -05:00
Riztard Lanthorn e0731985be add extra space before error in log description (#6505)
to make it easier to read if the log reader using word wrap

(cherry picked from commit dea585e69b)
2022-01-29 20:09:32 -05:00
arkon 6cf375436b Copy source ID to clipboard when long pressing source in migrate list (closes #6479)
(cherry picked from commit 879dacfba6)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrationSourcesController.kt
2022-01-29 20:09:27 -05:00
arkon df17440b40 Try to show more relevant exception messages when failing to restore a backup
(cherry picked from commit b459234ddc)
2022-01-29 20:08:03 -05:00
arkon 0c4dc91e9e Discard backup file if it fails to be created properly (e.g. fails validation)
(cherry picked from commit 76d2c676fd)
2022-01-29 20:07:56 -05:00
arkon 98ee328d1b Show error toast if empty URI is passed when trying to create/restore a backup
(cherry picked from commit d5015d37e1)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupManager.kt
2022-01-29 20:07:51 -05:00
arkon 5201126b06 Write job failure exceptions to error log
(cherry picked from commit 1b71e4cee7)
2022-01-29 20:07:03 -05:00
arkon 9938beb040 Update to AGP 7.1.0
(cherry picked from commit 18ef5c6ff9)
2022-01-29 20:06:54 -05:00
arkon 4921a66665 Replace custom download dialog buttons with MaterialButtons
(cherry picked from commit 35e0561950)
2022-01-29 20:06:40 -05:00
arkon 78488cc0d7 Allow choosing browser apps from WebView even when extension deep links are verified in Android 12+
(cherry picked from commit adab8e3ed8)
2022-01-29 20:06:31 -05:00
arkon b95dfa2974 Avoid migration failing if previous source doesn't exist
(cherry picked from commit 89dbb4d300)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchPresenter.kt
2022-01-29 20:06:21 -05:00
Jobobby04 e32e696606 Minor cleanup 2022-01-29 20:03:47 -05:00
Jobobby04 5499404267 Replace E-H icon and merged icon with standardized ones 2022-01-29 20:03:31 -05:00
Jobobby04 d0f9ad9857 Fix fresh installs databases 2022-01-25 10:24:28 -05:00
Jobobby04 b7a94a72fa Rewrite intent filters for Android 12 compliance 2022-01-23 17:08:32 -05:00
Jobobby04 254d739d12 Rewrite E-H favorites sync database, fixes:
- Freezing issues
- Build times
- Probably fixes bloated app size
2022-01-23 17:08:31 -05:00
Jobobby04 5224988265 Full-proof way of getting a mangadex manga title, update crashlytics 2022-01-23 17:08:31 -05:00
Román 1c69b066f7 Russian Translation (#511)
* Russian translation

* Russian translation
2022-01-22 19:13:42 -05:00
Jobobby04 c6f37f4aa5 Allow text to be selectable in debug dialogs 2022-01-22 19:07:47 -05:00
arkon 9bff630825 Allow Samsung devices on Android 12+ to use dynamic theme
Since it seems to work fine, regardless of what the Material Components library seems to dictate.

(cherry picked from commit e3f3686b8a)
2022-01-22 18:40:03 -05:00
arkon 10e60b4d94 Fix tab underline in chapter settings sheet
(cherry picked from commit 9984e983b4)
2022-01-22 18:39:56 -05:00
arkon bc7395c2bc Spacing adjustments in reader settings sheet
(cherry picked from commit 4ebe67ef53)
2022-01-22 18:39:49 -05:00
arkon e2446cd703 Fix solid background behind text selection UI in dialogs
(cherry picked from commit 1a11d4153e)
2022-01-22 18:39:42 -05:00
Gauthier 1d814aabae fix: handle Komga tracks during manga migration (#6463)
* fix: handle Komga tracks during manga migration

closes #6354

* refactor: remove Komga direct reference

(cherry picked from commit cd7cf3583e)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchPresenter.kt
2022-01-22 18:39:30 -05:00
Andreas a65b55a6bf Add ability to open FAQ and Guide, and Changelog in extension repository (#6469)
(cherry picked from commit 66a180bc36)
2022-01-22 18:32:06 -05:00
Jozef Hollý a1d39beff4 Weblate translations (#6429)
Co-authored-by: Ahmad Azwar Annas <ahmadazw2@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: Arun <arun007@pm.me>
Co-authored-by: AsyJAIZ <2007andrylavr@gmail.com>
Co-authored-by: Blue <bluestuffish@gmail.com>
Co-authored-by: Colin Tirion <grotehoed@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: DatTran MLL <tranthanhdat1142003@gmail.com>
Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: Eugene <e.shlyapkin99@gmail.com>
Co-authored-by: FateXBlood <zecrofelix@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: I. Musthafa <i.musthafa66@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jendrej <ejjendrej@gmail.com>
Co-authored-by: Jetspectre <jetspectre1@gmail.com>
Co-authored-by: Johkum <jacobomur@gmail.com>
Co-authored-by: Jozef Hollý <j2.00ghz@gmail.com>
Co-authored-by: Luiz-bro <luiznneto1@gmail.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Manu <manularrosa96@mailbox.org>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nabin Dhakal <nabin6707@gmail.com>
Co-authored-by: Niko Strijbol <strijbol.niko@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Sergio Gomez Damas <sergio.gomezdamas@gmail.com>
Co-authored-by: Soare Robert Daniel <soare.robert.daniel@protonmail.com>
Co-authored-by: StirCrazy <camigames252@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: Unai <uesandi@gmail.com>
Co-authored-by: Yahya Kerba <yahyakerba97@gmail.com>
Co-authored-by: Zakhar Timoshenko <vp1984tanki@gmail.com>
Co-authored-by: altinat <poiiiii4yy@gmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ar/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ca/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/cs/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es_419/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/eu/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fil/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/gl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ja/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ne/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ro/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/th/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/uk/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/vi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/
Translation: Tachiyomi/Tachiyomi 0.x

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Ahmad Azwar Annas <ahmadazw2@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: Arun <arun007@pm.me>
Co-authored-by: AsyJAIZ <2007andrylavr@gmail.com>
Co-authored-by: Blue <bluestuffish@gmail.com>
Co-authored-by: Colin Tirion <grotehoed@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: DatTran MLL <tranthanhdat1142003@gmail.com>
Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: Eugene <e.shlyapkin99@gmail.com>
Co-authored-by: FateXBlood <zecrofelix@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: I. Musthafa <i.musthafa66@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jendrej <ejjendrej@gmail.com>
Co-authored-by: Jetspectre <jetspectre1@gmail.com>
Co-authored-by: Johkum <jacobomur@gmail.com>
Co-authored-by: Luiz-bro <luiznneto1@gmail.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Manu <manularrosa96@mailbox.org>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nabin Dhakal <nabin6707@gmail.com>
Co-authored-by: Niko Strijbol <strijbol.niko@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Sergio Gomez Damas <sergio.gomezdamas@gmail.com>
Co-authored-by: Soare Robert Daniel <soare.robert.daniel@protonmail.com>
Co-authored-by: StirCrazy <camigames252@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: Unai <uesandi@gmail.com>
Co-authored-by: Yahya Kerba <yahyakerba97@gmail.com>
Co-authored-by: Zakhar Timoshenko <vp1984tanki@gmail.com>
Co-authored-by: altinat <poiiiii4yy@gmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
(cherry picked from commit eb06667455)
2022-01-22 18:31:58 -05:00
Jobobby04 7c8c6c4303 Remove lang hijacks on Hitomi and NHentai 2022-01-22 12:22:32 -05:00
arkon 87afe3191b Fix pages not being serializable for chapter cache (fixes #6483)
(cherry picked from commit 0ff8966a27)
2022-01-22 11:45:31 -05:00
arkon c95a274ff5 Update dependencies
(cherry picked from commit 0cb4094dd9)
2022-01-22 11:45:21 -05:00
arkon 324d74f6c3 Remove some dead code
(cherry picked from commit edd213343b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
2022-01-22 11:45:12 -05:00
Jobobby04 83e8b670da Minor cleanup 2022-01-22 11:43:52 -05:00
Jobobby04 849add02ad Use more performant getAllTags function 2022-01-20 22:50:37 -05:00
Jobobby04 464f343e4a Update EHTags using updated Scraper 2022-01-20 22:19:57 -05:00
Jobobby04 29241b0393 Improve library performance a bit 2022-01-16 15:05:44 -05:00
Jobobby04 ecc708b6cd Only use external url if pages count is 0 2022-01-16 12:38:23 -05:00
Jobobby04 38c161310a Minor cleanup 2022-01-16 11:45:38 -05:00
Jobobby04 992679e470 Probably fix bookmarks breaking reading progress 2022-01-16 11:40:49 -05:00
Jobobby04 cccf956fae Fix random scrolling when bookmarking a chapter 2022-01-15 20:44:51 -05:00
Jobobby04 e8100fc958 Properly handle EHentai browse duplication 2022-01-15 20:00:45 -05:00
Jobobby04 18a119e9cf Fix issue 158, some sources not updating with group by source 2022-01-15 19:28:05 -05:00
Ivan Iskandar 6b3813bb9a HistoryController: Drop first search event (#6465)
Removes unnecessary data set changes when entering history screen

(cherry picked from commit 769efd9d06)
2022-01-15 18:19:19 -05:00
Ivan Iskandar d6ba632c54 MangaInfo: Don't apply appbar padding on tablet ui (#6464)
(cherry picked from commit 49cb3b6aa7)
2022-01-15 18:19:11 -05:00
Jobobby04 479950e60e Fix data saver image quality crash 2022-01-15 18:16:29 -05:00
jopejoe1 dc60352bd6 Add support for Azuki Manga and MangaHot Chapters in Mangadex (#506)
* Update MangaDex.kt

* Add Azuki and MangaHot Handlers
2022-01-15 17:59:13 -05:00
Román bf7075629c Russian translation (#499) 2022-01-15 17:58:55 -05:00
Román 3c598f459a Adding more size to few things (#495)
* Adding more size to few things

* Fixing margins and paddings

* Reverting categories_item

* Increasing size of innerContainer
2022-01-15 17:58:39 -05:00
Román 04f284e27b Translating missing strings (#493)
* Translating missing strings

* Adding new string

* Adding new strings

* Fixing last commits

* Fixing strings missing

* Change incorrect translated string

* More changes
2022-01-09 15:43:49 -05:00
Ivan Iskandar d8ba5b4ddb Change library list item title style (#6457)
(cherry picked from commit 8ad98b67d2)
2022-01-09 15:42:48 -05:00
arkon 40c844f128 Update crop border shortcut state when reading mode or manga set (fixes #6441)
(cherry picked from commit 8a8f1d3205)
2022-01-09 15:42:41 -05:00
arkon b4c9ff4cae Fix bottom nav being visible when resuming app (fixes #6012)
(cherry picked from commit 4a27f0546c)
2022-01-09 15:42:35 -05:00
Midyan Hamdoun 6a82d57957 Change Toolbar to MaterialToolbar (#6456)
(cherry picked from commit 727a7e4b2d)
2022-01-09 15:42:26 -05:00
Jobobby04 020ce06ebd Remove GSON proguard rules 2022-01-09 15:40:05 -05:00
Jobobby04 4aa9cc3851 Cleanup group by tracking 2022-01-09 15:39:46 -05:00
Jobobby04 e0c88fea19 Re-add rating more info 2022-01-08 18:20:56 -05:00
Jobobby04 8bd1a708d0 Probably fix merged manga library updates 2022-01-08 18:20:34 -05:00
Jobobby04 aeed6f47a0 Add new mangadex relation 2022-01-08 18:20:15 -05:00
arkon 9bce035cc9 Fix more crashes
(cherry picked from commit 2b5e8241ab)
2022-01-08 18:19:04 -05:00
arkon 5d00fe7e78 Make tracker status wording/ordering more consistent
(cherry picked from commit 3dc4fd8dd1)
2022-01-08 18:18:57 -05:00
arkon 7cc14bb5d0 Add new manga statuses
To be exposed in extension-lib 1.3

(cherry picked from commit 375a27a93d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
2022-01-08 18:18:43 -05:00
arkon a6210baf70 Avoid reader crash
(cherry picked from commit 544387d1a0)
2022-01-08 18:02:32 -05:00
arkon afb6ca1b5c Update to Conductor 3.1.2
(cherry picked from commit cb8120d38f)
2022-01-08 18:02:25 -05:00
Ivan Iskandar 2b91af9ca5 Reduce stutter when entering Browse screen (#6435)
* More coil

* ExtensionController: Drop first text change event

* Browse-Source: Remove unnecessary load

* ExtensionPresenter: Increase debounce timeout

To avoid heavy list reload during first enter animation

(cherry picked from commit 78a261f5d3)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceHolder.kt
2022-01-08 18:02:11 -05:00
Ivan Iskandar cafec5a37b Use material components on reader error views (#6447)
* Use material components on reader error views

* Adjust image loading behavior

Don't set automatic background color right away and keep show progress indicator
until the page image is fully loaded.

(cherry picked from commit b8f7653fb2)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
2022-01-08 17:55:03 -05:00
arkon 59713f629a Add DoH abbreviation to preference title so it's searchable
(cherry picked from commit e0d2a01bc8)
2022-01-08 17:43:53 -05:00
Andreas b4348691f8 Remove clutter in main (#6437)
(cherry picked from commit 560be9f553)
2022-01-08 17:43:46 -05:00
arkon a3ec06b4fa Fallback to preference title if dialog title isn't set
(cherry picked from commit 47723042c5)
2022-01-08 17:43:39 -05:00
arkon a574f1ce23 URL encode Kitsu search queries (fixes #5712)
(cherry picked from commit d04d676d2f)
2022-01-08 17:43:31 -05:00
jmir1 f63614bf0f fix crash in ReaderActivity (#6439)
(cherry picked from commit 2e1572d7cc)
2022-01-08 17:42:59 -05:00
arkon f8e128f975 Custom Cloudflare failure exception to avoid user-facing "java.lang.Exception" text
(cherry picked from commit 938339690e)
2022-01-08 17:42:50 -05:00
arkon 867eed7b16 Avoid crashes in tracker interceptor errors
(cherry picked from commit dbb2c523c1)
2022-01-08 17:42:41 -05:00
arkon 31cdfc63e6 Fix some crashes
(cherry picked from commit 0b9d436753)
2022-01-08 17:42:32 -05:00
arkon 2dd2054d4c Add QuickJS dependency to eventually replace Duktape
(cherry picked from commit 2d03f3ce1e)

# Conflicts:
#	app/proguard-rules.pro
2022-01-08 17:42:23 -05:00
Jobobby04 07f32b8df0 Fix MangaDex 2022-01-01 18:07:53 -05:00
Román 7294f0c17e Fixing few things in ReaderActivity.xml (#491) 2022-01-01 17:15:50 -05:00
Jobobby04 2d3740f3d3 Reformat edited xml layout files 2022-01-01 17:14:48 -05:00
Jobobby04 d096740cda Add minimum height to simple categories items 2022-01-01 16:14:45 -05:00
Jobobby04 21b620ee86 Rewrite Batch Add into kotlin flow 2022-01-01 16:14:44 -05:00
Román 08f6a7fbd6 Russian Strings (#483)
Co-authored-by: jobobby04 <jobobby04@users.noreply.github.com>
2022-01-01 16:14:29 -05:00
Román f809e438f3 Migration manga fixes (#489) 2022-01-01 15:38:29 -05:00
Román 0a228019a9 EditManga fixes (#488)
* Few changes of EditMangaDialog

* Making cover having more space
2022-01-01 15:38:08 -05:00
Román f4a0342007 Batch add fix (#486) 2022-01-01 15:37:39 -05:00
Jobobby04 ab863c5bc9 Replace deprecated property 2022-01-01 15:34:28 -05:00
Jobobby04 12fcd451bb Update dependancies 2022-01-01 15:31:52 -05:00
arkon 55ca111b52 Handle renaming existing downloaded CBZ chapters on update
(cherry picked from commit c4a476d0d2)
2022-01-01 15:25:55 -05:00
Jozef Hollý 56dd6c5920 Weblate translations (#6352)
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: Andre Rahardjo <zertozzf@gmail.com>
Co-authored-by: Aviv Ben Ami <avivbenami@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: DatTran MLL <tranthanhdat1142003@gmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Flamm <robindevaux25@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: HaruSasaki <aiqusubaru@gmail.com>
Co-authored-by: Hossain Rizbi <rsajib387@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: Italian Translator <nekoxtranslator@etlgr.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jagadeesh Vijay Varma <jagadeeshvarma.b@gmail.com>
Co-authored-by: Jan Obst <macek04@volny.cz>
Co-authored-by: Jetspectre <jetspectre1@gmail.com>
Co-authored-by: Jozef Hollý <j2.00ghz@gmail.com>
Co-authored-by: KasukeLp <kasukelp23@yahoo.com>
Co-authored-by: Lyaiya <hipsnafoha@outlook.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Neterskian <neterskian@gmail.com>
Co-authored-by: Nikola Perović <nikolaperovicccc@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Rikishaaa <jebote90@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: Unai <uesandi@gmail.com>
Co-authored-by: Viktoria PETROVA <victoriaapetrova@gmail.com>
Co-authored-by: Zakhar Timoshenko <vp1984tanki@gmail.com>
Co-authored-by: Zero O <godarms2010@live.com>
Co-authored-by: f3rr31 <5920873@disroot.org>
Co-authored-by: stevenlele <stevenlele@126.com>
Co-authored-by: typek52 <typek52@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Co-authored-by: Тимур <tucirs@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/bg/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/bn/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/cs/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/eu/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fil/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/he/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hu/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ja/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sk/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/te/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/uk/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/vi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/
Translation: Tachiyomi/Tachiyomi 0.x

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: Andre Rahardjo <zertozzf@gmail.com>
Co-authored-by: Aviv Ben Ami <avivbenami@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: DatTran MLL <tranthanhdat1142003@gmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Flamm <robindevaux25@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: HaruSasaki <aiqusubaru@gmail.com>
Co-authored-by: Hossain Rizbi <rsajib387@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: Italian Translator <nekoxtranslator@etlgr.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jagadeesh Vijay Varma <jagadeeshvarma.b@gmail.com>
Co-authored-by: Jan Obst <macek04@volny.cz>
Co-authored-by: Jetspectre <jetspectre1@gmail.com>
Co-authored-by: KasukeLp <kasukelp23@yahoo.com>
Co-authored-by: Lyaiya <hipsnafoha@outlook.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Neterskian <neterskian@gmail.com>
Co-authored-by: Nikola Perović <nikolaperovicccc@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Rikishaaa <jebote90@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: Unai <uesandi@gmail.com>
Co-authored-by: Viktoria PETROVA <victoriaapetrova@gmail.com>
Co-authored-by: Zakhar Timoshenko <vp1984tanki@gmail.com>
Co-authored-by: Zero O <godarms2010@live.com>
Co-authored-by: f3rr31 <5920873@disroot.org>
Co-authored-by: stevenlele <stevenlele@126.com>
Co-authored-by: typek52 <typek52@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Co-authored-by: Тимур <tucirs@gmail.com>
(cherry picked from commit 5122aed332)
2022-01-01 15:25:47 -05:00
Jobobby04 60f3ee1978 Remove NSFW annotation 2022-01-01 15:25:10 -05:00
Seishirou101 fe77aa9ab1 Add compress to CBZ on download (#6360)
(cherry picked from commit 5336c5b46e)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt
2022-01-01 15:24:12 -05:00
Mohit Mandalia dc992ee932 Fixes descriptive notification message for errors (#6413)
* Fixes descriptive notification message for errors
Fixes #6401

* Fixes descriptive notification message for errors
Fixes #6401

(cherry picked from commit 22615f5981)
2022-01-01 15:05:17 -05:00
arkon b153f22c41 Add AppInfo functions to replace BuildConfig usages in extensions
(cherry picked from commit bdf4b4b679)
2022-01-01 15:04:53 -05:00
arkon c330e14fd8 Remove unused Nsfw annotation
Extensions now purely declare it through the Gradle config

(cherry picked from commit 548e300c4b)
2022-01-01 15:04:43 -05:00
arkon 7459a19e64 Remove explicit option to store downloads in app data folder
App data is typically deleted during app uninstallation, which some users are unaware of. The folder is also inaccessible externally by default in Android 11+, which is also annoying to users.

(cherry picked from commit 8a5d8c96ef)
2022-01-01 15:04:33 -05:00
arkon 0792ef3b1f Move preference extension functions to utils
(cherry picked from commit 78c2631b6f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
2022-01-01 15:04:16 -05:00
arkon 3de8480630 Add link to troubleshooting guide in library update error log file
(cherry picked from commit 7c246ffc71)
2022-01-01 14:35:21 -05:00
arkon e3fda751ae Update versions and about libraries plugins
(cherry picked from commit 8bb85753cc)
2022-01-01 14:35:06 -05:00
arkon 77d0dc2e1d Swallow observable errors instead of crashing
(cherry picked from commit abfdde28ef)
2022-01-01 14:34:36 -05:00
arkon a893ac6e5f Update analytics dependencies
(cherry picked from commit 9801f1edfa)

# Conflicts:
#	app/build.gradle.kts
2022-01-01 14:34:29 -05:00
FourTOne5 756ddebda9 Fix Crash while trying to search in Settings (#6397)
* Fix Crash while trying to search in Settings

* Use already provided categories

(cherry picked from commit fc3a200a63)
2022-01-01 14:33:56 -05:00
FourTOne5 4f861f698c Update wording of pref_remove_after_marked_as_read (#6418)
(cherry picked from commit 6a00658119)
2022-01-01 14:33:48 -05:00
arkon 47f09b936c Fix some crashes
(cherry picked from commit 353485054e)
2022-01-01 14:33:35 -05:00
Jobobby04 34f98a3cd4 MDList support rating mangas 2021-12-27 16:20:32 -05:00
Jobobby04 d7856fe351 Mangadex support manga rating 2021-12-27 16:19:42 -05:00
Jobobby04 77f5acf2dd Show Mangadex relations in Mangadex similar 2021-12-27 16:12:09 -05:00
Jobobby04 87d9512b1f Minor cleanup 2021-12-27 12:15:52 -05:00
Román 5c9d1afe41 Russian Strings (#475)
* Changing some russian strings

* Changed more strings

* Changed and deleted some strings

* Fixed the position of CDATA

* Some string changes before preview update

* Improved russian translation

* Why you bully me

* MOOOM, he's bullying me
2021-12-26 16:37:52 -05:00
HaruSasaki 359467d6f5 Add Indonesian translation for SY strings (#476) 2021-12-26 16:05:31 -05:00
Jobobby04 fb77eec2d3 Minor fix 2021-12-26 15:55:20 -05:00
FourTOne5 282abf12c9 Actually Fix #6341 (#6392)
(cherry picked from commit 800583b5e2)
2021-12-26 15:52:58 -05:00
arkon 4a2e8806c1 Fix crash for bound intListPreferences
(cherry picked from commit 2db2b7348d)
2021-12-26 15:52:48 -05:00
arkon 572eb0cceb Reduce redundancy in some preference declarations
The remaining ones could also be converted to FlowPreferences for this, but it's not really necessary.

(cherry picked from commit f3718257f5)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBrowseController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt
2021-12-26 15:52:25 -05:00
Riztard Lanthorn c5819fe96f Update "Library updates restrictions" wording (#6371)
* Update "Library updates restrictions" wording

Co-Authored-By: OncePunchedMan <64155117+OncePunchedMan@users.noreply.github.com>
Co-Authored-By: nicki <72807749+curche@users.noreply.github.com>
Co-Authored-By: Soitora <simon.mattila@protonmail.com>
Co-Authored-By: FourTOne5 <59261191+FourTOne5@users.noreply.github.com>

* Update strings.xml

Co-Authored-By: loocool2 <36128021+loocool2@users.noreply.github.com>

Co-authored-by: OncePunchedMan <64155117+OncePunchedMan@users.noreply.github.com>
Co-authored-by: nicki <72807749+curche@users.noreply.github.com>
Co-authored-by: Soitora <simon.mattila@protonmail.com>
Co-authored-by: FourTOne5 <59261191+FourTOne5@users.noreply.github.com>
Co-authored-by: loocool2 <36128021+loocool2@users.noreply.github.com>
(cherry picked from commit 5500762acd)
2021-12-26 12:49:12 -05:00
Ivan Iskandar 396ae8bea3 Use animation to hide/show fab (#6385)
(cherry picked from commit 4c8f5e1f7a)
2021-12-26 12:49:06 -05:00
arkon 29cb6c95fd Fix incorrect locale name casing in extension details (fixes #6391)
Also closing https://github.com/tachiyomiorg/tachiyomi-extensions/issues/10007 since multisource extensions aren't really a thing anymore.

(cherry picked from commit 733cf99bb4)
2021-12-26 12:48:58 -05:00
arkon 8e0ca68af7 Truncate MAL search queries to first 64 characters (closes #6314)
Is it worth telling the user? ¯\_(ツ)_/¯

(cherry picked from commit 58c2f22120)
2021-12-26 12:48:50 -05:00
FourTOne5 638e569410 Case insensitive sort in extension list. (#6375)
* Sort Extension irrespective of it's name's case.

* Avoid creating unnecessary strings

Co-Authored-By: arkon <arkon@users.noreply.github.com>

Co-authored-by: arkon <arkon@users.noreply.github.com>
(cherry picked from commit 42accebeca)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionPresenter.kt
2021-12-26 12:48:41 -05:00
arkon 23e43a78d9 Avoid unnecessary string creation when sorting
(cherry picked from commit 1c5c370c12)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceFilterController.kt
2021-12-26 12:47:22 -05:00
arkon d22591665c Don't recompute constant device info
(cherry picked from commit 448645d83a)
2021-12-26 12:34:37 -05:00
arkon 621d5cc2bb Rename night theme color files too
(cherry picked from commit 09b6a3b41e)
2021-12-26 12:34:28 -05:00
FourTOne5 2e25989a5a Rename theme color value files so they are not scattered (#6384)
(cherry picked from commit 74206d60ce)
2021-12-26 12:33:12 -05:00
arkon 5c4a15660a Update dependencies
(cherry picked from commit c3a0de7fab)
2021-12-26 12:33:04 -05:00
arkon b12a8f8af4 Avoid crash on Samsung devices on Android 12
Co-authored-by: Jays2Kings <Jays2Kings@users.noreply.github.com>
(cherry picked from commit 7edf7a434f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
2021-12-26 12:32:54 -05:00
arkon d4e3b463a3 Handle potentially missing sources list in extensions JSON
Can happen in:
- Unofficial repos
- If the inspector breaks

(cherry picked from commit b701821550)
2021-12-26 12:32:11 -05:00
Hunter Nickel 6cb0342929 Fix Global Search ignoring incognito mode when setting last used source. (#6374)
(cherry picked from commit d022bf2673)
2021-12-26 12:32:03 -05:00
FourTOne5 0e437eaa6a Fix readded chapters polluting 'Updates' tab. (#6377)
(cherry picked from commit 7eed8c440c)
2021-12-26 12:31:53 -05:00
FourTOne5 25091e80c1 Fix #6341 (#6383)
(cherry picked from commit 1ab12e380a)
2021-12-26 12:31:45 -05:00
Ivan Iskandar 317419bde5 TachiyomiCoordinatorLayout: Remove app bar lift mechanism for view pager (#6379)
This is a follow up to 845e061382
...jk i actually forgot about it

(cherry picked from commit 728e14e8e4)
2021-12-26 12:31:36 -05:00
FourTOne5 5474d29cc7 Fix #6366 (#6372)
(cherry picked from commit 8aa402526a)
2021-12-26 12:31:27 -05:00
FourTOne5 c76fe9bb1d Update some wording in Delete Chapters preference. (#6365)
(cherry picked from commit 4793ee4786)
2021-12-26 12:31:17 -05:00
Jobobby04 d60ff91ae4 Filter out unpublished chapters without an external url 2021-12-26 12:24:35 -05:00
Jobobby04 3ec0777d63 Remove useless extension function 2021-12-26 12:23:43 -05:00
Jobobby04 c498d03d6b Mangadex: Use updated /at-home/server/ endpoint for pages 2021-12-25 12:08:50 -05:00
Jobobby04 9e9fa80450 Migrate EHentaiThrottleManager from Longs to durations 2021-12-25 12:07:09 -05:00
Jobobby04 999e944c34 Move to official duration extensions 2021-12-25 12:05:06 -05:00
Jobobby04 8b8df62ff3 Fix clear database crash 2021-12-21 22:18:58 -05:00
Jobobby04 b8a53f9239 Manga info edit UI fixes 2021-12-21 15:13:48 -05:00
Jobobby04 a2df6a7f11 Fix Mangadex logout crashes 2021-12-18 21:45:34 -05:00
FourTOne5 6972edbcb4 Better Upload Date to not have a single blank upload date. (#6358)
(cherry picked from commit a09d6c0470)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt
2021-12-18 18:15:09 -05:00
FourTOne5 13beef4ebe Add Better Extension Search (#6359)
Add support to searching with source name, id and baseUrl for a extension's sources.

(cherry picked from commit 9e83130bd8)
2021-12-18 18:11:46 -05:00
Ivan Iskandar a9f037dc8b Action toolbar adjustments (#6353)
* Pair ActionToolbar with ActionMode

This makes ActionToolbar an activity object that can be configured in the
similar way as ActionMode

* Remove action toolbar workaround now that it stays in activity layout

5924

* Set status bar color when action mode is active

6256

* Adjust fab show timing after action mode finished

* Adjust action toolbar layout and animation

Default corner size and use bottom sheet animation

6069

* Adjust action toolbar layout on large screen

Right half of the screen

(cherry picked from commit 2ed01af723)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
2021-12-18 14:27:13 -05:00
arkon cb00bf66cf Adjust global update preference wording and visibility
(cherry picked from commit afc80d6a7c)
2021-12-18 12:09:27 -05:00
arkon 9b3a839515 Address some IDE warnings
(cherry picked from commit 532a1b1aba)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/database/mappers/CategoryTypeMapping.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/mappers/MangaTypeMapping.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/LibraryMangaGetResolver.kt
2021-12-18 12:06:55 -05:00
arkon b665bd35f6 Remove library update order setting
This doesn't make sense to have if the intention is to have reasonably sized global updates. Opting to remove it to remove complexity instead.

(cherry picked from commit 65062b4bcb)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt
2021-12-18 12:00:27 -05:00
arkon 838eda73e3 [skip ci] update workflow actions
(cherry picked from commit c16206d816)

# Conflicts:
#	.github/workflows/build_push.yml
#	.github/workflows/cancel_pull_request.yml
2021-12-18 11:56:14 -05:00
arkon c5c23e623e Hide irrelevant settings if global update isn't enabled
(cherry picked from commit 7d1f5c7383)
2021-12-18 11:55:20 -05:00
arkon 2bd9d2844f Refactor dependant preference visibility flows
(cherry picked from commit 945afc71ef)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt
2021-12-18 11:55:12 -05:00
arkon b19c178eae Combine global update item restrictions
(cherry picked from commit 818fe50f77)

# Conflicts:
#	app/build.gradle.kts
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt
2021-12-18 11:48:18 -05:00
Riztard Lanthorn a9bb01125e Add option for library update only update completely read manga (#6323)
* Add option for library update only update completely read manga

only check manga for updates if there is no unread chapter

* sum

(cherry picked from commit 6fddad7a77)
2021-12-18 11:29:31 -05:00
Ivan Iskandar ae9fe06f7d Workaround cleanup (#6350)
* Remove material-components workaround that was fixed upstream

* Remove unused toolbar workaround

* Fix cover dialog navigation icon

(cherry picked from commit 38d131be37)

# Conflicts:
#	app/src/main/res/menu/library_selection.xml
#	app/src/main/res/menu/reader.xml
2021-12-18 11:29:19 -05:00
arkon 9fd8d5aa7c Update dependencies
(cherry picked from commit aeff846e1f)

# Conflicts:
#	app/build.gradle.kts
2021-12-18 11:20:35 -05:00
arkon 870558b6a9 Remove Gson dependencies
All official extensions no longer use Gson and Kotson

(cherry picked from commit ba1a2e9942)
2021-12-18 11:19:55 -05:00
Ivan Iskandar 22a6c8d772 Use elevated overlay on reader menu (#6347)
(cherry picked from commit 6b52fc1e2d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
2021-12-18 11:19:44 -05:00
arkon 8d813e3d62 Update to Kotlin 1.6.10
(cherry picked from commit 0671b530ba)
2021-12-18 11:04:05 -05:00
arkon 75db31914b Add link to privacy policy
(cherry picked from commit 207f9c26ae)
2021-12-18 11:03:58 -05:00
OncePunchedMan bd22026d16 sfix some colors and going back to original pink-ish color (#6344)
(cherry picked from commit 6367ce5e5e)
2021-12-18 11:03:50 -05:00
arkon 1ff5075e87 Revert download notification icon changes
(cherry picked from commit 7f998ecdbd)
2021-12-18 11:03:39 -05:00
Jobobby04 323c0135df Fix MDList search 2021-12-17 11:02:55 -05:00
D3xron 6500199d40 Update and improve Russian translation 2021-12-13 22:40:05 -05:00
Jobobby04 f2250e7cee Extract more strings to localizable files 2021-12-12 20:40:11 -05:00
Jobobby04 0936d4b844 Fix reader buttons 2021-12-12 20:39:00 -05:00
Jobobby04 2f32aa6984 Drop blank scanlators 2021-12-12 20:38:22 -05:00
Jobobby04 d7f5ded41a Fix and cleanup SmartSearch 2021-12-12 17:59:29 -05:00
Jobobby04 04451ab14e Fix mangadex logout crash 2021-12-12 14:57:08 -05:00
Jobobby04 6e8ee38238 Improve data saver handling 2021-12-12 12:16:07 -05:00
D3xron df0083e2e3 Update Russian translation 2021-12-11 21:42:48 -05:00
Jobobby04 c93db99098 Test this cuz why not 2021-12-11 20:52:57 -05:00
Jobobby04 7aaec0b0ed Use unicode escaped % sign in Russian translation 2021-12-11 20:31:31 -05:00
Jobobby04 6ddd6b84f9 Escape singular % sign in Russian translation 2021-12-11 20:07:10 -05:00
D3xron f911b09b55 Further improve Russian translation
-created an <!-- Appearance Settings --> and changed the position of related strings
  -translated strings with name 'data_saver_exclude' & 'data_saver_stop_exclude' and moved to the <!-- Advanced Settings -->
  -deleted quantity 'zero' in string with name 'pref_tag_sorting_desc'
  -changed strings with name 'log_minimal','log_extra & 'log_extreme'
  -changed string with name 'latest_'
  -changed string with name 'similar'
  -changed string with name 'visible'
  -changed string with name 'media_id'
  -changed string with name 'page_layout'
  -changed string with name 'eh_batch_add'
  -changed string with name 'ext_redundant'
  -changed string with name 'loading_manga'
  -changed string with name 'latest_tab_empty'
  -changed string with name 'too_many_watched'
  -changed string with name 'batch_add_summary'
  -changed string with name 'pref_category_fork'
  -changed string with name 'skip_page_restyling'
  -changed string with name 'eh_batch_add_finish'
  -changed string with name 'data_saver_color_bw'
  -changed string with name 'clear_db_exclude_read'
  -changed string with name 'reader_preload_amount'
  -changed string with name 'alternative_login_page'
  -changed string with name 'gallery_update_checker'
  -changed string with name 'fields_cannot_be_blank'
  -changed string with name 'action_add_repo_message'
  -changed string with name 'mangadex_add_to_follows'
  -changed string with name 'delete_merged_manga_desc'
  -changed string with name 'preserve_reading_position'
  -changed string with name 'reader_cache_size_summary'
  -changed string with name 'automatic_can_still_switch'
  -changed string with name 'gallery_updater_stats_text'
  -changed string with name 'gallery_updater_statistics'
  -changed string with name 'download_merged_manga_desc'
  -changed string with name 'skip_queue_on_retry_summary'
  -changed string with name 'pref_show_bottom_bar_labels'
  -changed string with name 'favorites_sync_add_to_local'
  -changed string with name 'reader_preload_amount_summary'
  -changed string with name 'captcha_solve_failure_message'
  -changed string with name 'custom_igneous_cookie_message'
  -changed string with name 'eh_settings_out_of_slots_error'
  -changed string with name 'eh_settings_out_of_slots_error'
  -changed string with name 'pref_source_navigation_summery'
  -changed string with name 'toggle_hentai_features_summary'
  -changed string with name 'force_sync_state_reset_summary'
  -changed string with name 'pref_source_navigation_summery'
  -changed string with name 'pref_skip_pre_migration_summary'
  -changed string with name 'pref_force_horz_seekbar_summary'
  -changed string with name 'no_chapters_found_for_migration'
  -changed string with name 'favorites_sync_adding_to_remote'
  -changed string with name 'favorites_sync_remove_from_local'
  -changed string with name 'chapter_updates_merged_manga_desc'
  -changed string with name 'put_recommends_in_overflow_summary'
  -changed string with name 'batch_add_unknown_type_log_message'
  -changed string with name 'library_group_updates_all_but_ungrouped'
  -changed string with name 'mangadex_sync_follows_to_library_summary'
2021-12-11 19:39:23 -05:00
Jobobby04 7e7f707c1b Fix redundant extensions 2021-12-11 15:37:59 -05:00
Jobobby04 e9b4385619 Remove unused strings 2021-12-11 15:37:15 -05:00
D3xron aaeb5e0308 Improved Russian translation 2021-12-11 15:19:27 -05:00
arkon 545f275a44 Move custom brightness slider to top of filter sheet (closes #6205)
Brightness should be modified more often than the color filter. Since this will always be visible even when the sheet is half expanded, you have a better idea of its effect.

(cherry picked from commit ecd5414287)
2021-12-11 15:02:41 -05:00
arkon b9fdb774f5 Refactor backup restore process to stop relying on file extension
(cherry picked from commit 6107f5f3d2)
2021-12-11 15:02:33 -05:00
arkon 7c30cb0e21 Show version name in new update notification
(cherry picked from commit 13afa9f476)
2021-12-11 15:02:25 -05:00
arkon 5d5df6f502 Don't preselect any options in library remove manga/downloads dialog (closes #6333)
Since apparently people don't read and either option is considered destructive to different people.

(cherry picked from commit cd87c7e88e)
2021-12-11 15:02:18 -05:00
arkon 08d022d5e2 Update notification icons
Although no recent version of Android even shows these....

(cherry picked from commit ed4dea8686)
2021-12-11 15:02:10 -05:00
KieuQ d5d6f9428c Add download action to New Chapters Notification (#6336)
(cherry picked from commit 808177f8c9)
2021-12-11 15:01:59 -05:00
arkon 27d069bdd5 Update AGP and Gradle
(cherry picked from commit aed51251b3)
2021-12-11 15:01:32 -05:00
Andreas dff5b56a28 Apply dialog theme to Material Alert Dialog Theme (#6340)
(cherry picked from commit 1c2730163d)
2021-12-11 15:01:24 -05:00
Andreas 79a5a4cb80 Fix back button having wrong tint in Toolbar (#6339)
(cherry picked from commit 0de86dfe6f)
2021-12-11 15:01:18 -05:00
OncePunchedMan 25f20de088 Tweak Midnight Dusk colors (#6327)
* tweak midnight dusk colors

* more tweaking and change pure black dark mode option visibility

* revert changing pure black dark mode option visibility

* change tertiary color on light theme to match dark theme

(cherry picked from commit 7a1b99be46)
2021-12-11 15:01:10 -05:00
arkon d1d8e8ed84 Check if dynamic colors are available using official API
(cherry picked from commit 9b64b0139c)
2021-12-11 15:01:03 -05:00
Carlos Ruiz 1b04ce0ac6 Add sui support (#6318)
* Update shizuku api version

* SettingsAdvanced Controller: Verify if Sui is available

(cherry picked from commit 0a6160d7cf)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
2021-12-11 15:00:55 -05:00
Ivan Iskandar 3a4641f32c SourcePreferencesController: Also call onBindEditText listener set by extension (#6310)
(cherry picked from commit e51a6d332e)
2021-12-11 15:00:08 -05:00
jmir1 83ef443e59 Automatically set tracker as completed after reading the last chapter (#6289)
* Automatically set tracker as completed after reading the last chapter.

* use integer value in comparison

* also set `started_reading` date

* don't use source manga's status

* remove useless line

(cherry picked from commit a9d2741e6a)
2021-12-11 14:59:59 -05:00
arkon e23598e361 Remove unnecessary tab style
(cherry picked from commit 12bd7268d2)
2021-12-11 14:59:50 -05:00
Ivan Iskandar 81c089299e Tabbed bottom sheet adjustments (#6309)
* SimpleNavigationView: Don't set background and elevation

* Add divider for tabs in bottom sheet

(cherry picked from commit be0a23d9ad)
2021-12-11 14:59:40 -05:00
Ivan Iskandar d71ca9ae0f Apply elevation overlay to colored navbar (#6308)
(cherry picked from commit 458a0e608a)
2021-12-11 14:59:33 -05:00
arkon 3078b7fb89 Update dependencies
(cherry picked from commit 32f3a50def)
2021-12-11 14:59:24 -05:00
Jobobby04 4e9fe9790b Minor cleanup 2021-12-11 14:58:23 -05:00
Jobobby04 8dad132509 Improve library selection 2021-12-11 14:57:31 -05:00
Jobobby04 693ae6c7be Support Mangadex Nepali 2021-12-07 08:46:39 -05:00
Jobobby04 c5b2aa180e Data saver: Long click a source to exclude, also downloader can be excluded.
Small rewrite of Data saver
2021-12-04 14:12:20 -05:00
Jobobby04 54c67bf22c Library selection only show categories if there is room 2021-12-03 11:25:24 -05:00
Jobobby04 f1172c04e4 Fix genre spacing 2021-12-02 21:56:30 -05:00
Jobobby04 21346eefe2 Minor lint fixes 2021-12-02 20:54:54 -05:00
Jobobby04 42da9abe3e Build fixes after cherry picking 2021-12-02 20:44:05 -05:00
Jobobby04 85207b1d2d Update gradle-command-action 2021-12-02 19:37:24 -05:00
arkon df07276e20 Avoid loading available extensions list if it seems too small
(cherry picked from commit 6a39c8fc13)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt
2021-12-02 19:35:35 -05:00
arkon a3cea7e6a3 Use default snackbar styles (fixes unreadable text)
Sorry AMOLED users, you'll just have to deal with the brief light snackbars.

(cherry picked from commit dc39669321)
2021-12-02 19:30:18 -05:00
arkon 4a87181d3b Throw exceptions if some of the deprecated source methods are used
(cherry picked from commit be4f27028c)
2021-12-02 19:30:10 -05:00
arkon c49c2b28eb Allow loading extension-lib 1.3
(Which doesn't actually exist yet, but will at some point after the next major release)

(cherry picked from commit 60e73e2d1f)
2021-12-02 19:30:02 -05:00
arkon 586bd3301d Add convenience extension functions for rate limit interceptors
To be included in extension-lib 1.3 as a replacement for the lib that's currently compiled in tachiyomi-extensions.

(cherry picked from commit e8f284d377)
2021-12-02 19:29:56 -05:00
arkon a3a27dc1c6 Add UnmeteredSource interface
To be included in extension-lib 1.3 (or whatever it's going to be). This applies to sources like Komga or Lanragi, where large numbers of update/download aren't of concern since they're (usually) self-hosted.

(cherry picked from commit 3ea3b0bf2e)
2021-12-02 19:29:50 -05:00
arkon 7e25eb8587 Update dependencies
(cherry picked from commit e1a43d2e7d)
2021-12-02 19:29:43 -05:00
arkon 7bd46dac35 [skip ci] update issue-moderator-action
(cherry picked from commit 2e918fe1d6)
2021-12-02 19:29:33 -05:00
Jozef Hollý 80494a760a Weblate translations (#6179)
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: Anup Pandey <pandeyanup58@gmail.com>
Co-authored-by: Arunava Ghosh <senseiarunava@gmail.com>
Co-authored-by: Blue <bluestuffish@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: DatTran MLL <tranthanhdat1142003@gmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: FateXBlood <zecrofelix@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Guerilla Girl <tnfgdqzx@guerrillamail.info>
Co-authored-by: Haithem Djabi <zabiz9632@gmail.com>
Co-authored-by: HaruSasaki <aiqusubaru@gmail.com>
Co-authored-by: HeavenShadow <heavenshadow@outlook.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: Italian Translator <nekoxtranslator@etlgr.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jendrej <ejjendrej@gmail.com>
Co-authored-by: Jozef Hollý <j2.00ghz@gmail.com>
Co-authored-by: KasukeLp <kasukelp23@yahoo.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nepx <anandabaskara@outlook.com>
Co-authored-by: Neterskian <neterskian@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pavka <pavel-mosein@yandex.ru>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Raven Neil Ocampo <ocamporavenneil@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: Tom de Groot <ikbeniemanddieheet@gmail.com>
Co-authored-by: Zakhar Timoshenko <vp1984tanki@gmail.com>
Co-authored-by: anenasa <anenasaa@yahoo.com>
Co-authored-by: pepe1987 <killyourpepe@gmail.com>
Co-authored-by: ricardofontao2000 <up201806317@fe.up.pt>
Co-authored-by: sebastians17 <sebastians117.ss@gmail.com>
Co-authored-by: swastik <smokexd676@gmail.com>
Co-authored-by: zm-dksg <zemariadekonincksg@gmail.com>
Co-authored-by: Újvári Marcell <mmarci72@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ar/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/bn/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/cs/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es_419/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fil/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hu/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ja/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ne/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/uk/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/vi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/
Translation: Tachiyomi/Tachiyomi 0.x

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: Anup Pandey <pandeyanup58@gmail.com>
Co-authored-by: Arunava Ghosh <senseiarunava@gmail.com>
Co-authored-by: Blue <bluestuffish@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: DatTran MLL <tranthanhdat1142003@gmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: FateXBlood <zecrofelix@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Guerilla Girl <tnfgdqzx@guerrillamail.info>
Co-authored-by: Haithem Djabi <zabiz9632@gmail.com>
Co-authored-by: HaruSasaki <aiqusubaru@gmail.com>
Co-authored-by: HeavenShadow <heavenshadow@outlook.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: Italian Translator <nekoxtranslator@etlgr.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jendrej <ejjendrej@gmail.com>
Co-authored-by: KasukeLp <kasukelp23@yahoo.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nepx <anandabaskara@outlook.com>
Co-authored-by: Neterskian <neterskian@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pavka <pavel-mosein@yandex.ru>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Raven Neil Ocampo <ocamporavenneil@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: Tom de Groot <ikbeniemanddieheet@gmail.com>
Co-authored-by: Zakhar Timoshenko <vp1984tanki@gmail.com>
Co-authored-by: anenasa <anenasaa@yahoo.com>
Co-authored-by: pepe1987 <killyourpepe@gmail.com>
Co-authored-by: ricardofontao2000 <up201806317@fe.up.pt>
Co-authored-by: sebastians17 <sebastians117.ss@gmail.com>
Co-authored-by: swastik <smokexd676@gmail.com>
Co-authored-by: zm-dksg <zemariadekonincksg@gmail.com>
Co-authored-by: Újvári Marcell <mmarci72@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
(cherry picked from commit 601309c7cc)
2021-12-02 19:29:18 -05:00
jmir1 b2b5854910 Fix local source cover changing (#6252)
* fix local source cover changing

* Remove unnecessary check for `exists()`

* fix for when there is no thumbnail_url in the db

(cherry picked from commit 10ddeeb799)
2021-12-02 19:29:08 -05:00
Ivan Iskandar 8ad6e89ca6 MinMaxNumberPicker: Set IME input to use number only (#6286)
* MinMaxNumberPicker: Set IME input to use number only

* MinMaxNumberPicker: Auto disable keyboard input when needed

(cherry picked from commit 3463d6c752)
2021-12-02 19:29:00 -05:00
Henrik f4f898c5c5 fix MAL search novel filter (#6279)
(cherry picked from commit 8acce011b5)
2021-12-02 19:28:51 -05:00
Ivan Iskandar 4bfa2779ff Change Tako dark elevation overlay color (#6255)
(cherry picked from commit fe9ea50356)
2021-12-02 19:28:44 -05:00
Riztard Lanthorn 17928a2f40 Tweak Teal & Turquoise color for new M3 (#6268)
* Tweak Teal & Turquoise color for new M3

* capitalize

* tweak elevationOverlayColor

* more tweak

(cherry picked from commit e6f29ae57f)
2021-12-02 19:28:36 -05:00
arkon f2b071ee9d Fix crash in clear database screen (fixes #6271)
(cherry picked from commit 6cfd2c510b)
2021-12-02 19:28:23 -05:00
arkon fba5b999dd Add tertiary badge in appearance preview (closes #5867)
(cherry picked from commit 430ff80198)
2021-12-02 19:28:15 -05:00
arkon bf0902c186 Add divider under extension details header
(cherry picked from commit 230fa76d57)
2021-12-02 19:28:04 -05:00
arkon 43ef18cdc3 Partially migrate LocalSource to 1.x methods
(cherry picked from commit 46a4b0e0b6)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt
2021-12-02 19:27:53 -05:00
arkon 3af5098612 Clean up some tablet dimension values
(cherry picked from commit 5b3cadb7a8)
2021-12-02 19:22:59 -05:00
arkon 6661983d65 Update to Conductor 3.1.1
(cherry picked from commit 3153071a8a)
2021-12-02 19:22:53 -05:00
arkon 295d80e741 Add ability to clear cookies per-extension (closes #3153)
(cherry picked from commit bba7372556)
2021-12-02 19:22:44 -05:00
Hunter Nickel 7efde9c74c Add feature to clear database manga by source (#6241)
* Implement feature to selectively clear manga from database based on it's source

* Code cleanup and refactoring

(cherry picked from commit 9fe1a7e2ae)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/queries/RawQueries.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
2021-12-02 19:22:32 -05:00
arkon 475dc87604 Option to clear chapter cache when MainActivity is closed (closes #5651)
(cherry picked from commit 98822a39d9)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
2021-12-02 19:12:09 -05:00
arkon f049e1e2db Tweak app theme preference selection (closes #5866)
(cherry picked from commit a2c830b908)
2021-12-02 19:11:34 -05:00
Ivan Iskandar 4b25e3c31e Replace Resume FAB reveal animation with container transform (#6250)
(cherry picked from commit bdef2cfdfb)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/widget/RevealAnimationView.kt
2021-12-02 19:11:20 -05:00
Andreas ecbd80c55d Tweak relative date function (#6249)
* Tweak relative date function

* Cleanup

(cherry picked from commit f229a5e2ec)
2021-12-02 19:01:47 -05:00
Ivan Iskandar 1fd495f8d8 Reinstate elevation overlay (#6243)
* Theme default elevation overlay

* Fix app bar elevation overlay

Elevation overlay is disabled when tabs are visible

* Remove custom elevation overlay in tracking sheet item

* upsi

(cherry picked from commit 845e061382)
2021-12-02 19:01:41 -05:00
Soitora 1e8e02b0ea Rework the Library icon for the third time (#6237)
Power outtage made me lose an hour of work sadg

(cherry picked from commit e7d4eb1ae3)
2021-12-02 19:01:33 -05:00
arkon 1a2311e7ba Update dependencies
(cherry picked from commit b4ba56bfb4)
2021-12-02 19:01:25 -05:00
arkon 93a4634995 Clean up ActionMode styles
(cherry picked from commit 25784d1fe5)
2021-12-02 19:01:16 -05:00
arkon 7048d3e106 Use outlined cards in tracker search
(cherry picked from commit 619eca7a51)
2021-12-02 19:01:08 -05:00
arkon 1faeb083e4 Adjust manga genre chip style
(cherry picked from commit f3d85655a0)
2021-12-02 19:01:01 -05:00
arkon 9108b63ba4 Adjust CardView styles
(cherry picked from commit 9600675677)
2021-12-02 19:00:54 -05:00
arkon 3e7eaa58c1 Fix colorFilterActive in Tako theme
(cherry picked from commit ce8a759192)
2021-12-02 19:00:46 -05:00
Jobobby04 af89ebaa42 Remove Pure red theme 2021-12-02 19:00:09 -05:00
Ivan Iskandar a3f3099cfb Adapt App Themes to M3 Color System (#6230)
* Adapt Default theme to M3 color system

* Adapt Dynamic theme to M3 color system

* Adapt Midnight Dusk theme to M3 color system

* Adapt Strawberry Daiquiri theme to M3 color system

* Adapt Yotsuba theme to M3 color system

* Adapt Tako theme to M3 color system

* Adapt Green Apple theme to M3 color system

* Adapt Teal & Turquoise theme to M3 color system

* Adapt Yin & Yang theme to M3 color system

* Remove old theme colors

* Yotsuba theme adjustments

Co-authored-by: ztimms73 <vp1984tanki@gmail.com>

* Green Apple theme adjustments

Co-authored-by: Soitora <10836780+Soitora@users.noreply.github.com>

* Tako theme adjustments

* Midnight Dusk theme adjustments

* Use colorSurfaceVariant for colorControlHighlight

* Nits

Co-authored-by: ztimms73 <vp1984tanki@gmail.com>
Co-authored-by: Soitora <10836780+Soitora@users.noreply.github.com>
(cherry picked from commit 88bc0bf613)
2021-12-02 18:34:36 -05:00
Soitora 5031a6e47b Fix library animation lag (#6233)
(cherry picked from commit b508e4208a)
2021-12-02 18:34:28 -05:00
arkon 314f3b682b Fix overflowed action toolbar items
(cherry picked from commit c74d8cf499)
2021-12-02 18:34:21 -05:00
arkon c894f654de Remove outline from download queue items
(cherry picked from commit a34c2b082f)
2021-12-02 18:34:10 -05:00
Jobobby04 7e3e21f1a0 Fix a missing typography 2021-11-14 18:48:51 -05:00
arkon 19cdcdcab7 Address some Android lint warnings
(cherry picked from commit ad49a02879)

# Conflicts:
#	app/src/main/res/anim/fade_in_long.xml
#	app/src/main/res/drawable/ic_broken_image_grey_24dp.xml
2021-11-14 18:48:37 -05:00
arkon cd64b9b6eb Remove custom tab indicator style
M3 TabLayout has the same style built-in.

(cherry picked from commit e985ffc690)
2021-11-14 18:43:48 -05:00
Jobobby04 2b632fd6c5 Adapt M3 Typography SY 2021-11-14 18:43:38 -05:00
Ivan Iskandar a780ea8dd9 Adapt M3 Typography (#6228)
(cherry picked from commit 6cbb02f02d)
2021-11-14 18:35:32 -05:00
Andreas bc73e9f1d8 Fix "Check for updates" not working due to time cooldown (#6232)
* Fix "Check for updates" not working due to time cooldown

* Update AppUpdateChecker.kt

Co-authored-by: arkon <arkon@users.noreply.github.com>
(cherry picked from commit c0d0ff66b6)
2021-11-14 18:35:15 -05:00
Jobobby04 4ea72f5342 Keep future chapters on Mangadex like Billibi and Comikey 2021-11-14 18:34:22 -05:00
Jobobby04 b227f2a4a5 Fix most unknown titles 2021-11-14 18:09:47 -05:00
Jobobby04 fb4d15d9ef Better support tsumno and mangadex tag search 2021-11-13 23:19:01 -05:00
Jobobby04 114ef56329 Tweak title parsing 2021-11-13 22:52:50 -05:00
Jobobby04 0df5376545 Mangadex support completed status 2021-11-13 22:46:03 -05:00
Jobobby04 508f025092 Minor cleanup and fix build 2021-11-13 17:43:40 -05:00
Jobobby04 b41c4cac47 Cleanup filter sheet adapter 2021-11-13 17:43:17 -05:00
arkon 4795c16877 Only allow digits in custom download range dialog (closes #6220)
(cherry picked from commit 1e4d7f8c6e)
2021-11-13 17:31:42 -05:00
arkon a9dc395e19 Initial pass of Material 3 styling
Adjustments/fixes to follow.

(cherry picked from commit a8a761aa5f)
2021-11-13 17:31:35 -05:00
OncePunchedMan 49afc8c559 Added tabletUI option: "Automatic" (#6208)
* added automatic tablet ui option; useful for foldables

* set automatic as default, rename setting

* remove redundant checks

Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>

* remove redundant checks

Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>

* fix defaultValue

Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
(cherry picked from commit 41952f0215)
2021-11-13 17:31:26 -05:00
arkon 1b65243b59 Update dependencies
(cherry picked from commit bfcc883f01)
2021-11-13 17:31:18 -05:00
arkon 1cf6e030ef Don't auto-download chapters if excluded but no categories selected (fixes #6126)
(cherry picked from commit 39722055f5)
2021-11-13 17:31:09 -05:00
arkon 0f70c14879 Remove legacy blue theme
Causing too many theming issues/complexity. This will make the Material 3 transition easier.

(cherry picked from commit f85dfa90b8)
2021-11-13 17:31:00 -05:00
arkon e4f493503d Default to only updating non-completed manga
(cherry picked from commit 0a4163d236)
2021-11-13 17:30:52 -05:00
Andreas ab6445d010 Fix SwipeRefresh initial position in MangaController (#6211)
* Lower position of swipe refresh

* Tweak existing code that sets swipe refresh position

(cherry picked from commit 78de11a9e3)
2021-11-13 17:30:44 -05:00
arkon 188f2bf4f2 Use sw720dp for tablet UI threshold
(cherry picked from commit d2fc6d9f44)
2021-11-13 17:30:37 -05:00
arkon 9af4751095 Fix cutoff ripple for extension install cancel button
(cherry picked from commit abf31f4a79)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionHolder.kt
2021-11-13 17:30:27 -05:00
arkon 6f82ab64a0 Disable some unnecessary build features
(cherry picked from commit f28dd4f4de)

# Conflicts:
#	app/build.gradle.kts
2021-11-13 17:29:57 -05:00
arkon 5de01f4107 Update dependencies
(cherry picked from commit 55b64899f5)

# Conflicts:
#	app/build.gradle.kts
2021-11-13 17:28:58 -05:00
arkon c67193d00f Avoid crashing when notification channels can't be created/deleted
For example, the application may be launched from a service, where channels cannot be deleted.

(cherry picked from commit d4aeeadb26)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
2021-11-13 17:28:03 -05:00
arkon 683c9a9c69 Disable updates badge by default
(cherry picked from commit 7ce0110158)
2021-11-13 17:26:28 -05:00
Jobobby04 2e4120d436 Should fix crash with migration 2021-11-07 17:05:31 -05:00
Jobobby04 892f64829b Fix some weird behavior with saved searches 2021-11-02 19:47:20 -04:00
Jobobby04 bfe6ed1c12 Lint 2021-11-02 19:30:38 -04:00
Jobobby04 93f8a42742 Only show push to mdlist if mdlist is logged in 2021-11-02 19:14:18 -04:00
arkon 4d3e4bbea8 Update metadata in same scope as the rest of library update (fixes #5702, probably)
(cherry picked from commit 7c1e55eb7f)
2021-11-02 19:09:02 -04:00
jmir1 c04550fe15 Fix crash when updating library whithout manga to update (#6181)
(cherry picked from commit 27542bc81d)
2021-11-02 19:08:54 -04:00
arkon be2e95db38 Clean up local source chapter name cleaning (closes #5969)
(cherry picked from commit 9ebbfb2d90)
2021-11-02 19:08:47 -04:00
arkon 39449b66e1 Fix bottom nav sometimes appearing within navbar area
(cherry picked from commit 701b1ee744)
2021-11-02 19:08:37 -04:00
arkon d95833fce7 Move app and extension update notifications to new channels/group (closes #6168)
(cherry picked from commit 0edc981cd2)
2021-11-02 19:08:30 -04:00
arkon 13f1f37a3e Remove unused fast scroll bubble drawable and accidentally committed file
(cherry picked from commit da5942b398)
2021-11-02 19:08:21 -04:00
arkon d699d3899c Move unread chapters badge setting to General section
(cherry picked from commit 709de81814)
2021-11-02 19:08:15 -04:00
Ivan Iskandar 4ad33540f3 Extension "Update all" button (#6171)
Disabled for legacy installer

(cherry picked from commit 90b312a56e)
2021-11-02 19:08:08 -04:00
Hunter Nickel 951418b576 Add badge to bottom bar Updates tab indicating how many unread chapter updates are available (#5620)
Co-authored-by: arkon <arkon@users.noreply.github.com>
(cherry picked from commit 459759bfe5)
2021-11-02 19:08:00 -04:00
arkon 29801d4dd0 Remove translations of non-translatable strings
(cherry picked from commit 00817aacfe)
2021-11-02 19:07:52 -04:00
Jozef Hollý dd843649cb Weblate translations (#6118)
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Areen Anwar <areenanwar66@gmail.com>
Co-authored-by: Blue <bluestuffish@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: DatTran MLL <tranthanhdat1142003@gmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Hautzii <am.03012002@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jozef Hollý <j2.00ghz@gmail.com>
Co-authored-by: KasukeLp <kasukelp23@yahoo.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Neterskian <neterskian@gmail.com>
Co-authored-by: Nin Gun <luis_noxer@hotmail.es>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Rafi <ziomeq65@gmail.com>
Co-authored-by: Resshi <jyxo@centrum.cz>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Soitora <simon.mattila@protonmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: jTnqr <juliuspanjul25@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: sebastians17 <sebastians117.ss@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/cs/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es_419/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fil/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ja/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sdh/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/vi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/
Translation: Tachiyomi/Tachiyomi 0.x

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Areen Anwar <areenanwar66@gmail.com>
Co-authored-by: Blue <bluestuffish@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: DatTran MLL <tranthanhdat1142003@gmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Hautzii <am.03012002@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: KasukeLp <kasukelp23@yahoo.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Neterskian <neterskian@gmail.com>
Co-authored-by: Nin Gun <luis_noxer@hotmail.es>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Rafi <ziomeq65@gmail.com>
Co-authored-by: Resshi <jyxo@centrum.cz>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Soitora <simon.mattila@protonmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: jTnqr <juliuspanjul25@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: sebastians17 <sebastians117.ss@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
(cherry picked from commit e306eb0874)
2021-11-02 19:07:43 -04:00
Riztard Lanthorn af6b42cec7 Hide cutout toggle button if fullscreen is off (#6150)
(cherry picked from commit 33a02b47d5)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderGeneralSettings.kt
2021-11-02 19:07:29 -04:00
Tom Briden ec6b6ae779 Fix storing covers for local manga (#6127)
getCoverFile only returns a cover if it already exists, meaning
the block of code to write it from the inputstream never executes.
If getCoverFile returns null, then use previous behaviour of setting
it to cover.jpg so that if the file doesn't exist it's created

(cherry picked from commit f0a5557e60)
2021-11-02 19:06:35 -04:00
FlaminSarge 23fae05694 Allow manga titles to update from source if they are not in library (#6177)
The previous rationale for not allowing manga titles to update (at all) was that it would be confusing for users if a manga's title arbitrarily changed when the source changed it. Presumably, users would care less about this arbitrary change for manga that is not in library, so this provides a path for getting a manga's title updated, and prevents incorrect titles from persisting in the DB for manga that get title updates but aren't in library.

(cherry picked from commit 58a871c8cc)
2021-11-02 19:06:09 -04:00
arkon eb49df6ee8 Validate backup during creation
(cherry picked from commit 4f56071786)
2021-11-02 19:06:02 -04:00
arkon 64b1b3ac5d Update dependencies
(cherry picked from commit f8b2c79aef)
2021-11-02 19:05:54 -04:00
Andreas 29a24fa047 Change zoom from 3x to 5x (#6164)
Because some people actually read images with really small text

*I hope they have some extreme high quality pictures else I don't know how they read the raster images*

(cherry picked from commit 8f00d34b0b)
2021-11-02 19:05:45 -04:00
Soitora 95bca82355 More sensical string for 'pref_hide_threshold' (#6157)
(cherry picked from commit 6129519e5a)
2021-11-02 19:05:37 -04:00
arkon d8407e20da Sync view state with controller on activity resume
Hopefully fixes some weird states where the bottom nav shows up when it shouldn't.

(cherry picked from commit 593091a5e3)
2021-11-02 19:05:27 -04:00
arkon e28d72bf9c Minor cleanup
(cherry picked from commit 93e2b88d41)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateChecker.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
2021-11-02 19:05:18 -04:00
Jobobby04 8d291b1bc3 Implement invert double pages 2021-10-23 23:53:30 -04:00
Jobobby04 4d7d451fde Maybe help with double page jankyness 2021-10-23 22:35:07 -04:00
Jobobby04 ef9a4ee643 Launch the download warning toast in the UI thread 2021-10-23 16:44:21 -04:00
Jobobby04 04c683675f Fix MangaPlus errors 2021-10-23 16:36:42 -04:00
Jobobby04 f8d14827da Add some padding to the continue reading button if the lang badge is enabled 2021-10-23 16:30:20 -04:00
Jobobby04 c560b70b83 Fix extra padding if there is no namespace 2021-10-23 16:25:25 -04:00
Jobobby04 62ee9e6560 Fix vertical slider 2021-10-23 16:14:53 -04:00
Jobobby04 aa70a2e6f3 Fix reader slider not doing anything 2021-10-23 15:43:15 -04:00
Jobobby04 07d13aed4e Cleanup MangaPlus stuff, only keep what SY uses 2021-10-23 15:28:28 -04:00
Jobobby04 c0a3406335 fix imports 2021-10-23 14:35:15 -04:00
Jobobby04 0a91597dac Add in library badge to latest and new browse view 2021-10-23 14:25:14 -04:00
Jobobby04 b90f339476 Minor cleanup 2021-10-23 14:25:13 -04:00
Jobobby04 1f145ef0d4 Remove extra padding on namespace tags 2021-10-23 14:25:13 -04:00
Jobobby04 bb409e5ced Workaround for cbz long filename error 2021-10-23 14:25:12 -04:00
Midyan Hamdoun ed5c3f327c Fix double increment when updating covers (#6138)
* Fix double increment when updating covers

* Remove redundant block

(cherry picked from commit ccd7c8df53)
2021-10-23 14:25:12 -04:00
Jobobby04 72b33a1c52 Tweak mangadex integration 2021-10-23 14:25:11 -04:00
Jobobby04 8c23c07c78 Update dependancies 2021-10-23 14:25:11 -04:00
Jobobby04 080d845270 Update realm to move off JCenter for SY 2021-10-23 14:25:10 -04:00
Jobobby04 f2c881cb42 Update WI-FI restriction for EXH update worker 2021-10-23 14:25:10 -04:00
arkon 0b3a4e651e Remove jcenter usage (closes #4387)
(cherry picked from commit 5b3bd3f470)
2021-10-23 14:25:10 -04:00
arkon 9840e8ab57 Change tablet UI threshold to w720dp (closes #6054)
Was previously sw720dp. Now matches J2K.

(cherry picked from commit bf1b7f44b6)
2021-10-23 14:25:09 -04:00
arkon cdb9768335 Adjust update/download warnings
- Uses toasts now
- Adjusted wording to emphasize effect on sources
- Download warning has a different threshold (15 chapters per source, vs. 60 entries per source for library update)

(cherry picked from commit 538dd60580)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2021-10-23 14:25:08 -04:00
Platiplus 4e5a8668fc [6068] - Use semibold text for Browse items primary text (#6087)
* Changing the text on source title (browse items) to semibold and fixing the color of the subtitle on global search

* Updated history_item, updates_item and global_search to not have bold titles

* Changing global_search_controller_card

* Changing back history_item

(cherry picked from commit f453236840)
2021-10-23 14:25:08 -04:00
arkon 7849c7970e Minor cleanup
(cherry picked from commit bfe7aa1ed2)
2021-10-23 14:25:07 -04:00
arkon 5bf424af40 Remove global update intervals below 12 hours, add every 3 day interval
Users with smaller libraries have a lower change of getting updates frequently. "Power users" are actively hurting sources by updating frequently.

(cherry picked from commit 9e2ef82902)

# Conflicts:
#	app/build.gradle.kts
2021-10-23 14:25:07 -04:00
arkon 456fdbe4e9 Make tapping library update and backup restore error notifications open log
(cherry picked from commit 9352e249ee)
2021-10-23 14:25:06 -04:00
Midyan Hamdoun 5802bf7626 Fix crashing when clicking the search icon (#6128)
(cherry picked from commit 3800065230)
2021-10-23 14:25:06 -04:00
arkon 62c0f50314 Remove paused text when resuming downloads with info hidden (fixes #6119)
(cherry picked from commit ebc2c4f73a)
2021-10-23 14:25:05 -04:00
arkon cb55a46717 Use natural ordering when sorting by chapter numbers (fixes #6121)
(cherry picked from commit f057440cc1)
2021-10-23 14:25:05 -04:00
Jozef Hollý 8761451412 Weblate translations (#6047)
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Archie <careless.archie@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: DatTran MLL <tranthanhdat1142003@gmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Forqen <krecio555@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jendrej <ejjendrej@gmail.com>
Co-authored-by: Jetspectre <jetspectre1@gmail.com>
Co-authored-by: Jozef Hollý <j2.00ghz@gmail.com>
Co-authored-by: KasukeLp <kasukelp23@yahoo.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matey Krastev <matey_krastev2@abv.bg>
Co-authored-by: Pedro <pedro-mediavilla@hotmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Ric <rikku.debec@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Shippo <shiposhouyou@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: jTnqr <juliuspanjul25@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: swastik <smokexd676@gmail.com>
Co-authored-by: turhv jbufv <turhvjbufv@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ar/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/bg/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/cs/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es_419/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fil/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/he/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ja/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/uk/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/vi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/
Translation: Tachiyomi/Tachiyomi 0.x

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Archie <careless.archie@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: DatTran MLL <tranthanhdat1142003@gmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Forqen <krecio555@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jendrej <ejjendrej@gmail.com>
Co-authored-by: Jetspectre <jetspectre1@gmail.com>
Co-authored-by: KasukeLp <kasukelp23@yahoo.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matey Krastev <matey_krastev2@abv.bg>
Co-authored-by: Pedro <pedro-mediavilla@hotmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Ric <rikku.debec@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Shippo <shiposhouyou@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: jTnqr <juliuspanjul25@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: swastik <smokexd676@gmail.com>
Co-authored-by: turhv jbufv <turhvjbufv@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
(cherry picked from commit 506f9cfca8)
2021-10-23 14:25:04 -04:00
arkon 819075a8f1 Change global update unmetered connection restriction to connected to Wi-Fi (closes #6117)
(cherry picked from commit 8a70c3353f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt
2021-10-23 14:25:04 -04:00
arkon 01778c0c42 Add notification action to open GitHub release page
Co-authored-by: Jays2Kings <Jays2Kings@users.noreply.github.com>
(cherry picked from commit 3d8f123e05)
2021-10-23 14:25:03 -04:00
arkon b01e38f4c0 Update dependencies
(cherry picked from commit a8c8f15e07)

# Conflicts:
#	app/build.gradle.kts
2021-10-23 14:25:02 -04:00
arkon c4f06d9830 Rename app updating classes
So I stop confusing it for updaters of other things.

(cherry picked from commit 21e647017b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/Migrations.kt
2021-10-23 14:25:02 -04:00
Midyan Hamdoun 59d05af9ef Fix reappearing indicator in the History tab (#6105)
(cherry picked from commit 2a1bb3dc27)
2021-10-23 14:25:01 -04:00
Ivan Iskandar e63bd150e9 Fix AppBar lift state when snapped (#6103)
status bar foreground alpha is now handled separately

(cherry picked from commit 55a3094a65)
2021-10-23 14:25:01 -04:00
Andreas bfadfd0fc8 Fix inset not applying when in landscape (#6104)
Reverts inset change from #5997, was changed due to it not changing the padding when using setPadding

(cherry picked from commit b4490e209b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt
2021-10-23 14:25:00 -04:00
Jays2Kings 70c866d8f3 Use default source filters in global search (fixes #5583)
Based on https://github.com/Jays2Kings/tachiyomiJ2K/commit/45fbd9d2f5eba03f0734a58ad46de16a047ae783

(cherry picked from commit 9aa676333c)
2021-10-23 14:25:00 -04:00
Ivan Iskandar 28b57f4f42 Fix MangaController fast scroller position (#6090)
(cherry picked from commit bb06895145)
2021-10-23 14:24:59 -04:00
Jobobby04 01e4697a04 Fix badges binding 2021-10-23 14:24:59 -04:00
Ivan Iskandar b116f5e1fd MangaController optimizations (#6089)
* MangaController: Fix ignored stable ids

* MangaController: Replace notifyDataSetChanged

* ChaptersSettingsSheet: Optimizations

(cherry picked from commit 684965f3e5)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
2021-10-23 14:24:58 -04:00
Jays2Kings 7fb4cd29dc Add migration to add "all" to enabled langauges
Co-authored-by: Jays2Kings <Jays2Kings@users.noreply.github.com>
(cherry picked from commit e621f4e2fa)

# Conflicts:
#	app/build.gradle.kts
2021-10-23 14:24:57 -04:00
Jays2Kings 042bf4d4f6 Update missing chapters warning
Co-authored-by: Jays2Kings <Jays2Kings@users.noreply.github.com>
(cherry picked from commit 028ea57232)
2021-10-23 14:24:57 -04:00
arkon 6dac25855b Bump queue warning threshold to 60
Aligns with J2K.

(cherry picked from commit 718fa25c10)
2021-10-23 14:24:57 -04:00
arkon 01b0f0bec1 Update AGP
(cherry picked from commit 90c9f28818)
2021-10-23 14:24:56 -04:00
arkon f4d1f5ff95 Minor cleanup
(cherry picked from commit cb9c5a35cb)
2021-10-23 14:24:56 -04:00
arkon e202c108ff Handle HTTP 403 responses with CloudflareInterceptor
Based on https://github.com/jmir1/aniyomi/commit/8d34da591ed8e4341f0f8312402164a7bc17bc68

Co-authored-by: jmir1 <jmir1@users.noreply.github.com>
(cherry picked from commit fadaefeaef)
2021-10-23 14:24:55 -04:00
arkon 848a2ec4f6 Adjust update/download warning threshold
(cherry picked from commit b17b882a3b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
2021-10-23 14:24:55 -04:00
jmir1 def5bdca28 Fix issues with NSFW sources setting (#6085)
(cherry picked from commit f0f3afd5f1)
2021-10-23 14:24:54 -04:00
arkon e0a09cdac7 Allow hiding "All" section in extensions list (closes #6081)
(cherry picked from commit 42026b49bf)
2021-10-23 14:24:54 -04:00
arkon eea2d7b0e0 Reword missing chapters warning (closes #6074)
(cherry picked from commit 151193c4c3)
2021-10-23 14:24:53 -04:00
jmir1 7e11f3952f Fix crash when deleting last item in library (#6079)
(cherry picked from commit 3448751e0e)
2021-10-23 14:24:52 -04:00
arkon a9a93e2f8f Use SwitchMaterial for preferences too (closes #5724)
(cherry picked from commit aae011ed83)
2021-10-23 14:24:51 -04:00
arkon 38f1af7577 Use single layout for grid badges
(cherry picked from commit c95a269460)

# Conflicts:
#	app/src/main/res/layout/source_comfortable_grid_item.xml
#	app/src/main/res/layout/source_compact_grid_item.xml
2021-10-23 14:24:51 -04:00
arkon 155b36a0bc Reword badge titles
(cherry picked from commit 98c0e5271f)
2021-10-23 14:24:50 -04:00
arkon 806b35d024 Require authentication to toggle showing NSFW sources
(cherry picked from commit f343131802)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt
2021-10-23 14:24:50 -04:00
arkon 8bbaa60a1b Allow searching for multiple extensions at once (closes #5922)
(cherry picked from commit ea34ba53b9)
2021-10-23 14:24:49 -04:00
arkon bedb3f2bd8 Add some info about automatic backups
(cherry picked from commit b8d8cf19d9)
2021-10-23 14:24:49 -04:00
arkon 6b0927298a Smaller font size for reader page indicator (closes #6071)
(cherry picked from commit c9be4093e7)
2021-10-23 14:24:48 -04:00
arkon d9487ea7e9 Add warnings when library and download queues are considered large (closes #5950)
Arbitrarily set at a size of 100 for now. We could adjust this in the future as appropriate if needed.

(cherry picked from commit 082eef708f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
2021-10-23 14:24:48 -04:00
Ivan Iskandar 8a85d82587 Grouped chapter download list by source (#5575)
(cherry picked from commit 9106fc5b94)
2021-10-23 14:24:47 -04:00
Platiplus 59655ccfd1 [5893] - Implemented Language Badge (#6050)
* Implemented language badge on library items

* Added left margin for better viewing the badge on list view

* Adjusting borders on badges, cleaning string interpolation and cleaning code

* Improving readability on Holders and removing unused background and text on grid items

(cherry picked from commit 918502742d)
2021-10-23 14:24:47 -04:00
Ivan Iskandar 6bb8ae0d1e Manga description adjustments (#6011)
* Manga description adjustments

- Animated state changes
- Adjust scrim position to fully show 2 lines when shrunk
- Set minLines to avoid scrim hiding oneliner

* Change icon and adjust animation

* Revert fancy scrim animation

(cherry picked from commit f32f1eeaa5)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
#	app/src/main/res/layout-sw720dp/manga_info_header.xml
#	app/src/main/res/layout/manga_info_header.xml
2021-10-23 14:24:46 -04:00
nicki 1d80725ea9 Fix Local and Other lang sources showing up in seperate Other Categories (#6024)
* group LocalSource and Other lang source together

* use better kotlin syntactic sugar

* add lang "other" to local

* remove duplicate LocalSource entries in Browse

* linting

* revert unnecessary linting

was a manually adding change

* Revert previous two commit but not the most recent

This reverts commit 30250f2f82fc5e38a1b30c7b55c445efec23a114
This also reversts commit 359ed5a8cda91577216b593a4138280e971e0126

* better way to avoid duplicate Local Sources

* more linting by plugin

* `""` lang is no longer used anywhere

(cherry picked from commit 2d1404d155)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcePresenter.kt
2021-10-23 14:24:45 -04:00
arkon 353a3ffe00 Hide slider tooltip label everywhere
(cherry picked from commit a56997e98c)
2021-10-23 14:24:45 -04:00
arkon d0e6297995 Update dependencies
(cherry picked from commit ef918078d1)

# Conflicts:
#	app/build.gradle.kts
2021-10-23 14:24:44 -04:00
Jobobby04 be52ea6f18 Maybe fix a few crashes related to mangadex logins 2021-10-23 14:24:44 -04:00
Jobobby04 f76c48c8ae Fix SY text styles 2021-10-23 14:24:43 -04:00
Jobobby04 2f203f7a1d Cleanup and fixes 2021-10-23 14:24:43 -04:00
Ivan Iskandar 14d6e8dd94 Replace Timber with Square Logcat and make logging configurable (#6062)
* Replace Timber with Square Logcat

* Configurable logger

(cherry picked from commit 2e127dff1f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/details/SourcePreferencesController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewerAdapter.kt
2021-10-23 14:24:42 -04:00
Platiplus b10de38e9a [6059] - Pending downloads count on Download queue screen (#6064)
* Updating the download queue label to account for pending downloads even on paused state

* changing separator

* Created observer to update the TitleBar of the controller to reflect pending downloads

* Reverting changes from MoreController that were made in an another commit

* Refactoring updateTitle method

(cherry picked from commit e98f90b099)
2021-10-23 14:24:41 -04:00
Platiplus 22a1544427 [5753] - Add pending downloads count on Download queue (#6049)
* Updating the download queue label to account for pending downloads even on paused state

* changing separator

(cherry picked from commit 828db19e02)
2021-10-23 14:24:41 -04:00
Jozef Hollý 4380283ad1 Weblate translations (#6046)
Co-authored-by: AHmed HarBy <themagic1093@gmail.com>
Co-authored-by: Afiq Nazrie <afnazrie@gmail.com>
Co-authored-by: Ainārs Lapkovskis <ainarslapkovskis@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Albedo <Illiator27@gmail.com>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Blue <bluestuffish@gmail.com>
Co-authored-by: Christian Elbrianno <christian.elbrianno41@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Druvvaldis <druvvaldisr@gmail.com>
Co-authored-by: Emerson Nunes <emerson.nunes.ds@gmail.com>
Co-authored-by: Emma Jane Bonestell <EmmaJaneBonestell@gmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Fernando Sanchez <cheeze.sprinkels@gmail.com>
Co-authored-by: Forqen <krecio555@gmail.com>
Co-authored-by: Francesco Zanella <franzghosts@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Hassay Ádám Tamás <hassayadam@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jakub Fabijan <jakubfabijan@tuta.io>
Co-authored-by: Junan Chk <junanchakma2000@gmail.com>
Co-authored-by: K. Sz. Bence <tudi20@protonmail.com>
Co-authored-by: Kaleb <kalebcarvalho1@gmail.com>
Co-authored-by: Krishna Chand <krishna_chand67@naver.com>
Co-authored-by: LoneHash <sameepsk2@gmail.com>
Co-authored-by: Luna Jernberg <droidbittin@gmail.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Miguel Alexandro Manzano Guerra <kuro_eis@hotmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nishant Bodkhe <nishantbodkhe44@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pedro <pedro-mediavilla@hotmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Redy Apriyadi <redy.apriyadi@gmail.com>
Co-authored-by: Ric <rikku.debec@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Sieg Jaeger <zekerett@gmail.com>
Co-authored-by: Steven Pedroza <stevenpedroza56@gmail.com>
Co-authored-by: Temporary Person <TemporaryPerson@protonmail.com>
Co-authored-by: Zero O <godarms2010@live.com>
Co-authored-by: ZiomaleQ <r.partyka30@gmail.com>
Co-authored-by: crackheadakira <lasn.mine@gmail.com>
Co-authored-by: dmswd <Bmswad1@gmail.com>
Co-authored-by: julptk <julptk8@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: phannhanhn201 <phannhanhn201@gmail.com>
Co-authored-by: rytis sertvytis <knysliukas2002@gmail.com>
Co-authored-by: soplatnik <jestapom@protonmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Co-authored-by: พรหมชัย ชูแสง <promchai2sin@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/aii/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ar/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/bn/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/cs/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/eo/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es_419/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fil/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hu/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ja/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/jv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/lt/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/lv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/mr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ne/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/th/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/vi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/
Translation: Tachiyomi/Tachiyomi 0.x

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: AHmed HarBy <themagic1093@gmail.com>
Co-authored-by: Afiq Nazrie <afnazrie@gmail.com>
Co-authored-by: Ainārs Lapkovskis <ainarslapkovskis@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Albedo <Illiator27@gmail.com>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Blue <bluestuffish@gmail.com>
Co-authored-by: Christian Elbrianno <christian.elbrianno41@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Druvvaldis <druvvaldisr@gmail.com>
Co-authored-by: Emerson Nunes <emerson.nunes.ds@gmail.com>
Co-authored-by: Emma Jane Bonestell <EmmaJaneBonestell@gmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Fernando Sanchez <cheeze.sprinkels@gmail.com>
Co-authored-by: Forqen <krecio555@gmail.com>
Co-authored-by: Francesco Zanella <franzghosts@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Hassay Ádám Tamás <hassayadam@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jakub Fabijan <jakubfabijan@tuta.io>
Co-authored-by: Junan Chk <junanchakma2000@gmail.com>
Co-authored-by: K. Sz. Bence <tudi20@protonmail.com>
Co-authored-by: Kaleb <kalebcarvalho1@gmail.com>
Co-authored-by: Krishna Chand <krishna_chand67@naver.com>
Co-authored-by: LoneHash <sameepsk2@gmail.com>
Co-authored-by: Luna Jernberg <droidbittin@gmail.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Miguel Alexandro Manzano Guerra <kuro_eis@hotmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nishant Bodkhe <nishantbodkhe44@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pedro <pedro-mediavilla@hotmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Redy Apriyadi <redy.apriyadi@gmail.com>
Co-authored-by: Ric <rikku.debec@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Sieg Jaeger <zekerett@gmail.com>
Co-authored-by: Steven Pedroza <stevenpedroza56@gmail.com>
Co-authored-by: Temporary Person <TemporaryPerson@protonmail.com>
Co-authored-by: Zero O <godarms2010@live.com>
Co-authored-by: ZiomaleQ <r.partyka30@gmail.com>
Co-authored-by: crackheadakira <lasn.mine@gmail.com>
Co-authored-by: dmswd <Bmswad1@gmail.com>
Co-authored-by: julptk <julptk8@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: phannhanhn201 <phannhanhn201@gmail.com>
Co-authored-by: rytis sertvytis <knysliukas2002@gmail.com>
Co-authored-by: soplatnik <jestapom@protonmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Co-authored-by: พรหมชัย ชูแสง <promchai2sin@gmail.com>
(cherry picked from commit 99aa3f5713)
2021-10-23 14:24:40 -04:00
Andreas 908a2e19fe Fix stuck display mode for when not using per category setting (#6044)
(cherry picked from commit 1a568e2961)
2021-10-23 14:24:40 -04:00
arkon f72afd1359 Adjust Wi-Fi connection check (related to #6038)
(cherry picked from commit e863e8c64b)
2021-10-23 14:24:39 -04:00
Jozef Hollý f330ab3731 Weblate translations (#5913)
Co-authored-by: AHmed HarBy <themagic1093@gmail.com>
Co-authored-by: Ainārs Lapkovskis <ainarslapkovskis@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Albedo <Illiator27@gmail.com>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Blue <bluestuffish@gmail.com>
Co-authored-by: Christian Elbrianno <christian.elbrianno41@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Druvvaldis <druvvaldisr@gmail.com>
Co-authored-by: Emerson Nunes <emerson.nunes.ds@gmail.com>
Co-authored-by: Emma Jane Bonestell <EmmaJaneBonestell@gmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Fernando Sanchez <cheeze.sprinkels@gmail.com>
Co-authored-by: Forqen <krecio555@gmail.com>
Co-authored-by: Francesco Zanella <franzghosts@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Hassay Ádám Tamás <hassayadam@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jakub Fabijan <jakubfabijan@tuta.io>
Co-authored-by: Junan Chk <junanchakma2000@gmail.com>
Co-authored-by: K. Sz. Bence <tudi20@protonmail.com>
Co-authored-by: Kaleb <kalebcarvalho1@gmail.com>
Co-authored-by: Krishna Chand <krishna_chand67@naver.com>
Co-authored-by: LoneHash <sameepsk2@gmail.com>
Co-authored-by: Luna Jernberg <droidbittin@gmail.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Miguel Alexandro Manzano Guerra <kuro_eis@hotmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nishant Bodkhe <nishantbodkhe44@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pedro <pedro-mediavilla@hotmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Redy Apriyadi <redy.apriyadi@gmail.com>
Co-authored-by: Ric <rikku.debec@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Sieg Jaeger <zekerett@gmail.com>
Co-authored-by: Steven Pedroza <stevenpedroza56@gmail.com>
Co-authored-by: Temporary Person <TemporaryPerson@protonmail.com>
Co-authored-by: Zero O <godarms2010@live.com>
Co-authored-by: ZiomaleQ <r.partyka30@gmail.com>
Co-authored-by: crackheadakira <lasn.mine@gmail.com>
Co-authored-by: dmswd <Bmswad1@gmail.com>
Co-authored-by: julptk <julptk8@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: phannhanhn201 <phannhanhn201@gmail.com>
Co-authored-by: rytis sertvytis <knysliukas2002@gmail.com>
Co-authored-by: soplatnik <jestapom@protonmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Co-authored-by: พรหมชัย ชูแสง <promchai2sin@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/aii/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ar/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/bn/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/cs/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/eo/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es_419/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fil/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hu/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ja/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/jv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/lt/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/lv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/mr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ne/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/th/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/vi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/
Translation: Tachiyomi/Tachiyomi 0.x

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: AHmed HarBy <themagic1093@gmail.com>
Co-authored-by: Ainārs Lapkovskis <ainarslapkovskis@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Albedo <Illiator27@gmail.com>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Blue <bluestuffish@gmail.com>
Co-authored-by: Christian Elbrianno <christian.elbrianno41@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Druvvaldis <druvvaldisr@gmail.com>
Co-authored-by: Emerson Nunes <emerson.nunes.ds@gmail.com>
Co-authored-by: Emma Jane Bonestell <EmmaJaneBonestell@gmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Fernando Sanchez <cheeze.sprinkels@gmail.com>
Co-authored-by: Forqen <krecio555@gmail.com>
Co-authored-by: Francesco Zanella <franzghosts@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Hassay Ádám Tamás <hassayadam@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jakub Fabijan <jakubfabijan@tuta.io>
Co-authored-by: Junan Chk <junanchakma2000@gmail.com>
Co-authored-by: K. Sz. Bence <tudi20@protonmail.com>
Co-authored-by: Kaleb <kalebcarvalho1@gmail.com>
Co-authored-by: Krishna Chand <krishna_chand67@naver.com>
Co-authored-by: LoneHash <sameepsk2@gmail.com>
Co-authored-by: Luna Jernberg <droidbittin@gmail.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Miguel Alexandro Manzano Guerra <kuro_eis@hotmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nishant Bodkhe <nishantbodkhe44@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pedro <pedro-mediavilla@hotmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Redy Apriyadi <redy.apriyadi@gmail.com>
Co-authored-by: Ric <rikku.debec@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Sieg Jaeger <zekerett@gmail.com>
Co-authored-by: Steven Pedroza <stevenpedroza56@gmail.com>
Co-authored-by: Temporary Person <TemporaryPerson@protonmail.com>
Co-authored-by: Zero O <godarms2010@live.com>
Co-authored-by: ZiomaleQ <r.partyka30@gmail.com>
Co-authored-by: crackheadakira <lasn.mine@gmail.com>
Co-authored-by: dmswd <Bmswad1@gmail.com>
Co-authored-by: julptk <julptk8@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: phannhanhn201 <phannhanhn201@gmail.com>
Co-authored-by: rytis sertvytis <knysliukas2002@gmail.com>
Co-authored-by: soplatnik <jestapom@protonmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Co-authored-by: พรหมชัย ชูแสง <promchai2sin@gmail.com>
(cherry picked from commit 8cfaf8eb51)
2021-10-23 14:24:39 -04:00
arkon 52f4e60d9b Fix crash in single-page chapters
(cherry picked from commit 675c0cefc3)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
2021-10-23 14:24:38 -04:00
arkon 4ddaba06f7 Formatting
(cherry picked from commit 1a52385b78)
2021-10-23 14:24:38 -04:00
Andreas bd8a7c038e Remove extra padding when using list with Per Category setting (#5997)
* Remove padding when using list with Per Category setting (fixes #5636)

* Add view type to RecyclerViewPagerAdapter

Correctly this time (ノ◕ヮ◕)ノ*:・゚✧

* Minor tweaks

(cherry picked from commit 372e500590)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt
2021-10-23 14:24:37 -04:00
Ivan Iskandar 6f429cdb9c App-wide typography adjustments (#5931)
* Manga detail

Also adjust chapter item layout to accommodate bigger
display/font size

* Library

* Updates

* History

* Browse

* Preferences

* Button

* Navigation view

* category-download

* Google Sans

* Reader

* Chips

* Revert "Google Sans"

This reverts commit 5dd4c41f

* Misc

* Cleanups

* Section header text appearance

* Increase library manga title size

* Revert "Increase library manga title size"

This reverts commit 474be913

* Increase section header letter spacing

* Derps

(cherry picked from commit 6d650518a1)
2021-10-23 14:24:37 -04:00
FourTOne5 e1856e67c2 Sort and remove duplicates in genres (#6021)
* Sort and remove duplicates in genres

Co-authored-by: ivaniskandar <12537387+ivaniskandar@users.noreply.github.com>

* Remove Sort and filter out blank genre

Co-authored-by: ivaniskandar <12537387+ivaniskandar@users.noreply.github.com>
(cherry picked from commit 7940117577)
2021-10-23 14:24:36 -04:00
Ivan Iskandar 17fee7fba2 LicensesController: Move item init to IO thread (#6020)
(cherry picked from commit b0f87fdd21)
2021-10-23 14:24:36 -04:00
arkon 32e0a70024 Switch to Material Slider in color filter settings
(cherry picked from commit dc92ffed87)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/widget/NegativeSeekBar.kt
2021-10-23 14:24:35 -04:00
Ivan Iskandar 619c306069 Apply navigation bar insets to fast scroller and settings search list (#6015)
(cherry picked from commit 4af578e310)
2021-10-23 14:24:35 -04:00
FourTOne5 5f92fa0851 Check if wifi is connected rather than enabled while downloading. (#5967)
* Fixxy Wixxy

* Downgrade check from Android S to Android Q

(cherry picked from commit e22825d818)
2021-10-23 14:24:34 -04:00
arkon dbbe118ae9 Update AboutLib plugin
(cherry picked from commit e2da6259e7)
2021-10-23 14:24:34 -04:00
arkon d74e43b6a6 Switch to Material Slider for reader seekbar
Co-authored-by: Jays2Kings <Jays2Kings@users.noreply.github.com>
(cherry picked from commit d149017c60)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
2021-10-23 14:24:33 -04:00
arkon 7574b4baef Update dependencies
(cherry picked from commit afc400121b)
2021-10-23 14:24:33 -04:00
Ivan Iskandar 602b33705b Fix MangaController toolbar title showing when editing category (#6005)
(cherry picked from commit ef993515c6)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
2021-10-23 14:24:32 -04:00
arkon 53592d1f57 Don't bury sort menu in overflow in Migrate screen
(cherry picked from commit edb1d21ddc)
2021-10-23 14:24:32 -04:00
Andreas ce4ab83ae9 Ability to order sources by library count when migrating (#6000)
* order sources by library count when migrating (closes #4703)

* Use plain menu instead of full-on sheet

(cherry picked from commit ba8abd94a8)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrationSourcesController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrationSourcesPresenter.kt
2021-10-23 14:24:31 -04:00
Andreas f57c5d2f17 Move extensions enabled languages on top (closes #5694) (#5998)
(cherry picked from commit c6d4e4c15f)
2021-10-23 14:24:31 -04:00
Ivan Iskandar d9e6e0c956 Fix incorrect appbar lift state when opening MangaController in hidden state (#5990)
(cherry picked from commit 09f0ac866f)
2021-10-23 14:24:30 -04:00
Hunter Nickel e651bfc04f Add chapter bookmarking feature to Updates screen (#5984)
(cherry picked from commit 7ed25704d6)
2021-10-23 14:24:30 -04:00
FourTOne5 851a0c015b Fix variable name in isOnline (#5991)
(cherry picked from commit 2196dac63e)
2021-10-23 14:24:29 -04:00
Ivan Iskandar 4bb6bf445b ReaderActivity: Block focus on viewer (#5996)
(cherry picked from commit c8f70efded)
2021-10-23 14:24:28 -04:00
Jobobby04 e374281d21 Fix 437 2021-10-23 14:24:28 -04:00
Jobobby04 7a44fab5e7 Allow canceling a single migration job but keeping the manga 2021-10-23 14:24:27 -04:00
Jobobby04 29d786d8db Remove useless context switches 2021-10-23 14:24:27 -04:00
nicki 441358f1ae Fix "+" appearing on ConfigurableSources in Browse > Extensions (#434)
* align text towards right end

aligns the text (`Settings/Settings+` etc) to the end of the Text rather
than letting it be centred

* append "+" only for two states

"+" needs to be added only if the following conditions are met:
 - Extension is Installed and is a ConfigurableSource (regardless of it
   having an Update or not)
 - Extension is in InstallStep.Idle state

* linting

* Revert "align text towards right end"

This reverts commit 5e4511d0beaff038e9dc31189095e1b6d853c020.
Since it was rejected and doesn't help much

* better if checking strategy

because installStep.idle holds true for all extensions, even uninstalled
ones, that leads to not having to check Ext.installed anyways for the
combined OR to return `false`
Checking for extension.Installed check first leads to getting `false`
faster
2021-10-23 14:23:39 -04:00
Jobobby04 7097363f26 Fix clear db crashing 2021-09-26 14:21:53 -04:00
arkon f2caa59ec9 Mark installer names as non-translatable
(cherry picked from commit c2255b0a0f)
2021-09-26 14:14:42 -04:00
arkon 3337afcf97 Use data class to parse extensions list
(cherry picked from commit f754b081ce)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt
#	app/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt
2021-09-26 14:12:28 -04:00
arkon 53cfe1c609 Update kotlinx.serialization
(cherry picked from commit 07771cb5e4)
2021-09-26 13:29:29 -04:00
arkon c06ccf2480 Show message in migrate screen if library is empty
(cherry picked from commit 690d8e43ae)
2021-09-26 13:29:14 -04:00
Hunter Nickel e38322c4dc Hide soft keyboard after submitting search query throughout app (#5837)
* Clear focus from SearchView when submitting a search query in BrowseSourceController

* Revert "Clear focus from SearchView when submitting a search query"

* Implement SearchView focus clearing in Tachiyomi's subclass to enable feature throughout app

* Add support for keyboard Enter key

Pressing enter on a keyboard (when using the emulator for example) now also submits the query

(cherry picked from commit 82f14a7d59)
2021-09-26 13:29:08 -04:00
Ivan Iskandar fa14a1cb6d Implement new extension install methods (#5904)
* Implement new extension install methods

* Fixes

* Resolve feedback

* Keep pending status when waiting to install

* Cancellable installation

* Remove auto error now that we have cancellable job

(cherry picked from commit b284384f0a)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
2021-09-26 13:28:48 -04:00
Jobobby04 4c63c01501 Cleanup and reduce the amount of time it waits for logouts 2021-09-24 13:06:10 -04:00
Jobobby04 74ba072e01 Build fixes 2021-09-24 13:05:06 -04:00
Andreas fef5578a17 Reattach after slight delay instead on every db update (#5956)
(cherry picked from commit 1ae0d1b5d0)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
2021-09-24 12:55:01 -04:00
arkon b2ee3bf176 Update dependencies
(cherry picked from commit 9de08c8166)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
2021-09-24 12:54:31 -04:00
Ivan Iskandar e47e6de9f4 Toolbar and bottom nav scroll snap (#5915)
(cherry picked from commit a2d007f2a9)
2021-09-24 12:53:09 -04:00
arkon 6c7a3fb809 Fix setting search re-animating on activity recreation (fixes #5882)
(cherry picked from commit 774f818bbb)
2021-09-24 12:53:02 -04:00
arkon dce264fcae Adjust snackbar durations (closes #5932)
(cherry picked from commit 0ec7121b8f)
2021-09-24 12:52:55 -04:00
arkon b9fea9c045 Minor cleanup
(cherry picked from commit d7d46f4447)
2021-09-24 12:52:47 -04:00
Andreas 3d5e5da022 Remove spaces at end of line before removing multiple new lines (#5928)
(cherry picked from commit 45fad147bf)
2021-09-24 12:52:39 -04:00
Aria Moradi 970967104e rewrite getFormat the kotlin way (#5930)
(cherry picked from commit 3664195c71)
2021-09-24 12:52:30 -04:00
arkon c2543e6238 Remove setting to disable update error notifications and split out notification channel
Users can exclude things from updating if needed, or disable the notification channel from system settings.

(cherry picked from commit fce3cd00a1)
2021-09-24 12:52:23 -04:00
arkon f3d867f9aa Move extension app info button
Aligns with TachiyomiJ2K.

(cherry picked from commit 33b3be0d0e)
2021-09-24 12:52:16 -04:00
Ivan Iskandar 6af5f085cf Fix toolbar title alpha (#5910)
(cherry picked from commit cfd1b4a6c6)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
2021-09-24 12:52:05 -04:00
Gauthier 4ac2873a57 handle maxNumberSort from API (#5917)
(cherry picked from commit d45fefd6f0)
2021-09-24 12:50:06 -04:00
Ivan Iskandar 240b485a65 Change how the bottom navigation is hidden (#5823)
* Change how the bottom navigation is hidden

Modifies the translationY instead of the height.

* Cleanups

(cherry picked from commit f125ab01ee)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
2021-09-24 12:49:59 -04:00
paulo27ms 31dfac3ece [skip ci] Update issue closer to ignore myanimelist (#5911)
Not sure if there's any limitation for the regex but this will ignore myanimelist strings, in practice.

(cherry picked from commit be001d090c)
2021-09-24 12:47:45 -04:00
Soitora 57b9376b83 Allow preferences to multi-line (#5905)
(cherry picked from commit 971d8a7e40)
2021-09-24 12:47:36 -04:00
arkon 6618f848ea Unify NSFW flagging for sources/extensions
Since multisource extensions are no longer a thing, we now simply rely on the flag at the extension level, i.e. the per-Source/SourceFactory `@Nsfw` annotation is no longer checked.
We'll have to remove all of the annotation usages from the existing sources, which will also effectively break the setting for older versions of the app.

(cherry picked from commit a2cf210a52)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionPresenter.kt
2021-09-24 12:47:29 -04:00
Jozef Hollý 7d82320c82 Weblate translations (#5852)
Co-authored-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
Co-authored-by: Ahmed gamal <12355.ahmedgamal.com@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Forqen <krecio555@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jetspectre <jetspectre1@gmail.com>
Co-authored-by: Jozef Hollý <j2.00ghz@gmail.com>
Co-authored-by: Long Nguyễn Khánh <khanhlong17112000@gmail.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Maciej Sładkiewicz <krecio555@gmail.com>
Co-authored-by: Madddog1997 <madddog1997@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Nguyễn Thanh Bình <sikea0801@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Rocco Casadei <roccobot@gmail.com>
Co-authored-by: Scoop <Scoo0p@yandex.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Tymofii Lytvynenko <till.svit@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ar/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ca/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/cs/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fil/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sk/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/uk/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/vi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/
Translation: Tachiyomi/Tachiyomi 0.x

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
Co-authored-by: Ahmed gamal <12355.ahmedgamal.com@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Forqen <krecio555@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jetspectre <jetspectre1@gmail.com>
Co-authored-by: Long Nguyễn Khánh <khanhlong17112000@gmail.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Madddog1997 <madddog1997@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Nguyễn Thanh Bình <sikea0801@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Rocco Casadei <roccobot@gmail.com>
Co-authored-by: Scoop <Scoo0p@yandex.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Tymofii Lytvynenko <till.svit@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
(cherry picked from commit b5d83bdb56)
2021-09-24 12:45:55 -04:00
FourTOne5 e7803d305f Don't count "other" as a language. (#5901)
(cherry picked from commit 2c495c4119)
2021-09-24 12:45:33 -04:00
Jobobby04 23928d3c89 Fix Merged Manga not refreshing 2021-09-17 16:16:59 -04:00
Jobobby04 7ffe1794d9 Fix more info crash 2021-09-17 15:40:39 -04:00
Jobobby04 3b0523268a Fix build errors 2021-09-12 14:49:52 -04:00
arkon 5c3326e47d Fix scroller getting dragged incorrectly in RTL (fixes #5496)
(cherry picked from commit 7c72d6cb7c)
2021-09-12 14:44:27 -04:00
arkon f269483072 Don't show option to delete chapters for local manga (closes #5243)
(cherry picked from commit 8362bf0886)
2021-09-12 14:44:19 -04:00
arkon 8717c30498 Add link to help translate in about
(cherry picked from commit 1a8155c45b)

# Conflicts:
#	app/src/main/res/values/strings.xml
2021-09-12 14:44:10 -04:00
FourTOne5 a4dd13f491 Update ExtensionPresenter.kt (#5895)
(cherry picked from commit 3f2f946019)
2021-09-12 14:43:13 -04:00
arkon 823bd024b7 Minor cleanup for download delete exclusion
(cherry picked from commit 2c14a8dee1)
2021-09-12 14:43:05 -04:00
arkon eac2301e76 Fix manga info expand button background
(cherry picked from commit 917a283bd1)
2021-09-12 14:42:57 -04:00
arkon 01401b6312 Opt out of WebView metrics and disable Google Safe Browsing
cf. https://developer.android.com/guide/webapps/managing-webview

(cherry picked from commit 3e403d5ab3)

# Conflicts:
#	app/src/main/AndroidManifest.xml
2021-09-12 14:42:47 -04:00
Ivan Iskandar 4a93a93839 Reuse reader's image view in MangaFullCoverDialog (#5824)
* MangaFullCoverDialog: Support animated drawable

* Scaled zoom duration

* Wrap reader's image view to be reused in MangaFullCoverDialog

* Cleanups

* Forgot animated stuff for webtoon view

* Cleanups

* Oopsie

* Cleanups

* Consistent max scale for SubsamplingScaleImageView

The max scale will be obtained from the default scale times 3 for
consistent 3x zoom scale.

(cherry picked from commit 746d35b52b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerConfig.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt
2021-09-12 14:42:13 -04:00
Jace f77ac8cb36 Change ProtoNumber of Backup Models for History and Source to a non-zero digit (#5849)
* Change ProtoNumber of Backup Models for History and Source to non-zero

Changed BackupHistory url and BackupSource name properties

* Provide backwards compatibility to current proto backups

- Added data class for zero-based protoNumber
- Restore both 'new' proto and old ones by mapping old to 'new' proto format
- Thanks to @jobobby04  for providing the initial solution.

* Fix on createBackup missing parameter for brokenSource

* Fix issues on build

* Fix missing import on FullBackupRestore

(cherry picked from commit 9a7a03e327)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/models/Backup.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/models/BackupManga.kt
2021-09-12 13:34:54 -04:00
tobinstultiens d9d94ed321 Allow exclusion on Delete After Read per category (#5857)
* Added the exclude category from delete after being read

* Stopped it from adding a wildcard to the import

* Placed the remove after read to the download manager

(cherry picked from commit a051079c6a)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt
2021-09-12 13:33:36 -04:00
Ivan Iskandar 035a1518ad Less hacky way to make sure bottom action toolbar doesn't scroll down (#5871)
* Less hacky way to make sure bottom action toolbar doesn't scroll down

* Fix action toolbar overlapping on landscape

* Disable app bar transparency when ActionMode is present

(cherry picked from commit 7b3c18bb97)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
2021-09-12 13:10:33 -04:00
Ivan Iskandar 889a61704f MangaController: Fix listeners cancelled when pushing new controller within (#5883)
(cherry picked from commit f41bde5ee1)
2021-09-12 13:10:04 -04:00
Gauthier b7c0c7a094 use chapter_number instead of ordinal index for syncChaptersWithTrackServiceTwoWay (#5846)
use v2 api for Komga tracker for series

(cherry picked from commit 6151318ac1)
2021-09-12 13:09:56 -04:00
Ivan Iskandar 3d71e643e1 MangaController: Title fixes (#5879)
* MangaController: Move toolbar's TextView reference to ElevationAppBarLayout

* MangaController: Update title alpha earlier when exiting

(cherry picked from commit b45c322729)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
2021-09-12 13:09:49 -04:00
Ivan Iskandar 0492d501f3 Disable action mode status bar guard (#5872)
(cherry picked from commit b00e8768dc)

# Conflicts:
#	app/src/main/res/values/colors.xml
2021-09-12 13:09:07 -04:00
Jobobby04 e38255e895 Migrate to the new mangadex list response 2021-09-12 13:07:18 -04:00
Jobobby04 fcf6776fe4 Fix expander color 2021-09-12 12:09:11 -04:00
Jobobby04 98f285f777 Cleanup 2021-09-11 11:48:32 -04:00
Jobobby04 982f4d6a97 Debug function to clear watched sources 2021-09-11 11:48:17 -04:00
Jobobby04 972716d884 Only use site specific handlers if data is empty 2021-09-11 11:43:16 -04:00
Jobobby04 6f93fdd089 Cover includes on user follows 2021-09-11 11:42:51 -04:00
Jobobby04 f0329cfafa Improve mangadex title selection 2021-09-11 11:42:19 -04:00
Jobobby04 95e14a9ef9 Cleanup 2021-09-06 16:41:09 -04:00
FourTOne5 c66b57a3b4 Use "isOnline" utils in DownloadService (#5863)
* Use isOnline

* when -> if/else

(cherry picked from commit 156feb6e8e)
2021-09-06 16:40:36 -04:00
arkon 71533fb2bc Read from streams for local source manga details and legacy backups
(cherry picked from commit e942b8a402)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt
2021-09-06 16:40:36 -04:00
Andreas cf742c65aa Remove the remaining MotionLayout (#5854)
* Remove the remaining MotionLayout

* Use ImageButton instead of Blank View to handle taps in dead area

And some tweaks

(cherry picked from commit abdb67a123)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
#	app/src/main/res/layout-sw720dp/manga_info_header.xml
#	app/src/main/res/layout/manga_info_header.xml
#	app/src/main/res/xml/manga_summary_section_scene.xml
2021-09-06 16:40:35 -04:00
arkon 2f5718c92f Retain GLUtil.maxTextureSize
(cherry picked from commit ee20787c5e)
2021-09-06 16:39:05 -04:00
arkon 97ddafe539 Clean up some companion object usages
(cherry picked from commit ec4e631760)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SourceSearchController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt
2021-09-06 16:39:04 -04:00
Aran Leite 0f0937adf5 Skip bookmark check when cancelling downloads (#5853)
* Skip bookmark check when cancelling downloads

* DownloadManager: simplified filteredChapters declaration

* Completed documentation of DownloadManager's deleteChapters()

(cherry picked from commit 02b430a5bf)
2021-09-06 16:39:03 -04:00
arkon 6eac0f6f98 Fix crash in settings search (fixes #5855)
(cherry picked from commit 7878053df2)
2021-09-06 16:39:03 -04:00
arkon 336727e01a Adjust padding of themes preference
(cherry picked from commit 6b1f130750)
2021-09-06 16:39:02 -04:00
arkon 6f36675113 Avoid multiline library badges
Related to #5725

(cherry picked from commit bde4c0a648)
2021-09-06 16:39:02 -04:00
arkon 66d4966463 Queue tracking updates when offline (closes #1497)
Co-authored-by: Jays2Kings <Jays2Kings@users.noreply.github.com>
(cherry picked from commit 5ae4621da1)
2021-09-06 16:39:01 -04:00
arkon e734f7d13d Fix chapters getting deleted when marking as unread from library (fixes #5755)
(cherry picked from commit 5ea8d0546e)
2021-09-06 16:39:00 -04:00
arkon f29717272d Minor cleanup
(cherry picked from commit 8a064c118f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
2021-09-06 16:39:00 -04:00
arkon 50a9a907de Don't allow focus on reader containers (closes #5727)
(cherry picked from commit 2f91c27df2)
2021-09-06 16:38:59 -04:00
Soitora 3cb05b1442 Hide language tag when only one language is used (#5834)
* Hide lang tag when only one lang used

* Comment the code

Can't be too useless and do nothing, Ghostbear practically wrote the entire PR for me

* Exclude 'all' from counting as a language

Co-Authored-By: Andreas <6576096+ghostbear@users.noreply.github.com>

* Use existing Preferences directly from Presenter

* Replace regex with an existing value

Co-authored-by: Andreas <6576096+ghostbear@users.noreply.github.com>
(cherry picked from commit 763bd54707)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
2021-09-06 16:38:58 -04:00
Jozef Hollý b304082ca6 Weblate translations (#5670)
Co-authored-by: Ahmed gamal <12355.ahmedgamal.com@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Gianna E <giannela.e@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: IRFAN SHADIK <irfanshadikofficial@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jendrej <ejjendrej@gmail.com>
Co-authored-by: Jetspectre <jetspectre1@gmail.com>
Co-authored-by: KIRA <belguareh1@gmail.com>
Co-authored-by: Karlo Orioli <korioli1@gmail.com>
Co-authored-by: Luna Jernberg <droidbittin@gmail.com>
Co-authored-by: Lyaiya <hipsnafoha@outlook.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Marian Leontiev <leontievmarian@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Nikita Epifanov <nikgreens@protonmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Ric <rikku.debec@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
Co-authored-by: Sebastian Skoczek <sebastians17@onet.pl>
Co-authored-by: Sebs11_B <chevabermudezcastillo@gmail.com>
Co-authored-by: Shippo <shiposhouyou@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Tmp341 <tmp341@gmail.com>
Co-authored-by: Tymofii Lytvynenko <till.svit@gmail.com>
Co-authored-by: Wise <phxwise@gmail.com>
Co-authored-by: Zakhar Timoshenko <vp1984tanki@gmail.com>
Co-authored-by: Zero O <godarms2010@live.com>
Co-authored-by: anenasa <anenasaa@yahoo.com>
Co-authored-by: dmswd <Bmswad1@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Co-authored-by: 신민준 <sinmin70@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ar/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/be/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/bn/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/cs/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es_419/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fil/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ja/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ko/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/uk/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/
Translation: Tachiyomi/Tachiyomi 0.x

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Ahmed gamal <12355.ahmedgamal.com@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Gianna E <giannela.e@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: IRFAN SHADIK <irfanshadikofficial@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jendrej <ejjendrej@gmail.com>
Co-authored-by: Jetspectre <jetspectre1@gmail.com>
Co-authored-by: KIRA <belguareh1@gmail.com>
Co-authored-by: Karlo Orioli <korioli1@gmail.com>
Co-authored-by: Luna Jernberg <droidbittin@gmail.com>
Co-authored-by: Lyaiya <hipsnafoha@outlook.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Marian Leontiev <leontievmarian@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Nikita Epifanov <nikgreens@protonmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Ric <rikku.debec@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
Co-authored-by: Sebastian Skoczek <sebastians17@onet.pl>
Co-authored-by: Sebs11_B <chevabermudezcastillo@gmail.com>
Co-authored-by: Shippo <shiposhouyou@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Tmp341 <tmp341@gmail.com>
Co-authored-by: Tymofii Lytvynenko <till.svit@gmail.com>
Co-authored-by: Wise <phxwise@gmail.com>
Co-authored-by: Zakhar Timoshenko <vp1984tanki@gmail.com>
Co-authored-by: Zero O <godarms2010@live.com>
Co-authored-by: anenasa <anenasaa@yahoo.com>
Co-authored-by: dmswd <Bmswad1@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Co-authored-by: 신민준 <sinmin70@gmail.com>
(cherry picked from commit 0ea3cc7ce4)
2021-09-06 16:38:58 -04:00
arkon f51f9eb371 Retain scroll position when selecting app theme preference
Co-authored-by: Jays2Kings <Jays2Kings@users.noreply.github.com>
(cherry picked from commit 0de3558ab3)
2021-09-06 16:38:57 -04:00
arkon eda451a2e4 Rearrange themes, rename "Blue" to "Legacy Blue"
(cherry picked from commit 069f4e12d8)
2021-09-06 16:38:56 -04:00
arkon 4e9ab0cfdc Reword advanced tablet UI setting
(cherry picked from commit ae4dfc9956)
2021-09-06 16:38:56 -04:00
Quang Kieu 98da48ad73 Edit mangas' Categories in Library using TriState list (#5422)
* Use QuadState Categories to edit mangas in Library

Add updateMangasToCategories to build build correct Categories list for
  each manga using Common and Mix list
Update QuadState Multi-Choice to either Action or Display List
  Display list would have different state sequece from Action
  Uncheck-> Indeterminate (only if initial so)-> Check

fixup manga categories logic as Windows and push request comments

* fixup: Use QuadStateTextView.State enum

Update function to use  QuadStateTextView.State enum that missed in last change

* fixup: missing closing bracket and type cast

Co-authored-by: quangkieu <quangkieu1993@gmail.com>
(cherry picked from commit ee711dc0fb)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
2021-09-06 16:38:55 -04:00
arkon ca1699aabb Migrate to flow version of ReactiveNetwork
(cherry picked from commit c316e7faab)
2021-09-06 16:38:55 -04:00
arkon c45019e19c Don't show update progress notifications if job isn't active anymore (closes #5844)
(cherry picked from commit 7083b3d912)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2021-09-06 16:38:54 -04:00
arkon 74c394193a Update dependencies
(cherry picked from commit 2d3a1b6a9e)
2021-09-06 16:38:53 -04:00
Ivan Iskandar 0feb9d338f Tablet UI override (#5830)
* Tablet UI override

* Tablet UI advanced pref

(cherry picked from commit 0df23ab878)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
2021-09-06 16:38:53 -04:00
Soitora 88f9fb2b88 Remove autoSizeText (#5850)
Apparently it produces unexpected results in combination with 'wrap_content'.

(cherry picked from commit 7ed8de2ef4)
2021-09-06 16:38:52 -04:00
Jobobby04 9dc5aedba4 Hide the option to change cover on expand 2021-09-06 16:38:52 -04:00
Jobobby04 cc38579fca Cleanup 2021-09-06 16:38:51 -04:00
Jobobby04 52cdb636c9 MangaDex, add support for Bilibili chapters 2021-09-06 16:38:50 -04:00
Soitora 7e162c99ce Add SY-specific status icons (#412)
For MangaDex
2021-09-03 16:47:10 -04:00
Soitora d294bc0b2a Add status icons to manga info (#5832)
* Add icons to manga status

* Slightly better formatting

Mixed in with a dose of syntactic sugar

* Remove unnecessary lines

I think they are, at least

* Change according to review comments

- Fix forgotten Tablet code removal
- Change 'android:background' to 'app:srcCompat'

* Adjust size of icon

Smaller and more fitting to the environment

(cherry picked from commit d935e22f0d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
2021-09-03 15:28:00 -04:00
Jobobby04 e34c61c750 Manga Info Header onDestroyView 2021-09-03 15:25:24 -04:00
Jobobby04 7175fc3444 Fix source settings toolbar item color 2021-09-01 19:54:10 -04:00
Jobobby04 d9c9ed45bb Orginization 2021-09-01 18:41:16 -04:00
Jobobby04 19a00ce582 Temp fix for clear db, dont click it 2021-09-01 18:41:15 -04:00
Jobobby04 42d8b97f9b Improve loading display of namespace tags 2021-09-01 18:41:14 -04:00
Jobobby04 af4979fcba Fix name mismatch warning 2021-09-01 18:41:14 -04:00
Jobobby04 7d1dd087fb Fix gradle deprecation warnings 2021-09-01 18:41:14 -04:00
Jobobby04 b571ccccaa Fix tag margins 2021-09-01 18:41:13 -04:00
Jobobby04 ce39d6ec25 Fix metadata view 2021-09-01 18:41:13 -04:00
Jobobby04 94595a99ac Support Comikey chapters 2021-09-01 18:41:12 -04:00
Jobobby04 adc6398589 Fix compiling 2021-09-01 18:41:12 -04:00
arkon aa144603e2 Use ShapeableImageView for rounded thumbnails instead of Coil transformations
(cherry picked from commit 0e26abf7a6)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListHolder.kt
2021-09-01 18:41:11 -04:00
Soitora 7e0082b6f9 Improve placement of manga title section (#5796)
Also makes content expand logically through the help of constraint barriers.

(cherry picked from commit 59aef13200)
2021-09-01 18:41:10 -04:00
arkon 5cf65fe676 Update Material Components
(cherry picked from commit 9d1f6c4416)
2021-09-01 18:41:10 -04:00
arkon 4624754895 Added a getting started guide action for when the library is empty
Co-authored-by: Jays2Kings <Jays2Kings@users.noreply.github.com>
(cherry picked from commit b9f7660a91)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
2021-09-01 18:41:10 -04:00
Ivan Iskandar 7da6af5138 Fix MangaController's loading view initial position (#5827)
Make sure the loading view is hidden before updating the offset.

(cherry picked from commit 18b5250ed1)
2021-09-01 18:41:09 -04:00
nicki 15cd238223 Trim line breaks in manga info only when collapsed (#5818)
* don't trim newlines if summary expanded

* move description trim logic to separate function

* logic error oops

* let's try something

* fix bug on first load

makes it so that, description text is trimmed when entering manga from
library

Co-authored-by: Andreas <andreas.everos@gmail.com>

Co-authored-by: Andreas <andreas.everos@gmail.com>
(cherry picked from commit f683f21ee2)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
2021-09-01 18:41:09 -04:00
Ivan Iskandar 44b6983b3d Fix animated image detection (#5826)
(cherry picked from commit bd033db84c)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
2021-09-01 18:41:08 -04:00
Andreas 09a6e3661f Handle small cover better (#5815)
(cherry picked from commit ab036312a4)
2021-09-01 18:41:07 -04:00
Jays2Kings efd085cbcf Update kitsu to not show "null" for empty descriptions
(cherry picked from commit e6ea530532523ed033fd232fcea2da8f17b973f7)
(cherry picked from commit 634da15191)
2021-09-01 18:41:07 -04:00
arkon 79c3c7f356 Make appearance settings searchable (fixes #5814)
(cherry picked from commit cea1720ea0)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/search/SettingsSearchHelper.kt
2021-09-01 18:41:06 -04:00
arkon d060e4c425 Fix divider color in AMOLED mode (fixes #5778)
(cherry picked from commit 3f2f542265)
2021-09-01 18:41:06 -04:00
arkon 28a3dfeeea Fix crash when tapping title of "App theme" preference
(cherry picked from commit b77edb2b5b)
2021-09-01 18:41:05 -04:00
arkon 28ffb9288f Fix reader action sheet not opening
(cherry picked from commit 1b699bb814)
2021-09-01 18:41:05 -04:00
arkon b530216f21 Clean up reader action sheet layout
(cherry picked from commit 333c035fed)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPageSheet.kt
#	app/src/main/res/layout/reader_page_sheet.xml
2021-09-01 18:41:04 -04:00
arkon 091049cda9 Update save icon
(cherry picked from commit 70e5361146)
2021-09-01 18:41:04 -04:00
Andreas 74437e6809 Replace MotionLayout with full screen dialog (#5806)
* Remove MotionLayout and add full screen dialog for enlarged cover

* Address some of the review comments

(cherry picked from commit e7d6dfff53)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
#	app/src/main/res/xml/manga_info_header_scene.xml
#	app/src/main/res/xml/manga_info_header_scene_sw720dp.xml
2021-09-01 18:41:03 -04:00
arkon b916907491 Register TachiyomiImageDecoder after built-in Coil decoders
Not sure if this is related to #5702.

(cherry picked from commit eebfad5a95)
2021-09-01 18:41:03 -04:00
arkon b045ee1ba6 Tweak theme preference item UI
(cherry picked from commit 77c0a93ac6)
2021-09-01 18:41:02 -04:00
arkon 5d46569137 Rename Layout category to Navigation
(cherry picked from commit 63a3e126b3)
2021-09-01 18:41:01 -04:00
Ivan Iskandar 8875c3f9bb Add IME_FLAG_NO_PERSONALIZED_LEARNING flag to text input when incognito is enabled (#5801)
* Add IME_FLAG_NO_PERSONALIZED_LEARNING flag to text input when incognito is enabled

Tested with Gboard only.

* Revert "Add IME_FLAG_NO_PERSONALIZED_LEARNING flag to text input when incognito is enabled"

This reverts commit 068399db

* Add IME_FLAG_NO_PERSONALIZED_LEARNING flag to text inputs when incognito is enabled

Source preference is not affected.

* Source preference stuff

(cherry picked from commit 3ea84cf0ce)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/details/SourcePreferencesController.kt
2021-09-01 18:41:01 -04:00
arkon 676d8c85a0 Only update chapter/viewer flags for library manga instead of everything (addresses #5809)
(cherry picked from commit 7fa80ae556)
2021-09-01 18:41:00 -04:00
arkon 8d757ff37a Clean up track button changes
(cherry picked from commit 925f71af15)
2021-09-01 18:41:00 -04:00
OncePunchedMan 6deab45e80 Tracking: replace tick with button (#5768)
* make check only visible after selecting an item

* replace tick with button and send to bottom

* fixed button visibility

* grey btn out

* resolving some bits

* removing the tick from appbar

* remove useless lines, appl insetter

(cherry picked from commit c666dd623d)
2021-09-01 18:40:59 -04:00
Gauthier 54bd0c155f change Track.last_chapter_read to Float (#5802)
each TrackService can convert it to Int if decimal chapters are not supported

(cherry picked from commit 2cd8733212)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt
2021-09-01 18:40:59 -04:00
arkon 6b1e7a8b55 Clean up imports
(cherry picked from commit 4b2a9bc621)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt
2021-09-01 18:40:58 -04:00
Taco dafff19fff Use more Compat utilities (#5786)
* Use ActivityCompat.recreate

* Use more KTX extensions

* Use PackageInfoCompat.getLongVersionCode

* Remove unnecessary compat usages

(cherry picked from commit 12a9d0575d)
2021-09-01 18:40:58 -04:00
arkon f2a8ee3c20 Tweak theme preference item UI (closes #5805)
(cherry picked from commit edcfa28b0b)
2021-09-01 18:40:57 -04:00
Jobobby04 3ba3f4bbb2 Update depenancies 2021-09-01 18:40:57 -04:00
Jobobby04 baeec9e2e7 Update to support the latest Mangadex API 2021-09-01 18:40:56 -04:00
arkon 402e494cf7 Group advanced battery optimization setting entries
(cherry picked from commit b5e118e2b4)
2021-09-01 18:40:56 -04:00
arkon fe4344c518 Keep coroutine methods (fixes #5662)
(cherry picked from commit dfec0e45ed)
2021-09-01 18:40:55 -04:00
Ivan Iskandar 499b07f988 Remove reader page number inset margin (#5661)
(cherry picked from commit 5aea21a194)
2021-09-01 18:40:55 -04:00
arkon 6b70bdd732 Replace Wi-Fi connection check with WifiManager
Previous implementation couldn't detect Wi-Fi connection while using a VPN.

(cherry picked from commit 3155829994)
2021-09-01 18:40:54 -04:00
Soitora 3ab7c18e32 Fix shadow behind the Expand Info icon (#5804)
(cherry picked from commit d25707554e)
2021-09-01 18:40:54 -04:00
e-shl 11d6098d2b [Translation]RU (#406) 2021-09-01 17:35:21 -04:00
nicki 7e8e1fab11 Create Navbar category in Appearance settings (#404)
* add new category for navbar appearance

* update strings for new appearance settings

also adds `pref_category_navbar` for new Navbar settings sub section

* Update SettingsAppearanceController.kt

Co-authored-by: jobobby04 <jobobby04@users.noreply.github.com>
2021-08-27 21:26:22 -04:00
Jobobby04 325ac2b43e Cleanup 2021-08-27 13:13:28 -04:00
Jobobby04 9ddadae078 Use "No Group" properly in mangadex 2021-08-27 12:51:06 -04:00
Jobobby04 c29dc695ae Ktlint ignore some stuff 2021-08-27 12:51:06 -04:00
Jobobby04 6f85f0a6d5 Fix tablet layout crash 2021-08-27 12:51:05 -04:00
Jobobby04 ff965efcae Tweak chip stroke weight for E-Hentai manga 2021-08-27 12:51:05 -04:00
Jobobby04 c7a43cb36e Fix wildcard import 2021-08-27 12:51:05 -04:00
Jobobby04 4554813588 Build fixes 2021-08-27 12:51:04 -04:00
Hunter Nickel cfa6c180e7 Apply system animation scale to parts of Tachiyomi that don't respect it by default (#5794)
* Add initial code for scaling animations, apply scale to reader nav overlay

* Rename extension function, apply system animator scale to ActionToolbar

* Apply system animator scale to expanding manga cover animation

* Apply system animator scale to image crossfade (also disables animated covers when browsing)

* Add documentation, make MotionScene Transition comment a bit more clear

* Disable animated covers in MangaInfoHeaderAdapter if animator duration scale is 0

* Disable animated covers in Library if animator duration scale is 0

* Convert loadAny listener to extension function

(cherry picked from commit df683375b1)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryComfortableGridHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCompactGridHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
2021-08-27 12:51:04 -04:00
arkon e36957f00b Update Kotlin and Kotlinter
(cherry picked from commit cc3cbbc4bb)
2021-08-27 12:51:03 -04:00
Taco 18deebf728 Replace NetworkInfo with NetworkCapabilities (#5785)
(cherry picked from commit 6922394b8e)
2021-08-27 12:51:03 -04:00
Taco f7e219e9ac Use NotificationChannelCompat utilities (#5781)
(cherry picked from commit 24fd82d773)
2021-08-27 12:51:02 -04:00
Soitora 5b18769f70 New manga info expander (#5771)
* Replace "More" with Arrows

We used to have arrows but it was set away from the description which took a lot of space.

It was changed to "More" text, but with the recent design changes I think it'd look better to get a mix between them both.

* Properly align icons

Co-Authored-By: Andreas <6576096+ghostbear@users.noreply.github.com>

* Expand support to Tablets

Get it... expand... hehe 😎

* Fix expanded width

Also fixes so that the constraint for the toggleLess is dependant on the right thing

* Give info toggles its own space

Uses its own margin now to push info rather than just being attached as a info margin.

* Remove weird duplicates I did not add

I did not add these but I don't see a reason to keep dupes

* Add bottom scrim

* Change to centered arrow under info

Anyone wanna experiment/build on top off then feel free to tweak

* Add background glow to icon for contrast

Co-Authored-By: Andreas <6576096+ghostbear@users.noreply.github.com>

Co-authored-by: Andreas <6576096+ghostbear@users.noreply.github.com>
Co-authored-by: Andreas <andreas.everos@gmail.com>
(cherry picked from commit 57aefcd917)

# Conflicts:
#	app/src/main/res/drawable/manga_info_more_gradient.xml
#	app/src/main/res/layout/manga_info_header.xml
#	app/src/main/res/xml/manga_summary_section_scene.xml
2021-08-27 12:51:02 -04:00
Ivan Iskandar 2bc64c2096 Fix reader crash on Android 9 (#5789)
* Fix failed reader context creation on v28

* Re-apply the reader styles manually after overriding night mode

This commit replaces the ThemeCompat.rebase() call since the private API used is
in dark greylist max target P, thus making it unreachable.

* Revert "Fix failed reader context creation on v28"

This reverts commit 6e2104d7

(cherry picked from commit b3854ad382)
2021-08-27 12:51:01 -04:00
arkon 9a4e6bef7f Fix toolbar text color in light blue theme
(cherry picked from commit 5f5fc77877)
2021-08-27 12:51:01 -04:00
arkon e8c67999bc Split out appearance settings from general section
(cherry picked from commit 0493e77cff)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt
2021-08-27 12:51:00 -04:00
arkon ae392192f2 Update app theme preference UI
Heavily influenced by TachiyomiJ2K.

(cherry picked from commit 6240fe1dfc)
2021-08-27 12:51:00 -04:00
arkon a9a8e44ef6 Make nav overlay non-clickable (maybe fixes #5727)
(cherry picked from commit beb7f90908)
2021-08-27 12:50:59 -04:00
arkon 1559250f90 Update deprecated Android Gradle DSL calls
(cherry picked from commit a3917972b4)

# Conflicts:
#	app/build.gradle.kts
2021-08-27 12:50:59 -04:00
arkon 3fdd433d89 Update tracker services logo layout (closes #5625)
(cherry picked from commit 7094fef37f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsTrackingController.kt
#	app/src/main/java/eu/kanade/tachiyomi/widget/preference/LoginPreference.kt
#	app/src/main/res/layout/pref_widget_imageview.xml
2021-08-27 12:50:58 -04:00
arkon b6143467b6 [skip ci] Move acknowledgements to bottom of issue templates
(cherry picked from commit 0f41e56a24)

# Conflicts:
#	.github/ISSUE_TEMPLATE/report_issue.yml
#	.github/ISSUE_TEMPLATE/request_feature.yml
2021-08-27 12:50:58 -04:00
arkon 3cf1ae0aa4 Use custom tabs instead of browser (closes #5754)
(cherry picked from commit 6c527d52fb)
2021-08-27 12:50:57 -04:00
arkon 49916667a7 Fix blue background under action mode text selection handlers in blue theme
(cherry picked from commit 909aed4262)
2021-08-27 12:50:57 -04:00
arkon b40d25f929 Update dependencies
(cherry picked from commit 9a45983f17)

# Conflicts:
#	app/build.gradle.kts
2021-08-27 12:50:57 -04:00
Soitora 6d0f620629 Bold author and artist fields (#5770)
(cherry picked from commit 11926014da)
2021-08-27 12:50:56 -04:00
Andreas 6d8ab85ef5 Tweak MangaInfoHeader (#5766)
Make margin between transparent toolbar and cover more match 1.x
Fixes from when view was redone with MotionLayout

(cherry picked from commit 72002c13d6)

# Conflicts:
#	app/src/main/res/xml/manga_info_header_scene.xml
2021-08-27 12:50:56 -04:00
arkon 51c864fb86 Move PR template
(cherry picked from commit 6ed767ae84)
2021-08-27 12:50:55 -04:00
Soitora 9a5787af29 Add a much more clean design to Chips (#5765)
Based on the default chips and what is seen on J2K/Neko

(cherry picked from commit 3826b307f7)
2021-08-27 12:50:55 -04:00
Ivan Iskandar 6ac95ffcd6 Add haptic feedback to reader page slider (#5763)
(cherry picked from commit 887b157056)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
2021-08-27 12:50:54 -04:00
Soitora 41a16b6e83 Add a Pull Request template (#5764)
(cherry picked from commit d36dd39743)
2021-08-27 12:50:54 -04:00
arkon 1b2e0d1b11 Adjust blue theme
(cherry picked from commit dd008bc13a)
2021-08-27 12:50:53 -04:00
nicki 517cb437be update Anilist tracking title during refresh (#5760)
Co-authored-by: Andreas <andreas.everos@gmail.com>

Co-authored-by: Andreas <andreas.everos@gmail.com>
(cherry picked from commit 50b282f58b)
2021-08-27 12:50:53 -04:00
arkon cc384d1f25 Minor cleanup
(cherry picked from commit 7d2caeb270)

# Conflicts:
#	.github/ISSUE_TEMPLATE/report_issue.yml
2021-08-27 12:50:52 -04:00
arkon 1566ed4fda Update jsoup
(cherry picked from commit f8a7efbce7)
2021-08-27 12:50:52 -04:00
arkon 015327829d Minor cleanup
(cherry picked from commit b8ea57e097)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/SourceHolder.kt
2021-08-27 12:50:51 -04:00
nicki b293b52cf6 Use user preferred title language in Anilist (#5758)
* Use user preferred title language in Anilist

Since Anilist is only used by authenticated users, the title language
can be set using the `userPreferred` field (defaults to romaji)

Changed wherever `title>romaji` was being used. Shouldn't have missed
any. `userPreferred` is also available for Staff and Character but not
relevant to Tachiyomi for now.

Users might need to go Logout and log back in on Anilist to see the
change. Actual setting can be found at https://anilist.co/settings/media

closes https://github.com/tachiyomiorg/tachiyomi/issues/5757

* correct title in anilist model

indicates the fact that userPreferred title is used

* convert forgotten `type` to `format` as well

leads to NPE when using `findLibManga`.
missed one query in https://github.com/tachiyomiorg/tachiyomi/pull/5741

(cherry picked from commit 708e71a35a)
2021-08-27 12:50:51 -04:00
Ivan Iskandar 4603465783 Hide reader progress indicator right away (#5750)
The image will be drawn over it so the animation won't be visible anyway

(cherry picked from commit 4eaccc966e)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
2021-08-27 12:50:50 -04:00
Andreas d621ef0b3a Make default category translatable (#5751)
* Make default category translatable

* Replace duplicate strings with common one

(cherry picked from commit 3670d649b8)
2021-08-27 12:50:49 -04:00
Ivan Iskandar 56a2fec004 Require authentication-confirmation to change biometric lock settings (#5695)
* Requires authentication-confirmation to change biometric lock settings

* Prevent double authentications on older APIs when confirming settings changes

* Use new AuthPrompt API for app lock

With this commit, the app lock will only explicitly require Class 2 biometrics
or screen lock credential. Class 3 biometrics are guaranteed to meet Class 2
requirements thus will also be used when available.

* Use extension toast

(cherry picked from commit 90ab04e81d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/security/SecureActivityDelegate.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt
2021-08-27 12:50:49 -04:00
Ivan Iskandar f79ac55182 Partial revert 914b686c8e (#5749)
Didn't mean to remove this line, this fixes resuming to read downloaded chapter.

(cherry picked from commit 26b8df5354)
2021-08-27 12:50:48 -04:00
Ivan Iskandar add234ce0b PagerPageHolder: Move chooseBackground call to IO thread (#5737)
* ImageUtil.chooseBackground: Use built-in decoder

* PagerPageHolder: Move chooseBackground call to IO thread

Also move stuffs and reuse image stream as bytes

(cherry picked from commit 11a8046c5f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
2021-08-27 12:50:48 -04:00
Ivan Iskandar acbc4c48fa Edge-to-edge manga details view (#5613)
* Prepare for edge-to-edge MangaController

* Fix derpy liftToScroll with our own implementation

* Edge-to-edge MangaController

Except when legacy blue theme is used.

* Save app bar lift state for controller backstack

* Fix expanded cover position after the view recycled

* Handle overlap changes when incognito mode disabled

* Tablet fixes

* Revert "Handle overlap changes when incognito mode disabled"

This reverts commit 1f492449

Breaks on rotation changes.

* Fix MangaController's swipe refresh position

* All controllers are now doing lift app bar on scroll by default

They are already doing that before so this pretty much just a cleanups.

* TachiyomiCoordinatorLayout: Support ViewPager for app bar lift state check

I'm willing to revert this if this minute detail solution is deemed too hacky xD

* Fix app bar not lifted when scrolled without fling

* Save app bar lift state across configuration changes

* Fix MangaController's swipe refresh position after configuration change

* TachiyomiCoordinatorLayout: Update ViewPager reference when controller is changed

(cherry picked from commit da16110e1c)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/ConductorExtensions.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt
2021-08-27 12:50:47 -04:00
Ivan Iskandar 32fa99377d ReaderTransitionView: Use context theme color for texts (#5738)
* Put themed reader context in adapter

This avoids creating themed context everytime the page holder is created, this
also allows the transition view to use the same themed context.

* Check against app night mode to create themed reader context

* ReaderTransitionView: Use context theme color for texts

The whole reader will need to be recreated when changing reader background while
webtoon mode is used, because recreating just the RecyclerView without messing
up the scroll position is impossible (I hope I just missed something).

(cherry picked from commit 914b686c8e)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewerAdapter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonConfig.kt
2021-08-27 12:50:47 -04:00
nicki 6aa59325d0 Label one-shots correctly in anilist track search (#5741)
* use format instead of type in anilist search

As per anilist graphql docs, `type` refers to whether anime/manga and is
redundant (since we already limit it to `MANGA`). What we actually want
is `format` which includes whether the media is a One-shot or Manga

This should help in making search a bit better as one no longer needs to
rely on the Date to figure out if its the One-shot entry or the Manga
entry

* Revert "use format instead of type in anilist search"

This reverts commit 6f0ba4888669f414a2093d7632eb1fab109d74de.

Accidentally changed the wrong query while further testing whoops

* use format instead of type in anilist search

As per anilist graphql docs, `type` refers to whether anime/manga and is
redundant (since we already limit it to `MANGA`). What we actually want
is `format` which includes whether the media is a One-shot or Manga

Changes search query and corresponding JSONALManga structure

(cherry picked from commit 27133520fc)
2021-08-27 12:50:46 -04:00
Hunter Nickel b3b1d2abf4 Fix start/resume fab showing up when entering and then exiting action mode (#5735)
(cherry picked from commit 24b967ad5c)
2021-08-27 12:50:46 -04:00
Jobobby04 14be5c75ee Fuck motion layout 2021-08-27 12:50:45 -04:00
Hunter Nickel 77138aba72 Add check for current controller before setting extension update tab badge (#5733)
(cherry picked from commit faef35ec47)
2021-08-27 12:50:45 -04:00
Andreas 8da397c7ed Fix today still being displayed even though relative time is off (#5732)
(cherry picked from commit 326d4c2641)
2021-08-27 12:50:44 -04:00
Riztard Lanthorn ac75ad7489 add Theme "Teal & Turquoise" (#5681)
* add Theme "Teal & Turquoise"

* re sorting & change tertiary dark

* use alpha on ripple color & capitalize

(cherry picked from commit 83436c9550)
2021-08-27 12:50:43 -04:00
Ivan Iskandar 5d8c89ba01 Fix library icon unchecked state (#5728)
Path data from AVD version

(cherry picked from commit 2084822731)
2021-08-27 12:50:43 -04:00
arkon 2f2352e938 Use separate string for toRelativeString "Today"
Apparently 0 quantity is ignored for some locales...

(cherry picked from commit 071bad1232)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
2021-08-27 12:50:42 -04:00
arkon 26e9b45687 Use toRelativeString in Updates and History headings
(cherry picked from commit ae1a76da2b)
2021-08-27 12:50:42 -04:00
Andreas d33b868991 Use relative time in ChapterHolder (#5719)
* Use relative time in ChapterHolder

Similar to how J2K does it

* Use custom implementation for relative time

* Changes based on review comments

(cherry picked from commit 57a5862840)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt
2021-08-27 12:50:42 -04:00
Jobobby04 3059008476 Cleanup 2021-08-27 12:50:41 -04:00
Arraiment a79c4babae Allow FilterList to be passed with default values (#5716)
(cherry picked from commit 91fbccdbaa)
2021-08-27 12:50:41 -04:00
Long 7b56261719 DNS-over-HTTPS (Adguard) (#5715)
* Update DohProviders.kt

* Update NetworkHelper.kt

* Update SettingsAdvancedController.kt

* fix typo

* Fix typo

* Fix typo

(cherry picked from commit 0ab0dd95ae)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
2021-08-27 12:50:40 -04:00
Hunter Nickel dc56b47e16 Add toggle to invert page color in reader color filter settings (#5713)
(cherry picked from commit 4c8dfd0c0c)
2021-08-27 12:50:40 -04:00
arkon a773e99214 Fix global search menu item title
(cherry picked from commit 2b9dbfb390)
2021-08-27 12:50:39 -04:00
arkon 4fad8f70f3 Update menu icons in Browse Sources view (closes #5397)
(cherry picked from commit 63053b9940)
2021-08-27 12:50:39 -04:00
arkon 6857f35910 Don't allow focus on ReaderNavigationOverlayView (maybe fixes #5555)
(cherry picked from commit 2256030a2a)
2021-08-27 12:50:38 -04:00
arkon 06976401a5 Open tracker page when clicking logo (closes #5624)
(cherry picked from commit 79da33b597)
2021-08-27 12:50:38 -04:00
arkon c69bb5b33d Always re-setup background jobs on migration runs
(cherry picked from commit 7d67450e58)
2021-08-27 12:50:37 -04:00
arkon cde6f127b1 Do background app/extension checks less frequently
Since the in-app checks occur at least once a day anyway.

(cherry picked from commit 8aa11951bf)
2021-08-27 12:50:37 -04:00
arkon 4248a3132a Add in-app app update check
(cherry picked from commit f23f22ab01)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateChecker.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdaterJob.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt
2021-08-27 12:50:36 -04:00
arkon 5dac934cc4 Update dependencies
(cherry picked from commit 96a64c7bd2)
2021-08-27 12:50:36 -04:00
Hunter Nickel 47a534c454 Apply app theme styling to reader page errors and progress dialog (#5705)
(cherry picked from commit d1bb0fdf1d)
2021-08-27 12:50:35 -04:00
Zakhar Timoshenko 655298f44c Fix selector in search card item (#5711)
(cherry picked from commit feca30d7ed)
2021-08-27 12:50:35 -04:00
Jobobby04 10c8c3baee Add a option to force migrate all nhentai manga to the nhentai other lang
Dont blame me if this breaks your library
2021-08-27 12:50:34 -04:00
Jobobby04 e284c7a921 Add E/Exh popular as the default browse menu, add a Toplists filter for E-Hentai 2021-08-27 12:50:34 -04:00
Soitora 17a3185c7a Update to Contributor Covenant 2.1 (#5697)
(cherry picked from commit bb3afd0dc9)
2021-08-27 12:50:33 -04:00
Ivan Iskandar 374ecde463 Use correct color for reader loading indicator (#5685)
* Revert "Revert "Use correct color for reader loading indicator (#5645)" (fixes #5669)"

This reverts commit a4eba50c

* Fix crash on older APIs

(cherry picked from commit 5e77ae208d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonConfig.kt
2021-08-27 12:50:33 -04:00
Ivan Iskandar 564c8618cb Enable elevation overlay for MaterialSwitch (#5686)
(cherry picked from commit 24e5a4d7ec)
2021-08-27 12:50:32 -04:00
Jobobby04 eb7a2ab191 Fix build 2021-08-27 12:50:32 -04:00
arkon 98dfec8fdf Replace AboutLibraries activity with custom controller
(cherry picked from commit 1d10d29fa9)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt
2021-08-27 12:50:31 -04:00
arkon ce43417a26 Reorganize dependencies a bit
(cherry picked from commit 9b00e91773)

# Conflicts:
#	app/build.gradle.kts
2021-08-27 12:50:31 -04:00
arkon b01e48752d Remove explicit CardView dependency
(cherry picked from commit cd73c30d6f)
2021-08-27 12:50:31 -04:00
arkon d5ff08e9c8 Update Duktape
(cherry picked from commit 7bbba0c7d9)
2021-08-27 12:50:30 -04:00
Andreas e3ee972bf3 Add ability to tweak auto hide sensitivity in Webtoon Reader (#5650)
* Tweak threshold

* Put setting under Webtoon instead

Because it only affects Webtoon related viewers

(cherry picked from commit 7907a4fc24)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt
2021-08-27 12:50:29 -04:00
arkon 1f6e202597 Issue report changes
(cherry picked from commit 85791a9336)

# Conflicts:
#	.github/ISSUE_TEMPLATE.md
#	.github/ISSUE_TEMPLATE/report_issue.yml
#	.github/ISSUE_TEMPLATE/request_feature.yml
#	app/build.gradle.kts
2021-08-27 12:50:29 -04:00
Jobobby04 f5645a8382 Revert "Use correct color for reader loading indicator (#5685)"
This reverts commit de698fc2334030faeddc787ac3b224f4bc32d316.
2021-08-27 12:50:28 -04:00
arkon 7b038951b0 Remove ability to set in-app language differently from system's
(cherry picked from commit 03980b2f27)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt
2021-08-27 12:50:28 -04:00
arkon 8b93cf3cec [skip ci] Update issue templates
(cherry picked from commit 664e5cfb59)

# Conflicts:
#	.github/ISSUE_TEMPLATE.md
#	.github/ISSUE_TEMPLATE/report_issue.yml
#	.github/ISSUE_TEMPLATE/request_feature.yml
2021-08-27 12:50:27 -04:00
arkon bcb15d7ee3 Remove janky tracker icon UI
(cherry picked from commit ab46bd56b0)
2021-08-27 12:50:27 -04:00
arkon 711d0ec092 Fix RTL support
(cherry picked from commit c23506e887)
2021-08-27 12:50:27 -04:00
Jozef Hollý c8abf44666 Weblate translations (#5571)
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Albedo <Illiator27@gmail.com>
Co-authored-by: Alejandro Djeordjian <masterdragondark@gmail.com>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: Blue <bluestuffish@gmail.com>
Co-authored-by: Bùi Nguyễn Hoàng Thọ <buinguyenhoangtho97@gmail.com>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: Carlos Hernández García <carlosdezia@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Eugene <e.shlyapkin99@gmail.com>
Co-authored-by: Femto <yusufackerman10@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Hytashi <pierrot.bourdeau@yahoo.fr>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jendrej <ejjendrej@gmail.com>
Co-authored-by: Ken Swenson <flat@esoteric.moe>
Co-authored-by: Kurocon <weblate@kurocon.nl>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Napuzu <napuzu@hotmail.com>
Co-authored-by: Nikita Epifanov <nikgreens@protonmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Paulo Pinho <kebrus@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Prince Carl <addminusevei@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Tarık Yıldız <tariky113@gmail.com>
Co-authored-by: Zakhar Timoshenko <vp1984tanki@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Co-authored-by: あぽろあぽろ <aporotilyoko0000@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ar/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ca/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/cs/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/cv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es_419/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fil/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ja/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/jv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/uz/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/vi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translation: Tachiyomi/Tachiyomi 0.x

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Albedo <Illiator27@gmail.com>
Co-authored-by: Alejandro Djeordjian <masterdragondark@gmail.com>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alifian Caesar <alifiancaesar@gmail.com>
Co-authored-by: Blue <bluestuffish@gmail.com>
Co-authored-by: Bùi Nguyễn Hoàng Thọ <buinguyenhoangtho97@gmail.com>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: Carlos Hernández García <carlosdezia@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Eugene <e.shlyapkin99@gmail.com>
Co-authored-by: Femto <yusufackerman10@gmail.com>
Co-authored-by: Hytashi <pierrot.bourdeau@yahoo.fr>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jendrej <ejjendrej@gmail.com>
Co-authored-by: Ken Swenson <flat@esoteric.moe>
Co-authored-by: Kurocon <weblate@kurocon.nl>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Napuzu <napuzu@hotmail.com>
Co-authored-by: Nikita Epifanov <nikgreens@protonmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Paulo Pinho <kebrus@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Prince Carl <addminusevei@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Tarık Yıldız <tariky113@gmail.com>
Co-authored-by: Zakhar Timoshenko <vp1984tanki@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Co-authored-by: あぽろあぽろ <aporotilyoko0000@gmail.com>
(cherry picked from commit 9ad67a7b7d)
2021-08-27 12:50:26 -04:00
Ivan Iskandar a90f99c445 Use correct color for reader loading indicator (#5685)
* Revert "Revert "Use correct color for reader loading indicator (#5645)" (fixes #5669)"

This reverts commit a4eba50c

* Fix crash on older APIs

(cherry picked from commit 5e77ae208d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonConfig.kt
2021-08-27 12:50:26 -04:00
Jobobby04 1d9c3624a9 Main tachi title style 2021-08-27 12:50:25 -04:00
arkon bdbee22f29 Dependency updates
(cherry picked from commit 4d92caacef)
2021-08-27 12:50:25 -04:00
Andreas 82f0bf809d Fix weird behaviour in library when switching display mode (#5640)
(cherry picked from commit fd45de5c58)
2021-08-27 12:50:24 -04:00
Ivan Iskandar 306deb5e6a Fix forced secure screen disabled after disabling incognito
(cherry picked from commit 245132a1d136d41b5c139c09c58711ce224b6494)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/security/SecureActivityDelegate.kt
2021-08-27 12:50:24 -04:00
Jobobby04 ac6e0acc5d Drop blank 2021-08-27 12:50:23 -04:00
Jobobby04 8bcf2f7b82 Add uploader as a virtual tag 2021-08-27 12:50:04 -04:00
Jobobby04 5598ccf9e6 Search EHentai uploader on click 2021-08-27 12:50:04 -04:00
Jobobby04 478d7f989d Improve Hitomi tag list 2021-08-27 12:50:03 -04:00
Andy Bao b6f454ba66 Sync J2K fields in BackupManga to fix dupe ID (#400)
See: https://github.com/Jays2Kings/tachiyomiJ2K/issues/878
2021-08-20 18:30:26 -04:00
Riztard Lanthorn c613784fc4 fix toolbar btn color (#395)
* fix prev btn color in vert seekbar

* fix migration button color

use colorOnToolbar instead of colorOnPrimary
2021-08-16 23:01:41 -04:00
Eugene 6213d3e7a9 [Translation]RU (#383)
* [Translation]RU

* er

* del clone

* as pure white
2021-08-05 15:42:07 -04:00
Ivan Iskandar 6257d261b3 Fix wonky webtoon layout on less faster devices
(cherry picked from commit 0d28fb31a39c92f19e8cb8fc0ecf5ca1523c1085)
2021-08-04 23:05:29 -04:00
Jobobby04 3c24137810 Probably fix some weird bug when adding a tag 2021-08-04 22:56:33 -04:00
Jobobby04 03dbd617f9 Revert "Fix webtoon page takes up entire screen even if it's smaller (#5622)"
This reverts commit 4adf840f4b.
2021-08-04 15:10:08 -04:00
Jobobby04 8d7aa4b6a2 Fix filtered scanlators 2021-08-02 00:30:19 -04:00
Jobobby04 ae99b733e7 Better way to logout 2021-08-02 00:18:08 -04:00
Ivan Iskandar d5423caf91 Change BottomNavigationView behavior (#5603)
Similar to app bar's scroll behavior

(cherry picked from commit ff2a4e6952)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
2021-08-01 23:55:38 -04:00
Andreas 2b4adc0c7d Don't hide menu when scrolling through with ReaderSeekBar (#5611)
(cherry picked from commit 7660751f7f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt
2021-08-01 23:45:35 -04:00
arkon 52a0aa9d47 Set exported flags on activities
(cherry picked from commit 78b9ac4766)

# Conflicts:
#	app/src/main/AndroidManifest.xml
2021-08-01 23:43:08 -04:00
arkon 22d0a6f19a Disable Android system auto backup (closes #5114)
In practice this feature:
- Just didn't work
- Magically worked (sometimes; see first point)
- Restored something potentially too old and totally messed up the app

(cherry picked from commit d5c75571dc)
2021-08-01 23:39:32 -04:00
arkon 1f31633b27 Update Coil
(cherry picked from commit 16b9c459ab)
2021-08-01 23:39:23 -04:00
Hunter Nickel c673385653 Add functionality to open SettingsMainController when double-tapping the "more" button (#5633)
(cherry picked from commit 41c060e28b)
2021-08-01 23:39:13 -04:00
Ivan Iskandar e02057a066 Fix reader activity not using preferred language (#5630)
(cherry picked from commit a3090e62f5)
2021-08-01 23:38:39 -04:00
Ivan Iskandar 4adf840f4b Fix webtoon page takes up entire screen even if it's smaller (#5622)
(cherry picked from commit 39b7024be0)
2021-08-01 23:38:28 -04:00
Jobobby04 5ce8f549a6 Remove android build cache due to deprecation 2021-08-01 21:56:43 -04:00
Jobobby04 9916d89296 New attempt to logout 2021-08-01 21:56:04 -04:00
arkon 46d33b0cfb Update for AS Arctic Fox
(cherry picked from commit d019c5999b)

# Conflicts:
#	README.md
#	app/build.gradle.kts
2021-07-28 17:06:44 -04:00
Gauthier f56fef667b fix regression in cover fetching (#5621)
introduced in https://github.com/tachiyomiorg/tachiyomi/pull/4870
this was previously done here: https://github.com/tachiyomiorg/tachiyomi/blob/7d23fd8ef5bbb9efd12f65bb5c9670464dd6c0b1/app/src/main/java/eu/kanade/tachiyomi/data/glide/MangaThumbnailModelLoader.kt#L95 as part of https://github.com/tachiyomiorg/tachiyomi/pull/2908

this impacts Komga extension, where server url is manually provided by the user, but due to auto-correct on mobile keyboards the `http` prefix sometimes get capitalized to `Http`.

(cherry picked from commit 20264eecb9)
2021-07-28 17:03:08 -04:00
Ivan Iskandar 404c773fd7 ReaderProgressIndicator: Set indeterminate as default state (#5605)
Will also set to indeterminate if progress is 0.

(cherry picked from commit cc55453076)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
2021-07-28 17:02:58 -04:00
Carlos 9a47e812ed [skip ci] use the actions built in ignore case
(cherry picked from commit 6cab2427f5)
2021-07-28 17:01:12 -04:00
Carlos 4bd91c0d9e [skip ci] update issue closer to close anime/aniyomi
(cherry picked from commit 511bcc9197)
2021-07-28 17:01:05 -04:00
Ivan Iskandar c177b4516e Fix list scrolling on quad-state dialog (#5602)
(cherry picked from commit 00ac632d8f)
2021-07-25 14:22:29 -04:00
arkon 2de36cac79 Use chooser intent for sharing saved pages
(cherry picked from commit 649209890d)
2021-07-25 14:22:20 -04:00
arkon e422993c2e Remove unnecessary MultiDex library
(cherry picked from commit f2fca0f13d)

# Conflicts:
#	app/build.gradle.kts
2021-07-25 14:22:12 -04:00
FlaminSarge c89f88de16 Revert changes to last_update behavior from #5436 (#5590)
(cherry picked from commit 4084d5e69a)
2021-07-25 14:21:41 -04:00
arkon 0f7e251306 Reword tracking update preference since it updates status too
(cherry picked from commit e8beb7103c)
2021-07-25 14:21:32 -04:00
arkon 9e264a3b89 Relax MIUI backup/restore warning
(cherry picked from commit 0e4ce0f1ae)
2021-07-25 14:21:25 -04:00
Ivan Iskandar 673869bd13 Apply default night mode earlier (#5593)
(cherry picked from commit c42d517f6b)
2021-07-25 14:21:17 -04:00
Jobobby04 e40fbbecbb Add a few source helper functions 2021-07-25 14:16:16 -04:00
Jobobby04 81af5a5654 Cleanup 2021-07-25 14:15:27 -04:00
Jobobby04 1699c2ed67 Fix fab appearing after closing cover expand when no chapters are unread 2021-07-24 13:33:33 -04:00
Jobobby04 877adee4f7 Cleanup 2021-07-24 12:49:09 -04:00
Jobobby04 75f5d46f6a Delete the tokens on logout 2021-07-24 12:40:18 -04:00
Jobobby04 464f2b01a1 Manually try authenticating mangadex logout, skip if it fails 2021-07-24 12:38:55 -04:00
Jobobby04 d22b14734d Cleanup 2021-07-22 20:20:51 -04:00
Jobobby04 b30491c8fb Maybe fix crashing from J2k backups 2021-07-22 20:20:35 -04:00
Jobobby04 0c3e8f977c Fix crash with open in webview after migrate 2021-07-22 19:46:42 -04:00
Jobobby04 698246ee2a Fix crash when somehow a invalid filters json is passed 2021-07-22 19:34:00 -04:00
Jobobby04 0f4414e359 Fix crash if you somehow have a invalid saved search json 2021-07-22 19:29:47 -04:00
Jobobby04 b769043f36 Fix logout of mangadex 2021-07-22 19:28:59 -04:00
Andreas 1480829dd1 Auto hide reader menu when user starts reading again (#5578)
* Hide reader menu when user starts reading again

* Hide menu on zoom and scrolling around during zoom

Didn't work for webtoon

* Only listen when menu is visible

(cherry picked from commit 356cd4ef52)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt
2021-07-22 15:50:55 -04:00
FlaminSarge 25629b5a4c Group 'Source not installed' cases in library update error log (#5589)
(cherry picked from commit 88619145d8)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt
2021-07-22 15:48:36 -04:00
Ivan Iskandar 641ad196f9 Reader loading progress indicator changes (#5587)
* Use CircularProgressIndicator on PageHolder

Manually rotate the CircularProgressIndicator inside a wrapper view instead of
drawing our own custom indicator.

* Use CircularProgressIndicator on TransitionHolder

(cherry picked from commit 6ba779fb7a)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
2021-07-22 15:47:45 -04:00
FlaminSarge 0624b5e7d0 For library update error log, group errors by error string, and then sort the resulting list by source (#5586)
Format is
```
! Error
  # Source
    - Manga
```

(cherry picked from commit 8bd965267c)
2021-07-22 15:37:44 -04:00
Jobobby04 80128b1391 Update AboutLibraries 2021-07-22 15:37:19 -04:00
Jobobby04 ed19ad8819 Revert "Use jsDelivr as fallback when GitHub can't be reached for extensions list (closes #5517)"
This reverts commit 7891b4de31.
2021-07-22 15:36:04 -04:00
Ivan Iskandar c030a68d12 Fix incorrect saved tracker dates (#5581)
(cherry picked from commit be28e0b559)
2021-07-22 15:35:43 -04:00
Ivan Iskandar 8f0eeb6c9c Fix light navigation bar not applied on first launch (#5582)
No need to touch light system bars when running the splash screen since
they're not that noticeable, and it also breaks on some ROMs.

(cherry picked from commit 116fec208b)
2021-07-22 15:35:36 -04:00
Ivan Iskandar bd4a0e0a73 Fix transparent system bars after MainActivity recreated (#5574)
(cherry picked from commit fece92e15a)
2021-07-22 15:35:27 -04:00
arkon 02586404d7 Remove autoAddTrack preference
(cherry picked from commit dce3049446)
2021-07-22 15:35:17 -04:00
Jobobby04 86d28ac17f Build with Jdk 11 2021-07-22 15:35:05 -04:00
E3FxGaming 2a39a9105e Fix Cover sharing and saving (#5335)
* Fix Cover sharing and saving

The newly added manga cover sharing only worked with manga saved to the library (due to the implemented CoverCache only recording covers of library manga).
The changes made with this commit fixes that behaviour by implementing a fallback: the cover can now also be retrieved from the Coil memoryCache.

* Removal of coil MemoryKey usage

No longer uses the coil memory key, instead starts a new Coil request for the cover retrieval.

* Removed try-/catch-wrapper and added context-passing

useCoverAsBitmap lost its try-/catch-wrapper and doesn't call for the context anymore.
Instead shareCover and saveCover now pass their activity as context to useCoverAsBitmap.

* Added missing parameter description for useCoverAsBitmap

(cherry picked from commit fcd6fe5d8a)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
2021-07-22 15:34:28 -04:00
arkon 5e89c1c11c Require Komga to be installed when attempting to setup tracker (closes #5491)
(cherry picked from commit a69a833716)
2021-07-22 15:32:43 -04:00
arkon 4bad159174 Warn on backup creation for MIUI users
(cherry picked from commit 697b082591)
2021-07-22 15:32:35 -04:00
Jobobby04 fda6458821 Implement manga dir rename 2021-07-21 13:56:30 -04:00
Jobobby04 e4debc89f0 Cleanup 2021-07-19 21:34:35 -04:00
Jobobby04 c5dec52c02 AssembleStandardRelease 2021-07-19 21:34:03 -04:00
Jobobby04 afa267f88b Remove old strings 2021-07-18 22:14:28 -04:00
Jobobby04 e2a81b1f0c Support new tracking feature in MDList 2021-07-18 22:04:21 -04:00
Ivan Iskandar 699490685f Add Dynamic theme for Android 12 (#5569)
* Add Dynamic theme for Android 12

* Also theme text colors

(cherry picked from commit b2d58e04d2)
2021-07-18 22:02:54 -04:00
arkon 3fb7140587 Put Komga tracker in separate group
(cherry picked from commit 8bfc5f0450)
2021-07-18 22:02:47 -04:00
arkon d0b2f6eaec Update detection of disabled MIUI Optimization
(cherry picked from commit a252a8acee)
2021-07-18 22:02:38 -04:00
Andreas dd25cd04c1 Add support for start/end fields for Kitsu (#5573)
(cherry picked from commit 447ee4bd09)
2021-07-18 22:02:31 -04:00
Jozef Hollý 1696e90eeb Weblate translations (#5276)
Co-authored-by: Aagaman Luitel <aagaman@disroot.org>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: Bùi Nguyễn Hoàng Thọ <buinguyenhoangtho97@gmail.com>
Co-authored-by: Cypral <cypral@hotmail.fr>
Co-authored-by: Daniele Tricoli <eriol@mornie.org>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Edmerson Pizarra <edmerpizarra@gmail.com>
Co-authored-by: Elosy <gaudic99@gmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Eugene <e.shlyapkin99@gmail.com>
Co-authored-by: Fellow Turkish <f3ll0wm4il3r_12@protonmail.com>
Co-authored-by: HeavenShadow <heavenshadow@outlook.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jarel Sawangin <jarelsawangin18@gmail.com>
Co-authored-by: Jetspectre <jetspectre1@gmail.com>
Co-authored-by: Khane Mcdaddy <kumakichi.houtarou@gmail.com>
Co-authored-by: Kurocon <weblate@kurocon.nl>
Co-authored-by: Laurant Marijnissen <laurant@gigafyde.dev>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matteo Gaeta <matteo.gaeta.1998@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Mubarek Seyd Juhar <mubareksd@gmail.com>
Co-authored-by: Mubarek Seyd Juhar <mubareksej@gmail.com>
Co-authored-by: Neo <ohmaytt@naver.com>
Co-authored-by: Norbert Kovács <kovinor123@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
Co-authored-by: Shashank Pujari <shashankppujari@gmail.com>
Co-authored-by: Shippo <shiposhouyou@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Silvio Pastore <silvioppastore@gmail.com>
Co-authored-by: Techeira Damián <damian.techeira@mercadolibre.com>
Co-authored-by: Tooster <max@polarczyk.pl>
Co-authored-by: Zero O <godarms2010@live.com>
Co-authored-by: f0roots <f0rootss@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: whenwesober <naomi16i_1298q@cikuh.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Co-authored-by: 曹恩逢 <nelson22768384@gmail.com>
Co-authored-by: 殺Mustafa <mustafasheref8@gmail.com>
Co-authored-by: 莊景翔 <sean1781031@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ar/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ca/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/cs/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es_419/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fil/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hu/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ja/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/kn/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ko/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ne/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pl/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ro/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sv/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ti/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/uk/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/vi/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/
Translation: Tachiyomi/Tachiyomi 0.x

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Aagaman Luitel <aagaman@disroot.org>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: Bùi Nguyễn Hoàng Thọ <buinguyenhoangtho97@gmail.com>
Co-authored-by: Cypral <cypral@hotmail.fr>
Co-authored-by: Daniele Tricoli <eriol@mornie.org>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Edmerson Pizarra <edmerpizarra@gmail.com>
Co-authored-by: Elosy <gaudic99@gmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Eugene <e.shlyapkin99@gmail.com>
Co-authored-by: Fellow Turkish <f3ll0wm4il3r_12@protonmail.com>
Co-authored-by: HeavenShadow <heavenshadow@outlook.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jarel Sawangin <jarelsawangin18@gmail.com>
Co-authored-by: Jetspectre <jetspectre1@gmail.com>
Co-authored-by: Khane Mcdaddy <kumakichi.houtarou@gmail.com>
Co-authored-by: Kurocon <weblate@kurocon.nl>
Co-authored-by: Laurant Marijnissen <laurant@gigafyde.dev>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matteo Gaeta <matteo.gaeta.1998@gmail.com>
Co-authored-by: Matyáš Caras <contact@hernikplays.cz>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Mubarek Seyd Juhar <mubareksd@gmail.com>
Co-authored-by: Mubarek Seyd Juhar <mubareksej@gmail.com>
Co-authored-by: Neo <ohmaytt@naver.com>
Co-authored-by: Norbert Kovács <kovinor123@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
Co-authored-by: Shashank Pujari <shashankppujari@gmail.com>
Co-authored-by: Shippo <shiposhouyou@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Silvio Pastore <silvioppastore@gmail.com>
Co-authored-by: Techeira Damián <damian.techeira@mercadolibre.com>
Co-authored-by: Tooster <max@polarczyk.pl>
Co-authored-by: Zero O <godarms2010@live.com>
Co-authored-by: f0roots <f0rootss@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: whenwesober <naomi16i_1298q@cikuh.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Co-authored-by: 曹恩逢 <nelson22768384@gmail.com>
Co-authored-by: 殺Mustafa <mustafasheref8@gmail.com>
Co-authored-by: 莊景翔 <sean1781031@gmail.com>
(cherry picked from commit 3cd6382795)
2021-07-18 22:02:21 -04:00
arkon 6f73261e21 Add link to Don't Kill My App! in advanced settings
(cherry picked from commit 5d1134dfa8)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
2021-07-18 22:02:00 -04:00
Ivan Iskandar f2bd785c57 Fix splash screen icon on Android 12 (#5565)
* Use Core Splashscreen for splashscreen stuff

* Keep splash screen until activity ready

Ready as in the data inside starting screen is finished showing

* Use custom splash screen exit animation on older android version

* Add splash screen minimum duration to prevent exit jank

* Fix broken AMOLED theme

* Improvements

(cherry picked from commit 05e7b0dc22)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
#	app/src/main/res/drawable/ic_tachi_splash.xml
2021-07-18 22:01:04 -04:00
Andreas ec7f70e71c Make default tracking status depend if the user has read chapter or not (#5567)
- When user reads a chapter change tracking status to reading

(cherry picked from commit c0647c3110)
2021-07-18 20:21:25 -04:00
Ivan Iskandar c2f9e4637c Bump compileSdk to 31 (#5563)
(cherry picked from commit ef84ed4982)
2021-07-18 20:20:50 -04:00
Hunter Nickel 6e6d69b6b1 Add cover actions to a dialog when long-pressing manga cover (#5556)
(cherry picked from commit a1e83b9f19)
2021-07-18 20:20:41 -04:00
Soitora 6e45ed3c1d Make incognito bar use primary colors (#5558)
Looks better than the odd forced gray used for all themes

(cherry picked from commit 4ce4ee3c00)
2021-07-18 20:20:33 -04:00
Soitora a17747e2b4 Added "Tako" theme (#5546)
* Added "Ninomae" theme

Based on the lovely Ninomae Ina'nis, for Arkon and Flat

* Use updated colors from Ghostbear

Adapted after feedback

Co-Authored-By: Andreas <6576096+ghostbear@users.noreply.github.com>

* Tweak the Ninomae theme further

* Sort themes alphabetically

- Sorts themes alphabetically.
- Use the same capital word system in colors.xml for themes.xml as well.
- Rename AMOLED theme to AMOLED mode in theme.xml and color.xml references.

* More tweaks

* Style incognito bar

Uses a dark purple which looks super clean instead of a washed out gray

This sets the groundwork for other themes too

* Tweak final onPrimary color

* Rename Ninomae to Tako

RIP

Co-authored-by: Andreas <6576096+ghostbear@users.noreply.github.com>
(cherry picked from commit 0d62aedfbb)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt
2021-07-18 20:20:26 -04:00
Ivan Iskandar e0b62b9cd1 Don't show navigation overlay if tap navigation is disabled (#5534)
* Don't show navigation overlay if tap navigation is disabled

* Apply feedback

(cherry picked from commit b7c2890250)
2021-07-18 20:19:03 -04:00
Jobobby04 65b6f7df44 Fix build errors because of JSoup update 2021-07-18 20:18:20 -04:00
Jobobby04 cf54851342 Replace material-dialogs with Material Components' SY 2021-07-18 20:17:58 -04:00
Ivan Iskandar d4993d1b71 Replace material-dialogs usage with Material Components' (#5423)
* Use Material Components' dialogs

For all dialogs that has direct replacement.

* Convert text input dialogs

* Convert quad-state multi choices dialogs

* Convert date picker dialogs

This also changes the flow to remove selected start/finish tracking date and
the track item itself

* Remove material-dialogs dependencies

(cherry picked from commit ae97bb0445)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/WhatsNewDialogController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPageSheet.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt
2021-07-18 20:15:30 -04:00
arkon d8054b3f7b Chop long titles in library update notification, fix incrementing when updating covers
(cherry picked from commit 117fd4bd0f)
2021-07-18 13:10:14 -04:00
arkon 61a6f1ce4e Update to Kotlin 1.5.21
(cherry picked from commit bd424ce460)
2021-07-18 13:10:04 -04:00
FourTOne5 1587923162 Update Libary update notification. (#5545)
* Update LibraryUpdateNotifier.kt

* Update LibraryUpdateService.kt

(cherry picked from commit 1dddba7f25)
2021-07-18 13:09:56 -04:00
Hunter Nickel 10a927f9d7 Hide the reader seekbar for single-page chapters (#5551)
(cherry picked from commit 7fd75b7501)
2021-07-18 13:09:47 -04:00
Carlos 269af9a2f5 Update request_feature.yml
closes #5543

(cherry picked from commit 423f07033e)
2021-07-18 13:08:44 -04:00
arkon 051e360793 Update jsoup and Coil
(cherry picked from commit ef9c457681)
2021-07-18 13:08:20 -04:00
Hunter Nickel a46e62eee3 Hide Start/Resume FAB unless there are unread chapters and during loading (#5458)
* Hide Start/Resume FAB unless there are unread chapters

* Remove dead code, rewrite logic for hiding FAB

(cherry picked from commit a6d4a3b785)
2021-07-18 13:08:13 -04:00
Riztard Lanthorn 290efebf27 fix yin & yang theme (#5535)
refresh arrow color didnt change in dark mode

(cherry picked from commit 2e487f8a3f)
2021-07-18 13:08:05 -04:00
Ivan Iskandar 05dbfd94e7 Fix incognito mode disabled after URL intent launched (#5533)
(cherry picked from commit 2423a70abd)
2021-07-18 13:07:53 -04:00
Soitora d34147803c Tweak chip contrast (#5526)
* Set better contrast for chips

* Set custom chip colors for Yin Yang

(cherry picked from commit 13d39fc942)
2021-07-18 13:07:43 -04:00
Soitora 640b0f84f7 Optimize the Green Apple theme variant (#5530)
(cherry picked from commit b7547a8458)
2021-07-18 13:07:34 -04:00
arkon 085358d39c Remove unnecessary DB calls when setting chapter flag defaults
(cherry picked from commit 8931dbb657)
2021-07-18 13:07:25 -04:00
arkon 8d88467aa0 Fix Incognito Mode toggle not updating after disabled via notification
(cherry picked from commit 52416ff3a8)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/more/MoreController.kt
2021-07-18 13:07:16 -04:00
Soitora ee51813069 Improve Green Apple color in Light theme (#5528)
(cherry picked from commit 3dbfee91f6)
2021-07-18 13:06:49 -04:00
Jobobby04 2bdead3e5f Cleanup mangadex, hopefully mitigate freezing 2021-07-18 13:06:12 -04:00
Jobobby04 dee3abd0c3 Logout even if the logout response doesnt return ok 2021-07-18 13:05:35 -04:00
Jobobby04 09ea9deb67 Stop excluding Tsumino from library updates 2021-07-12 12:26:41 -04:00
Jobobby04 866c4a77a3 Use a empty title if none is found 2021-07-11 21:24:24 -04:00
Jobobby04 a856ea20b4 Cleanup 2021-07-10 17:33:25 -04:00
Jobobby04 e6cb339ff5 Mangadex fixes 2021-07-10 17:27:21 -04:00
arkon 7377892942 Reword delete chapter settings (closes #5494)
(cherry picked from commit 09d4901781)
2021-07-10 17:23:02 -04:00
arkon b7321ca204 Improving genre search started from the manga page of a popular manga (#4375)
Co-authored-by: E3FxGaming <E3FxGaming@users.noreply.github.com>
(cherry picked from commit 62955e7385)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
2021-07-10 17:22:54 -04:00
Ivan Iskandar db395f5e37 Support more image formats for covers (#5524)
* Add TachiyomiImageDecoder for Coil

Is currently used to decode AVIF and JPEG XL images.

* LocalSource: Check against file name for cover

This allows file with all supported formats to be set as cover

* TachiyomiImageDecoder: Handle HEIF on Android 7 and older

(cherry picked from commit 1ef7722504)
2021-07-10 17:18:50 -04:00
arkon 7891b4de31 Use jsDelivr as fallback when GitHub can't be reached for extensions list (closes #5517)
(cherry picked from commit 24bb2f02dc)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt
2021-07-10 17:18:37 -04:00
arkon 15707d933a Use fade transactions when handling shortcuts
(cherry picked from commit 627698d81f)
2021-07-10 15:48:10 -04:00
arkon 6516a4285f Add warning for MIUI users when trying to restore backups with MIUI Optimization disabled
(cherry picked from commit d4c8480dee)
2021-07-10 15:48:01 -04:00
arkon 5a1f09e904 Parallel cover update job
(cherry picked from commit 015e8deb79)
2021-07-09 17:52:45 -04:00
jmir1 a844c636a6 show correct number of items in the library tit... (#5516)
...le, even when all manga are in a category that isn't the default
category.

(cherry picked from commit 8d5f798591)
2021-07-09 17:52:37 -04:00
arkon 9ade06c6f7 Update dependencies
(cherry picked from commit 714aa4b4ba)

# Conflicts:
#	app/build.gradle.kts
2021-07-09 17:52:14 -04:00
arkon b5f4eb79d9 Show all currently updating manga in library update notification
(cherry picked from commit e65f59b3df)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateNotifier.kt
2021-07-08 23:34:28 -04:00
arkon cec05194eb Update dependencies
(cherry picked from commit 67128937ca)

# Conflicts:
#	app/build.gradle.kts
2021-07-08 23:10:14 -04:00
Riztard Lanthorn 22fd34088f add Yin Yang Theme (#5508)
* add Yin Yang Theme

* change download badge color to yin yang as well

* update string

* fix &

(cherry picked from commit d9ea621e54)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt
2021-07-08 23:08:47 -04:00
SBence 04326d17bf Sanitize manga title in page download subfolder name (#5514)
(cherry picked from commit fb35d7af59)
2021-07-08 23:05:29 -04:00
Jobobby04 4e8142b5b8 Cleanup library update a bit 2021-07-08 23:05:08 -04:00
Jobobby04 a29ddaaf1c Add debug function to reset viewer for all manga 2021-07-07 20:53:52 -04:00
Andreas 102811f781 Make Automatic Reader Theme pick background/text color based on dark mode preference (#5505)
* Make Automatic Reader Theme pick background/text color based on theme

* Use extension method

(cherry picked from commit c254aa6fcc)
2021-07-07 20:37:26 -04:00
Jobobby04 b49c64d4ff Cleanup 2021-07-07 20:37:14 -04:00
Ivan Iskandar 52b748d935 Simplify locale override (#5509)
(cherry picked from commit 37d30eb887)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
2021-07-07 20:37:02 -04:00
w 4d95306cd9 Update image decoder to add JPEG XL support (#5512)
(cherry picked from commit 49cdcc644c)
2021-07-07 20:24:08 -04:00
arkon 811be77144 Fix chapter source order not working correctly and allow refresh to update source order
Based on https://github.com/CarlosEsco/Neko/commit/00f916a4f0e8d677f8e2107e92139d43d88606ae

Co-authored-by: CarlosEsco <CarlosEsco@users.noreply.github.com>
(cherry picked from commit 07e5525c74)
2021-07-07 20:24:00 -04:00
arkon 6323306693 Only update in-library manga chapter settings instead of all
(cherry picked from commit 776194f5b2)
2021-07-07 20:23:48 -04:00
arkon c2b07717fc Sanitize spaces when setting URLs without domain
It throws an URISyntaxException otherwise.

(cherry picked from commit ed80ee98a7)
2021-07-07 20:23:42 -04:00
Jobobby04 aaad902d6a Fix filter theme 2021-07-07 16:00:34 -04:00
Jobobby04 bfb018d1b4 Fix migration menu icons 2021-07-06 17:08:50 -04:00
Jobobby04 211e0912a3 Fix intercept activity toolbar 2021-07-06 17:01:52 -04:00
Jobobby04 d788585d14 ReImplement Mangadex deeplink 2021-07-06 16:58:09 -04:00
Jobobby04 90654dc027 Fix page reporting 2021-07-06 15:28:32 -04:00
arkon 183da5cc84 Resource cleanup post-theme removal
(cherry picked from commit 040bac3da2)
2021-07-05 18:43:55 -04:00
arkon 693b57b14c Add DARK_BLUE enum value back to avoid crash
(cherry picked from commit 9df721d158)
2021-07-05 18:43:48 -04:00
arkon 243f6b3851 Update dependencies
(cherry picked from commit ba0907ae59)

# Conflicts:
#	app/build.gradle.kts
2021-07-05 18:43:39 -04:00
arkon 988249b177 Remove Hot Pink theme
The old AMOLED Hot Pink theme is pretty close to what Midnight Dusk + AMOLED is now.

(cherry picked from commit e9dce32a98)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt
2021-07-05 18:42:30 -04:00
arkon e6a4d1e2b4 Rename "Dark Blue" theme to "Blue"
(cherry picked from commit 535cc0d81e)
2021-07-05 18:41:17 -04:00
arkon c07cc7f0df Set root project name, remove jcenter for plugin resolution
(cherry picked from commit 5801297d78)
2021-07-05 18:41:06 -04:00
Jobobby04 20d8cf6c10 Update Mangadex 2021-07-05 18:31:30 -04:00
Jobobby04 efba76380a Reader cleanup 2021-07-04 17:14:21 -04:00
Jays2Kings 60f1c6a2b4 Fixed double page layout showing pages from other chapters
(cherry picked from commit 8ac340eff0451e59a1fdfeb3577c38db5eb7da00)
2021-07-04 17:14:20 -04:00
Jobobby04 f9ba8b0072 Fix reader toolbar insets 2021-07-04 14:59:24 -04:00
Jobobby04 2173a83196 Fix E-Hentai browse images being compressed 2021-07-04 14:53:52 -04:00
Jobobby04 ad04fab21a Always show mark as read 2021-07-04 14:49:55 -04:00
Jobobby04 74c94b9879 Small reader fixes 2021-07-04 14:49:41 -04:00
Jobobby04 3bdd508a81 Only show mark as read and mark as unread in library if there is room 2021-07-04 14:00:38 -04:00
Jobobby04 c9438d55e0 Fix words dissapearing 2021-07-03 22:49:12 -04:00
Jobobby04 33c48412be Multiple bugfixes for the reader, includes double page and chapter buttons 2021-07-03 22:37:25 -04:00
Jobobby04 a6cf6ffca8 Reorganize the code in the reader 2021-07-03 20:05:22 -04:00
Jobobby04 7d09c4da0d Use the Main Executor to schedule the EH Updater 2021-07-03 19:29:46 -04:00
arkon b71694fb54 Update to Conductor 3.0.0
(cherry picked from commit 01a1a9ebab)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SourceSearchController.kt
2021-07-03 19:08:00 -04:00
arkon 6daa93fd24 Fix category selected state
Co-authored-by: ivaniskandar <ivaniskandar@users.noreply.github.com>
(cherry picked from commit 438bad9649)
2021-07-03 18:59:27 -04:00
arkon 3ee68f5127 Fix some views being click-through-able
(cherry picked from commit fe3b36caeb)
2021-07-03 18:59:20 -04:00
curche f23b66507f fix link to List of Extensions (#5493)
(cherry picked from commit 83588e14d9)
2021-07-03 18:59:10 -04:00
Ivan Iskandar 30f478ea80 Track search dialog adjustments (#5479)
* Add clear text button to track search dialog text input

* Track search item adjustments

(cherry picked from commit 64b1c9636b)
2021-07-03 18:59:03 -04:00
FourTOne5 c4374240e8 Sort Installed, Update, Untrusted Extenion by Name in Extensions Tab (#5486)
* Update ExtensionPresenter.kt

* Update ExtensionPresenter.kt

* Update ExtensionPresenter.kt

(cherry picked from commit db0c1b2634)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionPresenter.kt
2021-07-03 18:58:50 -04:00
arkon dc6906250d Use current locale when sorting library "alphabetically" (closes #5281)
This _should_ handle things like Chinese that aren't actually alphabetical.

(cherry picked from commit 568c4d8c8e)
2021-07-03 18:57:25 -04:00
arkon e480001585 Update dependencies
(cherry picked from commit d645507eeb)
2021-07-03 18:57:18 -04:00
arkon 3df4389fc4 Update delete history icon (closes #5482)
(cherry picked from commit 3548112ab2)
2021-07-03 18:57:09 -04:00
arkon aa23de77bc Remove en-GB option since we don't actually localize different English locales
(cherry picked from commit 0cb042cd93)

# Conflicts:
#	app/build.gradle.kts
2021-07-03 18:56:53 -04:00
Ivan Iskandar ad2bbd0e3c Merge light and dark themes (#5470)
* Merge AMOLED and regular dark themes

This allows all variants of dark themes to use black backgrounds as a
separate preference.

* Merge light and dark themes

* Fix ReaderSeekBar color on Dark Blue theme

* Color fixes

* Fix Dark Blue bars ripple

* Simplify night mode check

(cherry picked from commit 0eadc028b6)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt
2021-07-03 18:55:12 -04:00
stinky-lizard 0e636d68c4 Imported implementation for updating library by next expected update from Neko (#5436)
* Imported implementation for updating library by next expected update from Neko. This sort uses the last 4 updates for a manga to compute an average time between updates and then extrapolates when the next update should occur.

Currently seems to work perfectly. However, I may have silently messed something up along the way.

All code and algorithms are credited to kyjibo on GitHub. The original commit adding this functionality is here: https://github.com/CarlosEsco/Neko/commit/681003926ae1e07b925155d4e1f43972bbe2b843

* Imported implementation for updating library by next expected update from Neko. This sort uses the last 4 updates for a manga to compute an average time between updates and then extrapolates when the next update should occur.

Currently seems to work perfectly. However, I may have silently messed something up along the way.

All code and algorithms are credited to kyjibo on GitHub. The original commit adding this functionality is here: https://github.com/CarlosEsco/Neko/commit/681003926ae1e07b925155d4e1f43972bbe2b843

* Remove commented-out line from LibraryUpdateRanker

I missed removing this when first committing. The removed line is a holdover from Neko, which requires 7+, but I removed the function that requires this.

(cherry picked from commit 70ed49e478)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/tables/MangaTable.kt
2021-07-03 18:22:38 -04:00
Andreas e59789f777 Change wording for "Per-category display setting" (#5484)
(cherry picked from commit 3c67a36b60)
2021-07-03 18:14:07 -04:00
Soitora a0549b304f Create parity with extension repo issues (#5473)
* [skip ci] Rename bug to issue

Also changes the file naming scheme of the issue forms.

Matches with tachiyomiorg/tachiyomi-extensions now.

* [skip ci] Tweak issue overview

(cherry picked from commit e5621246ec)
2021-07-03 18:13:37 -04:00
Jobobby04 69d762c131 Support WorkManager items in the debug list scheduled jobs option 2021-07-02 17:51:02 -04:00
Jobobby04 e9e3340c08 Convert EH Gallery Updater from a JobService to WorkManager 2021-07-02 17:50:22 -04:00
Jobobby04 0d8af29eeb Fix latest release reference 2021-07-02 17:12:21 -04:00
Jobobby04 60f9391b4e Cleanup 2021-06-29 19:00:34 -04:00
Eugene 56f4b1f224 [Translation]RU (#364)
* [Translation]RU

* more intuitive "zoom out" mode
2021-06-29 00:07:11 -04:00
simakover c123df4637 Add Migrate button marginTop and implement Hide not found manga for mass migration (#372)
* Add Migrate button marginTop and implement Hide not found manga in mass migration

* if else change

* move variable to adapter

* horizontal scroll view for checkboxes in migration_bottom_sheet.xml
2021-06-29 00:06:55 -04:00
Jobobby04 1cf48b3ab7 Update crashlytics 2021-06-29 00:06:12 -04:00
Jobobby04 ee73c0e282 Fix crashing library 2021-06-29 00:05:49 -04:00
Ivan Iskandar b7b1175207 Tracking sheet and search adjustments (#5427)
* Tracking sheet and search visual adjustments

* Remove track item divider

* Add start margin to "add tracking" button

* Fix track search dialog crash when no item chosen

* Show "remove" action only when track item is previously set

* Remove placeholder for total chapters

* Cleanups

* Add track search error/empty result message

* Make track search dialog fullscreen

* Use AutofitRecyclerView for track search dialog

* Fix text input overlapping

* Run track search from IME action instead

* Remove deprecated method

* Reformat

* Set track search error message on the placeholder

* Use payload to notify track search item change

* Fix track search action icon tint color

(cherry picked from commit cb71d44024)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackSearchAdapter.kt
#	app/src/main/res/values/styles.xml
2021-06-28 14:38:36 -04:00
curche 9903a6bde8 Extend library search by adding -<source> option (#5387)
* extend library search to enable -<source> search

library search already allows for <source> search to select manga from a
particular source. Similarly, -<source> allows to search for manga that
aren't from the said source. TachiyomiSy has this feature but it heavily
depends on exh methods

A problem when you directly add a negation check is that although
it will work, the genre search kicks in adds back every manga since
-<source> returns true for all genres of a manga

Thus, the solution I decided on was do source search first, and then
move to genre check when it fails. A perhaps useful addition is that,
now you're able to search like this:
 <genre1>, -<source>, -<genre2>

* make if-else statements more readable

* refactor containsSourceOrGenre() using `when`

* add comment describing the function

* remove lazy

not really required anymore now that containsSourceOrGenre was rewritten
using `when`

(cherry picked from commit 7e3ea9074c)
2021-06-28 14:24:37 -04:00
Ivan Iskandar da0b4bb94a Reader fixes after #5450 (#5465)
* Fix ReaderActivity system bars behavior

* Fix ReaderActivity transition view text color

* Don't change reader navbar color when windowLightNavigationBar is not available

(cherry picked from commit e2cf157857)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
2021-06-28 14:23:47 -04:00
Jobobby04 99042352fb Protect against a random library crash 2021-06-28 01:22:18 -04:00
Jobobby04 a132435967 Fix flashing library 2021-06-28 01:10:01 -04:00
Jobobby04 417c345946 Fix manga info 2021-06-28 00:16:22 -04:00
Jobobby04 c75d0a62b5 Workflow tweaks 2021-06-26 22:41:47 -04:00
Andreas 6f6e6ad326 Sort per category (#5408)
* Add flags for sorting per category

* Add logic to LibrarySettingsSheet

* Add  logic to LibraryPresenter

* Minor tweaks

* Use enum instead of variables

Also deprecates LibrarySort in favour of the new enum classes

* Remove debug log and suppress deprecation

* Convert DisplayMode setting to enum

Also fix bug were adapter would get de-synced with the current per category setting

* Fix migration crashing app due to values being access before migration

(cherry picked from commit 60890147c3)

# Conflicts:
#	app/build.gradle.kts
#	app/src/main/java/eu/kanade/tachiyomi/data/database/models/Category.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceItem.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
2021-06-26 22:41:34 -04:00
Ivan Iskandar 32e7750b7d Match ReaderActivity theme with the rest of the app (#5450)
* Match ReaderActivity theme with the rest of the app

* Fix viewer inset when fullscreen reader is off

* Fix incorrect toolbar color after recreate

* Remove animated inset

* Move isDarkMode to PreferencesHelper

(cherry picked from commit 64c95305b9)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
#	app/src/main/res/layout/reader_activity.xml
2021-06-26 22:38:56 -04:00
arkon d28331c9d2 [skip ci] Update issue closer rules
(cherry picked from commit feddd9285d)
2021-06-26 22:38:56 -04:00
Alessandro Jean 117aaf66a8 [skip ci] Update issue-moderator-action to v1.1 (#5459)
(cherry picked from commit d1b393965f)
2021-06-26 22:38:56 -04:00
Soitora 274d90aa11 [skip ci] Convert issue templates to the new issue forms (#5454)
* [SKIP-CI] Update issue config

* [SKIP-CI] Delete redundant Source Issue

* [SKIP-CI] Convert bug report to an issue form

* [SKIP-CI] Convert feature request to an issue form

(cherry picked from commit e31a39b9d5)

# Conflicts:
#	.github/ISSUE_TEMPLATE/bug_report.md
#	.github/ISSUE_TEMPLATE/feature_request.md
2021-06-26 22:38:55 -04:00
arkon 3544fadc74 [skip ci] Remove explicit SKIP CI workflow logic
GitHub has it built-in now: https://github.blog/changelog/2021-02-08-github-actions-skip-pull-request-and-push-workflows-with-skip-ci/

(cherry picked from commit 98fc028d39)
2021-06-26 22:38:55 -04:00
Soitora 2975acd8db Add favorited badge to browse and search (#5440)
(cherry picked from commit 88fd799a30)
2021-06-26 22:38:55 -04:00
inorichi fe51ad5d4b Update image decoder with better AVIF support
(cherry picked from commit ef937f277e)
2021-06-26 22:38:54 -04:00
Ivan Iskandar a59168f8b6 Fix issues on older API versions and tablets (#5433)
* Fix tablet's navigation rail and toolbar color

* Fix tracking sheet crash on older APIs

* Fix settings crash on older APIs

(cherry picked from commit c3fb5af3fc)
2021-06-26 22:38:54 -04:00
Riztard Lanthorn 6b5ee52dc7 [SKIP CI] fix GithubUpdateChecker url (#5434)
(cherry picked from commit 859e8deb02)
2021-06-26 22:38:54 -04:00
Ivan Iskandar f61bbfa77a More themes cleanup (#5410), remove AMOLED Blue
* More themes cleanup

* Tweak some things

* Fix 'Clear History' icon

* Split out ripple colored to its own drawable

* Tidy up things

* Unify background dim amount

* Use primaryColor for Account login button

* More colored ripples

* use colorOnPrimary for selected comfortable library item title

Co-authored-by: Soitora <simon.mattila@protonmail.com>
(cherry picked from commit 932c92412c)

# Conflicts:
#	app/src/main/res/layout-sw720dp/manga_info_header.xml
#	app/src/main/res/layout/manga_info_header.xml
#	app/src/main/res/layout/reader_activity.xml
#	app/src/main/res/menu/library_selection.xml
#	app/src/main/res/menu/reader.xml
#	app/src/main/res/values/colors.xml
#	app/src/main/res/values/dimens.xml
2021-06-26 22:38:53 -04:00
Riztard Lanthorn 6283754ce5 add start download now (#5386)
* add start download now

download now for selected chapter
from j2k

Co-Authored-By: Jays2Kings <jays@outlook.com>

* change string to action

* move to bottom

* oopsie

Co-authored-by: Jays2Kings <jays@outlook.com>
(cherry picked from commit 05771ddf6d)
2021-06-26 22:38:52 -04:00
Hunter Nickel ed78bca33e Add AlertDialog styles to Reader themes (#5426)
(cherry picked from commit 848d387ec4)
2021-06-26 22:38:52 -04:00
jmir1 9e38b5231c Fix crash when opening the MangaController from... (#5419)
...the browse search
null safe cast to TextView because when searching for manga in a source,
the toolbar has no children and
find() returns null.

(cherry picked from commit ac6b4235b9)
2021-06-26 22:38:52 -04:00
Ivan Iskandar 4706493057 Fix incorrect toolbar text color after theme change (#5388)
(cherry picked from commit ab73e98075)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
2021-06-26 22:38:51 -04:00
Soitora 18a76c6bc2 Move "Delete sweep" out from overflow (#5392)
Places it as its own icon, having an overflow with only one item doesn't make much sense when that's not the behavior in other parts of the app.

(cherry picked from commit aecdd04e04)
2021-06-26 22:38:51 -04:00
Jobobby04 104e200b4a Favorites sync show currently processing title after 5 seconds in case of issues 2021-06-26 22:38:50 -04:00
Jobobby04 9af351e0dd Cleanup 2021-06-26 22:38:50 -04:00
arkon 1ddfe956a7 Downgrade WorkManager
Related to #5364

(cherry picked from commit e5cdf74587)
2021-06-26 22:38:50 -04:00
Sam-Oak 40efaeafe1 tweak the PT-BR translation (#363) 2021-06-17 09:40:05 -04:00
Jobobby04 2b4cdfaee4 Support autofill for tracker logins 2021-06-13 20:00:53 -04:00
Jobobby04 e2324df0cc Use the same thread for db operations in places where trans are possible 2021-06-13 19:56:17 -04:00
Jobobby04 447ddfd8d5 Support autofill in source login dialog 2021-06-13 16:15:04 -04:00
Jobobby04 96a932264b Use the clear selection function to destroy the action mode 2021-06-13 14:41:14 -04:00
arkon d04161cc9e Surface exceptions when fetching pages properly (fixes #5377)
(cherry picked from commit 8d25ce7323)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt
2021-06-13 14:36:55 -04:00
Hunter Nickel 03c45f676a Added text to category changing dialog when shown with no categories (#5345)
* Added text to ChangeMangaCategoriesDialog if invoked with empty category list

* Change dialog text, add negative button, and change positive button to open CategoryController

* Tiny bit of code cleanup and reorganizing

(cherry picked from commit 8deca3b63a)
2021-06-13 14:36:04 -04:00
Zakhar Timoshenko 56fa39387f Added "Yotsuba" theme (#5290)
(cherry picked from commit 9b967177c5)
2021-06-13 14:35:40 -04:00
Soitora 60704ad3a7 Improvements to the new library item selectors (#5379)
* Increase card selector radius

* Add themed overlay to library selector

(cherry picked from commit 4dfb3cc972)
2021-06-13 14:35:29 -04:00
Jobobby04 e3fd17f550 Fix Mangadex random 2021-06-12 20:00:28 -04:00
Jobobby04 1dcf49200a Saved searches tweaks 2021-06-11 19:51:34 -04:00
Jobobby04 d5638c6204 Cleanup recs 2021-06-10 17:20:54 -04:00
Jobobby04 bf97dce150 Update firebase 2021-06-10 17:20:41 -04:00
Jobobby04 9e80f47e9f Help with favorites sync db locking 2021-06-10 17:20:29 -04:00
Ivan Iskandar 963b85f756 Add background to draggable items (#5353)
(cherry picked from commit 73e5e9ecd9)
2021-06-10 16:44:58 -04:00
Soitora fc141cb92a Fix black icon for small notifications on EMUI (#5350)
* Set notification icon fillColor to Android white

Closes #5340

* Remove '_black' suffix from the glasses icon drawable

(cherry picked from commit 653b7ffcd0)

# Conflicts:
#	app/src/main/res/drawable/ic_tachi.xml
2021-06-10 16:44:49 -04:00
jmir1 0bdddb365f Fix library settings sheet causing app to crash... (#5354)
...when the category list is empty

(cherry picked from commit 8791b72cb1)
2021-06-10 16:43:04 -04:00
arkon 0521c362c9 Revert "Set background job expedited policies"
This reverts commit c69420373a.

Caused crashes in TachiyomiSY for some reason. Will have to redo this once we target Android 12.

(cherry picked from commit 07de367476)
2021-06-10 16:42:53 -04:00
Ivan Iskandar 8cc51c7f71 Fix download status not updated properly after starting batch download (#5348)
(cherry picked from commit 31d96c2bf0)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
2021-06-10 16:42:43 -04:00
Ivan Iskandar eafce1ee5d Enable secure screen when incognito mode is enabled (#5339)
* Enable secure screen when incognito mode is enabled

* Fix incognito banner not showing up after configuration changes

(cherry picked from commit fb8aafb69f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/security/SecureActivityDelegate.kt
2021-06-10 16:41:38 -04:00
Soitora 341543da24 Add ripple to history items (#5341)
- Replaces margin with padding.
- Adds the drawable ripple background.
- Changes height to match the padding so it doesn't look odd.

(cherry picked from commit 3d58b78062)
2021-06-10 16:40:38 -04:00
arkon 65afc99ead Show global update error notifications by default
(cherry picked from commit ec5e6958ef)
2021-06-10 16:40:26 -04:00
arkon c301def4bc Fix crash on source page load error
(cherry picked from commit 71bd5fe367)
2021-06-10 16:40:15 -04:00
arkon a33a7c0844 Draw tablet manga info column under navbar (fixes #5323)
(cherry picked from commit d43255e688)
2021-06-10 16:39:27 -04:00
Ivan Iskandar 710196d514 Coil: Caching adjustments (#5311)
* Coil: Enable disk cache for source items

* MangaCoverFetcher: Let Coil's OkHttp client handle caching for non-library cover

(cherry picked from commit 3527dedc99)
2021-06-10 16:39:14 -04:00
arkon 216065fb38 Use coroutine job for fetching next source page
(cherry picked from commit e6f3cd03bb)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt
2021-06-10 16:36:14 -04:00
arkon 708c4b6905 Add shortcut to tracking guide on website
(cherry picked from commit a1e31549a2)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrationSourcesController.kt
2021-06-10 16:17:48 -04:00
arkon 3536c359f3 Address some build warnings
(cherry picked from commit 71d225c562)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchController.kt
2021-06-10 16:16:12 -04:00
arkon a3dbf6ff24 Don't expand source filter sheet on show (closes #5253)
(cherry picked from commit 7c23212850)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceFilterSheet.kt
2021-06-10 16:15:38 -04:00
Hunter Nickel 13235f3a37 Add behavior for modifying reader buttons depending on prev/next chapters (#5305)
(cherry picked from commit fdf178d4df)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
2021-06-05 16:09:45 -04:00
arkon 74636f4b1a Use smallest width instead of width for alt layouts
(cherry picked from commit 04ebca8413)

# Conflicts:
#	app/src/main/res/layout-sw720dp/manga_info_header.xml
2021-06-05 16:08:59 -04:00
arkon 9275d9ab55 Set orientation icon correctly when opening reader
(cherry picked from commit edeee54fb2)
2021-06-05 16:08:20 -04:00
Andreas 89249c9895 Added category-wise display setting (#5232)
* Added category-wise display setting

Co-authored-by: Rogavactive <30288842+Rogavactive@users.noreply.github.com>

* Use flag instead of preference

* Remove database call in LibraryItem

* Remove unnecessary code

Co-authored-by: Rogavactive <30288842+Rogavactive@users.noreply.github.com>
(cherry picked from commit a906e9b302)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/database/models/Category.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt
2021-06-05 16:07:57 -04:00
arkon 9b85b009a4 Fix image type build error
(cherry picked from commit fff72b61df)
2021-06-05 15:40:33 -04:00
arkon e017617612 Handle HEIF images (partly addresses #4756)
(cherry picked from commit 74381ef59e)
2021-06-05 15:40:26 -04:00
Jobobby04 38f2a93c0f Use PageHandler for page requests 2021-06-05 15:24:02 -04:00
Carlos 143dfc6ad2 pass auth header to md@home request when logged in
(cherry picked from commit c63bf955b308cbb67fcdda884eff76eaec901898)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/online/MangaDex.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/PageHandler.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt
2021-06-05 14:36:58 -04:00
Carlos d82967ea3d switch to dex covers
(cherry picked from commit 28d83509dadb0ddaca2e13e98f5e5f6e3df2d2a7)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/online/MangaDexCache.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/ApiMangaParser.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/FollowsHandler.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/PopularHandler.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/SearchHandler.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/SimilarHandler.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsPresenter.kt
#	app/src/main/java/exh/md/utils/MdUtil.kt
2021-06-05 14:31:51 -04:00
Jobobby04 eab7571feb Cleanup 2021-06-05 13:58:30 -04:00
Hunter Nickel 09eab48b1b Add check for backstack size before pushing DownloadController (#5312)
(cherry picked from commit 64f95af3e5)
2021-06-04 20:43:25 -04:00
jobobby04 9196a24eb1 Legacy backup conversion to Kotlin Serialization (#5282)
* Legacy backup conversion to Kotlin Serialization

* Fix BackupTest compiling

(cherry picked from commit 597cec3064)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/models/Backup.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/serializer/MangaTypeAdapter.kt
2021-06-04 19:27:19 -04:00
arkon 4f9eb19ead Update tablet UI
- Only used when width is >= 720dp instead of 600dp (typically 10" tablets)
- Fix fastscroll in manga view (fixes #5267)

(cherry picked from commit b03ebc1fa4)

# Conflicts:
#	app/src/main/res/layout-w720dp/manga_controller.xml
2021-06-04 19:09:21 -04:00
Jobobby04 3d33d50c63 Cleanup some constructors 2021-06-04 19:07:30 -04:00
Eugene 9e17ecbd4a Rus new strings (+fix original) (#348)
* Rus new strings and fix original in meaning

* Title Case

* from j2k
2021-06-04 18:12:12 -04:00
Sam-Oak a535d22f78 update the PT-BR translation (#347)
* update brazilian portuguese translation

* continue brazilian portuguese translation update

* final brazilian portuguese translation update

hopefully
2021-06-04 18:11:42 -04:00
Eugene 826602afb6 Fix black/invisible nav in blue theme (#350) 2021-06-04 18:11:27 -04:00
Jobobby04 b35aa30ea7 Address some lints 2021-06-03 16:28:38 -04:00
arkon 330b7990fe Allow center aligned side nav icons (closes #5177)
(cherry picked from commit 6c53bb4d51)
2021-06-03 14:01:13 -04:00
arkon 84330af417 Address some build warnings
(cherry picked from commit fb7a458747)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt
2021-06-03 14:01:05 -04:00
arkon e0945e4409 Support AVIF and HEIF images (closes #4756)
Co-authored-by: inorichi <inorichi@users.noreply.github.com>
(cherry picked from commit db25a9ae4f)
2021-06-03 14:00:08 -04:00
arkon ac8e53b9a7 Set background job expedited policies
(cherry picked from commit c69420373a)
2021-06-03 13:59:44 -04:00
arkon bdc9e43e9e Update dependencies
(cherry picked from commit 2b8347f899)
2021-06-03 13:59:27 -04:00
arkon 88102b9705 Add share and save cover actions (closes #3011)
(cherry picked from commit 281a3911f6)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt
2021-06-03 13:59:08 -04:00
Jobobby04 6d7e8cdcb9 Comment out more 2021-06-03 01:07:09 -04:00
Jobobby04 359ccdd052 Fix refactor for show history and updates button 2021-06-03 01:06:55 -04:00
Jobobby04 57ca396b46 Load chapters in the dialog instantly 2021-06-02 21:21:38 -04:00
Jobobby04 78d2881b4b Remove TachiEH Android 7 SSL Workaround, no idea why it was used 2021-06-02 21:04:51 -04:00
Jobobby04 cafce0ed5f Old saved searches can load now, but now toast on click 2021-06-02 21:04:06 -04:00
Jobobby04 3adde57db9 Use the same chapter sort that the chapters use in the reader dialog 2021-06-02 17:46:33 -04:00
Jobobby04 503ecb8076 Rename the reader chapter sheet to a dialog 2021-06-02 17:39:25 -04:00
Jobobby04 01d6dbba86 Add cancel button to reader chapters dialog 2021-06-02 17:34:08 -04:00
Jobobby04 b0bcad861f Open merged manga in webview properly 2021-06-02 17:17:11 -04:00
Jobobby04 d70a8848ec Fix merged manga delete after read 2021-06-02 16:53:00 -04:00
Jobobby04 c8426e71eb When browsing on Exh notify if the user has a bad igneous cookie 2021-06-02 16:10:26 -04:00
OncePunchedMan b523e47102 Fix label visibility for tablet ui (#343)
* fix label visibility for tablet ui

* change to less code
2021-06-02 15:44:11 -04:00
Jobobby04 57dde4c922 Refactor show history and updates buttons 2021-06-02 14:12:57 -04:00
Jobobby04 34c16015e5 Update kotlin serialization to 1.2.1 2021-06-02 14:05:15 -04:00
Jobobby04 8387492a9b Add biometric lock days, fix biometric time range 2021-06-02 13:39:04 -04:00
Jobobby04 114ba42af7 Fix duel page spread not marking chapters read 2021-06-02 00:11:55 -04:00
Jobobby04 aeaf52cb58 Handle more deprecated items 2021-06-02 00:10:36 -04:00
OncePunchedMan 1e55a3f21a add AMOLED prefix to theme name (#5263)
(cherry picked from commit 9b77dd9a2b)
2021-06-01 21:52:35 -04:00
Soitora 4fdb19d002 Add better library item selectors (#5240)
* Add better library item selectors

Inspired by the J2K method of library item selection.

* Tweak theme selection colors

It was missing for Hot Pink and Midnight Dusk.

The selector color is 75% alpha of the color accent, this looked fitting for all themes.

(cherry picked from commit 88d9ffe92e)
2021-06-01 21:09:18 -04:00
Jobobby04 d30c9f7120 Address some deprecation warnings 2021-06-01 21:09:03 -04:00
arkon 9697bffc5e Consolidate some of the app update classes
We only use GitHub for all update checks, so the abstraction isn't useful.

(cherry picked from commit 5113c78ab6)
2021-06-01 20:52:56 -04:00
arkon 65249a4ee7 Address some Kotlin language warnings
(cherry picked from commit 3854995ef2)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceFilterController.kt
#	app/src/main/java/eu/kanade/tachiyomi/util/chapter/ChapterRecognition.kt
2021-06-01 20:52:49 -04:00
arkon d5b72c3d3a Only show automatically refresh trackers setting if logged in to some trackers
(cherry picked from commit 36e14b951a)
2021-06-01 20:51:36 -04:00
Jobobby04 86bd55268f Revert "Temporarily disable Double Page Spread"
This reverts commit 02601aa32a.
2021-06-01 20:49:43 -04:00
Jobobby04 8563342d0f Revert "Temporarily disable Mangadex delegation"
This reverts commit 60e520e37e.
2021-06-01 20:49:26 -04:00
Jobobby04 d057b61158 Revert "Temporarily hide Komga tracker"
This reverts commit 3fb4b565fa.
2021-06-01 20:49:21 -04:00
928 changed files with 57412 additions and 42673 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
I acknowledge that:
- I have updated:
- To the latest version of the app (stable is v1.7.0)
- To the latest version of the app (stable is v1.8.1)
- All extensions
- I have tried the troubleshooting guide: https://tachiyomi.org/help/guides/troubleshooting-problems/
- If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions
-44
View File
@@ -1,44 +0,0 @@
---
name: "🐞 Bug report"
about: Report a bug
title: "[Bug] <Write short description here>"
labels: "bug"
---
**PLEASE READ THIS**
I acknowledge that:
- I have updated:
- To the latest version of the app (stable is v1.7.0)
- All extensions
- I have tried the troubleshooting guide: https://tachiyomi.org/help/guides/troubleshooting-problems/
- If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions
- I have searched the existing issues and this is new ticket **NOT** a duplicate or related to another open issue
- I will fill out the title and the information in this template
Note that the issue will be automatically closed if you do not fill out the title or requested information.
**DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT**
---
## Device information
* Tachiyomi version: ?
* Android version: ?
* Device: ?
## Steps to reproduce
1. First step
2. Second step
### Expected behavior
This should happen.
### Actual behavior
This happened instead.
## Other details
Additional details and attachments.
If you're experiencing crashes, share the crash logs from More → Settings → Advanced → Dump crash logs.
+8 -5
View File
@@ -1,8 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: Tachiyomi help website
- name: ⚠️ Extension/source issue
url: https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose
about: Issues and requests for extensions and sources should be opened in the tachiyomi-extensions repository instead
- name: 📦 Tachiyomi extensions
url: https://tachiyomi.org/extensions
about: List of all available extensions with download links
- name: 🖥️ Tachiyomi website
url: https://tachiyomi.org/help/
about: Common questions are answered here.
- name: Tachiyomi extensions GitHub repository
url: https://github.com/tachiyomiorg/tachiyomi-extensions
about: Issues about an extension/source/catalogue should be opened here instead.
about: Guides, troubleshooting, and answers to common questions
-29
View File
@@ -1,29 +0,0 @@
---
name: "🌟 Feature request"
about: Suggest a feature to improve Tachiyomi
title: "[Feature Request] <Write short description here>"
labels: "feature"
---
**PLEASE READ THIS**
I acknowledge that:
- I have updated:
- To the latest version of the app (stable is v1.7.0)
- All extensions
- If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions
- I have searched the existing issues and this is new ticket **NOT** a duplicate or related to another open issue
- I will fill out the title and the information in this template
Note that the issue will be automatically closed if you do not fill out the title or requested information.
**DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT**
---
## Why/User Benefit/User Problem
(explain why this feature should be added)
## What/Requirements
(explain how this feature would behave)
+106
View File
@@ -0,0 +1,106 @@
name: 🐞 Issue report
description: Report an issue in Tachiyomi
labels: [Bug]
body:
- type: textarea
id: reproduce-steps
attributes:
label: Steps to reproduce
description: Provide an example of the issue.
placeholder: |
Example:
1. First step
2. Second step
3. Issue here
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: Explain what you should expect to happen.
placeholder: |
Example:
"This should happen..."
validations:
required: true
- type: textarea
id: actual-behavior
attributes:
label: Actual behavior
description: Explain what actually happens.
placeholder: |
Example:
"This happened instead..."
validations:
required: true
- type: textarea
id: crash-logs
attributes:
label: Crash logs
description: |
If you're experiencing crashes, share the crash logs from **More → Settings → Advanced** then press **Dump crash logs**.
placeholder: |
You can paste the crash logs in pure text or upload it as an attachment.
- type: input
id: tachiyomi-version
attributes:
label: Tachiyomi version
description: You can find your Tachiyomi version in **More → About**.
placeholder: |
Example: "1.8.1"
validations:
required: true
- type: input
id: android-version
attributes:
label: Android version
description: You can find this somewhere in your Android settings.
placeholder: |
Example: "Android 11"
validations:
required: true
- type: input
id: device
attributes:
label: Device
description: List your device and model.
placeholder: |
Example: "Google Pixel 5"
validations:
required: true
- type: textarea
id: other-details
attributes:
label: Other details
placeholder: |
Additional details and attachments.
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Read this carefully, we will close and ignore your issue if you skimmed through this.
options:
- label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open issue.
required: true
- label: I have written a short but informative title.
required: true
- label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose).
required: true
- label: I have tried the [troubleshooting guide](https://tachiyomi.org/help/guides/troubleshooting/).
required: true
- label: I have updated the app to version **[1.8.1](https://github.com/jobobby04/tachiyomisy/releases/latest)**.
required: true
- label: I have updated all installed extensions.
required: true
- label: I will fill out all of the requested information in this form.
required: true
@@ -0,0 +1,39 @@
name: ⭐ Feature request
description: Suggest a feature to improve Tachiyomi
labels: [Feature request]
body:
- type: textarea
id: feature-description
attributes:
label: Describe your suggested feature
description: How can Tachiyomi be improved?
placeholder: |
Example:
"It should work like this..."
validations:
required: true
- type: textarea
id: other-details
attributes:
label: Other details
placeholder: |
Additional details and attachments.
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Read this carefully, we will close and ignore your issue if you skimmed through this.
options:
- label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open issue.
required: true
- label: I have written a short but informative title.
required: true
- label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose).
required: true
- label: I have updated the app to version **[1.8.1](https://github.com/jobobby04/tachiyomisy/releases/latest)**.
required: true
- label: I will fill out all of the requested information in this form.
required: true
-8
View File
@@ -1,8 +0,0 @@
---
name: "Extension/source/catalogue issue"
about: "Do not open an issue here. See https://github.com/tachiyomiorg/tachiyomi-extensions"
title: "THIS ISSUE IS IN THE WRONG REPO; SEE https://github.com/tachiyomiorg/tachiyomi-extensions"
labels: "catalog, invalid"
---
DO NOT OPEN AN ISSUE IN THIS REPO. SEE https://github.com/tachiyomiorg/tachiyomi-extensions
+12
View File
@@ -0,0 +1,12 @@
<!--
Please include a summary of the change and which issue is fixed.
Also make sure you've tested your code and also done a self-review of it.
Don't forget to check all base themes and tablet mode for relevant changes.
If your changes are visual, please provide images below:
### Images
| Image 1 | Image 2 |
| ------- | ------- |
| ![](https://github.githubassets.com/images/modules/logos_page/Octocat.png) | ![](https://github.githubassets.com/images/modules/logos_page/Octocat.png) |
-->
@@ -20,7 +20,6 @@ jobs:
preview:
name: Build app preview
needs: check_wrapper
if: "!startsWith(github.event.head_commit.message, '[SKIP CI]')"
runs-on: ubuntu-latest
steps:
@@ -20,7 +20,6 @@ jobs:
build:
name: Build app
needs: check_wrapper
if: "!startsWith(github.event.head_commit.message, '[SKIP CI]')"
runs-on: ubuntu-latest
steps:
@@ -32,10 +31,10 @@ jobs:
- name: Clone repo
uses: actions/checkout@v2
- name: Set up JDK 1.8
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 1.8
java-version: 11
- name: Copy CI gradle.properties
run: |
@@ -53,12 +52,9 @@ jobs:
write-mode: overwrite # optional, default is preserve
- name: Build app
uses: eskatos/gradle-command-action@v1
uses: gradle/gradle-command-action@v2
with:
arguments: assembleRelease --stacktrace
wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true
arguments: assembleStandardRelease --stacktrace
- name: Sign APK
uses: r0adkll/sign-android-release@v1
+5 -8
View File
@@ -16,7 +16,6 @@ jobs:
build:
name: Build app
needs: check_wrapper
if: "!startsWith(github.event.head_commit.message, '[SKIP CI]')"
runs-on: ubuntu-latest
steps:
@@ -28,10 +27,10 @@ jobs:
- name: Clone repo
uses: actions/checkout@v2
- name: Set up JDK 1.8
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 1.8
java-version: 11
- name: Copy CI gradle.properties
run: |
@@ -39,12 +38,10 @@ jobs:
cp .github/runner-files/ci-gradle.properties ~/.gradle/gradle.properties
- name: Build app
uses: eskatos/gradle-command-action@v1
uses: gradle/gradle-command-action@v2
with:
arguments: assembleStandardDebug
wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true
arguments: assembleDevDebug
- name: Upload APK
uses: actions/upload-artifact@v2
with:
+6 -10
View File
@@ -13,16 +13,6 @@ jobs:
repo-token: ${{ secrets.GITHUB_TOKEN }}
rules: |
[
{
"type": "title",
"regex": ".*THIS ISSUE IS IN THE WRONG REPO.*",
"message": "It was not opened in the correct repo, as the template mentioned."
},
{
"type": "title",
"regex": ".*<Write short description here>*",
"message": "The description in the title was not filled out."
},
{
"type": "body",
"regex": ".*DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT.*",
@@ -32,5 +22,11 @@ jobs:
"type": "body",
"regex": ".*\\* (Tachiyomi version|Android version|Device): \\?.*",
"message": "Requested information in the template was not filled out."
},
{
"type": "both",
"regex": "^(?!.*myanimelist.*).*(aniyomi|anime).*$",
"ignoreCase": true,
"message": "Tachiyomi does not support anime, and has no plans to support anime. In addition Tachiyomi is not affiliated with Aniyomi https://github.com/jmir1/aniyomi"
}
]
+1 -1
View File
@@ -9,6 +9,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Moderate issues
uses: tachiyomiorg/issue-moderator-action@v1.0
uses: tachiyomiorg/issue-moderator-action@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
+4 -4
View File
@@ -3,7 +3,7 @@ name: Lock threads
on:
# Daily
schedule:
- cron: '0 * * * *'
- cron: '0 0 * * *'
# Manual trigger
workflow_dispatch:
inputs:
@@ -12,8 +12,8 @@ jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v2
- uses: dessant/lock-threads@v3
with:
github-token: ${{ github.token }}
issue-lock-inactive-days: '2'
pr-lock-inactive-days: '2'
issue-inactive-days: '2'
pr-inactive-days: '2'
+99 -49
View File
@@ -1,76 +1,126 @@
# Code of Conduct
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
Examples of behavior that contributes to a positive environment for our
community include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior by participants include:
Examples of unacceptable behavior include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
professional setting
## Our Responsibilities
## Enforcement Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Community moderators are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
Community moderators have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at the Tachiyomi [Discord server](https://discord.gg/tachiyomi). All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
reported to the community moderators responsible for enforcement at
the [Tachiyomi Discord server](https://discord.gg/tachiyomi).
All complaints will be reviewed and investigated promptly and fairly.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
All community moderators are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community moderators will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community moderators, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/),
version 2.1, available at
[v2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html).
[homepage]: https://www.contributor-covenant.org
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
For answers to common questions about this code of conduct, see the FAQ at
[FAQ](https://www.contributor-covenant.org/faq). Translations are available
at [translations](https://www.contributor-covenant.org/translations).
+2 -1
View File
@@ -10,6 +10,7 @@ Thanks for your interest in contributing to Tachiyomi!
Pull requests are welcome!
If you're interested in taking on [an open issue](https://github.com/tachiyomiorg/tachiyomi/issues), please comment on it so others are aware.
You do not need to ask for permission nor an assignment.
# Translations
@@ -26,7 +27,7 @@ When creating a fork, remember to:
- To avoid confusion with the main app:
- Change the app name
- Change the app icon
- Change or disable the [app update checker](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubUpdateChecker.kt)
- Change or disable the [app update checker](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/src/main/java/eu/kanade/tachiyomi/data/updater/GithubUpdateChecker.kt)
- To avoid installation conflicts:
- Change the `applicationId` in [`build.gradle.kts`](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/build.gradle.kts)
- To avoid having your data polluting the main app's analytics and crash report services:
+4 -5
View File
@@ -11,10 +11,10 @@ Tachiyomi is a free and open source manga reader for Android 6.0 and above. This
## Features
Features of Tachiyomi(original) include:
* Online reading from [a variety of sources](https://github.com/tachiyomiorg/tachiyomi-extensions)
* Local reading of downloaded manga
* Online reading from a variety of sources
* Local reading of downloaded content
* A configurable reader with multiple viewers, reading directions and other settings.
* [MyAnimeList](https://myanimelist.net/), [AniList](https://anilist.co/), [Kitsu](https://kitsu.io/), [Shikimori](https://shikimori.one), and [Bangumi](https://bgm.tv/) support
* Tracker support: [MyAnimeList](https://myanimelist.net/), [AniList](https://anilist.co/), [Kitsu](https://kitsu.io/), [Shikimori](https://shikimori.one), and [Bangumi](https://bgm.tv/)
* Categories to organize your library
* Light and dark themes
* Schedule updating your library for new chapters
@@ -84,13 +84,12 @@ Please make sure to read the full guidelines. Your issue may be closed without w
<details><summary>Bugs</summary>
* Include version (More > About > Version)
* Include version (More About Version)
* If not latest, try updating, it may have already been solved
* Preview version is equal to the number of commits as seen in the main page
* Include steps to reproduce (if not obvious from description)
* Include screenshot (if needed)
* If it could be device-dependent, try reproducing on another device (if possible)
* For large logs use http://pastebin.com/ (or similar)
* Don't group unrelated requests into one issue
DO: https://github.com/tachiyomiorg/tachiyomi/issues/24 https://github.com/tachiyomiorg/tachiyomi/issues/71
+103 -110
View File
@@ -11,9 +11,6 @@ plugins {
kotlin("plugin.parcelize")
kotlin("plugin.serialization")
id("com.github.zellius.shortcut-helper")
// Realm (EH)
kotlin("kapt")
id("realm-android")
}
if (!gradle.startParameter.taskRequests.toString().contains("Debug")) {
@@ -25,32 +22,25 @@ if (!gradle.startParameter.taskRequests.toString().contains("Debug")) {
shortcutHelper.setFilePath("./shortcuts.xml")
android {
compileSdkVersion(AndroidConfig.compileSdk)
buildToolsVersion(AndroidConfig.buildTools)
compileSdk = AndroidConfig.compileSdk
ndkVersion = AndroidConfig.ndk
defaultConfig {
applicationId = "eu.kanade.tachiyomi.sy"
minSdkVersion(AndroidConfig.minSdk)
targetSdkVersion(AndroidConfig.targetSdk)
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
versionCode = 19
versionName = "1.7.0"
minSdk = AndroidConfig.minSdk
targetSdk = AndroidConfig.targetSdk
versionCode = 26
versionName = "1.8.1"
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"")
buildConfigField("String", "BUILD_TIME", "\"${getBuildTime()}\"")
buildConfigField("boolean", "INCLUDE_UPDATER", "false")
multiDexEnabled = true
ndk {
abiFilters += setOf("armeabi-v7a", "arm64-v8a", "x86")
}
}
buildFeatures {
viewBinding = true
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
@@ -71,7 +61,7 @@ android {
}
}
flavorDimensions("default")
flavorDimensions += "default"
productFlavors {
create("standard") {
@@ -82,31 +72,41 @@ android {
dimension = "default"
}
create("dev") {
resConfigs("en", "xxhdpi")
resourceConfigurations.addAll(listOf("en", "xxhdpi"))
dimension = "default"
}
}
packagingOptions {
exclude("META-INF/DEPENDENCIES")
exclude("LICENSE.txt")
exclude("META-INF/LICENSE")
exclude("META-INF/LICENSE.txt")
exclude("META-INF/NOTICE")
exclude("META-INF/*.kotlin_module")
// Compatibility for two RxJava versions (EXH)
exclude("META-INF/rxjava.properties")
resources.excludes.addAll(listOf(
"META-INF/DEPENDENCIES",
"LICENSE.txt",
"META-INF/LICENSE",
"META-INF/LICENSE.txt",
"META-INF/README.md",
"META-INF/NOTICE",
"META-INF/*.kotlin_module",
"META-INF/*.version",
))
}
dependenciesInfo {
includeInApk = false
}
lintOptions {
disable("MissingTranslation", "ExtraTranslation")
isAbortOnError = false
isCheckReleaseBuilds = false
buildFeatures {
viewBinding = true
// Disable some unused things
aidl = false
renderScript = false
shaders = false
}
lint {
disable.addAll(listOf("MissingTranslation", "ExtraTranslation"))
abortOnError = false
checkReleaseBuilds = false
}
compileOptions {
@@ -120,78 +120,78 @@ android {
}
dependencies {
implementation(kotlin("reflect", version = BuildPluginsVersion.KOTLIN))
val coroutinesVersion = "1.6.0"
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion")
// Source models and interfaces from Tachiyomi 1.x
implementation("org.tachiyomi:source-api:1.1")
// AndroidX libraries
implementation("androidx.annotation:annotation:1.3.0-alpha01")
implementation("androidx.appcompat:appcompat:1.4.0-alpha01")
implementation("androidx.biometric:biometric-ktx:1.2.0-alpha03")
implementation("androidx.browser:browser:1.3.0")
implementation("androidx.cardview:cardview:1.0.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.0-beta02")
implementation("androidx.coordinatorlayout:coordinatorlayout:1.1.0")
implementation("androidx.core:core-ktx:1.6.0-beta01")
implementation("androidx.multidex:multidex:2.0.1")
implementation("androidx.preference:preference-ktx:1.1.1")
implementation("androidx.recyclerview:recyclerview:1.2.0")
implementation("androidx.annotation:annotation:1.4.0-alpha01")
implementation("androidx.appcompat:appcompat:1.4.1")
implementation("androidx.biometric:biometric-ktx:1.2.0-alpha04")
implementation("androidx.browser:browser:1.4.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.3")
implementation("androidx.coordinatorlayout:coordinatorlayout:1.2.0")
implementation("androidx.core:core-ktx:1.8.0-alpha02")
implementation("androidx.core:core-splashscreen:1.0.0-alpha02")
implementation("androidx.recyclerview:recyclerview:1.3.0-alpha01")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01")
implementation("androidx.viewpager:viewpager:1.1.0-alpha01")
val lifecycleVersion = "2.4.0-alpha01"
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion")
val lifecycleVersion = "2.4.0"
implementation("androidx.lifecycle:lifecycle-common:$lifecycleVersion")
implementation("androidx.lifecycle:lifecycle-process:$lifecycleVersion")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion")
// Job scheduling
implementation("androidx.work:work-runtime-ktx:2.7.0-alpha03")
implementation("androidx.work:work-runtime-ktx:2.6.0")
// UI library
implementation("com.google.android.material:material:1.4.0-beta01")
"standardImplementation"("com.google.firebase:firebase-core:19.0.0")
// ReactiveX
// RX
implementation("io.reactivex:rxandroid:1.2.1")
implementation("io.reactivex:rxjava:1.3.8")
implementation("com.jakewharton.rxrelay:rxrelay:1.2.0")
implementation("com.github.pwittchen:reactivenetwork:0.13.0")
implementation("ru.beryukhov:flowreactivenetwork:1.0.4")
// Network client
val okhttpVersion = "4.9.1"
implementation("com.squareup.okhttp3:okhttp:$okhttpVersion")
implementation("com.squareup.okhttp3:logging-interceptor:$okhttpVersion")
implementation("com.squareup.okhttp3:okhttp-dnsoverhttps:$okhttpVersion")
implementation("com.squareup.okio:okio:2.10.0")
implementation("com.squareup.okio:okio:3.0.0")
// TLS 1.3 support for Android < 10
implementation("org.conscrypt:conscrypt-android:2.5.1")
implementation("org.conscrypt:conscrypt-android:2.5.2")
// JSON
val kotlinSerializationVersion = "1.1.0"
// Data serialization (JSON, protobuf)
val kotlinSerializationVersion = "1.3.2"
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinSerializationVersion")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-protobuf:$kotlinSerializationVersion")
implementation("com.google.code.gson:gson:2.8.6")
implementation("com.github.salomonbrys.kotson:kotson:2.5.0")
// JavaScript engine
implementation("com.squareup.duktape:duktape-android:1.3.0")
implementation("app.cash.quickjs:quickjs-android:0.9.2")
// TODO: remove Duktape once all extensions are using QuickJS
implementation("com.squareup.duktape:duktape-android:1.4.0")
// HTML parser
implementation("org.jsoup:jsoup:1.14.3")
// Disk
implementation("com.jakewharton:disklrucache:2.0.2")
implementation("com.github.tachiyomiorg:unifile:17bec43")
implementation("com.github.junrar:junrar:7.4.0")
// HTML parser
implementation("org.jsoup:jsoup:1.13.1")
// Database
implementation("androidx.sqlite:sqlite-ktx:2.1.0")
implementation("androidx.sqlite:sqlite-ktx:2.2.0")
implementation("com.github.inorichi.storio:storio-common:8be19de@aar")
implementation("com.github.inorichi.storio:storio-sqlite:8be19de@aar")
implementation("com.github.requery:sqlite-android:3.35.5")
implementation("com.github.requery:sqlite-android:3.36.0")
// Preferences
implementation("androidx.preference:preference-ktx:1.2.0-rc01")
implementation("com.github.tfcporciuncula.flow-preferences:flow-preferences:1.4.0")
// Model View Presenter
@@ -202,57 +202,59 @@ dependencies {
// Dependency injection
implementation("com.github.inorichi.injekt:injekt-core:65b0440")
// Image library
val coilVersion = "1.2.0"
// Image loading
val coilVersion = "1.4.0"
implementation("io.coil-kt:coil:$coilVersion")
implementation("io.coil-kt:coil-gif:$coilVersion")
implementation("com.github.tachiyomiorg:subsampling-scale-image-view:846abe0") {
exclude(module = "image-decoder")
}
implementation("com.github.tachiyomiorg:image-decoder:7a44c9b")
// Logging
implementation("com.jakewharton.timber:timber:4.7.1")
// Crash reports
//implementation("ch.acra:acra-http:5.7.0")
implementation("com.github.tachiyomiorg:image-decoder:7481a4a")
// Sort
implementation("com.github.gpanther:java-nat-sort:natural-comparator-1.1")
// UI
// UI libraries
implementation("com.google.android.material:material:1.6.0-alpha02")
implementation("com.github.dmytrodanylyk.android-process-button:library:1.0.4")
implementation("eu.davidea:flexible-adapter:5.1.0")
implementation("eu.davidea:flexible-adapter-ui:1.0.0")
implementation("com.github.arkon.FlexibleAdapter:flexible-adapter:c8013533")
implementation("com.github.arkon.FlexibleAdapter:flexible-adapter-ui:c8013533")
implementation("com.nightlynexus.viewstatepageradapter:viewstatepageradapter:1.1.0")
implementation("com.github.chrisbanes:PhotoView:2.3.0")
implementation("com.github.tachiyomiorg:DirectionalViewPager:1.0.0")
implementation("dev.chrisbanes.insetter:insetter:0.6.0")
// 3.2.0+ introduces weird UI blinking or cut off issues on some devices
val materialDialogsVersion = "3.1.1"
implementation("com.afollestad.material-dialogs:core:$materialDialogsVersion")
implementation("com.afollestad.material-dialogs:input:$materialDialogsVersion")
implementation("com.afollestad.material-dialogs:datetime:$materialDialogsVersion")
implementation("com.github.tachiyomiorg:DirectionalViewPager:1.0.0") {
exclude(group = "androidx.viewpager", module = "viewpager")
}
implementation("dev.chrisbanes.insetter:insetter:0.6.1")
// Conductor
implementation("com.bluelinelabs:conductor:2.1.5")
implementation("com.bluelinelabs:conductor-support:2.1.5") {
exclude(group = "com.android.support")
}
implementation("com.github.tachiyomiorg:conductor-support-preference:2.0.1")
val conductorVersion = "3.1.2"
implementation("com.bluelinelabs:conductor:$conductorVersion")
implementation("com.bluelinelabs:conductor-viewpager:$conductorVersion")
implementation("com.github.tachiyomiorg:conductor-support-preference:$conductorVersion")
// FlowBinding
val flowbindingVersion = "1.0.0"
val flowbindingVersion = "1.2.0"
implementation("io.github.reactivecircus.flowbinding:flowbinding-android:$flowbindingVersion")
implementation("io.github.reactivecircus.flowbinding:flowbinding-appcompat:$flowbindingVersion")
implementation("io.github.reactivecircus.flowbinding:flowbinding-recyclerview:$flowbindingVersion")
implementation("io.github.reactivecircus.flowbinding:flowbinding-swiperefreshlayout:$flowbindingVersion")
implementation("io.github.reactivecircus.flowbinding:flowbinding-viewpager:$flowbindingVersion")
// Logging
implementation("com.squareup.logcat:logcat:0.1")
// Crash reports/analytics
//implementation("ch.acra:acra-http:5.8.4")
//"standardImplementation"("com.google.firebase:firebase-analytics-ktx:20.0.2")
// Licenses
implementation("com.mikepenz:aboutlibraries:${BuildPluginsVersion.ABOUTLIB_PLUGIN}")
implementation("com.mikepenz:aboutlibraries-core:${BuildPluginsVersion.ABOUTLIB_PLUGIN}")
// Shizuku
val shizukuVersion = "12.1.0"
implementation("dev.rikka.shizuku:api:$shizukuVersion")
implementation("dev.rikka.shizuku:provider:$shizukuVersion")
// Tests
testImplementation("junit:junit:4.13.2")
@@ -261,22 +263,12 @@ dependencies {
val robolectricVersion = "3.1.4"
testImplementation("org.robolectric:robolectric:$robolectricVersion")
testImplementation("org.robolectric:shadows-multidex:$robolectricVersion")
testImplementation("org.robolectric:shadows-play-services:$robolectricVersion")
implementation(kotlin("reflect", version = BuildPluginsVersion.KOTLIN))
val coroutinesVersion = "1.5.0"
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion")
// For detecting memory leaks; see https://square.github.io/leakcanary/
// debugImplementation("com.squareup.leakcanary:leakcanary-android:2.7")
// SY -->
// [EXH] Android 7 SSL Workaround
implementation("com.google.android.gms:play-services-safetynet:17.0.0")
// Changelog
implementation("com.github.gabrielemariotti.changeloglib:changelog:2.1.0")
@@ -284,11 +276,11 @@ dependencies {
implementation ("info.debatty:java-string-similarity:2.0.0")
// Firebase (EH)
implementation("com.google.firebase:firebase-analytics-ktx:19.0.0")
implementation("com.google.firebase:firebase-crashlytics-ktx:18.0.0")
implementation("com.google.firebase:firebase-analytics-ktx:20.0.2")
implementation("com.google.firebase:firebase-crashlytics-ktx:18.2.7")
// Better logging (EH)
implementation("com.elvishew:xlog:1.9.0")
implementation("com.elvishew:xlog:1.11.0")
// Debug utils (EH)
val debugOverlayVersion = "1.1.3"
@@ -307,12 +299,13 @@ tasks {
kotlinOptions.freeCompilerArgs += listOf(
"-Xopt-in=kotlin.Experimental",
"-Xopt-in=kotlin.RequiresOptIn",
"-Xuse-experimental=kotlin.ExperimentalStdlibApi",
"-Xuse-experimental=kotlinx.coroutines.FlowPreview",
"-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-Xuse-experimental=kotlinx.coroutines.InternalCoroutinesApi",
"-Xuse-experimental=kotlinx.serialization.ExperimentalSerializationApi",
"-Xuse-experimental=coil.annotation.ExperimentalCoilApi",
"-Xopt-in=kotlin.ExperimentalStdlibApi",
"-Xopt-in=kotlinx.coroutines.FlowPreview",
"-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-Xopt-in=kotlinx.coroutines.InternalCoroutinesApi",
"-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi",
"-Xopt-in=coil.annotation.ExperimentalCoilApi",
"-Xopt-in=kotlin.time.ExperimentalTime",
)
}
+6 -30
View File
@@ -69,16 +69,19 @@
# Keep extension's common dependencies
-keep,allowoptimization class eu.kanade.tachiyomi.** { public protected *; }
-keep,allowoptimization class androidx.preference.** { *; }
-keep,allowoptimization class kotlin.** { public protected *; }
-keep,allowoptimization class kotlinx.coroutines.** { public protected *; }
-keep,allowoptimization class okhttp3.** { public protected *; }
-keep,allowoptimization class okio.** { public protected *; }
-keep,allowoptimization class rx.** { public protected *; }
-keep,allowoptimization class org.jsoup.** { public protected *; }
-keep,allowoptimization class com.google.gson.** { public protected *; }
-keep,allowoptimization class com.github.salomonbrys.kotson.** { public protected *; }
-keep,allowoptimization class com.squareup.duktape.** { public protected *; }
-keep,allowoptimization class androidx.preference.** { *; }
-keep,allowoptimization class okio.** { *; }
-keep,allowoptimization class kotlinx.serialization.** { *; }
-keep,allowoptimization class app.cash.quickjs.** { public protected *; }
-keep,allowoptimization class uy.kohesive.injekt.** { public protected *; }
-keep,allowoptimization class kotlinx.serialization.** { public protected *; }
# RxJava 1.1.0
-dontwarn sun.misc.**
@@ -104,33 +107,6 @@
# === Okio: https://github.com/square/okio/tree/9b8545e7fa267c9d89753283990f24a35cd69cd6#proguard
-dontwarn okio.**
# === GSON: https://raw.githubusercontent.com/google/gson/master/examples/android-proguard-example/proguard.cfg
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { <fields>; }
# Prevent proguard from stripping interface information from TypeAdapterFactory, TypeAdapter,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * extends com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}
# == Nucleus
-keepclassmembers class * extends nucleus.presenter.Presenter {
<init>();
+187 -186
View File
@@ -19,13 +19,13 @@
<!-- For managing extensions -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<uses-permission android:name="android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION" />
<!-- To view extension packages in API 30+ -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application
android:name=".App"
android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules"
android:allowBackup="false"
android:hardwareAccelerated="true"
android:hasFragileUserData="true"
android:icon="@mipmap/ic_launcher"
@@ -33,12 +33,15 @@
android:largeHeap="true"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/Theme.Base"
android:theme="@style/Theme.Tachiyomi"
android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config">
<activity
android:name=".ui.main.MainActivity"
android:launchMode="singleTop"
android:theme="@style/Theme.Splash">
android:theme="@style/Theme.Tachiyomi.SplashScreen"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -52,7 +55,8 @@
android:name=".ui.main.DeepLinkActivity"
android:launchMode="singleTask"
android:theme="@android:style/Theme.NoDisplay"
android:label="@string/action_global_search">
android:label="@string/action_global_search"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<action android:name="com.google.android.gms.actions.SEARCH_ACTION" />
@@ -73,9 +77,11 @@
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
<activity
android:name=".ui.reader.ReaderActivity"
android:launchMode="singleTask">
android:launchMode="singleTask"
android:exported="false">
<intent-filter>
<action android:name="com.samsung.android.support.REMOTE_ACTION" />
</intent-filter>
@@ -83,15 +89,26 @@
<meta-data android:name="com.samsung.android.support.REMOTE_ACTION"
android:resource="@xml/s_pen_actions"/>
</activity>
<activity
android:name=".ui.security.UnlockActivity"
android:theme="@style/Theme.Base" />
android:theme="@style/Theme.Tachiyomi"
android:exported="false" />
<activity
android:name=".ui.webview.WebViewActivity"
android:configChanges="uiMode|orientation|screenSize" />
android:configChanges="uiMode|orientation|screenSize"
android:exported="false" />
<activity
android:name=".extension.util.ExtensionInstallActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:exported="false" />
<activity
android:name=".ui.setting.track.AnilistLoginActivity"
android:label="Anilist">
android:label="Anilist"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@@ -105,7 +122,8 @@
</activity>
<activity
android:name=".ui.setting.track.MyAnimeListLoginActivity"
android:label="MyAnimeList">
android:label="MyAnimeList"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@@ -119,7 +137,8 @@
</activity>
<activity
android:name=".ui.setting.track.ShikimoriLoginActivity"
android:label="Shikimori">
android:label="Shikimori"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@@ -133,7 +152,8 @@
</activity>
<activity
android:name=".ui.setting.track.BangumiLoginActivity"
android:label="Bangumi">
android:label="Bangumi"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@@ -146,23 +166,10 @@
</intent-filter>
</activity>
<activity
android:name=".extension.util.ExtensionInstallActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<activity
android:name="exh.ui.login.EhLoginActivity"
android:label="EHentaiLogin" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
android:label="EHentaiLogin"
android:exported="false"/>
<receiver
android:name=".data.notification.NotificationReceiver"
@@ -177,7 +184,7 @@
android:exported="false" />
<service
android:name=".data.updater.UpdaterService"
android:name=".data.updater.AppUpdateService"
android:exported="false" />
<service
@@ -188,189 +195,183 @@
android:name=".data.backup.BackupRestoreService"
android:exported="false" />
<service android:name=".extension.util.ExtensionInstallService"
android:exported="false" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<provider
android:name="rikka.shizuku.ShizukuProvider"
android:authorities="${applicationId}.shizuku"
android:multiprocess="false"
android:enabled="true"
android:exported="true"
android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" />
<meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
android:value="false" />
<meta-data android:name="android.webkit.WebView.MetricsOptOut"
android:value="true" />
<!-- EH -->
<service
android:name="exh.eh.EHentaiUpdateWorker"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true" />
<activity
android:name="exh.ui.intercept.InterceptActivity"
android:label="@string/app_name"
android:theme="@style/Theme.Base">
android:theme="@style/Theme.Tachiyomi"
android:exported="true">
<!-- E-Hentai -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- EH -->
<data
android:host="g.e-hentai.org"
android:pathPrefix="/g/"
android:scheme="http" />
<data
android:host="g.e-hentai.org"
android:pathPrefix="/g/"
android:scheme="https" />
<data
android:host="e-hentai.org"
android:pathPrefix="/g/"
android:scheme="http" />
<data
android:host="e-hentai.org"
android:pathPrefix="/g/"
android:scheme="https" />
<data android:scheme="https" />
<data android:scheme="http" />
<!-- EXH -->
<data
android:host="exhentai.org"
android:pathPrefix="/g/"
android:scheme="http" />
<data
android:host="exhentai.org"
android:pathPrefix="/g/"
android:scheme="https" />
<data android:host="e-hentai.org" />
<data android:host="www.e-hentai.org" />
<data android:host="g.e-hentai.org" />
<!-- nhentai -->
<data
android:host="nhentai.net"
android:pathPrefix="/g/"
android:scheme="http" />
<data
android:host="nhentai.net"
android:pathPrefix="/g/"
android:scheme="https" />
<data android:pathPattern="/g/..*" />
</intent-filter>
<!-- ExHentai -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<!-- Perv Eden -->
<data
android:host="www.perveden.com"
android:pathPattern="/.*/.*-manga/.*"
android:scheme="http" />
<data
android:host="www.perveden.com"
android:pathPattern="/.*/.*-manga/.*"
android:scheme="https" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Hentai Cafe -->
<data
android:host="hentai.cafe"
android:pathPrefix="/hc.fyi/"
android:scheme="http" />
<data
android:host="hentai.cafe"
android:pathPrefix="/hc.fyi/"
android:scheme="https" />
<data android:scheme="https" />
<data android:scheme="http" />
<!-- Tsumino -->
<data
android:host="www.tsumino.com"
android:pathPrefix="/Book/Info/"
android:scheme="http" />
<data
android:host="www.tsumino.com"
android:pathPrefix="/Book/Info/"
android:scheme="https" />
<data
android:host="www.tsumino.com"
android:pathPrefix="/Read/View/"
android:scheme="http" />
<data
android:host="www.tsumino.com"
android:pathPrefix="/Read/View/"
android:scheme="https" />
<data android:host="exhentai.org" />
<data android:host="www.exhentai.org" />
<!-- Hitomi.la -->
<data
android:host="hitomi.la"
android:pathPrefix="/galleries/"
android:scheme="http" />
<data
android:host="hitomi.la"
android:pathPrefix="/reader/"
android:scheme="http" />
<data
android:host="hitomi.la"
android:pathPrefix="/galleries/"
android:scheme="https" />
<data
android:host="hitomi.la"
android:pathPrefix="/reader/"
android:scheme="https" />
<data android:pathPattern="/g/..*" />
</intent-filter>
<!-- NHentai -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<!-- Pururin.io -->
<data
android:host="pururin.io"
android:pathPrefix="/gallery/"
android:scheme="http" />
<data
android:host="pururin.io"
android:pathPrefix="/gallery/"
android:scheme="https" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- HBrowse -->
<data
android:host="www.hbrowse.com"
android:scheme="http" />
<data
android:host="www.hbrowse.com"
android:scheme="https" />
<data android:scheme="https" />
<data android:scheme="http" />
<!-- MangaDex -->
<!--<data
android:scheme="https"
android:host="www.mangadex.org"
android:pathPrefix="/manga/" />
<data
android:scheme="https"
android:host="mangadex.org"
android:pathPrefix="/manga/" />
<data
android:scheme="https"
android:host="www.mangadex.cc"
android:pathPrefix="/manga/" />
<data
android:scheme="https"
android:host="www.mangadex.cc"
android:pathPrefix="/manga/" />
<data android:host="nhentai.net" />
<data android:host="www.nhentai.net" />
<data
android:scheme="https"
android:host="www.mangadex.org"
android:pathPrefix="/title/" />
<data
android:scheme="https"
android:host="mangadex.org"
android:pathPrefix="/title/" />
<data
android:scheme="https"
android:host="www.mangadex.cc"
android:pathPrefix="/title/" />
<data
android:scheme="https"
android:host="www.mangadex.cc"
android:pathPrefix="/title/" />
<data android:pathPattern="/g/..*" />
</intent-filter>
<!-- Perv Eden -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data
android:scheme="https"
android:host="www.mangadex.org"
android:pathPrefix="/chapter/" />
<data
android:scheme="https"
android:host="mangadex.org"
android:pathPrefix="/chapter/" />
<data
android:scheme="https"
android:host="www.mangadex.cc"
android:pathPrefix="/chapter/" />
<data
android:scheme="https"
android:host="www.mangadex.cc"
android:pathPrefix="/chapter/" />-->
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:scheme="http" />
<data android:host="perveden.com" />
<data android:host="www.perveden.com" />
<data android:pathPattern="/.*/.*-manga/.*" />
</intent-filter>
<!-- Tsumino -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:scheme="http" />
<data android:host="tsumino.com" />
<data android:host="www.tsumino.com" />
<data android:pathPattern="/Read/View/..*" />
<data android:pathPattern="/Book/Info/..*" />
</intent-filter>
<!-- Hitomi.la -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:scheme="http" />
<data android:host="hitomi.la" />
<data android:host="www.hitomi.la" />
<data android:pathPattern="/reader/..*" />
<data android:pathPattern="/galleries/..*" />
</intent-filter>
<!-- Pururin -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:scheme="http" />
<data android:host="pururin.io" />
<data android:pathPattern="/gallery/..*" />
</intent-filter>
<!-- HBrowse -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:scheme="http" />
<data android:host="hbrowse.com" />
<data android:host="www.hbrowse.com" />
<!--<data android:pathPattern="/gallery/..*" />-->
</intent-filter>
<!-- Mangadex -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:host="mangadex.org" />
<data android:host="mangadex.cc" />
<data android:host="www.mangadex.org" />
<data android:host="www.mangadex.cc" />
<data android:pathPattern="/manga/..*" />
<data android:pathPattern="/title/..*" />
<data android:pathPattern="/chapter/..*" />
</intent-filter>
</activity>
<activity
android:name="exh.ui.captcha.BrowserActionActivity"
android:theme="@style/Theme.Base" />
android:theme="@style/Theme.Tachiyomi"
android:exported="false"/>
</application>
</manifest>
+55 -74
View File
@@ -7,23 +7,22 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.res.Configuration
import android.graphics.Color
import android.os.Build
import android.os.Environment
import android.webkit.WebView
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.getSystemService
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.multidex.MultiDex
import coil.ImageLoader
import coil.ImageLoaderFactory
import coil.decode.GifDecoder
import coil.decode.ImageDecoderDecoder
import coil.util.DebugLogger
import com.elvishew.xlog.LogConfiguration
import com.elvishew.xlog.LogLevel
import com.elvishew.xlog.XLog
@@ -32,62 +31,59 @@ import com.elvishew.xlog.printer.Printer
import com.elvishew.xlog.printer.file.backup.NeverBackupStrategy
import com.elvishew.xlog.printer.file.clean.FileLastModifiedCleanStrategy
import com.elvishew.xlog.printer.file.naming.DateFileNameGenerator
import com.google.android.gms.common.GooglePlayServicesNotAvailableException
import com.google.android.gms.common.GooglePlayServicesRepairableException
import com.google.android.gms.security.ProviderInstaller
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.ktx.Firebase
import com.ms_square.debugoverlay.DebugOverlay
import com.ms_square.debugoverlay.modules.FpsModule
import eu.kanade.tachiyomi.data.coil.ByteBufferFetcher
import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher
import eu.kanade.tachiyomi.data.coil.TachiyomiImageDecoder
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.preference.PreferenceValues
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
import eu.kanade.tachiyomi.util.system.LocaleHelper
import eu.kanade.tachiyomi.util.preference.asImmediateFlow
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil
import eu.kanade.tachiyomi.util.system.animatorDurationScale
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.notification
import exh.debug.DebugToggles
import exh.log.CrashlyticsPrinter
import exh.log.EHDebugModeOverlay
import exh.log.EHLogLevel
import exh.log.EnhancedFilePrinter
import exh.log.XLogTree
import exh.log.XLogLogcatLogger
import exh.log.xLogD
import exh.log.xLogE
import exh.syDebugVersion
import io.realm.Realm
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import logcat.LogPriority
import logcat.LogcatLogger
import org.conscrypt.Conscrypt
import timber.log.Timber
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.io.File
import java.security.NoSuchAlgorithmException
import java.security.Security
import java.text.SimpleDateFormat
import java.util.Locale
import javax.net.ssl.SSLContext
import kotlin.time.ExperimentalTime
import kotlin.time.days
import kotlin.time.Duration.Companion.days
open class App : Application(), LifecycleObserver, ImageLoaderFactory {
open class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory {
private val preferences: PreferencesHelper by injectLazy()
private val disableIncognitoReceiver = DisableIncognitoReceiver()
override fun onCreate() {
super.onCreate()
super<Application>.onCreate()
// if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
setupExhLogging() // EXH logging
Timber.plant(XLogTree()) // SY Redirect Timber to XLog
LogcatLogger.install(XLogLogcatLogger()) // SY Redirect Logcat to XLog
if (!BuildConfig.DEBUG) addAnalytics()
workaroundAndroid7BrokenSSL()
// TLS 1.3 support for Android < 10
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
Security.insertProviderAt(Conscrypt.newProvider(), 1)
@@ -102,13 +98,10 @@ open class App : Application(), LifecycleObserver, ImageLoaderFactory {
Injekt.importModule(AppModule(this))
setupNotificationChannels()
Realm.init(this)
if ((BuildConfig.DEBUG || BuildConfig.BUILD_TYPE == "releaseTest") && DebugToggles.ENABLE_DEBUG_OVERLAY.enabled) {
setupDebugOverlay()
}
LocaleHelper.updateConfiguration(this, resources.configuration)
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
// Show notification to disable Incognito Mode when it's enabled
@@ -120,7 +113,7 @@ open class App : Application(), LifecycleObserver, ImageLoaderFactory {
val notification = notification(Notifications.CHANNEL_INCOGNITO_MODE) {
setContentTitle(getString(R.string.pref_incognito_mode))
setContentText(getString(R.string.notification_incognito_text))
setSmallIcon(R.drawable.ic_glasses_black_24dp)
setSmallIcon(R.drawable.ic_glasses_24dp)
setOngoing(true)
val pendingIntent = PendingIntent.getBroadcast(
@@ -138,16 +131,21 @@ open class App : Application(), LifecycleObserver, ImageLoaderFactory {
}
}
.launchIn(ProcessLifecycleOwner.get().lifecycleScope)
}
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
MultiDex.install(this)
}
preferences.themeMode()
.asImmediateFlow {
AppCompatDelegate.setDefaultNightMode(
when (it) {
PreferenceValues.ThemeMode.light -> AppCompatDelegate.MODE_NIGHT_NO
PreferenceValues.ThemeMode.dark -> AppCompatDelegate.MODE_NIGHT_YES
PreferenceValues.ThemeMode.system -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
)
}.launchIn(ProcessLifecycleOwner.get().lifecycleScope)
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
LocaleHelper.updateConfiguration(this, newConfig, true)
/*if (!LogcatLogger.isInstalled && preferences.verboseLogging()) {
LogcatLogger.install(AndroidLogcatLogger(LogPriority.VERBOSE))
}*/
}
override fun newImageLoader(): ImageLoader {
@@ -158,51 +156,35 @@ open class App : Application(), LifecycleObserver, ImageLoaderFactory {
} else {
add(GifDecoder())
}
add(TachiyomiImageDecoder(this@App.resources))
add(ByteBufferFetcher())
add(MangaCoverFetcher())
}
okHttpClient(Injekt.get<NetworkHelper>().coilClient)
crossfade(300)
crossfade((300 * this@App.animatorDurationScale).toInt())
allowRgb565(getSystemService<ActivityManager>()!!.isLowRamDevice)
if (preferences.verboseLogging()) logger(DebugLogger())
}.build()
}
private fun workaroundAndroid7BrokenSSL() {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N ||
Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1
) {
try {
SSLContext.getInstance("TLSv1.2")
} catch (e: NoSuchAlgorithmException) {
xLogE("Could not install Android 7 broken SSL workaround!", e)
}
try {
ProviderInstaller.installIfNeeded(applicationContext)
} catch (e: GooglePlayServicesRepairableException) {
xLogE("Could not install Android 7 broken SSL workaround!", e)
} catch (e: GooglePlayServicesNotAvailableException) {
xLogE("Could not install Android 7 broken SSL workaround!", e)
}
}
}
private fun addAnalytics() {
if (syDebugVersion != "0") {
Firebase.analytics.setUserProperty("preview_version", syDebugVersion)
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
@Suppress("unused")
fun onAppBackgrounded() {
if (preferences.lockAppAfter().get() >= 0) {
override fun onStop(owner: LifecycleOwner) {
if (!AuthenticatorUtil.isAuthenticating && preferences.lockAppAfter().get() >= 0) {
SecureActivityDelegate.locked = true
}
}
protected open fun setupNotificationChannels() {
Notifications.createChannels(this)
try {
Notifications.createChannels(this)
} catch (e: Exception) {
logcat(LogPriority.ERROR, e) { "Failed to modify notification channels" }
}
}
// EXH
@@ -231,7 +213,6 @@ open class App : Application(), LifecycleObserver, ImageLoaderFactory {
val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault())
@OptIn(ExperimentalTime::class)
printers += EnhancedFilePrinter
.Builder(logFolder.absolutePath) {
fileNameGenerator = object : DateFileNameGenerator() {
@@ -245,7 +226,7 @@ open class App : Application(), LifecycleObserver, ImageLoaderFactory {
flattener { timeMillis, level, tag, message ->
"${dateFormat.format(timeMillis)} ${LogLevel.getShortLevelName(level)}/$tag: $message"
}
cleanStrategy = FileLastModifiedCleanStrategy(7.days.toLongMilliseconds())
cleanStrategy = FileLastModifiedCleanStrategy(7.days.inWholeMilliseconds)
backupStrategy = NeverBackupStrategy()
}
@@ -261,15 +242,17 @@ open class App : Application(), LifecycleObserver, ImageLoaderFactory {
xLogD("Application booting...")
xLogD(
"App version: ${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR}, ${BuildConfig.COMMIT_SHA}, ${BuildConfig.VERSION_CODE})\n" +
"Preview build: $syDebugVersion\n" +
"Android version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT}) \n" +
"Android build ID: ${Build.DISPLAY}\n" +
"Device brand: ${Build.BRAND}\n" +
"Device manufacturer: ${Build.MANUFACTURER}\n" +
"Device name: ${Build.DEVICE}\n" +
"Device model: ${Build.MODEL}\n" +
"Device product name: ${Build.PRODUCT}"
"""
App version: ${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR}, ${BuildConfig.COMMIT_SHA}, ${BuildConfig.VERSION_CODE})
Preview build: $syDebugVersion
Android version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT})
Android build ID: ${Build.DISPLAY}
Device brand: ${Build.BRAND}
Device manufacturer: ${Build.MANUFACTURER}
Device name: ${Build.DEVICE}
Device model: ${Build.MODEL}
Device product name: ${Build.PRODUCT}
""".trimIndent()
)
}
@@ -310,8 +293,6 @@ open class App : Application(), LifecycleObserver, ImageLoaderFactory {
}
}
}
companion object {
private const val ACTION_DISABLE_INCOGNITO_MODE = "tachi.action.DISABLE_INCOGNITO_MODE"
}
}
private const val ACTION_DISABLE_INCOGNITO_MODE = "tachi.action.DISABLE_INCOGNITO_MODE"
@@ -0,0 +1,11 @@
package eu.kanade.tachiyomi
/**
* Used by extensions.
*
* @since extension-lib 1.3
*/
object AppInfo {
fun getVersionCode() = BuildConfig.VERSION_CODE
fun getVersionName() = BuildConfig.VERSION_NAME
}
@@ -1,7 +1,7 @@
package eu.kanade.tachiyomi
import android.app.Application
import android.os.Handler
import androidx.core.content.ContextCompat
import eu.kanade.tachiyomi.data.cache.ChapterCache
import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.database.DatabaseHelper
@@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.library.CustomMangaManager
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.job.DelayedTrackingStore
import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.source.SourceManager
@@ -25,6 +26,8 @@ class AppModule(val app: Application) : InjektModule {
override fun InjektRegistrar.registerInjectables() {
addSingleton(app)
addSingletonFactory { Json { ignoreUnknownKeys = true } }
addSingletonFactory { PreferencesHelper(app) }
addSingletonFactory { DatabaseHelper(app) }
@@ -43,7 +46,7 @@ class AppModule(val app: Application) : InjektModule {
addSingletonFactory { TrackManager(app) }
addSingletonFactory { Json { ignoreUnknownKeys = true } }
addSingletonFactory { DelayedTrackingStore(app) }
// SY -->
addSingletonFactory { CustomMangaManager(app) }
@@ -52,7 +55,7 @@ class AppModule(val app: Application) : InjektModule {
// SY <--
// Asynchronously init expensive components for a faster cold start
Handler().post {
ContextCompat.getMainExecutor(app).execute {
get<PreferencesHelper>()
get<NetworkHelper>()
@@ -5,14 +5,19 @@ import androidx.core.content.edit
import androidx.preference.PreferenceManager
import eu.kanade.tachiyomi.data.backup.BackupCreatorJob
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
import eu.kanade.tachiyomi.data.preference.MANGA_ONGOING
import eu.kanade.tachiyomi.data.preference.PreferenceKeys
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.updater.UpdaterJob
import eu.kanade.tachiyomi.data.updater.AppUpdateJob
import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE
import eu.kanade.tachiyomi.ui.library.LibrarySort
import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting
import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
import eu.kanade.tachiyomi.util.preference.minusAssign
import eu.kanade.tachiyomi.util.preference.plusAssign
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
import uy.kohesive.injekt.Injekt
@@ -32,30 +37,29 @@ object Migrations {
fun upgrade(preferences: PreferencesHelper): Boolean {
val context = preferences.context
// Cancel app updater job for debug builds that don't include it
if (BuildConfig.DEBUG && !BuildConfig.INCLUDE_UPDATER) {
UpdaterJob.cancelTask(context)
}
val oldVersion = preferences.lastVersionCode().get()
if (oldVersion < BuildConfig.VERSION_CODE) {
preferences.lastVersionCode().set(BuildConfig.VERSION_CODE)
// Always set up background tasks to ensure they're running
if (BuildConfig.INCLUDE_UPDATER) {
AppUpdateJob.setupTask(context)
}
ExtensionUpdateJob.setupTask(context)
LibraryUpdateJob.setupTask(context)
BackupCreatorJob.setupTask(context)
// Fresh install
if (oldVersion == 0) {
// Set up default background tasks
if (BuildConfig.INCLUDE_UPDATER) {
UpdaterJob.setupTask(context)
}
ExtensionUpdateJob.setupTask(context)
LibraryUpdateJob.setupTask(context)
return false
}
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
if (oldVersion < 14) {
// Restore jobs after upgrading to Evernote's job scheduler.
if (BuildConfig.INCLUDE_UPDATER) {
UpdaterJob.setupTask(context)
AppUpdateJob.setupTask(context)
}
LibraryUpdateJob.setupTask(context)
}
@@ -88,7 +92,7 @@ object Migrations {
if (oldVersion < 43) {
// Restore jobs after migrating from Evernote's job scheduler to WorkManager.
if (BuildConfig.INCLUDE_UPDATER) {
UpdaterJob.setupTask(context)
AppUpdateJob.setupTask(context)
}
LibraryUpdateJob.setupTask(context)
BackupCreatorJob.setupTask(context)
@@ -98,14 +102,17 @@ object Migrations {
}
if (oldVersion < 44) {
// Reset sorting preference if using removed sort by source
val oldSortingMode = prefs.getInt(PreferenceKeys.librarySortingMode, 0)
@Suppress("DEPRECATION")
if (preferences.librarySortingMode().get() == LibrarySort.SOURCE) {
preferences.librarySortingMode().set(LibrarySort.ALPHA)
if (oldSortingMode == LibrarySort.SOURCE) {
prefs.edit {
putInt(PreferenceKeys.librarySortingMode, LibrarySort.ALPHA)
}
}
}
if (oldVersion < 52) {
// Migrate library filters to tri-state versions
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
fun convertBooleanPrefToTriState(key: String): Int {
val oldPrefValue = prefs.getBoolean(key, false)
return if (oldPrefValue) ExtendedNavigationView.Item.TriStateGroup.State.INCLUDE.value
@@ -122,7 +129,7 @@ object Migrations {
remove("pref_filter_completed_key")
}
}
if (oldVersion < 53) {
if (oldVersion < 54) {
// Force MAL log out due to login flow change
// v52: switched from scraping to WebView
// v53: switched from WebView to OAuth
@@ -134,7 +141,6 @@ object Migrations {
}
if (oldVersion < 57) {
// Migrate DNS over HTTPS setting
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val wasDohEnabled = prefs.getBoolean("enable_doh", false)
if (wasDohEnabled) {
prefs.edit {
@@ -145,7 +151,6 @@ object Migrations {
}
if (oldVersion < 59) {
// Reset rotation to Free after replacing Lock
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
if (prefs.contains("pref_rotation_type_key")) {
prefs.edit {
putInt("pref_rotation_type_key", 1)
@@ -154,12 +159,16 @@ object Migrations {
// Disable update check for Android 5.x users
if (BuildConfig.INCLUDE_UPDATER && Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
UpdaterJob.cancelTask(context)
AppUpdateJob.cancelTask(context)
}
}
if (oldVersion < 60) {
// Re-enable update check that was prevously accidentally disabled for M
if (BuildConfig.INCLUDE_UPDATER && Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
AppUpdateJob.setupTask(context)
}
// Migrate Rotation and Viewer values to default values for viewer_flags
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val newOrientation = when (prefs.getInt("pref_rotation_type_key", 1)) {
1 -> OrientationType.FREE.flagValue
2 -> OrientationType.PORTRAIT.flagValue
@@ -187,6 +196,58 @@ object Migrations {
LibraryUpdateJob.setupTask(context, 3)
}
}
if (oldVersion < 64) {
val oldSortingMode = prefs.getInt(PreferenceKeys.librarySortingMode, 0)
val oldSortingDirection = prefs.getBoolean(PreferenceKeys.librarySortingDirection, true)
@Suppress("DEPRECATION")
val newSortingMode = when (oldSortingMode) {
LibrarySort.ALPHA -> SortModeSetting.ALPHABETICAL
LibrarySort.LAST_READ -> SortModeSetting.LAST_READ
LibrarySort.LAST_CHECKED -> SortModeSetting.LAST_CHECKED
LibrarySort.UNREAD -> SortModeSetting.UNREAD
LibrarySort.TOTAL -> SortModeSetting.TOTAL_CHAPTERS
LibrarySort.LATEST_CHAPTER -> SortModeSetting.LATEST_CHAPTER
LibrarySort.CHAPTER_FETCH_DATE -> SortModeSetting.DATE_FETCHED
LibrarySort.DATE_ADDED -> SortModeSetting.DATE_ADDED
else -> SortModeSetting.ALPHABETICAL
}
val newSortingDirection = when (oldSortingDirection) {
true -> SortDirectionSetting.ASCENDING
else -> SortDirectionSetting.DESCENDING
}
prefs.edit(commit = true) {
remove(PreferenceKeys.librarySortingMode)
remove(PreferenceKeys.librarySortingDirection)
}
prefs.edit {
putString(PreferenceKeys.librarySortingMode, newSortingMode.name)
putString(PreferenceKeys.librarySortingDirection, newSortingDirection.name)
}
}
if (oldVersion < 70) {
if (preferences.enabledLanguages().isSet()) {
preferences.enabledLanguages() += "all"
}
}
if (oldVersion < 71) {
// Handle removed every 3, 4, 6, and 8 hour library updates
val updateInterval = preferences.libraryUpdateInterval().get()
if (updateInterval in listOf(3, 4, 6, 8)) {
preferences.libraryUpdateInterval().set(12)
LibraryUpdateJob.setupTask(context, 12)
}
}
if (oldVersion < 72) {
val oldUpdateOngoingOnly = prefs.getBoolean("pref_update_only_non_completed_key", true)
if (!oldUpdateOngoingOnly) {
preferences.libraryUpdateMangaRestriction() -= MANGA_ONGOING
}
}
return true
}
@@ -1,5 +0,0 @@
package eu.kanade.tachiyomi.annotations
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS)
annotation class Nsfw
@@ -28,7 +28,7 @@ abstract class AbstractBackupManager(protected val context: Context) {
protected val customMangaManager: CustomMangaManager by injectLazy()
// SY <--
abstract fun createBackup(uri: Uri, flags: Int, isJob: Boolean): String?
abstract fun createBackup(uri: Uri, flags: Int, isJob: Boolean): String
/**
* Returns manga
@@ -14,3 +14,5 @@ abstract class AbstractBackupRestoreValidator {
data class Results(val missingSources: List<String>, val missingTrackers: List<String>)
}
class ValidatorParseException(e: Exception) : RuntimeException(e)
@@ -9,6 +9,8 @@ import androidx.work.Worker
import androidx.work.WorkerParameters
import eu.kanade.tachiyomi.data.backup.full.FullBackupManager
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.concurrent.TimeUnit
@@ -24,6 +26,7 @@ class BackupCreatorJob(private val context: Context, workerParams: WorkerParamet
FullBackupManager(context).createBackup(uri, flags, true)
Result.success()
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
Result.failure()
}
}
@@ -139,10 +139,12 @@ class BackupNotifier(private val context: Context) {
val destFile = File(path, file)
val uri = destFile.getUriCompat(context)
val errorLogIntent = NotificationReceiver.openErrorLogPendingActivity(context, uri)
setContentIntent(errorLogIntent)
addAction(
R.drawable.ic_folder_24dp,
context.getString(R.string.action_show_errors),
NotificationReceiver.openErrorLogPendingActivity(context, uri)
errorLogIntent,
)
}
@@ -13,13 +13,14 @@ import eu.kanade.tachiyomi.data.backup.legacy.LegacyBackupRestore
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.util.system.acquireWakeLock
import eu.kanade.tachiyomi.util.system.isServiceRunning
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import timber.log.Timber
import logcat.LogPriority
/**
* Restores backup.
@@ -96,7 +97,7 @@ class BackupRestoreService : Service() {
private fun destroyJob() {
backupRestore?.job?.cancel()
ioScope?.cancel()
ioScope.cancel()
if (wakeLock.isHeld) {
wakeLock.release()
}
@@ -128,7 +129,7 @@ class BackupRestoreService : Service() {
}
val handler = CoroutineExceptionHandler { _, exception ->
Timber.e(exception)
logcat(LogPriority.ERROR, exception)
backupRestore?.writeErrorLog()
notifier.showRestoreError(exception.message)
@@ -35,6 +35,7 @@ import eu.kanade.tachiyomi.data.database.models.MangaCategory
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.system.logcat
import exh.metadata.metadata.base.getFlatMetadataForManga
import exh.metadata.metadata.base.insertFlatMetadataAsync
import exh.savedsearches.JsonSavedSearch
@@ -45,10 +46,10 @@ import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.protobuf.ProtoBuf
import logcat.LogPriority
import okio.buffer
import okio.gzip
import okio.sink
import timber.log.Timber
import kotlin.math.max
class FullBackupManager(context: Context) : AbstractBackupManager(context) {
@@ -61,7 +62,7 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
* @param uri path of Uri
* @param isJob backup called from job
*/
override fun createBackup(uri: Uri, flags: Int, isJob: Boolean): String? {
override fun createBackup(uri: Uri, flags: Int, isJob: Boolean): String {
// Create root object
var backup: Backup? = null
@@ -75,13 +76,15 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
backup = Backup(
backupManga(databaseManga, flags),
backupCategories(),
emptyList(),
backupExtensionInfo(databaseManga),
backupSavedSearches()
)
}
var file: UniFile? = null
try {
val file: UniFile = (
file = (
if (isJob) {
// Get dir of file and create
var dir = UniFile.fromUri(context, uri)
@@ -106,9 +109,15 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
val byteArray = parser.encodeToByteArray(BackupSerializer, backup!!)
file.openOutputStream().sink().gzip().buffer().use { it.write(byteArray) }
return file.uri.toString()
val fileUri = file.uri
// Make sure it's a valid backup file
FullBackupRestoreValidator().validate(context, fileUri)
return fileUri.toString()
} catch (e: Exception) {
Timber.e(e)
logcat(LogPriority.ERROR, e)
file?.delete()
throw e
}
}
@@ -147,8 +156,8 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
* @return list of [BackupSavedSearch] to be backed up
*/
private fun backupSavedSearches(): List<BackupSavedSearch> {
return preferences.savedSearches().get().map {
val sourceId = it.substringBefore(':').toLong()
return preferences.savedSearches().get().mapNotNull {
val sourceId = it.substringBefore(':').toLongOrNull() ?: return@mapNotNull null
val content = Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
BackupSavedSearch(
content.name,
@@ -180,8 +189,8 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
}
}
val source = sourceManager.get(manga.source)?.getMainSource()
if (source is MetadataSource<*, *>) {
val source = sourceManager.get(manga.source)?.getMainSource<MetadataSource<*, *>>()
if (source != null) {
manga.id?.let { mangaId ->
databaseHelper.getFlatMetadataForManga(mangaId).executeAsBlocking()?.let { flatMetadata ->
mangaObject.flatMetadata = BackupFlatMetadata.copyFrom(flatMetadata)
@@ -414,9 +423,13 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
// SY -->
internal fun restoreSavedSearches(backupSavedSearches: List<BackupSavedSearch>) {
val currentSavedSearches = preferences.savedSearches().get().map {
val sourceId = it.substringBefore(':').toLong()
val content = Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
val currentSavedSearches = preferences.savedSearches().get().mapNotNull {
val sourceId = it.substringBefore(':').toLongOrNull() ?: return@mapNotNull null
val content = try {
Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
} catch (e: Exception) {
return@mapNotNull null
}
BackupSavedSearch(
content.name,
content.query,
@@ -425,22 +438,19 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
)
}
preferences.savedSearches()
.set(
(
backupSavedSearches.filter { backupSavedSearch -> currentSavedSearches.none { it.name == backupSavedSearch.name && it.source == backupSavedSearch.source } }
.map {
"${it.source}:" + Json.encodeToString(
JsonSavedSearch(
it.name,
it.query,
Json.decodeFromString(it.filterList)
)
)
} + preferences.savedSearches().get()
)
.toSet()
val newSavedSearches = backupSavedSearches.filter { backupSavedSearch ->
currentSavedSearches.none { it.name == backupSavedSearch.name && it.source == backupSavedSearch.source }
}.map {
"${it.source}:" + Json.encodeToString(
JsonSavedSearch(
it.name,
it.query,
Json.decodeFromString(it.filterList)
)
)
}.toSet()
preferences.savedSearches().set(newSavedSearches + preferences.savedSearches().get())
}
/**
@@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.data.backup.full.models.BackupManga
import eu.kanade.tachiyomi.data.backup.full.models.BackupMergedMangaReference
import eu.kanade.tachiyomi.data.backup.full.models.BackupSavedSearch
import eu.kanade.tachiyomi.data.backup.full.models.BackupSerializer
import eu.kanade.tachiyomi.data.backup.full.models.BackupSource
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.Track
@@ -48,7 +49,8 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier) : AbstractBa
// SY <--
// Store source mapping for error messages
sourceMapping = backup.backupSources.map { it.sourceId to it.name }.toMap()
var backupMaps = backup.backupBrokenSources.map { BackupSource(it.name, it.sourceId) } + backup.backupSources
sourceMapping = backupMaps.map { it.sourceId to it.name }.toMap()
// Restore individual manga, sort by merged source so that merged source manga go last and merged references get the proper ids
backup.backupManga /* SY --> */.sortedBy { it.source == MERGED_SOURCE_ID } /* SY <-- */.forEach {
@@ -86,7 +88,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier) : AbstractBa
val manga = backupManga.getMangaImpl()
val chapters = backupManga.getChaptersImpl()
val categories = backupManga.categories
val history = backupManga.history
val history = backupManga.brokenHistory.map { BackupHistory(it.url, it.lastRead) } + backupManga.history
val tracks = backupManga.getTrackingImpl()
// SY -->
val mergedMangaReferences = backupManga.mergedMangaReferences
@@ -4,12 +4,14 @@ import android.content.Context
import android.net.Uri
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.AbstractBackupRestoreValidator
import eu.kanade.tachiyomi.data.backup.ValidatorParseException
import eu.kanade.tachiyomi.data.backup.full.models.BackupSerializer
import okio.buffer
import okio.gzip
import okio.source
class FullBackupRestoreValidator : AbstractBackupRestoreValidator() {
/**
* Checks for critical backup file data.
*
@@ -19,14 +21,20 @@ class FullBackupRestoreValidator : AbstractBackupRestoreValidator() {
override fun validate(context: Context, uri: Uri): Results {
val backupManager = FullBackupManager(context)
val backupString = context.contentResolver.openInputStream(uri)!!.source().gzip().buffer().use { it.readByteArray() }
val backup = backupManager.parser.decodeFromByteArray(BackupSerializer, backupString)
val backup = try {
val backupString =
context.contentResolver.openInputStream(uri)!!.source().gzip().buffer()
.use { it.readByteArray() }
backupManager.parser.decodeFromByteArray(BackupSerializer, backupString)
} catch (e: Exception) {
throw ValidatorParseException(e)
}
if (backup.backupManga.isEmpty()) {
throw Exception(context.getString(R.string.invalid_backup_file_missing_manga))
}
val sources = backup.backupSources.map { it.sourceId to it.name }.toMap()
val sources = backup.backupSources.associate { it.sourceId to it.name }
val missingSources = sources
.filter { sourceManager.get(it.key) == null }
.values
@@ -8,7 +8,8 @@ data class Backup(
@ProtoNumber(1) val backupManga: List<BackupManga>,
@ProtoNumber(2) var backupCategories: List<BackupCategory> = emptyList(),
// Bump by 100 to specify this is a 0.x value
@ProtoNumber(100) var backupSources: List<BackupSource> = emptyList(),
@ProtoNumber(100) var backupBrokenSources: List<BrokenBackupSource> = emptyList(),
@ProtoNumber(101) var backupSources: List<BackupSource> = emptyList(),
// SY specific values
@ProtoNumber(600) var backupSavedSearches: List<BackupSavedSearch> = emptyList()
)
@@ -4,7 +4,13 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class BackupHistory(
data class BrokenBackupHistory(
@ProtoNumber(0) var url: String,
@ProtoNumber(1) var lastRead: Long
)
@Serializable
data class BackupHistory(
@ProtoNumber(1) var url: String,
@ProtoNumber(2) var lastRead: Long
)
@@ -34,8 +34,9 @@ data class BackupManga(
// Bump by 100 for values that are not saved/implemented in 1.x but are used in 0.x
@ProtoNumber(100) var favorite: Boolean = true,
@ProtoNumber(101) var chapterFlags: Int = 0,
@ProtoNumber(102) var history: List<BackupHistory> = emptyList(),
@ProtoNumber(102) var brokenHistory: List<BrokenBackupHistory> = emptyList(),
@ProtoNumber(103) var viewer_flags: Int? = null,
@ProtoNumber(104) var history: List<BackupHistory> = emptyList(),
// SY specific values
@ProtoNumber(600) var mergedMangaReferences: List<BackupMergedMangaReference> = emptyList(),
@@ -46,8 +47,9 @@ data class BackupManga(
@ProtoNumber(800) var customTitle: String? = null,
@ProtoNumber(801) var customArtist: String? = null,
@ProtoNumber(802) var customAuthor: String? = null,
@ProtoNumber(803) var customDescription: String? = null,
@ProtoNumber(803) var customGenre: List<String>? = null,
// skipping 803 due to using duplicate value in previous builds
@ProtoNumber(804) var customDescription: String? = null,
@ProtoNumber(805) var customGenre: List<String>? = null,
// Neko specific values
@ProtoNumber(901) var filtered_scanlators: String? = null,
@@ -5,9 +5,15 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class BackupSource(
data class BrokenBackupSource(
@ProtoNumber(0) var name: String = "",
@ProtoNumber(1) var sourceId: Long
)
@Serializable
data class BackupSource(
@ProtoNumber(1) var name: String = "",
@ProtoNumber(2) var sourceId: Long
) {
companion object {
fun copyFrom(source: Source): BackupSource {
@@ -32,8 +32,7 @@ data class BackupTracking(
media_id = this@BackupTracking.mediaId
library_id = this@BackupTracking.libraryId
title = this@BackupTracking.title
// convert from float to int because of 1.x types
last_chapter_read = this@BackupTracking.lastChapterRead.toInt()
last_chapter_read = this@BackupTracking.lastChapterRead
total_chapters = this@BackupTracking.totalChapters
score = this@BackupTracking.score
status = this@BackupTracking.status
@@ -51,8 +50,7 @@ data class BackupTracking(
// forced not null so its compatible with 1.x backup system
libraryId = track.library_id!!,
title = track.title,
// convert to float for 1.x
lastChapterRead = track.last_chapter_read.toFloat(),
lastChapterRead = track.last_chapter_read,
totalChapters = track.total_chapters,
score = track.score,
status = track.status,
@@ -2,32 +2,26 @@ package eu.kanade.tachiyomi.data.backup.legacy
import android.content.Context
import android.net.Uri
import com.github.salomonbrys.kotson.fromJson
import com.github.salomonbrys.kotson.registerTypeAdapter
import com.github.salomonbrys.kotson.registerTypeHierarchyAdapter
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.AbstractBackupManager
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.CURRENT_VERSION
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.Companion.CURRENT_VERSION
import eu.kanade.tachiyomi.data.backup.legacy.models.DHistory
import eu.kanade.tachiyomi.data.backup.legacy.serializer.CategoryTypeAdapter
import eu.kanade.tachiyomi.data.backup.legacy.serializer.ChapterTypeAdapter
import eu.kanade.tachiyomi.data.backup.legacy.serializer.HistoryTypeAdapter
import eu.kanade.tachiyomi.data.backup.legacy.serializer.MangaTypeAdapter
import eu.kanade.tachiyomi.data.backup.legacy.serializer.MergedMangaReferenceTypeAdapter
import eu.kanade.tachiyomi.data.backup.legacy.serializer.TrackTypeAdapter
import eu.kanade.tachiyomi.data.database.models.CategoryImpl
import eu.kanade.tachiyomi.data.backup.legacy.serializer.CategoryImplTypeSerializer
import eu.kanade.tachiyomi.data.backup.legacy.serializer.CategoryTypeSerializer
import eu.kanade.tachiyomi.data.backup.legacy.serializer.ChapterImplTypeSerializer
import eu.kanade.tachiyomi.data.backup.legacy.serializer.ChapterTypeSerializer
import eu.kanade.tachiyomi.data.backup.legacy.serializer.HistoryTypeSerializer
import eu.kanade.tachiyomi.data.backup.legacy.serializer.MangaImplTypeSerializer
import eu.kanade.tachiyomi.data.backup.legacy.serializer.MangaTypeSerializer
import eu.kanade.tachiyomi.data.backup.legacy.serializer.MergedMangaTypeSerializer
import eu.kanade.tachiyomi.data.backup.legacy.serializer.TrackImplTypeSerializer
import eu.kanade.tachiyomi.data.backup.legacy.serializer.TrackTypeSerializer
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.ChapterImpl
import eu.kanade.tachiyomi.data.database.models.History
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaCategory
import eu.kanade.tachiyomi.data.database.models.MangaImpl
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.database.models.TrackImpl
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.model.toSManga
@@ -39,23 +33,33 @@ import exh.source.MERGED_SOURCE_ID
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import timber.log.Timber
import java.lang.RuntimeException
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.contextual
import kotlin.math.max
class LegacyBackupManager(context: Context, version: Int = CURRENT_VERSION) : AbstractBackupManager(context) {
val parser: Gson = when (version) {
2 -> GsonBuilder()
.registerTypeAdapter<MangaImpl>(MangaTypeAdapter.build())
.registerTypeHierarchyAdapter<ChapterImpl>(ChapterTypeAdapter.build())
.registerTypeAdapter<CategoryImpl>(CategoryTypeAdapter.build())
.registerTypeAdapter<DHistory>(HistoryTypeAdapter.build())
.registerTypeHierarchyAdapter<TrackImpl>(TrackTypeAdapter.build())
// SY -->
.registerTypeAdapter<MergedMangaReference>(MergedMangaReferenceTypeAdapter.build())
// SY <--
.create()
val parser: Json = when (version) {
2 -> Json {
// Forks may have added items to backup
ignoreUnknownKeys = true
// Register custom serializers
serializersModule = SerializersModule {
contextual(MangaTypeSerializer)
contextual(MangaImplTypeSerializer)
contextual(ChapterTypeSerializer)
contextual(ChapterImplTypeSerializer)
contextual(CategoryTypeSerializer)
contextual(CategoryImplTypeSerializer)
contextual(TrackTypeSerializer)
contextual(TrackImplTypeSerializer)
contextual(HistoryTypeSerializer)
// SY -->
contextual(MergedMangaTypeSerializer)
// SY <--
}
}
else -> throw Exception("Unknown backup version")
}
@@ -116,12 +120,11 @@ class LegacyBackupManager(context: Context, version: Int = CURRENT_VERSION) : Ab
/**
* Restore the categories from Json
*
* @param jsonCategories array containing categories
* @param backupCategories array containing categories
*/
internal fun restoreCategories(jsonCategories: JsonArray) {
internal fun restoreCategories(backupCategories: List<Category>) {
// Get categories from file and from db
val dbCategories = databaseHelper.getCategories().executeAsBlocking()
val backupCategories = parser.fromJson<List<CategoryImpl>>(jsonCategories)
// Iterate over them
backupCategories.forEach { category ->
@@ -281,58 +284,47 @@ class LegacyBackupManager(context: Context, version: Int = CURRENT_VERSION) : Ab
}
// SY -->
internal fun restoreSavedSearches(jsonSavedSearches: JsonElement) {
val backupSavedSearches = jsonSavedSearches.asString.split("***").toSet()
internal fun restoreSavedSearches(jsonSavedSearches: String) {
val backupSavedSearches = jsonSavedSearches.split("***").toSet()
val newSavedSearches = backupSavedSearches.mapNotNull {
try {
val id = it.substringBefore(':').toLong()
val content = Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
runCatching {
val id = it.substringBefore(':').toLongOrNull() ?: return@mapNotNull null
val content = parser.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
id to content
} catch (t: RuntimeException) {
// Load failed
Timber.e(t, "Failed to load saved search!")
t.printStackTrace()
null
}
}.toMutableList()
}.getOrNull()
}.toMutableSet()
val currentSources = newSavedSearches.map { it.first }.toSet()
val currentSources = newSavedSearches.map(Pair<Long, *>::first).toSet()
newSavedSearches += preferences.savedSearches().get().mapNotNull {
try {
val id = it.substringBefore(':').toLong()
val content = Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
kotlin.runCatching {
val id = it.substringBefore(':').toLongOrNull() ?: return@mapNotNull null
val content = parser.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
id to content
} catch (t: RuntimeException) {
// Load failed
Timber.e(t, "Failed to load saved search!")
t.printStackTrace()
null
}
}.toMutableList()
}.getOrNull()
}
val otherSerialized = preferences.savedSearches().get().mapNotNull {
val sourceId = it.split(":")[0].toLongOrNull() ?: return@mapNotNull null
val sourceId = it.substringBefore(":").toLongOrNull() ?: return@mapNotNull null
if (sourceId in currentSources) return@mapNotNull null
it
}
}.toSet()
val newSerialized = newSavedSearches.map {
"${it.first}:" + Json.encodeToString(it.second)
}
preferences.savedSearches().set((otherSerialized + newSerialized).toSet())
val newSerialized = newSavedSearches.map { (source, savedSearch) ->
"$source:" + Json.encodeToString(savedSearch)
}.toSet()
preferences.savedSearches().set(otherSerialized + newSerialized)
}
/**
* Restore the categories from Json
*
* @param jsonMergedMangaReferences array containing md manga references
* @param backupMergedMangaReferences array containing md manga references
*/
internal fun restoreMergedMangaReferences(jsonMergedMangaReferences: JsonArray) {
internal fun restoreMergedMangaReferences(backupMergedMangaReferences: List<MergedMangaReference>) {
// Get merged manga references from file and from db
val dbMergedMangaReferences = databaseHelper.getMergedMangaReferences().executeAsBlocking()
val backupMergedMangaReferences = parser.fromJson<List<MergedMangaReference>>(jsonMergedMangaReferences)
var lastMergeManga: Manga? = null
// Iterate over them
@@ -2,26 +2,26 @@ package eu.kanade.tachiyomi.data.backup.legacy
import android.content.Context
import android.net.Uri
import com.github.salomonbrys.kotson.fromJson
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.google.gson.stream.JsonReader
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.AbstractBackupRestore
import eu.kanade.tachiyomi.data.backup.BackupNotifier
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.MANGAS
import eu.kanade.tachiyomi.data.backup.legacy.models.DHistory
import eu.kanade.tachiyomi.data.backup.legacy.models.MangaObject
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.ChapterImpl
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaImpl
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.database.models.TrackImpl
import eu.kanade.tachiyomi.source.Source
import exh.EXHMigrations
import exh.merged.sql.models.MergedMangaReference
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.decodeFromJsonElement
import kotlinx.serialization.json.decodeFromStream
import kotlinx.serialization.json.intOrNull
import kotlinx.serialization.json.jsonPrimitive
import okio.source
import java.util.Date
class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : AbstractBackupRestore<LegacyBackupManager>(context, notifier) {
@@ -30,59 +30,59 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract
// SY -->
throttleManager.resetThrottle()
// SY <--
val reader = JsonReader(context.contentResolver.openInputStream(uri)!!.bufferedReader())
val json = JsonParser.parseReader(reader).asJsonObject
val version = json.get(Backup.VERSION)?.asInt ?: 1
// Read the json and create a Json Object,
// cannot use the backupManager json deserializer one because its not initialized yet
val backupObject = Json.decodeFromStream<JsonObject>(
context.contentResolver.openInputStream(uri)!!
)
// Get parser version
val version = backupObject["version"]?.jsonPrimitive?.intOrNull ?: 1
// Initialize manager
backupManager = LegacyBackupManager(context, version)
val mangasJson = json.get(MANGAS).asJsonArray
restoreAmount = mangasJson.size() + 3 // +1 for categories, +1 for saved searches, +1 for merged manga references
// Decode the json object to a Backup object
val backup = backupManager.parser.decodeFromJsonElement<Backup>(backupObject)
// Restore categories
json.get(Backup.CATEGORIES)?.let { restoreCategories(it) }
restoreAmount = backup.mangas.size + 3 // +1 for categories, +1 for saved searches, +1 for merged manga references
// SY -->
json.get(Backup.SAVEDSEARCHES)?.let { restoreSavedSearches(it) }
backup.savedSearches?.let { restoreSavedSearches(it) }
json.get(Backup.MERGEDMANGAREFERENCES)?.let { restoreMergedMangaReferences(it) }
backup.mergedMangaReferences?.let { restoreMergedMangaReferences(it) }
// SY <--
// Restore categories
backup.categories?.let { restoreCategories(it) }
// Store source mapping for error messages
sourceMapping = LegacyBackupRestoreValidator.getSourceMapping(json)
sourceMapping = LegacyBackupRestoreValidator.getSourceMapping(backup.extensions ?: emptyList())
// Restore individual manga
mangasJson.forEach {
backup.mangas.forEach {
if (job?.isActive != true) {
return false
}
restoreManga(it.asJsonObject)
restoreManga(it)
}
return true
}
private fun restoreCategories(categoriesJson: JsonElement) {
db.inTransaction {
backupManager.restoreCategories(categoriesJson.asJsonArray)
}
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.categories))
}
// SY -->
private fun restoreSavedSearches(savedSearchesJson: JsonElement) {
backupManager.restoreSavedSearches(savedSearchesJson)
private fun restoreSavedSearches(savedSearches: String) {
backupManager.restoreSavedSearches(savedSearches)
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.saved_searches))
}
private fun restoreMergedMangaReferences(mergedMangaReferencesJson: JsonElement) {
private fun restoreMergedMangaReferences(mergedMangaReferences: List<MergedMangaReference>) {
db.inTransaction {
backupManager.restoreMergedMangaReferences(mergedMangaReferencesJson.asJsonArray)
backupManager.restoreMergedMangaReferences(mergedMangaReferences)
}
restoreProgress += 1
@@ -90,28 +90,21 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract
}
// SY <--
private suspend fun restoreManga(mangaJson: JsonObject) {
val manga = backupManager.parser.fromJson<MangaImpl>(
mangaJson.get(
Backup.MANGA
)
)
val chapters = backupManager.parser.fromJson<List<ChapterImpl>>(
mangaJson.get(Backup.CHAPTERS)
?: JsonArray()
)
val categories = backupManager.parser.fromJson<List<String>>(
mangaJson.get(Backup.CATEGORIES)
?: JsonArray()
)
val history = backupManager.parser.fromJson<List<DHistory>>(
mangaJson.get(Backup.HISTORY)
?: JsonArray()
)
val tracks = backupManager.parser.fromJson<List<TrackImpl>>(
mangaJson.get(Backup.TRACK)
?: JsonArray()
)
private fun restoreCategories(categoriesJson: List<Category>) {
db.inTransaction {
backupManager.restoreCategories(categoriesJson)
}
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.categories))
}
private suspend fun restoreManga(mangaJson: MangaObject) {
val manga = mangaJson.manga
val chapters = mangaJson.chapters ?: emptyList()
val categories = mangaJson.categories ?: emptyList()
val history = mangaJson.history ?: emptyList()
val tracks = mangaJson.track ?: emptyList()
// EXH -->
EXHMigrations.migrateBackupEntry(manga)
@@ -2,14 +2,14 @@ package eu.kanade.tachiyomi.data.backup.legacy
import android.content.Context
import android.net.Uri
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.google.gson.stream.JsonReader
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.AbstractBackupRestoreValidator
import eu.kanade.tachiyomi.data.backup.ValidatorParseException
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup
import kotlinx.serialization.json.decodeFromStream
class LegacyBackupRestoreValidator : AbstractBackupRestoreValidator() {
/**
* Checks for critical backup file data.
*
@@ -17,30 +17,34 @@ class LegacyBackupRestoreValidator : AbstractBackupRestoreValidator() {
* @return List of missing sources or missing trackers.
*/
override fun validate(context: Context, uri: Uri): Results {
val reader = JsonReader(context.contentResolver.openInputStream(uri)!!.bufferedReader())
val json = JsonParser.parseReader(reader).asJsonObject
val backupManager = LegacyBackupManager(context)
val version = json.get(Backup.VERSION)
val mangasJson = json.get(Backup.MANGAS)
if (version == null || mangasJson == null) {
val backup = try {
backupManager.parser.decodeFromStream<Backup>(
context.contentResolver.openInputStream(uri)!!
)
} catch (e: Exception) {
throw ValidatorParseException(e)
}
if (backup.version == null) {
throw Exception(context.getString(R.string.invalid_backup_file_missing_data))
}
val mangas = mangasJson.asJsonArray
if (mangas.size() == 0) {
if (backup.mangas.isEmpty()) {
throw Exception(context.getString(R.string.invalid_backup_file_missing_manga))
}
val sources = getSourceMapping(json)
val sources = getSourceMapping(backup.extensions ?: emptyList())
val missingSources = sources
.filter { sourceManager.get(it.key) == null }
.values
.sorted()
val trackers = mangas
.filter { it.asJsonObject.has("track") }
.flatMap { it.asJsonObject["track"].asJsonArray }
.map { it.asJsonObject["s"].asInt }
val trackers = backup.mangas
.filterNot { it.track.isNullOrEmpty() }
.flatMap { it.track ?: emptyList() }
.map { it.sync_id }
.distinct()
val missingTrackers = trackers
.mapNotNull { trackManager.getService(it) }
@@ -52,15 +56,11 @@ class LegacyBackupRestoreValidator : AbstractBackupRestoreValidator() {
}
companion object {
fun getSourceMapping(json: JsonObject): Map<Long, String> {
val extensionsMapping = json.get(Backup.EXTENSIONS) ?: return emptyMap()
return extensionsMapping.asJsonArray
.map {
val items = it.asString.split(":")
items[0].toLong() to items[1]
}
.toMap()
fun getSourceMapping(extensionsMapping: List<String>): Map<Long, String> {
return extensionsMapping.associate {
val items = it.split(":")
items[0].toLong() to items[1]
}
}
}
}
@@ -1,30 +1,43 @@
package eu.kanade.tachiyomi.data.backup.legacy.models
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.Track
import exh.merged.sql.models.MergedMangaReference
import kotlinx.serialization.Contextual
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
/**
* Json values
*/
object Backup {
const val CURRENT_VERSION = 2
const val MANGA = "manga"
const val MANGAS = "mangas"
const val TRACK = "track"
const val CHAPTERS = "chapters"
const val CATEGORIES = "categories"
const val EXTENSIONS = "extensions"
const val HISTORY = "history"
const val VERSION = "version"
@Serializable
data class Backup(
val version: Int? = null,
var mangas: MutableList<MangaObject> = mutableListOf(),
var categories: List<@Contextual Category>? = null,
var extensions: List<String>? = null,
// SY Specific values
@SerialName("mergedmangareferences")
var mergedMangaReferences: List<@Contextual MergedMangaReference>? = null,
var savedSearches: String? = null
) {
companion object {
const val CURRENT_VERSION = 2
// SY -->
const val SAVEDSEARCHES = "savedsearches"
const val MERGEDMANGAREFERENCES = "mergedmangareferences"
// SY <--
fun getDefaultFilename(): String {
val date = SimpleDateFormat("yyyy-MM-dd_HH-mm", Locale.getDefault()).format(Date())
return "tachiyomi_$date.json"
fun getDefaultFilename(): String {
val date = SimpleDateFormat("yyyy-MM-dd_HH-mm", Locale.getDefault()).format(Date())
return "tachiyomi_$date.json"
}
}
}
@Serializable
data class MangaObject(
var manga: @Contextual Manga,
var chapters: List<@Contextual Chapter>? = null,
var categories: List<String>? = null,
var track: List<@Contextual Track>? = null,
var history: List<@Contextual DHistory>? = null
)
@@ -1,31 +0,0 @@
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
import eu.kanade.tachiyomi.data.database.models.CategoryImpl
/**
* JSON Serializer used to write / read [CategoryImpl] to / from json
*/
object CategoryTypeAdapter {
fun build(): TypeAdapter<CategoryImpl> {
return typeAdapter {
write {
beginArray()
value(it.name)
value(it.order)
endArray()
}
read {
beginArray()
val category = CategoryImpl()
category.name = nextString()
category.order = nextInt()
endArray()
category
}
}
}
}
@@ -0,0 +1,49 @@
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.CategoryImpl
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonEncoder
import kotlinx.serialization.json.add
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.int
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonPrimitive
/**
* JSON Serializer used to write / read [CategoryImpl] to / from json
*/
open class CategoryBaseSerializer<T : Category> : KSerializer<T> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Category")
override fun serialize(encoder: Encoder, value: T) {
encoder as JsonEncoder
encoder.encodeJsonElement(
buildJsonArray {
add(value.name)
add(value.order)
}
)
}
@Suppress("UNCHECKED_CAST")
override fun deserialize(decoder: Decoder): T {
// make a category impl and cast as T so that the serializer accepts it
return CategoryImpl().apply {
decoder as JsonDecoder
val array = decoder.decodeJsonElement().jsonArray
name = array[0].jsonPrimitive.content
order = array[1].jsonPrimitive.int
} as T
}
}
// Allow for serialization of a category and category impl
object CategoryTypeSerializer : CategoryBaseSerializer<Category>()
object CategoryImplTypeSerializer : CategoryBaseSerializer<CategoryImpl>()
@@ -1,59 +0,0 @@
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonToken
import eu.kanade.tachiyomi.data.database.models.ChapterImpl
/**
* JSON Serializer used to write / read [ChapterImpl] to / from json
*/
object ChapterTypeAdapter {
private const val URL = "u"
private const val READ = "r"
private const val BOOKMARK = "b"
private const val LAST_READ = "l"
fun build(): TypeAdapter<ChapterImpl> {
return typeAdapter {
write {
if (it.read || it.bookmark || it.last_page_read != 0) {
beginObject()
name(URL)
value(it.url)
if (it.read) {
name(READ)
value(1)
}
if (it.bookmark) {
name(BOOKMARK)
value(1)
}
if (it.last_page_read != 0) {
name(LAST_READ)
value(it.last_page_read)
}
endObject()
}
}
read {
val chapter = ChapterImpl()
beginObject()
while (hasNext()) {
if (peek() == JsonToken.NAME) {
when (nextName()) {
URL -> chapter.url = nextString()
READ -> chapter.read = nextInt() == 1
BOOKMARK -> chapter.bookmark = nextInt() == 1
LAST_READ -> chapter.last_page_read = nextInt()
}
}
}
endObject()
chapter
}
}
}
}
@@ -0,0 +1,66 @@
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.ChapterImpl
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonEncoder
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.intOrNull
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.put
/**
* JSON Serializer used to write / read [ChapterImpl] to / from json
*/
open class ChapterBaseSerializer<T : Chapter> : KSerializer<T> {
override val descriptor = buildClassSerialDescriptor("Chapter")
override fun serialize(encoder: Encoder, value: T) {
encoder as JsonEncoder
encoder.encodeJsonElement(
buildJsonObject {
put(URL, value.url)
if (value.read) {
put(READ, 1)
}
if (value.bookmark) {
put(BOOKMARK, 1)
}
if (value.last_page_read != 0) {
put(LAST_READ, value.last_page_read)
}
}
)
}
@Suppress("UNCHECKED_CAST")
override fun deserialize(decoder: Decoder): T {
// make a chapter impl and cast as T so that the serializer accepts it
return ChapterImpl().apply {
decoder as JsonDecoder
val jsonObject = decoder.decodeJsonElement().jsonObject
url = jsonObject[URL]!!.jsonPrimitive.content
read = jsonObject[READ]?.jsonPrimitive?.intOrNull == 1
bookmark = jsonObject[BOOKMARK]?.jsonPrimitive?.intOrNull == 1
last_page_read = jsonObject[LAST_READ]?.jsonPrimitive?.intOrNull ?: last_page_read
} as T
}
companion object {
private const val URL = "u"
private const val READ = "r"
private const val BOOKMARK = "b"
private const val LAST_READ = "l"
}
}
// Allow for serialization of a chapter and chapter impl
object ChapterTypeSerializer : ChapterBaseSerializer<Chapter>()
object ChapterImplTypeSerializer : ChapterBaseSerializer<ChapterImpl>()
@@ -1,32 +0,0 @@
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
import eu.kanade.tachiyomi.data.backup.legacy.models.DHistory
/**
* JSON Serializer used to write / read [DHistory] to / from json
*/
object HistoryTypeAdapter {
fun build(): TypeAdapter<DHistory> {
return typeAdapter {
write {
if (it.lastRead != 0L) {
beginArray()
value(it.url)
value(it.lastRead)
endArray()
}
}
read {
beginArray()
val url = nextString()
val lastRead = nextLong()
endArray()
DHistory(url, lastRead)
}
}
}
}
@@ -0,0 +1,41 @@
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import eu.kanade.tachiyomi.data.backup.legacy.models.DHistory
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonEncoder
import kotlinx.serialization.json.add
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.long
/**
* JSON Serializer used to write / read [DHistory] to / from json
*/
object HistoryTypeSerializer : KSerializer<DHistory> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("History")
override fun serialize(encoder: Encoder, value: DHistory) {
encoder as JsonEncoder
encoder.encodeJsonElement(
buildJsonArray {
add(value.url)
add(value.lastRead)
}
)
}
override fun deserialize(decoder: Decoder): DHistory {
decoder as JsonDecoder
val array = decoder.decodeJsonElement().jsonArray
return DHistory(
url = array[0].jsonPrimitive.content,
lastRead = array[1].jsonPrimitive.long
)
}
}
@@ -1,39 +0,0 @@
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
import eu.kanade.tachiyomi.data.database.models.MangaImpl
/**
* JSON Serializer used to write / read [MangaImpl] to / from json
*/
object MangaTypeAdapter {
fun build(): TypeAdapter<MangaImpl> {
return typeAdapter {
write {
beginArray()
value(it.url)
// SY -->
value(it.originalTitle)
// SY <--
value(it.source)
value(it.viewer_flags)
value(it.chapter_flags)
endArray()
}
read {
beginArray()
val manga = MangaImpl()
manga.url = nextString()
manga.title = nextString()
manga.source = nextLong()
manga.viewer_flags = nextInt()
manga.chapter_flags = nextInt()
endArray()
manga
}
}
}
}
@@ -0,0 +1,56 @@
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaImpl
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonEncoder
import kotlinx.serialization.json.add
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.int
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.long
/**
* JSON Serializer used to write / read [MangaImpl] to / from json
*/
open class MangaBaseSerializer<T : Manga> : KSerializer<T> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Manga")
override fun serialize(encoder: Encoder, value: T) {
encoder as JsonEncoder
encoder.encodeJsonElement(
buildJsonArray {
add(value.url)
add(value.title)
add(value.source)
add(value.viewer_flags)
add(value.chapter_flags)
}
)
}
@Suppress("UNCHECKED_CAST")
override fun deserialize(decoder: Decoder): T {
// make a manga impl and cast as T so that the serializer accepts it
return MangaImpl().apply {
decoder as JsonDecoder
val array = decoder.decodeJsonElement().jsonArray
url = array[0].jsonPrimitive.content
title = array[1].jsonPrimitive.content
source = array[2].jsonPrimitive.long
viewer_flags = array[3].jsonPrimitive.int
chapter_flags = array[4].jsonPrimitive.int
} as T
}
}
// Allow for serialization of a manga and manga impl
object MangaTypeSerializer : MangaBaseSerializer<Manga>()
object MangaImplTypeSerializer : MangaBaseSerializer<MangaImpl>()
@@ -1,45 +0,0 @@
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
import exh.merged.sql.models.MergedMangaReference
/**
* JSON Serializer used to write / read [MergedMangaReference] to / from json
*/
object MergedMangaReferenceTypeAdapter {
fun build(): TypeAdapter<MergedMangaReference> {
return typeAdapter {
write {
beginArray()
value(it.mangaUrl)
value(it.mergeUrl)
value(it.mangaSourceId)
value(it.chapterSortMode)
value(it.chapterPriority)
value(it.getChapterUpdates)
value(it.isInfoManga)
value(it.downloadChapters)
endArray()
}
read {
beginArray()
MergedMangaReference(
id = null,
mangaUrl = nextString(),
mergeUrl = nextString(),
mangaSourceId = nextLong(),
chapterSortMode = nextInt(),
chapterPriority = nextInt(),
getChapterUpdates = nextBoolean(),
isInfoManga = nextBoolean(),
downloadChapters = nextBoolean(),
mangaId = null,
mergeId = null
)
}
}
}
}
@@ -0,0 +1,58 @@
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import exh.merged.sql.models.MergedMangaReference
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonEncoder
import kotlinx.serialization.json.add
import kotlinx.serialization.json.boolean
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.int
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.long
/**
* JSON Serializer used to write / read [MergedMangaReference] to / from json
*/
object MergedMangaTypeSerializer : KSerializer<MergedMangaReference> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Manga")
override fun serialize(encoder: Encoder, value: MergedMangaReference) {
encoder as JsonEncoder
encoder.encodeJsonElement(
buildJsonArray {
add(value.mangaUrl)
add(value.mergeUrl)
add(value.mangaSourceId)
add(value.chapterSortMode)
add(value.chapterPriority)
add(value.getChapterUpdates)
add(value.isInfoManga)
add(value.downloadChapters)
}
)
}
override fun deserialize(decoder: Decoder): MergedMangaReference {
decoder as JsonDecoder
val array = decoder.decodeJsonElement().jsonArray
return MergedMangaReference(
id = null,
mangaUrl = array[0].jsonPrimitive.content,
mergeUrl = array[1].jsonPrimitive.content,
mangaSourceId = array[2].jsonPrimitive.long,
chapterSortMode = array[3].jsonPrimitive.int,
chapterPriority = array[4].jsonPrimitive.int,
getChapterUpdates = array[5].jsonPrimitive.boolean,
isInfoManga = array[6].jsonPrimitive.boolean,
downloadChapters = array[7].jsonPrimitive.boolean,
mangaId = null,
mergeId = null
)
}
}
@@ -1,59 +0,0 @@
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonToken
import eu.kanade.tachiyomi.data.database.models.TrackImpl
/**
* JSON Serializer used to write / read [TrackImpl] to / from json
*/
object TrackTypeAdapter {
private const val SYNC = "s"
private const val MEDIA = "r"
private const val LIBRARY = "ml"
private const val TITLE = "t"
private const val LAST_READ = "l"
private const val TRACKING_URL = "u"
fun build(): TypeAdapter<TrackImpl> {
return typeAdapter {
write {
beginObject()
name(TITLE)
value(it.title)
name(SYNC)
value(it.sync_id)
name(MEDIA)
value(it.media_id)
name(LIBRARY)
value(it.library_id)
name(LAST_READ)
value(it.last_chapter_read)
name(TRACKING_URL)
value(it.tracking_url)
endObject()
}
read {
val track = TrackImpl()
beginObject()
while (hasNext()) {
if (peek() == JsonToken.NAME) {
when (nextName()) {
TITLE -> track.title = nextString()
SYNC -> track.sync_id = nextInt()
MEDIA -> track.media_id = nextInt()
LIBRARY -> track.library_id = nextLong()
LAST_READ -> track.last_chapter_read = nextInt()
TRACKING_URL -> track.tracking_url = nextString()
}
}
}
endObject()
track
}
}
}
}
@@ -0,0 +1,68 @@
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.database.models.TrackImpl
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonEncoder
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.float
import kotlinx.serialization.json.int
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.long
import kotlinx.serialization.json.put
/**
* JSON Serializer used to write / read [TrackImpl] to / from json
*/
open class TrackBaseSerializer<T : Track> : KSerializer<T> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Track")
override fun serialize(encoder: Encoder, value: T) {
encoder as JsonEncoder
encoder.encodeJsonElement(
buildJsonObject {
put(TITLE, value.title)
put(SYNC, value.sync_id)
put(MEDIA, value.media_id)
put(LIBRARY, value.library_id)
put(LAST_READ, value.last_chapter_read)
put(TRACKING_URL, value.tracking_url)
}
)
}
@Suppress("UNCHECKED_CAST")
override fun deserialize(decoder: Decoder): T {
// make a track impl and cast as T so that the serializer accepts it
return TrackImpl().apply {
decoder as JsonDecoder
val jsonObject = decoder.decodeJsonElement().jsonObject
title = jsonObject[TITLE]!!.jsonPrimitive.content
sync_id = jsonObject[SYNC]!!.jsonPrimitive.int
media_id = jsonObject[MEDIA]!!.jsonPrimitive.int
library_id = jsonObject[LIBRARY]!!.jsonPrimitive.long
last_chapter_read = jsonObject[LAST_READ]!!.jsonPrimitive.float
tracking_url = jsonObject[TRACKING_URL]!!.jsonPrimitive.content
} as T
}
companion object {
private const val SYNC = "s"
private const val MEDIA = "r"
private const val LIBRARY = "ml"
private const val TITLE = "t"
private const val LAST_READ = "l"
private const val TRACKING_URL = "u"
}
}
// Allow for serialization of a track and track impl
object TrackTypeSerializer : TrackBaseSerializer<Track>()
object TrackImplTypeSerializer : TrackBaseSerializer<TrackImpl>()
@@ -10,6 +10,7 @@ import coil.network.HttpException
import coil.request.get
import coil.size.Size
import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher.Companion.USE_CUSTOM_COVER
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.await
@@ -27,7 +28,6 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.io.File
import java.util.Date
/**
* Coil component that fetches [Manga] cover while using the cached file in disk when available.
@@ -62,14 +62,15 @@ class MangaCoverFetcher : Fetcher<Manga> {
}
private suspend fun httpLoader(manga: Manga, options: Options): FetchResult {
val coverFile = coverCache.getCoverFile(manga) ?: error("No cover specified")
// Only cache separately if it's a library item
val coverCacheFile = if (manga.favorite) {
coverCache.getCoverFile(manga) ?: error("No cover specified")
} else {
null
}
// Use previously cached cover if exist
if (coverFile.exists() && options.diskCachePolicy.readEnabled) {
if (!manga.favorite) {
coverFile.setLastModified(Date().time)
}
return fileLoader(coverFile)
if (coverCacheFile?.exists() == true && options.diskCachePolicy.readEnabled) {
return fileLoader(coverCacheFile)
}
val (response, body) = awaitGetCall(manga, options)
@@ -78,18 +79,16 @@ class MangaCoverFetcher : Fetcher<Manga> {
throw HttpException(response)
}
// Write to disk for future use
if (options.diskCachePolicy.writeEnabled) {
if (coverCacheFile != null && options.diskCachePolicy.writeEnabled) {
@Suppress("BlockingMethodInNonBlockingContext")
response.peekBody(Long.MAX_VALUE).source().use { input ->
val tmpFile = File(coverFile.absolutePath + "_tmp")
tmpFile.parentFile?.mkdirs()
tmpFile.sink().buffer().use { output ->
coverCacheFile.parentFile?.mkdirs()
if (coverCacheFile.exists()) {
coverCacheFile.delete()
}
coverCacheFile.sink().buffer().use { output ->
output.writeAll(input)
}
if (coverFile.exists()) {
coverFile.delete()
}
tmpFile.renameTo(coverFile)
}
}
@@ -108,10 +107,6 @@ class MangaCoverFetcher : Fetcher<Manga> {
private fun getCall(manga: Manga, options: Options): Call {
val source = sourceManager.get(manga.source) as? HttpSource
val client = source?.client ?: defaultClient
val newClient = client.newBuilder().build()
val request = Request.Builder().url(manga.thumbnail_url!!).also {
if (source != null) {
it.headers(source.headers)
@@ -135,7 +130,8 @@ class MangaCoverFetcher : Fetcher<Manga> {
}
}.build()
return newClient.newCall(request)
val client = source?.client?.newBuilder()?.cache(defaultClient.cache)?.build() ?: defaultClient
return client.newCall(request)
}
private fun fileLoader(manga: Manga): FetchResult {
@@ -153,7 +149,7 @@ class MangaCoverFetcher : Fetcher<Manga> {
private fun getResourceType(cover: String?): Type? {
return when {
cover.isNullOrEmpty() -> null
cover.startsWith("http") || cover.startsWith("Custom-", true) -> Type.URL
cover.startsWith("http", true) || cover.startsWith("Custom-", true) -> Type.URL
cover.startsWith("/") || cover.startsWith("file://") -> Type.File
else -> null
}
@@ -0,0 +1,53 @@
package eu.kanade.tachiyomi.data.coil
import android.content.res.Resources
import android.os.Build
import androidx.core.graphics.drawable.toDrawable
import coil.bitmap.BitmapPool
import coil.decode.DecodeResult
import coil.decode.Decoder
import coil.decode.Options
import coil.size.Size
import eu.kanade.tachiyomi.util.system.ImageUtil
import okio.BufferedSource
import tachiyomi.decoder.ImageDecoder
/**
* A [Decoder] that uses built-in [ImageDecoder] to decode images that is not supported by the system.
*/
class TachiyomiImageDecoder(private val resources: Resources) : Decoder {
override fun handles(source: BufferedSource, mimeType: String?): Boolean {
val type = source.peek().inputStream().use {
ImageUtil.findImageType(it)
}
return when (type) {
ImageUtil.ImageType.AVIF, ImageUtil.ImageType.JXL -> true
ImageUtil.ImageType.HEIF -> Build.VERSION.SDK_INT < Build.VERSION_CODES.O
else -> false
}
}
override suspend fun decode(
pool: BitmapPool,
source: BufferedSource,
size: Size,
options: Options
): DecodeResult {
val decoder = source.use {
ImageDecoder.newInstance(it.inputStream())
}
check(decoder != null && decoder.width > 0 && decoder.height > 0) { "Failed to initialize decoder." }
val bitmap = decoder.decode(rgb565 = options.allowRgb565)
decoder.recycle()
check(bitmap != null) { "Failed to decode image." }
return DecodeResult(
drawable = bitmap.toDrawable(resources),
isSampled = false
)
}
}
@@ -21,6 +21,9 @@ import eu.kanade.tachiyomi.data.database.queries.HistoryQueries
import eu.kanade.tachiyomi.data.database.queries.MangaCategoryQueries
import eu.kanade.tachiyomi.data.database.queries.MangaQueries
import eu.kanade.tachiyomi.data.database.queries.TrackQueries
import exh.favorites.sql.mappers.FavoriteEntryTypeMapping
import exh.favorites.sql.models.FavoriteEntry
import exh.favorites.sql.queries.FavoriteEntryQueries
import exh.merged.sql.mappers.MergedMangaTypeMapping
import exh.merged.sql.models.MergedMangaReference
import exh.merged.sql.queries.MergedQueries
@@ -39,7 +42,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory
* This class provides operations to manage the database through its interfaces.
*/
open class DatabaseHelper(context: Context) :
MangaQueries, ChapterQueries, TrackQueries, CategoryQueries, MangaCategoryQueries, HistoryQueries /* SY --> */, SearchMetadataQueries, SearchTagQueries, SearchTitleQueries, MergedQueries /* SY <-- */ {
MangaQueries, ChapterQueries, TrackQueries, CategoryQueries, MangaCategoryQueries, HistoryQueries /* SY --> */, SearchMetadataQueries, SearchTagQueries, SearchTitleQueries, MergedQueries, FavoriteEntryQueries /* SY <-- */ {
private val configuration = SupportSQLiteOpenHelper.Configuration.builder(context)
.name(DbOpenCallback.DATABASE_NAME)
@@ -59,6 +62,7 @@ open class DatabaseHelper(context: Context) :
.addTypeMapping(SearchTag::class.java, SearchTagTypeMapping())
.addTypeMapping(SearchTitle::class.java, SearchTitleTypeMapping())
.addTypeMapping(MergedMangaReference::class.java, MergedMangaTypeMapping())
.addTypeMapping(FavoriteEntry::class.java, FavoriteEntryTypeMapping())
// SY <--
.build()
@@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.data.database.tables.HistoryTable
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable
import eu.kanade.tachiyomi.data.database.tables.MangaTable
import eu.kanade.tachiyomi.data.database.tables.TrackTable
import exh.favorites.sql.tables.FavoriteEntryTable
import exh.merged.sql.tables.MergedTable
import exh.metadata.sql.tables.SearchMetadataTable
import exh.metadata.sql.tables.SearchTagTable
@@ -24,7 +25,7 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
/**
* Version of the database.
*/
const val DATABASE_VERSION = /* SY --> */ 7 /* SY <-- */
const val DATABASE_VERSION = /* SY --> */ 12 /* SY <-- */
}
override fun onCreate(db: SupportSQLiteDatabase) = with(db) {
@@ -39,6 +40,7 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
execSQL(SearchTagTable.createTableQuery)
execSQL(SearchTitleTable.createTableQuery)
execSQL(MergedTable.createTableQuery)
execSQL(FavoriteEntryTable.createTableQuery)
// SY <--
// DB indexes
@@ -81,6 +83,24 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
if (oldVersion < 7) {
db.execSQL("DROP TABLE IF EXISTS manga_related")
}
if (oldVersion < 8) {
db.execSQL(MangaTable.addNextUpdateCol)
}
if (oldVersion < 9) {
db.execSQL(TrackTable.renameTableToTemp)
db.execSQL(TrackTable.createTableQuery)
db.execSQL(TrackTable.insertFromTempTable)
db.execSQL(TrackTable.dropTempTable)
}
if (oldVersion < 10) {
db.execSQL(ChapterTable.fixDateUploadIfNeeded)
}
if (oldVersion < 11) {
db.execSQL(FavoriteEntryTable.createTableQuery)
}
if (oldVersion < 12) {
db.execSQL(FavoriteEntryTable.fixTableQuery)
}
}
override fun onConfigure(db: SupportSQLiteDatabase) {
@@ -49,13 +49,13 @@ class CategoryPutResolver : DefaultPutResolver<Category>() {
class CategoryGetResolver : DefaultGetResolver<Category>() {
override fun mapFromCursor(cursor: Cursor): Category = CategoryImpl().apply {
id = cursor.getInt(cursor.getColumnIndex(COL_ID))
name = cursor.getString(cursor.getColumnIndex(COL_NAME))
order = cursor.getInt(cursor.getColumnIndex(COL_ORDER))
flags = cursor.getInt(cursor.getColumnIndex(COL_FLAGS))
id = cursor.getInt(cursor.getColumnIndexOrThrow(COL_ID))
name = cursor.getString(cursor.getColumnIndexOrThrow(COL_NAME))
order = cursor.getInt(cursor.getColumnIndexOrThrow(COL_ORDER))
flags = cursor.getInt(cursor.getColumnIndexOrThrow(COL_FLAGS))
// SY -->
val orderString = cursor.getString(cursor.getColumnIndex(COL_MANGA_ORDER))
val orderString = cursor.getString(cursor.getColumnIndexOrThrow(COL_MANGA_ORDER))
mangaOrder = orderString?.split("/")?.mapNotNull { it.toLongOrNull() }.orEmpty()
// SY <--
}
@@ -63,18 +63,18 @@ class ChapterPutResolver : DefaultPutResolver<Chapter>() {
class ChapterGetResolver : DefaultGetResolver<Chapter>() {
override fun mapFromCursor(cursor: Cursor): Chapter = ChapterImpl().apply {
id = cursor.getLong(cursor.getColumnIndex(COL_ID))
manga_id = cursor.getLong(cursor.getColumnIndex(COL_MANGA_ID))
url = cursor.getString(cursor.getColumnIndex(COL_URL))
name = cursor.getString(cursor.getColumnIndex(COL_NAME))
scanlator = cursor.getString(cursor.getColumnIndex(COL_SCANLATOR))
read = cursor.getInt(cursor.getColumnIndex(COL_READ)) == 1
bookmark = cursor.getInt(cursor.getColumnIndex(COL_BOOKMARK)) == 1
date_fetch = cursor.getLong(cursor.getColumnIndex(COL_DATE_FETCH))
date_upload = cursor.getLong(cursor.getColumnIndex(COL_DATE_UPLOAD))
last_page_read = cursor.getInt(cursor.getColumnIndex(COL_LAST_PAGE_READ))
chapter_number = cursor.getFloat(cursor.getColumnIndex(COL_CHAPTER_NUMBER))
source_order = cursor.getInt(cursor.getColumnIndex(COL_SOURCE_ORDER))
id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_ID))
manga_id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_MANGA_ID))
url = cursor.getString(cursor.getColumnIndexOrThrow(COL_URL))
name = cursor.getString(cursor.getColumnIndexOrThrow(COL_NAME))
scanlator = cursor.getString(cursor.getColumnIndexOrThrow(COL_SCANLATOR))
read = cursor.getInt(cursor.getColumnIndexOrThrow(COL_READ)) == 1
bookmark = cursor.getInt(cursor.getColumnIndexOrThrow(COL_BOOKMARK)) == 1
date_fetch = cursor.getLong(cursor.getColumnIndexOrThrow(COL_DATE_FETCH))
date_upload = cursor.getLong(cursor.getColumnIndexOrThrow(COL_DATE_UPLOAD))
last_page_read = cursor.getInt(cursor.getColumnIndexOrThrow(COL_LAST_PAGE_READ))
chapter_number = cursor.getFloat(cursor.getColumnIndexOrThrow(COL_CHAPTER_NUMBER))
source_order = cursor.getInt(cursor.getColumnIndexOrThrow(COL_SOURCE_ORDER))
}
}
@@ -47,10 +47,10 @@ open class HistoryPutResolver : DefaultPutResolver<History>() {
class HistoryGetResolver : DefaultGetResolver<History>() {
override fun mapFromCursor(cursor: Cursor): History = HistoryImpl().apply {
id = cursor.getLong(cursor.getColumnIndex(COL_ID))
chapter_id = cursor.getLong(cursor.getColumnIndex(COL_CHAPTER_ID))
last_read = cursor.getLong(cursor.getColumnIndex(COL_LAST_READ))
time_read = cursor.getLong(cursor.getColumnIndex(COL_TIME_READ))
id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_ID))
chapter_id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_CHAPTER_ID))
last_read = cursor.getLong(cursor.getColumnIndexOrThrow(COL_LAST_READ))
time_read = cursor.getLong(cursor.getColumnIndexOrThrow(COL_TIME_READ))
}
}
@@ -44,9 +44,9 @@ class MangaCategoryPutResolver : DefaultPutResolver<MangaCategory>() {
class MangaCategoryGetResolver : DefaultGetResolver<MangaCategory>() {
override fun mapFromCursor(cursor: Cursor): MangaCategory = MangaCategory().apply {
id = cursor.getLong(cursor.getColumnIndex(COL_ID))
manga_id = cursor.getLong(cursor.getColumnIndex(COL_MANGA_ID))
category_id = cursor.getInt(cursor.getColumnIndex(COL_CATEGORY_ID))
id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_ID))
manga_id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_MANGA_ID))
category_id = cursor.getInt(cursor.getColumnIndexOrThrow(COL_CATEGORY_ID))
}
}
@@ -76,24 +76,24 @@ class MangaPutResolver : DefaultPutResolver<Manga>() {
interface BaseMangaGetResolver {
fun mapBaseFromCursor(manga: Manga, cursor: Cursor) = manga.apply {
id = cursor.getLong(cursor.getColumnIndex(COL_ID))
source = cursor.getLong(cursor.getColumnIndex(COL_SOURCE))
url = cursor.getString(cursor.getColumnIndex(COL_URL))
artist = cursor.getString(cursor.getColumnIndex(COL_ARTIST))
author = cursor.getString(cursor.getColumnIndex(COL_AUTHOR))
description = cursor.getString(cursor.getColumnIndex(COL_DESCRIPTION))
genre = cursor.getString(cursor.getColumnIndex(COL_GENRE))
title = cursor.getString(cursor.getColumnIndex(COL_TITLE))
status = cursor.getInt(cursor.getColumnIndex(COL_STATUS))
thumbnail_url = cursor.getString(cursor.getColumnIndex(COL_THUMBNAIL_URL))
favorite = cursor.getInt(cursor.getColumnIndex(COL_FAVORITE)) == 1
last_update = cursor.getLong(cursor.getColumnIndex(COL_LAST_UPDATE))
initialized = cursor.getInt(cursor.getColumnIndex(COL_INITIALIZED)) == 1
viewer_flags = cursor.getInt(cursor.getColumnIndex(COL_VIEWER))
chapter_flags = cursor.getInt(cursor.getColumnIndex(COL_CHAPTER_FLAGS))
cover_last_modified = cursor.getLong(cursor.getColumnIndex(COL_COVER_LAST_MODIFIED))
date_added = cursor.getLong(cursor.getColumnIndex(COL_DATE_ADDED))
filtered_scanlators = cursor.getString(cursor.getColumnIndex(COL_FILTERED_SCANLATORS))
id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_ID))
source = cursor.getLong(cursor.getColumnIndexOrThrow(COL_SOURCE))
url = cursor.getString(cursor.getColumnIndexOrThrow(COL_URL))
artist = cursor.getString(cursor.getColumnIndexOrThrow(COL_ARTIST))
author = cursor.getString(cursor.getColumnIndexOrThrow(COL_AUTHOR))
description = cursor.getString(cursor.getColumnIndexOrThrow(COL_DESCRIPTION))
genre = cursor.getString(cursor.getColumnIndexOrThrow(COL_GENRE))
title = cursor.getString(cursor.getColumnIndexOrThrow(COL_TITLE))
status = cursor.getInt(cursor.getColumnIndexOrThrow(COL_STATUS))
thumbnail_url = cursor.getString(cursor.getColumnIndexOrThrow(COL_THUMBNAIL_URL))
favorite = cursor.getInt(cursor.getColumnIndexOrThrow(COL_FAVORITE)) == 1
last_update = cursor.getLong(cursor.getColumnIndexOrThrow(COL_LAST_UPDATE))
initialized = cursor.getInt(cursor.getColumnIndexOrThrow(COL_INITIALIZED)) == 1
viewer_flags = cursor.getInt(cursor.getColumnIndexOrThrow(COL_VIEWER))
chapter_flags = cursor.getInt(cursor.getColumnIndexOrThrow(COL_CHAPTER_FLAGS))
cover_last_modified = cursor.getLong(cursor.getColumnIndexOrThrow(COL_COVER_LAST_MODIFIED))
date_added = cursor.getLong(cursor.getColumnIndexOrThrow(COL_DATE_ADDED))
filtered_scanlators = cursor.getString(cursor.getColumnIndexOrThrow(COL_FILTERED_SCANLATORS))
}
}
@@ -65,19 +65,19 @@ class TrackPutResolver : DefaultPutResolver<Track>() {
class TrackGetResolver : DefaultGetResolver<Track>() {
override fun mapFromCursor(cursor: Cursor): Track = TrackImpl().apply {
id = cursor.getLong(cursor.getColumnIndex(COL_ID))
manga_id = cursor.getLong(cursor.getColumnIndex(COL_MANGA_ID))
sync_id = cursor.getInt(cursor.getColumnIndex(COL_SYNC_ID))
media_id = cursor.getInt(cursor.getColumnIndex(COL_MEDIA_ID))
library_id = cursor.getLong(cursor.getColumnIndex(COL_LIBRARY_ID))
title = cursor.getString(cursor.getColumnIndex(COL_TITLE))
last_chapter_read = cursor.getInt(cursor.getColumnIndex(COL_LAST_CHAPTER_READ))
total_chapters = cursor.getInt(cursor.getColumnIndex(COL_TOTAL_CHAPTERS))
status = cursor.getInt(cursor.getColumnIndex(COL_STATUS))
score = cursor.getFloat(cursor.getColumnIndex(COL_SCORE))
tracking_url = cursor.getString(cursor.getColumnIndex(COL_TRACKING_URL))
started_reading_date = cursor.getLong(cursor.getColumnIndex(COL_START_DATE))
finished_reading_date = cursor.getLong(cursor.getColumnIndex(COL_FINISH_DATE))
id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_ID))
manga_id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_MANGA_ID))
sync_id = cursor.getInt(cursor.getColumnIndexOrThrow(COL_SYNC_ID))
media_id = cursor.getInt(cursor.getColumnIndexOrThrow(COL_MEDIA_ID))
library_id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_LIBRARY_ID))
title = cursor.getString(cursor.getColumnIndexOrThrow(COL_TITLE))
last_chapter_read = cursor.getFloat(cursor.getColumnIndexOrThrow(COL_LAST_CHAPTER_READ))
total_chapters = cursor.getInt(cursor.getColumnIndexOrThrow(COL_TOTAL_CHAPTERS))
status = cursor.getInt(cursor.getColumnIndexOrThrow(COL_STATUS))
score = cursor.getFloat(cursor.getColumnIndexOrThrow(COL_SCORE))
tracking_url = cursor.getString(cursor.getColumnIndexOrThrow(COL_TRACKING_URL))
started_reading_date = cursor.getLong(cursor.getColumnIndexOrThrow(COL_START_DATE))
finished_reading_date = cursor.getLong(cursor.getColumnIndexOrThrow(COL_FINISH_DATE))
}
}
@@ -1,5 +1,10 @@
package eu.kanade.tachiyomi.data.database.models
import android.content.Context
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting
import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting
import java.io.Serializable
interface Category : Serializable {
@@ -16,12 +21,28 @@ interface Category : Serializable {
var mangaOrder: List<Long>
// SY <--
private fun setFlags(flag: Int, mask: Int) {
flags = flags and mask.inv() or (flag and mask)
}
var displayMode: Int
get() = flags and DisplayModeSetting.MASK
set(mode) = setFlags(mode, DisplayModeSetting.MASK)
var sortMode: Int
get() = flags and SortModeSetting.MASK
set(mode) = setFlags(mode, SortModeSetting.MASK)
var sortDirection: Int
get() = flags and SortDirectionSetting.MASK
set(mode) = setFlags(mode, SortDirectionSetting.MASK)
companion object {
fun create(name: String): Category = CategoryImpl().apply {
this.name = name
}
fun createDefault(): Category = create("Default").apply { id = 0 }
fun createDefault(context: Context): Category = create(context.getString(R.string.label_default)).apply { id = 0 }
}
}
@@ -13,6 +13,7 @@ interface Manga : SManga {
var favorite: Boolean
// last time the chapter list changed in any way
var last_update: Long
var date_added: Long
@@ -34,7 +35,8 @@ interface Manga : SManga {
}
fun getGenres(): List<String>? {
return genre?.split(", ")?.map { it.trim() }
if (genre.isNullOrBlank()) return null
return genre?.split(", ")?.map { it.trim() }?.filterNot { it.isBlank() }?.distinct()
}
// SY -->
@@ -12,8 +12,6 @@ open class MangaImpl : Manga {
override lateinit var url: String
// SY -->
private val customMangaManager: CustomMangaManager by injectLazy()
override var title: String
get() = if (favorite) {
val customTitle = customMangaManager.getManga(this)?.title
@@ -91,4 +89,10 @@ open class MangaImpl : Manga {
override fun hashCode(): Int {
return url.hashCode() + id.hashCode()
}
// SY -->
companion object {
private val customMangaManager: CustomMangaManager by injectLazy()
}
// SY <--
}
@@ -0,0 +1,3 @@
package eu.kanade.tachiyomi.data.database.models
data class SourceIdMangaCount(val source: Long, val count: Int)
@@ -16,7 +16,7 @@ interface Track : Serializable {
var title: String
var last_chapter_read: Int
var last_chapter_read: Float
var total_chapters: Int
@@ -14,7 +14,7 @@ class TrackImpl : Track {
override lateinit var title: String
override var last_chapter_read: Int = 0
override var last_chapter_read: Float = 0F
override var total_chapters: Int = 0
@@ -1,11 +1,14 @@
package eu.kanade.tachiyomi.data.database.queries
import com.pushtorefresh.storio.Queries
import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetListOfObjects
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery
import com.pushtorefresh.storio.sqlite.queries.Query
import com.pushtorefresh.storio.sqlite.queries.RawQuery
import eu.kanade.tachiyomi.data.database.DbProvider
import eu.kanade.tachiyomi.data.database.models.LibraryManga
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.SourceIdMangaCount
import eu.kanade.tachiyomi.data.database.resolvers.LibraryMangaGetResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaCoverLastModifiedPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaFavoritePutResolver
@@ -16,6 +19,7 @@ import eu.kanade.tachiyomi.data.database.resolvers.MangaLastUpdatedPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaMigrationPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaThumbnailPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaTitlePutResolver
import eu.kanade.tachiyomi.data.database.resolvers.SourceIdMangaCountGetResolver
import eu.kanade.tachiyomi.data.database.tables.CategoryTable
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable
@@ -25,15 +29,6 @@ import exh.metadata.sql.tables.SearchMetadataTable
interface MangaQueries : DbProvider {
fun getMangas() = db.get()
.listOfObjects(Manga::class.java)
.withQuery(
Query.builder()
.table(MangaTable.TABLE)
.build()
)
.prepare()
fun getLibraryMangas() = db.get()
.listOfObjects(LibraryManga::class.java)
.withQuery(
@@ -45,17 +40,21 @@ interface MangaQueries : DbProvider {
.withGetResolver(LibraryMangaGetResolver.INSTANCE)
.prepare()
fun getFavoriteMangas() = db.get()
.listOfObjects(Manga::class.java)
.withQuery(
Query.builder()
.table(MangaTable.TABLE)
.where("${MangaTable.COL_FAVORITE} = ?")
.whereArgs(1)
.orderBy(MangaTable.COL_TITLE)
.build()
)
.prepare()
fun getFavoriteMangas(sortByTitle: Boolean = true): PreparedGetListOfObjects<Manga> {
var queryBuilder = Query.builder()
.table(MangaTable.TABLE)
.where("${MangaTable.COL_FAVORITE} = ?")
.whereArgs(1)
if (sortByTitle) {
queryBuilder = queryBuilder.orderBy(MangaTable.COL_TITLE)
}
return db.get()
.listOfObjects(Manga::class.java)
.withQuery(queryBuilder.build())
.prepare()
}
fun getManga(url: String, sourceId: Long) = db.get()
.`object`(Manga::class.java)
@@ -79,7 +78,27 @@ interface MangaQueries : DbProvider {
)
.prepare()
fun getSourceIdsWithNonLibraryManga() = db.get()
.listOfObjects(SourceIdMangaCount::class.java)
.withQuery(
RawQuery.builder()
.query(getSourceIdsWithNonLibraryMangaQuery())
.observesTables(MangaTable.TABLE)
.build()
)
.withGetResolver(SourceIdMangaCountGetResolver.INSTANCE)
.prepare()
// SY -->
fun getMangas() = db.get()
.listOfObjects(Manga::class.java)
.withQuery(
Query.builder()
.table(MangaTable.TABLE)
.build()
)
.prepare()
fun getReadNotInLibraryMangas() = db.get()
.listOfObjects(Manga::class.java)
.withQuery(
@@ -121,7 +140,7 @@ interface MangaQueries : DbProvider {
fun updateChapterFlags(manga: List<Manga>) = db.put()
.objects(manga)
.withPutResolver(MangaFlagsPutResolver(MangaTable.COL_CHAPTER_FLAGS, Manga::chapter_flags, true))
.withPutResolver(MangaFlagsPutResolver(MangaTable.COL_CHAPTER_FLAGS, Manga::chapter_flags))
.prepare()
fun updateViewerFlags(manga: Manga) = db.put()
@@ -131,7 +150,7 @@ interface MangaQueries : DbProvider {
fun updateViewerFlags(manga: List<Manga>) = db.put()
.objects(manga)
.withPutResolver(MangaFlagsPutResolver(MangaTable.COL_VIEWER, Manga::viewer_flags, true))
.withPutResolver(MangaFlagsPutResolver(MangaTable.COL_VIEWER, Manga::viewer_flags))
.prepare()
fun updateLastUpdated(manga: Manga) = db.put()
@@ -165,30 +184,32 @@ interface MangaQueries : DbProvider {
fun deleteMangas(mangas: List<Manga>) = db.delete().objects(mangas).prepare()
fun deleteMangasNotInLibrary() = db.delete()
fun deleteMangasNotInLibraryBySourceIds(sourceIds: List<Long>) = db.delete()
.byQuery(
DeleteQuery.builder()
.table(MangaTable.TABLE)
// SY -->
.where(
"""
${MangaTable.COL_FAVORITE} = ? AND ${MangaTable.COL_ID} NOT IN (
${MangaTable.COL_FAVORITE} = ? AND ${MangaTable.COL_SOURCE} IN (${Queries.placeholders(sourceIds.size)}) AND ${MangaTable.COL_ID} NOT IN (
SELECT ${MergedTable.COL_MANGA_ID} FROM ${MergedTable.TABLE} WHERE ${MergedTable.COL_MANGA_ID} != ${MergedTable.COL_MERGE_ID}
)
""".trimIndent()
)
.whereArgs(0)
// SY <--
.whereArgs(0, *sourceIds.toTypedArray())
.build()
)
.prepare()
// SY -->
fun deleteMangasNotInLibraryAndNotRead() = db.delete()
fun deleteMangasNotInLibraryAndNotReadBySourceIds(sourceIds: List<Long>) = db.delete()
.byQuery(
DeleteQuery.builder()
.table(MangaTable.TABLE)
.where(
"""
${MangaTable.COL_FAVORITE} = ? AND ${MangaTable.COL_ID} NOT IN (
${MangaTable.COL_FAVORITE} = ? AND ${MangaTable.COL_SOURCE} IN (${Queries.placeholders(sourceIds.size)}) AND ${MangaTable.COL_ID} NOT IN (
SELECT ${MergedTable.COL_MANGA_ID} FROM ${MergedTable.TABLE} WHERE ${MergedTable.COL_MANGA_ID} != ${MergedTable.COL_MERGE_ID}
) AND ${MangaTable.COL_ID} NOT IN (
SELECT ${ChapterTable.COL_MANGA_ID} FROM ${ChapterTable.TABLE} WHERE ${ChapterTable.COL_READ} = 1 OR ${ChapterTable.COL_LAST_PAGE_READ} != 0
@@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.data.database.queries
import eu.kanade.tachiyomi.data.database.resolvers.SourceIdMangaCountGetResolver
import exh.source.MERGED_SOURCE_ID
import eu.kanade.tachiyomi.data.database.tables.CategoryTable as Category
import eu.kanade.tachiyomi.data.database.tables.ChapterTable as Chapter
@@ -241,3 +242,14 @@ fun getCategoriesForMangaQuery() =
${MangaCategory.TABLE}.${MangaCategory.COL_CATEGORY_ID}
WHERE ${MangaCategory.COL_MANGA_ID} = ?
"""
/** Query to get the list of sources in the database that have
* non-library manga, and how many
*/
fun getSourceIdsWithNonLibraryMangaQuery() =
"""
SELECT ${Manga.COL_SOURCE}, COUNT(*) as ${SourceIdMangaCountGetResolver.COL_COUNT}
FROM ${Manga.TABLE}
WHERE ${Manga.COL_FAVORITE} = 0
GROUP BY ${Manga.COL_SOURCE}
"""
@@ -27,9 +27,7 @@ class HistoryLastReadPutResolver : HistoryPutResolver() {
.build()
)
val putResult: PutResult
putResult = cursor.use { putCursor ->
cursor.use { putCursor ->
if (putCursor.count == 0) {
val insertQuery = mapToInsertQuery(history)
val insertedId = db.lowLevel().insert(insertQuery, mapToContentValues(history))
@@ -39,25 +37,15 @@ class HistoryLastReadPutResolver : HistoryPutResolver() {
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
}
}
putResult
}
/**
* Creates update query
* @param obj history object
*/
override fun mapToUpdateQuery(obj: History) = UpdateQuery.builder()
.table(HistoryTable.TABLE)
.where("${HistoryTable.COL_CHAPTER_ID} = ?")
.whereArgs(obj.chapter_id)
.build()
/**
* Create content query
* @param history object
*/
fun mapToUpdateContentValues(history: History) =
private fun mapToUpdateContentValues(history: History) =
contentValuesOf(
HistoryTable.COL_LAST_READ to history.last_read
)
@@ -16,10 +16,10 @@ class LibraryMangaGetResolver : DefaultGetResolver<LibraryManga>(), BaseMangaGet
val manga = LibraryManga()
mapBaseFromCursor(manga, cursor)
manga.unread = cursor.getInt(cursor.getColumnIndex(MangaTable.COL_UNREAD))
manga.category = cursor.getInt(cursor.getColumnIndex(MangaTable.COL_CATEGORY))
manga.unread = cursor.getInt(cursor.getColumnIndexOrThrow(MangaTable.COL_UNREAD))
manga.category = cursor.getInt(cursor.getColumnIndexOrThrow(MangaTable.COL_CATEGORY))
// SY -->
manga.read = cursor.getInt(cursor.getColumnIndex(MangaTable.COL_READ))
manga.read = cursor.getInt(cursor.getColumnIndexOrThrow(MangaTable.COL_READ))
// SY <--
return manga
@@ -20,7 +20,7 @@ class MangaChapterGetResolver : DefaultGetResolver<MangaChapter>() {
val manga = mangaGetResolver.mapFromCursor(cursor)
val chapter = chapterGetResolver.mapFromCursor(cursor)
manga.id = chapter.manga_id
manga.url = cursor.getString(cursor.getColumnIndex("mangaUrl"))
manga.url = cursor.getString(cursor.getColumnIndexOrThrow("mangaUrl"))
return MangaChapter(manga, chapter)
}
@@ -42,7 +42,7 @@ class MangaChapterHistoryGetResolver : DefaultGetResolver<MangaChapterHistory>()
// Make certain column conflicts are dealt with
manga.id = chapter.manga_id
manga.url = cursor.getString(cursor.getColumnIndex("mangaUrl"))
manga.url = cursor.getString(cursor.getColumnIndexOrThrow("mangaUrl"))
chapter.id = history.chapter_id
// Return result
@@ -22,8 +22,8 @@ class MangaFilteredScanlatorsPutResolver : PutResolver<Manga>() {
fun mapToUpdateQuery(manga: Manga) = UpdateQuery.builder()
.table(MangaTable.TABLE)
.where("${MangaTable.COL_FILTERED_SCANLATORS} = ?")
.whereArgs(manga.filtered_scanlators)
.where("${MangaTable.COL_ID} = ?")
.whereArgs(manga.id)
.build()
fun mapToContentValues(manga: Manga) = contentValuesOf(
@@ -10,7 +10,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.tables.MangaTable
import kotlin.reflect.KProperty1
class MangaFlagsPutResolver(private val colName: String, private val fieldGetter: KProperty1<Manga, Int>, private val updateAll: Boolean = false) : PutResolver<Manga>() {
class MangaFlagsPutResolver(private val colName: String, private val fieldGetter: KProperty1<Manga, Int>) : PutResolver<Manga>() {
override fun performPut(db: StorIOSQLite, manga: Manga) = db.inTransactionReturn {
val updateQuery = mapToUpdateQuery(manga)
@@ -20,21 +20,11 @@ class MangaFlagsPutResolver(private val colName: String, private val fieldGetter
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
}
fun mapToUpdateQuery(manga: Manga): UpdateQuery {
val builder = UpdateQuery.builder()
return if (updateAll) {
builder
.table(MangaTable.TABLE)
.build()
} else {
builder
.table(MangaTable.TABLE)
.where("${MangaTable.COL_ID} = ?")
.whereArgs(manga.id)
.build()
}
}
fun mapToUpdateQuery(manga: Manga) = UpdateQuery.builder()
.table(MangaTable.TABLE)
.where("${MangaTable.COL_ID} = ?")
.whereArgs(manga.id)
.build()
fun mapToContentValues(manga: Manga) =
contentValuesOf(
@@ -0,0 +1,23 @@
package eu.kanade.tachiyomi.data.database.resolvers
import android.annotation.SuppressLint
import android.database.Cursor
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
import eu.kanade.tachiyomi.data.database.models.SourceIdMangaCount
import eu.kanade.tachiyomi.data.database.tables.MangaTable
class SourceIdMangaCountGetResolver : DefaultGetResolver<SourceIdMangaCount>() {
companion object {
val INSTANCE = SourceIdMangaCountGetResolver()
const val COL_COUNT = "manga_count"
}
@SuppressLint("Range")
override fun mapFromCursor(cursor: Cursor): SourceIdMangaCount {
val sourceID = cursor.getLong(cursor.getColumnIndexOrThrow(MangaTable.COL_SOURCE))
val count = cursor.getInt(cursor.getColumnIndexOrThrow(COL_COUNT))
return SourceIdMangaCount(sourceID, count)
}
}
@@ -62,4 +62,7 @@ object ChapterTable {
val addScanlator: String
get() = "ALTER TABLE $TABLE ADD COLUMN $COL_SCANLATOR TEXT DEFAULT NULL"
val fixDateUploadIfNeeded: String
get() = "UPDATE $TABLE SET $COL_DATE_UPLOAD = $COL_DATE_FETCH WHERE $COL_DATE_UPLOAD = 0"
}
@@ -28,6 +28,9 @@ object MangaTable {
const val COL_LAST_UPDATE = "last_update"
// Not actually used anymore
const val COL_NEXT_UPDATE = "next_update"
const val COL_DATE_ADDED = "date_added"
const val COL_INITIALIZED = "initialized"
@@ -63,6 +66,7 @@ object MangaTable {
$COL_THUMBNAIL_URL TEXT,
$COL_FAVORITE INTEGER NOT NULL,
$COL_LAST_UPDATE LONG,
$COL_NEXT_UPDATE LONG,
$COL_INITIALIZED BOOLEAN NOT NULL,
$COL_VIEWER INTEGER NOT NULL,
$COL_CHAPTER_FLAGS INTEGER NOT NULL,
@@ -94,6 +98,11 @@ object MangaTable {
"ON $TABLE.$COL_ID = ${ChapterTable.TABLE}.${ChapterTable.COL_MANGA_ID} " +
"GROUP BY $TABLE.$COL_ID)"
val addNextUpdateCol: String
get() = "ALTER TABLE $TABLE ADD COLUMN $COL_NEXT_UPDATE LONG DEFAULT 0"
// SY -->
val addFilteredScanlators: String
get() = "ALTER TABLE $TABLE ADD COLUMN $COL_FILTERED_SCANLATORS TEXT"
// SY <--
}
@@ -39,7 +39,7 @@ object TrackTable {
$COL_MEDIA_ID INTEGER NOT NULL,
$COL_LIBRARY_ID INTEGER,
$COL_TITLE TEXT NOT NULL,
$COL_LAST_CHAPTER_READ INTEGER NOT NULL,
$COL_LAST_CHAPTER_READ REAL NOT NULL,
$COL_TOTAL_CHAPTERS INTEGER NOT NULL,
$COL_STATUS INTEGER NOT NULL,
$COL_SCORE FLOAT NOT NULL,
@@ -62,4 +62,19 @@ object TrackTable {
val addFinishDate: String
get() = "ALTER TABLE $TABLE ADD COLUMN $COL_FINISH_DATE LONG NOT NULL DEFAULT 0"
val renameTableToTemp: String
get() =
"ALTER TABLE $TABLE RENAME TO ${TABLE}_tmp"
val insertFromTempTable: String
get() =
"""
|INSERT INTO $TABLE($COL_ID,$COL_MANGA_ID,$COL_SYNC_ID,$COL_MEDIA_ID,$COL_LIBRARY_ID,$COL_TITLE,$COL_LAST_CHAPTER_READ,$COL_TOTAL_CHAPTERS,$COL_STATUS,$COL_SCORE,$COL_TRACKING_URL,$COL_START_DATE,$COL_FINISH_DATE)
|SELECT $COL_ID,$COL_MANGA_ID,$COL_SYNC_ID,$COL_MEDIA_ID,$COL_LIBRARY_ID,$COL_TITLE,$COL_LAST_CHAPTER_READ,$COL_TOTAL_CHAPTERS,$COL_STATUS,$COL_SCORE,$COL_TRACKING_URL,$COL_START_DATE,$COL_FINISH_DATE
|FROM ${TABLE}_tmp
""".trimMargin()
val dropTempTable: String
get() = "DROP TABLE ${TABLE}_tmp"
}
@@ -81,7 +81,7 @@ class DownloadCache(
if (sourceDir != null) {
val mangaDir = sourceDir.files[provider.getMangaDirName(manga)]
if (mangaDir != null) {
return provider.getValidChapterDirNames(chapter).any { it in mangaDir.files || "$it.cbz" in mangaDir.files }
return provider.getValidChapterDirNames(chapter).any { it in mangaDir.files }
}
}
return false
@@ -196,8 +196,6 @@ class DownloadCache(
provider.getValidChapterDirNames(chapter).forEach {
if (it in mangaDir.files) {
mangaDir.files -= it
} else if ("$it.cbz" in mangaDir.files) {
mangaDir.files -= "$it.cbz"
}
}
}
@@ -212,6 +210,7 @@ class DownloadCache(
}
}
}
// SY <--
/**
@@ -228,8 +227,6 @@ class DownloadCache(
provider.getValidChapterDirNames(chapter).forEach {
if (it in mangaDir.files) {
mangaDir.files -= it
} else if ("$it.cbz" in mangaDir.files) {
mangaDir.files -= "$it.cbz"
}
}
}
@@ -4,6 +4,7 @@ import android.content.Context
import com.hippo.unifile.UniFile
import com.jakewharton.rxrelay.BehaviorRelay
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.model.Download
@@ -13,8 +14,13 @@ import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.system.logcat
import exh.log.xLogE
import logcat.LogPriority
import rx.Observable
import timber.log.Timber
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
/**
@@ -24,7 +30,10 @@ import uy.kohesive.injekt.injectLazy
*
* @param context the application context.
*/
class DownloadManager(private val context: Context) {
class DownloadManager(
private val context: Context,
private val db: DatabaseHelper = Injekt.get()
) {
private val sourceManager: SourceManager by injectLazy()
private val preferences: PreferencesHelper by injectLazy()
@@ -32,7 +41,7 @@ class DownloadManager(private val context: Context) {
/**
* Downloads provider, used to retrieve the folders where the chapters are or should be stored.
*/
private val provider = DownloadProvider(context)
val provider = DownloadProvider(context)
/**
* Cache of downloaded chapters.
@@ -95,6 +104,23 @@ class DownloadManager(private val context: Context) {
downloader.clearQueue(isNotification)
}
fun startDownloadNow(chapter: Chapter) {
val download = downloader.queue.find { it.chapter.id == chapter.id } ?: return
val queue = downloader.queue.toMutableList()
queue.remove(download)
queue.add(0, download)
reorderQueue(queue)
if (isPaused()) {
if (DownloadService.isRunning(context)) {
downloader.start()
} else {
DownloadService.start(context)
}
}
}
fun isPaused() = downloader.isPaused()
/**
* Reorders the download queue.
*
@@ -200,7 +226,7 @@ class DownloadManager(private val context: Context) {
* @param download the download to cancel.
*/
fun deletePendingDownload(download: Download) {
deleteChapters(listOf(download.chapter), download.manga, download.source)
deleteChapters(listOf(download.chapter), download.manga, download.source, true)
}
fun deletePendingDownloads(vararg downloads: Download) {
@@ -208,7 +234,7 @@ class DownloadManager(private val context: Context) {
downloadsByManga.map { entry ->
val manga = entry.value.first().manga
val source = entry.value.first().source
deleteChapters(entry.value.map { it.chapter }, manga, source)
deleteChapters(entry.value.map { it.chapter }, manga, source, true)
}
}
@@ -218,9 +244,15 @@ class DownloadManager(private val context: Context) {
* @param chapters the list of chapters to delete.
* @param manga the manga of the chapters.
* @param source the source of the chapters.
* @param isCancelling true if it's simply cancelling a download
*/
fun deleteChapters(chapters: List<Chapter>, manga: Manga, source: Source): List<Chapter> {
val filteredChapters = getChaptersToDelete(chapters)
fun deleteChapters(chapters: List<Chapter>, manga: Manga, source: Source, isCancelling: Boolean = false): List<Chapter> {
val filteredChapters = if (isCancelling) {
chapters
} else {
getChaptersToDelete(chapters, manga)
}
launchIO {
removeFromDownloadQueue(filteredChapters)
@@ -297,7 +329,7 @@ class DownloadManager(private val context: Context) {
mangaFolder.delete()
cache.removeManga(manga)
} else {
Timber.e("Cache and download folder doesn't match for %s", manga.title)
xLogE("Cache and download folder doesn't match for " + manga.title)
}
}
return cleaned
@@ -325,7 +357,7 @@ class DownloadManager(private val context: Context) {
* @param manga the manga of the chapters.
*/
fun enqueueDeleteChapters(chapters: List<Chapter>, manga: Manga) {
pendingDeleter.addChapters(getChaptersToDelete(chapters), manga)
pendingDeleter.addChapters(getChaptersToDelete(chapters, manga), manga)
}
/**
@@ -349,27 +381,46 @@ class DownloadManager(private val context: Context) {
*/
fun renameChapter(source: Source, manga: Manga, oldChapter: Chapter, newChapter: Chapter) {
val oldNames = provider.getValidChapterDirNames(oldChapter)
val newName = provider.getChapterDirName(newChapter)
val mangaDir = provider.getMangaDir(manga, source)
// Assume there's only 1 version of the chapter name formats present
val oldFolder = oldNames.asSequence()
.mapNotNull { mangaDir.findFile(it) ?: mangaDir.findFile("$it.cbz") }
.firstOrNull()
val oldDownload = oldNames.asSequence()
.mapNotNull { mangaDir.findFile(it) }
.firstOrNull() ?: return
if (oldFolder?.renameTo(newName + if (oldFolder.name?.endsWith(".cbz") == true) ".cbz" else "") == true) {
var newName = provider.getChapterDirName(newChapter)
if (oldDownload.isFile && oldDownload.name?.endsWith(".cbz") == true) {
newName += ".cbz"
}
if (oldDownload.renameTo(newName)) {
cache.removeChapter(oldChapter, manga)
cache.addChapter(newName + if (oldFolder.name?.endsWith(".cbz") == true) ".cbz" else "", mangaDir, manga)
cache.addChapter(newName, mangaDir, manga)
} else {
Timber.e("Could not rename downloaded chapter: %s.", oldNames.joinToString())
logcat(LogPriority.ERROR) { "Could not rename downloaded chapter: ${oldNames.joinToString()}." }
}
}
private fun getChaptersToDelete(chapters: List<Chapter>): List<Chapter> {
return if (!preferences.removeBookmarkedChapters()) {
private fun getChaptersToDelete(chapters: List<Chapter>, manga: Manga): List<Chapter> {
// Retrieve the categories that are set to exclude from being deleted on read
val categoriesToExclude = preferences.removeExcludeCategories().get().map(String::toInt)
val categoriesForManga = db.getCategoriesForManga(manga).executeAsBlocking()
.mapNotNull { it.id }
.takeUnless { it.isEmpty() }
?: listOf(0)
return if (categoriesForManga.intersect(categoriesToExclude).isNotEmpty()) {
chapters.filterNot { it.read }
} else if (!preferences.removeBookmarkedChapters()) {
chapters.filterNot { it.bookmark }
} else {
chapters
}
}
fun renameMangaDir(oldTitle: String, newTitle: String, source: Long) {
val sourceDir = provider.findSourceDir(sourceManager.getOrStub(source)) ?: return
val mangaDir = sourceDir.findFile(DiskUtil.buildValidFilename(oldTitle), true) ?: return
mangaDir.renameTo(DiskUtil.buildValidFilename(newTitle))
}
}
@@ -52,7 +52,7 @@ internal class DownloadNotifier(private val context: Context) {
/**
* Updated when error is thrown
*/
var errorThrown = false
private var errorThrown = false
/**
* Updated when paused
@@ -105,6 +105,7 @@ internal class DownloadNotifier(private val context: Context) {
if (preferences.hideNotificationContent()) {
setContentTitle(downloadingProgressText)
setContentText(null)
} else {
val title = download.manga.title.chop(15)
val quotedTitle = Pattern.quote(title)
@@ -187,8 +188,8 @@ internal class DownloadNotifier(private val context: Context) {
fun onWarning(reason: String) {
with(errorNotificationBuilder) {
setContentTitle(context.getString(R.string.download_notifier_downloader_title))
setContentText(reason)
setSmallIcon(android.R.drawable.stat_sys_warning)
setStyle(NotificationCompat.BigTextStyle().bigText(reason))
setSmallIcon(R.drawable.ic_warning_white_24dp)
setAutoCancel(true)
clearActions()
setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context))
@@ -208,15 +209,14 @@ internal class DownloadNotifier(private val context: Context) {
* @param error string containing error information.
* @param chapter string containing chapter title.
*/
fun onError(error: String? = null, chapter: String? = null) {
fun onError(error: String? = null, chapter: String? = null, mangaTitle: String? = null) {
// Create notification
with(errorNotificationBuilder) {
setContentTitle(
chapter
?: context.getString(R.string.download_notifier_downloader_title)
mangaTitle?.plus(": $chapter") ?: context.getString(R.string.download_notifier_downloader_title)
)
setContentText(error ?: context.getString(R.string.download_notifier_unknown_error))
setSmallIcon(android.R.drawable.stat_sys_warning)
setSmallIcon(R.drawable.ic_warning_white_24dp)
clearActions()
setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context))
setProgress(0, 0, false)
@@ -155,7 +155,7 @@ class DownloadPendingDeleter(context: Context) {
* Returns a manga entry from a manga model.
*/
private fun Manga.toEntry(): MangaEntry {
return MangaEntry(id!!, url, title, source)
return MangaEntry(id!!, url, originalTitle, source)
}
/**
@@ -9,10 +9,11 @@ import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
import logcat.LogPriority
import uy.kohesive.injekt.injectLazy
/**
@@ -54,7 +55,7 @@ class DownloadProvider(private val context: Context) {
.createDirectory(getSourceDirName(source))
.createDirectory(getMangaDirName(manga))
} catch (e: Throwable) {
Timber.e(e, "Invalid download directory")
logcat(LogPriority.ERROR, e) { "Invalid download directory" }
throw Exception(context.getString(R.string.invalid_download_dir))
}
}
@@ -89,7 +90,7 @@ class DownloadProvider(private val context: Context) {
fun findChapterDir(chapter: Chapter, manga: Manga, source: Source): UniFile? {
val mangaDir = findMangaDir(manga, source)
return getValidChapterDirNames(chapter).asSequence()
.mapNotNull { mangaDir?.findFile(it, true) ?: mangaDir?.findFile("$it.cbz", true) }
.mapNotNull { mangaDir?.findFile(it, true) }
.firstOrNull()
}
@@ -104,7 +105,7 @@ class DownloadProvider(private val context: Context) {
val mangaDir = findMangaDir(manga, source) ?: return emptyList()
return chapters.mapNotNull { chapter ->
getValidChapterDirNames(chapter).asSequence()
.mapNotNull { mangaDir.findFile(it) ?: mangaDir.findFile("$it.cbz") }
.mapNotNull { mangaDir.findFile(it) }
.firstOrNull()
}
}
@@ -126,7 +127,7 @@ class DownloadProvider(private val context: Context) {
return mangaDir.listFiles().orEmpty().asList().filter {
chapters.find { chp ->
getValidChapterDirNames(chp).any { dir ->
mangaDir.findFile(dir) ?: mangaDir.findFile("$dir.cbz") != null
mangaDir.findFile(dir) != null
}
} == null || it.name?.endsWith(Downloader.TMP_DIR_SUFFIX) == true
}
@@ -173,10 +174,14 @@ class DownloadProvider(private val context: Context) {
* @param chapter the chapter to query.
*/
fun getValidChapterDirNames(chapter: Chapter): List<String> {
val chapterName = getChapterDirName(chapter)
return listOf(
getChapterDirName(chapter),
// Folder of images
chapterName,
// Archived chapters
"$chapterName.cbz",
// TODO: remove this
// Legacy chapter directory name used in v0.9.2 and before
DiskUtil.buildValidFilename(chapter.name)
)
@@ -4,25 +4,32 @@ import android.app.Notification
import android.app.Service
import android.content.Context
import android.content.Intent
import android.net.ConnectivityManager
import android.net.NetworkInfo.State.CONNECTED
import android.net.NetworkInfo.State.DISCONNECTED
import android.os.IBinder
import android.os.PowerManager
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import com.github.pwittchen.reactivenetwork.library.Connectivity
import com.github.pwittchen.reactivenetwork.library.ReactiveNetwork
import com.jakewharton.rxrelay.BehaviorRelay
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.util.lang.plusAssign
import eu.kanade.tachiyomi.util.lang.withUIContext
import eu.kanade.tachiyomi.util.system.acquireWakeLock
import eu.kanade.tachiyomi.util.system.connectivityManager
import eu.kanade.tachiyomi.util.system.isConnectedToWifi
import eu.kanade.tachiyomi.util.system.isOnline
import eu.kanade.tachiyomi.util.system.isServiceRunning
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.notification
import eu.kanade.tachiyomi.util.system.toast
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import logcat.LogPriority
import ru.beryukhov.reactivenetwork.ReactiveNetwork
import rx.subscriptions.CompositeSubscription
import uy.kohesive.injekt.injectLazy
@@ -58,6 +65,16 @@ class DownloadService : Service() {
fun stop(context: Context) {
context.stopService(Intent(context, DownloadService::class.java))
}
/**
* Returns the status of the service.
*
* @param context the application context.
* @return true if the service is running, false otherwise.
*/
fun isRunning(context: Context): Boolean {
return context.isServiceRunning(DownloadService::class.java)
}
}
private val downloadManager: DownloadManager by injectLazy()
@@ -69,16 +86,15 @@ class DownloadService : Service() {
*/
private lateinit var wakeLock: PowerManager.WakeLock
/**
* Subscriptions to store while the service is running.
*/
private lateinit var subscriptions: CompositeSubscription
private lateinit var ioScope: CoroutineScope
/**
* Called when the service is created.
*/
override fun onCreate() {
super.onCreate()
ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
startForeground(Notifications.ID_DOWNLOAD_CHAPTER_PROGRESS, getPlaceholderNotification())
wakeLock = acquireWakeLock(javaClass.name)
runningRelay.call(true)
@@ -91,6 +107,7 @@ class DownloadService : Service() {
* Called when the service is destroyed.
*/
override fun onDestroy() {
ioScope?.cancel()
runningRelay.call(false)
subscriptions.unsubscribe()
downloadManager.stopDownloads()
@@ -118,55 +135,56 @@ class DownloadService : Service() {
* @see onNetworkStateChanged
*/
private fun listenNetworkChanges() {
subscriptions += ReactiveNetwork.observeNetworkConnectivity(applicationContext)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ state ->
onNetworkStateChanged(state)
},
{
ReactiveNetwork()
.observeNetworkConnectivity(applicationContext)
.onEach {
withUIContext {
onNetworkStateChanged()
}
}
.catch { error ->
withUIContext {
logcat(LogPriority.ERROR, error)
toast(R.string.download_queue_error)
stopSelf()
}
)
}
.launchIn(ioScope)
}
/**
* Called when the network state changes.
*
* @param connectivity the new network state.
*/
private fun onNetworkStateChanged(connectivity: Connectivity) {
when (connectivity.state) {
CONNECTED -> {
if (preferences.downloadOnlyOverWifi() && connectivityManager.activeNetworkInfo?.type != ConnectivityManager.TYPE_WIFI) {
downloadManager.stopDownloads(getString(R.string.download_notifier_text_only_wifi))
} else {
val started = downloadManager.startDownloads()
if (!started) stopSelf()
}
}
DISCONNECTED -> {
downloadManager.stopDownloads(getString(R.string.download_notifier_no_network))
}
else -> {
/* Do nothing */
private fun onNetworkStateChanged() {
if (isOnline()) {
if (preferences.downloadOnlyOverWifi() && !isConnectedToWifi()) {
stopDownloads(R.string.download_notifier_text_only_wifi)
} else {
val started = downloadManager.startDownloads()
if (!started) stopSelf()
}
} else {
stopDownloads(R.string.download_notifier_no_network)
}
}
private fun stopDownloads(@StringRes string: Int) {
downloadManager.stopDownloads(getString(string))
}
/**
* Listens to downloader status. Enables or disables the wake lock depending on the status.
*/
private fun listenDownloaderState() {
subscriptions += downloadManager.runningRelay.subscribe { running ->
if (running) {
wakeLock.acquireIfNeeded()
} else {
wakeLock.releaseIfNeeded()
subscriptions += downloadManager.runningRelay
.doOnError { /* Swallow wakelock error */ }
.subscribe { running ->
if (running) {
wakeLock.acquireIfNeeded()
} else {
wakeLock.releaseIfNeeded()
}
}
}
}
/**
@@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.UnmeteredSource
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.fetchAllImageUrlsFromPageList
@@ -23,13 +24,16 @@ import eu.kanade.tachiyomi.util.lang.plusAssign
import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.storage.saveTo
import eu.kanade.tachiyomi.util.system.ImageUtil
import eu.kanade.tachiyomi.util.system.logcat
import exh.util.DataSaver
import exh.util.DataSaver.Companion.fetchImage
import kotlinx.coroutines.async
import logcat.LogPriority
import okhttp3.Response
import rx.Observable
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import rx.subscriptions.CompositeSubscription
import timber.log.Timber
import uy.kohesive.injekt.injectLazy
import java.io.BufferedOutputStream
import java.io.File
@@ -58,10 +62,10 @@ class Downloader(
private val sourceManager: SourceManager
) {
private val preferences: PreferencesHelper by injectLazy()
private val chapterCache: ChapterCache by injectLazy()
private val preferences: PreferencesHelper by injectLazy()
/**
* Store for persisting downloads across restarts.
*/
@@ -164,6 +168,11 @@ class Downloader(
notifier.paused = true
}
/**
* Check if downloader is paused
*/
fun isPaused() = !isRunning
/**
* Removes everything from the queue.
*
@@ -211,7 +220,7 @@ class Downloader(
},
{ error ->
DownloadService.stop(context)
Timber.e(error)
logcat(LogPriority.ERROR, error)
notifier.onError(error.message)
}
)
@@ -264,7 +273,17 @@ class Downloader(
// Start downloader if needed
if (autoStart && wasEmpty) {
DownloadService.start(this@Downloader.context)
val maxDownloadsFromSource = queue
.groupBy { it.source }
.filterKeys { it !is UnmeteredSource }
.maxOf { it.value.size }
// TODO: re-enable warning
if (maxDownloadsFromSource > CHAPTERS_PER_SOURCE_QUEUE_WARNING_THRESHOLD) {
// withUIContext {
// context.toast(R.string.download_queue_size_warning, Toast.LENGTH_LONG)
// }
}
DownloadService.start(context)
}
}
}
@@ -280,7 +299,7 @@ class Downloader(
val availSpace = DiskUtil.getAvailableStorageSpace(mangaDir)
if (availSpace != -1L && availSpace < MIN_DISK_SPACE) {
download.status = Download.State.ERROR
notifier.onError(context.getString(R.string.download_insufficient_space), download.chapter.name)
notifier.onError(context.getString(R.string.download_insufficient_space), download.chapter.name, download.manga.title)
return@defer Observable.just(download)
}
@@ -301,6 +320,10 @@ class Downloader(
Observable.just(download.pages!!)
}
val dataSaver = if (preferences.dataSaverDownloader().get()) {
DataSaver(download.source, preferences)
} else DataSaver.NoOp
pageListObservable
.doOnNext { _ ->
// Delete all temporary (unfinished) files
@@ -315,7 +338,7 @@ class Downloader(
.flatMap { download.source.fetchAllImageUrlsFromPageList(it) }
// Start downloading images, consider we can have downloaded images already
// Concurrently do 5 pages at a time
.flatMap({ page -> getOrDownloadImage(page, download, tmpDir) }, 5)
.flatMap({ page -> getOrDownloadImage(page, download, tmpDir, dataSaver) }, 5)
.onBackpressureLatest()
// Do when page is downloaded.
.doOnNext { notifier.onProgressChange(download) }
@@ -326,7 +349,7 @@ class Downloader(
// If the page list threw, it will resume here
.onErrorReturn { error ->
download.status = Download.State.ERROR
notifier.onError(error.message, download.chapter.name)
notifier.onError(error.message, download.chapter.name, download.manga.title)
download
}
}
@@ -339,7 +362,7 @@ class Downloader(
* @param download the download of the page.
* @param tmpDir the temporary directory of the download.
*/
private fun getOrDownloadImage(page: Page, download: Download, tmpDir: UniFile): Observable<Page> {
private fun getOrDownloadImage(page: Page, download: Download, tmpDir: UniFile, dataSaver: DataSaver): Observable<Page> {
// If the image URL is empty, do nothing
if (page.imageUrl == null) {
return Observable.just(page)
@@ -358,7 +381,7 @@ class Downloader(
val pageObservable = when {
imageFile != null -> Observable.just(imageFile)
chapterCache.isImageInCache(page.imageUrl!!) -> copyImageFromCache(chapterCache.getImageFile(page.imageUrl!!), tmpDir, filename)
else -> downloadImage(page, download.source, tmpDir, filename)
else -> downloadImage(page, download.source, tmpDir, filename, dataSaver)
}
return pageObservable
@@ -386,10 +409,10 @@ class Downloader(
* @param tmpDir the temporary directory of the download.
* @param filename the filename of the image.
*/
private fun downloadImage(page: Page, source: HttpSource, tmpDir: UniFile, filename: String): Observable<UniFile> {
private fun downloadImage(page: Page, source: HttpSource, tmpDir: UniFile, filename: String, dataSaver: DataSaver): Observable<UniFile> {
page.status = Page.DOWNLOAD_IMAGE
page.progress = 0
return source.fetchImage(page)
return source.fetchImage(page, dataSaver)
.map { response ->
val file = tmpDir.createFile("$filename.tmp")
try {
@@ -473,35 +496,7 @@ class Downloader(
// Only rename the directory if it's downloaded.
if (download.status == Download.State.DOWNLOADED) {
if (preferences.saveChaptersAsCBZ().get()) {
val zip = mangaDir.createFile("$dirname.cbz.tmp")
val zipOut = ZipOutputStream(BufferedOutputStream(zip.openOutputStream()))
val compressionLevel = preferences.saveChaptersAsCBZLevel().get()
zipOut.setLevel(compressionLevel)
if (compressionLevel == 0) {
zipOut.setMethod(ZipEntry.STORED)
}
tmpDir.listFiles()?.forEach { img ->
val input = img.openInputStream()
val data = input.readBytes()
val entry = ZipEntry(img.name)
if (compressionLevel == 0) {
val crc = CRC32()
val size = img.length()
crc.update(data)
entry.crc = crc.value
entry.compressedSize = size
entry.size = size
}
zipOut.putNextEntry(entry)
zipOut.write(data)
input.close()
}
zipOut.close()
zip.renameTo("$dirname.cbz")
tmpDir.delete()
archiveChapter(mangaDir, dirname, tmpDir)
} else {
tmpDir.renameTo(dirname)
}
@@ -511,6 +506,40 @@ class Downloader(
}
}
/**
* Archive the chapter pages as a CBZ.
*/
private fun archiveChapter(
mangaDir: UniFile,
dirname: String,
tmpDir: UniFile,
) {
val zip = mangaDir.createFile("$dirname.cbz.tmp")
ZipOutputStream(BufferedOutputStream(zip.openOutputStream())).use { zipOut ->
zipOut.setMethod(ZipEntry.STORED)
tmpDir.listFiles()?.forEach { img ->
img.openInputStream().use { input ->
val data = input.readBytes()
val size = img.length()
val entry = ZipEntry(img.name).apply {
val crc = CRC32().apply {
update(data)
}
setCrc(crc.value)
compressedSize = size
setSize(size)
}
zipOut.putNextEntry(entry)
zipOut.write(data)
}
}
}
zip.renameTo("$dirname.cbz")
tmpDir.delete()
}
/**
* Completes a download. This method is called in the main thread.
*/
@@ -534,8 +563,9 @@ class Downloader(
companion object {
const val TMP_DIR_SUFFIX = "_tmp"
// Arbitrary minimum required space to start a download: 50 MB
const val MIN_DISK_SPACE = 50 * 1024 * 1024
const val CHAPTERS_PER_SOURCE_QUEUE_WARNING_THRESHOLD = 15
}
}
// Arbitrary minimum required space to start a download: 50 MB
private const val MIN_DISK_SPACE = 50 * 1024 * 1024
@@ -36,7 +36,14 @@ class CustomMangaManager(val context: Context) {
}
fun saveMangaInfo(manga: MangaJson) {
if (manga.title == null && manga.author == null && manga.artist == null && manga.description == null && manga.genre == null && manga.status == null) {
if (
manga.title == null &&
manga.author == null &&
manga.artist == null &&
manga.description == null &&
manga.genre == null &&
manga.status == null
) {
customMangaMap.remove(manga.id!!)
} else {
customMangaMap[manga.id!!] = manga.toManga()
@@ -8,9 +8,10 @@ import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.Worker
import androidx.work.WorkerParameters
import eu.kanade.tachiyomi.data.preference.CHARGING
import eu.kanade.tachiyomi.data.preference.DEVICE_CHARGING
import eu.kanade.tachiyomi.data.preference.DEVICE_ONLY_ON_WIFI
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.UNMETERED_NETWORK
import eu.kanade.tachiyomi.util.system.isConnectedToWifi
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.concurrent.TimeUnit
@@ -19,6 +20,11 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
Worker(context, workerParams) {
override fun doWork(): Result {
val preferences = Injekt.get<PreferencesHelper>()
if (requiresWifiConnection(preferences) && !context.isConnectedToWifi()) {
Result.failure()
}
return if (LibraryUpdateService.start(context)) {
Result.success()
} else {
@@ -33,17 +39,10 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
val preferences = Injekt.get<PreferencesHelper>()
val interval = prefInterval ?: preferences.libraryUpdateInterval().get()
if (interval > 0) {
val restrictions = preferences.libraryUpdateRestriction().get()
val acRestriction = CHARGING in restrictions
val wifiRestriction = if (UNMETERED_NETWORK in restrictions) {
NetworkType.UNMETERED
} else {
NetworkType.CONNECTED
}
val restrictions = preferences.libraryUpdateDeviceRestriction().get()
val constraints = Constraints.Builder()
.setRequiredNetworkType(wifiRestriction)
.setRequiresCharging(acRestriction)
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(DEVICE_CHARGING in restrictions)
.build()
val request = PeriodicWorkRequestBuilder<LibraryUpdateJob>(
@@ -61,5 +60,10 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
WorkManager.getInstance(context).cancelAllWorkByTag(TAG)
}
}
fun requiresWifiConnection(preferences: PreferencesHelper): Boolean {
val restrictions = preferences.libraryUpdateDeviceRestriction().get()
return DEVICE_ONLY_ON_WIFI in restrictions
}
}
}
@@ -16,6 +16,7 @@ import coil.transform.CircleCropTransformation
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.Downloader
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
@@ -52,7 +53,7 @@ class LibraryUpdateNotifier(private val context: Context) {
* Cached progress notification to avoid creating a lot.
*/
val progressNotificationBuilder by lazy {
context.notificationBuilder(Notifications.CHANNEL_LIBRARY) {
context.notificationBuilder(Notifications.CHANNEL_LIBRARY_PROGRESS) {
setContentTitle(context.getString(R.string.app_name))
setSmallIcon(R.drawable.ic_refresh_24dp)
setLargeIcon(notificationBitmap)
@@ -65,22 +66,25 @@ class LibraryUpdateNotifier(private val context: Context) {
/**
* Shows the notification containing the currently updating manga and the progress.
*
* @param manga the manga that's being updated.
* @param manga the manga that are being updated.
* @param current the current progress.
* @param total the total progress.
*/
fun showProgressNotification(manga: /* SY --> */ SManga /* SY <-- */, current: Int, total: Int) {
val title = if (preferences.hideNotificationContent()) {
context.getString(R.string.notification_check_updates)
fun showProgressNotification(manga: List</* SY --> */SManga/* SY <-- */>, current: Int, total: Int) {
if (preferences.hideNotificationContent()) {
progressNotificationBuilder
.setContentTitle(context.getString(R.string.notification_check_updates))
.setContentText("($current/$total)")
} else {
manga.title
val updatingText = manga.joinToString("\n") { it.title.chop(40) }
progressNotificationBuilder
.setContentTitle(context.getString(R.string.notification_updating, current, total))
.setStyle(NotificationCompat.BigTextStyle().bigText(updatingText))
}
context.notificationManager.notify(
Notifications.ID_LIBRARY_PROGRESS,
progressNotificationBuilder
.setContentTitle(title.chop(40))
.setContentText("($current/$total)")
.setProgress(total, current, false)
.build()
)
@@ -99,25 +103,12 @@ class LibraryUpdateNotifier(private val context: Context) {
context.notificationManager.notify(
Notifications.ID_LIBRARY_ERROR,
context.notificationBuilder(Notifications.CHANNEL_LIBRARY) {
context.notificationBuilder(Notifications.CHANNEL_LIBRARY_ERROR) {
setContentTitle(context.resources.getQuantityString(R.plurals.notification_update_error, errors.size, errors.size))
setStyle(
NotificationCompat.BigTextStyle().bigText(
errors.joinToString("\n") {
it.chop(NOTIF_TITLE_MAX_LEN)
}
)
)
setContentText(context.getString(R.string.action_show_errors))
setSmallIcon(R.drawable.ic_tachi)
val errorLogIntent = NotificationReceiver.openErrorLogPendingActivity(context, uri)
setContentIntent(errorLogIntent)
addAction(
R.drawable.ic_folder_24dp,
context.getString(R.string.action_show_errors),
errorLogIntent
)
setContentIntent(NotificationReceiver.openErrorLogPendingActivity(context, uri))
}
.build()
)
@@ -204,7 +195,7 @@ class LibraryUpdateNotifier(private val context: Context) {
// Mark chapters as read action
addAction(
R.drawable.ic_glasses_black_24dp,
R.drawable.ic_glasses_24dp,
context.getString(R.string.action_mark_as_read),
NotificationReceiver.markAsReadPendingBroadcast(
context,
@@ -223,6 +214,20 @@ class LibraryUpdateNotifier(private val context: Context) {
Notifications.ID_NEW_CHAPTERS
)
)
// Download chapters action
// Only add the action when chapters is within threshold
if (chapters.size <= Downloader.CHAPTERS_PER_SOURCE_QUEUE_WARNING_THRESHOLD) {
addAction(
android.R.drawable.stat_sys_download_done,
context.getString(R.string.action_download),
NotificationReceiver.downloadChaptersPendingBroadcast(
context,
manga,
chapters,
Notifications.ID_NEW_CHAPTERS
)
)
}
}
}
@@ -1,39 +0,0 @@
package eu.kanade.tachiyomi.data.library
import eu.kanade.tachiyomi.data.database.models.Manga
/**
* This class will provide various functions to rank manga to efficiently schedule manga to update.
*/
object LibraryUpdateRanker {
val rankingScheme = listOf(
(this::lexicographicRanking)(),
(this::latestFirstRanking)()
)
/**
* Provides a total ordering over all the [Manga]s.
*
* Assumption: An active [Manga] mActive is expected to have been last updated after an
* inactive [Manga] mInactive.
*
* Using this insight, function returns a Comparator for which mActive appears before mInactive.
* @return a Comparator that ranks manga based on relevance.
*/
private fun latestFirstRanking(): Comparator<Manga> =
Comparator { first: Manga, second: Manga ->
compareValues(second.last_update, first.last_update)
}
/**
* Provides a total ordering over all the [Manga]s.
*
* Order the manga lexicographically.
* @return a Comparator that ranks manga lexicographically based on the title.
*/
private fun lexicographicRanking(): Comparator<Manga> =
Comparator { first: Manga, second: Manga ->
compareValues(first.title, second.title)
}
}
@@ -16,15 +16,17 @@ import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.library.LibraryUpdateRanker.rankingScheme
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.preference.PreferenceValues
import eu.kanade.tachiyomi.data.preference.MANGA_FULLY_READ
import eu.kanade.tachiyomi.data.preference.MANGA_ONGOING
import eu.kanade.tachiyomi.data.preference.PreferenceValues.GroupLibraryMode
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.UnattendedTrackService
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.UnmeteredSource
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.source.model.toSManga
@@ -41,6 +43,8 @@ import eu.kanade.tachiyomi.util.storage.getUriCompat
import eu.kanade.tachiyomi.util.system.acquireWakeLock
import eu.kanade.tachiyomi.util.system.createFileInCacheDir
import eu.kanade.tachiyomi.util.system.isServiceRunning
import eu.kanade.tachiyomi.util.system.logcat
import exh.log.xLogE
import exh.md.utils.FollowStatus
import exh.md.utils.MdUtil
import exh.metadata.metadata.base.insertFlatMetadataAsync
@@ -54,7 +58,6 @@ import exh.util.nullIfBlank
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.async
@@ -64,10 +67,12 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.supervisorScope
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit
import timber.log.Timber
import logcat.LogPriority
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.File
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
/**
@@ -244,7 +249,7 @@ class LibraryUpdateService(
// Destroy service when completed or in case of an error.
val handler = CoroutineExceptionHandler { _, exception ->
Timber.e(exception)
logcat(LogPriority.ERROR, exception)
stopSelf(startId)
}
updateJob = ioScope.launch(handler) {
@@ -278,7 +283,11 @@ class LibraryUpdateService(
var listToUpdate = if (categoryId != -1) {
libraryManga.filter { it.category == categoryId }
// SY -->
} else if (group == LibraryGroup.BY_DEFAULT || groupLibraryUpdateType == PreferenceValues.GroupLibraryMode.GLOBAL || (groupLibraryUpdateType == PreferenceValues.GroupLibraryMode.ALL_BUT_UNGROUPED && group == LibraryGroup.UNGROUPED)) {
} else if (
group == LibraryGroup.BY_DEFAULT ||
groupLibraryUpdateType == GroupLibraryMode.GLOBAL ||
(groupLibraryUpdateType == GroupLibraryMode.ALL_BUT_UNGROUPED && group == LibraryGroup.UNGROUPED)
) {
val categoriesToUpdate = preferences.libraryUpdateCategories().get().map(String::toInt)
val listToInclude = if (categoriesToUpdate.isNotEmpty()) {
libraryManga.filter { it.category in categoriesToUpdate }
@@ -288,9 +297,9 @@ class LibraryUpdateService(
val categoriesToExclude = preferences.libraryUpdateCategoriesExclude().get().map(String::toInt)
val listToExclude = if (categoriesToExclude.isNotEmpty()) {
libraryManga.filter { it.category in categoriesToExclude }
libraryManga.filter { it.category in categoriesToExclude }.toSet()
} else {
emptyList()
emptySet()
}
listToInclude.minus(listToExclude)
@@ -312,13 +321,17 @@ class LibraryUpdateService(
"not tracked"
}
}
trackManager.mapTrackingOrder(status, applicationContext) == trackingExtra
(trackManager.trackMap[status] ?: TrackManager.OTHER) == trackingExtra
}
}
LibraryGroup.BY_SOURCE -> {
val sourceExtra = groupExtra.nullIfBlank()
val source = sourceManager.getCatalogueSources().find { it.name == sourceExtra }
if (source != null) libraryManga.filter { it.source == source.id } else emptyList()
val sourceExtra = groupExtra.nullIfBlank()?.toIntOrNull()
val source = libraryManga.map { it.source }
.distinct()
.sorted()
.getOrNull(sourceExtra ?: -1)
if (source != null) libraryManga.filter { it.source == source } else emptyList()
}
LibraryGroup.BY_STATUS -> {
val statusExtra = groupExtra?.toIntOrNull() ?: -1
@@ -331,14 +344,30 @@ class LibraryUpdateService(
}
// SY <--
}
if (target == Target.CHAPTERS && preferences.updateOnlyNonCompleted()) {
listToUpdate = listToUpdate.filterNot { it.status == SManga.COMPLETED }
if (target == Target.CHAPTERS) {
val restrictions = preferences.libraryUpdateMangaRestriction().get()
if (MANGA_ONGOING in restrictions) {
listToUpdate = listToUpdate.filterNot { it.status == SManga.COMPLETED }
}
if (MANGA_FULLY_READ in restrictions) {
listToUpdate = listToUpdate.filter { it.unread == 0 }
}
}
val selectedScheme = preferences.libraryUpdatePrioritization().get()
mangaToUpdate = listToUpdate
.distinctBy { it.id }
.sortedWith(rankingScheme[selectedScheme])
.sortedBy { it.title }
// Warn when excessively checking a single source
val maxUpdatesFromSource = mangaToUpdate
.groupBy { it.source }
.filterKeys { sourceManager.get(it) !is UnmeteredSource }
.maxOfOrNull { it.value.size } ?: 0
// TODO: re-enable warning
if (maxUpdatesFromSource > MANGA_PER_SOURCE_QUEUE_WARNING_THRESHOLD) {
// toast(R.string.notification_size_warning, Toast.LENGTH_LONG)
}
}
/**
@@ -353,32 +382,37 @@ class LibraryUpdateService(
suspend fun updateChapterList() {
val semaphore = Semaphore(5)
val progressCount = AtomicInteger(0)
val newUpdates = mutableListOf<Pair<LibraryManga, Array<Chapter>>>()
val failedUpdates = mutableListOf<Pair<Manga, String?>>()
var hasDownloads = false
val currentlyUpdatingManga = CopyOnWriteArrayList<LibraryManga>()
val newUpdates = CopyOnWriteArrayList<Pair<LibraryManga, Array<Chapter>>>()
val failedUpdates = CopyOnWriteArrayList<Pair<Manga, String?>>()
val hasDownloads = AtomicBoolean(false)
val loggedServices by lazy { trackManager.services.filter { it.isLogged } }
val currentUnreadUpdatesCount = preferences.unreadUpdatesCount().get()
withIOContext {
mangaToUpdate.groupBy { it.source }
.filterNot { it.key in LIBRARY_UPDATE_EXCLUDED_SOURCES }
.values.map { mangaInSource ->
.values
.map { mangaInSource ->
async {
semaphore.withPermit {
mangaInSource
.onEach { manga ->
if (updateJob?.isActive != true) {
return@async
}
notifier.showProgressNotification(manga, progressCount.andIncrement, mangaToUpdate.size)
mangaInSource.forEach { manga ->
if (updateJob?.isActive != true) {
return@async
}
withUpdateNotification(
currentlyUpdatingManga,
progressCount,
manga,
) { manga ->
try {
val (newChapters, _) = updateManga(manga)
val (newChapters, _) = updateManga(manga, loggedServices)
if (newChapters.isNotEmpty()) {
if (manga.shouldDownloadNewChapters(db, preferences)) {
downloadChapters(manga, newChapters)
hasDownloads = true
hasDownloads.set(true)
}
// Convert to the manga that contains new chapters
@@ -388,10 +422,17 @@ class LibraryUpdateService(
)
}
} catch (e: Throwable) {
val errorMessage = if (e is NoChaptersException) {
getString(R.string.no_chapters_error)
} else {
e.message
val errorMessage = when (e) {
is NoChaptersException -> {
getString(R.string.no_chapters_error)
}
is SourceManager.SourceNotInstalledException -> {
// failedUpdates will already have the source, don't need to copy it into the message
getString(R.string.loader_not_implemented_error)
}
else -> {
e.message
}
}
failedUpdates.add(manga to errorMessage)
}
@@ -400,21 +441,25 @@ class LibraryUpdateService(
updateTrackings(manga, loggedServices)
}
}
}
}
}
}.awaitAll()
}
.awaitAll()
}
notifier.cancelProgressNotification()
if (newUpdates.isNotEmpty()) {
notifier.showUpdateNotifications(newUpdates)
if (hasDownloads) {
val newChapterCount = newUpdates.sumOf { it.second.size }
preferences.unreadUpdatesCount().set(currentUnreadUpdatesCount + newChapterCount)
if (hasDownloads.get()) {
DownloadService.start(this)
}
}
if (preferences.showLibraryUpdateErrors() && failedUpdates.isNotEmpty()) {
if (failedUpdates.isNotEmpty()) {
val errorFile = writeErrorFile(failedUpdates)
notifier.showUpdateErrorNotification(
failedUpdates.map { it.first.title },
@@ -428,10 +473,12 @@ class LibraryUpdateService(
// may don't like it and they could ban the user.
// SY -->
val chapterFilter = if (manga.source == MERGED_SOURCE_ID) {
db.getMergedMangaReferences(manga.id!!).executeAsBlocking().filterNot { it.downloadChapters }.mapNotNull { it.mangaId }
db.getMergedMangaReferences(manga.id!!).executeAsBlocking()
.filterNot { it.downloadChapters }
.mapNotNull { it.mangaId } + manga.id!!
} else emptyList()
// SY <--
downloadManager.downloadChapters(manga, /* SY --> */ chapters.filter { it.manga_id !in chapterFilter } /* SY <-- */, false)
downloadManager.downloadChapters(manga, /* SY --> */ chapters.filterNot { it.manga_id in chapterFilter } /* SY <-- */, false)
}
/**
@@ -440,40 +487,34 @@ class LibraryUpdateService(
* @param manga the manga to update.
* @return a pair of the inserted and removed chapters.
*/
suspend fun updateManga(manga: Manga): Pair<List<Chapter>, List<Chapter>> {
suspend fun updateManga(manga: Manga, loggedServices: List<TrackService>): Pair<List<Chapter>, List<Chapter>> {
val source = sourceManager.getOrStub(manga.source).getMainSource()
// Update manga details metadata in the background
// Update manga details metadata
if (preferences.autoUpdateMetadata()) {
val handler = CoroutineExceptionHandler { _, exception ->
Timber.e(exception)
val updatedManga = source.getMangaDetails(manga.toMangaInfo())
val sManga = updatedManga.toSManga()
// Avoid "losing" existing cover
if (!sManga.thumbnail_url.isNullOrEmpty()) {
manga.prepUpdateCover(coverCache, sManga, false)
} else {
sManga.thumbnail_url = manga.thumbnail_url
}
GlobalScope.launch(Dispatchers.IO + handler) {
val updatedManga = source.getMangaDetails(manga.toMangaInfo())
val sManga = updatedManga.toSManga()
// Avoid "losing" existing cover
if (!sManga.thumbnail_url.isNullOrEmpty()) {
manga.prepUpdateCover(coverCache, sManga, false)
} else {
sManga.thumbnail_url = manga.thumbnail_url
}
manga.copyFrom(sManga)
db.insertManga(manga).executeAsBlocking()
}
manga.copyFrom(sManga)
db.insertManga(manga).executeAsBlocking()
}
// SY -->
val handler = CoroutineExceptionHandler { _, exception ->
Timber.e(exception)
}
ioScope.launch(handler) {
if (source.isMdBasedSource() && trackManager.mdList.isLogged) {
val tracks = db.getTracks(manga).executeOnIO()
if (source.isMdBasedSource() && trackManager.mdList in loggedServices) {
val handler = CoroutineExceptionHandler { _, exception ->
xLogE("Error adding initial track for ${manga.title}", exception)
}
ioScope.launch(handler) {
val tracks = db.getTracks(manga).executeAsBlocking()
if (tracks.isEmpty() || tracks.none { it.sync_id == TrackManager.MDLIST }) {
var track = trackManager.mdList.createInitialTracker(manga)
track = trackManager.mdList.refresh(track)
db.insertTrack(track).executeOnIO()
val track = trackManager.mdList.createInitialTracker(manga)
db.insertTrack(trackManager.mdList.refresh(track)).executeAsBlocking()
}
}
}
@@ -490,29 +531,47 @@ class LibraryUpdateService(
}
private suspend fun updateCovers() {
var progressCount = 0
val semaphore = Semaphore(5)
val progressCount = AtomicInteger(0)
val currentlyUpdatingManga = CopyOnWriteArrayList<LibraryManga>()
mangaToUpdate.forEach { manga ->
if (updateJob?.isActive != true) {
return
}
withIOContext {
mangaToUpdate.groupBy { it.source }
.values
.map { mangaInSource ->
async {
semaphore.withPermit {
mangaInSource.forEach { manga ->
if (updateJob?.isActive != true) {
return@async
}
notifier.showProgressNotification(manga, progressCount++, mangaToUpdate.size)
sourceManager.get(manga.source)?.let { source ->
try {
val networkManga = source.getMangaDetails(manga.toMangaInfo())
val sManga = networkManga.toSManga()
manga.prepUpdateCover(coverCache, sManga, true)
sManga.thumbnail_url?.let {
manga.thumbnail_url = it
db.insertManga(manga).executeAsBlocking()
withUpdateNotification(
currentlyUpdatingManga,
progressCount,
manga,
) { manga ->
sourceManager.get(manga.source)?.let { source ->
try {
val networkManga =
source.getMangaDetails(manga.toMangaInfo())
val sManga = networkManga.toSManga()
manga.prepUpdateCover(coverCache, sManga, true)
sManga.thumbnail_url?.let {
manga.thumbnail_url = it
db.insertManga(manga).executeAsBlocking()
}
} catch (e: Throwable) {
// Ignore errors and continue
logcat(LogPriority.ERROR, e)
}
}
}
}
}
}
} catch (e: Throwable) {
// Ignore errors and continue
Timber.e(e)
}
}
.awaitAll()
}
coverCache.clearMemoryCache()
@@ -532,8 +591,7 @@ class LibraryUpdateService(
return
}
// Notify manga that will update.
notifier.showProgressNotification(manga, progressCount++, mangaToUpdate.size)
notifier.showProgressNotification(listOf(manga), progressCount++, mangaToUpdate.size)
// Update the tracking details.
updateTrackings(manga, loggedServices)
@@ -553,12 +611,12 @@ class LibraryUpdateService(
val updatedTrack = service.refresh(track)
db.insertTrack(updatedTrack).executeAsBlocking()
if (service is UnattendedTrackService) {
if (service is EnhancedTrackService) {
syncChaptersWithTrackServiceTwoWay(db, db.getChapters(manga).executeAsBlocking(), track, service)
}
} catch (e: Throwable) {
// Ignore errors and continue
Timber.e(e)
logcat(LogPriority.ERROR, e)
}
}
}
@@ -567,12 +625,44 @@ class LibraryUpdateService(
.awaitAll()
}
private suspend fun withUpdateNotification(
updatingManga: CopyOnWriteArrayList<LibraryManga>,
completed: AtomicInteger,
manga: LibraryManga,
block: suspend (LibraryManga) -> Unit,
) {
if (updateJob?.isActive != true) {
return
}
updatingManga.add(manga)
notifier.showProgressNotification(
updatingManga,
completed.get(),
mangaToUpdate.size
)
block(manga)
if (updateJob?.isActive != true) {
return
}
updatingManga.remove(manga)
completed.andIncrement
notifier.showProgressNotification(
updatingManga,
completed.get(),
mangaToUpdate.size
)
}
// SY -->
/**
* filter all follows from Mangadex and only add reading or rereading manga to library
*/
private suspend fun syncFollows() {
val count = AtomicInteger(0)
var count = 0
val mangaDex = MdUtil.getEnabledMangaDex(preferences, sourceManager) ?: return
val syncFollowStatusInts = preferences.mangadexSyncToLibraryIndexes().get().map { it.toInt() }
@@ -587,7 +677,8 @@ class LibraryUpdateService(
return
}
notifier.showProgressNotification(networkManga, count.andIncrement, size)
count++
notifier.showProgressNotification(listOf(networkManga), count, size)
var dbManga = db.getManga(networkManga.url, mangaDex.id)
.executeOnIO()
@@ -616,7 +707,7 @@ class LibraryUpdateService(
* Method that updates the all mangas which are not tracked as "reading" on mangadex
*/
private suspend fun pushFavorites() {
val count = AtomicInteger(0)
var count = 0
val listManga = db.getFavoriteMangas().executeAsBlocking().filter { it.source in mangaDexSourceIds }
// filter all follows from Mangadex and only add reading or rereading manga to library
@@ -626,7 +717,8 @@ class LibraryUpdateService(
return
}
notifier.showProgressNotification(manga, count.andIncrement, listManga.size)
count++
notifier.showProgressNotification(listOf(manga), count, listManga.size)
// Get this manga's trackers from the database
val dbTracks = db.getTracks(manga).executeAsBlocking()
@@ -654,9 +746,20 @@ class LibraryUpdateService(
if (errors.isNotEmpty()) {
val file = createFileInCacheDir("tachiyomi_update_errors.txt")
file.bufferedWriter().use { out ->
errors.forEach { (manga, error) ->
val source = sourceManager.getOrStub(manga.source)
out.write("${manga.title} ($source): $error\n")
out.write(getString(R.string.library_errors_help, ERROR_LOG_HELP_URL) + "\n\n")
// Error file format:
// ! Error
// # Source
// - Manga
errors.groupBy({ it.second }, { it.first }).forEach { (error, mangas) ->
out.write("\n! ${error}\n")
mangas.groupBy { it.source }.forEach { (srcId, mangas) ->
val source = sourceManager.getOrStub(srcId)
out.write(" # $source\n")
mangas.forEach {
out.write(" - ${it.title}\n")
}
}
}
}
return file
@@ -667,3 +770,6 @@ class LibraryUpdateService(
return File("")
}
}
private const val MANGA_PER_SOURCE_QUEUE_WARNING_THRESHOLD = 60
private const val ERROR_LOG_HELP_URL = "https://tachiyomi.org/help/guides/troubleshooting"
@@ -20,10 +20,10 @@ object NotificationHandler {
*/
internal fun openDownloadManagerPendingActivity(context: Context): PendingIntent {
val intent = Intent(context, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
action = MainActivity.SHORTCUT_DOWNLOADS
}
return PendingIntent.getActivity(context, 0, intent, 0)
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
/**
@@ -2,12 +2,11 @@ package eu.kanade.tachiyomi.data.notification
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.ClipData
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Handler
import androidx.core.content.ContextCompat
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.BackupRestoreService
import eu.kanade.tachiyomi.data.database.DatabaseHelper
@@ -25,6 +24,7 @@ import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.storage.getUriCompat
import eu.kanade.tachiyomi.util.system.notificationManager
import eu.kanade.tachiyomi.util.system.toShareIntent
import eu.kanade.tachiyomi.util.system.toast
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -102,6 +102,18 @@ class NotificationReceiver : BroadcastReceiver() {
markAsRead(urls, mangaId)
}
}
// Download manga chapters
ACTION_DOWNLOAD_CHAPTER -> {
val notificationId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1)
if (notificationId > -1) {
dismissNotification(context, notificationId, intent.getIntExtra(EXTRA_GROUP_ID, 0))
}
val urls = intent.getStringArrayExtra(EXTRA_CHAPTER_URL) ?: return
val mangaId = intent.getLongExtra(EXTRA_MANGA_ID, -1)
if (mangaId > -1) {
downloadChapters(urls, mangaId)
}
}
// Share crash dump file
ACTION_SHARE_CRASH_LOG ->
shareFile(
@@ -130,16 +142,8 @@ class NotificationReceiver : BroadcastReceiver() {
* @param notificationId id of notification
*/
private fun shareImage(context: Context, path: String, notificationId: Int) {
val intent = Intent(Intent.ACTION_SEND).apply {
val uri = File(path).getUriCompat(context)
putExtra(Intent.EXTRA_STREAM, uri)
clipData = ClipData.newRawUri(null, uri)
type = "image/*"
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
}
dismissNotification(context, notificationId)
// Launch share activity
context.startActivity(intent)
context.startActivity(File(path).getUriCompat(context).toShareIntent(context))
}
/**
@@ -150,16 +154,8 @@ class NotificationReceiver : BroadcastReceiver() {
* @param notificationId id of notification
*/
private fun shareFile(context: Context, uri: Uri, fileMimeType: String, notificationId: Int) {
val sendIntent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_STREAM, uri)
clipData = ClipData.newRawUri(null, uri)
type = fileMimeType
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
}
// Dismiss notification
dismissNotification(context, notificationId)
// Launch share activity
context.startActivity(sendIntent)
context.startActivity(uri.toShareIntent(context, fileMimeType))
}
/**
@@ -208,7 +204,7 @@ class NotificationReceiver : BroadcastReceiver() {
*/
private fun cancelRestore(context: Context, notificationId: Int) {
BackupRestoreService.stop(context)
Handler().post { dismissNotification(context, notificationId) }
ContextCompat.getMainExecutor(context).execute { dismissNotification(context, notificationId) }
}
/**
@@ -219,7 +215,7 @@ class NotificationReceiver : BroadcastReceiver() {
*/
private fun cancelLibraryUpdate(context: Context, notificationId: Int) {
LibraryUpdateService.stop(context)
Handler().post { dismissNotification(context, notificationId) }
ContextCompat.getMainExecutor(context).execute { dismissNotification(context, notificationId) }
}
/**
@@ -251,6 +247,24 @@ class NotificationReceiver : BroadcastReceiver() {
}
}
/**
* Method called when user wants to download chapters
*
* @param chapterUrls URLs of chapter to download
* @param mangaId id of manga
*/
private fun downloadChapters(chapterUrls: Array<String>, mangaId: Long) {
val db: DatabaseHelper = Injekt.get()
launchIO {
val chapters = chapterUrls.mapNotNull { db.getChapter(it, mangaId).executeAsBlocking() }
val manga = db.getManga(mangaId).executeAsBlocking()
if (chapters.isNotEmpty() && manga != null) {
downloadManager.downloadChapters(manga, chapters)
}
}
}
companion object {
private const val NAME = "NotificationReceiver"
@@ -267,6 +281,7 @@ class NotificationReceiver : BroadcastReceiver() {
private const val ACTION_MARK_AS_READ = "$ID.$NAME.MARK_AS_READ"
private const val ACTION_OPEN_CHAPTER = "$ID.$NAME.ACTION_OPEN_CHAPTER"
private const val ACTION_DOWNLOAD_CHAPTER = "$ID.$NAME.ACTION_DOWNLOAD_CHAPTER"
private const val ACTION_RESUME_DOWNLOADS = "$ID.$NAME.ACTION_RESUME_DOWNLOADS"
private const val ACTION_PAUSE_DOWNLOADS = "$ID.$NAME.ACTION_PAUSE_DOWNLOADS"
@@ -458,6 +473,28 @@ class NotificationReceiver : BroadcastReceiver() {
return PendingIntent.getBroadcast(context, manga.id.hashCode(), newIntent, PendingIntent.FLAG_UPDATE_CURRENT)
}
/**
* Returns [PendingIntent] that downloads chapters
*
* @param context context of application
* @param manga manga of chapter
*/
internal fun downloadChaptersPendingBroadcast(
context: Context,
manga: Manga,
chapters: Array<Chapter>,
groupId: Int
): PendingIntent {
val newIntent = Intent(context, NotificationReceiver::class.java).apply {
action = ACTION_DOWNLOAD_CHAPTER
putExtra(EXTRA_CHAPTER_URL, chapters.map { it.url }.toTypedArray())
putExtra(EXTRA_MANGA_ID, manga.id)
putExtra(EXTRA_NOTIFICATION_ID, manga.id.hashCode())
putExtra(EXTRA_GROUP_ID, groupId)
}
return PendingIntent.getBroadcast(context, manga.id.hashCode(), newIntent, PendingIntent.FLAG_UPDATE_CURRENT)
}
/**
* Returns [PendingIntent] that starts a service which stops the library update
*
@@ -1,12 +1,13 @@
package eu.kanade.tachiyomi.data.notification
import android.app.NotificationChannel
import android.app.NotificationChannelGroup
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.NotificationManagerCompat.IMPORTANCE_DEFAULT
import androidx.core.app.NotificationManagerCompat.IMPORTANCE_HIGH
import androidx.core.app.NotificationManagerCompat.IMPORTANCE_LOW
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.notificationManager
import eu.kanade.tachiyomi.util.system.buildNotificationChannel
import eu.kanade.tachiyomi.util.system.buildNotificationChannelGroup
/**
* Class to manage the basic information of all the notifications used in the app.
@@ -17,14 +18,15 @@ object Notifications {
* Common notification channel and ids used anywhere.
*/
const val CHANNEL_COMMON = "common_channel"
const val ID_UPDATER = 1
const val ID_DOWNLOAD_IMAGE = 2
/**
* Notification channel and ids used by the library updater.
*/
const val CHANNEL_LIBRARY = "library_channel"
private const val GROUP_LIBRARY = "group_library"
const val CHANNEL_LIBRARY_PROGRESS = "library_progress_channel"
const val ID_LIBRARY_PROGRESS = -101
const val CHANNEL_LIBRARY_ERROR = "library_errors_channel"
const val ID_LIBRARY_ERROR = -102
/**
@@ -45,12 +47,6 @@ object Notifications {
const val ID_NEW_CHAPTERS = -301
const val GROUP_NEW_CHAPTERS = "eu.kanade.tachiyomi.NEW_CHAPTERS"
/**
* Notification channel and ids used by the library updater.
*/
const val CHANNEL_UPDATES_TO_EXTS = "updates_ext_channel"
const val ID_UPDATES_TO_EXTS = -401
/**
* Notification channel and ids used by the backup/restore system.
*/
@@ -74,101 +70,112 @@ object Notifications {
const val CHANNEL_INCOGNITO_MODE = "incognito_mode_channel"
const val ID_INCOGNITO_MODE = -701
/**
* Notification channel and ids used for app and extension updates.
*/
private const val GROUP_APK_UPDATES = "group_apk_updates"
const val CHANNEL_APP_UPDATE = "app_apk_update_channel"
const val ID_APP_UPDATER = 1
const val CHANNEL_EXTENSIONS_UPDATE = "ext_apk_update_channel"
const val ID_UPDATES_TO_EXTS = -401
const val ID_EXTENSION_INSTALLER = -402
private val deprecatedChannels = listOf(
"downloader_channel",
"backup_restore_complete_channel"
"backup_restore_complete_channel",
"library_channel",
"library_progress_channel",
"updates_ext_channel",
)
/**
* Creates the notification channels introduced in Android Oreo.
* This won't do anything on Android versions that don't support notification channels.
*
* @param context The application context.
*/
fun createChannels(context: Context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
listOf(
NotificationChannelGroup(GROUP_BACKUP_RESTORE, context.getString(R.string.group_backup_restore)),
NotificationChannelGroup(GROUP_DOWNLOADER, context.getString(R.string.group_downloader))
).forEach(context.notificationManager::createNotificationChannelGroup)
listOf(
NotificationChannel(
CHANNEL_COMMON,
context.getString(R.string.channel_common),
NotificationManager.IMPORTANCE_LOW
),
NotificationChannel(
CHANNEL_LIBRARY,
context.getString(R.string.channel_library),
NotificationManager.IMPORTANCE_LOW
).apply {
setShowBadge(false)
},
NotificationChannel(
CHANNEL_DOWNLOADER_PROGRESS,
context.getString(R.string.channel_progress),
NotificationManager.IMPORTANCE_LOW
).apply {
group = GROUP_DOWNLOADER
setShowBadge(false)
},
NotificationChannel(
CHANNEL_DOWNLOADER_COMPLETE,
context.getString(R.string.channel_complete),
NotificationManager.IMPORTANCE_LOW
).apply {
group = GROUP_DOWNLOADER
setShowBadge(false)
},
NotificationChannel(
CHANNEL_DOWNLOADER_ERROR,
context.getString(R.string.channel_errors),
NotificationManager.IMPORTANCE_LOW
).apply {
group = GROUP_DOWNLOADER
setShowBadge(false)
},
NotificationChannel(
CHANNEL_NEW_CHAPTERS,
context.getString(R.string.channel_new_chapters),
NotificationManager.IMPORTANCE_DEFAULT
),
NotificationChannel(
CHANNEL_UPDATES_TO_EXTS,
context.getString(R.string.channel_ext_updates),
NotificationManager.IMPORTANCE_DEFAULT
),
NotificationChannel(
CHANNEL_BACKUP_RESTORE_PROGRESS,
context.getString(R.string.channel_progress),
NotificationManager.IMPORTANCE_LOW
).apply {
group = GROUP_BACKUP_RESTORE
setShowBadge(false)
},
NotificationChannel(
CHANNEL_BACKUP_RESTORE_COMPLETE,
context.getString(R.string.channel_complete),
NotificationManager.IMPORTANCE_HIGH
).apply {
group = GROUP_BACKUP_RESTORE
setShowBadge(false)
setSound(null, null)
},
NotificationChannel(
CHANNEL_CRASH_LOGS,
context.getString(R.string.channel_crash_logs),
NotificationManager.IMPORTANCE_HIGH
),
NotificationChannel(
CHANNEL_INCOGNITO_MODE,
context.getString(R.string.pref_incognito_mode),
NotificationManager.IMPORTANCE_LOW
)
).forEach(context.notificationManager::createNotificationChannel)
val notificationService = NotificationManagerCompat.from(context)
// Delete old notification channels
deprecatedChannels.forEach(context.notificationManager::deleteNotificationChannel)
deprecatedChannels.forEach(notificationService::deleteNotificationChannel)
notificationService.createNotificationChannelGroupsCompat(
listOf(
buildNotificationChannelGroup(GROUP_BACKUP_RESTORE) {
setName(context.getString(R.string.label_backup))
},
buildNotificationChannelGroup(GROUP_DOWNLOADER) {
setName(context.getString(R.string.download_notifier_downloader_title))
},
buildNotificationChannelGroup(GROUP_LIBRARY) {
setName(context.getString(R.string.label_library))
},
buildNotificationChannelGroup(GROUP_APK_UPDATES) {
setName(context.getString(R.string.label_recent_updates))
},
)
)
notificationService.createNotificationChannelsCompat(
listOf(
buildNotificationChannel(CHANNEL_COMMON, IMPORTANCE_LOW) {
setName(context.getString(R.string.channel_common))
},
buildNotificationChannel(CHANNEL_LIBRARY_PROGRESS, IMPORTANCE_LOW) {
setName(context.getString(R.string.channel_progress))
setGroup(GROUP_LIBRARY)
setShowBadge(false)
},
buildNotificationChannel(CHANNEL_LIBRARY_ERROR, IMPORTANCE_LOW) {
setName(context.getString(R.string.channel_errors))
setGroup(GROUP_LIBRARY)
setShowBadge(false)
},
buildNotificationChannel(CHANNEL_NEW_CHAPTERS, IMPORTANCE_DEFAULT) {
setName(context.getString(R.string.channel_new_chapters))
},
buildNotificationChannel(CHANNEL_DOWNLOADER_PROGRESS, IMPORTANCE_LOW) {
setName(context.getString(R.string.channel_progress))
setGroup(GROUP_DOWNLOADER)
setShowBadge(false)
},
buildNotificationChannel(CHANNEL_DOWNLOADER_COMPLETE, IMPORTANCE_LOW) {
setName(context.getString(R.string.channel_complete))
setGroup(GROUP_DOWNLOADER)
setShowBadge(false)
},
buildNotificationChannel(CHANNEL_DOWNLOADER_ERROR, IMPORTANCE_LOW) {
setName(context.getString(R.string.channel_errors))
setGroup(GROUP_DOWNLOADER)
setShowBadge(false)
},
buildNotificationChannel(CHANNEL_BACKUP_RESTORE_PROGRESS, IMPORTANCE_LOW) {
setName(context.getString(R.string.channel_progress))
setGroup(GROUP_BACKUP_RESTORE)
setShowBadge(false)
},
buildNotificationChannel(CHANNEL_BACKUP_RESTORE_COMPLETE, IMPORTANCE_HIGH) {
setName(context.getString(R.string.channel_complete))
setGroup(GROUP_BACKUP_RESTORE)
setShowBadge(false)
setSound(null, null)
},
buildNotificationChannel(CHANNEL_CRASH_LOGS, IMPORTANCE_HIGH) {
setName(context.getString(R.string.channel_crash_logs))
},
buildNotificationChannel(CHANNEL_INCOGNITO_MODE, IMPORTANCE_LOW) {
setName(context.getString(R.string.pref_incognito_mode))
},
buildNotificationChannel(CHANNEL_APP_UPDATE, IMPORTANCE_DEFAULT) {
setGroup(GROUP_APK_UPDATES)
setName(context.getString(R.string.channel_app_updates))
},
buildNotificationChannel(CHANNEL_EXTENSIONS_UPDATE, IMPORTANCE_DEFAULT) {
setGroup(GROUP_APK_UPDATES)
setName(context.getString(R.string.channel_ext_updates))
},
)
)
}
}
@@ -5,141 +5,28 @@ package eu.kanade.tachiyomi.data.preference
*/
object PreferenceKeys {
const val themeMode = "pref_theme_mode_key"
const val themeLight = "pref_theme_light_key"
const val themeDark = "pref_theme_dark_key"
const val confirmExit = "pref_confirm_exit"
const val hideBottomBarOnScroll = "pref_hide_bottom_bar_on_scroll"
const val showSideNavOnBottom = "pref_show_side_nav_on_bottom"
const val enableTransitionsPager = "pref_enable_transitions_pager_key"
const val enableTransitionsWebtoon = "pref_enable_transitions_webtoon_key"
const val doubleTapAnimationSpeed = "pref_double_tap_anim_speed"
const val showPageNumber = "pref_show_page_number_key"
const val dualPageSplitPaged = "pref_dual_page_split"
const val dualPageSplitWebtoon = "pref_dual_page_split_webtoon"
const val dualPageInvertPaged = "pref_dual_page_invert"
const val dualPageInvertWebtoon = "pref_dual_page_invert_webtoon"
const val showReadingMode = "pref_show_reading_mode"
const val trueColor = "pref_true_color_key"
const val fullscreen = "fullscreen"
const val cutoutShort = "cutout_short"
const val keepScreenOn = "pref_keep_screen_on_key"
const val customBrightness = "pref_custom_brightness_key"
const val customBrightnessValue = "custom_brightness_value"
const val colorFilter = "pref_color_filter_key"
const val colorFilterValue = "color_filter_value"
const val colorFilterMode = "color_filter_mode"
const val grayscale = "pref_grayscale"
const val defaultReadingMode = "pref_default_reading_mode_key"
const val defaultOrientationType = "pref_default_orientation_type_key"
const val imageScaleType = "pref_image_scale_type_key"
const val zoomStart = "pref_zoom_start_key"
const val readerTheme = "pref_reader_theme_key"
const val cropBorders = "crop_borders"
const val cropBordersWebtoon = "crop_borders_webtoon"
const val readWithTapping = "reader_tap"
const val pagerNavInverted = "reader_tapping_inverted"
const val webtoonNavInverted = "reader_tapping_inverted_webtoon"
const val readWithLongTap = "reader_long_tap"
const val readWithVolumeKeys = "reader_volume_keys"
const val readWithVolumeKeysInverted = "reader_volume_keys_inverted"
const val navigationModePager = "reader_navigation_mode_pager"
const val navigationModeWebtoon = "reader_navigation_mode_webtoon"
const val showNavigationOverlayNewUser = "reader_navigation_overlay_new_user"
const val showNavigationOverlayOnStart = "reader_navigation_overlay_on_start"
const val webtoonSidePadding = "webtoon_side_padding"
const val portraitColumns = "pref_library_columns_portrait_key"
const val landscapeColumns = "pref_library_columns_landscape_key"
const val jumpToChapters = "jump_to_chapters"
const val updateOnlyNonCompleted = "pref_update_only_non_completed_key"
const val autoUpdateTrack = "pref_auto_update_manga_sync_key"
const val autoAddTrack = "pref_auto_add_track_key"
const val lastUsedSource = "last_catalogue_source"
const val lastUsedCategory = "last_used_category"
const val sourceDisplayMode = "pref_display_mode_catalogue"
const val enabledLanguages = "source_languages"
const val backupDirectory = "backup_directory"
const val downloadsDirectory = "download_directory"
const val downloadOnlyOverWifi = "pref_download_only_over_wifi_key"
const val folderPerManga = "create_folder_per_manga"
const val numberOfBackups = "backup_slots"
const val backupInterval = "backup_interval"
const val removeAfterReadSlots = "remove_after_read_slots"
const val removeAfterMarkedAsRead = "pref_remove_after_marked_as_read_key"
const val removeBookmarkedChapters = "pref_remove_bookmarked"
const val libraryUpdateInterval = "pref_library_update_interval_key"
const val libraryUpdateRestriction = "library_update_restriction"
const val libraryUpdateCategories = "library_update_categories"
const val libraryUpdateCategoriesExclude = "library_update_categories_exclude"
const val libraryUpdatePrioritization = "library_update_prioritization"
const val downloadedOnly = "pref_downloaded_only"
const val filterDownloaded = "pref_filter_library_downloaded"
const val filterUnread = "pref_filter_library_unread"
@@ -153,40 +40,19 @@ object PreferenceKeys {
const val filterLewd = "pref_filter_library_lewd"
const val librarySortingMode = "library_sorting_mode"
const val librarySortingDirection = "library_sorting_ascending"
const val automaticExtUpdates = "automatic_ext_updates"
const val showNsfwSource = "show_nsfw_source"
const val showNsfwExtension = "show_nsfw_extension"
const val labelNsfwExtension = "label_nsfw_extension"
const val migrationSortingMode = "pref_migration_sorting"
const val migrationSortingDirection = "pref_migration_direction"
const val startScreen = "start_screen"
const val useAuthenticator = "use_biometric_lock"
const val lockAppAfter = "lock_app_after"
const val lastAppUnlock = "last_app_unlock"
const val secureScreen = "secure_screen"
const val hideNotificationContent = "hide_notification_content"
const val autoUpdateMetadata = "auto_update_metadata"
const val autoUpdateTrackers = "auto_update_trackers"
const val showLibraryUpdateErrors = "show_library_update_errors"
const val downloadNew = "download_new"
const val downloadNewCategories = "download_new_categories"
const val downloadNewCategoriesExclude = "download_new_categories_exclude"
const val libraryDisplayMode = "pref_display_mode_library"
const val lang = "app_language"
const val dateFormat = "app_date_format"
const val defaultCategory = "default_category"
@@ -195,18 +61,6 @@ object PreferenceKeys {
const val skipFiltered = "skip_filtered"
const val downloadBadge = "display_download_badge"
const val unreadBadge = "display_unread_badge"
const val localBadge = "display_local_badge"
const val categoryTabs = "display_category_tabs"
const val categoryNumberOfItems = "display_number_of_items"
const val alwaysShowChapterTransition = "always_show_chapter_transition"
const val searchPinnedSourcesOnly = "search_pinned_sources_only"
const val dohProvider = "doh_provider"
@@ -223,7 +77,9 @@ object PreferenceKeys {
const val defaultChapterDisplayByNameOrNumber = "default_chapter_display_by_name_or_number"
const val incognitoMode = "incognito_mode"
const val verboseLogging = "verbose_logging"
const val autoClearChapterCache = "auto_clear_chapter_cache"
fun trackUsername(syncId: Int) = "pref_mangasync_username_$syncId"
@@ -231,157 +87,7 @@ object PreferenceKeys {
fun trackToken(syncId: Int) = "track_token_$syncId"
const val skipPreMigration = "skip_pre_migration"
const val eh_showSyncIntro = "eh_show_sync_intro"
const val eh_readOnlySync = "eh_sync_read_only"
const val eh_lenientSync = "eh_lenient_sync"
const val eh_useOrigImages = "eh_useOrigImages"
const val eh_ehSettingsProfile = "eh_ehSettingsProfile"
const val eh_exhSettingsProfile = "eh_exhSettingsProfile"
const val eh_settingsKey = "eh_settingsKey"
const val eh_sessionCookie = "eh_sessionCookie"
const val eh_hathPerksCookie = "eh_hathPerksCookie"
const val eh_enableExHentai = "enable_exhentai"
const val eh_showSettingsUploadWarning = "eh_showSettingsUploadWarning2"
const val eh_expandFilters = "eh_expand_filters"
const val eh_readerThreads = "eh_reader_threads"
const val eh_readerInstantRetry = "eh_reader_instant_retry"
const val eh_utilAutoscrollInterval = "eh_util_autoscroll_interval"
const val eh_cacheSize = "eh_cache_size"
const val eh_preserveReadingPosition = "eh_preserve_reading_position"
const val eh_autoSolveCaptchas = "eh_autosolve_captchas"
const val eh_delegateSources = "eh_delegate_sources"
// SY -->
const val eh_logLevel = "eh_log_level"
const val eh_enableSourceBlacklist = "eh_enable_source_blacklist"
const val eh_autoUpdateFrequency = "eh_auto_update_frequency"
const val eh_autoUpdateRestrictions = "eh_auto_update_restrictions"
const val eh_autoUpdateStats = "eh_auto_update_stats"
const val eh_aggressivePageLoading = "eh_aggressive_page_loading"
const val eh_preload_size = "eh_preload_size"
const val eh_tag_filtering_value = "eh_tag_filtering_value"
const val eh_tag_watching_value = "eh_tag_watching_value"
const val eh_is_hentai_enabled = "eh_is_hentai_enabled"
const val eh_use_auto_webtoon = "eh_use_auto_webtoon"
const val eh_watched_list_default_state = "eh_watched_list_default_state"
const val eh_settings_languages = "eh_settings_languages"
const val eh_enabled_categories = "eh_enabled_categories"
const val eh_ehentai_quality = "ehentai_quality"
const val eh_enable_hah = "eh_enable_hah"
const val latest_tab_sources = "latest_tab_sources"
const val latest_tab_position = "latest_tab_position"
const val sources_tab_categories = "sources_tab_categories"
const val sources_tab_categories_filter = "sources_tab_categories_filter"
const val sources_tab_source_categories = "sources_tab_source_categories"
const val sourcesSort = "sources_sort"
const val recommendsInOverflow = "recommends_in_overflow"
const val enhancedEHentaiView = "enhanced_e_hentai_view"
const val webtoonEnableZoomOut = "webtoon_enable_zoom_out"
const val startReadingButton = "start_reading_button"
const val groupLibraryBy = "group_library_by"
const val continuousVerticalTappingByPage = "continuous_vertical_tapping_by_page"
const val groupLibraryUpdateType = "group_library_update_type"
const val useNewSourceNavigation = "use_new_source_navigation"
const val mangaDexForceLatestCovers = "manga_dex_force_latest_covers"
const val mangadexSyncToLibraryIndexes = "pref_mangadex_sync_to_library_indexes"
const val preferredMangaDexId = "preferred_mangaDex_id"
const val dataSaver = "data_saver"
const val ignoreJpeg = "ignore_jpeg"
const val ignoreGif = "ignore_gif"
const val dataSaverImageQuality = "data_saver_image_quality"
const val dataSaverImageFormatJpeg = "data_saver_image_format_jpeg"
const val dataSaverServer = "data_saver_server"
const val dataSaverColorBW = "data_saver_color_bw"
const val saveChaptersAsCBZ = "save_chapter_as_cbz"
const val saveChaptersAsCBZLevel = "save_chapter_as_cbz_level"
const val allowLocalSourceHiddenFolders = "allow_local_source_hidden_folders"
const val authenticatorTimeRanges = "biometric_time_ranges"
const val sortTagsForLibrary = "sort_tags_for_library"
const val dontDeleteFromCategories = "dont_delete_from_categories"
const val extensionRepos = "extension_repos"
const val cropBordersContinuousVertical = "crop_borders_continues_vertical"
const val landscapeVerticalSeekbar = "pref_show_vert_seekbar_landscape"
const val leftVerticalSeekbar = "pref_left_handed_vertical_seekbar"
const val forceHorizontalSeekbar = "pref_force_horz_seekbar"
const val readerBottomButtons = "reader_bottom_buttons"
const val bottomBarLabels = "pref_show_bottom_bar_labels"
const val hideUpdatesButton = "pref_hide_updates_button"
const val hideHistoryButton = "pref_hide_history_button"
const val pageLayout = "page_layout"
const val invertDoublePages = "invert_double_pages"
// SY <--
}
@@ -1,7 +1,12 @@
package eu.kanade.tachiyomi.data.preference
const val UNMETERED_NETWORK = "wifi"
const val CHARGING = "ac"
import eu.kanade.tachiyomi.R
const val DEVICE_ONLY_ON_WIFI = "wifi"
const val DEVICE_CHARGING = "ac"
const val MANGA_ONGOING = "manga_ongoing"
const val MANGA_FULLY_READ = "manga_fully_read"
/**
* This class stores the values for the preferences in the application.
@@ -17,43 +22,54 @@ object PreferenceValues {
system,
}
// Keys are lowercase to match legacy string values
enum class LightThemeVariant {
default,
blue,
strawberrydaiquiri,
}
// Keys are lowercase to match legacy string values
enum class DarkThemeVariant {
default,
blue,
greenapple,
midnightdusk,
amoled,
hotpink,
amoledblue,
red,
}
/* ktlint-enable experimental:enum-entry-name-case */
enum class DisplayMode {
COMPACT_GRID,
COMFORTABLE_GRID,
enum class AppTheme(val titleResId: Int?) {
DEFAULT(R.string.label_default),
MONET(R.string.theme_monet),
MIDNIGHT_DUSK(R.string.theme_midnightdusk),
STRAWBERRY_DAIQUIRI(R.string.theme_strawberrydaiquiri),
YOTSUBA(R.string.theme_yotsuba),
TAKO(R.string.theme_tako),
GREEN_APPLE(R.string.theme_greenapple),
TEALTURQUOISE(R.string.theme_tealturquoise),
YINYANG(R.string.theme_yinyang),
// Deprecated
DARK_BLUE(null),
HOT_PINK(null),
BLUE(null),
// SY -->
NO_TITLE_GRID,
PURE_RED(null),
// SY <--
LIST,
}
enum class TappingInvertMode(val shouldInvertHorizontal: Boolean = false, val shouldInvertVertical: Boolean = false) {
NONE,
HORIZONTAL(shouldInvertHorizontal = true),
VERTICAL(shouldInvertVertical = true),
BOTH(shouldInvertHorizontal = true, shouldInvertVertical = true)
BOTH(shouldInvertHorizontal = true, shouldInvertVertical = true),
}
enum class ReaderHideThreshold(val threshold: Int) {
HIGHEST(5),
HIGH(13),
LOW(31),
LOWEST(47),
}
enum class TabletUiMode {
AUTOMATIC,
ALWAYS,
LANDSCAPE,
NEVER,
}
enum class ExtensionInstaller {
LEGACY,
PACKAGEINSTALLER,
SHIZUKU,
}
// SY -->
@@ -1,24 +1,27 @@
package eu.kanade.tachiyomi.data.preference
import android.content.Context
import android.os.Build
import android.os.Environment
import androidx.core.content.edit
import androidx.core.net.toUri
import androidx.preference.PreferenceManager
import com.tfcporciuncula.flow.FlowSharedPreferences
import com.tfcporciuncula.flow.Preference
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.anilist.Anilist
import eu.kanade.tachiyomi.ui.browse.migration.sources.MigrationSourcesController
import eu.kanade.tachiyomi.ui.library.LibraryGroup
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting
import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
import eu.kanade.tachiyomi.ui.reader.setting.ReaderBottomButton
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig
import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.onEach
import java.io.File
import java.text.DateFormat
import java.text.SimpleDateFormat
@@ -26,25 +29,6 @@ import java.util.Locale
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
import eu.kanade.tachiyomi.data.preference.PreferenceValues as Values
fun <T> Preference<T>.asImmediateFlow(block: (T) -> Unit): Flow<T> {
block(get())
return asFlow()
.onEach { block(it) }
}
operator fun <T> Preference<Set<T>>.plusAssign(item: T) {
set(get() + item)
}
operator fun <T> Preference<Set<T>>.minusAssign(item: T) {
set(get() - item)
}
fun Preference<Boolean>.toggle(): Boolean {
set(!get())
return get()
}
class PreferencesHelper(val context: Context) {
private val prefs = PreferenceManager.getDefaultSharedPreferences(context)
@@ -66,17 +50,17 @@ class PreferencesHelper(val context: Context) {
fun confirmExit() = prefs.getBoolean(Keys.confirmExit, false)
fun hideBottomBarOnScroll() = flowPrefs.getBoolean(Keys.hideBottomBarOnScroll, true)
fun hideBottomBarOnScroll() = flowPrefs.getBoolean("pref_hide_bottom_bar_on_scroll", true)
fun showSideNavOnBottom() = flowPrefs.getBoolean(Keys.showSideNavOnBottom, false)
fun sideNavIconAlignment() = flowPrefs.getInt("pref_side_nav_icon_alignment", 0)
fun useAuthenticator() = flowPrefs.getBoolean(Keys.useAuthenticator, false)
fun useAuthenticator() = flowPrefs.getBoolean("use_biometric_lock", false)
fun lockAppAfter() = flowPrefs.getInt(Keys.lockAppAfter, 0)
fun lockAppAfter() = flowPrefs.getInt("lock_app_after", 0)
fun lastAppUnlock() = flowPrefs.getLong(Keys.lastAppUnlock, 0)
fun lastAppUnlock() = flowPrefs.getLong("last_app_unlock", 0)
fun secureScreen() = flowPrefs.getBoolean(Keys.secureScreen, false)
fun secureScreen() = flowPrefs.getBoolean("secure_screen", false)
fun hideNotificationContent() = prefs.getBoolean(Keys.hideNotificationContent, false)
@@ -84,111 +68,117 @@ class PreferencesHelper(val context: Context) {
fun autoUpdateTrackers() = prefs.getBoolean(Keys.autoUpdateTrackers, false)
fun showLibraryUpdateErrors() = prefs.getBoolean(Keys.showLibraryUpdateErrors, false)
fun themeMode() = flowPrefs.getEnum(
"pref_theme_mode_key",
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { Values.ThemeMode.system } else { Values.ThemeMode.light }
)
fun themeMode() = flowPrefs.getEnum(Keys.themeMode, Values.ThemeMode.system)
fun appTheme() = flowPrefs.getEnum(
"pref_app_theme",
if (DeviceUtil.isDynamicColorAvailable) { Values.AppTheme.MONET } else { Values.AppTheme.DEFAULT }
)
fun themeLight() = flowPrefs.getEnum(Keys.themeLight, Values.LightThemeVariant.default)
fun themeDarkAmoled() = flowPrefs.getBoolean("pref_theme_dark_amoled_key", false)
fun themeDark() = flowPrefs.getEnum(Keys.themeDark, Values.DarkThemeVariant.default)
// SY -->
fun pageTransitionsPager() = flowPrefs.getBoolean("pref_enable_transitions_pager_key", true)
fun pageTransitionsPager() = flowPrefs.getBoolean(Keys.enableTransitionsPager, true)
fun pageTransitionsWebtoon() = flowPrefs.getBoolean("pref_enable_transitions_webtoon_key", true)
// SY <--
fun pageTransitionsWebtoon() = flowPrefs.getBoolean(Keys.enableTransitionsWebtoon, true)
fun doubleTapAnimSpeed() = flowPrefs.getInt("pref_double_tap_anim_speed", 500)
fun doubleTapAnimSpeed() = flowPrefs.getInt(Keys.doubleTapAnimationSpeed, 500)
fun showPageNumber() = flowPrefs.getBoolean("pref_show_page_number_key", true)
fun showPageNumber() = flowPrefs.getBoolean(Keys.showPageNumber, true)
fun dualPageSplitPaged() = flowPrefs.getBoolean("pref_dual_page_split", false)
fun dualPageSplitPaged() = flowPrefs.getBoolean(Keys.dualPageSplitPaged, false)
fun dualPageSplitWebtoon() = flowPrefs.getBoolean("pref_dual_page_split_webtoon", false)
fun dualPageSplitWebtoon() = flowPrefs.getBoolean(Keys.dualPageSplitWebtoon, false)
fun dualPageInvertPaged() = flowPrefs.getBoolean("pref_dual_page_invert", false)
fun dualPageInvertPaged() = flowPrefs.getBoolean(Keys.dualPageInvertPaged, false)
fun dualPageInvertWebtoon() = flowPrefs.getBoolean(Keys.dualPageInvertWebtoon, false)
fun dualPageInvertWebtoon() = flowPrefs.getBoolean("pref_dual_page_invert_webtoon", false)
fun showReadingMode() = prefs.getBoolean(Keys.showReadingMode, true)
fun trueColor() = flowPrefs.getBoolean(Keys.trueColor, false)
fun trueColor() = flowPrefs.getBoolean("pref_true_color_key", false)
fun fullscreen() = flowPrefs.getBoolean(Keys.fullscreen, true)
fun fullscreen() = flowPrefs.getBoolean("fullscreen", true)
fun cutoutShort() = flowPrefs.getBoolean(Keys.cutoutShort, true)
fun cutoutShort() = flowPrefs.getBoolean("cutout_short", true)
fun keepScreenOn() = flowPrefs.getBoolean(Keys.keepScreenOn, true)
fun keepScreenOn() = flowPrefs.getBoolean("pref_keep_screen_on_key", true)
fun customBrightness() = flowPrefs.getBoolean(Keys.customBrightness, false)
fun customBrightness() = flowPrefs.getBoolean("pref_custom_brightness_key", false)
fun customBrightnessValue() = flowPrefs.getInt(Keys.customBrightnessValue, 0)
fun customBrightnessValue() = flowPrefs.getInt("custom_brightness_value", 0)
fun colorFilter() = flowPrefs.getBoolean(Keys.colorFilter, false)
fun colorFilter() = flowPrefs.getBoolean("pref_color_filter_key", false)
fun colorFilterValue() = flowPrefs.getInt(Keys.colorFilterValue, 0)
fun colorFilterValue() = flowPrefs.getInt("color_filter_value", 0)
fun colorFilterMode() = flowPrefs.getInt(Keys.colorFilterMode, 0)
fun colorFilterMode() = flowPrefs.getInt("color_filter_mode", 0)
fun grayscale() = flowPrefs.getBoolean(Keys.grayscale, false)
fun grayscale() = flowPrefs.getBoolean("pref_grayscale", false)
fun invertedColors() = flowPrefs.getBoolean("pref_inverted_colors", false)
fun defaultReadingMode() = prefs.getInt(Keys.defaultReadingMode, ReadingModeType.RIGHT_TO_LEFT.flagValue)
fun defaultOrientationType() = prefs.getInt(Keys.defaultOrientationType, OrientationType.FREE.flagValue)
fun imageScaleType() = flowPrefs.getInt(Keys.imageScaleType, 1)
fun imageScaleType() = flowPrefs.getInt("pref_image_scale_type_key", 1)
fun zoomStart() = flowPrefs.getInt(Keys.zoomStart, 1)
fun zoomStart() = flowPrefs.getInt("pref_zoom_start_key", 1)
fun readerTheme() = flowPrefs.getInt(Keys.readerTheme, 3)
fun readerTheme() = flowPrefs.getInt("pref_reader_theme_key", 3)
fun alwaysShowChapterTransition() = flowPrefs.getBoolean(Keys.alwaysShowChapterTransition, true)
fun alwaysShowChapterTransition() = flowPrefs.getBoolean("always_show_chapter_transition", true)
fun cropBorders() = flowPrefs.getBoolean(Keys.cropBorders, false)
fun cropBorders() = flowPrefs.getBoolean("crop_borders", false)
fun cropBordersWebtoon() = flowPrefs.getBoolean(Keys.cropBordersWebtoon, false)
fun cropBordersWebtoon() = flowPrefs.getBoolean("crop_borders_webtoon", false)
fun webtoonSidePadding() = flowPrefs.getInt(Keys.webtoonSidePadding, 0)
fun webtoonSidePadding() = flowPrefs.getInt("webtoon_side_padding", 0)
fun readWithTapping() = flowPrefs.getBoolean(Keys.readWithTapping, true)
fun readWithTapping() = flowPrefs.getBoolean("reader_tap", true)
fun pagerNavInverted() = flowPrefs.getEnum(Keys.pagerNavInverted, Values.TappingInvertMode.NONE)
fun pagerNavInverted() = flowPrefs.getEnum("reader_tapping_inverted", Values.TappingInvertMode.NONE)
fun webtoonNavInverted() = flowPrefs.getEnum(Keys.webtoonNavInverted, Values.TappingInvertMode.NONE)
fun webtoonNavInverted() = flowPrefs.getEnum("reader_tapping_inverted_webtoon", Values.TappingInvertMode.NONE)
fun readWithLongTap() = flowPrefs.getBoolean(Keys.readWithLongTap, true)
fun readWithLongTap() = flowPrefs.getBoolean("reader_long_tap", true)
fun readWithVolumeKeys() = flowPrefs.getBoolean(Keys.readWithVolumeKeys, false)
fun readWithVolumeKeys() = flowPrefs.getBoolean("reader_volume_keys", false)
fun readWithVolumeKeysInverted() = flowPrefs.getBoolean(Keys.readWithVolumeKeysInverted, false)
fun readWithVolumeKeysInverted() = flowPrefs.getBoolean("reader_volume_keys_inverted", false)
fun navigationModePager() = flowPrefs.getInt(Keys.navigationModePager, 0)
fun navigationModePager() = flowPrefs.getInt("reader_navigation_mode_pager", 0)
fun navigationModeWebtoon() = flowPrefs.getInt(Keys.navigationModeWebtoon, 0)
fun navigationModeWebtoon() = flowPrefs.getInt("reader_navigation_mode_webtoon", 0)
fun showNavigationOverlayNewUser() = flowPrefs.getBoolean(Keys.showNavigationOverlayNewUser, true)
fun showNavigationOverlayNewUser() = flowPrefs.getBoolean("reader_navigation_overlay_new_user", true)
fun showNavigationOverlayOnStart() = flowPrefs.getBoolean(Keys.showNavigationOverlayOnStart, false)
fun showNavigationOverlayOnStart() = flowPrefs.getBoolean("reader_navigation_overlay_on_start", false)
fun portraitColumns() = flowPrefs.getInt(Keys.portraitColumns, 0)
fun readerHideThreshold() = flowPrefs.getEnum("reader_hide_threshold", Values.ReaderHideThreshold.LOW)
fun landscapeColumns() = flowPrefs.getInt(Keys.landscapeColumns, 0)
fun portraitColumns() = flowPrefs.getInt("pref_library_columns_portrait_key", 0)
fun landscapeColumns() = flowPrefs.getInt("pref_library_columns_landscape_key", 0)
fun jumpToChapters() = prefs.getBoolean(Keys.jumpToChapters, false)
fun updateOnlyNonCompleted() = prefs.getBoolean(Keys.updateOnlyNonCompleted, false)
fun autoUpdateTrack() = prefs.getBoolean(Keys.autoUpdateTrack, true)
fun autoAddTrack() = prefs.getBoolean(Keys.autoAddTrack, true)
fun lastUsedSource() = flowPrefs.getLong("last_catalogue_source", -1)
fun lastUsedSource() = flowPrefs.getLong(Keys.lastUsedSource, -1)
fun lastUsedCategory() = flowPrefs.getInt(Keys.lastUsedCategory, 0)
fun lastUsedCategory() = flowPrefs.getInt("last_used_category", 0)
fun lastVersionCode() = flowPrefs.getInt("last_version_code", 0)
fun sourceDisplayMode() = flowPrefs.getEnum(Keys.sourceDisplayMode, DisplayMode.COMPACT_GRID)
fun sourceDisplayMode() = flowPrefs.getEnum("pref_display_mode_catalogue", DisplayModeSetting.COMPACT_GRID)
fun enabledLanguages() = flowPrefs.getStringSet(Keys.enabledLanguages, setOf("all", "en", Locale.getDefault().language))
fun enabledLanguages() = flowPrefs.getStringSet("source_languages", setOf("all", "en", Locale.getDefault().language))
fun trackUsername(sync: TrackService) = prefs.getString(Keys.trackUsername(sync.id), "")
@@ -205,22 +195,26 @@ class PreferencesHelper(val context: Context) {
fun anilistScoreType() = flowPrefs.getString("anilist_score_type", Anilist.POINT_10)
fun backupsDirectory() = flowPrefs.getString(Keys.backupDirectory, defaultBackupDir.toString())
fun backupsDirectory() = flowPrefs.getString("backup_directory", defaultBackupDir.toString())
fun relativeTime() = flowPrefs.getInt("relative_time", 7)
fun dateFormat(format: String = flowPrefs.getString(Keys.dateFormat, "").get()): DateFormat = when (format) {
"" -> DateFormat.getDateInstance(DateFormat.SHORT)
else -> SimpleDateFormat(format, Locale.getDefault())
}
fun downloadsDirectory() = flowPrefs.getString(Keys.downloadsDirectory, defaultDownloadsDir.toString())
fun downloadsDirectory() = flowPrefs.getString("download_directory", defaultDownloadsDir.toString())
fun downloadOnlyOverWifi() = prefs.getBoolean(Keys.downloadOnlyOverWifi, true)
fun saveChaptersAsCBZ() = flowPrefs.getBoolean("save_chapter_as_cbz", false)
fun folderPerManga() = prefs.getBoolean(Keys.folderPerManga, false)
fun numberOfBackups() = flowPrefs.getInt(Keys.numberOfBackups, 1)
fun numberOfBackups() = flowPrefs.getInt("backup_slots", 1)
fun backupInterval() = flowPrefs.getInt(Keys.backupInterval, 0)
fun backupInterval() = flowPrefs.getInt("backup_interval", 0)
fun removeAfterReadSlots() = prefs.getInt(Keys.removeAfterReadSlots, -1)
@@ -228,28 +222,34 @@ class PreferencesHelper(val context: Context) {
fun removeBookmarkedChapters() = prefs.getBoolean(Keys.removeBookmarkedChapters, false)
fun libraryUpdateInterval() = flowPrefs.getInt(Keys.libraryUpdateInterval, 24)
fun removeExcludeCategories() = flowPrefs.getStringSet("remove_exclude_categories", emptySet())
fun libraryUpdateRestriction() = flowPrefs.getStringSet(Keys.libraryUpdateRestriction, setOf(UNMETERED_NETWORK))
fun libraryUpdateInterval() = flowPrefs.getInt("pref_library_update_interval_key", 24)
fun libraryUpdateCategories() = flowPrefs.getStringSet(Keys.libraryUpdateCategories, emptySet())
fun libraryUpdateCategoriesExclude() = flowPrefs.getStringSet(Keys.libraryUpdateCategoriesExclude, emptySet())
fun libraryUpdateDeviceRestriction() = flowPrefs.getStringSet("library_update_restriction", setOf(DEVICE_ONLY_ON_WIFI))
fun libraryUpdateMangaRestriction() = flowPrefs.getStringSet("library_update_manga_restriction", setOf(MANGA_FULLY_READ, MANGA_ONGOING))
fun libraryUpdatePrioritization() = flowPrefs.getInt(Keys.libraryUpdatePrioritization, 0)
fun showUpdatesNavBadge() = flowPrefs.getBoolean("library_update_show_tab_badge", false)
fun unreadUpdatesCount() = flowPrefs.getInt("library_unread_updates_count", 0)
fun libraryDisplayMode() = flowPrefs.getEnum(Keys.libraryDisplayMode, DisplayMode.COMPACT_GRID)
fun libraryUpdateCategories() = flowPrefs.getStringSet("library_update_categories", emptySet())
fun libraryUpdateCategoriesExclude() = flowPrefs.getStringSet("library_update_categories_exclude", emptySet())
fun downloadBadge() = flowPrefs.getBoolean(Keys.downloadBadge, false)
fun libraryDisplayMode() = flowPrefs.getEnum("pref_display_mode_library", DisplayModeSetting.COMPACT_GRID)
fun localBadge() = flowPrefs.getBoolean(Keys.localBadge, true)
fun downloadBadge() = flowPrefs.getBoolean("display_download_badge", false)
fun downloadedOnly() = flowPrefs.getBoolean(Keys.downloadedOnly, false)
fun localBadge() = flowPrefs.getBoolean("display_local_badge", true)
fun unreadBadge() = flowPrefs.getBoolean(Keys.unreadBadge, true)
fun downloadedOnly() = flowPrefs.getBoolean("pref_downloaded_only", false)
fun categoryTabs() = flowPrefs.getBoolean(Keys.categoryTabs, true)
fun unreadBadge() = flowPrefs.getBoolean("display_unread_badge", true)
fun categoryNumberOfItems() = flowPrefs.getBoolean(Keys.categoryNumberOfItems, false)
fun languageBadge() = flowPrefs.getBoolean("display_language_badge", false)
fun categoryTabs() = flowPrefs.getBoolean("display_category_tabs", true)
fun categoryNumberOfItems() = flowPrefs.getBoolean("display_number_of_items", false)
fun filterDownloaded() = flowPrefs.getInt(Keys.filterDownloaded, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
@@ -263,18 +263,19 @@ class PreferencesHelper(val context: Context) {
fun filterLewd() = flowPrefs.getInt(Keys.filterLewd, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
fun librarySortingMode() = flowPrefs.getInt(Keys.librarySortingMode, 0)
fun librarySortingMode() = flowPrefs.getEnum(Keys.librarySortingMode, SortModeSetting.ALPHABETICAL)
fun librarySortingAscending() = flowPrefs.getEnum(Keys.librarySortingDirection, SortDirectionSetting.ASCENDING)
fun librarySortingAscending() = flowPrefs.getBoolean("library_sorting_ascending", true)
fun migrationSortingMode() = flowPrefs.getEnum(Keys.migrationSortingMode, MigrationSourcesController.SortSetting.ALPHABETICAL)
fun migrationSortingDirection() = flowPrefs.getEnum(Keys.migrationSortingDirection, MigrationSourcesController.DirectionSetting.ASCENDING)
fun automaticExtUpdates() = flowPrefs.getBoolean(Keys.automaticExtUpdates, true)
fun automaticExtUpdates() = flowPrefs.getBoolean("automatic_ext_updates", true)
fun showNsfwSource() = flowPrefs.getBoolean(Keys.showNsfwSource, true)
fun showNsfwExtension() = flowPrefs.getBoolean(Keys.showNsfwExtension, true)
fun labelNsfwExtension() = prefs.getBoolean(Keys.labelNsfwExtension, true)
fun showNsfwSource() = flowPrefs.getBoolean("show_nsfw_source", true)
fun extensionUpdatesCount() = flowPrefs.getInt("ext_updates_count", 0)
fun lastAppCheck() = flowPrefs.getLong("last_app_check", 0)
fun lastExtCheck() = flowPrefs.getLong("last_ext_check", 0)
fun searchPinnedSourcesOnly() = prefs.getBoolean(Keys.searchPinnedSourcesOnly, false)
@@ -283,15 +284,15 @@ class PreferencesHelper(val context: Context) {
fun pinnedSources() = flowPrefs.getStringSet("pinned_catalogues", emptySet())
fun downloadNew() = flowPrefs.getBoolean(Keys.downloadNew, false)
fun downloadNew() = flowPrefs.getBoolean("download_new", false)
fun downloadNewCategories() = flowPrefs.getStringSet(Keys.downloadNewCategories, emptySet())
fun downloadNewCategoriesExclude() = flowPrefs.getStringSet(Keys.downloadNewCategoriesExclude, emptySet())
fun lang() = prefs.getString(Keys.lang, "")
fun downloadNewCategories() = flowPrefs.getStringSet("download_new_categories", emptySet())
fun downloadNewCategoriesExclude() = flowPrefs.getStringSet("download_new_categories_exclude", emptySet())
fun defaultCategory() = prefs.getInt(Keys.defaultCategory, -1)
fun categorizedDisplaySettings() = flowPrefs.getBoolean("categorized_display", false)
fun skipRead() = prefs.getBoolean(Keys.skipRead, false)
fun skipFiltered() = prefs.getBoolean(Keys.skipFiltered, true)
@@ -316,7 +317,18 @@ class PreferencesHelper(val context: Context) {
fun sortChapterByAscendingOrDescending() = prefs.getInt(Keys.defaultChapterSortByAscendingOrDescending, Manga.CHAPTER_SORT_DESC)
fun incognitoMode() = flowPrefs.getBoolean(Keys.incognitoMode, false)
fun incognitoMode() = flowPrefs.getBoolean("incognito_mode", false)
fun tabletUiMode() = flowPrefs.getEnum("tablet_ui_mode", Values.TabletUiMode.AUTOMATIC)
fun extensionInstaller() = flowPrefs.getEnum(
"extension_installer",
if (DeviceUtil.isMiui) Values.ExtensionInstaller.LEGACY else Values.ExtensionInstaller.PACKAGEINSTALLER
)
fun verboseLogging() = prefs.getBoolean(Keys.verboseLogging, false)
fun autoClearChapterCache() = prefs.getBoolean(Keys.autoClearChapterCache, false)
fun setChapterSettingsDefault(manga: Manga) {
prefs.edit {
@@ -328,7 +340,6 @@ class PreferencesHelper(val context: Context) {
putInt(Keys.defaultChapterSortByAscendingOrDescending, if (manga.sortDescending()) Manga.CHAPTER_SORT_DESC else Manga.CHAPTER_SORT_ASC)
}
}
// SY -->
fun defaultMangaOrder() = flowPrefs.getString("default_manga_order", "")
@@ -339,58 +350,60 @@ class PreferencesHelper(val context: Context) {
fun useSourceWithMost() = flowPrefs.getBoolean("use_source_with_most", false)
fun skipPreMigration() = flowPrefs.getBoolean(Keys.skipPreMigration, false)
fun skipPreMigration() = flowPrefs.getBoolean("skip_pre_migration", false)
fun isHentaiEnabled() = flowPrefs.getBoolean(Keys.eh_is_hentai_enabled, true)
fun hideNotFoundMigration() = flowPrefs.getBoolean("hide_not_found_migration", false)
fun enableExhentai() = flowPrefs.getBoolean(Keys.eh_enableExHentai, false)
fun isHentaiEnabled() = flowPrefs.getBoolean("eh_is_hentai_enabled", true)
fun imageQuality() = flowPrefs.getString(Keys.eh_ehentai_quality, "auto")
fun enableExhentai() = flowPrefs.getBoolean("enable_exhentai", false)
fun useHentaiAtHome() = flowPrefs.getInt(Keys.eh_enable_hah, 0)
fun imageQuality() = flowPrefs.getString("ehentai_quality", "auto")
fun useHentaiAtHome() = flowPrefs.getInt("eh_enable_hah", 0)
fun useJapaneseTitle() = flowPrefs.getBoolean("use_jp_title", false)
fun exhUseOriginalImages() = flowPrefs.getBoolean(Keys.eh_useOrigImages, false)
fun exhUseOriginalImages() = flowPrefs.getBoolean("eh_useOrigImages", false)
fun ehTagFilterValue() = flowPrefs.getInt(Keys.eh_tag_filtering_value, 0)
fun ehTagFilterValue() = flowPrefs.getInt("eh_tag_filtering_value", 0)
fun ehTagWatchingValue() = flowPrefs.getInt(Keys.eh_tag_watching_value, 0)
fun ehTagWatchingValue() = flowPrefs.getInt("eh_tag_watching_value", 0)
// EH Cookies
fun memberIdVal() = flowPrefs.getString("eh_ipb_member_id", "")
fun passHashVal() = flowPrefs.getString("eh_ipb_pass_hash", "")
fun igneousVal() = flowPrefs.getString("eh_igneous", "")
fun ehSettingsProfile() = flowPrefs.getInt(Keys.eh_ehSettingsProfile, -1)
fun exhSettingsProfile() = flowPrefs.getInt(Keys.eh_exhSettingsProfile, -1)
fun exhSettingsKey() = flowPrefs.getString(Keys.eh_settingsKey, "")
fun exhSessionCookie() = flowPrefs.getString(Keys.eh_sessionCookie, "")
fun exhHathPerksCookies() = flowPrefs.getString(Keys.eh_hathPerksCookie, "")
fun ehSettingsProfile() = flowPrefs.getInt("eh_ehSettingsProfile", -1)
fun exhSettingsProfile() = flowPrefs.getInt("eh_exhSettingsProfile", -1)
fun exhSettingsKey() = flowPrefs.getString("eh_settingsKey", "")
fun exhSessionCookie() = flowPrefs.getString("eh_sessionCookie", "")
fun exhHathPerksCookies() = flowPrefs.getString("eh_hathPerksCookie", "")
fun exhShowSyncIntro() = flowPrefs.getBoolean(Keys.eh_showSyncIntro, true)
fun exhShowSyncIntro() = flowPrefs.getBoolean("eh_show_sync_intro", true)
fun exhReadOnlySync() = flowPrefs.getBoolean(Keys.eh_readOnlySync, false)
fun exhReadOnlySync() = flowPrefs.getBoolean("eh_sync_read_only", false)
fun exhLenientSync() = flowPrefs.getBoolean(Keys.eh_lenientSync, false)
fun exhLenientSync() = flowPrefs.getBoolean("eh_lenient_sync", false)
fun exhShowSettingsUploadWarning() = flowPrefs.getBoolean(Keys.eh_showSettingsUploadWarning, true)
fun exhShowSettingsUploadWarning() = flowPrefs.getBoolean("eh_showSettingsUploadWarning2", true)
fun expandFilters() = flowPrefs.getBoolean(Keys.eh_expandFilters, false)
fun expandFilters() = flowPrefs.getBoolean("eh_expand_filters", false)
fun readerThreads() = flowPrefs.getInt(Keys.eh_readerThreads, 2)
fun readerThreads() = flowPrefs.getInt("eh_reader_threads", 2)
fun readerInstantRetry() = flowPrefs.getBoolean(Keys.eh_readerInstantRetry, true)
fun readerInstantRetry() = flowPrefs.getBoolean("eh_reader_instant_retry", true)
fun autoscrollInterval() = flowPrefs.getFloat(Keys.eh_utilAutoscrollInterval, 3f)
fun autoscrollInterval() = flowPrefs.getFloat("eh_util_autoscroll_interval", 3f)
fun cacheSize() = flowPrefs.getString(Keys.eh_cacheSize, "75")
fun cacheSize() = flowPrefs.getString("eh_cache_size", "75")
fun preserveReadingPosition() = flowPrefs.getBoolean(Keys.eh_preserveReadingPosition, false)
fun preserveReadingPosition() = flowPrefs.getBoolean("eh_preserve_reading_position", false)
fun autoSolveCaptcha() = flowPrefs.getBoolean(Keys.eh_autoSolveCaptchas, false)
fun autoSolveCaptcha() = flowPrefs.getBoolean("eh_autosolve_captchas", false)
fun delegateSources() = flowPrefs.getBoolean(Keys.eh_delegateSources, true)
fun delegateSources() = flowPrefs.getBoolean("eh_delegate_sources", true)
fun ehLastVersionCode() = flowPrefs.getInt("eh_last_version_code", 0)
@@ -398,105 +411,109 @@ class PreferencesHelper(val context: Context) {
fun logLevel() = flowPrefs.getInt(Keys.eh_logLevel, 0)
fun enableSourceBlacklist() = flowPrefs.getBoolean(Keys.eh_enableSourceBlacklist, true)
fun enableSourceBlacklist() = flowPrefs.getBoolean("eh_enable_source_blacklist", true)
fun exhAutoUpdateFrequency() = flowPrefs.getInt(Keys.eh_autoUpdateFrequency, 1)
fun exhAutoUpdateFrequency() = flowPrefs.getInt("eh_auto_update_frequency", 1)
fun exhAutoUpdateRequirements() = flowPrefs.getStringSet(Keys.eh_autoUpdateRestrictions, emptySet())
fun exhAutoUpdateRequirements() = flowPrefs.getStringSet("eh_auto_update_restrictions", emptySet())
fun exhAutoUpdateStats() = flowPrefs.getString(Keys.eh_autoUpdateStats, "")
fun exhAutoUpdateStats() = flowPrefs.getString("eh_auto_update_stats", "")
fun aggressivePageLoading() = flowPrefs.getBoolean(Keys.eh_aggressivePageLoading, false)
fun aggressivePageLoading() = flowPrefs.getBoolean("eh_aggressive_page_loading", false)
fun preloadSize() = flowPrefs.getInt(Keys.eh_preload_size, 10)
fun preloadSize() = flowPrefs.getInt("eh_preload_size", 10)
fun useAutoWebtoon() = flowPrefs.getBoolean(Keys.eh_use_auto_webtoon, true)
fun useAutoWebtoon() = flowPrefs.getBoolean("eh_use_auto_webtoon", true)
fun exhWatchedListDefaultState() = flowPrefs.getBoolean(Keys.eh_watched_list_default_state, false)
fun exhWatchedListDefaultState() = flowPrefs.getBoolean("eh_watched_list_default_state", false)
fun exhSettingsLanguages() = flowPrefs.getString(Keys.eh_settings_languages, "false*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false")
fun exhSettingsLanguages() = flowPrefs.getString(
"eh_settings_languages",
"false*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false\nfalse*false*false"
)
fun exhEnabledCategories() = flowPrefs.getString(Keys.eh_enabled_categories, "false,false,false,false,false,false,false,false,false,false")
fun exhEnabledCategories() = flowPrefs.getString(
"eh_enabled_categories",
"false,false,false,false,false,false,false,false,false,false"
)
fun latestTabSources() = flowPrefs.getStringSet(Keys.latest_tab_sources, mutableSetOf())
fun latestTabSources() = flowPrefs.getStringSet("latest_tab_sources", mutableSetOf())
fun latestTabInFront() = flowPrefs.getBoolean(Keys.latest_tab_position, false)
fun latestTabInFront() = flowPrefs.getBoolean("latest_tab_position", false)
fun sourcesTabCategories() = flowPrefs.getStringSet(Keys.sources_tab_categories, mutableSetOf())
fun sourcesTabCategories() = flowPrefs.getStringSet("sources_tab_categories", mutableSetOf())
fun sourcesTabCategoriesFilter() = flowPrefs.getBoolean(Keys.sources_tab_categories_filter, false)
fun sourcesTabCategoriesFilter() = flowPrefs.getBoolean("sources_tab_categories_filter", false)
fun sourcesTabSourcesInCategories() = flowPrefs.getStringSet(Keys.sources_tab_source_categories, mutableSetOf())
fun sourcesTabSourcesInCategories() = flowPrefs.getStringSet("sources_tab_source_categories", mutableSetOf())
fun sourceSorting() = flowPrefs.getInt(Keys.sourcesSort, 0)
fun sourceSorting() = flowPrefs.getInt("sources_sort", 0)
fun recommendsInOverflow() = flowPrefs.getBoolean(Keys.recommendsInOverflow, false)
fun recommendsInOverflow() = flowPrefs.getBoolean("recommends_in_overflow", false)
fun enhancedEHentaiView() = flowPrefs.getBoolean(Keys.enhancedEHentaiView, true)
fun enhancedEHentaiView() = flowPrefs.getBoolean("enhanced_e_hentai_view", true)
fun webtoonEnableZoomOut() = flowPrefs.getBoolean(Keys.webtoonEnableZoomOut, false)
fun webtoonEnableZoomOut() = flowPrefs.getBoolean("webtoon_enable_zoom_out", false)
fun startReadingButton() = flowPrefs.getBoolean(Keys.startReadingButton, true)
fun startReadingButton() = flowPrefs.getBoolean("start_reading_button", true)
fun groupLibraryBy() = flowPrefs.getInt(Keys.groupLibraryBy, 0)
fun groupLibraryBy() = flowPrefs.getInt("group_library_by", LibraryGroup.BY_DEFAULT)
fun continuousVerticalTappingByPage() = flowPrefs.getBoolean(Keys.continuousVerticalTappingByPage, false)
fun continuousVerticalTappingByPage() = flowPrefs.getBoolean("continuous_vertical_tapping_by_page", false)
fun groupLibraryUpdateType() = flowPrefs.getEnum(Keys.groupLibraryUpdateType, Values.GroupLibraryMode.GLOBAL)
fun groupLibraryUpdateType() = flowPrefs.getEnum("group_library_update_type", Values.GroupLibraryMode.GLOBAL)
fun useNewSourceNavigation() = flowPrefs.getBoolean(Keys.useNewSourceNavigation, true)
fun useNewSourceNavigation() = flowPrefs.getBoolean("use_new_source_navigation", true)
fun mangaDexForceLatestCovers() = flowPrefs.getBoolean(Keys.mangaDexForceLatestCovers, false)
fun preferredMangaDexId() = flowPrefs.getString("preferred_mangaDex_id", "0")
fun preferredMangaDexId() = flowPrefs.getString(Keys.preferredMangaDexId, "0")
fun mangadexSyncToLibraryIndexes() = flowPrefs.getStringSet("pref_mangadex_sync_to_library_indexes", emptySet())
fun mangadexSyncToLibraryIndexes() = flowPrefs.getStringSet(Keys.mangadexSyncToLibraryIndexes, emptySet())
fun dataSaver() = flowPrefs.getBoolean("data_saver", false)
fun dataSaver() = flowPrefs.getBoolean(Keys.dataSaver, false)
fun dataSaverIgnoreJpeg() = flowPrefs.getBoolean("ignore_jpeg", false)
fun ignoreJpeg() = flowPrefs.getBoolean(Keys.ignoreJpeg, false)
fun dataSaverIgnoreGif() = flowPrefs.getBoolean("ignore_gif", true)
fun ignoreGif() = flowPrefs.getBoolean(Keys.ignoreGif, true)
fun dataSaverImageQuality() = flowPrefs.getInt("data_saver_image_quality", 80)
fun dataSaverImageQuality() = flowPrefs.getInt(Keys.dataSaverImageQuality, 80)
fun dataSaverImageFormatJpeg() = flowPrefs.getBoolean("data_saver_image_format_jpeg", false)
fun dataSaverImageFormatJpeg() = flowPrefs.getBoolean(Keys.dataSaverImageFormatJpeg, false)
fun dataSaverServer() = flowPrefs.getString("data_saver_server", "")
fun dataSaverServer() = flowPrefs.getString(Keys.dataSaverServer, "")
fun dataSaverColorBW() = flowPrefs.getBoolean("data_saver_color_bw", false)
fun dataSaverColorBW() = flowPrefs.getBoolean(Keys.dataSaverColorBW, false)
fun dataSaverExcludedSources() = flowPrefs.getStringSet("data_saver_excluded", emptySet())
fun saveChaptersAsCBZ() = flowPrefs.getBoolean(Keys.saveChaptersAsCBZ, false)
fun dataSaverDownloader() = flowPrefs.getBoolean("data_saver_downloader", true)
fun saveChaptersAsCBZLevel() = flowPrefs.getInt(Keys.saveChaptersAsCBZLevel, 0)
fun allowLocalSourceHiddenFolders() = flowPrefs.getBoolean("allow_local_source_hidden_folders", false)
fun allowLocalSourceHiddenFolders() = flowPrefs.getBoolean(Keys.allowLocalSourceHiddenFolders, false)
fun authenticatorTimeRanges() = flowPrefs.getStringSet("biometric_time_ranges", mutableSetOf())
fun authenticatorTimeRanges() = flowPrefs.getStringSet(Keys.authenticatorTimeRanges, mutableSetOf())
fun authenticatorDays() = flowPrefs.getInt("biometric_days", 0x7F)
fun sortTagsForLibrary() = flowPrefs.getStringSet(Keys.sortTagsForLibrary, mutableSetOf())
fun sortTagsForLibrary() = flowPrefs.getStringSet("sort_tags_for_library", mutableSetOf())
fun dontDeleteFromCategories() = flowPrefs.getStringSet(Keys.dontDeleteFromCategories, emptySet())
fun extensionRepos() = flowPrefs.getStringSet("extension_repos", emptySet())
fun extensionRepos() = flowPrefs.getStringSet(Keys.extensionRepos, emptySet())
fun cropBordersContinuousVertical() = flowPrefs.getBoolean("crop_borders_continues_vertical", false)
fun cropBordersContinuousVertical() = flowPrefs.getBoolean(Keys.cropBordersContinuousVertical, false)
fun forceHorizontalSeekbar() = flowPrefs.getBoolean("pref_force_horz_seekbar", false)
fun forceHorizontalSeekbar() = flowPrefs.getBoolean(Keys.forceHorizontalSeekbar, false)
fun landscapeVerticalSeekbar() = flowPrefs.getBoolean("pref_show_vert_seekbar_landscape", false)
fun landscapeVerticalSeekbar() = flowPrefs.getBoolean(Keys.landscapeVerticalSeekbar, false)
fun leftVerticalSeekbar() = flowPrefs.getBoolean("pref_left_handed_vertical_seekbar", false)
fun leftVerticalSeekbar() = flowPrefs.getBoolean(Keys.leftVerticalSeekbar, false)
fun readerBottomButtons() = flowPrefs.getStringSet("reader_bottom_buttons", ReaderBottomButton.BUTTONS_DEFAULTS)
fun readerBottomButtons() = flowPrefs.getStringSet(Keys.readerBottomButtons, ReaderBottomButton.BUTTONS_DEFAULTS)
fun bottomBarLabels() = flowPrefs.getBoolean("pref_show_bottom_bar_labels", true)
fun bottomBarLabels() = flowPrefs.getBoolean(Keys.bottomBarLabels, true)
fun showNavUpdates() = flowPrefs.getBoolean("pref_show_updates_button", true)
fun hideUpdatesButton() = flowPrefs.getBoolean(Keys.hideUpdatesButton, false)
fun showNavHistory() = flowPrefs.getBoolean("pref_show_history_button", true)
fun hideHistoryButton() = flowPrefs.getBoolean(Keys.hideHistoryButton, false)
fun pageLayout() = flowPrefs.getInt("page_layout", PagerConfig.PageLayout.AUTOMATIC)
fun pageLayout() = flowPrefs.getInt(Keys.pageLayout, PagerConfig.PageLayout.SINGLE_PAGE)
fun invertDoublePages() = flowPrefs.getBoolean(Keys.invertDoublePages, false)
fun invertDoublePages() = flowPrefs.getBoolean("invert_double_pages", false)
}

Some files were not shown because too many files have changed in this diff Show More