Compare commits

...

818 Commits

Author SHA1 Message Date
Jobobby04 0413d502c1 Revert Jdk 11 update 2021-02-12 20:05:46 -05:00
Jobobby04 d3416a4df5 Release 1.5.0 2021-02-12 19:49:07 -05:00
Jobobby04 1a12caa487 Hide dedupe by priority
(cherry picked from commit 2cf0475066)
2021-02-12 19:25:38 -05:00
arkon 72b7dc805c Avoid crash when source list is animating
(cherry picked from commit 2dae706198)
2021-02-12 18:54:29 -05:00
arkon 8029ff8ecc Avoid rare crashes in settings search for ListPreferences
(cherry picked from commit 3eda2a220a)
2021-02-12 18:54:21 -05:00
arkon cd8543d40b Avoid crash when device fails to handle opening a URL
(cherry picked from commit 61e5440b7c)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/ConductorExtensions.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/WhatsNewDialogController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt
2021-02-12 18:54:09 -05:00
arkon 7d1fd9f0bb Avoid crash if activity is already dead
(cherry picked from commit 2e2663bad9)
2021-02-12 18:41:31 -05:00
arkon fd65aa8fe4 Switch to stable image decoder
(cherry picked from commit f590378761)

# Conflicts:
#	.github/ISSUE_TEMPLATE.md
#	.github/ISSUE_TEMPLATE/bug_report.md
#	.github/ISSUE_TEMPLATE/feature_request.md
#	app/build.gradle.kts
2021-02-12 18:41:16 -05:00
arkon 0f349da3bc Require minimum WebView v88, try to catch fatal errors too
(cherry picked from commit f5f592be91)
2021-02-12 18:40:12 -05:00
arkon 33d0507f98 Minor download icon optimizations
(cherry picked from commit 7a373fb43a)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
2021-02-12 18:40:02 -05:00
arkon 16f9ca381e Make backup restoring logic more sequential
(cherry picked from commit aded11e599)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt
2021-02-12 18:37:19 -05:00
arkon 2ff186eaec Remove ExperimentalSerializationApi opt-in annotations
(cherry picked from commit 41d7cee020)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt
2021-02-12 16:31:23 -05:00
Jozef Hollý f3678e3fd3 Weblate translations (#4378)
Co-authored-by: Adaś <adam.prosniak@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alex <linuxrf@gmail.com>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: Crazyom <naxom@laposte.net>
Co-authored-by: Cream π <f.t.nayeem014@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Eugene <eugcheung94@gmail.com>
Co-authored-by: Flamm <robindevaux25@gmail.com>
Co-authored-by: Habibur Rahman <habiburr016@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: Iuri Jikidze <ijiki16@freeuni.edu.ge>
Co-authored-by: Jimly Asshiddiqy <j_mly@ymail.com>
Co-authored-by: Kurocon <weblate@kurocon.nl>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Matteo Gaeta <matteo.gaeta.1998@gmail.com>
Co-authored-by: Michalis <michalisntovas@yahoo.gr>
Co-authored-by: Murilo Simionato Arnemann <murilo2110@hotmail.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: Rocco Casadei <roccobot@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
Co-authored-by: Soitora <simon.mattila@protonmail.com>
Co-authored-by: darkbeast13 <nikhil15mps@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Co-authored-by: 赤城 悠 <hapipon815@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/bn/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ca/
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/fi/
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/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/ka/
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/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: Adaś <adam.prosniak@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alex <linuxrf@gmail.com>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: Crazyom <naxom@laposte.net>
Co-authored-by: Cream π <f.t.nayeem014@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Eugene <eugcheung94@gmail.com>
Co-authored-by: Flamm <robindevaux25@gmail.com>
Co-authored-by: Habibur Rahman <habiburr016@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: Iuri Jikidze <ijiki16@freeuni.edu.ge>
Co-authored-by: Jimly Asshiddiqy <j_mly@ymail.com>
Co-authored-by: Kurocon <weblate@kurocon.nl>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Matteo Gaeta <matteo.gaeta.1998@gmail.com>
Co-authored-by: Michalis <michalisntovas@yahoo.gr>
Co-authored-by: Murilo Simionato Arnemann <murilo2110@hotmail.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: Rocco Casadei <roccobot@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
Co-authored-by: Soitora <simon.mattila@protonmail.com>
Co-authored-by: darkbeast13 <nikhil15mps@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Co-authored-by: 赤城 悠 <hapipon815@gmail.com>
(cherry picked from commit f2ef6a20e6)
2021-02-12 16:30:29 -05:00
arkon c29690282c Handle link for multisource extension commits (closes #4432)
(cherry picked from commit a398c3fb81)
2021-02-11 19:27:23 -05:00
arkon f93d21774f Adjust some scopes
(cherry picked from commit 2a454b44cc)
2021-02-11 19:27:15 -05:00
Jobobby04 efe0d9de05 Cleanup 2021-02-11 19:27:10 -05:00
arkon 04da26195e Fix invisible overflow icon in chapter filter sheet in light blue theme
(cherry picked from commit 7b66ece895)
2021-02-11 19:26:46 -05:00
Jobobby04 e8e7f96be5 Add monthly to SY strings 2021-02-11 19:26:17 -05:00
vance 37ce2140f3 Added dual page split setting (#4252)
* Add DualPageSplit option

* remove extra line

* Split double-page into two pages

* Remove !isAnimated check and add (ALPHA) to the label

* Fix missing insert pages

* Pager cleanup

* Add dual split to Webtoon and fix Vertical

* Fix L2R/R2L

* Add comments and refactor code in ImageUtil

* Use a simpler split solution in webtoon mode

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

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt
2021-02-11 19:25:58 -05:00
arkon c5ef58ac72 Add weekly to library update frequency options (closes #4422)
(cherry picked from commit aa67229daf)
2021-02-11 19:17:57 -05:00
arkon cb1ea6f571 Clean up LibraryUpdateService a bit
(cherry picked from commit 5af68186d6)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2021-02-11 19:17:44 -05:00
Jobobby04 a207b4b729 Fix build after AboutLibraries update 2021-02-11 19:12:50 -05:00
arkon e9ec281159 Open manga when clicking thumbnail in migration list (closes #4152)
(cherry picked from commit 545bc0e605)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaPresenter.kt
2021-02-11 19:12:23 -05:00
arkon ede6a54b30 Remove unnecessary LayoutContainer implementations
(cherry picked from commit 291168f4de)
2021-02-11 18:13:41 -05:00
arkon 79770a9deb Add action to directly share crash log file from notification
(cherry picked from commit 9facb51f22)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt
2021-02-11 18:13:32 -05:00
arkon 197083e437 Show locales in list of sources to migrate
(cherry picked from commit 5b7d8c5e37)
2021-02-11 18:12:39 -05:00
arkon f8da1fba7d Update AboutLibraries
(cherry picked from commit 5945937e4b)
2021-02-11 18:12:32 -05:00
Jobobby04 56ead63798 Fix legacy backups
(cherry picked from commit ded58541f5)
(cherry picked from commit 9f9f9872eb)
2021-02-11 18:12:24 -05:00
arkon 7d81d812bc Revert attempt to programmatically determine user agent string; fallback to Edge
(cherry picked from commit 3566072f4a)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/online/HttpSource.kt
2021-02-11 18:12:14 -05:00
arkon e25991544e Add Esperanto locale
(cherry picked from commit b85cd86b24)
2021-02-11 18:11:27 -05:00
arkon f91837a019 Chapter backup optimization
From https://github.com/jobobby04/TachiyomiSY/commit/fc6d9aaf519ce8830d3b45fd704b32e37f3f786f#diff-9872ccc3c9af14d2872ec99199409e60a11cb754ab23e733b1d45843778f7c95R24

(cherry picked from commit 79c3767fff)
2021-02-11 18:11:14 -05:00
arkon 14db2351c6 Massage user agent string from WebView a bit more
(cherry picked from commit cf1609a429)
2021-02-11 18:11:05 -05:00
arkon a616193cdf Fix selected tab in sheets not being the accent color
(cherry picked from commit 3aeac7e7b5)
2021-02-11 18:10:58 -05:00
arkon 72b0fcca9d Don't restrict filter sheet height anymore
(cherry picked from commit 1557f713f4)
2021-02-11 18:10:49 -05:00
Andreas d4de925ec7 Add Right and Left navigation (#4392)
and remove default navigation classes in favor of the navigation classes

(cherry picked from commit b63d24ac1a)
2021-02-11 18:10:37 -05:00
arkon b6c7e96ddc Avoid some unnecessary re-renderings of download icons
(cherry picked from commit 348c1ff29d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
2021-02-11 18:10:28 -05:00
arkon c5b5c8c21d Fix downloads getting deleted when marked as unread
(cherry picked from commit 717e55497f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
2021-02-11 18:09:44 -05:00
Jobobby04 0ab28fd6d6 Remove useless var shadow 2021-02-11 18:08:30 -05:00
Jobobby04 7b5dd4fed4 Cleanup SyncFollows 2021-02-11 18:08:13 -05:00
Jobobby04 4896f3d16c Allow MDList tracking for all manga 2021-02-11 17:55:43 -05:00
Jobobby04 eb5469d362 Get MDList working with merged manga 2021-02-11 17:02:48 -05:00
Jobobby04 227de5d838 Separate MDList from Mangadex manga, allowing it to be used with other sources(not implemented) 2021-02-11 16:41:23 -05:00
Jobobby04 86c228243d Fix merged manga chapterlist not updating, fix merge chapter downloads 2021-02-10 16:39:11 -05:00
Carlos 88690008f7 use super high quality on mangaplus
(cherry picked from commit 2074fbc192b9cfe9475643583d3d77f3cd9e4b4c)
2021-02-07 23:39:51 -05:00
Carlos 4388e7bc3a fix more descriptions
(cherry picked from commit 2f69b74f3429ab94aaee0e55eefbb64047a9737c)
2021-02-07 23:39:41 -05:00
Jobobby04 ded58541f5 Fix legacy backups 2021-02-07 21:54:26 -05:00
arkon aadfa2aa8c Show help action when source fails to load
(cherry picked from commit d84b5e8b46)
2021-02-06 19:16:11 -05:00
arkon e63b15a133 Use AndroidX version of ContextThemeWrapper
(cherry picked from commit 5f9ddf9ff5)
2021-02-06 19:16:02 -05:00
arkon 84590688be Remove some logic around old legacy backup versions + minor optimizations
(cherry picked from commit bbee093c63)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupManager.kt
2021-02-06 19:15:48 -05:00
arkon 2270d3d8e3 Do a regular return to cancel update jobs instead of throwing an exception
(cherry picked from commit e8c35ae4e1)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2021-02-06 19:14:25 -05:00
arkon bc9602a0f2 Set clip data when sharing content URIs (closes #4198)
(cherry picked from commit 1607658c30)
2021-02-06 19:11:26 -05:00
arkon bd8084c565 Minor optimizations for restoring full backups
Based on https://github.com/jobobby04/TachiyomiSY/commit/fc6d9aaf519ce8830d3b45fd704b32e37f3f786f

(cherry picked from commit 2e9ef373f3)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt
2021-02-06 19:11:13 -05:00
arkon 6be485ea79 Switch back to new image decoder for preview builds
(cherry picked from commit ec6eef6d37)

# Conflicts:
#	app/build.gradle.kts
2021-02-06 19:09:43 -05:00
arkon e80a4bea18 Avoid crash when changing spinner indeterminate state
(cherry picked from commit 7191552126)
2021-02-06 19:08:20 -05:00
arkon 73a1c27dd9 Update dependencies
(cherry picked from commit cfa07490e5)

# Conflicts:
#	build.gradle.kts
2021-02-06 19:08:07 -05:00
arkon eb2ceebeeb Update to Gradle 6.8.2
(cherry picked from commit ae40990eb9)

# Conflicts:
#	gradle/wrapper/gradle-wrapper.jar
2021-02-06 19:06:58 -05:00
Jobobby04 d7eac12eee Use some core ktx 2021-02-06 19:02:35 -05:00
Jobobby04 e633da5567 Backup read manga that are not in library 2021-02-06 18:59:40 -05:00
Jobobby04 e26ab22e41 Update manga from differernt sources in parallel 2021-02-04 19:05:35 -05:00
arkon 9a3faad499 Fix unreadable sheet tab text in light blue theme
(cherry picked from commit 9f2fe33ce0)
2021-02-04 17:13:11 -05:00
arkon c635d72b30 Remove buildSrc module's dependency on JCenter
(cherry picked from commit 33660de6b1)

# Conflicts:
#	build.gradle.kts
2021-02-04 17:12:06 -05:00
arkon 15b826074f Don't automatically set MAL start date (closes #4349)
(cherry picked from commit 13d25e0849)
2021-02-04 17:07:56 -05:00
arkon b235521dd1 Rounded bottom sheets
(cherry picked from commit 6662e2002f)
2021-02-04 17:07:39 -05:00
Jobobby04 fc6d9aaf51 Restore offline optimization
Should make restore offline faster when data is already there
2021-02-04 17:06:28 -05:00
Jobobby04 e629703afd Build fix 2021-01-31 19:39:11 -05:00
arkon 24d5d5737e Remove strings that shouldn't have been translated
(cherry picked from commit d4081dc899)
2021-01-31 19:38:53 -05:00
arkon 6168dadba3 Pad trackers list a bit
(cherry picked from commit 62dffb8226)
2021-01-31 19:38:45 -05:00
Jozef Hollý a0c9418174 Weblate translations (#4346)
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Andreas E <andreas.everos@gmail.com>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: Byron Vanstien <byronvanstien@rocketmail.com>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Flamm <robindevaux25@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nestor A. Sanchez <help.toastcode@gmail.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: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Soitora <simon.mattila@protonmail.com>
Co-authored-by: Tantia <ilovechocobi@yahoo.com>
Co-authored-by: Tooster <max@polarczyk.pl>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/
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/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/fi/
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/hu/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/
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/nb_NO/
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/sk/
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/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: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Andreas E <andreas.everos@gmail.com>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: Byron Vanstien <byronvanstien@rocketmail.com>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Flamm <robindevaux25@gmail.com>
Co-authored-by: Lyfja <yassinelaoud@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nestor A. Sanchez <help.toastcode@gmail.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: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Soitora <simon.mattila@protonmail.com>
Co-authored-by: Tantia <ilovechocobi@yahoo.com>
Co-authored-by: Tooster <max@polarczyk.pl>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
(cherry picked from commit cb6aa18480)
2021-01-31 19:38:37 -05:00
arkon 08bf113dcb Minor cleanup
(cherry picked from commit d5cfbef42b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
2021-01-31 19:38:27 -05:00
Andreas 369e075ed9 Move tracking to a bottom sheet (#4364)
* Move tracking to a bottom sheet

* Give methods better names and remove unnecessary annotation

(cherry picked from commit 535abcbb8b)

# 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/manga/track/TrackController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackPresenter.kt
2021-01-31 19:36:22 -05:00
Jobobby04 7bb4191d41 Maybe fix merge chapter downloads 2021-01-31 18:33:56 -05:00
Unlocked 8539d5b4db Add manga count to the library header (#3884)
* Add manga count to the library header

* Make showing the number of manga configurable

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

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
2021-01-31 18:33:22 -05:00
Taco f8763c71ff Regenerate drawables (#4352)
(cherry picked from commit 9bf452856c)
2021-01-31 18:32:13 -05:00
arkon 925ecb282c Handle failures when updating metadata in library updater
(cherry picked from commit 17109ab760)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2021-01-31 18:31:53 -05:00
arkon 675d6e95d3 Remove unused dimen values
(cherry picked from commit 6bc6e1a1d1)
2021-01-31 18:30:25 -05:00
Jobobby04 0ccfca51e7 Fix weirdly aligned merge button 2021-01-30 01:47:32 -05:00
Jobobby04 284a456184 Handle failures in the library updater 2021-01-28 15:04:17 -05:00
arkon 4cbb2ae082 Apply bottom sheet dialog with restriction consistently
(cherry picked from commit 7eef4f7fbf)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceFilterSheet.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersSettingsSheet.kt
2021-01-28 14:19:04 -05:00
arkon 466cfd82c9 Update AndroidX dependencies
(cherry picked from commit 75bec6a8e3)
2021-01-28 13:41:10 -05:00
Andreas 9cb600e9d6 Unify history and update item (#4361)
* Unify history and update item

* Use card_radius

(cherry picked from commit 0a10f66053)
2021-01-28 13:41:01 -05:00
arkon 4f50fcadeb Ignore failures when updating metadata as part of library update
(cherry picked from commit 58860b51a2)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2021-01-28 13:40:25 -05:00
Jobobby04 1eb8ee502e Optimize imports 2021-01-26 23:47:44 -05:00
Jobobby04 2b845ec01f Cleanup MetadataViewPresenter 2021-01-26 23:47:26 -05:00
Jobobby04 dbadec2c67 Revert "Fix reader bug with new suspend getFlatMetadata"
This reverts commit 9603186927.
2021-01-26 23:36:40 -05:00
Jobobby04 dc6aa11bc7 Revert "Run more db queries inside the IO pool, convert some RxJava references to Coroutines"
This reverts commit 18f02a85ac.

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsEhController.kt
2021-01-26 23:36:03 -05:00
Jobobby04 628eedf15a Remove duplicate raised search metadata code 2021-01-26 23:33:51 -05:00
arkon fcc095ffa3 Add comments to not translate the word "WebView"
(cherry picked from commit 426ed7308b)
2021-01-26 20:36:20 -05:00
Jobobby04 4a86f39a40 Handle blank NHentai Scanlator 2021-01-26 20:31:44 -05:00
Jobobby04 9603186927 Fix reader bug with new suspend getFlatMetadata 2021-01-26 20:31:04 -05:00
Jobobby04 5d600166ea Move EnhancedSource helper functions to SourceHelpers 2021-01-26 20:26:31 -05:00
arkon 2e580cfb55 Address unit test compilation errors
They don't actually run since they broke a long time ago (AndroidX + Roboelectric issues?), but it addresses the annoying red squigglies in Android Studio at least.

(cherry picked from commit 0ecfef3f70)
2021-01-26 16:11:25 -05:00
Taco ec1fe205ad Update Okio, use more KTX stuff (#4353)
* Update Okio to 2.10.0

* Use some more KTX extensions

(cherry picked from commit 5f7e34b6a1)

# 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/MangaFavoritePutResolver.kt
2021-01-26 16:11:02 -05:00
arkon 9a70f25552 Update total number of chapters when refreshing MAL entries (fixes #4348)
(cherry picked from commit 34cb24fe34)
2021-01-26 15:51:27 -05:00
arkon 78fbef637c Parse correct object when finding existing MAL list item (fixes #4347)
(cherry picked from commit 1490112135)
2021-01-26 15:51:17 -05:00
arkon 26385c9225 Fix cancelling library updates not working
(cherry picked from commit c4716a3f4c)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2021-01-26 15:51:09 -05:00
arkon deaefe8fa6 Refactor tracker name strings
(cherry picked from commit 0a54901eb0)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt
2021-01-26 15:48:36 -05:00
Jobobby04 fbc041846b Fix track filter for Mangadex unfollowed 2021-01-26 15:26:35 -05:00
Andreas a2aad23eae Extend track filter (#4344)
* Allow to filter for each tracker logged in

* Simplify filter logic

* Use variable names instead of it

and rename variables

* Change how trackFilters and items are setup

* Use variable name instead of it and try cleanup filterFnTracking

* Changes from feedback

(cherry picked from commit fea2e0a265)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt
2021-01-26 15:26:16 -05:00
Jozef Hollý 1619282e19 Weblate translations (#4204)
Co-authored-by: ARiyou Jahan <AR.Jahan2000@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Ciavola Pennelli <loxli91@gmail.com>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alessandro Zangrandi <alessandro@mzit.it>
Co-authored-by: Alex <linuxrf@gmail.com>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jozef Hollý <j2.00ghz@gmail.com>
Co-authored-by: Lyaiya <hipsnafoha@outlook.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Redya Rachmandanu <redyarachmandanu@gmail.com>
Co-authored-by: Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
Co-authored-by: Sl3iN <fddf.ddrf2015@ya.ru>
Co-authored-by: Tooster <max@polarczyk.pl>
Co-authored-by: Woodyx <shiposhouyou@gmail.com>
Co-authored-by: Yassin <yassinelaoud@gmail.com>
Co-authored-by: Zulkifli <zulhaha1@gmail.com>
Co-authored-by: arkon <eugcheung94@gmail.com>
Co-authored-by: waquack <idragonus@gmail.com>
Co-authored-by: Николаев Дмитрий <nikolaevddv@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/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/fa/
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/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/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/sah/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/
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: ARiyou Jahan <AR.Jahan2000@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Ciavola Pennelli <loxli91@gmail.com>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alessandro Zangrandi <alessandro@mzit.it>
Co-authored-by: Alex <linuxrf@gmail.com>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Lyaiya <hipsnafoha@outlook.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Redya Rachmandanu <redyarachmandanu@gmail.com>
Co-authored-by: Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
Co-authored-by: Sl3iN <fddf.ddrf2015@ya.ru>
Co-authored-by: Tooster <max@polarczyk.pl>
Co-authored-by: Woodyx <shiposhouyou@gmail.com>
Co-authored-by: Yassin <yassinelaoud@gmail.com>
Co-authored-by: Zulkifli <zulhaha1@gmail.com>
Co-authored-by: arkon <eugcheung94@gmail.com>
Co-authored-by: waquack <idragonus@gmail.com>
Co-authored-by: Николаев Дмитрий <nikolaevddv@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
(cherry picked from commit d3c087375b)
2021-01-26 14:19:40 -05:00
arkon 9320221a4e Minor cleanup
(cherry picked from commit a93c0577ac)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/util/lang/RxCoroutineBridge.kt
#	app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt
2021-01-26 14:19:29 -05:00
arkon 6fdff1b03b Perform metadata update in global scope
(cherry picked from commit e4dc35674d)
2021-01-26 14:10:24 -05:00
arkon bf7af0c099 Revert async metadata updates to fix lag when updating (fixes #4341)
(cherry picked from commit 8a668ba7b9)
2021-01-26 14:10:12 -05:00
arkon ffc628fc97 Update AboutLibraries plugin
(cherry picked from commit 78e8d40649)
2021-01-26 14:09:53 -05:00
arkon 87db322ec6 Remove some unused rx/coroutine bridge code
(cherry picked from commit 660e13b701)
2021-01-26 14:07:20 -05:00
arkon 55f3ade9e7 Extract user agent string from WebView
(cherry picked from commit 0685382083)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/online/HttpSource.kt
2021-01-26 14:07:11 -05:00
arkon 788ed6dcc9 Update trackers in parallel, update manga metadata asynchronously
(cherry picked from commit 04a993c997)
2021-01-26 14:06:26 -05:00
arkon dd3b8c7967 Minor dependency updates
(cherry picked from commit 7cae3095c4)
2021-01-26 14:06:17 -05:00
arkon c376699c37 Reword download chapter number sorting options
(cherry picked from commit e288bf902b)
2021-01-26 14:06:07 -05:00
Riztard Lanthorn 8bd5b75fd9 add sort by chapter number in download queue (#4337)
* add sort by chapter number in download queue

* Bigest, smallest chapter download

* grouped

(cherry picked from commit a083e1f71a)
2021-01-26 14:05:59 -05:00
arkon e3ee3159fc Remove usage of RxJava from LibraryUpdateService
(cherry picked from commit 86b9d7e843)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2021-01-26 14:05:48 -05:00
Riztard Lanthorn 355170b8ff add source name in download queue (#4338)
(cherry picked from commit 628bd5d6b4)
2021-01-26 13:42:21 -05:00
arkon 9fe039ba3f Ignore error when cover is missing in Kitsu search results (fixes #4334)
(cherry picked from commit 00285a782c)
2021-01-26 13:42:12 -05:00
arkon cdd5f3b345 Surface tracking search errors properly
(cherry picked from commit 16be469ecb)
2021-01-26 13:42:03 -05:00
arkon c270a8c51d Add QUERY_ALL_PACKAGES permission (maybe fixes #4313)
(cherry picked from commit fdcbc4cffa)
2021-01-26 13:41:55 -05:00
arkon 80c11a32c2 Remove unused RECEIVE_BOOT_COMPLETED permission
Was originally added for the library check mechanism: https://github.com/tachiyomiorg/tachiyomi/commit/fcb5bf4dd4a75cf9cdeeee82463cf044ef1ed41d

(cherry picked from commit fc548304cf)
2021-01-26 13:41:44 -05:00
arkon fc481e4fd4 Don't stop downloader after deleting downloads if it wasn't running (fixes #4309)
(cherry picked from commit 7c7ff8165e)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt
2021-01-26 13:41:33 -05:00
Clarence Castillo 41607ab259 Fix multi-select phantom anchor bug in manga chapters and library (#4201)
* Fix phantom anchor bug in manga chapters list when multi-selecting

* Fix phantom bug when long pressing selected items not at top of stack

* Fix phantom anchor bug in library page

(cherry picked from commit 496a476c13)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
2021-01-26 13:40:43 -05:00
Andreas 3927c62a32 Match color for download, header, and pin buttons (#4331)
* Match download button color to pin color

* Match manga header buttons color to pin color

(cherry picked from commit 441fc6e45b)
2021-01-26 13:38:13 -05:00
Jobobby04 b0981a00bd Fix Reder PR build errors 2021-01-26 13:37:31 -05:00
Jobobby04 295af5306b Handle delegated source id lists better using a LisenterMutableMap
Better source id comparisons
2021-01-26 13:31:22 -05:00
Jobobby04 cf1ce9e069 Search in the regular coroutine scope instead of a custom one 2021-01-26 13:31:21 -05:00
Jobobby04 18f02a85ac Run more db queries inside the IO pool, convert some RxJava references to Coroutines 2021-01-26 13:31:20 -05:00
Jobobby04 64eeab7c5e Use a Enum for genre color 2021-01-26 13:31:18 -05:00
Jobobby04 1e2f4fc35e Cleanup MigrationSource 2021-01-26 13:31:17 -05:00
Jobobby04 a088e1ffc2 Cleanup removeArticals extension function 2021-01-26 13:31:17 -05:00
Jobobby04 0b7f8da84e Cleanup EHentai Description extension 2021-01-26 13:31:14 -05:00
Jobobby04 9f2e582281 Cleanup view extensions 2021-01-26 13:31:14 -05:00
Jobobby04 d63eae4444 Use bundleOf in merge settings dialog 2021-01-26 13:31:13 -05:00
Jobobby04 4552b9f849 Cleanup edit manga info dialog 2021-01-26 13:31:12 -05:00
Jobobby04 02e3b49dc7 Move StringBuilderExtensions to utils 2021-01-26 13:31:12 -05:00
Jobobby04 5c21f7ec30 Fix deprecated Parcelize annotation 2021-01-26 13:31:11 -05:00
Jobobby04 9235f0e5ed Fix similar manga notification channel name 2021-01-26 13:31:10 -05:00
jobobby04 2a211c68a9 Merge pull request #186 from CrepeTF/Reader_PR
Reader PR + stuff
2021-01-26 13:30:25 -05:00
CrepeTF 653ae10caf Reader PR 2021-01-26 13:11:42 -05:00
arkon 9ec67db8cb Use proper method to clear notification actions
(cherry picked from commit cf7ec6aa76)
2021-01-21 19:06:57 -05:00
arkon 4d6bd382e8 Add method for users to save error logs to a file
(cherry picked from commit db2dd4b6c6)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
2021-01-21 19:06:38 -05:00
arkon 48b713aad5 Update AGP for Android Studio 4.1.2
(cherry picked from commit a68417a0b0)
2021-01-21 18:55:28 -05:00
Jobobby04 677909cd6e Fix compile error 2021-01-21 18:49:37 -05:00
Andreas e0afe65096 Fix Kitsu toasting "Logged in" when there is an error (#4329)
(cherry picked from commit 2a5102a457)
2021-01-21 18:48:51 -05:00
Jobobby04 003e916ab0 Fix app crash if mangadex logout dialog has a issue 2021-01-21 18:46:54 -05:00
arkon 94f0dd8362 Delay restoring AppBar elevation on Android 5.0 (fixes #4311)
(cherry picked from commit 837d8f5f30)
2021-01-21 15:00:13 -05:00
Andreas 2b8a0f2215 Hide tracking when no tracker is logged in and change filter logic (#4310)
* Hide tracking when not logged in

* Change string name and value

(cherry picked from commit 1a5858e99b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt
2021-01-21 15:00:06 -05:00
Jobobby04 34f8407983 Fix MangaPlus chapters for MangaDex 2021-01-21 14:47:03 -05:00
Jobobby04 a17c4c151f Cleanup custom info, fix custom genre not saving if you dont edit it 2021-01-20 21:00:58 -05:00
Jobobby04 0a4fcb480d Small cleanup and optimizations, add a coroutine version of insertFlatMetadata 2021-01-20 21:00:23 -05:00
Jobobby04 e6d62dd1dc Support MDList unfollowed for tracking filter 2021-01-17 22:17:37 -05:00
Jobobby04 3b364c91f1 Do quite a bit of code cleanup 2021-01-17 22:17:15 -05:00
arkon 8db57aef6c Add shortcut to see commit history for official extensions
(cherry picked from commit 4044427d93)
2021-01-17 18:04:33 -05:00
arkon 25caba6905 More consistent injectLazy style
(cherry picked from commit f667f85fa5)
2021-01-17 18:04:25 -05:00
Andreas c92c9fada5 Add filter for tracking (#4276)
* Add filter for tracking or not

* Use .any

* Access database only when needed

(cherry picked from commit 5cddc0c387)

# 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/library/LibraryPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt
2021-01-17 18:03:57 -05:00
arkon 84a28ddb87 [SKIP CI] Update fork change checklist
(cherry picked from commit cbc01dd6f1)
2021-01-17 17:06:59 -05:00
arkon 3d400981b8 Remove duplicated info from CONTRIBUTING.md
(cherry picked from commit b820c7debf)
2021-01-17 17:06:51 -05:00
arkon 0248e2b5d0 Add list of things to change in forks to CONTRIBUTING.md
(cherry picked from commit 2bee072cba)
2021-01-17 17:06:41 -05:00
arkon 3844615a98 Move CONTRIBUTING.md to top level
(cherry picked from commit 80710b0b94)
2021-01-17 17:06:32 -05:00
arkon a47e88a953 Move ACRA endpoint config to build.gradle.kts
(cherry picked from commit 3319ccfd41)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
2021-01-17 17:06:21 -05:00
arkon 54071507c1 Reimplement MAL start/end date support
(cherry picked from commit 878008e93b)
2021-01-16 19:50:28 -05:00
arkon 7a893e3009 Revert removal of tracker start/end date
(cherry picked from commit 0cd551d4fd)
2021-01-16 19:50:20 -05:00
arkon 70d5907cc8 Handle download cancelation from icon properly (fixes #4241)
(cherry picked from commit f85194ec46)
2021-01-16 19:50:12 -05:00
arkon d5a912bda2 Fix display mode not updating in source view
(cherry picked from commit 271489bdfd)
2021-01-16 19:50:00 -05:00
arkon 3340ca83c6 Update Material Components (fixes #4251)
(cherry picked from commit bd5f22a049)
2021-01-16 19:49:51 -05:00
arkon b6acb3d7f6 Simplify lookup for existing MAL list item
(cherry picked from commit 189f18b112)
2021-01-16 19:49:41 -05:00
arkon 64f6904ddb Update AndroidX dependencies
(cherry picked from commit df166184ea)
2021-01-16 19:49:20 -05:00
Carlos e713340ced switch off kotson for chapter deeplink
(cherry picked from commit 6b545e84aba0d5657a09a8c00735f9f9d4ee28bb)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/ApiMangaParser.kt
#	app/src/main/java/exh/md/handlers/serializers/ApiChapterSerializer.kt
2021-01-15 22:59:37 -05:00
Carlos 5fefefcb23 Mark manga complete on mangadex when all chapters are marked in mdlist
(cherry picked from commit b95cca91fc19fedb42fce895e0a5f062e342dc21)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/track/mdlist/MdList.kt
2021-01-15 22:52:44 -05:00
Carlos 4a268de6dc fix more descriptions
(cherry picked from commit a04a0f534f679a9f908ffaf6f8bcff0018d742be)
2021-01-15 22:38:32 -05:00
Jobobby04 80c7abe098 Fix chapters not updating correctly on mdlist 2021-01-15 22:38:16 -05:00
Jobobby04 37787f040c Mangadex code cleanup 2021-01-15 22:29:57 -05:00
Jobobby04 ae15a178e5 Cleanup 2021-01-15 22:21:10 -05:00
Jobobby04 9465803e5b Cleanup NHentai tags code 2021-01-15 22:20:25 -05:00
Jobobby04 f29ad69534 Remove uneeded preferences from a Mangadex file 2021-01-15 22:18:59 -05:00
Jobobby04 05793d8a60 Remove a uneeded .asObservable call 2021-01-15 22:18:23 -05:00
inorichi 6ea90d982d Fix jpeg decoder when used with high samples
(cherry picked from commit ce42cba096)
2021-01-15 22:17:45 -05:00
Jobobby04 fe5058c94b Fix FAB when going to index controller to browse source controller 2021-01-15 22:06:30 -05:00
Carlos 85425a66a2 fix chapter deeplink
(cherry picked from commit f0dd30587a98c27bca59088f119d85f2fc044f25)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/ApiMangaParser.kt
2021-01-13 19:49:14 -05:00
arkon 7b4311c7dc Show error when trying to download chapters from not installed source (closes #4283)
(cherry picked from commit 9670863a41)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt
2021-01-10 19:38:10 -05:00
arkon d4b0e2869d Update SubsamplingScaleImageView
Merged with upstream master and disabled Jetifier.

(cherry picked from commit 1ae52bd33f)
2021-01-10 19:37:07 -05:00
Jobobby04 a0ac2daad1 Deal with SY for the coroutine function changes 2021-01-10 19:36:24 -05:00
arkon 0edff11353 More coroutine tweaks
(cherry picked from commit c9cf9cfff0)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
#	app/src/main/java/eu/kanade/tachiyomi/AppModule.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/util/lang/RxCoroutineBridge.kt
2021-01-10 18:43:47 -05:00
arkon c7bedb96a0 Avoid using global scope where appropriate
Also fixes the crash in tracking when an exception is thrown during a refresh.

(cherry picked from commit 2ffbee3db2)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubUpdateChecker.kt
#	app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchPresenter.kt
2021-01-10 18:25:57 -05:00
inorichi 954573fc33 Fix png artifacts & banding when ratio > 1
(cherry picked from commit 96b8beb9cd)

# Conflicts:
#	app/build.gradle.kts
2021-01-10 18:14:04 -05:00
Jobobby04 cda886ecb3 Unknown source compile fix 2021-01-10 18:12:14 -05:00
Carlos 57c4ead5fb fix a description
(cherry picked from commit c1a603c68bf5a9fb34e2681862e4769e157a5966)
2021-01-10 17:33:07 -05:00
Carlos 3a5182103a fix manga plus entries
(cherry picked from commit 1b5624a601144b4ccdebf379d53a2b4c5f90c2f6)

# Conflicts:
#	app/src/main/java/exh/md/handlers/ApiChapterParser.kt
2021-01-10 17:32:53 -05:00
Carlos 85853b159d fix descriptions
(cherry picked from commit 74a06675d4b42cd700fdbe210cf2e281dfae7d45)
2021-01-10 17:29:43 -05:00
Jobobby04 a04f848ad1 Unknown source error for Deeplink 2021-01-10 17:28:52 -05:00
Jobobby04 73e861ec9e Mangadex replace list of langs with just the source lang 2021-01-10 17:28:20 -05:00
Carlos 6bb7b676bd fix mdlist
(cherry picked from commit ebf5e492ca8dcc6771349b631ebf7661dfbb7d44)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/FollowsHandler.kt
#	app/src/main/java/exh/md/utils/FollowStatus.kt
2021-01-10 17:21:08 -05:00
Jobobby04 33fac3e96b Search manga descriptions 2021-01-10 15:22:47 -05:00
Carlos 35936e3c9a finish transition to api v2
(cherry picked from commit 4039f6927e627279cf1b324279a2d817a007d29b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/ApiMangaParser.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterSheet.kt
#	app/src/main/java/exh/md/handlers/MangaHandler.kt
#	app/src/main/java/exh/md/utils/MdUtil.kt
#	app/src/main/res/layout/reader_activity.xml
#	app/src/main/res/layout/reader_chapters_sheet.xml
#	app/src/main/res/menu/reader.xml
2021-01-09 16:11:15 -05:00
Jobobby04 7006341fab Cleanup 2021-01-09 15:16:23 -05:00
Jobobby04 4afe227e02 Revert "Request a new image from E-Hentai if it fails to download, should make E-Hentai downloads more relaible"
This reverts commit a21d7f4f90.
2021-01-08 16:24:42 -05:00
Jobobby04 fca7dad7b0 Address coroutine scope leaks for SY 2021-01-07 23:14:08 -05:00
arkon 3683665e8a Address coroutine scope leaks in custom views
(cherry picked from commit 8e613d03e3)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt
2021-01-07 22:29:35 -05:00
arkon a68f18d180 Use lifecycleScope directly
(cherry picked from commit b18a794eca)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
2021-01-07 22:22:27 -05:00
arkon d09406dc29 Revert "Use flows instead of relays for extensions loading"
This reverts commit 07e76f35fa.

(cherry picked from commit c620c924f9)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt
2021-01-07 22:12:29 -05:00
Andreas E d41c619c8a Fix navigation from feedback (#4238)
* Fix navigation from feedback (fixes #4237)

* Add additional enum values to NavigationRegion mainly for PagerViewer

Co-authored-by: arkon <arkon@users.noreply.github.com>
(cherry picked from commit 9db81a5a49)
2021-01-07 22:11:24 -05:00
arkon 7330be555d Address more coroutine scope leaks
(cherry picked from commit 6fb7a85e8a)

# Conflicts:
#	app/build.gradle.kts
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
2021-01-07 22:11:14 -05:00
Jobobby04 fd3e0bc449 Import cleanup 2021-01-07 21:56:33 -05:00
inorichi c8dd2190ba Minor fixes regarding leaks
(cherry picked from commit 36f81b4a62)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
2021-01-07 14:27:22 -05:00
arkon 1b41546bc9 Fix crash when no chapters can't be loaded
(cherry picked from commit 2caecc01b2)
2021-01-07 01:14:05 -05:00
inorichi 6da1654825 Fix a crash with the new decoder when cropping borders of an entirely white or black image
(cherry picked from commit dedb8d2d68)

# Conflicts:
#	app/build.gradle.kts
2021-01-07 01:13:58 -05:00
arkon 25e56f3c77 Switch to version of SubsamplingScaleImageView with new image decoder
Courtesy of @inorichi.
Branch: https://github.com/tachiyomiorg/subsampling-scale-image-view/commits/tachiyomi-new-decoder

Decoding speed will be a bit slower now due to two passes if crop borders is enabled, but should be more
reliable on colored images and work for black borders. Memory usage (re: leaks) should also be better.

(cherry picked from commit 762f5bdc33)

# Conflicts:
#	app/build.gradle.kts
2021-01-07 01:13:15 -05:00
arkon fd050b8178 Allow typing in tracker score similar to chapters (closes #2498)
(cherry picked from commit bebb52b4e8)
2021-01-07 01:12:34 -05:00
arkon 5387e24bb4 Revert bad RxJava conversion that prevented tracking data to be updated in UI
(cherry picked from commit 2c9f8bb9ce)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackPresenter.kt
2021-01-07 01:12:23 -05:00
arkon e363e2fbb2 Reword unmetered network restriction for library updates
(cherry picked from commit efbefabb01)
2021-01-07 01:11:34 -05:00
arkon b7986a6773 Remove usage of RxJava from backup/restore
(cherry picked from commit 990fb22d3e)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt
2021-01-07 01:11:22 -05:00
arkon d6d8cbd346 Use JDK 11 for build workflow (#4250)
(cherry picked from commit 9b2c22b2d9)
2021-01-07 00:59:44 -05:00
arkon 27496ae77b Surface "NSFW" (includes things like ecchi) results in MAL search (closes #4249)
(cherry picked from commit df7e0d2f2f)
2021-01-07 00:59:36 -05:00
arkon bd73b1b068 Refactor bridged RxJava/coroutine calls in SearchPresenters
(cherry picked from commit 5cfda1b1bf)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchPresenter.kt
2021-01-07 00:59:27 -05:00
arkon 208d4574db Refactor bridged RxJava/coroutine calls in MangaPresenter
(cherry picked from commit ac9bf1f3ff)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
2021-01-07 00:58:46 -05:00
arkon e92e942fcd Remove use of RxJava from TrackPresenter
(cherry picked from commit 7eb0868791)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackPresenter.kt
2021-01-07 00:55:47 -05:00
Jobobby04 a6d4644713 Cleanup 2021-01-07 00:55:00 -05:00
Carlos c9062cc089 switch to v2 and api server + old style chapter urls for delegation
(cherry picked from commit b79c1572470fea4568708d3526f5170868a0c3c1)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/ApiChapterParser.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/FollowsHandler.kt
#	app/src/main/java/exh/md/handlers/SearchHandler.kt
2021-01-07 00:32:12 -05:00
Carlos ac2301e4be fix group serializer
(cherry picked from commit e47d84f1af1eebe63b3dfc618daee29e18ee4156)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/ApiMangaParser.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsController.kt
#	app/src/main/res/raw/changelog_release.xml
#	buildSrc/src/main/kotlin/Configs.kt
2021-01-06 22:48:22 -05:00
Carlos c073f71ec1 fix v2 api call for groups
(cherry picked from commit 01903e341be6cd5ae50ce6eee88be6ad40fd1835)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/ApiMangaParser.kt
2021-01-06 22:46:07 -05:00
Carlos f1a65edd3a Mangadex api v2 for manga info
(cherry picked from commit 38ec991a15d2eebc7ebd0522f8615c2d8dd7003b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/ApiMangaParser.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/serializers/CoversSerializer.kt
#	app/src/main/java/exh/md/handlers/MangaHandler.kt
#	app/src/main/java/exh/md/handlers/SearchHandler.kt
#	app/src/main/java/exh/md/handlers/serializers/ApiMangaSerializer.kt
#	app/src/main/res/drawable/manga_info_more_gradient.xml
2021-01-06 22:42:55 -05:00
CrepeTF 4b91013750 Change merge manga icon 2021-01-06 03:11:06 -05:00
CrepeTF 556fdb2e8d Modify midnight dusk theme colurs 2021-01-06 03:09:37 -05:00
Jobobby04 68c12d79ee CoroutinePresenter changes 2021-01-06 00:54:11 -05:00
arkon 142aa0f02a MAL: add way to search by list items' titles
(cherry picked from commit 8a792e6d76)
2021-01-04 14:37:46 -05:00
arkon a1102d790f Fix content focusiblity issues when using remote/controllers (closes #3766)
(cherry picked from commit d8a3692d92)
2021-01-04 14:24:47 -05:00
arkon f4549c5910 Fix malformed extension URLs
(cherry picked from commit 95ce0e39ef)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt
2021-01-04 14:23:31 -05:00
arkon 4e026c1cf1 Refactor Kitsu API to remove Retrofit usage
(cherry picked from commit 17b70ab38c)
2021-01-04 14:21:21 -05:00
arkon 73fc1ac80f Use flows instead of relays for extensions loading
(cherry picked from commit 07e76f35fa)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt
2021-01-04 14:21:13 -05:00
arkon 838953a739 More consistent wording for NSFW warning strings
(cherry picked from commit a4cab9876a)
2021-01-04 14:17:56 -05:00
arkon 66d2e8090a Remove some OptIn annotations
(cherry picked from commit c06a932c95)
2021-01-04 14:17:46 -05:00
Jobobby04 7bd5157bca Update MDList tracker with the new tracker changes, also library update may be a bit faster 2021-01-04 03:38:30 -05:00
arkon 298c1e92db Fully remove usages of RxJava from tracker classes
TODO: refactor usages to coroutines as well
(cherry picked from commit 7d713b87b1)
2021-01-04 02:01:26 -05:00
arkon 5ba087f2ee Adjust download icon alignment more
(cherry picked from commit b1167146c5)
2021-01-04 02:01:18 -05:00
arkon 68113f8c7d Convert more TrackService methods to coroutines
(cherry picked from commit 2d0a5eb02c)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupRestore.kt
2021-01-04 01:55:08 -05:00
arkon b824f09966 Change MAL ID search prefix to "id:"
(cherry picked from commit 8d68859c2a)
2021-01-04 01:19:30 -05:00
arkon 0f000caa9d Use updated Tachiyomi version of DirectionalViewPager
(cherry picked from commit 444cefc9a2)
2021-01-04 01:17:39 -05:00
arkon ae3a36cc5a Tint downloaded icons with primary color
Makes them more easily distinguishable from other states.

(cherry picked from commit d0deceabbd)
2021-01-04 01:17:30 -05:00
arkon ee0625e9a6 Adjust padding of text before download icons
(cherry picked from commit 9cc6491c2a)
2021-01-04 01:16:16 -05:00
arkon 6028fdfc4d Note valid backup file extensions in error toast
(cherry picked from commit 710179f4b4)
2021-01-04 01:16:08 -05:00
arkon 68f209b91b Replace global search context menu option with share target
(cherry picked from commit d11c72fd48)

# Conflicts:
#	app/src/main/res/values/strings.xml
2021-01-04 01:16:01 -05:00
arkon 74dc7a645d Add more padding to download buttons
(cherry picked from commit 0af505828e)
2021-01-04 01:14:56 -05:00
arkon a0981c4944 Minor cleanup
(cherry picked from commit 135cf9960f)
2021-01-04 01:14:45 -05:00
Andreas E aab3ba5b48 Navigation settings and split invert tapping for webtoon and pager (#4233)
(cherry picked from commit 3bf7c74f93)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonConfig.kt
#	app/src/main/res/layout/reader_settings_sheet.xml
2021-01-04 01:08:35 -05:00
Riztard Lanthorn 2bd67860a7 add date Format (#4236)
(cherry picked from commit cea4911c4d)
2021-01-04 00:28:15 -05:00
Jobobby04 b57dc1a6c8 Add android proguard to release test builds 2021-01-03 15:01:09 -05:00
Jobobby04 cbd25332e1 Fix proguard rules, re-enable proguard 2021-01-02 17:36:44 -05:00
Jobobby04 d8bb15cdcd Disable proguard for now 2021-01-02 17:28:32 -05:00
Jobobby04 ce0726d863 Update SY fetchMangaInfo and getchChapterList to use the new 1.x functions 2021-01-02 16:36:13 -05:00
Jobobby04 28fca8c839 Make internal and delegated sources able to use getMangaDetails, getChapterList, and getPageList properly 2021-01-02 03:28:03 -05:00
arkon 23ac4b271c Replace usages of fetchChapterList with 1.x getChapterList API
(cherry picked from commit 54dc01253d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
2021-01-02 03:08:16 -05:00
arkon 423983d41a Replace usages of fetchMangaDetails with 1.x getMangaDetails API
(cherry picked from commit 4db9a90da2)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
2021-01-02 02:59:33 -05:00
Andreas E 651f4659a5 Viewer navigation (#3869)
* Viewer navigation

Co-authored-by: Harsh Parekh <h.x.dev@outlook.com>

* Match current reader behavior and add ability to invert it

* A bit of clean up

* Clean up inversion

* Only create navigator when changed

and change tap zone when invertTapping is changed

* Clean up PagerConfig

* Change how Viewer navigation works

* Add Edge Navigation

Co-authored-by: Harsh Parekh <h.x.dev@outlook.com>
(cherry picked from commit d69e9034ab)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonConfig.kt
#	app/src/main/res/layout/reader_settings_sheet.xml
2021-01-01 23:49:25 -05:00
Clarence Castillo b8751f6d15 Direct user back to global search when coming from source search results (#4196)
(cherry picked from commit 71ece73d99)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt
2021-01-01 23:44:45 -05:00
arkon 8a8d8f7189 Include source name in backup restore error logs (closes #4230)
(cherry picked from commit 3bb2102eb4)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt
2021-01-01 23:43:15 -05:00
arkon 7a6a33d5fe Remove some unnecessary coroutine dispatcher switching
(cherry picked from commit b7914909d0)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
2021-01-01 23:42:02 -05:00
Jobobby04 3e6c3ac151 Do some cleanup 2021-01-01 15:15:16 -05:00
arkon 8dd435b5b5 Implement click events for chapter download icons
(cherry picked from commit 63398fe491)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt
2020-12-31 19:45:26 -05:00
arkon 6d4136248c Use coroutines instead of rx for some MangaPresenter operations
(cherry picked from commit bf32bf28da)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
2020-12-31 19:38:33 -05:00
arkon 67b919423a Remove some unused variables
(cherry picked from commit dcb6bfb18d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/SourceAdapter.kt
2020-12-31 19:36:53 -05:00
arkon d5af2ed80c Adjust chapters filter icon to line up with download icons
(cherry picked from commit 8f605dc0f6)
2020-12-31 19:32:33 -05:00
arkon 8ee8cae1f7 Fix download progress bar sizing to match icons
(cherry picked from commit 47e770948b)
2020-12-31 19:32:26 -05:00
arkon 171a610d0d Move some build.gradle.kts content around
(cherry picked from commit 9ab29f5b7f)

# Conflicts:
#	app/build.gradle.kts
2020-12-31 19:31:43 -05:00
arkon 1d134a94a6 Only include Firebase dependency in standard flavor
(cherry picked from commit 10bf430ce6)
2020-12-31 19:29:39 -05:00
jobobby04 f143ac1572 Convert app build.gradle to Kotlin DSL 2020-12-31 19:29:18 -05:00
arkon 1f3c805a0f Handle last read page being above total page count (fixes #4010)
(cherry picked from commit 141f9b7730)
2020-12-31 17:33:20 -05:00
arkon 426af9c93c Increase per-page limit when searching MAL manga list
(cherry picked from commit 139a589ad6)
2020-12-31 17:33:06 -05:00
arkon 50cc6e5e83 Minor cleanup of some tracker observables
(cherry picked from commit 97a308b114)
2020-12-31 17:32:48 -05:00
arkon b6d0594d10 Find existing entry in MAL list when binding
(cherry picked from commit 430714e67f)
2020-12-31 17:32:41 -05:00
arkon f5f71fa4a7 Add ID search workaround for MAL tracking
(cherry picked from commit a49adbd09c)
2020-12-31 17:32:33 -05:00
arkon 9085c142d5 Fix crash on updating trackers after reading with no network (closes #4207)
(cherry picked from commit 3df98d576e)
2020-12-31 17:32:25 -05:00
arkon 73092a2832 Adjust download icon sizing
(cherry picked from commit 8135136c86)
2020-12-31 17:32:14 -05:00
arkon d2e594be0c Tweak manga info header backdrop
(cherry picked from commit cef1c4b8a1)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
2020-12-31 17:32:09 -05:00
arkon aef21dabd5 Refactor tracker response parsing
(cherry picked from commit 2e8791a101)
2020-12-31 17:23:55 -05:00
arkon cd9c26f278 Show download progress in download icons
(cherry picked from commit 0e2b8b10d1)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
2020-12-31 17:23:39 -05:00
arkon dbda419d29 Animate download icon
(cherry picked from commit 3cb64669e4)
2020-12-31 17:17:05 -05:00
arkon 92cc022fb4 Add Telugu to language setting
(cherry picked from commit bc0d32f330)
2020-12-31 17:16:55 -05:00
Jozef Hollý 1c5ffcca24 Weblate translations (#4173)
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alessandro Zangrandi <alessandro@mzit.it>
Co-authored-by: Alex <linuxrf@gmail.com>
Co-authored-by: Alperen Arslan <slyvioborin@gmail.com>
Co-authored-by: Andreas E <andreas.everos@gmail.com>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: Crazyom <naxom@laposte.net>
Co-authored-by: Damiano Mason <damicricio99@gmail.com>
Co-authored-by: Dams <qashdzn@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Edgar Mejía <edgar13155@gmail.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eric <spice2wolf@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: Kurocon <weblate@kurocon.nl>
Co-authored-by: Luis Andrés Bajaña F <labfernandez2014@gmail.com>
Co-authored-by: Lyaiya <hipsnafoha@outlook.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: MINEJHAZZ <minecrafterngt@gmail.com>
Co-authored-by: Matteo Gaeta <matteo.gaeta.1998@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nicolas Meunier <minecraft.arsenof@gmail.com>
Co-authored-by: Nikola Perović <nikolaperovicccc@gmail.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: Redya Rachmandanu <redyarachmandanu@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Samiul Azam <yeasin.sanny99@gmail.com>
Co-authored-by: Shashank Pujari <shashankppujari@gmail.com>
Co-authored-by: SmolderingGummy <bairamsaieesh@gmail.com>
Co-authored-by: Soitora <simon.mattila@protonmail.com>
Co-authored-by: Tooster <max@polarczyk.pl>
Co-authored-by: Woodyx <shiposhouyou@gmail.com>
Co-authored-by: Xoko14 <xoquinperezb@gmail.com>
Co-authored-by: Yassin <yassinelaoud@gmail.com>
Co-authored-by: Zulkifli <zulhaha1@gmail.com>
Co-authored-by: darkbeast13 <nikhil15mps@gmail.com>
Co-authored-by: vlad hateg <vhateg@gmail.com>
Co-authored-by: Đỗ Vũ Minh Quang <quacmichael@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/ca/
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/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/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/kn/
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/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/sr/
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/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/Strings
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: Alessandro Zangrandi <alessandro@mzit.it>
Co-authored-by: Alex <linuxrf@gmail.com>
Co-authored-by: Alperen Arslan <slyvioborin@gmail.com>
Co-authored-by: Andreas E <andreas.everos@gmail.com>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: Crazyom <naxom@laposte.net>
Co-authored-by: Damiano Mason <damicricio99@gmail.com>
Co-authored-by: Dams <qashdzn@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Edgar Mejía <edgar13155@gmail.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Kurocon <weblate@kurocon.nl>
Co-authored-by: Luis Andrés Bajaña F <labfernandez2014@gmail.com>
Co-authored-by: Lyaiya <hipsnafoha@outlook.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: MINEJHAZZ <minecrafterngt@gmail.com>
Co-authored-by: Matteo Gaeta <matteo.gaeta.1998@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nicolas Meunier <minecraft.arsenof@gmail.com>
Co-authored-by: Nikola Perović <nikolaperovicccc@gmail.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: Redya Rachmandanu <redyarachmandanu@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Samiul Azam <yeasin.sanny99@gmail.com>
Co-authored-by: Shashank Pujari <shashankppujari@gmail.com>
Co-authored-by: SmolderingGummy <bairamsaieesh@gmail.com>
Co-authored-by: Soitora <simon.mattila@protonmail.com>
Co-authored-by: Tooster <max@polarczyk.pl>
Co-authored-by: Woodyx <shiposhouyou@gmail.com>
Co-authored-by: Xoko14 <xoquinperezb@gmail.com>
Co-authored-by: Yassin <yassinelaoud@gmail.com>
Co-authored-by: Zulkifli <zulhaha1@gmail.com>
Co-authored-by: darkbeast13 <nikhil15mps@gmail.com>
Co-authored-by: vlad hateg <vhateg@gmail.com>
Co-authored-by: Đỗ Vũ Minh Quang <quacmichael@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
(cherry picked from commit 0db17beacc)
2020-12-31 17:16:44 -05:00
arkon 59fb4a71e6 Minor cleanup of UpdatesHolder
(cherry picked from commit 6378a41b6d)
2020-12-31 17:15:01 -05:00
arkon 157f7802b2 Hide chapter download icons for local manga
(cherry picked from commit 23bf7faf9f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt
2020-12-31 17:14:53 -05:00
arkon 406f77c645 Add error state to chapter download icons
(cherry picked from commit 01ff3af63f)
2020-12-31 17:14:03 -05:00
arkon 959559a89f Refactor response parsing helper function
(cherry picked from commit 8f98055e9e)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubUpdateChecker.kt
#	app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt
2020-12-31 17:13:49 -05:00
arkon df1daa6b7f Refactor download states into enum
(cherry picked from commit 84ae61f72c)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
2020-12-31 17:12:02 -05:00
arkon 56a4ef33f5 Initial chapter download icon implementation
(cherry picked from commit 6dd280205b)
2020-12-31 17:07:32 -05:00
arkon 4be204e0b1 Log exception on invalid download directory issue
(cherry picked from commit 1365d553a4)
2020-12-31 17:07:22 -05:00
Jobobby04 8e659f3355 Remove usage of retrofit in similar manga pull 2020-12-31 17:07:03 -05:00
arkon e78197ab48 Remove usage of Retrofit for update check and extensions list
(cherry picked from commit 61a594493c)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubService.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubUpdateChecker.kt
#	app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt
#	app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubService.kt
2020-12-31 17:06:36 -05:00
arkon a25d7b39a7 Remove unnecessary BaseWebViewActivity class
(cherry picked from commit 62ab70f889)
2020-12-31 16:39:39 -05:00
Jobobby04 08e52cca97 Remove manga tags scrollbar 2020-12-29 20:01:51 -05:00
CrepeTF 4b3d92a050 Added "Midnight Dusk" theme (#183)
* Added Midnight Dusk theme + tweaks

* Added Midnight Dusk theme + tweaks

* Colouring mistakes

* Space error
2020-12-26 19:25:34 -05:00
Jobobby04 a907c93147 Fix Index adapter crash 2020-12-26 19:23:46 -05:00
Jobobby04 294bb286e9 Deal with the SY ProgressBars 2020-12-26 17:02:07 -05:00
arkon 54736ea410 Replace circular ProgressBars with Material component
(cherry picked from commit eaccfdde59)
2020-12-26 16:42:07 -05:00
arkon 897f5f1732 Replace ProgressBars with Material component
(cherry picked from commit a8e536478c)
2020-12-26 16:41:58 -05:00
arkon 7fc7ea9c9b Update dependencies
(cherry picked from commit e94d5626dd)
2020-12-26 16:41:47 -05:00
arkon 7cdda6241f Try to avoid crashing when unable to get backup filename for some reason
(cherry picked from commit be3e31ddc4)
2020-12-26 16:41:38 -05:00
Andreas E 45ef778e6d Reader snackbar dismissible (#4190)
* Make Reading Mode Snackbar dismissible

* Change reader FrameLayout to CoordinatorLayout

(cherry picked from commit b92b6520cb)
2020-12-26 16:41:29 -05:00
Jobobby04 528c2dbae7 Allow clicking the toolbar to go to the manga 2020-12-26 16:39:56 -05:00
Jobobby04 e078e34ab0 Add chapter deeplink, make MangaDex use it 2020-12-26 16:13:55 -05:00
Jobobby04 1a609e557b Refactor and cleanup 2020-12-26 16:12:52 -05:00
arkon d3b7f639b5 Convert tracker add/update/login methods to coroutines
(cherry picked from commit ea33179a95)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt
2020-12-26 00:36:08 -05:00
arkon f99aa721d0 Use coroutines for Bangumi and Shikimori APIs
(cherry picked from commit 6fcf6ae1f5)
2020-12-26 00:34:40 -05:00
arkon 0519d8ea17 Remove usage of Gson in Kitsu tracker
(cherry picked from commit f2a9247b68)
2020-12-26 00:34:32 -05:00
arkon 0c84d51e1b Use coroutines for Anilist API
(cherry picked from commit dc3ed7fffc)
2020-12-26 00:34:23 -05:00
arkon bcd7a2d21b Migrate Kitsu API to coroutines and kotlinx.serialization
(cherry picked from commit 271de31d51)
2020-12-26 00:34:15 -05:00
arkon d332be88ba Make OkHttp coroutine calls always throw exceptions on errors
(cherry picked from commit 1268caf3e0)
2020-12-26 00:34:04 -05:00
arkon f10a499a36 Surface MAL HTTP errors properly
(cherry picked from commit c0cef58e39)
2020-12-26 00:33:56 -05:00
arkon db06c6614e Fix trackers after MAL not updating
(cherry picked from commit d363d205c3)
2020-12-26 00:33:47 -05:00
arkon 51032fa65b Filter out novels from MAL search results
(cherry picked from commit 2fd5a9e883)
2020-12-26 00:33:40 -05:00
arkon 98a20b2756 Format MAL search result status/type better
(cherry picked from commit e7ef974a39)
2020-12-26 00:33:28 -05:00
specterflare c00ba701b3 Remove License Appendix That Should Have Been Removed Initially (#4158)
http://www.apache.org/licenses/LICENSE-2.0 makes it pretty clear the appendix is supposed to be separate from the rest of the license. I guess inorichi just forget to get rid of it at the end of LICENSES.txt
(cherry picked from commit 2d28750782)
2020-12-26 00:33:11 -05:00
Taco 52c5c35e1a Update NDK & buildTools, fix deprecated Parcelize (#4157)
* Update buildTools and NDK

* Fix deprecated Parcelize

(cherry picked from commit e2054a0ab7)
2020-12-26 00:33:02 -05:00
arkon de03174131 Strip out no longer used tracker start/end date code
Unfortunately MAL was the only one that supported it in the app, but the official API doesn't support it, so now no trackers have it.

(cherry picked from commit 6e7fefb8b2)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/models/BackupTracking.kt
2020-12-26 00:32:26 -05:00
Jobobby04 f33a4e2ecc Also do the last commit for SY 2020-12-26 00:31:38 -05:00
arkon 118e1d302b Add forced MAL logout for next release migration
(cherry picked from commit 450bef278b)
2020-12-26 00:30:07 -05:00
arkon 1dcead9d79 Migrate to official MyAnimeList API (closes #4140)
(cherry picked from commit 0affc0d58b)
2020-12-26 00:29:58 -05:00
arkon b001768b96 Don't surface hidden settings when searching
(cherry picked from commit 3d153b6c8e)
2020-12-26 00:29:47 -05:00
Jobobby04 78f48d28c3 Convert SmartSearch channel to SharedFlow 2020-12-26 00:06:52 -05:00
Jobobby04 a7b05f372b Cleanup 2020-12-25 23:59:11 -05:00
Jobobby04 d392b58ced Change mangadex deeplink to PathPrefix deeplinks 2020-12-25 23:58:59 -05:00
Jobobby04 1dcf161131 Fix Hentai Cafe deeplinking, fixes other deeplinks 2020-12-25 23:58:40 -05:00
Jobobby04 dfabe1d2fa Revert "Deeplink using pathPattern instead of pathPrefix"
This reverts commit 8e03375664.
2020-12-25 23:20:12 -05:00
Jobobby04 bbc70801db Fix weird MangaDex login dialog fill-in 2020-12-25 20:07:06 -05:00
Jobobby04 d68341aaba Allow editing local manga even if not in library 2020-12-21 22:51:46 -05:00
Jobobby04 e1e64c79d2 Revert "Hide dedupe by priority"
This reverts commit 2cf0475066.
2020-12-21 17:29:33 -05:00
Jobobby04 7d53c7af4a Fix crop borders webtoon/cont vertical settings inversion 2020-12-21 17:29:06 -05:00
Jobobby04 2cf0475066 Hide dedupe by priority 2020-12-21 14:46:38 -05:00
Jobobby04 0923cd6509 Release 1.4.1 2020-12-21 14:41:49 -05:00
Jobobby04 330908c49d Add continues vertical crop borders to the reading settings 2020-12-21 14:39:54 -05:00
Jobobby04 644140b617 Make a coroutine presenter 2020-12-21 14:21:43 -05:00
Jobobby04 d302a0fbc7 Cleanup 2020-12-21 14:21:43 -05:00
Jobobby04 ce8f7da9ca Use ContextCompat to get custom source icons 2020-12-21 14:21:42 -05:00
Jobobby04 f1a4811030 In batch add and deeplink, only use enabled sources 2020-12-21 14:21:42 -05:00
Jobobby04 a439ffcafc Add separate continues vertical crop borders setting 2020-12-21 14:21:42 -05:00
Jobobby04 5eeab103c2 Fix external repo preference conflict 2020-12-21 14:21:41 -05:00
Jobobby04 78ffd9d56e Cleanup 2020-12-21 14:21:41 -05:00
Jobobby04 96213900ac Add external repo support 2020-12-21 14:21:40 -05:00
Jobobby04 85e30ef6ca Cleanup 2020-12-21 14:21:40 -05:00
arkon f38df69983 Update app repo URL
(cherry picked from commit 04fff91e23)

# Conflicts:
#	.github/workflows/TachiyomiSY-Release-Builder.yml
#	README.md
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubUpdateChecker.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/WhatsNewDialogController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt
2020-12-21 14:21:40 -05:00
arkon 64e9515293 Update extensions repo URL
(cherry picked from commit 28a23452f2)

# Conflicts:
#	README.md
2020-12-21 14:21:39 -05:00
arkon 67e676d4ae Apply theme to OAuth login redirect activities
(cherry picked from commit 6d403851cf)
2020-12-21 14:21:39 -05:00
arkon ef36a9c28c Misc tracker code cleanup
(cherry picked from commit 395a749bce)
2020-12-21 14:21:38 -05:00
arkon 513bcbb80d Refactor CustomTabsIntent creation
(cherry picked from commit 2cc2a90941)
2020-12-21 14:21:38 -05:00
Jobobby04 3d5952ebbd Cleanup some unneeded lambas 2020-12-21 14:21:38 -05:00
arkon 1d55a1bec4 Fix loading fallback thumbnails in browse view (closes #4127)
(cherry picked from commit c5ca739b49)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt
2020-12-21 14:21:37 -05:00
arkon 962344f5fc Minor code cleanup
(cherry picked from commit 00fe4cdf2d)
2020-12-21 14:21:37 -05:00
Jobobby04 ba6bcc82b6 More dialog fixes 2020-12-21 14:21:36 -05:00
arkon 6659935f3d Complete migration off of Kotlin synthetics
(cherry picked from commit 69be3e1e87)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt
2020-12-21 14:21:36 -05:00
arkon ccca9e8828 Show MAL relogin message on update, localize error message
(cherry picked from commit 2cb3984d68)
2020-12-21 14:21:36 -05:00
arkon b4cce2b3e0 Use view binding for date headers
(cherry picked from commit 5901978889)
2020-12-21 14:21:35 -05:00
arkon 9737d847fd Update to coroutines 1.4.2
Should fix crashes on some devices. See https://github.com/Kotlin/kotlinx.coroutines/issues/2371

(cherry picked from commit 8bf1cf3cc5)
2020-12-21 14:21:35 -05:00
arkon f180c6a07c Reword NSFW settings section
(cherry picked from commit f6af1184bc)
2020-12-21 14:21:35 -05:00
arkon 024c2d4ce0 More crash fixes
(cherry picked from commit 4880741b8b)
2020-12-21 14:21:34 -05:00
arkon 17731f3904 Remove bundled fallback file picker
(cherry picked from commit e8627800fe)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt
#	app/src/main/res/layout/common_listitem_dir.xml
#	app/src/main/res/values/styles.xml
2020-12-21 14:21:34 -05:00
arkon e2dadd4213 Require WebView 86+
(cherry picked from commit 907fbb94a2)
2020-12-21 14:21:34 -05:00
Jobobby04 b4fedf9a87 Maybe fix push to mangadex 2020-12-21 14:21:33 -05:00
Jobobby04 beaf6284fd Fixes to merged settings dialog and edit manga dialog 2020-12-21 14:21:33 -05:00
arkon 3300eb0e79 Some crash fixes
(cherry picked from commit fd2028557e)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt
2020-12-21 14:21:33 -05:00
arkon 3599526fde Suppress some deprecation warnings
(cherry picked from commit 91fa1ec6b2)
2020-12-21 14:21:32 -05:00
arkon 8b6a0ad891 Note that toggling NSFW sources requires a restart
(cherry picked from commit bbc00768f0)
2020-12-21 14:21:32 -05:00
arkon cf99ee73f5 Break out NSFW hiding/labeling into separate settings
(cherry picked from commit 5b09461ccf)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionHolder.kt
2020-12-21 14:21:31 -05:00
arkon bbd3e3c29c Remove source overwrite logic since built-in sources no longer exist
(cherry picked from commit 1a439ecece)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt
2020-12-21 14:21:31 -05:00
arkon 972579bbec Flip left/right key events for Webtoon viewer (fixes #4111)
(cherry picked from commit 836aec4396)
2020-12-21 14:21:31 -05:00
Jobobby04 4044b0897e Make S Pen action ids unique 2020-12-21 14:21:30 -05:00
Jobobby04 5e6c0bbc14 Change Search in Tachiyomi to Search in TachiyomiSY 2020-12-21 14:21:30 -05:00
she11sh0cked a8c6474f5e Use a different title for japanese manga vs other manga (#181)
* Use a different title for japanese manga vs other manga

* Revert wildcard import
2020-12-21 14:20:49 -05:00
jobobby04 820279634e [SKIP CI] Update readme 2020-12-12 14:47:55 -05:00
jobobby04 ce7577a2b4 [SKIP CI] Update readme 2020-12-12 14:46:35 -05:00
Jobobby04 31376e5a52 Revert "Hide incomplete NSFW source labelling settings"
This reverts commit 134f776a86.
2020-12-12 14:07:33 -05:00
Jobobby04 b021f57273 Update Readme, images and issue templates 2020-12-12 14:06:15 -05:00
Jobobby04 958b6d4b71 Release 1.4.0 2020-12-12 13:27:13 -05:00
Jobobby04 6f712c7f17 Lint 2020-12-12 12:36:29 -05:00
arkon 134f776a86 Hide incomplete NSFW source labelling settings
(cherry picked from commit a3b1690d38)
2020-12-12 12:21:32 -05:00
arkon d91ac659fd Force MAL logout on update
(cherry picked from commit a3bad75899)
2020-12-12 12:20:39 -05:00
arkon bd8f703c28 Update Gradle
(cherry picked from commit d1aaafbfff)
2020-12-12 12:20:31 -05:00
Jozef Hollý bbeca97524 Weblate translations (#4078)
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: C201 <derasetad@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: HaruSasaki <aiqusubaru@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: Kurocon <weblate@kurocon.nl>
Co-authored-by: Mario Kevin D. A <programas013@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
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: Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
Co-authored-by: Tooster <max@polarczyk.pl>
Co-authored-by: Woodyx <shiposhouyou@gmail.com>
Co-authored-by: Yassin <yassinelaoud@gmail.com>
Co-authored-by: f0roots <f0rootss@gmail.com>
Co-authored-by: sunbeams001 <sunbeams001@gmail.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/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/fi/
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/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/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/tr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translation: Tachiyomi/Strings

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: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: HaruSasaki <aiqusubaru@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Kurocon <weblate@kurocon.nl>
Co-authored-by: Mario Kevin D. A <programas013@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
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: Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
Co-authored-by: Tooster <max@polarczyk.pl>
Co-authored-by: Woodyx <shiposhouyou@gmail.com>
Co-authored-by: Yassin <yassinelaoud@gmail.com>
Co-authored-by: f0roots <f0rootss@gmail.com>
Co-authored-by: sunbeams001 <sunbeams001@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
(cherry picked from commit 93d4af99bf)
2020-12-12 12:20:22 -05:00
arkon 6e346b231e Revert "Distinguish between no results and loading when sorting global search results"
This reverts commit 2be9871d05.

(cherry picked from commit c950595fe3)
2020-12-12 12:20:13 -05:00
arkon cb1a1e29be Don't scroll to top when navigating back/forward in WebView
(cherry picked from commit 8ffd3a8ed2)
2020-12-12 12:20:02 -05:00
arkon 7d11cc4837 Add text selection shortcut to invoke global search (closes #4058)
(cherry picked from commit b6e246c6b2)
2020-12-12 12:19:53 -05:00
arkon 0137262e4c Update to Kotlin 1.4.21 and kotlinter 3.3.0
(cherry picked from commit 59859e124f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2020-12-12 12:19:44 -05:00
arkon 45086af3ae Use WebView auth flow for MAL (fixes #4100)
(cherry picked from commit 2bb7a33bc3)
2020-12-12 12:18:40 -05:00
Taco d33cb59af5 Update libraries, some lints (#4099)
* Update some plugins

* Fix some miscellaneous lints

(cherry picked from commit c2b8fea291)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrationSourcesPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt
2020-12-12 12:18:30 -05:00
arkon 161d4e237f Update to Kotlin 1.4.20
(cherry picked from commit 08ab7f6aa0)
2020-12-12 12:11:29 -05:00
arkon 0db60d68f0 Use more up-to-date fork of junrar
(cherry picked from commit 560f0bba5c)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt
2020-12-12 12:11:19 -05:00
arkon 11b10f00dd Update AndroidX and Material Components dependencies
(cherry picked from commit 722437a022)
2020-12-12 12:09:30 -05:00
Jobobby04 8fbc6aa29b Convert intercept activity to a stateflow 2020-11-30 20:34:48 -05:00
Jobobby04 ee18f94788 Convert Favorites sync to a StateFlow 2020-11-30 20:22:29 -05:00
Jobobby04 9a2ed755b7 Cleanup EH and AZ preferences 2020-11-30 15:11:58 -05:00
Jobobby04 f1a6218a4b Throw a error when the 509 gif is given when your downloading or loading a chapter from Exh and E-H 2020-11-30 13:21:56 -05:00
Jobobby04 bff654eac8 Cleanup 2020-11-30 13:19:41 -05:00
Jobobby04 5e5b155992 Run getRecs in IO 2020-11-30 13:19:28 -05:00
Jobobby04 dacc5502fc Fix community recommendation stalling 2020-11-30 13:19:02 -05:00
Jobobby04 e7169bda19 Fix exclude from deletion 2020-11-30 13:02:47 -05:00
Jobobby04 8110a2cabd Cleanup 2020-11-29 20:38:36 -05:00
Jobobby04 1118fe7cf7 More recs cleanup 2020-11-29 20:38:22 -05:00
Jobobby04 5b54fc8885 Localize the similar manga no results error 2020-11-29 20:38:07 -05:00
Jobobby04 2e75cc0cc9 Add title to similar manga header 2020-11-29 20:35:46 -05:00
arkon 3f89d8ec99 Add Galician locale
(cherry picked from commit 8a44b1dabe)
2020-11-29 18:53:06 -05:00
arkon b44ffd1d63 Fix annotations package name
(cherry picked from commit b39191ff50)
2020-11-29 18:52:50 -05:00
Jobobby04 9bad33930a Fix weird recs map sort 2020-11-29 18:52:32 -05:00
Jobobby04 e23b048d53 Fixes to reader ui from @CrepTF 2020-11-29 18:52:01 -05:00
Jozef Hollý d291b41080 Weblate translations (#3997)
Co-authored-by: AXEL IVAN GARCIA BERNAL <ga419623@uaeh.edu.mx>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alex <linuxrf@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Andreas E <andreas.everos@gmail.com>
Co-authored-by: Aria Moradi <aria.moradi007@gmail.com>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: HaruSasaki <aiqusubaru@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: Johkum <jacobomur@gmail.com>
Co-authored-by: Kurocon <weblate@kurocon.nl>
Co-authored-by: Milo Ivir <mail@milotype.de>
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: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Simon Mattila <simon.mattila@protonmail.com>
Co-authored-by: The Pumpkin God <sbh13112002@gmail.com>
Co-authored-by: Tooster <max@polarczyk.pl>
Co-authored-by: Tristan Garnier <espeletpro@gmail.com>
Co-authored-by: Woodyx <shiposhouyou@gmail.com>
Co-authored-by: Yassin El Aoud <yassinelaoud@gmail.com>
Co-authored-by: george k <norhorn@gmail.com>
Co-authored-by: Николаев Павел Дмитриевич <pavliknikolaev128@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/ca/
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/fa/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fi/
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/he/
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/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/
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/sah/
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/
Translation: Tachiyomi/Strings

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: AXEL IVAN GARCIA BERNAL <ga419623@uaeh.edu.mx>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alex <linuxrf@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Andreas E <andreas.everos@gmail.com>
Co-authored-by: Aria Moradi <aria.moradi007@gmail.com>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: HaruSasaki <aiqusubaru@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Johkum <jacobomur@gmail.com>
Co-authored-by: Kurocon <weblate@kurocon.nl>
Co-authored-by: Milo Ivir <mail@milotype.de>
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: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Simon Mattila <simon.mattila@protonmail.com>
Co-authored-by: The Pumpkin God <sbh13112002@gmail.com>
Co-authored-by: Tooster <max@polarczyk.pl>
Co-authored-by: Tristan Garnier <espeletpro@gmail.com>
Co-authored-by: Woodyx <shiposhouyou@gmail.com>
Co-authored-by: Yassin El Aoud <yassinelaoud@gmail.com>
Co-authored-by: george k <norhorn@gmail.com>
Co-authored-by: Николаев Павел Дмитриевич <pavliknikolaev128@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
(cherry picked from commit 9814d20404)
2020-11-29 17:20:39 -05:00
arkon 177981da6c Use regular minified extensions JSON instead of explicitly handling gzip encoding
Turns out GitHub *does* do gzip encoding by default, it just doesn't show up in the header logs for some reason...

(cherry picked from commit 6664dfb048)
2020-11-29 17:20:14 -05:00
arkon a19d59cdf0 Fix crash when a preference doesn't have a title (e.g. info preference)
(cherry picked from commit 3133a63cf8)
2020-11-29 17:20:05 -05:00
Andreas E 6a1a7275c8 Enhance incognito mode (#4073)
* When in Incognito Mode don't set lastUsedSource

* When in Incognito Mode don't save chapter progress

Still allows tracking and mark as read when reaching last page

* When in Incognito Mode don't mark as read (overwritten if hasTrackers)

(cherry picked from commit c9c0f3d014)
2020-11-29 17:19:40 -05:00
Jobobby04 4a1e832bf5 Revert "Cool gray theme (#169)"
This reverts commit ac31f12138.
2020-11-29 17:19:29 -05:00
CrepeTF edc2065ea3 Tweak default dark theme colors (#4074)
(cherry picked from commit ff66f307dd)
2020-11-29 17:19:19 -05:00
arkon 0bb153fba9 Revert edge to edge
This was a bigger headache than it was worth. To note, phone landscape wasn't considered, so the navbar overlaps the content on the side. Additionally, the ability to programatically control the navbar scrim is missing, so it'd have to manually be added.

(cherry picked from commit e048d66f74)

# Conflicts:
#	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/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
2020-11-29 17:19:09 -05:00
arkon 495d63e66b Replace more Kotlin synthetics
(cherry picked from commit 66e3fa7df8)

# 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/manga/MangaController.kt
2020-11-29 17:16:20 -05:00
Jobobby04 ede4f40133 Cleanup rec changes 2020-11-29 17:13:44 -05:00
she11sh0cked 2cefc93797 Rework code to enable UI rendered error messages (#172) 2020-11-29 16:24:25 -05:00
arkon 9d16b0efd2 Replace more Kotlin synthetics
(cherry picked from commit 019a0f31c7)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceComfortableGridHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceItem.kt
#	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/library/LibraryHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/widget/preference/LoginDialogPreference.kt
2020-11-29 00:23:09 -05:00
arkon c9c808a782 Replace Kotlin synthetic views in viewholders
(cherry picked from commit 749c2071af)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MangaHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/SelectionHeader.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/SourceHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceComfortableGridHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceGridHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceListHolder.kt
#	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/library/LibraryHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt
2020-11-29 00:23:08 -05:00
Jobobby04 6f9edb7903 Add this back 2020-11-29 00:23:08 -05:00
arkon 7017b7b3ea Replace more usages of Kotlin synthetic views
(cherry picked from commit 322d66d282)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
2020-11-29 00:23:07 -05:00
arkon 65cf11ec10 Fix keyboard sometimes affecting bottom inset padding
(cherry picked from commit aa98cd0da0)
2020-11-29 00:23:07 -05:00
arkon 02946af081 Move NSFW source setting into Browse settings
(cherry picked from commit c8316c7254)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsMainController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/search/SettingsSearchHelper.kt
2020-11-29 00:23:06 -05:00
arkon 2b627128a6 Fall back to filename in backup creation notification if path not available
(cherry picked from commit 6b9180844d)
2020-11-29 00:23:06 -05:00
arkon efa1f47392 Fix restore in Android 11
(cherry picked from commit c0e4863229)
2020-11-29 00:23:05 -05:00
arkon 3f55759b8b Distinguish between no results and loading when sorting global search results
(cherry picked from commit 2be9871d05)
2020-11-29 00:23:05 -05:00
arkon 41433eb262 More bottom inset padding fixes
(cherry picked from commit 776f6a9a16)
2020-11-29 00:23:04 -05:00
Jobobby04 160d6ea013 Replace more menu Tachi logo with SY logo 2020-11-29 00:23:03 -05:00
CrepeTF ac31f12138 Cool gray theme (#169)
* Added "Cool gray" (Google gray)

* Added "Cool gray" (Google gray) theme
2020-11-27 13:14:31 -05:00
arkon 9f542aaed4 Use jcenter to get 1.x dependencies
(cherry picked from commit 10163aab21)
2020-11-27 13:11:25 -05:00
arkon ec31d8605a Handle bottom insets in FAB controllers too
(cherry picked from commit 60b2a4ea9d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
2020-11-27 13:10:32 -05:00
Jobobby04 ad38a79752 Use a shared flow for the exh redirect to latest 2020-11-27 13:01:58 -05:00
Jobobby04 643aa377bf Update XLog 2020-11-26 19:12:00 -05:00
Jobobby04 fcc2b1773b Update firebase 2020-11-25 15:49:33 -05:00
Jobobby04 92970bb812 Log to file cleanup 2020-11-25 15:13:06 -05:00
arkon 7129b79785 Further abstract how bottom navbar padding is applied
(cherry picked from commit 56e1e3e205)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt
2020-11-25 15:12:35 -05:00
arkon 6aaa9dcdb7 Handle bottom navbar padding when drawing edge to edge
(cherry picked from commit 0f805cd45e)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt
2020-11-25 15:07:38 -05:00
arkon 5c76faa638 Create extension function for applying system insets
(cherry picked from commit 1d7c692e89)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
2020-11-25 15:05:57 -05:00
arkon 0f6745d4a3 Add global search progress bar (closes #3727)
(cherry picked from commit 38bc8ec6b4)
2020-11-25 15:05:10 -05:00
arkon 438646727e Remove 10 results per source limit from global search (still limited to 1 page)
(cherry picked from commit 2154e3aa2d)
2020-11-25 15:04:45 -05:00
arkon bb7b79a6e9 Add help shortcut for source migration (closes #3951)
(cherry picked from commit 56c19e57a9)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrationSourcesController.kt
2020-11-25 15:04:32 -05:00
arkon d0293fef0a Fix transparent navbar when bottom sheets are opened (fixes #3848)
(cherry picked from commit d548c690d6)
2020-11-25 14:59:44 -05:00
arkon 0228d4611a Use ViewCompat for setting MainActivity inset paddings
(cherry picked from commit 3fa70dade3)
2020-11-25 14:59:34 -05:00
arkon f594ee66e5 More restore code cleanup
(cherry picked from commit 368c30a2cc)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt
2020-11-25 14:59:24 -05:00
arkon 610cad3bc5 Update Firebase
(cherry picked from commit 5539e4591f)
2020-11-25 14:52:20 -05:00
arkon b25e604bc2 Set preview/experimental compiler flags instead of using annotations
(cherry picked from commit 781971ee81)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
2020-11-25 14:52:06 -05:00
arkon b4be82d021 Pad bottom of MoreController so bottom nav doesn't overlap content
(cherry picked from commit 1140316d1b)
2020-11-21 18:13:15 -05:00
Jobobby04 9985646e58 Lint 2020-11-21 16:54:33 -05:00
arkon 383a797469 Some more code cleanup
(cherry picked from commit cf6c48744a)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt
2020-11-21 16:53:42 -05:00
arkon 692e7e17d8 Default automatic legacy backups to true for now
(cherry picked from commit eed6db8e92)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
2020-11-21 16:34:29 -05:00
arkon 978acec659 Some more code cleanup
(cherry picked from commit 858664bfd7)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupManager.kt
2020-11-21 16:33:45 -05:00
arkon 22019a8046 Merge restore entry points, avoid unnecessary new strings
(cherry picked from commit eceac4d6e3)
2020-11-21 16:31:37 -05:00
arkon b456d69aec Remove "full_" from v3 backup default file names
(cherry picked from commit 47a172df1f)
2020-11-21 16:31:27 -05:00
arkon a5abdaa5b1 Minor cleanup
(cherry picked from commit f2c0732c40)
2020-11-21 16:31:18 -05:00
arkon 8156804f7a Fix manga info description scrim on Android 5
(cherry picked from commit a150762c63)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
2020-11-21 16:30:59 -05:00
arkon be6f9d4a9f Fix non-transparent navigation bar
(cherry picked from commit 2695bdddf8)
2020-11-21 16:28:23 -05:00
Dominik Chrástecký 61b0039a78 add support for S Pen actions (#4029)
(cherry picked from commit c9b1a425a7)
2020-11-21 16:28:14 -05:00
arkon 72e95ea6fc Draw under navbar in Android 9+
(cherry picked from commit 122b2b1a8e)
2020-11-21 16:28:03 -05:00
arkon d6e7c1851b Update AGP for AS 4.1.1
(cherry picked from commit 2351c1b426)
2020-11-21 16:27:52 -05:00
arkon 99a27376d6 Remove TravisCI build config
(cherry picked from commit 0b5128dfd1)
2020-11-21 16:27:22 -05:00
arkon 97452ba9c8 Remove a stray trailing dash
(cherry picked from commit c0519e8670)
2020-11-21 16:27:14 -05:00
arkon 197019c65b Update dependencies
(cherry picked from commit fd545db1bd)
2020-11-21 16:27:02 -05:00
arkon 2b9c25cf71 Tweak manga info header
(cherry picked from commit 6991c224b2)

# Conflicts:
#	app/src/main/res/layout/manga_info_header.xml
2020-11-21 16:26:48 -05:00
arkon 76330f51c9 Add 1.x page model converters
(cherry picked from commit 7dc70c9eab)
2020-11-21 16:25:17 -05:00
arkon 3898a72cf8 Hide locale subtitle for local source
(cherry picked from commit e32445f2cf)
2020-11-21 16:25:07 -05:00
Jobobby04 1e98b09f24 Use more core-ktx 2020-11-21 16:24:16 -05:00
Jobobby04 2bece67f6e Fix Mangadex random button not showing results for some manga because they have no chapters 2020-11-13 22:48:08 -05:00
Jobobby04 7978dc9d2c Fix Mangadex random button returning the same result multiple times 2020-11-13 22:48:08 -05:00
jobobby04 9e41605512 [SKIP CI] Move back to r0adkll's sign release 2020-11-12 19:35:04 -05:00
Jobobby04 6e8ac9cc10 Fix Full backup, DELETE ALL FULL BACKUPS MADE BEFORE THIS UPDATE 2020-11-12 14:58:58 -05:00
Jobobby04 0594efb1c8 Cleanup 2020-11-11 17:30:38 -05:00
Jobobby04 a35e7871e8 Enhance file logging 2020-11-11 17:28:54 -05:00
Jobobby04 67aafab46a Forgot to commit this 2020-11-08 15:11:42 -05:00
Jobobby04 89a20be7ef Fix E-H Sync favorites getting stuck 2020-11-08 15:02:26 -05:00
Jobobby04 a4e05f297c Fix icon tint for share and save cover 2020-11-07 14:44:04 -05:00
Jobobby04 803ee3d547 Fix mangadex login dialog crash 2020-11-06 18:19:11 -05:00
Jobobby04 c6b0d0c9a5 Update SY french translation(From Adam-sama) 2020-11-06 15:50:46 -05:00
Jobobby04 d1887d4847 New Icon! Thanks to Aytox who made it! 2020-11-06 15:50:44 -05:00
Jobobby04 e987ba8c3e Lets try this out for full backup categories 2020-11-06 14:24:55 -05:00
Jobobby04 acefd33e2e Cleanup 2020-11-06 14:24:28 -05:00
Jobobby04 319c41905e Update latest tab with the new global search update 2020-11-05 00:31:00 -05:00
Jobobby04 079dd953bd Replace elvis operators with .orEmpty where possible 2020-11-04 22:10:13 -05:00
Jobobby04 015c610205 Use stable versions of RxUtil functions 2020-11-04 21:44:08 -05:00
Jobobby04 56ef3fd018 Remove unused values 2020-11-04 21:41:06 -05:00
arkon fe064a067e Update to serialization 1.0.1 and coroutines 1.4.1
(cherry picked from commit 8aa6486bf7)

# Conflicts:
#	app/build.gradle
2020-11-04 21:03:17 -05:00
arkon f283fbfd6f Singleton instance of Json serializer
(cherry picked from commit d21c147203)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/AppModule.kt
2020-11-04 21:01:55 -05:00
arkon 505a0db164 Fix Bangumi login (fixes #3994)
(cherry picked from commit 9b10e851d1)
2020-11-04 21:01:16 -05:00
arkon 4d00b2f8ce Update dependencies
(cherry picked from commit 6675508b24)

# Conflicts:
#	app/build.gradle
2020-11-04 21:01:07 -05:00
arkon c2ccbe5aff Use 1.x API to fetch manga details in browse view
(cherry picked from commit 7310ec4fe4)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt
2020-11-04 20:59:51 -05:00
Andreas E 98dade1b4d Change list view font size back to 16sp (#3978)
Make list view font size bigger again

(cherry picked from commit b1ce3693ed)
2020-11-04 20:58:51 -05:00
arkon eed7ef0aa8 Add Uzbek locale
(cherry picked from commit deb1ed5623)
2020-11-04 20:58:41 -05:00
Jozef Hollý 3f71795d05 Weblate translations (#3895)
Co-authored-by: Adam <bessaa935@gmail.com>
Co-authored-by: Ashraf Is <rediancool@gmail.com>
Co-authored-by: Ashraf Isl <rediancool@gmail.com>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: Credits125Cre <credits125@gmail.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eva Godoy <godoytraduccion@gmail.com>
Co-authored-by: Hara Desu <aqjbgr09@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: Jozef Hollý <j2.00ghz@gmail.com>
Co-authored-by: Kurocon <weblate@kurocon.nl>
Co-authored-by: Luka Paun <croluxgame@gmail.com>
Co-authored-by: Lyaiya <hipsnafoha@outlook.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: Mubarek Seyd Juhar <mubareksej@gmail.com>
Co-authored-by: Nico <nicknicola94@gmail.com>
Co-authored-by: Paulo Pinho <kebrus@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Pxeexe <johongira192@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Ruud Schouten <ruud.schouten@outlook.com>
Co-authored-by: Salem Almashaikhi <salemnabil1@outlook.com>
Co-authored-by: darkbeast13 <nikhil15mps@gmail.com>
Co-authored-by: f0roots <f0rootss@gmail.com>
Co-authored-by: opb <myniceaddress@outlook.com>
Co-authored-by: İlle <derasetad@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/am/
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/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/el/
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/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/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/ro/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/uk/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/uz/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/
Translation: Tachiyomi/Strings

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Adam <bessaa935@gmail.com>
Co-authored-by: Ashraf Is <rediancool@gmail.com>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: Credits125Cre <credits125@gmail.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eva Godoy <godoytraduccion@gmail.com>
Co-authored-by: Hara Desu <aqjbgr09@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: Kurocon <weblate@kurocon.nl>
Co-authored-by: Luka Paun <croluxgame@gmail.com>
Co-authored-by: Lyaiya <hipsnafoha@outlook.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: Mubarek Seyd Juhar <mubareksej@gmail.com>
Co-authored-by: Nico <nicknicola94@gmail.com>
Co-authored-by: Paulo Pinho <kebrus@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Pxeexe <johongira192@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Ruud Schouten <ruud.schouten@outlook.com>
Co-authored-by: Salem Almashaikhi <salemnabil1@outlook.com>
Co-authored-by: darkbeast13 <nikhil15mps@gmail.com>
Co-authored-by: f0roots <f0rootss@gmail.com>
Co-authored-by: opb <myniceaddress@outlook.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
(cherry picked from commit 0902d7cca9)
2020-11-04 20:58:32 -05:00
arkon d9b41ce4c5 Fix Bangumi API response deserialization (fixes #3977)
(cherry picked from commit 95ec903862)
2020-11-04 20:58:22 -05:00
arkon 195dbbf1c2 Consume and extend 1.x Source API
TODO: make the rest of the app actually call the 1.x functions
(cherry picked from commit 2ab6af6471)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/model/SManga.kt
2020-11-04 20:58:14 -05:00
Andreas E c12fb337f5 Replace language code in Global Search with secondary text (#3972)
Replace language code in Global Search with secondary text

(cherry picked from commit 9493577de2)
2020-11-04 20:56:45 -05:00
Jobobby04 4a4cdcb682 Add french translation for SY strings 2020-11-04 20:52:24 -05:00
Jobobby04 76de2d4447 Bind to the correct dialog view, fixed manga info edit crash 2020-11-04 17:18:10 -05:00
Jobobby04 7cbd7bd419 Cleanup 2020-11-01 19:19:57 -05:00
Jobobby04 8f1f6d5a97 Fix mangadex update interval not updating the interval on first click 2020-10-31 22:04:54 -04:00
Jobobby04 98bfe34e18 Update lewd manga checker with new sources and tags 2020-10-31 17:33:59 -04:00
Jobobby04 95c331b8b4 Convert all SY specific things to use ViewBindings instead of synthetics 2020-10-29 23:43:24 -04:00
Jobobby04 528f6c7f65 Drop humanize and guava(an older version still gets compiled in), use custom humanize solution for E-Hentai updater stats 2020-10-29 23:41:54 -04:00
Jobobby04 fe798e40cb Remove kotlin synthetics from E-Hentai settings 2020-10-29 21:52:27 -04:00
Jobobby04 133fe61408 Change manga edit to say Edit info 2020-10-29 21:50:44 -04:00
Jobobby04 3b5249c8bc Convert java threads to kotlin coroutines 2020-10-29 15:29:43 -04:00
Jobobby04 46998d81f4 Do a bit of cleanup 2020-10-29 15:28:48 -04:00
Jobobby04 fccf609c81 Fix NHentai covers 2020-10-29 14:25:37 -04:00
Jobobby04 406b5a89c8 Fix smart background for real this time, fix issues with theme not changing 2020-10-29 00:37:07 -04:00
Jobobby04 4881571293 Big refactor for the E-Hentai config builder, I sucked when making my additions, now its better 2020-10-29 00:13:25 -04:00
Jobobby04 9cba544ffd Refactor and cleanup a bunch of code 2020-10-27 23:05:53 -04:00
Jobobby04 114fb723dc Trim Mangadex descriptions, fixes extra blank lines 2020-10-27 17:59:21 -04:00
Jobobby04 8e03375664 Deeplink using pathPattern instead of pathPrefix 2020-10-26 21:53:31 -04:00
Jobobby04 6142e9be1c More mangadex deeplink tweaks 2020-10-26 21:51:28 -04:00
Jobobby04 24be0aa50b For E-Hentai manga display chapter date with the E-Hentai date format 2020-10-26 19:40:12 -04:00
Jobobby04 a7cfae1603 Mangadex deeplink tweaks 2020-10-26 19:39:37 -04:00
Jobobby04 079405c17e More tweaks to delegated manga views 2020-10-26 19:23:59 -04:00
Jobobby04 105302aa7b Fix delegated sources trying to always open in SY, even with links SY doesnt support 2020-10-26 14:53:48 -04:00
Jobobby04 05269c557d Make TF happy, cleanup the more info menu 2020-10-26 14:28:56 -04:00
Jobobby04 35217036ce Fix chapters in delegated manga where you haven't filtered any groups 2020-10-26 13:07:55 -04:00
Jobobby04 eb3a987826 Implement Neko similar manga, Mangadex only recommendations 2020-10-26 02:13:02 -04:00
Jobobby04 3f1dede133 Fix a oppsies 2020-10-25 23:41:15 -04:00
Jobobby04 e9cef78d19 Filter scanlators on delegated manga 2020-10-25 20:24:30 -04:00
Jobobby04 32232c80aa Extra info updates 2020-10-25 20:19:02 -04:00
Jobobby04 112bbdfcf7 Remove outdated comment 2020-10-25 18:12:36 -04:00
Jobobby04 415f30f38a Manga metadata is now easier to use in the manga view 2020-10-25 13:37:08 -04:00
Jobobby04 2a24f659d2 Disable things that dont work how I want them to 2020-10-24 23:56:40 -04:00
Jobobby04 484cb86ca9 Cleanup 2020-10-24 22:53:43 -04:00
Jobobby04 a21d7f4f90 Request a new image from E-Hentai if it fails to download, should make E-Hentai downloads more relaible 2020-10-24 22:00:45 -04:00
Jobobby04 a75cf8ec53 Attempt a new way to move chapters between EH manga versions 2020-10-24 21:59:56 -04:00
Jobobby04 b252a9e060 Fixed EH update helper crashes 2020-10-24 19:41:16 -04:00
Jobobby04 fa7c6716f4 Remove EH legacy code 2020-10-24 19:07:46 -04:00
Jobobby04 99b1f6e56f Cleanup 2020-10-24 19:07:16 -04:00
Jobobby04 a2cda24e01 Fix broken menu after clicking source, move latest to the top 2020-10-24 17:17:00 -04:00
Jobobby04 c049ce9018 Convert E-Hentai Update helper to Flows 2020-10-24 16:44:20 -04:00
Jobobby04 1a0109df1d Cleanup 2020-10-24 15:44:52 -04:00
Jobobby04 c999229700 Use bundleOf everywhere I can 2020-10-24 14:28:03 -04:00
arkon 86fc50d62b Janky workaround for collapsed global search covers
(cherry picked from commit 837ce62844)
2020-10-24 14:15:19 -04:00
Andreas E b9bddd264b Update Global search layout to match Library and Browse (#3892)
* Update Global Search card item to be comfortable with rounded corners

* Remove card background

(cherry picked from commit a2b1acd70f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchCardHolder.kt
#	app/src/main/res/layout/global_search_controller_card.xml
#	app/src/main/res/layout/global_search_controller_comfortable_card_item.xml
2020-10-24 14:08:28 -04:00
Andreas E 4937c7fff2 Fix missing chapter warning when chapter number is not recognized (#3928)
* Fix missing chapter warning when chapter number is not recognized

* Add case where ch number is recognized as zero but has no ch number

Yes this will ignore ch 0

* Use RegEx to double check if ch. name contains potential ch. number

(cherry picked from commit f1350bc33e)
2020-10-24 13:41:22 -04:00
arkon 6419d79960 Fix Shikimori login (closes #3966)
(cherry picked from commit 6af0eb4068)
2020-10-24 13:41:13 -04:00
arkon 295fe37a9d Use default height for extended FAB (closes #3949)
(cherry picked from commit 538c168641)
2020-10-24 13:41:04 -04:00
arkon 3ff2321a95 Lower minWidth for extended FAB (fixes #3939)
(cherry picked from commit 832a4fa68e)
2020-10-24 13:40:54 -04:00
arkon 8322f7b95f Show locale in sources list items
(cherry picked from commit ed41604f56)
2020-10-24 13:40:40 -04:00
Jobobby04 3ed0ef5e3e Cleanup 2020-10-24 13:39:28 -04:00
Jobobby04 b850a8729f Remove old backup code I tried for dummy restore 2020-10-24 13:39:04 -04:00
Jobobby04 024a39d06b Lets try this for sort by tag performance 2020-10-24 13:38:45 -04:00
Jobobby04 01496ab34c Cleanup some merged manga code 2020-10-24 13:38:25 -04:00
Jobobby04 9a45891ed6 Fix saving cover putting it in a weird folder, cleanup 2020-10-21 23:02:32 -04:00
Jobobby04 5e531ba469 Put manga metadata into backups 2020-10-21 23:01:57 -04:00
Jobobby04 cb6a991e9f Fix share cover name, make ainz happy by hiding other options 2020-10-21 17:03:15 -04:00
Jobobby04 96989bfa53 Likely fix smart background 2020-10-21 14:59:39 -04:00
Jobobby04 b1048d8014 Fix migrate extra data like chapter filters and viewer 2020-10-20 16:13:34 -04:00
Jobobby04 89d9768759 Re-add some stuff from EH that I lost along the way 2020-10-19 21:05:24 -04:00
Jobobby04 1dfe3890a9 Add intercept activity source choosing 2020-10-19 18:41:41 -04:00
Jobobby04 a4a1c2827c Fix some backup duplication issues 2020-10-19 18:39:08 -04:00
Jobobby04 0b68bb20a8 Copy categories over from the original manga to the merged manga 2020-10-19 16:08:11 -04:00
Jobobby04 a8b1e8fdb0 Switch to the Mangadex extension for the low quality covers setting 2020-10-19 15:47:14 -04:00
Jobobby04 9945752667 Support the short title setting in NHentai 2020-10-19 15:46:08 -04:00
Jobobby04 05c2b43ffb Fix the release builder for AGP 4.1.0 2020-10-19 00:46:00 -04:00
Jobobby04 b2cd5648bb Update to android gradle plugin 4.1.0 to see if I fixed the action 2020-10-18 23:12:20 -04:00
Jobobby04 853f195d0e Hide biometric lock times when biometric lock is not enabled 2020-10-17 17:07:35 -04:00
Jobobby04 a481f3239c Throttle E-Hentai migrations 2020-10-16 19:33:24 -04:00
Jobobby04 510ae46fbf Lint 2020-10-15 11:27:56 -04:00
Jobobby04 c3a5439d26 Fixes for delete if in category 2020-10-15 11:27:30 -04:00
Jobobby04 a4273bb9a2 Add share/save manga cover when expanded from J2k, not tested 2020-10-15 11:26:39 -04:00
Carlos 0b6f7c5e23 Add push to mangadex
(cherry picked from commit 869f24f2092c761bc2a7bf075784bc8b7cbaea23)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSiteController.kt
#	app/src/main/res/values/strings_neko.xml
2020-10-14 18:43:27 -04:00
Jobobby04 c789203ff8 fix some mangadex manga not being marked as complete in status 2020-10-14 17:48:12 -04:00
Carlos 7f73094bb4 follows sort yolo
(cherry picked from commit 097d44ef35b021ba11e164f45234356fd8395540)

# Conflicts:
#	app/src/main/java/exh/md/handlers/FollowsHandler.kt
2020-10-14 17:43:40 -04:00
Jobobby04 a2a21bbbb7 Fix strings(again) 2020-10-14 17:36:51 -04:00
Jobobby04 c42e8739f6 Move some functions to the abstract backup manager 2020-10-14 17:36:22 -04:00
Jobobby04 d9ce86aca6 Dedupe some code, move over read and bookmarks properly 2020-10-14 15:19:46 -04:00
Jobobby04 f4200e2146 Rewrite backup categories 2020-10-14 14:15:14 -04:00
Jobobby04 e32f4eb317 Replace migrate button with merge 2020-10-14 14:06:05 -04:00
Jobobby04 e7c16cd0d1 Also apply changes to online restore 2020-10-14 13:15:54 -04:00
Jobobby04 f91d1af373 Dont break after finding one chapter 2020-10-14 13:10:24 -04:00
Jobobby04 326dc27009 Find chapter based on the url 2020-10-14 13:05:52 -04:00
Jobobby04 0a790c3c25 Fix grammer 2020-10-14 13:05:36 -04:00
Jobobby04 f6fd8a8ddb Make offline the default 2020-10-14 12:46:39 -04:00
Jobobby04 413c88d99f Fix backups always loading the full backup restore mode, even when legacy restore was used 2020-10-13 23:29:21 -04:00
Jobobby04 d15a473ed1 Enable the proguard rules 2020-10-13 21:53:23 -04:00
Jobobby04 c31beccf3c Lets try this 2020-10-13 21:33:34 -04:00
Jobobby04 f92c09b0f6 More comments 2020-10-13 20:55:18 -04:00
Jobobby04 5b056c6b70 Comment it all out 2020-10-13 20:27:36 -04:00
Jobobby04 2281a7a03d Comment out even more for a test 2020-10-13 17:23:43 -04:00
Jobobby04 713dcdfe53 Comment out some new rules for testing 2020-10-13 16:51:47 -04:00
Jobobby04 f3fc479020 Revert temp fixes, add serialization progurd rules
This reverts commit 543e089982.
2020-10-13 13:49:28 -04:00
Soitora 13196a68b1 Darken the description colors (#3858)
* Darken the description colors

* Restore UpdatesHolder.kt

* Use the same color as the Extensions subtitles

(cherry picked from commit 9f05d563f9)
2020-10-13 12:39:14 -04:00
arkon 90452a7833 Use secondary color for manga info header action button default state
(cherry picked from commit 72d114d46a)
2020-10-13 12:39:00 -04:00
Taco 8722c1806e Use some more KTX and Compat stuff (#3933)
* Use more KTX extensions

* Update Android Studio

* Use more Compat classes

(cherry picked from commit 60755d0c26)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt
2020-10-13 12:38:23 -04:00
Jobobby04 543e089982 Revert the converter factory back to gson 2020-10-13 11:43:46 -04:00
Jobobby04 b67db6a25e Manually deserialize saved searches, fix NHentai 2020-10-13 11:34:29 -04:00
Jobobby04 3dd10df45e Likely fixed the full backup crashing for some users 2020-10-12 23:03:38 -04:00
Jobobby04 22f81758b0 Refactor custom manga info manager 2020-10-12 22:35:45 -04:00
Jobobby04 405b0580fc Implement exclude categories from deletion 2020-10-12 22:11:16 -04:00
Jobobby04 eea1f696ca Update dependencies 2020-10-12 21:52:20 -04:00
Jobobby04 7e93557bd2 Remove markwan dependancy 2020-10-12 21:50:06 -04:00
Jobobby04 36c0d24143 Cleanup 2020-10-12 20:20:42 -04:00
jobobby04 445878794c Make a protobuf based backup system (#112)
* Make a protobuf based backup system, restore not tested

* Fix a number

* Remove uneeded change

* Remove more uneeded changes

* Use 1.x style models, backup should be 100% compatible with the 1.x backups

* Fix restore service not running

* Fix offline chapter restore
Cleanup saved searches restore(untested)

* Implement onlione/offline option, fix merged manga restore online, fix restore total

* Allow setting auto backup to use a full backup

* Fix for saved searches restore

* Edit some comments

* Convert flows back to observables

* Fix a model

* Fixes and comment only the SY specific things

* Move SY values range to 600 from 60

* Combine legacy and full backup services into one
Deduplicate a lot of code
Simplify a lot of stuff
Modify comments

* Cleanup

* Remove unneeded protobuf config edit because its now the default

* Migrate to kotlinx.serialization for backup saved searches

* Cleanup saved searches more, move gson type adapters to the legacy package
2020-10-12 14:41:56 -04:00
Jobobby04 f3365cef67 Convert SY specific usages of Gson to Kotlin Serialization
Cleanup saved searches a bit
Cleanup json parsing
2020-10-12 14:20:54 -04:00
arkon bbfce97125 Trust user-added CAs (closes https://github.com/inorichi/tachiyomi-extensions/issues/4581)
(cherry picked from commit a689e4e041)
2020-10-11 16:07:35 -04:00
arkon 232f5b8aab Migrate to kotlinx.serialization for Bangumi
(cherry picked from commit f5aa36c787)
2020-10-11 16:07:24 -04:00
arkon 4f575f37c0 Migrate to kotlinx.serialization for Shikimori
(cherry picked from commit f8d82cb052)
2020-10-11 16:07:11 -04:00
arkon 5b4f17777c Migrate to kotlinx.serialization for download store and deleter
(cherry picked from commit 980feb6c96)
2020-10-11 15:53:50 -04:00
arkon 38c3a926bb Migrate to kotlinx.serialization for Anilist
(cherry picked from commit e7d6605490)
2020-10-11 15:53:42 -04:00
arkon b4cf0e9723 Migrate to kotlinx.serialization for extensions and update fetching
(cherry picked from commit 7a476abb53)

# Conflicts:
#	build.gradle.kts
2020-10-11 15:53:27 -04:00
arkon 4d64734dec [SKIP CI] Remove dev build logic from Travis CI config (#3873)
(cherry picked from commit 19581792fc)

# Conflicts:
#	.travis/build.sh
2020-10-11 15:37:19 -04:00
specterflare 30d3d88d03 [SKIP CI] Replace dead link in README with correct one (#3929)
(cherry picked from commit aadc6a56cd)

# Conflicts:
#	README.md
2020-10-11 15:36:13 -04:00
arkon 57803bce2f Bump minimum WebView version to 84
(cherry picked from commit b88e444cbc)
2020-10-11 15:34:53 -04:00
arkon 6d235e23ff Update dependencies
(cherry picked from commit 6c792d2821)
2020-10-11 15:34:34 -04:00
arkon 428720fb74 Update AboutLibraries
(cherry picked from commit 9afb445620)

# Conflicts:
#	build.gradle.kts
2020-10-11 15:34:15 -04:00
jobobby04 f32ccf1c6d Remove pong 2020-10-10 01:01:39 -04:00
Jobobby04 776a4b2a24 History fixes 2020-10-10 00:32:39 -04:00
Jobobby04 883af56a9a Do some work on the workflows 2020-10-09 13:19:51 -04:00
arkon a9279fbb2e Cancel previous CI workflow runs
(cherry picked from commit a249373bf5)

# Conflicts:
#	README.md
2020-10-09 13:06:13 -04:00
arkon 6dc55a3fc4 Use eskatos/gradle-command-action instead of manually handling caching
(cherry picked from commit e1eb030b18)

# Conflicts:
#	.github/workflows/build_check.yml
2020-10-09 13:04:43 -04:00
Aakash Singh f0e2367071 skip ci in commit message condition check (#3902)
* skip ci condition check

* always Validate Gradle Wrapper

* naming workflow jobs

(cherry picked from commit 6aea0f48ed)

# Conflicts:
#	.github/workflows/build_check.yml
2020-10-09 13:04:02 -04:00
arkon 8e27ffcad7 Add Amharic locale
(cherry picked from commit 842295348e)
2020-10-09 13:02:30 -04:00
Jozef Hollý 856a149032 Translations (Continuous) (#3886)
* Weblate translations

Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alessandro Zangrandi <alessandro@mzit.it>
Co-authored-by: Alex <linuxrf@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Félix D <felix.desmaretz@protonmail.com>
Co-authored-by: Hara Desu <aqjbgr09@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: Josh Ciardi <jbciardi@gmail.com>
Co-authored-by: Juan Aranda <juan50055005@gmail.com>
Co-authored-by: Kurocon <weblate@kurocon.nl>
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: Mubarek Juhar <mubareksej@gmail.com>
Co-authored-by: Nikita Epifanov <nikgreens@protonmail.com>
Co-authored-by: Nin Gun <luis_noxer@hotmail.es>
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: Redya Rachmandanu <redyarachmandanu@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Salem Almashaikhi <salemnabil1@outlook.com>
Co-authored-by: Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
Co-authored-by: Shashank Pujari <shashankppujari@gmail.com>
Co-authored-by: Simon Mattila <simon.mattila@protonmail.com>
Co-authored-by: Yassin El Aoud <yassinelaoud@gmail.com>
Co-authored-by: abidin toumi <abidin24@disroot.org>
Co-authored-by: darkbeast13 <nikhil15mps@gmail.com>
Co-authored-by: f0roots <f0rootss@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: İlle <derasetad@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/am/
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/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/en_US/
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/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/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/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/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/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/Strings

* Deleted translation using Weblate (Belarusian)

* Deleted translation using Weblate (Bengali (Bangladesh))

* Deleted translation using Weblate (Spanish (Mexico))

* Deleted translation using Weblate (Tigrinya)

* Deleted translation using Weblate (English (United States))

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: Alessandro Zangrandi <alessandro@mzit.it>
Co-authored-by: Alex <linuxrf@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Félix D <felix.desmaretz@protonmail.com>
Co-authored-by: Hara Desu <aqjbgr09@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: Josh Ciardi <jbciardi@gmail.com>
Co-authored-by: Juan Aranda <juan50055005@gmail.com>
Co-authored-by: Kurocon <weblate@kurocon.nl>
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: Mubarek Juhar <mubareksej@gmail.com>
Co-authored-by: Nikita Epifanov <nikgreens@protonmail.com>
Co-authored-by: Nin Gun <luis_noxer@hotmail.es>
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: Redya Rachmandanu <redyarachmandanu@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Salem Almashaikhi <salemnabil1@outlook.com>
Co-authored-by: Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
Co-authored-by: Shashank Pujari <shashankppujari@gmail.com>
Co-authored-by: Simon Mattila <simon.mattila@protonmail.com>
Co-authored-by: Yassin El Aoud <yassinelaoud@gmail.com>
Co-authored-by: abidin toumi <abidin24@disroot.org>
Co-authored-by: darkbeast13 <nikhil15mps@gmail.com>
Co-authored-by: f0roots <f0rootss@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: İlle <derasetad@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
(cherry picked from commit 2992a0f4d8)
2020-10-09 13:02:21 -04:00
Aakash Singh c94e6c0304 Workflow improvements (#3891)
* add caching steps to build_check workflow

* add gradle.properites for github runner

* refactor ci-gradle.properties

* specify ndk versiion in build.gradle

* remove ndk install and cache steps from build_check

* moved runner files to separate folder

* refactor build_check.yml

(cherry picked from commit e8f5963a57)
2020-10-09 13:01:50 -04:00
Jobobby04 292dbf85c9 Cleanup 2020-10-09 12:59:40 -04:00
Jobobby04 96a5b456f5 Remove tooltip 2020-10-03 17:43:10 -04:00
jobobby04 05bcdadbd5 Merge pull request #125 from jobobby04/pr
Update to preview
2020-10-03 17:27:39 -04:00
arkon 95de42ad80 Prevent tag search if browsing from latest (sort of closes #3625)
(cherry picked from commit 4cbe497770)
2020-10-03 13:05:29 -04:00
Aakash Singh d26b8a9e41 Update issue_closer.yml (#3885)
Limit the issue_closer workflow to run only when the issue is opened, edited or reopened

(cherry picked from commit 76a53097b1)
2020-10-03 13:02:51 -04:00
arkon 8404b1c0c2 Set activated states for manga info favorite/tracker buttons
(cherry picked from commit 0904692f15)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
#	app/src/main/res/layout/manga_info_header.xml
2020-10-03 13:01:25 -04:00
arkon eef8b776f6 Reorder chapter filters to better match library filters
(cherry picked from commit 65bacd288b)
2020-10-03 12:58:26 -04:00
Andreas E 527e26137f Remove from queue after read (#3870)
* Add option to remove chapter from download queue after marked as read

* Begone bug

There was a bug when one queued a new download to the downloader. Which resulted in getChapterDownloadOrNull() would not find the corresponding download for the provided chapter

* Fix review comment

* Remove preference and just remove from queue

(cherry picked from commit 11ab3b2c2e)
2020-10-03 12:57:42 -04:00
Andreas E f6d3c38d03 Ability to delete reading history (#3871)
* Added ability to delete history for all manga

* Fix review comments

(cherry picked from commit 812368e332)
2020-10-03 12:57:29 -04:00
arkon 2772e4960e Add banner for Incognito Mode
(cherry picked from commit cf39ae0000)
2020-10-03 12:57:20 -04:00
arkon 085722e077 Show downloaded only banner in all views
(cherry picked from commit 7194f65203)
2020-10-03 12:57:10 -04:00
arkon 6a3a5c58d4 Minor string cleanup for Incognito Mode
(cherry picked from commit 4b78ff324d)
2020-10-03 12:57:01 -04:00
Platiplus e1d7713f14 [Feature Request] Option to turn off History - #3772 (#3855)
* Implementing do not save chapter history preference

* Refactor of labels

* Changing incognito mode from Readers section to More

* Fixing imports and removing unused strings

(cherry picked from commit 79ccfcd553)
2020-10-03 12:56:53 -04:00
arkon 925e9d9516 Update AndroidX dependencies
(cherry picked from commit 2df6a4dde8)
2020-10-03 12:54:58 -04:00
Jobobby04 a0cf7730f5 Undo some weird thing SY had 2020-10-02 22:01:25 -04:00
Unlocked e1fc94e6d3 Fix visual issue with bottom padding in filters sheet (#3881)
(cherry picked from commit 25d1c40cda)
2020-10-02 12:14:49 -04:00
arkon dc7a492d75 Update subsampling-scale-image-view
(cherry picked from commit 969b57ade9)
2020-10-02 12:14:18 -04:00
Jobobby04 63aab6f11e Fix deleting history not refreshing the view 2020-10-02 12:06:49 -04:00
Jobobby04 32748fa056 Allow migrating extra info like viewer, chapter filters, and other stuff 2020-10-01 22:12:37 -04:00
Jobobby04 1a55f4845c Fix manual search using browse's menu 2020-10-01 21:43:43 -04:00
Jobobby04 b4194de9e0 Fix SY filters not properly setting 2020-10-01 10:07:44 -04:00
Jobobby04 4f864152ea Cleanup some code 2020-09-30 19:48:26 -04:00
Jobobby04 c501c9ecc3 Modify the looks of the extra info for a few sources 2020-09-30 19:29:44 -04:00
Jobobby04 4bd88fa194 Add source categories removing the source in the language as a option 2020-09-30 18:27:09 -04:00
Jobobby04 604b4ec01e Fix expanding tags on E-Hentai and similar manga 2020-09-30 17:52:24 -04:00
Jobobby04 789f1392ac Fix clicking the updates button multiple times opening multiple download menus 2020-09-29 19:16:33 -04:00
Jobobby04 1b9c66896a Add a double click action on the updates bottom bar button to open downloads 2020-09-29 15:52:39 -04:00
Andreas E c6db5a01dd Fix color filter sheet content alignment (#3862)
Fix color filter sheet content alignment

(cherry picked from commit bddeb86223)
2020-09-29 12:41:56 -04:00
arkon 3a07ee3deb Fix chapter filter icon tinting
(cherry picked from commit b5986b509e)
2020-09-29 12:41:28 -04:00
jobobby04 9c76f1fd8f Match infinite history and search history from preview (#3827)
* Add infinite history and search history

* Cleanup code

(cherry picked from commit 9d2adcd512)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/database/queries/HistoryQueries.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/queries/RawQueries.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/recent/history/HistoryController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/recent/history/HistoryPresenter.kt
2020-09-29 12:41:10 -04:00
arkon 8acd834783 Use tristate checkboxes for chapters list filters
(cherry picked from commit fb3756420b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
2020-09-29 12:35:40 -04:00
arkon 7494033b90 Fix scrolled content being visible behind navigation view group
(cherry picked from commit 2eab43a669)
2020-09-29 12:26:30 -04:00
arkon 703263246e Clean up bottom nav bar scrolling behavior toggling
(cherry picked from commit caeab0a63b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
2020-09-29 12:26:21 -04:00
arkon 59020deb6f Tweak navigation view group header style
(cherry picked from commit 7c69b1b649)
2020-09-29 12:25:33 -04:00
scb261 2130a2a67e Add option to hide bottom bar when scrolling (#3758)
* [wip] hardcoded flag for hide on scroll

* add corresponding option in settings

* clean up a little

Co-authored-by: arkon <arkon@users.noreply.github.com>
(cherry picked from commit 3784d1a8f2)
2020-09-29 12:25:25 -04:00
scb261 a8946e4f98 Add ability to choose what to remove for selected mangas (#3796)
* [wip] started to change manga delete options

* Change dialog for deleting selected manga

* Move array to appropriate file

* Make first option enabled by default

* Use radio buttons to reduce amount of clicks

* Revert "Use radio buttons to reduce amount of clicks"

(cherry picked from commit 458e761b45)
2020-09-29 12:25:16 -04:00
arkon c59ca51944 Color selected bottom nav item with accent color when theme isn't blue
(cherry picked from commit 371b0b2132)
2020-09-29 12:25:05 -04:00
arkon ad03dfee97 Use same padding as source icons for extensions
(cherry picked from commit 5d1ca64768)
2020-09-29 12:24:55 -04:00
arkon 3b5a869fd0 Color selected tab with accent color when theme isn't blue
(cherry picked from commit 972a595c74)
2020-09-29 12:24:47 -04:00
arkon 815ac9d55b Remove card backgrounds from browse lists
(cherry picked from commit a3c598a3e1)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrationSourcesController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceHolder.kt
2020-09-29 12:24:33 -04:00
arkon 7b76823b60 Use background color for list view
(cherry picked from commit 9ce8c5c160)
2020-09-29 12:17:18 -04:00
arkon ab7bd3ebc2 Shorten settings search package name
(cherry picked from commit 79bbc99882)
2020-09-29 12:17:10 -04:00
Carlos 4faaf577be Update Ben Manes versions lib (#3843)
Update Ben Manes versions lib

(cherry picked from commit 31867362dc)
2020-09-29 12:16:55 -04:00
Jobobby04 4805d3c0c0 Manage Exhentai better, if login is disabled the source will disappear 2020-09-29 12:15:41 -04:00
Jobobby04 3c8fe2ed0e Make mangadex icon in settings smol 2020-09-27 17:23:42 -04:00
Jobobby04 d7433a0cd8 Change reader preload amount to Page Preload amount 2020-09-25 14:36:21 -04:00
Jobobby04 a8e80c663e String tweaks 2020-09-25 10:27:58 -04:00
Jobobby04 1b90590260 Cleanup Autoscroll coroutine code 2020-09-25 10:26:42 -04:00
Jobobby04 a903a48718 Add source setting controllers to search settings, hide settings in the E-Hentai settings when not logged in 2020-09-25 10:26:42 -04:00
Carlos 1038913e2c Update strings_sy.xml (#120)
remove neko strings
2020-09-25 10:25:58 -04:00
Jobobby04 748e5d5b0f History tweak 2020-09-24 09:19:36 -04:00
arkon ea3f90f107 Minor settings search code cleanup
(cherry picked from commit 3bce07e873)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsMainController.kt
2020-09-24 09:13:48 -04:00
arkon 26557b3257 #3520 Searchable Settings (#3683)
* Adding class stubs for settings search, UI elements.

* -  implement searchable settings
- `SettingsController.setupPreferenceScreen` must return a PreferenceScreen

* Remove unneeded SettingsControllerFactory.

* Set query hint, clean up code smell.

* Add search button to MoreController, stop infinite recursion.

* - initialize SearchResultCollection once in Activity.onCreate

* - implement prefernce highlighting after settings search

* - Ensure all Preferences have a key set or else the highlighting effect will have no effect on it.
- remove ExtensionFilterController and SourceFilterController from settingControllersList in SettingsSearchHelper, since those are related to Extensions and not Settings

* Limiting search to settings menu only, localized breadcrumb string, and code cleanup after code review.

* - moved call to SettingsSearchHelper.initPreferenceSearchResultCollection() into SettingsSearchController

* Code review cleanup and refactoring.

* Inlined non-reused key strings.

* Adding more UI polish, add comments for future enhancements.

* - retain search query when navigating *away* from SettingsSearchController
- keep `searchItem` in `expandActionView` state until user goes back (fixes the empty view in `SettingsSearchSearchController` issue)

Co-authored-by: mpm11011 <markuscicero5@gmail.com>
Co-authored-by: lmj0011 <9396189+lmj0011@users.noreply.github.com>
(cherry picked from commit 766f9e37b5)

# Conflicts:
#	app/build.gradle
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceFilterController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt
2020-09-24 09:09:45 -04:00
arkon 89eea4ab91 Move manga info summary more/less button toggle
(cherry picked from commit a9bed90d02)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
#	app/src/main/res/layout/manga_info_header.xml
2020-09-24 08:41:48 -04:00
arkon 616fbe4afe Center reader transition text properly (fixes #3819)
(cherry picked from commit 01ad405dd2)
2020-09-24 08:24:16 -04:00
arkon c57abf67eb Move Gradle wrapper validation into build action
(cherry picked from commit 274f0edd76)

# Conflicts:
#	.github/workflows/build_check.yml
2020-09-24 08:23:58 -04:00
arkon 4aff2d79b7 Remove support for backup v1
(cherry picked from commit 88aea311f8)
2020-09-24 08:22:09 -04:00
arkon a87f6811e5 Minor updates
(cherry picked from commit 477aedbffa)
2020-09-24 08:22:00 -04:00
arkon 10f15d54f3 Add sah locale (closes #3818)
(cherry picked from commit b898442fe3)
2020-09-24 08:21:48 -04:00
Jobobby04 91c05e76bc Fix mangadex manga getting set to completed when not actually finished 2020-09-22 14:22:21 -04:00
Jobobby04 caa6dd6d62 Fix issues with mangadex tracking, infinite loading and showing up on non-mangadex manga 2020-09-22 13:45:50 -04:00
Jobobby04 ffc80c084d Parse the error Mangadex sends so people know what they are doing wrong 2020-09-17 12:10:12 -04:00
Jobobby04 9ee712aea4 Fix some mangadex login imports 2020-09-17 10:41:41 -04:00
Jobobby04 11fbc1faf9 Use XLog in more places 2020-09-17 09:05:19 -04:00
Jobobby04 bd6e048108 Fix search in latest + browse view 2020-09-17 00:43:38 -04:00
Jobobby04 a3be1c2c39 Fix merged manga getting backed up 2020-09-16 14:19:16 -04:00
Jobobby04 cbbb3bbf72 Trim the created tag to account for user errors 2020-09-16 13:00:39 -04:00
Jobobby04 67c99c9c42 More fixing to the sort by tags logic 2020-09-16 12:58:25 -04:00
Jobobby04 905e1b68c6 Sort by tag settings is able to sort the tags and save the changes 2020-09-16 12:25:08 -04:00
Jobobby04 f5998505a3 Cleanup 2020-09-15 23:34:14 -04:00
Jobobby04 67e1fee4c5 Fix everything about the sort by tag list 2020-09-15 23:16:49 -04:00
Jobobby04 db70a62c8f Fix sort tag preference 2020-09-15 18:21:26 -04:00
arkon a4d3fa5878 Fix downloaded only filter
(cherry picked from commit 7641bb4d0d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
2020-09-15 18:18:33 -04:00
Jobobby04 a8aef554bd Migrate button tweak 2020-09-15 18:16:29 -04:00
Jay 2583be9923 Send manga/chapter/page details when sharing a chapter page
(cherry picked from commit 004e1c98ee)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
2020-09-15 18:16:06 -04:00
arkon 573768482f Tri-state library filters (closes #1814)
Based on https://github.com/inorichi/tachiyomi/pull/2127.

Co-authored-by: hXtreme <hXtreme@users.noreply.github.com>
(cherry picked from commit 687f3d48ea)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.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/widget/ExtendedNavigationView.kt
2020-09-15 16:29:44 -04:00
arkon 8df978a91c Clean up global chapter settings code
(cherry picked from commit da5f10a2f1)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt
2020-09-15 14:52:31 -04:00
lmj0011 763335bd85 [feature] add ability to set global filter/sort/display for Manga chapters (#3622)
* - [feature] add ability to set global filter/sort/display for Manga chapters

* - move default chapter settings functionality to overflow menu
- code clean up

* - show confirmation dialog when user selects "Set as Default" option in Chapter Settings

* - hide overflow menu in LibrarySettingsSheet

* - apply default chapter settings if manga is added to Library from a Source's browsing screen

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

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
2020-09-15 14:27:42 -04:00
arkon 4e8c30b7fe Start updating manga info view header design (SY edition)
(cherry picked from commit 791a7d5a01)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
#	app/src/main/res/layout/manga_info_header.xml
2020-09-15 14:08:14 -04:00
Jobobby04 07973bff32 Revert "Disable tag sorting for release"
This reverts commit 70bef08ed6.
2020-09-15 13:29:03 -04:00
Jobobby04 c69972f83a Revert "Hide dedupe by priority for release"
This reverts commit 92ae67630c.
2020-09-15 13:28:58 -04:00
Jobobby04 d05ea94d78 Revert "Hide parental controls section for release"
This reverts commit 02b90000f0.
2020-09-15 13:28:50 -04:00
Jobobby04 332a631b6c Release 1.3.1
Validate Gradle Wrapper / Validation (push) Successful in 13s
2020-09-15 13:21:37 -04:00
Jobobby04 70bef08ed6 Disable tag sorting for release 2020-09-15 13:03:15 -04:00
Jobobby04 de05f88d5f Fix Mangadex 2 factor auth
Fix Backups with merge manga breaking(I think)
Tweak preload settings, make the max 20, defaults to 10
Add tag based sorting
2020-09-15 13:00:40 -04:00
Jay 89427ff37e Send manga/chapter/page details when sharing a chapter page
(cherry picked from commit 32aea55f424d77e78be50f288996fe04053db009)
2020-09-14 21:15:40 -04:00
Jobobby04 63617f3079 Release 1.3.0
Validate Gradle Wrapper / Validation (push) Failing after 23s
2020-09-14 20:24:48 -04:00
Jobobby04 0f9f7ffc28 Cleanup 2020-09-14 14:36:56 -04:00
Jobobby04 9aab9d4ca4 Fix autofill exclusion 2020-09-14 14:06:48 -04:00
Jobobby04 92ae67630c Hide dedupe by priority for release 2020-09-14 12:47:54 -04:00
arkon 02b90000f0 Hide parental controls section for release
(cherry picked from commit 76c795d0d0)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsMainController.kt
2020-09-14 12:42:39 -04:00
arkon 6ed5d858aa Fix Kotlinter name typo
(cherry picked from commit b20bced3ca)
2020-09-14 12:40:58 -04:00
arkon 83bc059573 Fix Chinese plurals
(cherry picked from commit 4f2da9a78f)
2020-09-14 12:40:47 -04:00
Jozef Hollý ad39af55d6 Translated using Weblate (Bulgarian) (#3646)
Currently translated at 99.4% (574 of 577 strings)

Translated using Weblate (Filipino)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (French)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Croatian)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Sardinian)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Finnish)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Chuvash)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Malay)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (German)

Currently translated at 100.0% (577 of 577 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (French)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Finnish)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Malay)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (German)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translated using Weblate (Italian)

Currently translated at 98.9% (570 of 576 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (French)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Yakut)

Currently translated at 87.3% (503 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sah/

Translated using Weblate (Bulgarian)

Currently translated at 96.7% (557 of 576 strings)

Translated using Weblate (Chuvash)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Vietnamese)

Currently translated at 86.2% (497 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/vi/

Translated using Weblate (Japanese)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (German)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Arabic)

Currently translated at 95.4% (550 of 576 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Yakut)

Currently translated at 85.2% (491 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sah/

Translated using Weblate (Croatian)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Sardinian)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 99.6% (574 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Finnish)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Chuvash)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Hindi)

Currently translated at 99.3% (572 of 576 strings)

Translated using Weblate (German)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Filipino)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (576 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es_419/

Translated using Weblate (Greek)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Malay)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese)

Currently translated at 99.8% (575 of 576 strings)

Translated using Weblate (French)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Latvian)

Currently translated at 33.6% (194 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/lv/

Translated using Weblate (Arabic)

Currently translated at 91.8% (529 of 576 strings)

Translated using Weblate (Latvian)

Currently translated at 33.3% (192 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/lv/

Translated using Weblate (Latvian)

Currently translated at 33.3% (192 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/lv/

Translated using Weblate (French)

Currently translated at 99.8% (575 of 576 strings)

Translated using Weblate (Croatian)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 98.7% (569 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/

Translated using Weblate (Indonesian)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Croatian)

Currently translated at 99.4% (573 of 576 strings)

Translated using Weblate (Finnish)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Bengali (Bangladesh))

Currently translated at 0.5% (3 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/bn_BD/

Translated using Weblate (Filipino)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Japanese)

Currently translated at 97.7% (563 of 576 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (576 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sv/

Translated using Weblate (Turkish)

Currently translated at 99.8% (575 of 576 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Finnish)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Chuvash)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Hindi)

Currently translated at 99.1% (571 of 576 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Polish)

Currently translated at 96.8% (558 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pl/

Translated using Weblate (Malay)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Bengali)

Currently translated at 57.6% (332 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/bn/

Translated using Weblate (Bengali)

Currently translated at 57.6% (332 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/bn/

Added translation using Weblate (Bengali (Bangladesh))

Translated using Weblate (Yakut)

Currently translated at 80.2% (462 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sah/

Translated using Weblate (Russian)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Bengali)

Currently translated at 58.3% (336 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/bn/

Translated using Weblate (Sardinian)

Currently translated at 99.6% (574 of 576 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 98.0% (565 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Chuvash)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Filipino)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (576 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (576 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es_419/

Translated using Weblate (Finnish)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Indonesian)

Currently translated at 98.9% (570 of 576 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Chuvash)

Currently translated at 99.6% (574 of 576 strings)

Translated using Weblate (Malay)

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 90.4% (521 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nb_NO/

Translated using Weblate (Malay)

Currently translated at 99.8% (575 of 576 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (576 of 576 strings)

Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sv/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (576 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.8% (575 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.8% (575 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.6% (574 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.6% (574 of 576 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.4% (573 of 576 strings)

Translated using Weblate (German)

Currently translated at 100.0% (576 of 576 strings)

Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alessandro Jean <alessandrojean@gmail.com>
Co-authored-by: Alessandro Zangrandi <alessandro@mzit.it>
Co-authored-by: Alex <linuxrf@gmail.com>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Gabriel Lebis <gableb@hotmail.fr>
Co-authored-by: George <georgeramzy37@gmail.com>
Co-authored-by: Hara Desu <aqjbgr09@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: Kurocon <weblate@kurocon.nl>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matteo Gaeta <matteo.gaeta.1998@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Paulo Pinho <kebrus@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: RealKC <mitrut.e.super@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
Co-authored-by: Whod <whodizhod@gmail.com>
Co-authored-by: Yassin El Aoud <yassinelaoud@gmail.com>
Co-authored-by: darkbeast13 <nikhil15mps@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: İlle <derasetad@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/ca/
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/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/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/nl/
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/tr/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/uk/
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/
Translation: Tachiyomi/Strings

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: Alessandro Zangrandi <alessandro@mzit.it>
Co-authored-by: Alex <linuxrf@gmail.com>
Co-authored-by: Ava <Sasu.ruotsalainen@live.fi>
Co-authored-by: DarKCroX <darkcrox.2020@outlook.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Gabriel Lebis <gableb@hotmail.fr>
Co-authored-by: George <georgeramzy37@gmail.com>
Co-authored-by: Hara Desu <aqjbgr09@gmail.com>
Co-authored-by: Huang Zhiyi <hzy980512@126.com>
Co-authored-by: Kurocon <weblate@kurocon.nl>
Co-authored-by: Marco Santos <enum.scima@gmail.com>
Co-authored-by: Matteo Gaeta <matteo.gaeta.1998@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Paulo Pinho <kebrus@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: RealKC <mitrut.e.super@gmail.com>
Co-authored-by: Rostyslav <info@ubilling.net.ua>
Co-authored-by: Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
Co-authored-by: Whod <whodizhod@gmail.com>
Co-authored-by: Yassin El Aoud <yassinelaoud@gmail.com>
Co-authored-by: darkbeast13 <nikhil15mps@gmail.com>
Co-authored-by: monolifed <monolifed@protonmail.com>
Co-authored-by: İlle <derasetad@gmail.com>
Co-authored-by: Роман <Rozhenkov69@gmail.com>
(cherry picked from commit 8e0ba3650b)
2020-09-14 12:40:33 -04:00
arkon 8d5b2f40b3 Use Kolinter Gradle plugin for linting instead of ktlint directly
(cherry picked from commit 76f6fe4601)
2020-09-13 23:08:52 -04:00
arkon 49bee1af91 Update to Preivews new update checker, while keeping the SY repos and versions
(cherry picked from commit ca1373f36b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdateChecker.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubService.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubUpdateChecker.kt
2020-09-13 23:03:22 -04:00
Jobobby04 a48508a98e reader light theme chapters bottom sheet fixes 2020-09-13 22:52:11 -04:00
arkon 4e3288b2af Use background color for some lists
(cherry picked from commit c0789cd6ba)
2020-09-13 22:51:46 -04:00
arkon 0f16150613 Replace deprecated system window insets usage
(cherry picked from commit af47103707)
2020-09-13 22:24:06 -04:00
arkon 6dd7491ffe Remove list dividers
(cherry picked from commit c466baaa25)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDividerItemDecoration.kt
2020-09-13 22:24:06 -04:00
Jobobby04 02e6eaae12 Cleanup and fix a few compiler warnings 2020-09-13 22:24:03 -04:00
Jobobby04 73523dbff8 Remove Manga Plus delegation as it is not needed with the new extension update 2020-09-13 18:54:38 -04:00
Jobobby04 58a503814d Update firebase crashlytics 2020-09-13 18:46:14 -04:00
Jobobby04 7a834ea9f4 Mangadex tweaks, fix global update crashing sometimes 2020-09-13 18:45:57 -04:00
Jobobby04 dcca19e6b8 Undo Reds manga title changes 2020-09-12 19:21:54 -04:00
arkon 210fd000b3 Update OkHttp and Conscrypt
(cherry picked from commit 670294a427)
2020-09-12 13:51:55 -04:00
arkon 3d6f8ddd13 Update to Kotlin 1.4.10
(cherry picked from commit 21ddae6a86)
2020-09-12 13:51:55 -04:00
Andreas E a4578611d7 Always show missing chapter warning if there are missing chapters (#3755)
* Always show missing chapter warning if there are missing chapters

* Change function parameter names

(cherry picked from commit 9f260c3513)
2020-09-12 13:51:55 -04:00
Jobobby04 bb6932ff80 Mangadex follows, tell browse there are no more pages 2020-09-12 13:51:54 -04:00
AbdullahM0hamed 8dce9a674b Fix title on light theme (#101) 2020-09-12 13:51:19 -04:00
Jobobby04 b93298c411 Add MangaDex only implementation of Mangadex Follows list
Add login dialog that pops up whenever you are not logged in when trying to browse MangaDex
Remove attempts at porting over chapter read history from older galleries to new ones
Disable latest for ExHentai, it was browse without buttons anyway
2020-09-11 23:12:13 -04:00
Jobobby04 8928aa77eb Disable logging thread info, it wasnt very useful and made the log difficult to read 2020-09-10 20:27:49 -04:00
jobobby04 a6e6fa0099 Merge pull request #96 from AbdullahM0hamed/patch-1
Remove navigationBarColor from Black-Red theme
2020-09-10 18:43:46 -04:00
AbdullahM0hamed c23edd5b72 Remove navigationBarColor from Black-Red theme 2020-09-10 23:42:14 +01:00
AbdullahM0hamed c8a4ec37e0 Add Black-Red theme (#95)
* Appveyor

* stuff

* resolve conflict

* Let's try this again

* try again

* More fixing

* remove appveyor

* revert build.gradle

* Revert "revert build.gradle"

This reverts commit feaaa78157ffe8d6d6af7d6d63a74bc14b92f584.

* Undo line change

* Update build.gradle

* Update MainActivity.kt

Co-authored-by: AbdullahM0hamed<AbdullahM0hamed@users.noreply.github.com>
2020-09-10 17:06:49 -04:00
Jobobby04 f62d277894 Opps, forgot to push these changes 2020-09-08 12:04:53 -04:00
Jobobby04 b7efc21ea9 Update pt-rBR translation(curtsy of 0k//lux)
Change some gallery references to manga
2020-09-08 11:57:10 -04:00
Jobobby04 238b2d108d Cleanup 2020-09-06 22:43:58 -04:00
Jobobby04 bdaf0f7492 Fix exclusion in library search 2020-09-06 22:43:45 -04:00
Jobobby04 ced8dc750a Cleanup 2020-09-06 21:30:36 -04:00
Jobobby04 035fb9e755 Add biometric lock times 2020-09-06 21:30:22 -04:00
Jobobby04 86defec57c Fix latest + browse page crash when source returns null 2020-09-06 20:05:10 -04:00
Jobobby04 f20e5d864d Move from kizitonwose time to kotlin duration 2020-09-06 16:24:43 -04:00
Jobobby04 d83f938e07 Add a option to allow local source to read hidden folders 2020-09-06 00:31:08 -04:00
Jobobby04 b4e73cb1eb Upgrade the cleanup downloads to the new J2k version 2020-09-05 19:43:12 -04:00
arkon 604c7c703a Fix text alignment in transition view when no more chapters available
(cherry picked from commit b55d394a1f)
2020-09-05 19:20:53 -04:00
Andreas E 20021dbf54 Add spacing on top of sources/extensions/migrate lists (#3751)
(cherry picked from commit 5e2e177aa9)
2020-09-05 19:20:42 -04:00
arkon 281fb9c67b Refactor common chapter transition views into separate view
(cherry picked from commit 86e59977de)
2020-09-05 19:19:49 -04:00
arkon 7579bb026f Localize "No chapters found" error
(cherry picked from commit 66baf01e43)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2020-09-05 19:19:37 -04:00
Andreas E 61fb836be4 Add missing chapter warning (#3745)
* Add missing chapter warning

* Flip calculation instead of flipping variables

* Change logic

* Change tint based on reader theme

* Add missing chapter warning to WebtoonTransitionHolder

* Add chapter warning between current/finished and prev/next

* Fix mix up of TextViews

* Fix review comments

(cherry picked from commit 7a33e198dc)
2020-09-05 19:11:20 -04:00
scb261 d83361dfe3 Change sources sort to case-insensitive (#3743)
(cherry picked from commit 4b493ebbaf)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrationSourcesPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceFilterController.kt
2020-09-05 19:11:02 -04:00
arkon a5a79c1127 Remove unused string, fix improperly formatted Slovak string
(cherry picked from commit 565e8cf00b)
2020-09-05 19:03:58 -04:00
arkon 2f0f938d5e Update Conscrypt
(cherry picked from commit 738a3999b4)

# Conflicts:
#	app/build.gradle
2020-09-05 19:03:52 -04:00
arkon 750a6c3d11 Move share manga button to toolbar menu
(cherry picked from commit 8bedc8f456)
2020-09-05 19:02:48 -04:00
arkon b65305c73e Update dependencies
(cherry picked from commit d9000f6fd1)
2020-09-05 19:02:38 -04:00
Jobobby04 85ef1031b5 Display read progress on read chapters for E/Exhentai manga 2020-09-05 19:02:09 -04:00
Jobobby04 69c530dc34 Fix migrate to source with most chapters 2020-09-05 18:19:04 -04:00
Jobobby04 ea620a8c74 Probably fix previously read exh chapters affect updated gallery chapters 2020-09-05 18:18:39 -04:00
Jobobby04 1fdbae5bf8 Cleanup 2020-09-05 18:17:48 -04:00
Jobobby04 a1d54880c3 Merged manga implementation, man this took forever to make and bugfix, its not even done 2020-09-05 18:17:33 -04:00
Jobobby04 d21a652944 Remake the merged database, has support for future features 2020-09-04 17:31:35 -04:00
Jobobby04 444d346874 Probably make previously read exh chapters affect updated gallery chapters when loading the new version in the source 2020-08-25 02:09:15 -04:00
Jobobby04 41b8786415 Cleanup some mangatype logs 2020-08-25 02:07:40 -04:00
Jobobby04 d97805e38b Respect manga chapter order for reader chapter list, as well as fix page progress updating 2020-08-25 00:12:07 -04:00
Jobobby04 eafe3a62e4 Fix the bottom sheet and remove the bookmark button at the top of the reader 2020-08-24 19:25:47 -04:00
Jobobby04 0a502fcf31 Cleanup merged source code so I can modify it easier later on 2020-08-24 17:28:14 -04:00
Jobobby04 80960d87f2 Cleanup 2020-08-24 17:25:10 -04:00
Jobobby04 166aebdf25 Grab started filter from J2k 2020-08-23 21:59:43 -04:00
Jobobby04 b8836b9b6f Update firebase 2020-08-23 21:57:06 -04:00
Jobobby04 1d70f0b1dd Lint 2020-08-22 22:13:14 -04:00
Jobobby04 1240cc5232 Reader bottom sheet transparency, as well as a half fix for the fullscreen reader bug 2020-08-22 22:12:59 -04:00
Jobobby04 0abee585fc Some more cleanup to Save as CBZ 2020-08-22 18:41:42 -04:00
arkon 4870bb153d Filter out hidden directories for local source (closes #3706)
(cherry picked from commit fe7c7e72f5)
2020-08-22 18:19:33 -04:00
Jobobby04 f2b90bd772 Cleanup 2020-08-22 18:19:33 -04:00
arkon d77c65b515 Clean up X-Requested-With change
This only really affects the initial request, subsequent requests may still use the package name.

(cherry picked from commit 9920ff617b)
2020-08-22 18:17:48 -04:00
armangido 5004e2d62c Update WebViewActivity.kt (#3617)
This code added is for some extension that blocks tachiyomi, by tricking it that it was sent by a android browser, nothing major changes,

(cherry picked from commit 3f1355c413)
2020-08-22 18:17:37 -04:00
arkon 6e4a0ca1ea Update ActionMode styling
(cherry picked from commit 4929e66ecc)
2020-08-22 18:17:29 -04:00
arkon 883ffaa815 AndroidX dependency updates
(cherry picked from commit 4c31e3fc5f)
2020-08-22 18:17:08 -04:00
Jobobby04 3967a569c4 Cleanup Save as CBZ 2020-08-22 18:12:32 -04:00
Jobobby04 79e4e3d2a0 Add chapters bottom sheet for reader 2020-08-22 17:37:42 -04:00
Jobobby04 4b12e977c0 Cleanup some code 2020-08-22 17:37:42 -04:00
Fahad1998 4333999b85 Add Save As CBZ (#84)
Co-authored-by: Fahad1998 <f1998>
2020-08-22 17:37:03 -04:00
Fahad1998 fae290cf22 data saver fix (#85)
Co-authored-by: Fahad1998 <f1998>
2020-08-22 17:35:50 -04:00
Jobobby04 9ecf83f842 Delegate mangaplus so that it doesnt crash the app, it is literally just a copy of the extension with no extra features, but at least the app doesnt crash when you use it now 2020-08-21 16:27:01 -04:00
Jobobby04 f594962731 Cleanup 2020-08-21 15:32:42 -04:00
Jobobby04 048eecf655 Optimize and cleanup data saver 2020-08-21 15:32:29 -04:00
Fahad1998 90253f3bd4 Add Data Saver (#82)
Co-authored-by: Fahad1998 <f1998>
2020-08-21 13:50:08 -04:00
Jobobby04 0deb6f6b8d Finish some more advanced mangadex delegation features, more to come later 2020-08-20 20:50:37 -04:00
Jobobby04 294ade035e Rename LewdSource to MetadataSource to account for that Metadata will not always be for lewd sources 2020-08-19 18:45:56 -04:00
Jobobby04 64bb34b50d Delegate Mangadex (Part 1) 2020-08-19 18:20:05 -04:00
Jobobby04 9efb1482f9 Updated delegation system to account for custom headers 2020-08-19 18:19:22 -04:00
Jobobby04 aff15b3ee2 Remove library search log 2020-08-19 18:14:42 -04:00
Jobobby04 d86f3ffad8 Add a custom view change handler, makes it fade only one way 2020-08-19 02:08:58 -04:00
arkon 2a3eef0610 Don't enqueue bookmarked chapters for deletion (fixes #3691)
(cherry picked from commit 4c8665c9f0)
2020-08-18 22:32:06 -04:00
arkon 3b87111f22 Minor wording edit
(cherry picked from commit ba67781431)

# Conflicts:
#	app/src/main/res/values/strings.xml
2020-08-18 22:31:50 -04:00
arkon b654613345 Use core-ktx for bolding chapter transition text
(cherry picked from commit 4ef25c75b7)
2020-08-18 22:31:20 -04:00
arkon 136b25fb92 Dependency updates
(cherry picked from commit 3aafc671f8)

# Conflicts:
#	app/build.gradle
2020-08-18 22:31:00 -04:00
arkon f3875bda50 Update to Kotlin 1.4
(cherry picked from commit 967df6f7a3)

# Conflicts:
#	app/build.gradle
2020-08-18 22:29:54 -04:00
Jobobby04 c41148b465 Make animations smoother, add change handlers to bottom nav transactions, make animations go by their default value instead of a custom fast one 2020-08-18 22:23:39 -04:00
Jobobby04 eb0a1668f8 Made the ViewHeightAnimator duration configurable 2020-08-18 22:07:39 -04:00
Jobobby04 f7bc3e0a82 Cleanup some strings 2020-08-18 22:07:14 -04:00
Jobobby04 2e4def13e3 Add custom browese view, disabled by default and can be enabled in the settings
Signed-off-by: Jobobby04 <jobobby04@users.noreply.github.com>
2020-08-18 22:05:56 -04:00
Jobobby04 9e0e2db25d Add dynamic category library update upgrades 2020-08-18 18:55:00 -04:00
Jobobby04 20aa5b9aa1 Cleanup E-Hentai 2020-08-18 18:31:00 -04:00
Jobobby04 6ce4612aa7 Fix latest packages 2020-08-16 20:57:10 -04:00
Jobobby04 b51d147986 Cleanup 2020-08-16 20:47:09 -04:00
Jobobby04 bc896cf605 Make XLog display debug info in a debug build 2020-08-16 20:40:30 -04:00
Jobobby04 e48f274072 Updates and cleanup build.gradle 2020-08-15 23:01:16 -04:00
Jobobby04 a6b98e24dc Undo linting 2020-08-15 15:57:07 -04:00
Jobobby04 9a26a3e5a2 Revert "Slight gradle cleanup, plugin updates"
This reverts commit 08d11914af.
2020-08-14 18:54:34 -04:00
Jobobby04 eeb0f76cce Cleanup 2020-08-14 18:41:21 -04:00
Jobobby04 bcd36c8fad Add tap to move by page for continues vertical reader 2020-08-14 18:41:21 -04:00
Jobobby04 7f7b2901cb Convert autoscroll to a coroutine 2020-08-14 18:41:21 -04:00
Jobobby04 84b9b4db55 Cleanup 2020-08-14 18:41:21 -04:00
Jobobby04 a5c10dbf28 Add no title grid option 2020-08-14 18:41:21 -04:00
Jobobby04 5fee3ac05a Add a option to open the library bottom sheet in the library Settings 2020-08-14 18:41:21 -04:00
Jobobby04 d3603a664c Un-break XLog network logging, code contributed from Neko 2020-08-14 18:41:21 -04:00
Jobobby04 7ccaea0d72 Remove unused hitomi class 2020-08-14 18:41:20 -04:00
Jobobby04 921f7aad01 Make FAB disappear on image expand 2020-08-14 18:41:20 -04:00
Jobobby04 bc549c56d6 Automatic linting fixes 2020-08-14 18:41:20 -04:00
Jobobby04 b639e1e4d7 Delete my pull request tester in favor of previews 2020-08-14 18:41:13 -04:00
arkon 4f877820b2 Add PR build check action
(cherry picked from commit 19a7f37efa)
2020-08-14 18:41:13 -04:00
arkon c35e0a0c29 Unhide parental controls settings
(cherry picked from commit c3084ac43a)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsMainController.kt
2020-08-14 18:41:13 -04:00
TacoTheDank 08d11914af Slight gradle cleanup, plugin updates
(cherry picked from commit 159146e197)

# Conflicts:
#	app/build.gradle
#	build.gradle.kts
2020-08-14 18:41:13 -04:00
Jobobby04 309bd83730 Update gradle wrapper
(cherry picked from commit 67ddf4a5b8)
2020-08-14 18:40:55 -04:00
Taco 6b158cc864 Optimize images using ezgif (#3649) 2020-08-12 22:45:32 -04:00
Jobobby04 7d82be964c Add long click to copy on the special manga views 2020-08-12 22:34:20 -04:00
Jobobby04 525c3f84e4 Enable click to copy to clipboard in the more info 2020-08-12 22:32:13 -04:00
Jobobby04 ef37811020 Expand manga thumbnails 2020-08-12 21:10:39 -04:00
Jobobby04 0d033c7080 Cleanup some delegation code 2020-08-12 18:46:05 -04:00
934 changed files with 34771 additions and 16616 deletions
-33
View File
@@ -1,33 +0,0 @@
1. **Before reporting a new issue, take a look at the [FAQ](https://tachiyomi.org/help/faq/), the [changelog](https://github.com/inorichi/tachiyomi/releases) and the already opened [issues](https://github.com/inorichi/tachiyomi/issues).**
2. If you are unsure, ask here: [![Discord](https://img.shields.io/discord/349436576037732353.svg)](https://discord.gg/tachiyomi)
3. What is your type of issue?
* [Catalogue request](#catalogue-requests)
* [Bugs](#bugs)
* [Feature requests](#feature-requests)
* [Translations](https://tachiyomi.org/help/contribution/#translation)
4. After following 1. and 3. you can [open your issue](https://github.com/inorichi/tachiyomi/issues/new)
***
# Catalogue requests
* Catalogue requests should be created at https://github.com/inorichi/tachiyomi-extensions#readme, not here
# Bugs
* 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/inorichi/tachiyomi/issues/24 https://github.com/inorichi/tachiyomi/issues/71
DON'T: https://github.com/inorichi/tachiyomi/issues/75
# Feature requests
* Write a detailed issue, explaining what it should do or how. Avoid writing just "like X app does"
* Include screenshot (if needed)
+2 -2
View File
@@ -2,9 +2,9 @@
I acknowledge that:
- I have updated to the latest version of the app (stable is v1.2.0)
- I have updated to the latest version of the app (stable is v1.5.0)
- I have updated all extensions
- If this is an issue with an extension, that I should be opening an issue in https://github.com/inorichi/tachiyomi-extensions
- If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions
**DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT**
+2 -2
View File
@@ -9,9 +9,9 @@ labels: "bug"
I acknowledge that:
- I have updated to the latest version of the app (stable is v1.2.0)
- I have updated to the latest version of the app (stable is v1.5.0)
- I have updated all extensions
- If this is an issue with an extension, that I should be opening an issue in https://github.com/inorichi/tachiyomi-extensions
- If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions
**DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT**
+1 -1
View File
@@ -4,5 +4,5 @@ contact_links:
url: https://tachiyomi.org/help/
about: Common questions are answered here.
- name: Tachiyomi extensions GitHub repository
url: https://github.com/inorichi/tachiyomi-extensions
url: https://github.com/tachiyomiorg/tachiyomi-extensions
about: Issues about an extension/source/catalogue should be opened here instead.
+2 -2
View File
@@ -9,9 +9,9 @@ labels: "feature"
I acknowledge that:
- I have updated to the latest version of the app (stable is v1.2.0)
- I have updated to the latest version of the app (stable is v1.5.0)
- I have updated all extensions
- If this is an issue with an extension, that I should be opening an issue in https://github.com/inorichi/tachiyomi-extensions
- If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions
**DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT**
+3 -3
View File
@@ -1,8 +1,8 @@
---
name: "Extension/source/catalogue issue"
about: "Do not open an issue here. See https://github.com/inorichi/tachiyomi-extensions"
title: "THIS ISSUE IS IN THE WRONG REPO; SEE https://github.com/inorichi/tachiyomi-extensions"
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/inorichi/tachiyomi-extensions
DO NOT OPEN AN ISSUE IN THIS REPO. SEE https://github.com/tachiyomiorg/tachiyomi-extensions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 482 KiB

After

Width:  |  Height:  |  Size: 1.7 MiB

+28 -18
View File
@@ -1,24 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="svg8" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 172 172" style="enable-background:new 0 0 172 172;" xml:space="preserve">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1000 1000" style="enable-background:new 0 0 1000 1000;" xml:space="preserve">
<style type="text/css">
.st0{stroke:#CE2828;stroke-width:14;stroke-linecap:round;stroke-linejoin:round;}
.st1{fill:#F7D009;}
.st2{fill:#E40F85;}
.st0{fill:#232B30;}
.st1{fill:#2E84BF;}
.st2{fill:#CE2828;}
</style>
<title>sy_hobo_stds_mine</title>
<g id="layer1">
<path id="path4535" class="st0" d="M85.3,7C129,6.6,164.6,41.7,165,85.3c0.4,43.6-34.7,79.3-78.3,79.7C43.1,165.4,7.4,130.3,7,86.7
c0-0.5,0-0.9,0-1.4C7.4,42.2,42.2,7.4,85.3,7z"/>
<g id="text4543">
<path id="path4545" class="st1" d="M76,64.2c2.9,0,8.4-9.4,8.4-12.5S73.5,40.7,58.2,40.7c-21.4,0-27.4,15-27.4,23.8
c0,9.1,2.5,19.6,25.6,26.6c6.1,2,15.6,5.1,15.6,12.8c0,6.5-6.9,9.9-15,9.9c-22.6,0-20.9-21.3-22.6-21.3c-1.1,0-6.4,5.1-6.4,14.2
c0,16.7,15.2,24.7,30.1,24.7c22.3,0,31-15,31-27.2c0-9.9-4.5-20.7-26.7-28.1c-5.8-2-16.2-4.8-16.2-12.5c0-6.2,6.8-8.8,12-8.8
C69.2,54.8,73.3,64.2,76,64.2L76,64.2z"/>
<path id="path4547" class="st2" d="M95.4,128.7c0,1.4,1.1,2.6,2.6,2.6c23.2,0,47-29.8,46-60.7c0-4.5,0.3-7.9-1.7-8.2h-9.4
c-1.2,0-3.8-0.3-3.8,1.4s1.2,6.2,1.2,11.3c0,8.2-2.8,21-7.1,21c-2.1,0-12.4-11.6-12.4-24.1c0-3.1,1-6.2,1-7.9c0-2-2.3-1.7-3.7-1.7
h-8.6c-4.1,0-4,0-4,4.8c0,29.5,18.3,36.8,18.3,41.4c0,1.1-3.1,5.1-15.3,5.1c-2.8,0-3.1,3.1-3.1,4.3L95.4,128.7z"/>
</g>
<g id="Calque_2">
<path class="st0" d="M304.4,891.3h391.2c107,0,194.5-87.5,194.5-194.5V305.6c0-107-87.5-194.5-194.5-194.5H304.4
c-107,0-194.5,87.5-194.5,194.5v391.2C109.9,803.8,197.5,891.3,304.4,891.3z"/>
</g>
<g id="Calque_1">
<path class="st1" d="M474.4,242.2c115.3-1.4,144.2,48.2,185.2,74.7c21.6,8.3,17.7,16.3,26.2,28.7c2.5,3.5,5.5,5,9.5,7.5
c30.3,18.2-10.8,39.6-28.2,40.3c7.1-4.6,13.2-5.9,17.7-12.4c-0.3,0-0.6,0-0.9,0c0-0.3,0-0.6,0-0.9c-14.6-4-13.3,8.8-29.2,6.2
c3.5-0.4,12.6-5.8,12.4-13.3c-11.9-7.2-31.6-15.2-46.9-14.2c-0.1,0.4-0.1,0.4-0.2,0.8c36.3,24.2,25.7,57.3,47.1,63.8
c-11.6-0.5-5.9,2.1,0,7.1c-14.6-3-16.1-19.2-23-33.6c-7.8-12.9-15.4-28.5-23.9-29.2c-2,9.2,2,56.4,14.7,46.6
c-10,12.3,4.4,7.2,11,4.7c-23.9,19-35.1,13.8-42.8-13.8c-6.2-13.4-14.6-34.2-19.5-46.6c-2.8-7.1-7.5-13.3-13.6-17.9
c-41.8-31.2-72.8-33.3-116.9-26.1c-11.1-21.4-27.5-40.4-38.9-61.9C435,247.7,452,242.4,474.4,242.2z"/>
<path class="st1" d="M313.4,336C395.3,494.3,482,442.7,607.1,502.8c109.3,67.9,83.8,212.8-30.1,257.7c0-28.3,0-56.6,0-84.9
c46.4-45.1,20.7-112.1-37.1-125c-68.8-15-145.6-29.5-191.7-62.5C298,450.3,286.6,386.8,313.4,336z"/>
<path class="st1" d="M424.8,690.6c0.1,25.4,1.9,53.9-0.9,77.8c-94.2-25.7-162.5-103.3-124.7-192.8c0,4.7,0,9.4,0,14.2
C307.8,650,359.3,682.6,424.8,690.6z"/>
</g>
<g id="Calque_3">
<path class="st2" d="M247,198l138.9,37.1L500,414.7l47.8-72.5c34.5,14.5,37,85.5,55.7,96.4l-23,34.5
C477,444.9,387.8,439.9,351.3,364.7C317.9,311.3,247.1,198.1,247,198z"/>
<path class="st2" d="M602.6,255.5c16.2,9.6,33.1,19.8,46.5,32.8c7.5,7.2,14.9,12.3,25.3,18.3c3.9,2.2,4.7,2.1,7.8,4.7L753,198
l-137.1,37.1L602.6,255.5z"/>
<path class="st2" d="M500.9,841l61.9-50.4l0.9-212.3c0,0-4.5-11.4-85.2-25.5c-17.1-3-29.7-7.2-29.8-7.2l-12.3-3.6l1.8,248.5
L500.9,841z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

@@ -0,0 +1,6 @@
org.gradle.daemon=false
org.gradle.jvmargs=-Xmx5120m
org.gradle.workers.max=2
kotlin.incremental=false
kotlin.compiler.execution.strategy=in-process
-25
View File
@@ -1,25 +0,0 @@
name: Pull Request Checker
on:
pull_request:
jobs:
apk:
name: Generate APK
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Get NDK
run: sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;21.0.6113669"
- name: Build Release APK
run: bash ./gradlew assembleDebug --stacktrace
- name: Upload APK
uses: actions/upload-artifact@v2
with:
name: TachiyomiSY-${{ github.sha }}.apk
path: app/build/outputs/apk/dev/debug/app-dev-debug.apk
@@ -4,38 +4,40 @@ on:
push:
branches:
- 'master'
repository_dispatch:
jobs:
ping-pong:
check_wrapper:
name: Validate Gradle Wrapper
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
with:
fetch-depth: '0'
- name: Set CISKIP flag to false
run: echo ::set-env name=CISKIP::'false'
- name: Set CISKIP flag if action has ci skip
if: contains(github.event.action, 'skip-ci') || contains(github.event.action, 'skip-ci') || contains(github.event.action, 'skip ci') || contains(github.event.action, 'ci skip') || contains(github.event.action, 'ci-skip')
run: echo ::set-env name=CISKIP::'true'
- name: Exho
run: echo env.CISKIP
- name: Clone repo
uses: actions/checkout@v2
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
preview:
name: Build app preview
needs: check_wrapper
if: "!startsWith(github.event.head_commit.message, '[SKIP CI]')"
runs-on: ubuntu-latest
steps:
- name: Clone repo
uses: actions/checkout@v2
- name: TAG - Bump version and push tag
uses: anothrNick/github-tag-action@1.17.2
if: github.event.action != 'pong' && env.CISKIP == 'false'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WITH_V: true
RELEASE_BRANCHES: master
DEFAULT_BUMP: patch
- name: PING - Dispatch initiating repository event
if: github.event.action != 'pong' && env.CISKIP == 'false'
run: |
curl -X POST https://api.github.com/repos/jobobby04/TachiyomiSYPreview/dispatches \
-H 'Accept: application/vnd.github.everest-preview+json' \
-u ${{ secrets.ACCESS_TOKEN }} \
--data '{"event_type": "ping", "client_payload": { "repository": "'"$GITHUB_REPOSITORY"'" }}'
- name: ACK - Acknowledge pong from remote repository
if: github.event.action == 'pong'
run: |
echo "PONG received from '${{ github.event.client_payload.repository }}'"
@@ -6,22 +6,42 @@ on:
- 'release'
jobs:
apk:
check_wrapper:
name: Validate Gradle Wrapper
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Clone repo
uses: actions/checkout@v2
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
build:
name: Build app
needs: check_wrapper
if: "!startsWith(github.event.head_commit.message, '[SKIP CI]')"
runs-on: ubuntu-latest
steps:
- name: Cancel previous runs
uses: styfle/cancel-workflow-action@0.5.0
with:
access_token: ${{ github.token }}
- name: Clone repo
uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Get NDK
run: sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;21.0.6113669"
- name: Cache Gradle packages
uses: actions/cache@v2
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
restore-keys: ${{ runner.os }}-gradle
- name: Copy CI gradle.properties
run: |
mkdir -p ~/.gradle
cp .github/runner-files/ci-gradle.properties ~/.gradle/gradle.properties
- name: Write google-services.json
uses: DamianReeves/write-file-action@v1.0
with:
@@ -31,22 +51,25 @@ jobs:
contents: ${{ secrets.GOOGLE_SERVICES_TEXT }}
# The mode of writing to use: `overwrite`, `append`, or `preserve`.
write-mode: overwrite # optional, default is preserve
- name: Build Release APK
run: bash ./gradlew assembleRelease --stacktrace
- name: Sign Android Release
- name: Build app
uses: eskatos/gradle-command-action@v1
with:
arguments: assembleRelease --stacktrace
wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true
- name: Sign APK
uses: r0adkll/sign-android-release@v1
with:
# The directory to find your release to sign
releaseDirectory: app/build/outputs/apk/standard/release
# The key used to sign your release in base64 encoded format
signingKeyBase64: ${{ secrets.SIGNING_KEY }}
# The key alias
alias: ${{ secrets.ALIAS }}
# The password to the keystore
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
# The password for the key
keyPassword: ${{ secrets.KEY_PASSWORD }}
- name: Create Release
- name: Create release
id: create_release
uses: actions/create-release@v1
env:
@@ -56,7 +79,8 @@ jobs:
release_name: TachiyomiSY
draft: true
prerelease: false
- name: Upload Release APK
- name: Upload APK to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+52
View File
@@ -0,0 +1,52 @@
name: CI
on: [pull_request]
jobs:
check_wrapper:
name: Validate Gradle Wrapper
runs-on: ubuntu-latest
steps:
- name: Clone repo
uses: actions/checkout@v2
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
build:
name: Build app
needs: check_wrapper
if: "!startsWith(github.event.head_commit.message, '[SKIP CI]')"
runs-on: ubuntu-latest
steps:
- name: Cancel previous runs
uses: styfle/cancel-workflow-action@0.5.0
with:
access_token: ${{ github.token }}
- name: Clone repo
uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Copy CI gradle.properties
run: |
mkdir -p ~/.gradle
cp .github/runner-files/ci-gradle.properties ~/.gradle/gradle.properties
- name: Build app
uses: eskatos/gradle-command-action@v1
with:
arguments: assembleStandardDebug
wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true
- name: Upload APK
uses: actions/upload-artifact@v2
with:
name: TachiyomiSY-${{ github.sha }}.apk
path: app/build/outputs/apk/dev/debug/app-dev-debug.apk
+5 -2
View File
@@ -1,5 +1,8 @@
name: Issue closer
on: [issues]
on:
issues:
types: [opened, edited, reopened]
jobs:
autoclose:
runs-on: ubuntu-latest
@@ -31,4 +34,4 @@ jobs:
repo-token: ${{ secrets.GITHUB_TOKEN }}
type: body
regex: ".*\\* (Tachiyomi version|Android version|Device): \\?.*"
message: "@${issue.user.login} this issue was automatically closed because the requested information was not filled out."
message: "@${issue.user.login} this issue was automatically closed because the requested information was not filled out."
-81
View File
@@ -1,81 +0,0 @@
dist: trusty
language: android
android:
components:
- tools
- platform-tools
- build-tools-29.0.3
- android-29
- extra-android-m2repository
- extra-google-m2repository
- extra-android-support
- extra-google-google_play_services
licenses:
- 'android-sdk-license-.+'
- 'android-sdk-preview-license-.+'
before_install:
- yes | sdkmanager "platforms;android-29" # workaround for accepting the license
- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
openssl aes-256-cbc -K $encrypted_e56be693d4fd_key -iv $encrypted_e56be693d4fd_iv -in "$PWD/.travis/secrets.tar.enc" -out secrets.tar -d;
tar xf secrets.tar;
mv debug.keystore "$HOME/.android";
fi
- mkdir "$ANDROID_HOME/licenses" || true
- echo -e "\n24333f8a63b6825ea9c5514f83c2829b004d1fee" > "$ANDROID_HOME/licenses/android-sdk-license"
- echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license"
install:
- echo y | sdkmanager "ndk-bundle"
before_script:
- export ANDROID_NDK_HOME=$ANDROID_HOME/ndk-bundle
script: ".travis/build.sh"
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- "$HOME/.gradle/caches/"
- "$HOME/.gradle/wrapper/"
- "$HOME/.android/build-cache"
deploy:
- provider: releases
api_key:
secure: qmS9SyMq8xPDqaY83rvAFyZcvic24lGBj3MFt22RhVJzIXAAN/vqL1R70PnNiCF7CE+R7PaDlBpwjxDMBiuh0QQNc1oX6cgepUbro4/Nt7NFFfCvKXaFdR1cSgYouhuHmy0SS0/alrcfhQ2bPwcm1/vAOiSa8Wu7hsXhCcxbFyEbXZVD11QZmiffEM0py+OeuqOFo2JxZaGRu2z04E/u5TWep1ZEuhFRCC87PGgFqABgg6jYYebQOUZADG/0G8581HTGU0mdwueYsiA35ncRzpV2V8DajEEBd5wOe5d8SyMtE+6Qs5PD9KcXAqGGe4QRmrJMX5EcLQaLZf/Qd5s9SFZVHb1aJIw/y05w4L5dlVpsjx5WuUAYAVg7Ol5UawofFo/hYkYCNmfub67wJQdHSIxPif7V6YeON6RQQMpc5GBYY9eA6ZxhrdA2m7eyoOT3jcbdaVJwC0jMGhn26hkgJfTo1LfAUs85Cs3BrK8w6Poqc/Jb+4Y0NhdGIKgO5tS3vY54cTJVVrQTq4/XmME4ZnzOX3HaOqzfyt/6M4gEQMvaeFksxwoFhocV7wfaCq9ps/Kdq2dl4KwoqRV2WqVaauqzCP4XPSlVLaJqztsw0wboupcaZepWJ2a/6j9IrKo1pEnyeHF5y+k0SUAxL0X8iKZ0uPxsgoVrlNtqXJWNGvA=
file: tachiyomi-v*.apk
file_glob: true
skip_cleanup: true
on:
tags: true
repo: inorichi/tachiyomi
- provider: script
script: ".travis/deploy.sh"
skip_cleanup: true
on:
branch: master
condition: "-z $TRAVIS_TAG"
repo: inorichi/tachiyomi
- provider: script
script: ".travis/deploy.sh"
skip_cleanup: true
on:
branch: dev
condition: "-z $TRAVIS_TAG"
repo: inorichi/tachiyomi
env:
global:
- secure: Ita1+tzo7P5IC2yqU3KgRcXt+5DTpP0103Hx/ECYi42/7rLt+TC7PMjl2yH3Z189+tGwLq0Ol1KJ2Z5Rn3q7EaQgD0+WRkH/ijtrjKoVh7dyItIBp7yowZpA0TJHQ4EZpGSxZakKbIP4di8XMxJ2+5VzEivYUt04LCUpzugemL6b6XOfUmOZykVxV2UDAlPPggklITYBXkHUa0mwJhjS1aPPeeR3PhVXomkqfuOJOKejPXXXJope9fhAnmopHA7ISfjIrTuwDVQJqNSuco+O9kQShmlu0C8pob1vFGPEDvafaDS8SZ9A6gKT1ZfgSUqVmvDbx0WLX8XugBLrQedtZv63esOa1WUyGhgFVpeJjexlszXlhyfP1gH5QbzRr+EiSaagCyjf9II2veLAtU5cFY+nj6KBdKQsazIMRHf8SAQlWASyJYMED/N9RnUFxSf1rnLGqiY2ezjycx4ieFj7vhlbTgyao1GHjjR9cwNuntdMYWhY8+Vc7Fctmzm46xOyyz9oJGdyim76Y4w4MZvQNKeZOBAjdEgX6cXBk15scoM2Vj9ENox+MKZLaKRawXg2U1ujK+bWAQkXiVvPriv05/JtYsNUft8qAsm+69vtohDsUW7Wu0bBIKDL+v0W30ty1PpyNehBB2OquUE7fp53gitOmYl7TyuxktkMY8PXKKU=
- secure: NABCfigMUVM/9TLALYBpQLp/p3rG6MbH5y34/oqCSej/oh2u0nyhFSi8veS0lFpDIcv0TZvxHJXoSA0zeZijb1fUU8jYVNT2azuPWE6Gu7sf0TfBeCvulqbgLMoaA6JuWbEbZwHcxpKHg4vLSMjNk+ZP4v2dffI6A620fxLltxxhTpsYkYYsfKG857CpQtdgN/HqcOaxyvzXFmWWyVWHala1uMcMeXZCwgnlVAqau9o0bsU092txSmHqoesHoAinidSCTCmTlEqp/1AFaYQTbxmnfNC1yLgzxWAlJcS3NWzNo3ellMvKjsiIGn3JJpAjTGcyf3yPsvhs1cY3MZbmJYVyKH5HbnkA5ms6mx0DDJ2UOs5H2dmED82m14+hu62Xb8XN8zAdq+bySNSwgsGzvr1PT74pT4BW1T+D7L1xvUe6k1enZ38GIMJbJPhBybRQazhjKPmXRB30Thxoqe5VqU8UeiXHAEps7JYAWUR1PLZvEYQb6MWurmTxs9be/OTwrUT1LDiqeJZg6XkDGgQwuR2YBaQJHJD17Piq6q1BUX8abhK6wzAAYVqyGvpmUCmQCtHZgenE6ulwcKChzBv4n97OjE21LGWnbNF5ViUhfAbGcKOVufd1chZsfbkJ7a3tHYCfLnxHUIhKvHk26f5Em8h68D0wQkPnkcVVkfh7XpI=
- secure: C93UADV5aR0zhLCLwR6tCyz+fwUYslZbhjBl3PHQp+0boIGS/Be2UQTFHp/NB9mQmhWqbwqHoAVFENZFytV04ePgOuNtMFcjAIfnzm19Am7iRAMFixD45pF/CuYYfLupElkAcSequtAzN0g4G0sQ5KR1hibaDIoz9kfA2YcUAMaZ4T5bhCr8os/xA2nOlmvPDWsRWCFBYkSpnmbsSsgYAhulA/V5bSNAWnp9LPw3CBLibW3WsVP4wuhZAkXznKwn/mHT31kfQlpMH3qNhXpsN9huUkZ/k8QWeakcHJKugung0Z2T1StK8rlI8OrJstVcwueHTa2ses4f5VbhWog/Z8HDkdll9W9RM/QqXjNDtOVBt/SPuhCp4k2rvJixFUxzvSqgSWQvQnbHwjWxIUVVyHtnb0/zc/S9ONZG14TOwB/+Lkgacb85PNszurZ2f3mH0O6slIh1mH+5d9J4+L976ot4nTPlK1OtothagVyKGOrn9HycrPk/MjftIJuElHzo7NEJd/wRPqIb5y12iZN1RSPriU+itg1uSAVP891/o3peJyuqY9WSB7dYwgDJos6dDvbr19emtdyxkQR+eAb5duyH6s4R58wh1kJ1d4zu0X6uSnF4AIc+6teKkN24rSXcqB/hrcojS49jgLy5P0/CVsUbYZPI/tx8E/IJfr8m36E=
- secure: mawwBvllvESc/mp+JHvncq1iUhiC7nyokPgXmOehffc0K3byMLs2L25HjNsU6EnXG9Lcae1cfP8S9bWLquU2C3kpAkLBUpjEbdx7K0654uvs7Rrvb5hcTRHwjzaEVmVaBFX4ROcjUhBYny/Wjj/YENCkSWpkfcMd1esFbVsO+fOLyaAPvrb6auKY7H+pUSqlEwaEnrkYeBBZIHa7KqwL4g5DHbq6K368tjmval/wBzwMB0V8V3dt/ik8RMVDtKPrik4Bu0V9UmXZUIo/a06ii/CM82ekFRh3eUb0DKkdkmYbdH6MBMoLTfQtMa6A4luXaA0oycAnTX3OGB5MWIjK39KhWRavh6ybSIt4aHKoolxzH8Zgmk7xMhFSot/laX5q5IzjZu5KU6F2SmdV0kcQugM8oAjANFySetPvY1q7nZ8pM+NO1xKS/mH0w4vChhdJFD1mw7aCoh8FdeUf0Eym2+pp5Q9uAisWMmNn5XN8/fL5q6PzAxkXmkedfrr1N61FmIL6EKx8qiWpOUNlRRTIMJ4GMhCyckCF6cNxDkBItp52c+Hmkbn+ZEInEyX6gpjYVm3xyEi0Z5kLCi/fMX2nBNczc5BuGLzzmJnITv4ovpeYn2/vPvHbaPgPC4LqDK3AjlpVadMZk/M5Egn+hWY7Mni57CmpZD+SpxUbbsItI0c=
- secure: PJPDkUg1zc57brxUvNpSh+Q3ZEaGpBqZzwDavqslkn0WmjBTLrE6/OG7TFHKNmO+P56qFl+pMEKqThxqR3+4bWEeEx8ykkixDVzxNJMmws+7A7ImJ75iQyB6giMW/4tykVMMHgIPNAdcnI8VOWn0LGHnpFWUd70yoyAGX8s6cspHCKgcuWMA3GS410KJfHpyd0B9/QS7ZyWzSETW7zSPyLPa81SBO95EhOF3TOGZYLt/mBhdtU3YGFs4k9fZ8jDDcm9XmBfqVlUhb8HiZcxJiZDdRvxODERfNnwc47uaJk6+kxGDzIW2uAxrMXXVKkG04GeMOokXoR9kW1Hl2JmoyySLKLZmB7I/XEtVWdzZw16mWi+4zmhjLhfB0phSW+/5I+0VtZZ6jO031J5FL/JqVrcq1ws/aw4QlaOdPUco/x2u4LNHyYYgOi5arD9xSyu6IRy0jCC4Xa1zuqM5adGJX+rZyVfKZ0TxOW661HTxlo8COtkB2i0WR2deZGVN75ooCAEO8DauQoUcFH1OelahmPtzVs1/6ZczuxGdp9ED7ZQq9NHEOsOdUGCj/D79Dm1hWFQsIsslnnGYWitAycNCgEwmlt2Q6fbrv2CJrmLqZ9a9r3AhzxoHn9Qx1GyuyfhZJzm/6Ff2kcOjma2kcz13KUwTxdW+2G5dDCotK3f7aiI=
- secure: FIIZfEEYfjNMKODs33Czh603CYVn6LRrzpFNIiPHYTb8iQWv9qAYhsg4FpHfOjDikokTwb5X/h8G7AX93Z0xKyyDi75ACT11oPeTNTArDdcmdDVlOYBvYHc2Ci7pMW5r8LGejB7Y3mWM8uKyA3oKvneEFutB65vO3JVZvFWrm03Lmqqe7+mA4qNqNqTbN7R7fmk5b7zt7A3DHvDu0JPTbSSUwpso/p2I5WJYjrf71I7YMQwIFLoMfplC1onVA3EFS3lZsF65zE+xVRy34AKa41iZAMbhVDyqUHEnx6L0dwEdn2Z5XLlK0ov1+qLTLlQsBE4Knre6TNkWMfktk7MKA+ch8RYxvEYLODhQkIrOkLSNWhZPhdaT+xD4fr0RCKSHo6uWRC4aofsJx8wSqb8ZL4j2zopUp9VisMOI202UEnvFDBtOkVGJSxxYbFjifIB7NCJBn788w+3k+k4IbOg537VdyoK2PMBR8/TDdjImWhWHY1i7+345ejwmzHL7ZPfb6GTNnQTWkajT77/n6Yk41twR5vvegOSTKuuO++WN/pUks4PGqtcQe9fnSfx2OcOq1ofLiG+JDorJ7z8kHSG13wHLq+QYMDayQbyJEYpDzmn/w3Ou1s2o0a7A41+cIkRzAgH9y3v4lgjp9GcMP2S74ZPA7OecWbFSexM7tL/dYxY=
- secure: DKCGc4E9PKeTX68r9pbbNg5qITsN0bApQ1m0x8xdEoi8GLRKVMYNn6ahoAxvy1YsBXC9Zlt5++gLmUV1I1JyDMyJXMr/lZrp4oarW0xWpTBmn3HzOph/K2W4i/fTGgMFieumPEbQIFOnU3JSjK6UJB8qVGEXD2OqS7A//EdrGDbAYVDL3ZTKE6JUlTNHgaKaNHhn+Dq4aBLTSYPwlLyqo+WNBVUUCKCHOq62ULF8MpX5YGaPFNxKYzircV7HpF1hCbV31dmpkeYT9xztra5V0SIBM27jAcQqGmtHH2mhx1sLu+gjhFJbbtY6cggA9EedzYYLDx/NPmgfyuOJfyVbSwTF3vhDUYfskqc1THWpwOSKO0Ry+8/xYb9crxg+FSwuI5hnfkIFk9woBvRGBhjto3/1buMNY9dSFiWtEbN6Let8e747l0wIGJCpJxSeh7vn7F1mWjixhf9GX1+V9BrUvGTd3XJDNb9cVnafYa1RTj8BLteA4HBza7Z9R3dvG4YWp16L/94UuaTzgAQfERLTZGopQth/hsaVTlYesJmJLF70lGM+W83y3YuNkSaX1zQ5FAIvp7oH0O16t7ISm6GprUFwN2Uox7AAbPZdWHxJbly+D+yCFNcqS3Bz9mV3YCLo690Sy1ePNHr+nCseVfBMo7OYyavSS/EjPWfEy65Wq04=
+34
View File
@@ -0,0 +1,34 @@
Looking to report an issue/bug or make a feature request? Please refer to the [README file](https://github.com/tachiyomiorg/tachiyomi#issues-feature-requests-and-contributing).
---
Thanks for your interest in contributing to Tachiyomi!
# Code contributions
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.
# Translations
Translations are done externally via Weblate. See [our website](https://tachiyomi.org/help/contribution/#translation) for more details.
# Forks
Forks are allowed so long as they abide by [the project's LICENSE](https://github.com/tachiyomiorg/tachiyomi/blob/master/LICENSE).
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)
- 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:
- If you want to use Firebase analytics, replace [`google-services.json`](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/src/standard/google-services.json) with your own
- If you want to use ACRA crash reporting, replace the `ACRA_URI` endpoint in [`build.gradle.kts`](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/build.gradle.kts) with your own
-26
View File
@@ -174,29 +174,3 @@
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+31 -31
View File
@@ -4,14 +4,14 @@
# ![app icon](./.github/readme-images/app-icon.png)TachiyomiSY
Tachiyomi is a free and open source manga reader for Android 5.0 and above. This version of Tachiyomi, TachiyomiSY was based off TachiyomiAZ. TachiyomiAZ has decided to keep the old UI of the app, this version is meant to push forward in the ways of UI and usability, doing that it takes the new Tachiyomi(original) UI. TachiyomiSY also includes a lot of the up in coming features of the Tachiyomi Preview, as well as features from other forks like J2K, it has quite a few custom features from myself and contributors as well.
Tachiyomi is a free and open source manga reader for Android 5.0 and above. This version of Tachiyomi, TachiyomiSY was based off TachiyomiAZ. This version is meant to push forward in the ways of usability and features. TachiyomiSY tries to push forward where it can, but staying in a place where it can easily grab updates and features from the main app, it tries to make new features, or take features from other forks like J2K and Neko.
![screenshots of app](./.github/readme-images/screens.png)
## Features
Features of Tachiyomi(original) include:
* Online reading from sources such as MangaDex, MangaSee, Mangakakalot, [and more](https://github.com/inorichi/tachiyomi-extensions)
* Online reading from sources such as MangaDex, MangaSee, Mangakakalot, [and more](https://github.com/tachiyomiorg/tachiyomi-extensions)
* Local reading of downloaded manga
* 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
@@ -21,55 +21,50 @@ Features of Tachiyomi(original) include:
* Create backups locally to read offline or to your desired cloud service
Features of TachiyomiSY include:
* Uses the new Tachiyomi Stable UI
* Latest tab, store up to 5 sources where you can easily view the latest manga by viewing the tab
* Hentai features enable/disable, in advanced settings
* Automatic webtoon detection, allowing the reader to switch to webtoon mode automatically when viewing one
* Recommendations, from AZ but heavily modified by She11Shocked to use both MAL and Anilist interchangeably
* Manga recommendations, uses MAL and Anilist, as well as Neko Similar Manga for Mangadex manga(Thanks to Az, She11Shocked, Carlos, and Goldbattle)
* Lewd filter, hide the lewd manga in your library when you want to
* Tracking filter, filter your tracked manga so you can see them or see non-tracked manga, made by She11Shocked
* Search tracking status in library, made by She11Shocked
* Backup saved searches
* New E-Hentai/ExHentai features, such as language settings and watched list settings
* Comfortable grid view
* Custom categories for sources, liked the pinned sources, but you can make your own versions and put any sources in them
* Manga info edit
* Enhanced views for internal and integrated sources
* Enhanced usability for internal and delegated sources
* Manga Cover view + share and save
* Dynamic Categories, view the library in multiple ways
* Smart background for reading modes like LTR or Vertical, changes the backgorund based on the page color
* Smart background for reading modes like LTR or Vertical, changes the background based on the page color
* Force disable webtoon zoom
* Continue reading button in library
* Hentai features enable/disable, in advanced settings
* Quick clean titles
Inherited from TachiyomiAZ or TachiyomiEH and are included and possibly modified in TachiyomiSY
* Source migration, migrate all your manga from one source to another
* Custom hentai sources:
* * E-Hentai/ExHentai
* Additional features for some extensions, features include custom description, opening in app, batch add to library:
* * 8Muses (EroMuse)
* * HBrowse
* * HentaiCafe (Foolside)
* * Hitomi.la
* * NHentai
* * PervEden (EN and IT)
* * Puruin
* * Tsumino
* Saving searches
* Autoscroll
* Page preload customization
* Customize image cache size
* Batch import of custom sources and featured extensions
* Automatic CAPTCHA solving
* TriState Filters
* Infinite history page
* Search your history page
* Advanced source settings page, searching, enable/disable all
* Click tag for local search, long click tag for global search
* Merge multiple of the same manga from different sources
* Drag and drop library sorting
* Library search engine, includes exclude, quotes as absolute, and a bunch of other ways to search
* New E-Hentai/ExHentai features, such as language settings and watched list settings
* Enhanced views for internal and integrated sources
* Enhanced usability for internal and delegated sources
Custom sources:
* E-Hentai/ExHentai
Additional features for some extensions, features include custom description, opening in app, batch add to library, and a bunch of other things based on the source:
* 8Muses (EroMuse)
* HBrowse
* HentaiCafe (inside Foolside)
* Hitomi.la
* Mangadex
* NHentai
* PervEden (EN and IT)
* Puruin
* Tsumino
## Download
Get the app from our [releases page](https://github.com/jobobby04/tachiyomisy/releases/latest).
@@ -82,7 +77,7 @@ Please make sure to read the full guidelines. Your issue may be closed without w
<details><summary>Issues</summary>
1. **Before reporting a new issue, take a look at the [FAQ](https://github.com/inorichi/tachiyomi/wiki/FAQ), the [changelog](https://github.com/jobobby04/tachiyomisy/releases) and the already opened [issues](https://github.com/jobobby04/tachiyomisy/issues).**
1. **Before reporting a new issue, take a look at the [FAQ](https://tachiyomi.org/help/faq/), the [changelog](https://github.com/jobobby04/tachiyomisy/releases) and the already opened [issues](https://github.com/jobobby04/tachiyomisy/issues).**
2. If you are unsure, ask here: [![Discord](https://img.shields.io/discord/349436576037732353.svg)](https://discord.gg/tachiyomi)
</details>
@@ -98,9 +93,9 @@ Please make sure to read the full guidelines. Your issue may be closed without w
* For large logs use http://pastebin.com/ (or similar)
* Don't group unrelated requests into one issue
DO: https://github.com/inorichi/tachiyomi/issues/24 https://github.com/inorichi/tachiyomi/issues/71
DO: https://github.com/tachiyomiorg/tachiyomi/issues/24 https://github.com/tachiyomiorg/tachiyomi/issues/71
DON'T: https://github.com/inorichi/tachiyomi/issues/75
DON'T: https://github.com/tachiyomiorg/tachiyomi/issues/75
</details>
@@ -109,7 +104,12 @@ DON'T: https://github.com/inorichi/tachiyomi/issues/75
* Write a detailed issue, explaining what it should do or how. Avoid writing just "like X app does"
* Include screenshot (if needed)
Catalogue requests should be created at https://github.com/inorichi/tachiyomi-extensions, they do not belong in this repository.
Source requests should be created at https://github.com/tachiyomiorg/tachiyomi-extensions, they do not belong in this repository.
</details>
<details><summary>Contributing</summary>
See [CONTRIBUTING.md](https://github.com/tachiyomiorg/tachiyomi/blob/master/CONTRIBUTING.md).
</details>
## FAQ
-393
View File
@@ -1,393 +0,0 @@
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import java.text.SimpleDateFormat
apply plugin: 'com.android.application'
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'com.github.zellius.shortcut-helper'
// Realm (EH)
apply plugin: 'realm-android'
shortcutHelper.filePath = './shortcuts.xml'
ext {
// Git is needed in your system PATH for these commands to work.
// If it's not installed, you can return a random value as a workaround
getCommitCount = {
return 'git rev-list --count HEAD'.execute().text.trim()
// return "1"
}
getGitSha = {
return 'git rev-parse --short HEAD'.execute().text.trim()
// return "1"
}
getBuildTime = {
def df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'")
df.setTimeZone(TimeZone.getTimeZone("UTC"))
return df.format(new Date())
}
}
android {
compileSdkVersion AndroidConfig.compileSdk
buildToolsVersion AndroidConfig.buildTools
defaultConfig {
applicationId "eu.kanade.tachiyomi.sy"
minSdkVersion AndroidConfig.minSdk
targetSdkVersion AndroidConfig.targetSdk
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
versionCode 6
versionName "1.2.0"
buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\""
buildConfigField "String", "COMMIT_SHA", "\"${getGitSha()}\""
buildConfigField "String", "BUILD_TIME", "\"${getBuildTime()}\""
buildConfigField "boolean", "INCLUDE_UPDATER", "true"
multiDexEnabled true
ndk {
abiFilters "armeabi-v7a", "arm64-v8a", "x86"
}
}
buildFeatures {
viewBinding = true
}
buildTypes {
debug {
versionNameSuffix "-${getCommitCount()}"
applicationIdSuffix ".debug"
ext.enableCrashlytics = false
}
releaseTest {
applicationIdSuffix ".rt"
// minifyEnabled true
// shrinkResources true
zipAlignEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled true
shrinkResources true
zipAlignEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
flavorDimensions "default"
productFlavors {
standard {
buildConfigField "boolean", "INCLUDE_UPDATER", "true"
dimension "default"
}
fdroid {
dimension "default"
}
dev {
resConfigs "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'
}
dependenciesInfo {
includeInApk = false
}
lintOptions {
disable 'MissingTranslation'
disable 'ExtraTranslation'
abortOnError false
checkReleaseBuilds false
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
}
androidExtensions {
experimental = true
}
dependencies {
// AndroidX libraries
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.appcompat:appcompat:1.3.0-alpha01'
implementation 'androidx.biometric:biometric:1.0.1'
implementation 'androidx.browser:browser:1.2.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-rc1'
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
implementation 'androidx.core:core-ktx:1.4.0-alpha01'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha05'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01'
final lifecycle_version = '2.3.0-alpha06'
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
// Job scheduling
final work_version = '2.4.0'
implementation "androidx.work:work-runtime:$work_version"
implementation "androidx.work:work-runtime-ktx:$work_version"
// UI library
implementation 'com.google.android.material:material:1.3.0-alpha02'
standardImplementation 'com.google.firebase:firebase-core:17.4.4'
// ReactiveX
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'
// Network client
final okhttp_version = '4.8.1'
implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
implementation "com.squareup.okhttp3:logging-interceptor:$okhttp_version"
implementation "com.squareup.okhttp3:okhttp-dnsoverhttps:$okhttp_version"
implementation 'com.squareup.okio:okio:2.7.0'
// TLS 1.3 support for Android < 10
implementation 'org.conscrypt:conscrypt-android:2.4.0'
// REST
final retrofit_version = '2.9.0'
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
implementation "com.squareup.retrofit2:adapter-rxjava:$retrofit_version"
// JSON
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'
// Disk
implementation 'com.jakewharton:disklrucache:2.0.2'
implementation 'com.github.inorichi:unifile:e9ee588'
implementation 'com.github.inorichi:junrar-android:634c1f5'
// HTML parser
implementation 'org.jsoup:jsoup:1.13.1'
// [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'
// Database
implementation 'androidx.sqlite:sqlite:2.1.0'
implementation 'com.github.inorichi.storio:storio-common:8be19de@aar'
implementation 'com.github.inorichi.storio:storio-sqlite:8be19de@aar'
implementation 'io.requery:sqlite-android:3.32.2'
// Preferences
implementation 'com.github.tfcporciuncula:flow-preferences:1.3.0'
// Model View Presenter
final nucleus_version = '3.0.0'
implementation "info.android15.nucleus:nucleus:$nucleus_version"
implementation "info.android15.nucleus:nucleus-support-v7:$nucleus_version"
// Dependency injection
implementation "com.github.inorichi.injekt:injekt-core:65b0440"
// Image library
final glide_version = '4.11.0'
implementation "com.github.bumptech.glide:glide:$glide_version"
implementation "com.github.bumptech.glide:okhttp3-integration:$glide_version"
kapt "com.github.bumptech.glide:compiler:$glide_version"
implementation 'com.github.tachiyomiorg:subsampling-scale-image-view:bff2806'
// Logging
implementation 'com.jakewharton.timber:timber:4.7.1'
// Crash reports
//implementation 'ch.acra:acra-http:5.7.0'
// Sort
implementation 'com.github.gpanther:java-nat-sort:natural-comparator-1.1'
// UI
implementation 'com.dmitrymalkovich.android:material-design-dimens:1.4'
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.nononsenseapps:filepicker:2.5.2'
implementation 'com.nightlynexus.viewstatepageradapter:viewstatepageradapter:1.1.0'
implementation 'com.github.mthli:Slice:v1.3'
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
implementation 'com.github.carlosesco:DirectionalViewPager:a844dbca0a'
// 3.2.0+ introduces weird UI blinking or cut off issues on some devices
final material_dialogs_version = '3.1.1'
implementation "com.afollestad.material-dialogs:core:$material_dialogs_version"
implementation "com.afollestad.material-dialogs:input:$material_dialogs_version"
implementation "com.afollestad.material-dialogs:datetime:$material_dialogs_version"
// 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:1.1.1'
// FlowBinding
final flowbinding_version = '0.12.0'
implementation "io.github.reactivecircus.flowbinding:flowbinding-android:$flowbinding_version"
implementation "io.github.reactivecircus.flowbinding:flowbinding-appcompat:$flowbinding_version"
implementation "io.github.reactivecircus.flowbinding:flowbinding-recyclerview:$flowbinding_version"
implementation "io.github.reactivecircus.flowbinding:flowbinding-swiperefreshlayout:$flowbinding_version"
implementation "io.github.reactivecircus.flowbinding:flowbinding-viewpager:$flowbinding_version"
// Licenses
final aboutlibraries_version = '8.3.0'
implementation "com.mikepenz:aboutlibraries-core:$aboutlibraries_version"
implementation "com.mikepenz:aboutlibraries:$aboutlibraries_version"
// Tests
testImplementation 'junit:junit:4.13'
testImplementation 'org.assertj:assertj-core:3.12.2'
testImplementation 'org.mockito:mockito-core:1.10.19'
final robolectric_version = '3.1.4'
testImplementation "org.robolectric:robolectric:$robolectric_version"
testImplementation "org.robolectric:shadows-multidex:$robolectric_version"
testImplementation "org.robolectric:shadows-play-services:$robolectric_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
final coroutines_version = '1.3.8'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-reactive:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:$coroutines_version"
// For detecting memory leaks; see https://square.github.io/leakcanary/
// debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.4'
// Debug tool; see https://fbflipper.com/
// debugImplementation 'com.facebook.flipper:flipper:0.50.0'
// debugImplementation 'com.facebook.soloader:soloader:0.9.0'
// Text distance (EH)
implementation 'info.debatty:java-string-similarity:1.2.1'
// Reprint (EH)
implementation 'com.github.ajalt.reprint:core:3.2.1@aar'
implementation 'com.github.ajalt.reprint:rxjava:3.2.1@aar' // optional: the RxJava 1 interface
// Swirl (EH)
implementation 'com.mattprecious.swirl:swirl:1.2.0'
// RxJava 2 interop for Realm (EH)
implementation 'com.github.akarnokd:rxjava2-interop:0.13.7'
// Firebase (EH)
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
// Better logging (EH)
implementation 'com.elvishew:xlog:1.6.1'
// Time utils (EH)
def typed_time_version = '1.0.2'
implementation "com.github.kizitonwose.time:time:$typed_time_version"
implementation "com.github.kizitonwose.time:time-android:$typed_time_version"
// Debug utils (EH)
debugImplementation 'com.ms-square:debugoverlay:1.1.3'
releaseTestImplementation 'com.ms-square:debugoverlay:1.1.3'
releaseImplementation 'com.ms-square:debugoverlay-no-op:1.1.3'
testImplementation 'com.ms-square:debugoverlay-no-op:1.1.3'
// Humanize (EH)
implementation 'com.github.mfornos:humanize-slim:1.2.2'
// RatingBar (SY)
implementation 'me.zhanghai.android.materialratingbar:library:1.3.1'
implementation 'androidx.gridlayout:gridlayout:1.0.0'
final def markwon_version = '4.1.0'
implementation "io.noties.markwon:core:$markwon_version"
implementation "io.noties.markwon:ext-strikethrough:$markwon_version"
implementation "io.noties.markwon:ext-tables:$markwon_version"
implementation "io.noties.markwon:html:$markwon_version"
implementation "io.noties.markwon:image:$markwon_version"
implementation "io.noties.markwon:linkify:$markwon_version"
implementation 'com.google.guava:guava:27.0.1-android'
}
buildscript {
ext.kotlin_version = '1.3.72'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
repositories {
mavenCentral()
}
// See https://kotlinlang.org/docs/reference/experimental.html#experimental-status-of-experimental-api-markers
tasks.withType(AbstractKotlinCompile).all {
kotlinOptions.freeCompilerArgs += ["-Xuse-experimental=kotlin.Experimental"]
}
// Duplicating Hebrew string assets due to some locale code issues on different devices
task copyResources(type: Copy) {
from './src/main/res/values-he'
into './src/main/res/values-iw'
include '**/*'
}
preBuild.dependsOn(ktlintFormat, copyResources)
if (!getGradle().getStartParameter().getTaskRequests().toString().contains("Debug")) {
apply plugin: 'com.google.gms.google-services'
// Firebase (EH)
apply plugin: 'io.fabric'
}
+375
View File
@@ -0,0 +1,375 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.io.ByteArrayOutputStream
import java.text.SimpleDateFormat
import java.util.Date
import java.util.TimeZone
plugins {
id("com.android.application")
id("com.mikepenz.aboutlibraries.plugin")
kotlin("android")
kotlin("kapt")
kotlin("plugin.parcelize")
kotlin("plugin.serialization")
id("com.github.zellius.shortcut-helper")
// Realm (EH)
id("realm-android")
}
if (!gradle.startParameter.taskRequests.toString().contains("Debug")) {
apply(plugin = "com.google.gms.google-services")
// Firebase Crashlytics
apply(plugin = "com.google.firebase.crashlytics")
}
shortcutHelper.setFilePath("./shortcuts.xml")
android {
compileSdkVersion(AndroidConfig.compileSdk)
buildToolsVersion(AndroidConfig.buildTools)
ndkVersion = AndroidConfig.ndk
defaultConfig {
applicationId = "eu.kanade.tachiyomi.sy"
minSdkVersion(AndroidConfig.minSdk)
targetSdkVersion(AndroidConfig.targetSdk)
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
versionCode = 13
versionName = "1.5.0"
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
}
buildTypes {
named("debug") {
versionNameSuffix = "-${getCommitCount()}"
applicationIdSuffix = ".debug"
}
create("releaseTest") {
applicationIdSuffix = ".rt"
//isMinifyEnabled = true
//isShrinkResources = true
isZipAlignEnabled = true
setProguardFiles(listOf(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"))
}
named("release") {
isMinifyEnabled = true
isShrinkResources = true
isZipAlignEnabled = true
setProguardFiles(listOf(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"))
}
}
flavorDimensions("default")
productFlavors {
create("standard") {
buildConfigField("boolean", "INCLUDE_UPDATER", "true")
dimension = "default"
}
create("fdroid") {
dimension = "default"
}
create("dev") {
resConfigs("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")
// Compatibility for two RxJava versions (EXH)
exclude("META-INF/rxjava.properties")
}
dependenciesInfo {
includeInApk = false
}
lintOptions {
disable("MissingTranslation", "ExtraTranslation")
isAbortOnError = false
isCheckReleaseBuilds = false
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
}
dependencies {
// Source models and interfaces from Tachiyomi 1.x
implementation("tachiyomi.sourceapi:source-api:1.1")
// AndroidX libraries
implementation("androidx.annotation:annotation:1.2.0-beta01")
implementation("androidx.appcompat:appcompat:1.3.0-beta01")
implementation("androidx.biometric:biometric-ktx:1.2.0-alpha02")
implementation("androidx.browser:browser:1.3.0")
implementation("androidx.cardview:cardview:1.0.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.0-alpha2")
implementation("androidx.coordinatorlayout:coordinatorlayout:1.1.0")
implementation("androidx.core:core-ktx:1.5.0-beta01")
implementation("androidx.multidex:multidex:2.0.1")
implementation("androidx.preference:preference-ktx:1.1.1")
implementation("androidx.recyclerview:recyclerview:1.2.0-beta01")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01")
val lifecycleVersion = "2.3.0-rc01"
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion")
implementation("androidx.lifecycle:lifecycle-process:$lifecycleVersion")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion")
// Job scheduling
implementation("androidx.work:work-runtime-ktx:2.5.0")
// UI library
implementation("com.google.android.material:material:1.3.0")
"standardImplementation"("com.google.firebase:firebase-core:18.0.2")
// ReactiveX
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")
// Network client
val okhttpVersion = "4.10.0-RC1"
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")
// TLS 1.3 support for Android < 10
implementation("org.conscrypt:conscrypt-android:2.5.1")
// JSON
val kotlinSerializationVersion = "1.0.1"
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")
// Disk
implementation("com.jakewharton:disklrucache:2.0.2")
implementation("com.github.inorichi:unifile:e9ee588")
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("com.github.inorichi.storio:storio-common:8be19de@aar")
implementation("com.github.inorichi.storio:storio-sqlite:8be19de@aar")
implementation("io.requery:sqlite-android:3.33.0")
// Preferences
implementation("com.github.tfcporciuncula.flow-preferences:flow-preferences:1.3.3")
// Model View Presenter
val nucleusVersion = "3.0.0"
implementation("info.android15.nucleus:nucleus:$nucleusVersion")
implementation("info.android15.nucleus:nucleus-support-v7:$nucleusVersion")
// Dependency injection
implementation("com.github.inorichi.injekt:injekt-core:65b0440")
// Image library
val glideVersion = "4.11.0"
implementation("com.github.bumptech.glide:glide:$glideVersion")
implementation("com.github.bumptech.glide:okhttp3-integration:$glideVersion")
kapt("com.github.bumptech.glide:compiler:$glideVersion")
implementation("com.github.tachiyomiorg:subsampling-scale-image-view:6caf219")
// TODO: switch to new decoder for stable releases
// implementation("com.github.tachiyomiorg:subsampling-scale-image-view:ca26317")
// Logging
implementation("com.jakewharton.timber:timber:4.7.1")
// Crash reports
//implementation("ch.acra:acra-http:5.7.0")
// Sort
implementation("com.github.gpanther:java-nat-sort:natural-comparator-1.1")
// UI
implementation("com.dmitrymalkovich.android:material-design-dimens:1.4")
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.nightlynexus.viewstatepageradapter:viewstatepageradapter:1.1.0")
implementation("com.github.chrisbanes:PhotoView:2.3.0")
implementation("com.github.tachiyomiorg:DirectionalViewPager:7d0617d")
// 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")
// 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:1.1.1")
// FlowBinding
val flowbindingVersion = "0.12.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")
// Licenses
implementation("com.mikepenz:aboutlibraries:${BuildPluginsVersion.ABOUTLIB_PLUGIN}")
// Tests
testImplementation("junit:junit:4.13.1")
testImplementation("org.assertj:assertj-core:3.16.1")
testImplementation("org.mockito:mockito-core:1.10.19")
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.4.2"
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.6")
// 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")
// Text distance (EH)
implementation ("info.debatty:java-string-similarity:2.0.0")
// Firebase (EH)
implementation("com.google.firebase:firebase-analytics-ktx:18.0.0")
implementation("com.google.firebase:firebase-crashlytics-ktx:17.3.0")
// Better logging (EH)
implementation("com.elvishew:xlog:1.7.1")
// Debug utils (EH)
val debugOverlayVersion = "1.1.3"
debugImplementation("com.ms-square:debugoverlay:$debugOverlayVersion")
"releaseTestImplementation"("com.ms-square:debugoverlay-no-op:$debugOverlayVersion")
releaseImplementation("com.ms-square:debugoverlay-no-op:$debugOverlayVersion")
testImplementation("com.ms-square:debugoverlay-no-op:$debugOverlayVersion")
// RatingBar (SY)
implementation ("me.zhanghai.android.materialratingbar:library:1.4.0")
// JsonReader for similar manga
implementation("com.squareup.moshi:moshi:1.11.0")
implementation("androidx.gridlayout:gridlayout:1.0.0")
implementation("com.mikepenz:fastadapter:5.3.4")
// SY -->
}
tasks {
// See https://kotlinlang.org/docs/reference/experimental.html#experimental-status-of-experimental-api(-markers)
withType<KotlinCompile> {
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"
)
}
// Duplicating Hebrew string assets due to some locale code issues on different devices
val copyHebrewStrings = task("copyHebrewStrings", type = Copy::class) {
from("./src/main/res/values-he")
into("./src/main/res/values-iw")
include("**/*")
}
preBuild {
dependsOn(formatKotlin, copyHebrewStrings)
}
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath(kotlin("gradle-plugin", version = BuildPluginsVersion.KOTLIN))
}
}
// Git is needed in your system PATH for these commands to work.
// If it's not installed, you can return a random value as a workaround
fun getCommitCount(): String {
return runCommand("git rev-list --count HEAD")
// return "1"
}
fun getGitSha(): String {
return runCommand("git rev-parse --short HEAD")
// return "1"
}
fun getBuildTime(): String {
val df = SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'")
df.timeZone = TimeZone.getTimeZone("UTC")
return df.format(Date())
}
fun runCommand(command: String): String {
val byteOut = ByteArrayOutputStream()
project.exec {
commandLine = command.split(" ")
standardOutput = byteOut
}
return String(byteOut.toByteArray()).trim()
}
+36
View File
@@ -30,6 +30,42 @@
<init>();
}
# Kotlin Serialization
-keepattributes *Annotation*, InnerClasses
-dontnote kotlinx.serialization.AnnotationsKt # core serialization annotations
# kotlinx-serialization-json specific. Add this if you have java.lang.NoClassDefFoundError kotlinx.serialization.json.JsonObjectSerializer
-keepclassmembers class kotlinx.serialization.json.** {
*** Companion;
}
-keepclasseswithmembers class kotlinx.serialization.json.** {
kotlinx.serialization.KSerializer serializer(...);
}
-keep,includedescriptorclasses class eu.kanade.tachiyomi.**$$serializer { *; }
-keepclassmembers class eu.kanade.tachiyomi.** {
*** Companion;
}
-keepclasseswithmembers class eu.kanade.tachiyomi.** {
kotlinx.serialization.KSerializer serializer(...);
}
-keep,includedescriptorclasses class exh.**$$serializer { *; }
-keepclassmembers class exh.** {
*** Companion;
}
-keepclasseswithmembers class exh.** {
kotlinx.serialization.KSerializer serializer(...);
}
-keep,includedescriptorclasses class xyz.nulldev.ts.api.http.serializer.**$$serializer { *; }
-keepclassmembers class xyz.nulldev.ts.api.http.serializer.** {
*** Companion;
}
-keepclasseswithmembers class xyz.nulldev.ts.api.http.serializer.** {
kotlinx.serialization.KSerializer serializer(...);
}
# Madokami extension username and password crash fix
-keepclassmembers class androidx.preference.EditTextPreference {
*** mOnBindEditTextListener;
@@ -1,38 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108.0"
android:viewportHeight="108.0">
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group android:scaleX="0.07776"
android:scaleY="0.07776"
android:translateX="15.12"
android:translateY="15.12">
<path
android:pathData="M14.5,7L86.5,7A7,7 0,0 1,93.5 14L93.5,95A7,7 0,0 1,86.5 102L14.5,102A7,7 0,0 1,7.5 95L7.5,14A7,7 0,0 1,14.5 7z"
android:fillType="evenOdd"
android:fillColor="#000"/>
android:pathData="M474.4,272.2c115.3,-1.4 144.2,48.2 185.2,74.7c21.6,8.3 17.7,16.3 26.2,28.7c2.5,3.5 5.5,5 9.5,7.5c30.3,18.2 -10.8,39.6 -28.2,40.3c7.1,-4.6 13.2,-5.9 17.7,-12.4c-0.3,0 -0.6,0 -0.9,0c0,-0.3 0,-0.6 0,-0.9c-14.6,-4 -13.3,8.8 -29.2,6.2c3.5,-0.4 12.6,-5.8 12.4,-13.3c-11.9,-7.2 -31.6,-15.2 -46.9,-14.2c-0.1,0.4 -0.1,0.4 -0.2,0.8c36.3,24.2 25.7,57.3 47.1,63.8c-11.6,-0.5 -5.9,2.1 0,7.1c-14.6,-3 -16.1,-19.2 -23,-33.6c-7.8,-12.9 -15.4,-28.5 -23.9,-29.2c-2,9.2 2,56.4 14.7,46.6c-10,12.3 4.4,7.2 11,4.7c-23.9,19 -35.1,13.8 -42.8,-13.8c-6.2,-13.4 -14.6,-34.2 -19.5,-46.6c-2.8,-7.1 -7.5,-13.3 -13.6,-17.9c-41.8,-31.2 -72.8,-33.3 -116.9,-26.1c-11.1,-21.4 -27.5,-40.4 -38.9,-61.9C435,277.7 452,272.4 474.4,272.2z"
android:fillColor="#2E84BF"/>
<path
android:pathData="M14.5,7L86.5,7A7,7 0,0 1,93.5 14L93.5,95A7,7 0,0 1,86.5 102L14.5,102A7,7 0,0 1,7.5 95L7.5,14A7,7 0,0 1,14.5 7z"
android:fillType="evenOdd"
android:fillColor="#455A64"/>
android:pathData="M313.4,366C395.3,524.3 482,472.7 607.1,532.8c109.3,67.9 83.8,212.8 -30.1,257.7c0,-28.3 0,-56.6 0,-84.9c46.4,-45.1 20.7,-112.1 -37.1,-125c-68.8,-15 -145.6,-29.5 -191.7,-62.5C298,480.3 286.6,416.8 313.4,366z"
android:fillColor="#2E84BF"/>
<path
android:pathData="M7.5,12.01C7.5,9.24 9.74,7 12.5,7L17.5,7L17.5,102L12.5,102C9.74,102 7.5,99.77 7.5,96.99L7.5,12.01Z"
android:fillType="evenOdd"
android:fillColor="#607D8B"/>
android:pathData="M424.8,720.6c0.1,25.4 1.9,53.9 -0.9,77.8c-94.2,-25.7 -162.5,-103.3 -124.7,-192.8c0,4.7 0,9.4 0,14.2C307.8,680 359.3,712.6 424.8,720.6z"
android:fillColor="#2E84BF"/>
<path
android:name="path_3"
android:pathData="M 54 54.5 M 28.5 54.5 C 28.5 47.74 31.188 41.249 35.969 36.469 C 40.749 31.688 47.24 29 54 29 C 60.76 29 67.251 31.688 72.031 36.469 C 76.812 41.249 79.5 47.74 79.5 54.5 C 79.5 61.26 76.812 67.751 72.031 72.531 C 67.251 77.312 60.76 80 54 80 C 47.24 80 40.749 77.312 35.969 72.531 C 31.188 67.751 28.5 61.26 28.5 54.5"
android:fillColor="#CE2828"
android:fillType="evenOdd"/>
android:pathData="M247,228l138.9,37.1L500,444.7l47.8,-72.5c34.5,14.5 37,85.5 55.7,96.4l-23,34.5C477,474.9 387.8,469.9 351.3,394.7C317.9,341.3 247.1,228.1 247,228z"
android:fillColor="#CE2828"/>
<path
android:name="path_4"
android:pathData="M 54 54.5 M 34.06 54.5 C 33.964 50.23 35.243 46.04 37.707 42.551 C 40.171 39.062 43.692 36.455 47.748 35.117 C 51.805 33.779 56.185 33.779 60.242 35.117 C 64.298 36.455 67.819 39.062 70.283 42.551 C 72.747 46.04 74.026 50.23 73.93 54.5 C 74.026 58.77 72.747 62.96 70.283 66.449 C 67.819 69.938 64.298 72.545 60.242 73.883 C 56.185 75.221 51.805 75.221 47.748 73.883 C 43.692 72.545 40.171 69.938 37.707 66.449 C 35.243 62.96 33.964 58.77 34.06 54.5"
android:fillColor="#000"
android:fillType="evenOdd"/>
android:pathData="M602.6,285.5c16.2,9.6 33.1,19.8 46.5,32.8c7.5,7.2 14.9,12.3 25.3,18.3c3.9,2.2 4.7,2.1 7.8,4.7L753,228l-137.1,37.1L602.6,285.5z"
android:fillColor="#CE2828"/>
<path
android:name="path_5"
android:pathData="M50.953,47.457C51.828,47.457 53.465,44.672 53.465,43.746C53.465,42.82 50.238,40.461 45.684,40.461C39.32,40.461 37.535,44.926 37.535,47.539C37.535,50.238 38.285,53.355 45.152,55.465C46.977,56.055 49.789,56.98 49.789,59.258C49.789,61.195 47.727,62.207 45.34,62.207C38.605,62.207 39.137,55.883 38.605,55.883C38.285,55.883 36.691,57.402 36.691,60.098C36.691,65.07 41.199,67.434 45.652,67.434C52.27,67.434 54.871,62.965 54.871,59.34C54.871,56.391 53.523,53.188 46.941,50.996C45.215,50.406 42.113,49.563 42.113,47.285C42.113,45.434 44.117,44.672 45.684,44.672C48.949,44.672 50.168,47.457 50.953,47.457ZM50.953,47.457"
android:fillColor="#F7D009"
android:fillType="evenOdd" />
<path
android:name="path_6"
android:pathData="M56.734,66.254C56.734,67.012 56.734,67.434 57.496,67.434C64.391,67.434 71.469,58.582 71.191,49.395C71.191,48.047 71.285,47.035 70.688,46.949L67.895,46.949C67.551,46.949 66.766,46.867 66.766,47.371C66.766,47.875 67.113,49.227 67.113,50.742C67.113,53.188 66.27,56.98 65.012,56.98C64.391,56.98 61.313,53.523 61.313,49.816C61.313,48.887 61.598,47.961 61.598,47.457C61.598,46.867 60.906,46.949 60.504,46.949L57.934,46.949C56.711,46.949 56.734,46.949 56.734,48.383C56.734,57.148 62.188,59.34 62.188,60.688C62.188,61.027 61.254,62.207 57.645,62.207C56.805,62.207 56.734,63.133 56.734,63.469ZM56.734,66.254"
android:fillColor="#E40F85"
android:fillType="evenOdd" />
android:pathData="M500.9,871l61.9,-50.4l0.9,-212.3c0,0 -4.5,-11.4 -85.2,-25.5c-17.1,-3 -29.7,-7.2 -29.8,-7.2l-12.3,-3.6l1.8,248.5L500.9,871z"
android:fillColor="#CE2828"/>
</group>
</vector>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@android:color/transparent"/>
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@android:color/transparent"/>
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 12 KiB

+92 -25
View File
@@ -2,16 +2,24 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="eu.kanade.tachiyomi">
<!-- Internet -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- Storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- For background jobs -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<!-- 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.FOREGROUND_SERVICE" />
<!-- To view extension packages in API 30+ -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application
android:name=".App"
@@ -25,7 +33,7 @@
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/Theme.Tachiyomi.Light"
android:usesCleartextTraffic="true">
android:networkSecurityConfig="@xml/network_security_config">
<activity
android:name=".ui.main.MainActivity"
android:launchMode="singleTop"
@@ -42,7 +50,8 @@
<activity
android:name=".ui.main.DeepLinkActivity"
android:launchMode="singleTask"
android:theme="@android:style/Theme.NoDisplay">
android:theme="@android:style/Theme.NoDisplay"
android:label="@string/action_global_search">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<action android:name="com.google.android.gms.actions.SEARCH_ACTION" />
@@ -53,6 +62,11 @@
<action android:name="eu.kanade.tachiyomi.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
@@ -60,17 +74,20 @@
</activity>
<activity
android:name=".ui.reader.ReaderActivity"
android:launchMode="singleTask" />
android:launchMode="singleTask">
<intent-filter>
<action android:name="com.samsung.android.support.REMOTE_ACTION" />
</intent-filter>
<meta-data android:name="com.samsung.android.support.REMOTE_ACTION"
android:resource="@xml/s_pen_actions"/>
</activity>
<activity
android:name=".ui.security.BiometricUnlockActivity"
android:theme="@style/Theme.Splash" />
<activity
android:name=".ui.webview.WebViewActivity"
android:configChanges="uiMode|orientation|screenSize" />
<activity
android:name=".widget.CustomLayoutPickerActivity"
android:label="@string/app_name"
android:theme="@style/FilePickerTheme" />
<activity
android:name=".ui.setting.track.AnilistLoginActivity"
android:label="Anilist">
@@ -85,6 +102,20 @@
android:scheme="tachiyomi" />
</intent-filter>
</activity>
<activity
android:name=".ui.setting.track.MyAnimeListLoginActivity"
android:label="MyAnimeList">
<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:host="myanimelist-auth"
android:scheme="tachiyomi" />
</intent-filter>
</activity>
<activity
android:name=".ui.setting.track.ShikimoriLoginActivity"
android:label="Shikimori">
@@ -153,6 +184,10 @@
android:exported="false" />
<!-- EH -->
<service
android:name="exh.md.similar.SimilarUpdateService"
android:exported="false" />
<service
android:name="exh.eh.EHentaiUpdateWorker"
android:permission="android.permission.BIND_JOB_SERVICE"
@@ -218,11 +253,11 @@
<!-- Hentai Cafe -->
<data
android:host="hentai.cafe"
android:pathPattern="/.*/.*"
android:pathPrefix="/hc.fyi/"
android:scheme="http" />
<data
android:host="hentai.cafe"
android:pathPattern="/.*/.*"
android:pathPrefix="/hc.fyi/"
android:scheme="https" />
<!-- Tsumino -->
@@ -274,30 +309,62 @@
<!-- HBrowse -->
<data
android:host="www.hbrowse.com"
android:pathPrefix="/"
android:scheme="http" />
<data
android:host="www.hbrowse.com"
android:pathPrefix="/"
android:scheme="https" />
<!-- MangaDex -->
<!-- <data
android:host="mangadex.org"
android:pathPattern="\/(title|manga)\/"
android:scheme="http" />
<data
android:host="mangadex.org"
android:pathPattern="\/(title|manga)\/"
android:scheme="https" />
<data
android:scheme="https"
android:host="www.mangadex.org"
android:pathPattern="\/(title|manga)\/"
android:scheme="http" />
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:scheme="https"
android:host="www.mangadex.org"
android:pathPattern="\/(title|manga)\/"
android:scheme="https" />-->
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: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/" />
</intent-filter>
</activity>
<activity
+65 -39
View File
@@ -16,14 +16,15 @@ import com.elvishew.xlog.LogLevel
import com.elvishew.xlog.XLog
import com.elvishew.xlog.printer.AndroidPrinter
import com.elvishew.xlog.printer.Printer
import com.elvishew.xlog.printer.file.FilePrinter
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.kizitonwose.time.days
import com.google.firebase.analytics.FirebaseAnalytics
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.notification.Notifications
@@ -34,52 +35,50 @@ import exh.debug.DebugToggles
import exh.log.CrashlyticsPrinter
import exh.log.EHDebugModeOverlay
import exh.log.EHLogLevel
import exh.log.EnhancedFilePrinter
import exh.syDebugVersion
import io.realm.Realm
import io.realm.RealmConfiguration
import java.io.File
import java.security.NoSuchAlgorithmException
import java.security.Security
import javax.net.ssl.SSLContext
import kotlin.concurrent.thread
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.conscrypt.Conscrypt
import timber.log.Timber
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.InjektScope
import uy.kohesive.injekt.injectLazy
import uy.kohesive.injekt.registry.default.DefaultRegistrar
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.concurrent.thread
import kotlin.time.ExperimentalTime
import kotlin.time.days
open class App : Application(), LifecycleObserver {
private val preferences: PreferencesHelper by injectLazy()
private lateinit var firebaseAnalytics: FirebaseAnalytics
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
setupExhLogging() // EXH logging
if (!BuildConfig.DEBUG) addAnalytics()
workaroundAndroid7BrokenSSL()
// Debug tool; see https://fbflipper.com/
// SoLoader.init(this, false)
// if (BuildConfig.DEBUG && FlipperUtils.shouldEnableFlipper(this)) {
// val client = AndroidFlipperClient.getInstance(this)
// client.addPlugin(InspectorFlipperPlugin(this, DescriptorMapping.withDefaults()))
// client.addPlugin(DatabasesFlipperPlugin(this))
// client.start()
// }
// TLS 1.3 support for Android < 10
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
Security.insertProviderAt(Conscrypt.newProvider(), 1)
}
Injekt = InjektScope(DefaultRegistrar())
Injekt.importModule(AppModule(this))
setupNotificationChannels()
Realm.init(this)
GlobalScope.launch { deleteOldMetadataRealm() } // Delete old metadata DB (EH)
// Reprint.initialize(this) //Setup fingerprint (EH)
if ((BuildConfig.DEBUG || BuildConfig.BUILD_TYPE == "releaseTest") && DebugToggles.ENABLE_DEBUG_OVERLAY.enabled) {
setupDebugOverlay()
}
@@ -106,23 +105,29 @@ open class App : Application(), LifecycleObserver {
try {
SSLContext.getInstance("TLSv1.2")
} catch (e: NoSuchAlgorithmException) {
XLog.e("Could not install Android 7 broken SSL workaround!", e)
XLog.tag("Init").e("Could not install Android 7 broken SSL workaround!", e)
}
try {
ProviderInstaller.installIfNeeded(applicationContext)
} catch (e: GooglePlayServicesRepairableException) {
XLog.e("Could not install Android 7 broken SSL workaround!", e)
XLog.tag("Init").e("Could not install Android 7 broken SSL workaround!", e)
} catch (e: GooglePlayServicesNotAvailableException) {
XLog.e("Could not install Android 7 broken SSL workaround!", e)
XLog.tag("Init").e("Could not install Android 7 broken SSL workaround!", e)
}
}
}
private fun addAnalytics() {
firebaseAnalytics = Firebase.analytics
if (syDebugVersion != "0") {
firebaseAnalytics.setUserProperty("preview_version", syDebugVersion)
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
@Suppress("unused")
fun onAppBackgrounded() {
val preferences: PreferencesHelper by injectLazy()
if (preferences.lockAppAfter().get() >= 0) {
SecureActivityDelegate.locked = true
}
@@ -159,17 +164,16 @@ open class App : Application(), LifecycleObserver {
private fun setupExhLogging() {
EHLogLevel.init(this)
val logLevel = if (EHLogLevel.shouldLog(EHLogLevel.EXTRA)) {
LogLevel.ALL
} else {
LogLevel.WARN
val logLevel = when {
EHLogLevel.shouldLog(EHLogLevel.EXTRA) -> LogLevel.ALL
BuildConfig.DEBUG -> LogLevel.DEBUG
else -> LogLevel.WARN
}
val logConfig = LogConfiguration.Builder()
.logLevel(logLevel)
.t()
.st(2)
.nb()
.disableStackTrace()
.disableBorder()
.build()
val printers = mutableListOf<Printer>(AndroidPrinter())
@@ -180,14 +184,25 @@ open class App : Application(), LifecycleObserver {
"logs"
)
printers += FilePrinter
val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault())
@OptIn(ExperimentalTime::class)
printers += EnhancedFilePrinter
.Builder(logFolder.absolutePath)
.fileNameGenerator(object : DateFileNameGenerator() {
override fun generateFileName(logLevel: Int, timestamp: Long): String {
return super.generateFileName(logLevel, timestamp) + "-${BuildConfig.BUILD_TYPE}"
.fileNameGenerator(
object : DateFileNameGenerator() {
override fun generateFileName(logLevel: Int, timestamp: Long): String {
return super.generateFileName(
logLevel,
timestamp
) + "-${BuildConfig.BUILD_TYPE}.log"
}
}
})
.cleanStrategy(FileLastModifiedCleanStrategy(7.days.inMilliseconds.longValue))
)
.flattener { timeMillis, level, tag, message ->
"${dateFormat.format(timeMillis)} ${LogLevel.getShortLevelName(level)}/$tag: $message"
}
.cleanStrategy(FileLastModifiedCleanStrategy(7.days.toLongMilliseconds()))
.backupStrategy(NeverBackupStrategy())
.build()
@@ -201,7 +216,18 @@ open class App : Application(), LifecycleObserver {
*printers.toTypedArray()
)
XLog.d("Application booting...")
XLog.tag("Init").d("Application booting...")
XLog.tag("Init").disableStackTrace().d(
"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}"
)
}
// EXH
@@ -216,7 +242,7 @@ open class App : Application(), LifecycleObserver {
.install()
} catch (e: IllegalStateException) {
// Crashes if app is in background
XLog.e("Failed to initialize debug overlay, app in background?", e)
XLog.tag("Init").e("Failed to initialize debug overlay, app in background?", e)
}
}
}
@@ -1,6 +1,7 @@
package eu.kanade.tachiyomi
import android.app.Application
import android.os.Handler
import com.google.gson.Gson
import eu.kanade.tachiyomi.data.cache.ChapterCache
import eu.kanade.tachiyomi.data.cache.CoverCache
@@ -13,9 +14,7 @@ import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.source.SourceManager
import exh.eh.EHentaiUpdateHelper
import io.noties.markwon.Markwon
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
import uy.kohesive.injekt.api.InjektModule
import uy.kohesive.injekt.api.InjektRegistrar
import uy.kohesive.injekt.api.addSingleton
@@ -43,32 +42,33 @@ class AppModule(val app: Application) : InjektModule {
addSingletonFactory { DownloadManager(app) }
addSingletonFactory { CustomMangaManager(app) }
addSingletonFactory { TrackManager(app) }
addSingletonFactory { Gson() }
// SY -->
addSingletonFactory { EHentaiUpdateHelper(app) }
addSingletonFactory { Json { ignoreUnknownKeys = true } }
addSingletonFactory { Markwon.create(app) }
// SY -->
addSingletonFactory { CustomMangaManager(app) }
addSingletonFactory { EHentaiUpdateHelper(app) }
// SY <--
// Asynchronously init expensive components for a faster cold start
Handler().post {
get<PreferencesHelper>()
GlobalScope.launch { get<PreferencesHelper>() }
get<NetworkHelper>()
GlobalScope.launch { get<NetworkHelper>() }
get<SourceManager>()
GlobalScope.launch { get<SourceManager>() }
get<DatabaseHelper>()
GlobalScope.launch { get<DatabaseHelper>() }
get<DownloadManager>()
GlobalScope.launch { get<DownloadManager>() }
// SY -->
GlobalScope.launch { get<CustomMangaManager>() }
// SY <--
// SY -->
get<CustomMangaManager>()
// SY <--
}
}
}
@@ -1,11 +1,19 @@
package eu.kanade.tachiyomi
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.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.extension.ExtensionUpdateJob
import eu.kanade.tachiyomi.ui.library.LibrarySort
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.File
object Migrations {
@@ -20,13 +28,13 @@ object Migrations {
*/
fun upgrade(preferences: PreferencesHelper): Boolean {
val context = preferences.context
val oldVersion = preferences.lastVersionCode().get()
// 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)
@@ -92,8 +100,38 @@ object Migrations {
preferences.librarySortingMode().set(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
else ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value
}
prefs.edit {
putInt(PreferenceKeys.filterDownloaded, convertBooleanPrefToTriState("pref_filter_downloaded_key"))
remove("pref_filter_downloaded_key")
putInt(PreferenceKeys.filterUnread, convertBooleanPrefToTriState("pref_filter_unread_key"))
remove("pref_filter_unread_key")
putInt(PreferenceKeys.filterCompleted, convertBooleanPrefToTriState("pref_filter_completed_key"))
remove("pref_filter_completed_key")
}
}
if (oldVersion < 53) {
// Force MAL log out due to login flow change
// v52: switched from scraping to WebView
// v53: switched from WebView to OAuth
val trackManager = Injekt.get<TrackManager>()
if (trackManager.myAnimeList.isLogged) {
trackManager.myAnimeList.logout()
context.toast(R.string.myanimelist_relogin)
}
}
return true
}
return false
}
}
@@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.annoations
package eu.kanade.tachiyomi.annotations
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS)
@@ -0,0 +1,118 @@
package eu.kanade.tachiyomi.data.backup
import android.content.Context
import android.net.Uri
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.database.models.toMangaInfo
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.source.online.all.EHentai
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
import exh.eh.EHentaiThrottleManager
import uy.kohesive.injekt.injectLazy
abstract class AbstractBackupManager(protected val context: Context) {
internal val databaseHelper: DatabaseHelper by injectLazy()
internal val sourceManager: SourceManager by injectLazy()
internal val trackManager: TrackManager by injectLazy()
protected val preferences: PreferencesHelper by injectLazy()
abstract fun createBackup(uri: Uri, flags: Int, isJob: Boolean): String?
/**
* Returns manga
*
* @return [Manga], null if not found
*/
internal fun getMangaFromDatabase(manga: Manga): Manga? =
databaseHelper.getManga(manga.url, manga.source).executeAsBlocking()
/**
* Fetches chapter information.
*
* @param source source of manga
* @param manga manga that needs updating
* @param chapters list of chapters in the backup
* @return Updated manga chapters.
*/
internal open suspend fun restoreChapters(source: Source, manga: Manga, chapters: List<Chapter> /* SY --> */, throttleManager: EHentaiThrottleManager /* SY <-- */): Pair<List<Chapter>, List<Chapter>> {
// SY -->
val fetchedChapters = if (source is EHentai) {
source.getChapterList(manga.toMangaInfo(), throttleManager::throttle)
.map { it.toSChapter() }
} else {
source.getChapterList(manga.toMangaInfo())
.map { it.toSChapter() }
}
// SY <--
val syncedChapters = syncChaptersWithSource(databaseHelper, fetchedChapters, manga, source)
if (syncedChapters.first.isNotEmpty()) {
chapters.forEach { it.manga_id = manga.id }
updateChapters(chapters)
}
return syncedChapters
}
/**
* Returns list containing manga from library
*
* @return [Manga] from library
*/
protected fun getFavoriteManga(): List<Manga> =
databaseHelper.getFavoriteMangas().executeAsBlocking()
// SY -->
protected fun getReadManga(): List<Manga> =
databaseHelper.getReadNotInLibraryMangas().executeAsBlocking()
/**
* Returns list containing merged manga that are possibly not in the library
*
* @return merged [Manga] that are possibly not in the library
*/
protected fun getMergedManga(): List<Manga> =
databaseHelper.getMergedMangas().executeAsBlocking()
// SY <--
/**
* Inserts manga and returns id
*
* @return id of [Manga], null if not found
*/
internal fun insertManga(manga: Manga): Long? =
databaseHelper.insertManga(manga).executeAsBlocking().insertedId()
/**
* Inserts list of chapters
*/
protected fun insertChapters(chapters: List<Chapter>) {
databaseHelper.insertChapters(chapters).executeAsBlocking()
}
/**
* Updates a list of chapters
*/
protected fun updateChapters(chapters: List<Chapter>) {
databaseHelper.updateChaptersBackup(chapters).executeAsBlocking()
}
/**
* Updates a list of chapters with known database ids
*/
protected fun updateKnownChapters(chapters: List<Chapter>) {
databaseHelper.updateKnownChaptersBackup(chapters).executeAsBlocking()
}
/**
* Return number of backups.
*
* @return number of backups selected by user
*/
protected fun numberOfBackups(): Int = preferences.numberOfBackups().get()
}
@@ -0,0 +1,143 @@
package eu.kanade.tachiyomi.data.backup
import android.content.Context
import android.net.Uri
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.database.models.Track
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.util.chapter.NoChaptersException
import eu.kanade.tachiyomi.util.system.createFileInCacheDir
import exh.eh.EHentaiThrottleManager
import kotlinx.coroutines.Job
import uy.kohesive.injekt.injectLazy
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
abstract class AbstractBackupRestore<T : AbstractBackupManager>(protected val context: Context, protected val notifier: BackupNotifier) {
protected val db: DatabaseHelper by injectLazy()
protected val trackManager: TrackManager by injectLazy()
var job: Job? = null
protected lateinit var backupManager: T
protected var restoreAmount = 0
protected var restoreProgress = 0
// SY -->
protected val throttleManager = EHentaiThrottleManager()
// SY <--
/**
* Mapping of source ID to source name from backup data
*/
protected var sourceMapping: Map<Long, String> = emptyMap()
protected val errors = mutableListOf<Pair<Date, String>>()
abstract suspend fun performRestore(uri: Uri): Boolean
suspend fun restoreBackup(uri: Uri): Boolean {
val startTime = System.currentTimeMillis()
restoreProgress = 0
errors.clear()
if (!performRestore(uri)) {
return false
}
val endTime = System.currentTimeMillis()
val time = endTime - startTime
val logFile = writeErrorLog()
notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name)
return true
}
/**
* Fetches chapter information.
*
* @param source source of manga
* @param manga manga that needs updating
* @return Updated manga chapters.
*/
internal suspend fun updateChapters(source: Source, manga: Manga, chapters: List<Chapter>): Pair<List<Chapter>, List<Chapter>> {
return try {
backupManager.restoreChapters(source, manga, chapters /* SY --> */, throttleManager /* SY <-- */)
} catch (e: Exception) {
// If there's any error, return empty update and continue.
val errorMessage = if (e is NoChaptersException) {
context.getString(R.string.no_chapters_error)
} else {
e.message
}
errors.add(Date() to "${manga.title} - $errorMessage")
Pair(emptyList(), emptyList())
}
}
/**
* Refreshes tracking information.
*
* @param manga manga that needs updating.
* @param tracks list containing tracks from restore file.
*/
internal suspend fun updateTracking(manga: Manga, tracks: List<Track>) {
tracks.forEach { track ->
val service = trackManager.getService(track.sync_id)
if (service != null && service.isLogged) {
try {
val updatedTrack = service.refresh(track)
db.insertTrack(updatedTrack).executeAsBlocking()
} catch (e: Exception) {
errors.add(Date() to "${manga.title} - ${e.message}")
}
} else {
val serviceName = service?.nameRes()?.let { context.getString(it) }
errors.add(Date() to "${manga.title} - ${context.getString(R.string.tracker_not_logged_in, serviceName)}")
}
}
}
/**
* Called to update dialog in [BackupConst]
*
* @param progress restore progress
* @param amount total restoreAmount of manga
* @param title title of restored manga
*/
internal fun showRestoreProgress(
progress: Int,
amount: Int,
title: String
) {
notifier.showRestoreProgress(title, progress, amount)
}
internal fun writeErrorLog(): File {
try {
if (errors.isNotEmpty()) {
val file = context.createFileInCacheDir("tachiyomi_restore.txt")
val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault())
file.bufferedWriter().use { out ->
errors.forEach { (date, message) ->
out.write("[${sdf.format(date)}] $message\n")
}
}
return file
}
} catch (e: Exception) {
// Empty
}
return File("")
}
}
@@ -0,0 +1,16 @@
package eu.kanade.tachiyomi.data.backup
import android.content.Context
import android.net.Uri
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.SourceManager
import uy.kohesive.injekt.injectLazy
abstract class AbstractBackupRestoreValidator {
protected val sourceManager: SourceManager by injectLazy()
protected val trackManager: TrackManager by injectLazy()
abstract fun validate(context: Context, uri: Uri): Results
data class Results(val missingSources: List<String>, val missingTrackers: List<String>)
}
@@ -7,4 +7,9 @@ object BackupConst {
private const val NAME = "BackupRestoreServices"
const val EXTRA_URI = "$ID.$NAME.EXTRA_URI"
const val EXTRA_FLAGS = "$ID.$NAME.EXTRA_FLAGS"
const val EXTRA_MODE = "$ID.$NAME.EXTRA_MODE"
const val EXTRA_TYPE = "$ID.$NAME.EXTRA_TYPE"
const val BACKUP_TYPE_LEGACY = 0
const val BACKUP_TYPE_FULL = 1
}
@@ -4,11 +4,13 @@ import android.app.Service
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.IBinder
import android.os.PowerManager
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.data.backup.full.FullBackupManager
import eu.kanade.tachiyomi.data.backup.legacy.LegacyBackupManager
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.util.system.acquireWakeLock
import eu.kanade.tachiyomi.util.system.isServiceRunning
@@ -46,17 +48,14 @@ class BackupCreateService : Service() {
* @param uri path of Uri
* @param flags determines what to backup
*/
fun start(context: Context, uri: Uri, flags: Int) {
fun start(context: Context, uri: Uri, flags: Int, type: Int) {
if (!isRunning(context)) {
val intent = Intent(context, BackupCreateService::class.java).apply {
putExtra(BackupConst.EXTRA_URI, uri)
putExtra(BackupConst.EXTRA_FLAGS, flags)
putExtra(BackupConst.EXTRA_TYPE, type)
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
context.startService(intent)
} else {
context.startForegroundService(intent)
}
ContextCompat.startForegroundService(context, intent)
}
}
}
@@ -66,7 +65,6 @@ class BackupCreateService : Service() {
*/
private lateinit var wakeLock: PowerManager.WakeLock
private lateinit var backupManager: BackupManager
private lateinit var notifier: BackupNotifier
override fun onCreate() {
@@ -105,11 +103,15 @@ class BackupCreateService : Service() {
try {
val uri = intent.getParcelableExtra<Uri>(BackupConst.EXTRA_URI)
val backupFlags = intent.getIntExtra(BackupConst.EXTRA_FLAGS, 0)
backupManager = BackupManager(this)
val backupType = intent.getIntExtra(BackupConst.EXTRA_TYPE, BackupConst.BACKUP_TYPE_LEGACY)
val backupManager = when (backupType) {
BackupConst.BACKUP_TYPE_FULL -> FullBackupManager(this)
else -> LegacyBackupManager(this)
}
val backupFileUri = backupManager.createBackup(uri, backupFlags, false)?.toUri()
val unifile = UniFile.fromUri(this, backupFileUri)
notifier.showBackupComplete(unifile)
notifier.showBackupComplete(unifile, backupType == BackupConst.BACKUP_TYPE_LEGACY)
} catch (e: Exception) {
notifier.showBackupError(e.message)
}
@@ -7,21 +7,25 @@ import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.Worker
import androidx.work.WorkerParameters
import eu.kanade.tachiyomi.data.backup.full.FullBackupManager
import eu.kanade.tachiyomi.data.backup.legacy.LegacyBackupManager
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import java.util.concurrent.TimeUnit
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.concurrent.TimeUnit
class BackupCreatorJob(private val context: Context, workerParams: WorkerParameters) :
Worker(context, workerParams) {
override fun doWork(): Result {
val preferences = Injekt.get<PreferencesHelper>()
val backupManager = BackupManager(context)
val uri = preferences.backupsDirectory().get().toUri()
val flags = BackupCreateService.BACKUP_ALL
return try {
backupManager.createBackup(uri, flags, true)
FullBackupManager(context).createBackup(uri, flags, true)
if (preferences.createLegacyBackup().get()) {
LegacyBackupManager(context).createBackup(uri, flags, true)
}
Result.success()
} catch (e: Exception) {
Result.failure()
@@ -36,8 +40,10 @@ class BackupCreatorJob(private val context: Context, workerParams: WorkerParamet
val interval = prefInterval ?: preferences.backupInterval().get()
if (interval > 0) {
val request = PeriodicWorkRequestBuilder<BackupCreatorJob>(
interval.toLong(), TimeUnit.HOURS,
10, TimeUnit.MINUTES
interval.toLong(),
TimeUnit.HOURS,
10,
TimeUnit.MINUTES
)
.addTag(TAG)
.build()
@@ -11,11 +11,11 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.util.storage.getUriCompat
import eu.kanade.tachiyomi.util.system.notificationBuilder
import eu.kanade.tachiyomi.util.system.notificationManager
import uy.kohesive.injekt.injectLazy
import java.io.File
import java.util.concurrent.TimeUnit
import uy.kohesive.injekt.injectLazy
internal class BackupNotifier(private val context: Context) {
class BackupNotifier(private val context: Context) {
private val preferences: PreferencesHelper by injectLazy()
@@ -60,25 +60,20 @@ internal class BackupNotifier(private val context: Context) {
}
}
fun showBackupComplete(unifile: UniFile) {
fun showBackupComplete(unifile: UniFile, isLegacyFormat: Boolean) {
context.notificationManager.cancel(Notifications.ID_BACKUP_PROGRESS)
with(completeNotificationBuilder) {
setContentTitle(context.getString(R.string.backup_created))
if (unifile.filePath != null) {
setContentText(unifile.filePath)
}
setContentText(unifile.filePath ?: unifile.name)
// Clear old actions if they exist
if (mActions.isNotEmpty()) {
mActions.clear()
}
clearActions()
addAction(
R.drawable.ic_share_24dp,
context.getString(R.string.action_share),
NotificationReceiver.shareBackupPendingBroadcast(context, unifile.uri, Notifications.ID_BACKUP_COMPLETE)
NotificationReceiver.shareBackupPendingBroadcast(context, unifile.uri, isLegacyFormat, Notifications.ID_BACKUP_COMPLETE)
)
show(Notifications.ID_BACKUP_COMPLETE)
@@ -97,9 +92,7 @@ internal class BackupNotifier(private val context: Context) {
setOnlyAlertOnce(true)
// Clear old actions if they exist
if (mActions.isNotEmpty()) {
mActions.clear()
}
clearActions()
addAction(
R.drawable.ic_close_24dp,
@@ -140,16 +133,14 @@ internal class BackupNotifier(private val context: Context) {
setContentText(context.resources.getQuantityString(R.plurals.restore_completed_message, errorCount, timeString, errorCount))
// Clear old actions if they exist
if (mActions.isNotEmpty()) {
mActions.clear()
}
clearActions()
if (errorCount > 0 && !path.isNullOrEmpty() && !file.isNullOrEmpty()) {
val destFile = File(path, file)
val uri = destFile.getUriCompat(context)
addAction(
R.drawable.nnf_ic_file_folder,
R.drawable.ic_folder_24dp,
context.getString(R.string.action_open_log),
NotificationReceiver.openErrorLogPendingActivity(context, uri)
)
@@ -4,53 +4,25 @@ import android.app.Service
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.IBinder
import android.os.PowerManager
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 androidx.core.content.ContextCompat
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.models.Backup.CATEGORIES
import eu.kanade.tachiyomi.data.backup.models.Backup.CHAPTERS
import eu.kanade.tachiyomi.data.backup.models.Backup.HISTORY
import eu.kanade.tachiyomi.data.backup.models.Backup.MANGA
import eu.kanade.tachiyomi.data.backup.models.Backup.MANGAS
import eu.kanade.tachiyomi.data.backup.models.Backup.SAVEDSEARCHES
import eu.kanade.tachiyomi.data.backup.models.Backup.TRACK
import eu.kanade.tachiyomi.data.backup.models.Backup.VERSION
import eu.kanade.tachiyomi.data.backup.models.DHistory
import eu.kanade.tachiyomi.data.database.DatabaseHelper
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.data.backup.full.FullBackupRestore
import eu.kanade.tachiyomi.data.backup.legacy.LegacyBackupRestore
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.util.system.acquireWakeLock
import eu.kanade.tachiyomi.util.system.isServiceRunning
import exh.EXHMigrations
import exh.eh.EHentaiThrottleManager
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import rx.Observable
import timber.log.Timber
import uy.kohesive.injekt.injectLazy
/**
* Restores backup from a JSON file.
* Restores backup.
*/
class BackupRestoreService : Service() {
@@ -71,16 +43,14 @@ class BackupRestoreService : Service() {
* @param context context of application
* @param uri path of Uri
*/
fun start(context: Context, uri: Uri) {
fun start(context: Context, uri: Uri, mode: Int, online: Boolean?) {
if (!isRunning(context)) {
val intent = Intent(context, BackupRestoreService::class.java).apply {
putExtra(BackupConst.EXTRA_URI, uri)
putExtra(BackupConst.EXTRA_MODE, mode)
online?.let { putExtra(BackupConst.EXTRA_TYPE, it) }
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
context.startService(intent)
} else {
context.startForegroundService(intent)
}
ContextCompat.startForegroundService(context, intent)
}
}
@@ -101,46 +71,14 @@ class BackupRestoreService : Service() {
*/
private lateinit var wakeLock: PowerManager.WakeLock
private var job: Job? = null
// SY -->
private val throttleManager = EHentaiThrottleManager()
private var skippedAmount = 0
private var totalAmount = 0
// SY <--
/**
* The progress of a backup restore
*/
private var restoreProgress = 0
/**
* Amount of manga in Json file (needed for restore)
*/
private var restoreAmount = 0
/**
* Mapping of source ID to source name from backup data
*/
private var sourceMapping: Map<Long, String> = emptyMap()
/**
* List containing errors
*/
private val errors = mutableListOf<Pair<Date, String>>()
private lateinit var backupManager: BackupManager
private lateinit var ioScope: CoroutineScope
private var backupRestore: AbstractBackupRestore<*>? = null
private lateinit var notifier: BackupNotifier
private val db: DatabaseHelper by injectLazy()
private val trackManager: TrackManager by injectLazy()
override fun onCreate() {
super.onCreate()
ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
notifier = BackupNotifier(this)
wakeLock = acquireWakeLock(javaClass.name)
@@ -158,7 +96,8 @@ class BackupRestoreService : Service() {
}
private fun destroyJob() {
job?.cancel()
backupRestore?.job?.cancel()
ioScope?.cancel()
if (wakeLock.isHeld) {
wakeLock.release()
}
@@ -179,335 +118,34 @@ class BackupRestoreService : Service() {
*/
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val uri = intent?.getParcelableExtra<Uri>(BackupConst.EXTRA_URI) ?: return START_NOT_STICKY
// SY -->
throttleManager.resetThrottle()
// SY <--
val mode = intent.getIntExtra(BackupConst.EXTRA_MODE, BackupConst.BACKUP_TYPE_FULL)
val online = intent.getBooleanExtra(BackupConst.EXTRA_TYPE, true)
// Cancel any previous job if needed.
job?.cancel()
backupRestore?.job?.cancel()
backupRestore = when (mode) {
BackupConst.BACKUP_TYPE_FULL -> FullBackupRestore(this, notifier, online)
else -> LegacyBackupRestore(this, notifier)
}
val handler = CoroutineExceptionHandler { _, exception ->
Timber.e(exception)
writeErrorLog()
backupRestore?.writeErrorLog()
notifier.showRestoreError(exception.message)
stopSelf(startId)
}
job = GlobalScope.launch(handler) {
if (!restoreBackup(uri)) {
val job = ioScope.launch(handler) {
if (backupRestore?.restoreBackup(uri) == false) {
notifier.showRestoreError(getString(R.string.restoring_backup_canceled))
}
}
job?.invokeOnCompletion {
job.invokeOnCompletion {
stopSelf(startId)
}
backupRestore?.job = job
return START_NOT_STICKY
}
/**
* Restores data from backup file.
*
* @param uri backup file to restore
*/
private fun restoreBackup(uri: Uri): Boolean {
val startTime = System.currentTimeMillis()
val reader = JsonReader(contentResolver.openInputStream(uri)!!.bufferedReader())
val json = JsonParser.parseReader(reader).asJsonObject
// Get parser version
val version = json.get(VERSION)?.asInt ?: 1
// Initialize manager
backupManager = BackupManager(this, version)
val mangasJson = json.get(MANGAS).asJsonArray
// SY -->
val validManga = mangasJson.filter {
var manga = backupManager.parser.fromJson<MangaImpl>(it.asJsonObject.get(MANGA))
// EXH -->
manga = EXHMigrations.migrateBackupEntry(manga)
val sourced = backupManager.sourceManager.get(manga.source) != null
if (!sourced) {
restoreAmount -= 1
}
sourced
}
totalAmount = mangasJson.size()
restoreAmount = validManga.count() + 1 // +1 for categories
skippedAmount = mangasJson.size() - validManga.count()
// SY <--
restoreProgress = 0
errors.clear()
// Restore categories
json.get(CATEGORIES)?.let { restoreCategories(it) }
// SY -->
json.get(SAVEDSEARCHES)?.let { restoreSavedSearches(it) }
// SY <--
// Store source mapping for error messages
sourceMapping = BackupRestoreValidator.getSourceMapping(json)
// Restore individual manga
mangasJson.forEach {
if (job?.isActive != true) {
return false
}
restoreManga(it.asJsonObject)
}
val endTime = System.currentTimeMillis()
val time = endTime - startTime
val logFile = writeErrorLog()
notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name)
return true
}
private fun restoreCategories(categoriesJson: JsonElement) {
db.inTransaction {
backupManager.restoreCategories(categoriesJson.asJsonArray)
}
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, getString(R.string.categories))
}
// SY -->
private fun restoreSavedSearches(savedSearchesJson: JsonElement) {
backupManager.restoreSavedSearches(savedSearchesJson)
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, getString(R.string.saved_searches))
}
// SY <--
private fun restoreManga(mangaJson: JsonObject) {
/* SY --> */ var /* SY <-- */ manga = backupManager.parser.fromJson<MangaImpl>(mangaJson.get(MANGA))
val chapters = backupManager.parser.fromJson<List<ChapterImpl>>(
mangaJson.get(CHAPTERS)
?: JsonArray()
)
val categories = backupManager.parser.fromJson<List<String>>(
mangaJson.get(CATEGORIES)
?: JsonArray()
)
val history = backupManager.parser.fromJson<List<DHistory>>(
mangaJson.get(HISTORY)
?: JsonArray()
)
val tracks = backupManager.parser.fromJson<List<TrackImpl>>(
mangaJson.get(TRACK)
?: JsonArray()
)
// EXH -->
manga = EXHMigrations.migrateBackupEntry(manga)
// <-- EXH
try {
val source = backupManager.sourceManager.get(manga.source)
if (source != null) {
restoreMangaData(manga, source, chapters, categories, history, tracks)
} else {
val sourceName = sourceMapping[manga.source] ?: manga.source.toString()
errors.add(Date() to "${manga.title} - ${getString(R.string.source_not_found_name, sourceName)}")
}
} catch (e: Exception) {
errors.add(Date() to "${manga.title} - ${e.message}")
}
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, manga.title)
}
/**
* Returns a manga restore observable
*
* @param manga manga data from json
* @param source source to get manga data from
* @param chapters chapters data from json
* @param categories categories data from json
* @param history history data from json
* @param tracks tracking data from json
*/
private fun restoreMangaData(
manga: Manga,
source: Source,
chapters: List<Chapter>,
categories: List<String>,
history: List<DHistory>,
tracks: List<Track>
) {
val dbManga = backupManager.getMangaFromDatabase(manga)
db.inTransaction {
if (dbManga == null) {
// Manga not in database
restoreMangaFetch(source, manga, chapters, categories, history, tracks)
} else { // Manga in database
// Copy information from manga already in database
backupManager.restoreMangaNoFetch(manga, dbManga)
// Fetch rest of manga information
restoreMangaNoFetch(source, manga, chapters, categories, history, tracks)
}
}
}
/**
* [Observable] that fetches manga information
*
* @param manga manga that needs updating
* @param chapters chapters of manga that needs updating
* @param categories categories that need updating
*/
private fun restoreMangaFetch(
source: Source,
manga: Manga,
chapters: List<Chapter>,
categories: List<String>,
history: List<DHistory>,
tracks: List<Track>
) {
backupManager.restoreMangaFetchObservable(source, manga)
.onErrorReturn {
errors.add(Date() to "${manga.title} - ${it.message}")
manga
}
.filter { it.id != null }
.flatMap {
chapterFetchObservable(source, it, chapters)
// Convert to the manga that contains new chapters.
.map { manga }
}
.doOnNext {
restoreExtraForManga(it, categories, history, tracks)
}
.flatMap {
trackingFetchObservable(it, tracks)
}
.subscribe()
}
private fun restoreMangaNoFetch(
source: Source,
backupManga: Manga,
chapters: List<Chapter>,
categories: List<String>,
history: List<DHistory>,
tracks: List<Track>
) {
Observable.just(backupManga)
.flatMap { manga ->
if (!backupManager.restoreChaptersForManga(manga, chapters)) {
chapterFetchObservable(source, manga, chapters)
.map { manga }
} else {
Observable.just(manga)
}
}
.doOnNext {
restoreExtraForManga(it, categories, history, tracks)
}
.flatMap { manga ->
trackingFetchObservable(manga, tracks)
}
.subscribe()
}
private fun restoreExtraForManga(manga: Manga, categories: List<String>, history: List<DHistory>, tracks: List<Track>) {
// Restore categories
backupManager.restoreCategoriesForManga(manga, categories)
// Restore history
backupManager.restoreHistoryForManga(history)
// Restore tracking
backupManager.restoreTrackForManga(manga, tracks)
}
/**
* [Observable] that fetches chapter information
*
* @param source source of manga
* @param manga manga that needs updating
* @return [Observable] that contains manga
*/
private fun chapterFetchObservable(source: Source, manga: Manga, chapters: List<Chapter>): Observable<Pair<List<Chapter>, List<Chapter>>> {
return backupManager.restoreChapterFetchObservable(source, manga, chapters /* SY --> */, throttleManager /* SY <-- */)
// If there's any error, return empty update and continue.
.onErrorReturn {
errors.add(Date() to "${manga.title} - ${it.message}")
Pair(emptyList(), emptyList())
}
}
/**
* [Observable] that refreshes tracking information
* @param manga manga that needs updating.
* @param tracks list containing tracks from restore file.
* @return [Observable] that contains updated track item
*/
private fun trackingFetchObservable(manga: Manga, tracks: List<Track>): Observable<Track> {
return Observable.from(tracks)
.flatMap { track ->
val service = trackManager.getService(track.sync_id)
if (service != null && service.isLogged) {
service.refresh(track)
.doOnNext { db.insertTrack(it).executeAsBlocking() }
.onErrorReturn {
errors.add(Date() to "${manga.title} - ${it.message}")
track
}
} else {
errors.add(Date() to "${manga.title} - ${getString(R.string.tracker_not_logged_in, service?.name)}")
Observable.empty()
}
}
}
/**
* Called to update dialog in [BackupConst]
*
* @param progress restore progress
* @param amount total restoreAmount of manga
* @param title title of restored manga
*/
private fun showRestoreProgress(
progress: Int,
amount: Int,
title: String
) {
notifier.showRestoreProgress(title, progress, amount)
}
/**
* Write errors to error log
*/
private fun writeErrorLog(): File {
try {
if (errors.isNotEmpty()) {
val destFile = File(externalCacheDir, "tachiyomi_restore.txt")
val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault())
destFile.bufferedWriter().use { out ->
errors.forEach { (date, message) ->
out.write("[${sdf.format(date)}] $message\n")
}
}
return destFile
}
} catch (e: Exception) {
// Empty
}
return File("")
}
}
@@ -0,0 +1,541 @@
package eu.kanade.tachiyomi.data.backup.full
import android.content.Context
import android.net.Uri
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.data.backup.AbstractBackupManager
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CATEGORY
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CATEGORY_MASK
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CHAPTER
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CHAPTER_MASK
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_HISTORY
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_HISTORY_MASK
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_TRACK
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_TRACK_MASK
import eu.kanade.tachiyomi.data.backup.full.models.Backup
import eu.kanade.tachiyomi.data.backup.full.models.BackupCategory
import eu.kanade.tachiyomi.data.backup.full.models.BackupChapter
import eu.kanade.tachiyomi.data.backup.full.models.BackupFlatMetadata
import eu.kanade.tachiyomi.data.backup.full.models.BackupFull
import eu.kanade.tachiyomi.data.backup.full.models.BackupHistory
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.backup.full.models.BackupTracking
import eu.kanade.tachiyomi.data.database.models.Chapter
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.Track
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.all.MergedSource
import exh.metadata.metadata.base.getFlatMetadataForManga
import exh.metadata.metadata.base.insertFlatMetadataAsync
import exh.savedsearches.JsonSavedSearch
import exh.source.MERGED_SOURCE_ID
import exh.source.getMainSource
import exh.util.executeOnIO
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.protobuf.ProtoBuf
import okio.buffer
import okio.gzip
import okio.sink
import timber.log.Timber
import kotlin.math.max
class FullBackupManager(context: Context) : AbstractBackupManager(context) {
val parser = ProtoBuf
/**
* Create backup Json file from database
*
* @param uri path of Uri
* @param isJob backup called from job
*/
override fun createBackup(uri: Uri, flags: Int, isJob: Boolean): String? {
// Create root object
var backup: Backup? = null
databaseHelper.inTransaction {
val databaseManga = getFavoriteManga() /* SY --> */ + getReadManga() + getMergedManga().filterNot { it.source == MERGED_SOURCE_ID } /* SY <-- */
backup = Backup(
backupManga(databaseManga, flags),
backupCategories(),
backupExtensionInfo(databaseManga),
backupSavedSearches()
)
}
try {
val file: UniFile = (
if (isJob) {
// Get dir of file and create
var dir = UniFile.fromUri(context, uri)
dir = dir.createDirectory("automatic")
// Delete older backups
val numberOfBackups = numberOfBackups()
val backupRegex = Regex("""tachiyomi_\d+-\d+-\d+_\d+-\d+.proto.gz""")
dir.listFiles { _, filename -> backupRegex.matches(filename) }
.orEmpty()
.sortedByDescending { it.name }
.drop(numberOfBackups - 1)
.forEach { it.delete() }
// Create new file to place backup
dir.createFile(BackupFull.getDefaultFilename())
} else {
UniFile.fromUri(context, uri)
}
)
?: throw Exception("Couldn't create backup file")
val byteArray = parser.encodeToByteArray(BackupSerializer, backup!!)
file.openOutputStream().sink().gzip().buffer().use { it.write(byteArray) }
return file.uri.toString()
} catch (e: Exception) {
Timber.e(e)
throw e
}
}
private fun backupManga(mangas: List<Manga>, flags: Int): List<BackupManga> {
return mangas.map {
backupMangaObject(it, flags)
}
}
private fun backupExtensionInfo(mangas: List<Manga>): List<BackupSource> {
return mangas
.asSequence()
.map { it.source }
.distinct()
.map { sourceManager.getOrStub(it) }
.map { BackupSource.copyFrom(it) }
.toList()
}
/**
* Backup the categories of library
*
* @return list of [BackupCategory] to be backed up
*/
private fun backupCategories(): List<BackupCategory> {
return databaseHelper.getCategories()
.executeAsBlocking()
.map { BackupCategory.copyFrom(it) }
}
// SY -->
/**
* Backup the saved searches from sources
*
* @return list of [BackupSavedSearch] to be backed up
*/
private fun backupSavedSearches(): List<BackupSavedSearch> {
return preferences.savedSearches().get().map {
val sourceId = it.substringBefore(':').toLong()
val content = Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
BackupSavedSearch(
content.name,
content.query,
content.filters.toString(),
sourceId
)
}
}
// SY <--
/**
* Convert a manga to Json
*
* @param manga manga that gets converted
* @param options options for the backup
* @return [BackupManga] containing manga in a serializable form
*/
private fun backupMangaObject(manga: Manga, options: Int): BackupManga {
// Entry for this manga
val mangaObject = BackupManga.copyFrom(manga)
// SY -->
if (manga.source == MERGED_SOURCE_ID) {
manga.id?.let { mangaId ->
mangaObject.mergedMangaReferences = databaseHelper.getMergedMangaReferences(mangaId)
.executeAsBlocking()
.map { BackupMergedMangaReference.copyFrom(it) }
}
}
val source = sourceManager.get(manga.source)?.getMainSource()
if (source is MetadataSource<*, *>) {
manga.id?.let { mangaId ->
databaseHelper.getFlatMetadataForManga(mangaId).executeAsBlocking()?.let { flatMetadata ->
mangaObject.flatMetadata = BackupFlatMetadata.copyFrom(flatMetadata)
}
}
}
// SY <--
// Check if user wants chapter information in backup
if (options and BACKUP_CHAPTER_MASK == BACKUP_CHAPTER) {
// Backup all the chapters
val chapters = databaseHelper.getChapters(manga).executeAsBlocking()
if (chapters.isNotEmpty()) {
mangaObject.chapters = chapters.map { BackupChapter.copyFrom(it) }
}
}
// Check if user wants category information in backup
if (options and BACKUP_CATEGORY_MASK == BACKUP_CATEGORY) {
// Backup categories for this manga
val categoriesForManga = databaseHelper.getCategoriesForManga(manga).executeAsBlocking()
if (categoriesForManga.isNotEmpty()) {
mangaObject.categories = categoriesForManga.mapNotNull { it.order }
}
}
// Check if user wants track information in backup
if (options and BACKUP_TRACK_MASK == BACKUP_TRACK) {
val tracks = databaseHelper.getTracks(manga).executeAsBlocking()
if (tracks.isNotEmpty()) {
mangaObject.tracking = tracks.map { BackupTracking.copyFrom(it) }
}
}
// Check if user wants history information in backup
if (options and BACKUP_HISTORY_MASK == BACKUP_HISTORY) {
val historyForManga = databaseHelper.getHistoryByMangaId(manga.id!!).executeAsBlocking()
if (historyForManga.isNotEmpty()) {
val history = historyForManga.mapNotNull { history ->
val url = databaseHelper.getChapter(history.chapter_id).executeAsBlocking()?.url
url?.let { BackupHistory(url, history.last_read) }
}
if (history.isNotEmpty()) {
mangaObject.history = history
}
}
}
return mangaObject
}
fun restoreMangaNoFetch(manga: Manga, dbManga: Manga) {
manga.id = dbManga.id
manga.copyFrom(dbManga)
insertManga(manga)
}
/**
* Fetches manga information
*
* @param source source of manga
* @param manga manga that needs updating
* @return Updated manga info.
*/
suspend fun restoreMangaFetch(source: Source?, manga: Manga, online: Boolean): Manga {
return if (online && source != null /* SY --> */ && source !is MergedSource /* SY <-- */) {
val networkManga = source.getMangaDetails(manga.toMangaInfo())
manga.also {
it.copyFrom(networkManga.toSManga())
it.favorite = manga.favorite
it.initialized = true
it.id = insertManga(manga)
}
} else {
manga.also {
it.initialized = it.description != null
it.id = insertManga(it)
}
}
}
/**
* Restore the categories from Json
*
* @param backupCategories list containing categories
*/
internal fun restoreCategories(backupCategories: List<BackupCategory>) {
// Get categories from file and from db
val dbCategories = databaseHelper.getCategories().executeAsBlocking()
// Iterate over them
backupCategories.map { it.getCategoryImpl() }.forEach { category ->
// Used to know if the category is already in the db
var found = false
for (dbCategory in dbCategories) {
// If the category is already in the db, assign the id to the file's category
// and do nothing
if (category.name == dbCategory.name) {
category.id = dbCategory.id
found = true
break
}
}
// If the category isn't in the db, remove the id and insert a new category
// Store the inserted id in the category
if (!found) {
// Let the db assign the id
category.id = null
val result = databaseHelper.insertCategory(category).executeAsBlocking()
category.id = result.insertedId()?.toInt()
}
}
}
/**
* Restores the categories a manga is in.
*
* @param manga the manga whose categories have to be restored.
* @param categories the categories to restore.
*/
internal fun restoreCategoriesForManga(manga: Manga, categories: List<Int>, backupCategories: List<BackupCategory>) {
val dbCategories = databaseHelper.getCategories().executeAsBlocking()
val mangaCategoriesToUpdate = ArrayList<MangaCategory>(categories.size)
categories.forEach { backupCategoryOrder ->
backupCategories.firstOrNull {
it.order == backupCategoryOrder
}?.let { backupCategory ->
dbCategories.firstOrNull { dbCategory ->
dbCategory.name == backupCategory.name
}?.let { dbCategory ->
mangaCategoriesToUpdate += MangaCategory.create(manga, dbCategory)
}
}
}
// Update database
if (mangaCategoriesToUpdate.isNotEmpty()) {
databaseHelper.deleteOldMangasCategories(listOf(manga)).executeAsBlocking()
databaseHelper.insertMangasCategories(mangaCategoriesToUpdate).executeAsBlocking()
}
}
/**
* Restore history from Json
*
* @param history list containing history to be restored
*/
internal fun restoreHistoryForManga(history: List<BackupHistory>) {
// List containing history to be updated
val historyToBeUpdated = ArrayList<History>(history.size)
for ((url, lastRead) in history) {
val dbHistory = databaseHelper.getHistoryByChapterUrl(url).executeAsBlocking()
// Check if history already in database and update
if (dbHistory != null) {
dbHistory.apply {
last_read = max(lastRead, dbHistory.last_read)
}
historyToBeUpdated.add(dbHistory)
} else {
// If not in database create
databaseHelper.getChapter(url).executeAsBlocking()?.let {
val historyToAdd = History.create(it).apply {
last_read = lastRead
}
historyToBeUpdated.add(historyToAdd)
}
}
}
databaseHelper.updateHistoryLastRead(historyToBeUpdated).executeAsBlocking()
}
/**
* Restores the sync of a manga.
*
* @param manga the manga whose sync have to be restored.
* @param tracks the track list to restore.
*/
internal fun restoreTrackForManga(manga: Manga, tracks: List<Track>) {
// Fix foreign keys with the current manga id
tracks.map { it.manga_id = manga.id!! }
// Get tracks from database
val dbTracks = databaseHelper.getTracks(manga).executeAsBlocking()
val trackToUpdate = mutableListOf<Track>()
tracks.forEach { track ->
val service = trackManager.getService(track.sync_id)
if (service != null && service.isLogged) {
var isInDatabase = false
for (dbTrack in dbTracks) {
if (track.sync_id == dbTrack.sync_id) {
// The sync is already in the db, only update its fields
if (track.media_id != dbTrack.media_id) {
dbTrack.media_id = track.media_id
}
if (track.library_id != dbTrack.library_id) {
dbTrack.library_id = track.library_id
}
dbTrack.last_chapter_read = max(dbTrack.last_chapter_read, track.last_chapter_read)
isInDatabase = true
trackToUpdate.add(dbTrack)
break
}
}
if (!isInDatabase) {
// Insert new sync. Let the db assign the id
track.id = null
trackToUpdate.add(track)
}
}
}
// Update database
if (trackToUpdate.isNotEmpty()) {
databaseHelper.insertTracks(trackToUpdate).executeAsBlocking()
}
}
/**
* Restore the chapters for manga if chapters already in database
*
* @param manga manga of chapters
* @param chapters list containing chapters that get restored
* @return boolean answering if chapter fetch is not needed
*/
internal fun restoreChaptersForManga(manga: Manga, chapters: List<Chapter>): Boolean {
val dbChapters = databaseHelper.getChapters(manga).executeAsBlocking()
// Return if fetch is needed
if (dbChapters.isEmpty() || dbChapters.size < chapters.size) {
return false
}
chapters.forEach { chapter ->
val dbChapter = dbChapters.find { it.url == chapter.url }
if (dbChapter != null) {
chapter.id = dbChapter.id
chapter.copyFrom(dbChapter)
if (dbChapter.read && !chapter.read) {
chapter.read = dbChapter.read
chapter.last_page_read = dbChapter.last_page_read
} else if (chapter.last_page_read == 0 && dbChapter.last_page_read != 0) {
chapter.last_page_read = dbChapter.last_page_read
}
if (!chapter.bookmark && dbChapter.bookmark) {
chapter.bookmark = dbChapter.bookmark
}
}
chapter.manga_id = manga.id
}
// Filter the chapters that couldn't be found.
updateChapters(chapters.filter { it.id != null })
return true
}
internal fun restoreChaptersForMangaOffline(manga: Manga, chapters: List<Chapter>) {
val dbChapters = databaseHelper.getChapters(manga).executeAsBlocking()
chapters.forEach { chapter ->
val dbChapter = dbChapters.find { it.url == chapter.url }
if (dbChapter != null) {
chapter.id = dbChapter.id
chapter.copyFrom(dbChapter)
if (dbChapter.read && !chapter.read) {
chapter.read = dbChapter.read
chapter.last_page_read = dbChapter.last_page_read
} else if (chapter.last_page_read == 0 && dbChapter.last_page_read != 0) {
chapter.last_page_read = dbChapter.last_page_read
}
if (!chapter.bookmark && dbChapter.bookmark) {
chapter.bookmark = dbChapter.bookmark
}
}
chapter.manga_id = manga.id
}
val newChapters = chapters.groupBy { it.id != null }
newChapters[true]?.let { updateKnownChapters(it) }
newChapters[false]?.let { insertChapters(it) }
}
// 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(':'))
BackupSavedSearch(
content.name,
content.query,
content.filters.toString(),
sourceId
)
}
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()
)
}
/**
* Restore the categories from Json
*
* @param manga the merge manga for the references
* @param backupMergedMangaReferences the list of backup manga references for the merged manga
*/
internal fun restoreMergedMangaReferencesForManga(manga: Manga, backupMergedMangaReferences: List<BackupMergedMangaReference>) {
// Get merged manga references from file and from db
val dbMergedMangaReferences = databaseHelper.getMergedMangaReferences().executeAsBlocking()
// Iterate over them
backupMergedMangaReferences.forEach { backupMergedMangaReference ->
// Used to know if the merged manga reference is already in the db
var found = false
for (dbMergedMangaReference in dbMergedMangaReferences) {
// If the backupMergedMangaReference is already in the db, assign the id to the file's backupMergedMangaReference
// and do nothing
if (backupMergedMangaReference.mergeUrl == dbMergedMangaReference.mergeUrl && backupMergedMangaReference.mangaUrl == dbMergedMangaReference.mangaUrl) {
found = true
break
}
}
// If the backupMergedMangaReference isn't in the db, remove the id and insert a new backupMergedMangaReference
// Store the inserted id in the backupMergedMangaReference
if (!found) {
// Let the db assign the id
val mergedManga = databaseHelper.getManga(backupMergedMangaReference.mangaUrl, backupMergedMangaReference.mangaSourceId).executeAsBlocking() ?: return@forEach
val mergedMangaReference = backupMergedMangaReference.getMergedMangaReference()
mergedMangaReference.mergeId = manga.id
mergedMangaReference.mangaId = mergedManga.id
databaseHelper.insertMergedManga(mergedMangaReference).executeAsBlocking()
}
}
}
internal suspend fun restoreFlatMetadata(manga: Manga, backupFlatMetadata: BackupFlatMetadata) {
manga.id?.let { mangaId ->
databaseHelper.getFlatMetadataForManga(mangaId).executeOnIO().let {
if (it == null) {
val flatMetadata = backupFlatMetadata.getFlatMetadata(mangaId)
databaseHelper.insertFlatMetadataAsync(flatMetadata).await()
}
}
}
}
// SY <--
}
@@ -0,0 +1,237 @@
package eu.kanade.tachiyomi.data.backup.full
import android.content.Context
import android.net.Uri
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.full.models.BackupCategory
import eu.kanade.tachiyomi.data.backup.full.models.BackupFlatMetadata
import eu.kanade.tachiyomi.data.backup.full.models.BackupHistory
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.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.online.all.MergedSource
import exh.EXHMigrations
import exh.source.MERGED_SOURCE_ID
import okio.buffer
import okio.gzip
import okio.source
import java.util.Date
class FullBackupRestore(context: Context, notifier: BackupNotifier, private val online: Boolean) : AbstractBackupRestore<FullBackupManager>(context, notifier) {
override suspend fun performRestore(uri: Uri): Boolean {
// SY -->
throttleManager.resetThrottle()
// SY <--
backupManager = FullBackupManager(context)
val backupString = context.contentResolver.openInputStream(uri)!!.source().gzip().buffer().use { it.readByteArray() }
val backup = backupManager.parser.decodeFromByteArray(BackupSerializer, backupString)
restoreAmount = backup.backupManga.size + 1 /* SY --> */ + 1 /* SY <-- */ // +1 for categories, +1 for saved searches
// Restore categories
if (backup.backupCategories.isNotEmpty()) {
restoreCategories(backup.backupCategories)
}
// SY -->
if (backup.backupSavedSearches.isNotEmpty()) {
restoreSavedSearches(backup.backupSavedSearches)
}
// SY <--
// Store source mapping for error messages
sourceMapping = backup.backupSources.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 {
if (job?.isActive != true) {
return false
}
restoreManga(it, backup.backupCategories, online)
}
return true
}
private fun restoreCategories(backupCategories: List<BackupCategory>) {
db.inTransaction {
backupManager.restoreCategories(backupCategories)
}
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.categories))
}
// SY -->
private fun restoreSavedSearches(backupSavedSearches: List<BackupSavedSearch>) {
backupManager.restoreSavedSearches(backupSavedSearches)
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.saved_searches))
}
// SY <--
private suspend fun restoreManga(backupManga: BackupManga, backupCategories: List<BackupCategory>, online: Boolean) {
var manga = backupManga.getMangaImpl()
val chapters = backupManga.getChaptersImpl()
val categories = backupManga.categories
val history = backupManga.history
val tracks = backupManga.getTrackingImpl()
// SY -->
val mergedMangaReferences = backupManga.mergedMangaReferences
val flatMetadata = backupManga.flatMetadata
// SY <--
// SY -->
manga = EXHMigrations.migrateBackupEntry(manga)
// SY <--
val source = backupManager.sourceManager.get(manga.source)
val sourceName = sourceMapping[manga.source] ?: manga.source.toString()
try {
if (source != null || !online) {
restoreMangaData(manga, source, chapters, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata, online)
} else {
errors.add(Date() to "${manga.title} [$sourceName]: ${context.getString(R.string.source_not_found_name, sourceName)}")
}
} catch (e: Exception) {
errors.add(Date() to "${manga.title} [$sourceName]: ${e.message}")
}
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, manga.title)
}
/**
* Returns a manga restore observable
*
* @param manga manga data from json
* @param source source to get manga data from
* @param chapters chapters data from json
* @param categories categories data from json
* @param history history data from json
* @param tracks tracking data from json
*/
private suspend fun restoreMangaData(
manga: Manga,
source: Source?,
chapters: List<Chapter>,
categories: List<Int>,
history: List<BackupHistory>,
tracks: List<Track>,
backupCategories: List<BackupCategory>,
mergedMangaReferences: List<BackupMergedMangaReference>,
flatMetadata: BackupFlatMetadata?,
online: Boolean
) {
val dbManga = backupManager.getMangaFromDatabase(manga)
db.inTransaction {
if (dbManga == null) {
// Manga not in database
restoreMangaFetch(source, manga, chapters, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata, online)
} else { // Manga in database
// Copy information from manga already in database
backupManager.restoreMangaNoFetch(manga, dbManga)
// Fetch rest of manga information
restoreMangaNoFetch(source, manga, chapters, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata, online)
}
}
}
/**
* Fetches manga information
*
* @param manga manga that needs updating
* @param chapters chapters of manga that needs updating
* @param categories categories that need updating
*/
private suspend fun restoreMangaFetch(
source: Source?,
manga: Manga,
chapters: List<Chapter>,
categories: List<Int>,
history: List<BackupHistory>,
tracks: List<Track>,
backupCategories: List<BackupCategory>,
mergedMangaReferences: List<BackupMergedMangaReference>,
flatMetadata: BackupFlatMetadata?,
online: Boolean
) {
try {
val fetchedManga = backupManager.restoreMangaFetch(source, manga, online)
fetchedManga.id ?: return
if (online && source != null) {
// SY -->
if (source !is MergedSource) {
updateChapters(source, fetchedManga, chapters)
}
// SY <--
} else {
backupManager.restoreChaptersForMangaOffline(fetchedManga, chapters)
}
restoreExtraForManga(fetchedManga, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata)
updateTracking(fetchedManga, tracks)
} catch (e: Exception) {
errors.add(Date() to "${manga.title} - ${e.message}")
}
}
private suspend fun restoreMangaNoFetch(
source: Source?,
backupManga: Manga,
chapters: List<Chapter>,
categories: List<Int>,
history: List<BackupHistory>,
tracks: List<Track>,
backupCategories: List<BackupCategory>,
mergedMangaReferences: List<BackupMergedMangaReference>,
flatMetadata: BackupFlatMetadata?,
online: Boolean
) {
if (online && source != null) {
if (/* SY --> */ source !is MergedSource && /* SY <-- */ !backupManager.restoreChaptersForManga(backupManga, chapters)) {
updateChapters(source, backupManga, chapters)
}
} else {
backupManager.restoreChaptersForMangaOffline(backupManga, chapters)
}
restoreExtraForManga(backupManga, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata)
updateTracking(backupManga, tracks)
}
private suspend fun restoreExtraForManga(manga: Manga, categories: List<Int>, history: List<BackupHistory>, tracks: List<Track>, backupCategories: List<BackupCategory>, mergedMangaReferences: List<BackupMergedMangaReference>, flatMetadata: BackupFlatMetadata?) {
// Restore categories
backupManager.restoreCategoriesForManga(manga, categories, backupCategories)
// Restore history
backupManager.restoreHistoryForManga(history)
// Restore tracking
backupManager.restoreTrackForManga(manga, tracks)
// SY -->
// Restore merged manga references if its a merged manga
backupManager.restoreMergedMangaReferencesForManga(manga, mergedMangaReferences)
// Restore flat metadata for metadata sources
flatMetadata?.let { backupManager.restoreFlatMetadata(manga, it) }
// SY <--
}
}
@@ -0,0 +1,47 @@
package eu.kanade.tachiyomi.data.backup.full
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.full.models.BackupSerializer
import okio.buffer
import okio.gzip
import okio.source
class FullBackupRestoreValidator : AbstractBackupRestoreValidator() {
/**
* Checks for critical backup file data.
*
* @throws Exception if manga cannot be found.
* @return List of missing sources or missing trackers.
*/
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)
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 missingSources = sources
.filter { sourceManager.get(it.key) == null }
.values
.sorted()
val trackers = backup.backupManga
.flatMap { it.tracking }
.map { it.syncId }
.distinct()
val missingTrackers = trackers
.mapNotNull { trackManager.getService(it) }
.filter { !it.isLogged }
.map { context.getString(it.nameRes()) }
.sorted()
return Results(missingSources, missingTrackers)
}
}
@@ -0,0 +1,14 @@
package eu.kanade.tachiyomi.data.backup.full.models
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
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(),
// SY specific values
@ProtoNumber(600) var backupSavedSearches: List<BackupSavedSearch> = emptyList()
)
@@ -0,0 +1,37 @@
package eu.kanade.tachiyomi.data.backup.full.models
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.CategoryImpl
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
class BackupCategory(
@ProtoNumber(1) var name: String,
@ProtoNumber(2) var order: Int = 0,
// @ProtoNumber(3) val updateInterval: Int = 0, 1.x value not used in 0.x
// Bump by 100 to specify this is a 0.x value
@ProtoNumber(100) var flags: Int = 0,
// SY specific values
@ProtoNumber(600) var mangaOrder: List<Long> = emptyList()
) {
fun getCategoryImpl(): CategoryImpl {
return CategoryImpl().apply {
name = this@BackupCategory.name
flags = this@BackupCategory.flags
order = this@BackupCategory.order
mangaOrder = this@BackupCategory.mangaOrder
}
}
companion object {
fun copyFrom(category: Category): BackupCategory {
return BackupCategory(
name = category.name,
order = category.order,
flags = category.flags,
mangaOrder = category.mangaOrder
)
}
}
}
@@ -0,0 +1,56 @@
package eu.kanade.tachiyomi.data.backup.full.models
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.ChapterImpl
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class BackupChapter(
// in 1.x some of these values have different names
// url is called key in 1.x
@ProtoNumber(1) var url: String,
@ProtoNumber(2) var name: String,
@ProtoNumber(3) var scanlator: String? = null,
@ProtoNumber(4) var read: Boolean = false,
@ProtoNumber(5) var bookmark: Boolean = false,
// lastPageRead is called progress in 1.x
@ProtoNumber(6) var lastPageRead: Int = 0,
@ProtoNumber(7) var dateFetch: Long = 0,
@ProtoNumber(8) var dateUpload: Long = 0,
// chapterNumber is called number is 1.x
@ProtoNumber(9) var chapterNumber: Float = 0F,
@ProtoNumber(10) var sourceOrder: Int = 0,
) {
fun toChapterImpl(): ChapterImpl {
return ChapterImpl().apply {
url = this@BackupChapter.url
name = this@BackupChapter.name
chapter_number = this@BackupChapter.chapterNumber
scanlator = this@BackupChapter.scanlator
read = this@BackupChapter.read
bookmark = this@BackupChapter.bookmark
last_page_read = this@BackupChapter.lastPageRead
date_fetch = this@BackupChapter.dateFetch
date_upload = this@BackupChapter.dateUpload
source_order = this@BackupChapter.sourceOrder
}
}
companion object {
fun copyFrom(chapter: Chapter): BackupChapter {
return BackupChapter(
url = chapter.url,
name = chapter.name,
chapterNumber = chapter.chapter_number,
scanlator = chapter.scanlator,
read = chapter.read,
bookmark = chapter.bookmark,
lastPageRead = chapter.last_page_read,
dateFetch = chapter.date_fetch,
dateUpload = chapter.date_upload,
sourceOrder = chapter.source_order
)
}
}
}
@@ -0,0 +1,33 @@
package eu.kanade.tachiyomi.data.backup.full.models
import eu.kanade.tachiyomi.data.backup.full.models.metadata.BackupSearchMetadata
import eu.kanade.tachiyomi.data.backup.full.models.metadata.BackupSearchTag
import eu.kanade.tachiyomi.data.backup.full.models.metadata.BackupSearchTitle
import exh.metadata.metadata.base.FlatMetadata
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class BackupFlatMetadata(
@ProtoNumber(1) var searchMetadata: BackupSearchMetadata,
@ProtoNumber(2) var searchTags: List<BackupSearchTag> = emptyList(),
@ProtoNumber(3) var searchTitles: List<BackupSearchTitle> = emptyList()
) {
fun getFlatMetadata(mangaId: Long): FlatMetadata {
return FlatMetadata(
metadata = searchMetadata.getSearchMetadata(mangaId),
tags = searchTags.map { it.getSearchTag(mangaId) },
titles = searchTitles.map { it.getSearchTitle(mangaId) }
)
}
companion object {
fun copyFrom(flatMetadata: FlatMetadata): BackupFlatMetadata {
return BackupFlatMetadata(
searchMetadata = BackupSearchMetadata.copyFrom(flatMetadata.metadata),
searchTags = flatMetadata.tags.map { BackupSearchTag.copyFrom(it) },
searchTitles = flatMetadata.titles.map { BackupSearchTitle.copyFrom(it) }
)
}
}
}
@@ -0,0 +1,12 @@
package eu.kanade.tachiyomi.data.backup.full.models
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
object BackupFull {
fun getDefaultFilename(): String {
val date = SimpleDateFormat("yyyy-MM-dd_HH-mm", Locale.getDefault()).format(Date())
return "tachiyomi_$date.proto.gz"
}
}
@@ -0,0 +1,10 @@
package eu.kanade.tachiyomi.data.backup.full.models
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class BackupHistory(
@ProtoNumber(0) var url: String,
@ProtoNumber(1) var lastRead: Long
)
@@ -0,0 +1,90 @@
package eu.kanade.tachiyomi.data.backup.full.models
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.TrackImpl
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class BackupManga(
// in 1.x some of these values have different names
@ProtoNumber(1) var source: Long,
// url is called key in 1.x
@ProtoNumber(2) var url: String,
@ProtoNumber(3) var title: String = "",
@ProtoNumber(4) var artist: String? = null,
@ProtoNumber(5) var author: String? = null,
@ProtoNumber(6) var description: String? = null,
@ProtoNumber(7) var genre: List<String> = emptyList(),
@ProtoNumber(8) var status: Int = 0,
// thumbnailUrl is called cover in 1.x
@ProtoNumber(9) var thumbnailUrl: String? = null,
// @ProtoNumber(10) val customCover: String = "", 1.x value, not used in 0.x
// @ProtoNumber(11) val lastUpdate: Long = 0, 1.x value, not used in 0.x
// @ProtoNumber(12) val lastInit: Long = 0, 1.x value, not used in 0.x
@ProtoNumber(13) var dateAdded: Long = 0,
@ProtoNumber(14) var viewer: Int = 0,
// @ProtoNumber(15) val flags: Int = 0, 1.x value, not used in 0.x
@ProtoNumber(16) var chapters: List<BackupChapter> = emptyList(),
@ProtoNumber(17) var categories: List<Int> = emptyList(),
@ProtoNumber(18) var tracking: List<BackupTracking> = emptyList(),
// 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(),
// SY specific values
@ProtoNumber(600) var mergedMangaReferences: List<BackupMergedMangaReference> = emptyList(),
@ProtoNumber(601) var flatMetadata: BackupFlatMetadata? = null
) {
fun getMangaImpl(): MangaImpl {
return MangaImpl().apply {
url = this@BackupManga.url
title = this@BackupManga.title
artist = this@BackupManga.artist
author = this@BackupManga.author
description = this@BackupManga.description
genre = this@BackupManga.genre.joinToString()
status = this@BackupManga.status
thumbnail_url = this@BackupManga.thumbnailUrl
favorite = this@BackupManga.favorite
source = this@BackupManga.source
date_added = this@BackupManga.dateAdded
viewer = this@BackupManga.viewer
chapter_flags = this@BackupManga.chapterFlags
}
}
fun getChaptersImpl(): List<ChapterImpl> {
return chapters.map {
it.toChapterImpl()
}
}
fun getTrackingImpl(): List<TrackImpl> {
return tracking.map {
it.getTrackingImpl()
}
}
companion object {
fun copyFrom(manga: Manga): BackupManga {
return BackupManga(
url = manga.url,
title = manga.title,
artist = manga.artist,
author = manga.author,
description = manga.description,
genre = manga.getGenres() ?: emptyList(),
status = manga.status,
thumbnailUrl = manga.thumbnail_url,
favorite = manga.favorite,
source = manga.source,
dateAdded = manga.date_added,
viewer = manga.viewer,
chapterFlags = manga.chapter_flags
)
}
}
}
@@ -0,0 +1,51 @@
package eu.kanade.tachiyomi.data.backup.full.models
import exh.merged.sql.models.MergedMangaReference
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
/*
* SY merged manga backup class
*/
@Serializable
data class BackupMergedMangaReference(
@ProtoNumber(1) var isInfoManga: Boolean,
@ProtoNumber(2) var getChapterUpdates: Boolean,
@ProtoNumber(3) var chapterSortMode: Int,
@ProtoNumber(4) var chapterPriority: Int,
@ProtoNumber(5) var downloadChapters: Boolean,
@ProtoNumber(6) var mergeUrl: String,
@ProtoNumber(7) var mangaUrl: String,
@ProtoNumber(8) var mangaSourceId: Long
) {
fun getMergedMangaReference(): MergedMangaReference {
return MergedMangaReference(
isInfoManga = isInfoManga,
getChapterUpdates = getChapterUpdates,
chapterSortMode = chapterSortMode,
chapterPriority = chapterPriority,
downloadChapters = downloadChapters,
mergeUrl = mergeUrl,
mangaUrl = mangaUrl,
mangaSourceId = mangaSourceId,
mergeId = null,
mangaId = null,
id = null
)
}
companion object {
fun copyFrom(mergedMangaReference: MergedMangaReference): BackupMergedMangaReference {
return BackupMergedMangaReference(
isInfoManga = mergedMangaReference.isInfoManga,
getChapterUpdates = mergedMangaReference.getChapterUpdates,
chapterSortMode = mergedMangaReference.chapterSortMode,
chapterPriority = mergedMangaReference.chapterPriority,
downloadChapters = mergedMangaReference.downloadChapters,
mergeUrl = mergedMangaReference.mergeUrl,
mangaUrl = mergedMangaReference.mangaUrl,
mangaSourceId = mergedMangaReference.mangaSourceId
)
}
}
}
@@ -0,0 +1,15 @@
package eu.kanade.tachiyomi.data.backup.full.models
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
/*
* SY saved searches class
*/
@Serializable
data class BackupSavedSearch(
@ProtoNumber(1) val name: String,
@ProtoNumber(2) val query: String = "",
@ProtoNumber(3) val filterList: String = "",
@ProtoNumber(4) val source: Long = 0
)
@@ -0,0 +1,6 @@
package eu.kanade.tachiyomi.data.backup.full.models
import kotlinx.serialization.Serializer
@Serializer(forClass = Backup::class)
object BackupSerializer
@@ -0,0 +1,20 @@
package eu.kanade.tachiyomi.data.backup.full.models
import eu.kanade.tachiyomi.source.Source
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class BackupSource(
@ProtoNumber(0) var name: String = "",
@ProtoNumber(1) var sourceId: Long
) {
companion object {
fun copyFrom(source: Source): BackupSource {
return BackupSource(
name = source.name,
sourceId = source.id
)
}
}
}
@@ -0,0 +1,65 @@
package eu.kanade.tachiyomi.data.backup.full.models
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.database.models.TrackImpl
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class BackupTracking(
// in 1.x some of these values have different types or names
// syncId is called siteId in 1,x
@ProtoNumber(1) var syncId: Int,
// LibraryId is not null in 1.x
@ProtoNumber(2) var libraryId: Long,
@ProtoNumber(3) var mediaId: Int = 0,
// trackingUrl is called mediaUrl in 1.x
@ProtoNumber(4) var trackingUrl: String = "",
@ProtoNumber(5) var title: String = "",
// lastChapterRead is called last read, and it has been changed to a float in 1.x
@ProtoNumber(6) var lastChapterRead: Float = 0F,
@ProtoNumber(7) var totalChapters: Int = 0,
@ProtoNumber(8) var score: Float = 0F,
@ProtoNumber(9) var status: Int = 0,
// startedReadingDate is called startReadTime in 1.x
@ProtoNumber(10) var startedReadingDate: Long = 0,
// finishedReadingDate is called endReadTime in 1.x
@ProtoNumber(11) var finishedReadingDate: Long = 0,
) {
fun getTrackingImpl(): TrackImpl {
return TrackImpl().apply {
sync_id = this@BackupTracking.syncId
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()
total_chapters = this@BackupTracking.totalChapters
score = this@BackupTracking.score
status = this@BackupTracking.status
started_reading_date = this@BackupTracking.startedReadingDate
finished_reading_date = this@BackupTracking.finishedReadingDate
tracking_url = this@BackupTracking.trackingUrl
}
}
companion object {
fun copyFrom(track: Track): BackupTracking {
return BackupTracking(
syncId = track.sync_id,
mediaId = track.media_id,
// 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(),
totalChapters = track.total_chapters,
score = track.score,
status = track.status,
startedReadingDate = track.started_reading_date,
finishedReadingDate = track.finished_reading_date,
trackingUrl = track.tracking_url
)
}
}
}
@@ -0,0 +1,34 @@
package eu.kanade.tachiyomi.data.backup.full.models.metadata
import exh.metadata.sql.models.SearchMetadata
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class BackupSearchMetadata(
@ProtoNumber(1) var uploader: String? = null,
@ProtoNumber(2) var extra: String,
@ProtoNumber(3) var indexedExtra: String? = null,
@ProtoNumber(4) var extraVersion: Int
) {
fun getSearchMetadata(mangaId: Long): SearchMetadata {
return SearchMetadata(
mangaId = mangaId,
uploader = uploader,
extra = extra,
indexedExtra = indexedExtra,
extraVersion = extraVersion
)
}
companion object {
fun copyFrom(searchMetadata: SearchMetadata): BackupSearchMetadata {
return BackupSearchMetadata(
uploader = searchMetadata.uploader,
extra = searchMetadata.extra,
indexedExtra = searchMetadata.indexedExtra,
extraVersion = searchMetadata.extraVersion
)
}
}
}
@@ -0,0 +1,32 @@
package eu.kanade.tachiyomi.data.backup.full.models.metadata
import exh.metadata.sql.models.SearchTag
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class BackupSearchTag(
@ProtoNumber(1) var namespace: String? = null,
@ProtoNumber(2) var name: String,
@ProtoNumber(3) var type: Int
) {
fun getSearchTag(mangaId: Long): SearchTag {
return SearchTag(
id = null,
mangaId = mangaId,
namespace = namespace,
name = name,
type = type
)
}
companion object {
fun copyFrom(searchTag: SearchTag): BackupSearchTag {
return BackupSearchTag(
namespace = searchTag.namespace,
name = searchTag.name,
type = searchTag.type
)
}
}
}
@@ -0,0 +1,29 @@
package eu.kanade.tachiyomi.data.backup.full.models.metadata
import exh.metadata.sql.models.SearchTitle
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class BackupSearchTitle(
@ProtoNumber(1) var title: String,
@ProtoNumber(2) var type: Int
) {
fun getSearchTitle(mangaId: Long): SearchTitle {
return SearchTitle(
id = null,
mangaId = mangaId,
title = title,
type = type
)
}
companion object {
fun copyFrom(searchTitle: SearchTitle): BackupSearchTitle {
return BackupSearchTitle(
title = searchTitle.title,
type = searchTitle.type
)
}
}
}
@@ -1,22 +1,19 @@
package eu.kanade.tachiyomi.data.backup
package eu.kanade.tachiyomi.data.backup.legacy
import android.content.Context
import android.net.Uri
import com.github.salomonbrys.kotson.array
import com.github.salomonbrys.kotson.fromJson
import com.github.salomonbrys.kotson.jsonObject
import com.github.salomonbrys.kotson.obj
import com.github.salomonbrys.kotson.registerTypeAdapter
import com.github.salomonbrys.kotson.registerTypeHierarchyAdapter
import com.github.salomonbrys.kotson.set
import com.github.salomonbrys.kotson.string
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.AbstractBackupManager
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CATEGORY
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CATEGORY_MASK
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CHAPTER
@@ -25,22 +22,23 @@ import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_HIST
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_HISTORY_MASK
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_TRACK
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_TRACK_MASK
import eu.kanade.tachiyomi.data.backup.models.Backup
import eu.kanade.tachiyomi.data.backup.models.Backup.CATEGORIES
import eu.kanade.tachiyomi.data.backup.models.Backup.CHAPTERS
import eu.kanade.tachiyomi.data.backup.models.Backup.CURRENT_VERSION
import eu.kanade.tachiyomi.data.backup.models.Backup.EXTENSIONS
import eu.kanade.tachiyomi.data.backup.models.Backup.HISTORY
import eu.kanade.tachiyomi.data.backup.models.Backup.MANGA
import eu.kanade.tachiyomi.data.backup.models.Backup.SAVEDSEARCHES
import eu.kanade.tachiyomi.data.backup.models.Backup.TRACK
import eu.kanade.tachiyomi.data.backup.models.DHistory
import eu.kanade.tachiyomi.data.backup.serializer.CategoryTypeAdapter
import eu.kanade.tachiyomi.data.backup.serializer.ChapterTypeAdapter
import eu.kanade.tachiyomi.data.backup.serializer.HistoryTypeAdapter
import eu.kanade.tachiyomi.data.backup.serializer.MangaTypeAdapter
import eu.kanade.tachiyomi.data.backup.serializer.TrackTypeAdapter
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.CATEGORIES
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.CHAPTERS
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.CURRENT_VERSION
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.EXTENSIONS
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.HISTORY
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.MANGA
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.MERGEDMANGAREFERENCES
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.SAVEDSEARCHES
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.TRACK
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.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.ChapterImpl
@@ -50,64 +48,39 @@ 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.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.all.EHentai
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
import exh.EXHSavedSearch
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.source.online.all.MergedSource
import exh.eh.EHentaiThrottleManager
import java.lang.RuntimeException
import kotlin.math.max
import rx.Observable
import exh.merged.sql.models.MergedMangaReference
import exh.savedsearches.JsonSavedSearch
import exh.source.MERGED_SOURCE_ID
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import timber.log.Timber
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import xyz.nulldev.ts.api.http.serializer.FilterSerializer
import java.lang.RuntimeException
import kotlin.math.max
class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
class LegacyBackupManager(context: Context, version: Int = CURRENT_VERSION) : AbstractBackupManager(context) {
internal val databaseHelper: DatabaseHelper by injectLazy()
internal val sourceManager: SourceManager by injectLazy()
internal val trackManager: TrackManager by injectLazy()
private val preferences: PreferencesHelper by injectLazy()
/**
* Version of parser
*/
var version: Int = version
private set
/**
* Json Parser
*/
var parser: Gson = initParser()
/**
* Set version of parser
*
* @param version version of parser
*/
internal fun setVersion(version: Int) {
this.version = version
parser = initParser()
}
private fun initParser(): Gson = when (version) {
1 -> GsonBuilder().create()
2 ->
GsonBuilder()
.registerTypeAdapter<MangaImpl>(MangaTypeAdapter.build())
.registerTypeHierarchyAdapter<ChapterImpl>(ChapterTypeAdapter.build())
.registerTypeAdapter<CategoryImpl>(CategoryTypeAdapter.build())
.registerTypeAdapter<DHistory>(HistoryTypeAdapter.build())
.registerTypeHierarchyAdapter<TrackImpl>(TrackTypeAdapter.build())
.create()
else -> throw Exception("Json version unknown")
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()
else -> throw Exception("Unknown backup version")
}
/**
@@ -116,7 +89,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
* @param uri path of Uri
* @param isJob backup called from job
*/
fun createBackup(uri: Uri, flags: Int, isJob: Boolean): String? {
override fun createBackup(uri: Uri, flags: Int, isJob: Boolean): String? {
// Create root object
val root = JsonObject()
@@ -129,15 +102,20 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
// Create extension ID/name mapping
val extensionEntries = JsonArray()
// Merged Manga References
val mergedMangaReferenceEntries = JsonArray()
// Add value's to root
root[Backup.VERSION] = CURRENT_VERSION
root[Backup.MANGAS] = mangaEntries
root[CATEGORIES] = categoryEntries
root[EXTENSIONS] = extensionEntries
// SY -->
root[MERGEDMANGAREFERENCES] = mergedMangaReferenceEntries
// SY <--
databaseHelper.inTransaction {
// Get manga from database
val mangas = getFavoriteManga()
val mangas = getFavoriteManga()/* SY --> */.filterNot { it.source == MERGED_SOURCE_ID } + getMergedManga().filterNot { it.source == MERGED_SOURCE_ID } /* SY <-- */
val extensions: MutableSet<String> = mutableSetOf()
@@ -162,44 +140,40 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
backupExtensionInfo(extensionEntries, extensions)
// SY -->
root[SAVEDSEARCHES] =
Injekt.get<PreferencesHelper>().eh_savedSearches().get().joinToString(separator = "***")
Injekt.get<PreferencesHelper>().savedSearches().get().joinToString(separator = "***")
backupMergedMangaReferences(mergedMangaReferenceEntries)
// SY <--
}
try {
// When BackupCreatorJob
if (isJob) {
// Get dir of file and create
var dir = UniFile.fromUri(context, uri)
dir = dir.createDirectory("automatic")
val file: UniFile = (
if (isJob) {
// Get dir of file and create
var dir = UniFile.fromUri(context, uri)
dir = dir.createDirectory("automatic")
// Delete older backups
val numberOfBackups = numberOfBackups()
val backupRegex = Regex("""tachiyomi_\d+-\d+-\d+_\d+-\d+.json""")
dir.listFiles { _, filename -> backupRegex.matches(filename) }
.orEmpty()
.sortedByDescending { it.name }
.drop(numberOfBackups - 1)
.forEach { it.delete() }
// Delete older backups
val numberOfBackups = numberOfBackups()
val backupRegex = Regex("""tachiyomi_\d+-\d+-\d+_\d+-\d+.json""")
dir.listFiles { _, filename -> backupRegex.matches(filename) }
.orEmpty()
.sortedByDescending { it.name }
.drop(numberOfBackups - 1)
.forEach { it.delete() }
// Create new file to place backup
val newFile = dir.createFile(Backup.getDefaultFilename())
?: throw Exception("Couldn't create backup file")
newFile.openOutputStream().bufferedWriter().use {
parser.toJson(root, it)
// Create new file to place backup
dir.createFile(Backup.getDefaultFilename())
} else {
UniFile.fromUri(context, uri)
}
)
?: throw Exception("Couldn't create backup file")
return newFile.uri.toString()
} else {
val file = UniFile.fromUri(context, uri)
?: throw Exception("Couldn't create backup file")
file.openOutputStream().bufferedWriter().use {
parser.toJson(root, it)
}
return file.uri.toString()
file.openOutputStream().bufferedWriter().use {
parser.toJson(root, it)
}
return file.uri.toString()
} catch (e: Exception) {
Timber.e(e)
throw e
@@ -212,6 +186,13 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
}
}
// SY -->
private fun backupMergedMangaReferences(root: JsonArray) {
val mergedMangaReferences = databaseHelper.getMergedMangaReferences().executeAsBlocking()
mergedMangaReferences.forEach { root.add(parser.toJsonTree(it)) }
}
// SY <--
/**
* Backup the categories of library
*
@@ -291,21 +272,20 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
}
/**
* [Observable] that fetches manga information
* Fetches manga information
*
* @param source source of manga
* @param manga manga that needs updating
* @return [Observable] that contains manga
* @return Updated manga.
*/
fun restoreMangaFetchObservable(source: Source, manga: Manga): Observable<Manga> {
return source.fetchMangaDetails(manga)
.map { networkManga ->
manga.copyFrom(networkManga)
manga.favorite = true
manga.initialized = true
manga.id = insertManga(manga)
manga
}
suspend fun fetchManga(source: Source, manga: Manga): Manga {
val networkManga = source.getMangaDetails(manga.toMangaInfo())
return manga.also {
it.copyFrom(networkManga.toSManga())
it.favorite = true
it.initialized = true
it.id = insertManga(manga)
}
}
/**
@@ -315,31 +295,18 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
* @param manga manga that needs updating
* @return [Observable] that contains manga
*/
fun restoreChapterFetchObservable(source: Source, manga: Manga, chapters: List<Chapter>, throttleManager: EHentaiThrottleManager): Observable<Pair<List<Chapter>, List<Chapter>>> {
override suspend fun restoreChapters(source: Source, manga: Manga, chapters: List<Chapter>, throttleManager: EHentaiThrottleManager): Pair<List<Chapter>, List<Chapter>> {
// SY -->
return (
if (source is EHentai) {
source.fetchChapterList(manga, throttleManager::throttle)
} else {
source.fetchChapterList(manga)
}
).map {
if (it.last().chapter_number == -99F) {
chapters.forEach { chapter ->
chapter.name = "Chapter ${chapter.chapter_number} restored by dummy source"
}
syncChaptersWithSource(databaseHelper, chapters, manga, source)
} else {
syncChaptersWithSource(databaseHelper, it, manga, source)
return if (source is MergedSource) {
val syncedChapters = source.fetchChaptersAndSync(manga, false)
syncedChapters.first.onEach {
it.manga_id = manga.id
}
updateChapters(syncedChapters.first)
syncedChapters
} else {
super.restoreChapters(source, manga, chapters, throttleManager)
}
// SY <--
.doOnNext { pair ->
if (pair.first.isNotEmpty()) {
chapters.forEach { it.manga_id = manga.id }
insertChapters(chapters)
}
}
}
/**
@@ -384,7 +351,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
*/
internal fun restoreCategoriesForManga(manga: Manga, categories: List<String>) {
val dbCategories = databaseHelper.getCategories().executeAsBlocking()
val mangaCategoriesToUpdate = mutableListOf<MangaCategory>()
val mangaCategoriesToUpdate = ArrayList<MangaCategory>(categories.size)
for (backupCategoryStr in categories) {
for (dbCategory in dbCategories) {
if (backupCategoryStr == dbCategory.name) {
@@ -408,7 +375,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
*/
internal fun restoreHistoryForManga(history: List<DHistory>) {
// List containing history to be updated
val historyToBeUpdated = mutableListOf<History>()
val historyToBeUpdated = ArrayList<History>(history.size)
for ((url, lastRead) in history) {
val dbHistory = databaseHelper.getHistoryByChapterUrl(url).executeAsBlocking()
// Check if history already in database and update
@@ -437,14 +404,14 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
* @param tracks the track list to restore.
*/
internal fun restoreTrackForManga(manga: Manga, tracks: List<Track>) {
// Fix foreign keys with the current manga id
tracks.map { it.manga_id = manga.id!! }
// Get tracks from database
val dbTracks = databaseHelper.getTracks(manga).executeAsBlocking()
val trackToUpdate = mutableListOf<Track>()
val trackToUpdate = ArrayList<Track>(tracks.size)
tracks.forEach { track ->
// Fix foreign keys with the current manga id
track.manga_id = manga.id!!
val service = trackManager.getService(track.sync_id)
if (service != null && service.isLogged) {
var isInDatabase = false
@@ -499,37 +466,25 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
chapter.copyFrom(dbChapter)
break
}
}
// Filter the chapters that couldn't be found.
chapters.filter { it.id != null }
chapters.map { it.manga_id = manga.id }
insertChapters(chapters)
chapter.manga_id = manga.id
}
// Filter the chapters that couldn't be found.
updateChapters(chapters.filter { it.id != null })
return true
}
// SY -->
internal fun restoreSavedSearches(jsonSavedSearches: JsonElement) {
val backupSavedSearches = jsonSavedSearches.asString.split("***").toSet()
val filterSerializer = FilterSerializer()
val newSavedSearches = backupSavedSearches.mapNotNull {
try {
val id = it.substringBefore(':').toLong()
val content = JsonParser.parseString(it.substringAfter(':')).obj
val source = sourceManager.getOrStub(id)
if (source !is CatalogueSource) return@mapNotNull null
val originalFilters = source.getFilterList()
filterSerializer.deserialize(originalFilters, content["filters"].array)
Pair(
id,
EXHSavedSearch(
content["name"].string,
content["query"].string,
originalFilters
)
)
val content = Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
id to content
} catch (t: RuntimeException) {
// Load failed
Timber.e(t, "Failed to load saved search!")
@@ -540,24 +495,11 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
val currentSources = newSavedSearches.map { it.first }.toSet()
newSavedSearches += preferences.eh_savedSearches().get().mapNotNull {
newSavedSearches += preferences.savedSearches().get().mapNotNull {
try {
val id = it.substringBefore(':').toLong()
val content = JsonParser.parseString(it.substringAfter(':')).obj
if (id !in currentSources) return@mapNotNull null
val source = sourceManager.getOrStub(id)
if (source !is CatalogueSource) return@mapNotNull null
val originalFilters = source.getFilterList()
filterSerializer.deserialize(originalFilters, content["filters"].array)
Pair(
id,
EXHSavedSearch(
content["name"].string,
content["query"].string,
originalFilters
)
)
val content = Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
id to content
} catch (t: RuntimeException) {
// Load failed
Timber.e(t, "Failed to load saved search!")
@@ -566,61 +508,67 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
}
}.toMutableList()
val otherSerialized = preferences.eh_savedSearches().get().mapNotNull {
val otherSerialized = preferences.savedSearches().get().mapNotNull {
val sourceId = it.split(":")[0].toLongOrNull() ?: return@mapNotNull null
if (sourceId in currentSources) return@mapNotNull null
it
}
/*.filter {
!it.startsWith("${newSource.id}:")
}*/
val newSerialized = newSavedSearches.map {
"${it.first}:" + jsonObject(
"name" to it.second.name,
"query" to it.second.query,
"filters" to filterSerializer.serialize(it.second.filterList)
).toString()
"${it.first}:" + Json.encodeToString(it.second)
}
preferences.savedSearches().set((otherSerialized + newSerialized).toSet())
}
/**
* Restore the categories from Json
*
* @param jsonMergedMangaReferences array containing md manga references
*/
internal fun restoreMergedMangaReferences(jsonMergedMangaReferences: JsonArray) {
// 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
backupMergedMangaReferences.forEach { mergedMangaReference ->
// Used to know if the merged manga reference is already in the db
var found = false
for (dbMergedMangaReference in dbMergedMangaReferences) {
// If the mergedMangaReference is already in the db, assign the id to the file's mergedMangaReference
// and do nothing
if (mergedMangaReference.mergeUrl == dbMergedMangaReference.mergeUrl && mergedMangaReference.mangaUrl == dbMergedMangaReference.mangaUrl) {
mergedMangaReference.id = dbMergedMangaReference.id
mergedMangaReference.mergeId = dbMergedMangaReference.mergeId
mergedMangaReference.mangaId = dbMergedMangaReference.mangaId
found = true
break
}
}
// If the mergedMangaReference isn't in the db, remove the id and insert a new mergedMangaReference
// Store the inserted id in the mergedMangaReference
if (!found) {
// Let the db assign the id
var mergedManga = if (mergedMangaReference.mergeUrl != lastMergeManga?.url) databaseHelper.getManga(mergedMangaReference.mergeUrl, MERGED_SOURCE_ID).executeAsBlocking() else lastMergeManga
if (mergedManga == null) {
mergedManga = Manga.create(MERGED_SOURCE_ID).apply {
url = mergedMangaReference.mergeUrl
title = context.getString(R.string.refresh_merge)
}
mergedManga.id = databaseHelper.insertManga(mergedManga).executeAsBlocking().insertedId()
}
val manga = databaseHelper.getManga(mergedMangaReference.mangaUrl, mergedMangaReference.mangaSourceId).executeAsBlocking() ?: return@forEach
lastMergeManga = mergedManga
mergedMangaReference.mergeId = mergedManga.id
mergedMangaReference.mangaId = manga.id
mergedMangaReference.id = null
val result = databaseHelper.insertMergedManga(mergedMangaReference).executeAsBlocking()
mergedMangaReference.id = result.insertedId()
}
}
preferences.eh_savedSearches().set((otherSerialized + newSerialized).toSet())
}
// SY <--
/**
* Returns manga
*
* @return [Manga], null if not found
*/
internal fun getMangaFromDatabase(manga: Manga): Manga? =
databaseHelper.getManga(manga.url, manga.source).executeAsBlocking()
/**
* Returns list containing manga from library
*
* @return [Manga] from library
*/
internal fun getFavoriteManga(): List<Manga> =
databaseHelper.getFavoriteMangas().executeAsBlocking()
/**
* Inserts manga and returns id
*
* @return id of [Manga], null if not found
*/
internal fun insertManga(manga: Manga): Long? =
databaseHelper.insertManga(manga).executeAsBlocking().insertedId()
/**
* Inserts list of chapters
*/
private fun insertChapters(chapters: List<Chapter>) {
databaseHelper.updateChaptersBackup(chapters).executeAsBlocking()
}
/**
* Return number of backups.
*
* @return number of backups selected by user
*/
fun numberOfBackups(): Int = preferences.numberOfBackups().get()
}
@@ -0,0 +1,226 @@
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.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 java.util.Date
class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : AbstractBackupRestore<LegacyBackupManager>(context, notifier) {
override suspend fun performRestore(uri: Uri): Boolean {
// 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
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
// Restore categories
json.get(Backup.CATEGORIES)?.let { restoreCategories(it) }
// SY -->
json.get(Backup.SAVEDSEARCHES)?.let { restoreSavedSearches(it) }
json.get(Backup.MERGEDMANGAREFERENCES)?.let { restoreMergedMangaReferences(it) }
// SY <--
// Store source mapping for error messages
sourceMapping = LegacyBackupRestoreValidator.getSourceMapping(json)
// Restore individual manga
mangasJson.forEach {
if (job?.isActive != true) {
return false
}
restoreManga(it.asJsonObject)
}
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)
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.saved_searches))
}
private fun restoreMergedMangaReferences(mergedMangaReferencesJson: JsonElement) {
db.inTransaction {
backupManager.restoreMergedMangaReferences(mergedMangaReferencesJson.asJsonArray)
}
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.merged_references))
}
// SY <--
private suspend fun restoreManga(mangaJson: JsonObject) {
/* SY --> */ var /* SY <-- */ 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()
)
// EXH -->
manga = EXHMigrations.migrateBackupEntry(manga)
// <-- EXH
val source = backupManager.sourceManager.get(manga.source)
val sourceName = sourceMapping[manga.source] ?: manga.source.toString()
try {
if (source != null) {
restoreMangaData(manga, source, chapters, categories, history, tracks)
} else {
errors.add(Date() to "${manga.title} [$sourceName]: ${context.getString(R.string.source_not_found_name, sourceName)}")
}
} catch (e: Exception) {
errors.add(Date() to "${manga.title} [$sourceName]: ${e.message}")
}
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, manga.title)
}
/**
* Returns a manga restore observable
*
* @param manga manga data from json
* @param source source to get manga data from
* @param chapters chapters data from json
* @param categories categories data from json
* @param history history data from json
* @param tracks tracking data from json
*/
private suspend fun restoreMangaData(
manga: Manga,
source: Source,
chapters: List<Chapter>,
categories: List<String>,
history: List<DHistory>,
tracks: List<Track>
) {
val dbManga = backupManager.getMangaFromDatabase(manga)
db.inTransaction {
if (dbManga == null) {
// Manga not in database
restoreMangaFetch(source, manga, chapters, categories, history, tracks)
} else { // Manga in database
// Copy information from manga already in database
backupManager.restoreMangaNoFetch(manga, dbManga)
// Fetch rest of manga information
restoreMangaNoFetch(source, manga, chapters, categories, history, tracks)
}
}
}
/**
* Fetches manga information.
*
* @param manga manga that needs updating
* @param chapters chapters of manga that needs updating
* @param categories categories that need updating
*/
private suspend fun restoreMangaFetch(
source: Source,
manga: Manga,
chapters: List<Chapter>,
categories: List<String>,
history: List<DHistory>,
tracks: List<Track>
) {
try {
val fetchedManga = backupManager.fetchManga(source, manga)
fetchedManga.id ?: return
updateChapters(source, fetchedManga, chapters)
restoreExtraForManga(fetchedManga, categories, history, tracks)
updateTracking(fetchedManga, tracks)
} catch (e: Exception) {
errors.add(Date() to "${manga.title} - ${e.message}")
}
}
private suspend fun restoreMangaNoFetch(
source: Source,
backupManga: Manga,
chapters: List<Chapter>,
categories: List<String>,
history: List<DHistory>,
tracks: List<Track>
) {
if (!backupManager.restoreChaptersForManga(backupManga, chapters)) {
updateChapters(source, backupManga, chapters)
}
restoreExtraForManga(backupManga, categories, history, tracks)
updateTracking(backupManga, tracks)
}
private fun restoreExtraForManga(manga: Manga, categories: List<String>, history: List<DHistory>, tracks: List<Track>) {
// Restore categories
backupManager.restoreCategoriesForManga(manga, categories)
// Restore history
backupManager.restoreHistoryForManga(history)
// Restore tracking
backupManager.restoreTrackForManga(manga, tracks)
}
}
@@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.data.backup
package eu.kanade.tachiyomi.data.backup.legacy
import android.content.Context
import android.net.Uri
@@ -6,23 +6,17 @@ 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.models.Backup
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.SourceManager
import uy.kohesive.injekt.injectLazy
object BackupRestoreValidator {
private val sourceManager: SourceManager by injectLazy()
private val trackManager: TrackManager by injectLazy()
import eu.kanade.tachiyomi.data.backup.AbstractBackupRestoreValidator
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup
class LegacyBackupRestoreValidator : AbstractBackupRestoreValidator() {
/**
* Checks for critical backup file data.
*
* @throws Exception if version or manga cannot be found.
* @return List of missing sources or missing trackers.
*/
fun validate(context: Context, uri: Uri): Results {
override fun validate(context: Context, uri: Uri): Results {
val reader = JsonReader(context.contentResolver.openInputStream(uri)!!.bufferedReader())
val json = JsonParser.parseReader(reader).asJsonObject
@@ -51,22 +45,22 @@ object BackupRestoreValidator {
val missingTrackers = trackers
.mapNotNull { trackManager.getService(it) }
.filter { !it.isLogged }
.map { it.name }
.map { context.getString(it.nameRes()) }
.sorted()
return Results(missingSources, missingTrackers)
}
fun getSourceMapping(json: JsonObject): Map<Long, String> {
val extensionsMapping = json.get(Backup.EXTENSIONS) ?: return emptyMap()
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()
return extensionsMapping.asJsonArray
.map {
val items = it.asString.split(":")
items[0].toLong() to items[1]
}
.toMap()
}
}
data class Results(val missingSources: List<String>, val missingTrackers: List<String>)
}
@@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.data.backup.models
package eu.kanade.tachiyomi.data.backup.legacy.models
import java.text.SimpleDateFormat
import java.util.Date
@@ -17,8 +17,10 @@ object Backup {
const val EXTENSIONS = "extensions"
const val HISTORY = "history"
const val VERSION = "version"
// SY -->
const val SAVEDSEARCHES = "savedsearches"
const val MERGEDMANGAREFERENCES = "mergedmangareferences"
// SY <--
fun getDefaultFilename(): String {
@@ -1,3 +1,3 @@
package eu.kanade.tachiyomi.data.backup.models
package eu.kanade.tachiyomi.data.backup.legacy.models
data class DHistory(val url: String, val lastRead: Long)
@@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.data.backup.serializer
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
@@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.data.backup.serializer
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
@@ -1,8 +1,8 @@
package eu.kanade.tachiyomi.data.backup.serializer
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.models.DHistory
import eu.kanade.tachiyomi.data.backup.legacy.models.DHistory
/**
* JSON Serializer used to write / read [DHistory] to / from json
@@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.data.backup.serializer
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
@@ -0,0 +1,45 @@
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
)
}
}
}
}
@@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.data.backup.serializer
package eu.kanade.tachiyomi.data.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
@@ -10,8 +10,6 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.storage.saveTo
import java.io.File
import java.io.IOException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@@ -22,6 +20,8 @@ import okio.buffer
import okio.sink
import rx.Observable
import uy.kohesive.injekt.injectLazy
import java.io.File
import java.io.IOException
/**
* Class used to create chapter cache
@@ -56,10 +56,10 @@ class ChapterCache(private val context: Context) {
/** Cache class used for cache management. */
// --> EH
private var diskCache = setupDiskCache(prefs.eh_cacheSize().get().toLong())
private var diskCache = setupDiskCache(prefs.cacheSize().get().toLong())
init {
prefs.eh_cacheSize().asFlow()
prefs.cacheSize().asFlow()
.onEach {
// Save old cache for destruction later
val oldCache = diskCache
@@ -21,6 +21,12 @@ 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.md.similar.sql.mappers.SimilarTypeMapping
import exh.md.similar.sql.models.MangaSimilar
import exh.md.similar.sql.queries.SimilarQueries
import exh.merged.sql.mappers.MergedMangaTypeMapping
import exh.merged.sql.models.MergedMangaReference
import exh.merged.sql.queries.MergedQueries
import exh.metadata.sql.mappers.SearchMetadataTypeMapping
import exh.metadata.sql.mappers.SearchTagTypeMapping
import exh.metadata.sql.mappers.SearchTitleTypeMapping
@@ -36,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 /* EXH --> */, SearchMetadataQueries, SearchTagQueries, SearchTitleQueries /* EXH <-- */ {
MangaQueries, ChapterQueries, TrackQueries, CategoryQueries, MangaCategoryQueries, HistoryQueries /* SY --> */, SearchMetadataQueries, SearchTagQueries, SearchTitleQueries, MergedQueries, SimilarQueries /* SY <-- */ {
private val configuration = SupportSQLiteOpenHelper.Configuration.builder(context)
.name(DbOpenCallback.DATABASE_NAME)
@@ -51,11 +57,13 @@ open class DatabaseHelper(context: Context) :
.addTypeMapping(Category::class.java, CategoryTypeMapping())
.addTypeMapping(MangaCategory::class.java, MangaCategoryTypeMapping())
.addTypeMapping(History::class.java, HistoryTypeMapping())
// EXH -->
// SY -->
.addTypeMapping(SearchMetadata::class.java, SearchMetadataTypeMapping())
.addTypeMapping(SearchTag::class.java, SearchTagTypeMapping())
.addTypeMapping(SearchTitle::class.java, SearchTitleTypeMapping())
// EXH <--
.addTypeMapping(MergedMangaReference::class.java, MergedMangaTypeMapping())
.addTypeMapping(MangaSimilar::class.java, SimilarTypeMapping())
// SY <--
.build()
inline fun inTransaction(block: () -> Unit) = db.inTransaction(block)
@@ -7,8 +7,9 @@ import eu.kanade.tachiyomi.data.database.tables.ChapterTable
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.MergedTable
import eu.kanade.tachiyomi.data.database.tables.TrackTable
import exh.md.similar.sql.tables.SimilarTable
import exh.merged.sql.tables.MergedTable
import exh.metadata.sql.tables.SearchMetadataTable
import exh.metadata.sql.tables.SearchTagTable
import exh.metadata.sql.tables.SearchTitleTable
@@ -24,7 +25,7 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
/**
* Version of the database.
*/
const val DATABASE_VERSION = /* SY --> */ 3 /* SY <-- */
const val DATABASE_VERSION = /* SY --> */ 5 /* SY <-- */
}
override fun onCreate(db: SupportSQLiteDatabase) = with(db) {
@@ -34,14 +35,13 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
execSQL(CategoryTable.createTableQuery)
execSQL(MangaCategoryTable.createTableQuery)
execSQL(HistoryTable.createTableQuery)
// EXH -->
// SY -->
execSQL(SearchMetadataTable.createTableQuery)
execSQL(SearchTagTable.createTableQuery)
execSQL(SearchTitleTable.createTableQuery)
// EXH <--
// AZ -->
execSQL(MergedTable.createTableQuery)
// AZ <--
execSQL(SimilarTable.createTableQuery)
// SY <--
// DB indexes
execSQL(MangaTable.createUrlIndexQuery)
@@ -49,17 +49,16 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
execSQL(ChapterTable.createMangaIdIndexQuery)
execSQL(ChapterTable.createUnreadChaptersIndexQuery)
execSQL(HistoryTable.createChapterIdIndexQuery)
// EXH -->
db.execSQL(SearchMetadataTable.createUploaderIndexQuery)
db.execSQL(SearchMetadataTable.createIndexedExtraIndexQuery)
db.execSQL(SearchTagTable.createMangaIdIndexQuery)
db.execSQL(SearchTagTable.createNamespaceNameIndexQuery)
db.execSQL(SearchTitleTable.createMangaIdIndexQuery)
db.execSQL(SearchTitleTable.createTitleIndexQuery)
// EXH <--
// AZ -->
// SY -->
execSQL(SearchMetadataTable.createUploaderIndexQuery)
execSQL(SearchMetadataTable.createIndexedExtraIndexQuery)
execSQL(SearchTagTable.createMangaIdIndexQuery)
execSQL(SearchTagTable.createNamespaceNameIndexQuery)
execSQL(SearchTitleTable.createMangaIdIndexQuery)
execSQL(SearchTitleTable.createTitleIndexQuery)
execSQL(MergedTable.createIndexQuery)
// AZ <--
execSQL(SimilarTable.createMangaIdIndexQuery)
// SY <--
}
override fun onUpgrade(db: SupportSQLiteDatabase, oldVersion: Int, newVersion: Int) {
@@ -70,6 +69,15 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
db.execSQL(MangaTable.addDateAdded)
db.execSQL(MangaTable.backfillDateAdded)
}
if (oldVersion < 4) {
db.execSQL(MergedTable.dropTableQuery)
db.execSQL(MergedTable.createTableQuery)
db.execSQL(MergedTable.createIndexQuery)
}
if (oldVersion < 5) {
db.execSQL(SimilarTable.createTableQuery)
db.execSQL(SimilarTable.createMangaIdIndexQuery)
}
}
override fun onConfigure(db: SupportSQLiteDatabase) {
@@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.data.database.mappers
import android.content.ContentValues
import android.database.Cursor
import androidx.core.content.contentValuesOf
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
import com.pushtorefresh.storio.sqlite.operations.delete.DefaultDeleteResolver
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
@@ -36,16 +36,14 @@ class CategoryPutResolver : DefaultPutResolver<Category>() {
.whereArgs(obj.id)
.build()
override fun mapToContentValues(obj: Category) = ContentValues(4).apply {
put(COL_ID, obj.id)
put(COL_NAME, obj.name)
put(COL_ORDER, obj.order)
put(COL_FLAGS, obj.flags)
// SY -->
val orderString = obj.mangaOrder.joinToString("/")
put(COL_MANGA_ORDER, orderString)
// SY <--
}
override fun mapToContentValues(obj: Category) =
contentValuesOf(
COL_ID to obj.id,
COL_NAME to obj.name,
COL_ORDER to obj.order,
COL_FLAGS to obj.flags,
COL_MANGA_ORDER to obj.mangaOrder.joinToString("/")
)
}
class CategoryGetResolver : DefaultGetResolver<Category>() {
@@ -58,7 +56,7 @@ class CategoryGetResolver : DefaultGetResolver<Category>() {
// SY -->
val orderString = cursor.getString(cursor.getColumnIndex(COL_MANGA_ORDER))
mangaOrder = orderString?.split("/")?.mapNotNull { it.toLongOrNull() } ?: emptyList()
mangaOrder = orderString?.split("/")?.mapNotNull { it.toLongOrNull() }.orEmpty()
// SY <--
}
}
@@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.data.database.mappers
import android.content.ContentValues
import android.database.Cursor
import androidx.core.content.contentValuesOf
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
import com.pushtorefresh.storio.sqlite.operations.delete.DefaultDeleteResolver
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
@@ -43,20 +43,21 @@ class ChapterPutResolver : DefaultPutResolver<Chapter>() {
.whereArgs(obj.id)
.build()
override fun mapToContentValues(obj: Chapter) = ContentValues(11).apply {
put(COL_ID, obj.id)
put(COL_MANGA_ID, obj.manga_id)
put(COL_URL, obj.url)
put(COL_NAME, obj.name)
put(COL_READ, obj.read)
put(COL_SCANLATOR, obj.scanlator)
put(COL_BOOKMARK, obj.bookmark)
put(COL_DATE_FETCH, obj.date_fetch)
put(COL_DATE_UPLOAD, obj.date_upload)
put(COL_LAST_PAGE_READ, obj.last_page_read)
put(COL_CHAPTER_NUMBER, obj.chapter_number)
put(COL_SOURCE_ORDER, obj.source_order)
}
override fun mapToContentValues(obj: Chapter) =
contentValuesOf(
COL_ID to obj.id,
COL_MANGA_ID to obj.manga_id,
COL_URL to obj.url,
COL_NAME to obj.name,
COL_READ to obj.read,
COL_SCANLATOR to obj.scanlator,
COL_BOOKMARK to obj.bookmark,
COL_DATE_FETCH to obj.date_fetch,
COL_DATE_UPLOAD to obj.date_upload,
COL_LAST_PAGE_READ to obj.last_page_read,
COL_CHAPTER_NUMBER to obj.chapter_number,
COL_SOURCE_ORDER to obj.source_order
)
}
class ChapterGetResolver : DefaultGetResolver<Chapter>() {
@@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.data.database.mappers
import android.content.ContentValues
import android.database.Cursor
import androidx.core.content.contentValuesOf
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
import com.pushtorefresh.storio.sqlite.operations.delete.DefaultDeleteResolver
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
@@ -35,12 +35,13 @@ open class HistoryPutResolver : DefaultPutResolver<History>() {
.whereArgs(obj.id)
.build()
override fun mapToContentValues(obj: History) = ContentValues(4).apply {
put(COL_ID, obj.id)
put(COL_CHAPTER_ID, obj.chapter_id)
put(COL_LAST_READ, obj.last_read)
put(COL_TIME_READ, obj.time_read)
}
override fun mapToContentValues(obj: History) =
contentValuesOf(
COL_ID to obj.id,
COL_CHAPTER_ID to obj.chapter_id,
COL_LAST_READ to obj.last_read,
COL_TIME_READ to obj.time_read
)
}
class HistoryGetResolver : DefaultGetResolver<History>() {
@@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.data.database.mappers
import android.content.ContentValues
import android.database.Cursor
import androidx.core.content.contentValuesOf
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
import com.pushtorefresh.storio.sqlite.operations.delete.DefaultDeleteResolver
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
@@ -33,11 +33,12 @@ class MangaCategoryPutResolver : DefaultPutResolver<MangaCategory>() {
.whereArgs(obj.id)
.build()
override fun mapToContentValues(obj: MangaCategory) = ContentValues(3).apply {
put(COL_ID, obj.id)
put(COL_MANGA_ID, obj.manga_id)
put(COL_CATEGORY_ID, obj.category_id)
}
override fun mapToContentValues(obj: MangaCategory) =
contentValuesOf(
COL_ID to obj.id,
COL_MANGA_ID to obj.manga_id,
COL_CATEGORY_ID to obj.category_id
)
}
class MangaCategoryGetResolver : DefaultGetResolver<MangaCategory>() {
@@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.data.database.mappers
import android.content.ContentValues
import android.database.Cursor
import androidx.core.content.contentValuesOf
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
import com.pushtorefresh.storio.sqlite.operations.delete.DefaultDeleteResolver
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
@@ -48,27 +48,28 @@ class MangaPutResolver : DefaultPutResolver<Manga>() {
.whereArgs(obj.id)
.build()
override fun mapToContentValues(obj: Manga) = ContentValues(17).apply {
put(COL_ID, obj.id)
put(COL_SOURCE, obj.source)
put(COL_URL, obj.url)
// SY -->
put(COL_ARTIST, obj.originalArtist)
put(COL_AUTHOR, obj.originalAuthor)
put(COL_DESCRIPTION, obj.originalDescription)
put(COL_GENRE, obj.originalGenre)
put(COL_TITLE, obj.originalTitle)
// SY <--
put(COL_STATUS, obj.status)
put(COL_THUMBNAIL_URL, obj.thumbnail_url)
put(COL_FAVORITE, obj.favorite)
put(COL_LAST_UPDATE, obj.last_update)
put(COL_INITIALIZED, obj.initialized)
put(COL_VIEWER, obj.viewer)
put(COL_CHAPTER_FLAGS, obj.chapter_flags)
put(COL_COVER_LAST_MODIFIED, obj.cover_last_modified)
put(COL_DATE_ADDED, obj.date_added)
}
override fun mapToContentValues(obj: Manga) =
contentValuesOf(
COL_ID to obj.id,
COL_SOURCE to obj.source,
COL_URL to obj.url,
// SY -->
COL_ARTIST to obj.originalArtist,
COL_AUTHOR to obj.originalAuthor,
COL_DESCRIPTION to obj.originalDescription,
COL_GENRE to obj.originalGenre,
COL_TITLE to obj.originalTitle,
// SY <--
COL_STATUS to obj.status,
COL_THUMBNAIL_URL to obj.thumbnail_url,
COL_FAVORITE to obj.favorite,
COL_LAST_UPDATE to obj.last_update,
COL_INITIALIZED to obj.initialized,
COL_VIEWER to obj.viewer,
COL_CHAPTER_FLAGS to obj.chapter_flags,
COL_COVER_LAST_MODIFIED to obj.cover_last_modified,
COL_DATE_ADDED to obj.date_added
)
}
interface BaseMangaGetResolver {
@@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.data.database.mappers
import android.content.ContentValues
import android.database.Cursor
import androidx.core.content.contentValuesOf
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
import com.pushtorefresh.storio.sqlite.operations.delete.DefaultDeleteResolver
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
@@ -44,21 +44,22 @@ class TrackPutResolver : DefaultPutResolver<Track>() {
.whereArgs(obj.id)
.build()
override fun mapToContentValues(obj: Track) = ContentValues(10).apply {
put(COL_ID, obj.id)
put(COL_MANGA_ID, obj.manga_id)
put(COL_SYNC_ID, obj.sync_id)
put(COL_MEDIA_ID, obj.media_id)
put(COL_LIBRARY_ID, obj.library_id)
put(COL_TITLE, obj.title)
put(COL_LAST_CHAPTER_READ, obj.last_chapter_read)
put(COL_TOTAL_CHAPTERS, obj.total_chapters)
put(COL_STATUS, obj.status)
put(COL_TRACKING_URL, obj.tracking_url)
put(COL_SCORE, obj.score)
put(COL_START_DATE, obj.started_reading_date)
put(COL_FINISH_DATE, obj.finished_reading_date)
}
override fun mapToContentValues(obj: Track) =
contentValuesOf(
COL_ID to obj.id,
COL_MANGA_ID to obj.manga_id,
COL_SYNC_ID to obj.sync_id,
COL_MEDIA_ID to obj.media_id,
COL_LIBRARY_ID to obj.library_id,
COL_TITLE to obj.title,
COL_LAST_CHAPTER_READ to obj.last_chapter_read,
COL_TOTAL_CHAPTERS to obj.total_chapters,
COL_STATUS to obj.status,
COL_TRACKING_URL to obj.tracking_url,
COL_SCORE to obj.score,
COL_START_DATE to obj.started_reading_date,
COL_FINISH_DATE to obj.finished_reading_date
)
}
class TrackGetResolver : DefaultGetResolver<Track>() {
@@ -5,4 +5,8 @@ class LibraryManga : MangaImpl() {
var unread: Int = 0
var category: Int = 0
// SY -->
var read: Int = 0
// SY <--
}
@@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.data.database.models
import eu.kanade.tachiyomi.source.model.SManga
import tachiyomi.source.model.MangaInfo
interface Manga : SManga {
@@ -104,3 +105,16 @@ interface Manga : SManga {
}
}
}
fun Manga.toMangaInfo(): MangaInfo {
return MangaInfo(
artist = this.artist ?: "",
author = this.author ?: "",
cover = this.thumbnail_url ?: "",
description = this.description ?: "",
genres = this.getGenres() ?: emptyList(),
key = this.url,
status = this.status,
title = this.title
)
}
@@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaChapter
import eu.kanade.tachiyomi.data.database.resolvers.ChapterBackupPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.ChapterKnownBackupPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.ChapterProgressPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.ChapterSourceOrderPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterGetResolver
@@ -15,9 +16,9 @@ import java.util.Date
interface ChapterQueries : DbProvider {
// SY -->
fun getChapters(manga: Manga) = getChaptersByMangaId(manga.id)
fun getChapters(manga: Manga) = getChapters(manga.id)
fun getChaptersByMangaId(mangaId: Long?) = db.get()
fun getChapters(mangaId: Long?) = db.get()
.listOfObjects(Chapter::class.java)
.withQuery(
Query.builder()
@@ -27,15 +28,6 @@ interface ChapterQueries : DbProvider {
.build()
)
.prepare()
fun getChaptersByMergedMangaId(mangaId: Long) = db.get()
.listOfObjects(Chapter::class.java)
.withQuery(
RawQuery.builder()
.query(getMergedChaptersQuery(mangaId))
.build()
)
.prepare()
// SY <--
fun getRecentChapters(date: Date) = db.get()
@@ -94,6 +86,17 @@ interface ChapterQueries : DbProvider {
.build()
)
.prepare()
fun getChaptersReadByUrls(urls: List<String>) = db.get()
.listOfObjects(Chapter::class.java)
.withQuery(
Query.builder()
.table(ChapterTable.TABLE)
.where("${ChapterTable.COL_URL} IN (?) AND (${ChapterTable.COL_READ} = 1 OR ${ChapterTable.COL_LAST_PAGE_READ} != 0)")
.whereArgs(urls.joinToString { "\"$it\"" })
.build()
)
.prepare()
// SY <--
fun insertChapter(chapter: Chapter) = db.put().`object`(chapter).prepare()
@@ -109,6 +112,11 @@ interface ChapterQueries : DbProvider {
.withPutResolver(ChapterBackupPutResolver())
.prepare()
fun updateKnownChaptersBackup(chapters: List<Chapter>) = db.put()
.objects(chapters)
.withPutResolver(ChapterKnownBackupPutResolver())
.prepare()
fun updateChapterProgress(chapter: Chapter) = db.put()
.`object`(chapter)
.withPutResolver(ChapterProgressPutResolver())
@@ -18,41 +18,25 @@ interface HistoryQueries : DbProvider {
*/
fun insertHistory(history: History) = db.put().`object`(history).prepare()
// SY -->
/**
* Returns history of recent manga containing last read chapter
* @param date recent date range
* @param limit the limit of manga to grab
* @param offset offset the db by
* @param search what to search in the db history
*/
fun getRecentManga(date: Date, offset: Int = 0, search: String = "") = db.get()
fun getRecentManga(date: Date, limit: Int = 25, offset: Int = 0, search: String = "") = db.get()
.listOfObjects(MangaChapterHistory::class.java)
.withQuery(
RawQuery.builder()
.query(getRecentMangasQuery(offset, search))
.args(date.time)
.query(getRecentMangasQuery(search))
.args(date.time, limit, offset)
.observesTables(HistoryTable.TABLE)
.build()
)
.withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
.prepare()
/**
* Returns history of recent manga containing last read chapter in 25s
* @param date recent date range
* @offset offset the db by
*/
fun getRecentMangaLimit(date: Date, limit: Int = 0, search: String = "") = db.get()
.listOfObjects(MangaChapterHistory::class.java)
.withQuery(
RawQuery.builder()
.query(getRecentMangasLimitQuery(limit, search))
.args(date.time)
.observesTables(HistoryTable.TABLE)
.build()
)
.withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
.prepare()
// SY <--
fun getHistoryByMangaId(mangaId: Long) = db.get()
.listOfObjects(History::class.java)
.withQuery(
@@ -12,12 +12,14 @@ import eu.kanade.tachiyomi.data.database.resolvers.MangaFavoritePutResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaFlagsPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaInfoPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaLastUpdatedPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaMigrationPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaTitlePutResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaViewerPutResolver
import eu.kanade.tachiyomi.data.database.tables.CategoryTable
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable
import eu.kanade.tachiyomi.data.database.tables.MangaTable
import exh.merged.sql.tables.MergedTable
import exh.metadata.sql.tables.SearchMetadataTable
interface MangaQueries : DbProvider {
@@ -77,11 +79,11 @@ interface MangaQueries : DbProvider {
.prepare()
// SY -->
fun getMergedMangas(id: Long) = db.get()
fun getReadNotInLibraryMangas() = db.get()
.listOfObjects(Manga::class.java)
.withQuery(
RawQuery.builder()
.query(getMergedMangaQuery(id))
.query(getReadMangaNotInLibraryQuery())
.build()
)
.prepare()
@@ -95,6 +97,11 @@ interface MangaQueries : DbProvider {
.`object`(manga)
.withPutResolver(MangaInfoPutResolver(true))
.prepare()
fun updateMangaMigrate(manga: Manga) = db.put()
.`object`(manga)
.withPutResolver(MangaMigrationPutResolver())
.prepare()
// SY <--
fun insertManga(manga: Manga) = db.put().`object`(manga).prepare()
@@ -106,6 +113,11 @@ interface MangaQueries : DbProvider {
.withPutResolver(MangaFlagsPutResolver())
.prepare()
fun updateFlags(mangas: List<Manga>) = db.put()
.objects(mangas)
.withPutResolver(MangaFlagsPutResolver(true))
.prepare()
fun updateLastUpdated(manga: Manga) = db.put()
.`object`(manga)
.withPutResolver(MangaLastUpdatedPutResolver())
@@ -139,7 +151,7 @@ interface MangaQueries : DbProvider {
.byQuery(
DeleteQuery.builder()
.table(MangaTable.TABLE)
.where("${MangaTable.COL_FAVORITE} = ?")
.where("${MangaTable.COL_FAVORITE} = ? AND ${MangaTable.COL_ID} NOT IN (SELECT ${MergedTable.COL_MANGA_ID} FROM ${MergedTable.TABLE})")
.whereArgs(0)
.build()
)
@@ -1,21 +1,48 @@
package eu.kanade.tachiyomi.data.database.queries
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
import eu.kanade.tachiyomi.data.database.tables.HistoryTable as History
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable as MangaCategory
import eu.kanade.tachiyomi.data.database.tables.MangaTable as Manga
import eu.kanade.tachiyomi.data.database.tables.MergedTable as Merged
import exh.merged.sql.tables.MergedTable as Merged
// SY -->
/**
* Query to get the manga merged into a merged manga
*/
fun getMergedMangaQuery(id: Long) =
fun getMergedMangaQuery() =
"""
SELECT ${Manga.TABLE}.*
FROM (
SELECT ${Merged.COL_MANGA_ID} FROM ${Merged.TABLE} WHERE $(Merged.COL_MERGE_ID} = $id
SELECT ${Merged.COL_MANGA_ID} FROM ${Merged.TABLE} WHERE ${Merged.COL_MERGE_ID} = ?
) AS M
JOIN ${Manga.TABLE}
ON ${Manga.TABLE}.${Manga.COL_ID} = M.${Merged.COL_MANGA_ID}
"""
/**
* Query to get all the manga that are merged into other manga
*/
fun getAllMergedMangaQuery() =
"""
SELECT ${Manga.TABLE}.*
FROM (
SELECT ${Merged.COL_MANGA_ID} FROM ${Merged.TABLE}
) AS M
JOIN ${Manga.TABLE}
ON ${Manga.TABLE}.${Manga.COL_ID} = M.${Merged.COL_MANGA_ID}
"""
/**
* Query to get the manga merged into a merged manga using the Url
*/
fun getMergedMangaFromUrlQuery() =
"""
SELECT ${Manga.TABLE}.*
FROM (
SELECT ${Merged.COL_MANGA_ID} FROM ${Merged.TABLE} WHERE ${Merged.COL_MERGE_URL} = ?
) AS M
JOIN ${Manga.TABLE}
ON ${Manga.TABLE}.${Manga.COL_ID} = M.${Merged.COL_MANGA_ID}
@@ -24,16 +51,27 @@ fun getMergedMangaQuery(id: Long) =
/**
* Query to get the chapters of all manga in a merged manga
*/
fun getMergedChaptersQuery(id: Long) =
fun getMergedChaptersQuery() =
"""
SELECT ${Chapter.TABLE}.*
FROM (
SELECT ${Merged.COL_MANGA_ID} FROM ${Merged.TABLE} WHERE $(Merged.COL_MERGE_ID} = $id
SELECT ${Merged.COL_MANGA_ID} FROM ${Merged.TABLE} WHERE ${Merged.COL_MERGE_ID} = ?
) AS M
JOIN ${Chapter.TABLE}
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = M.${Merged.COL_MANGA_ID}
"""
// SY <--
/**
* Query to get manga that are not in library, but have read chapters
*/
fun getReadMangaNotInLibraryQuery() =
"""
SELECT ${Manga.TABLE}.*
FROM ${Manga.TABLE}
WHERE ${Manga.COL_FAVORITE} = 0 AND ${Manga.COL_ID} IN(
SELECT ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} FROM ${Chapter.TABLE} WHERE ${Chapter.COL_READ} = 1
)
"""
/**
* Query to get the manga from the library, with their categories and unread count.
@@ -42,23 +80,55 @@ val libraryQuery =
"""
SELECT M.*, COALESCE(MC.${MangaCategory.COL_CATEGORY_ID}, 0) AS ${Manga.COL_CATEGORY}
FROM (
SELECT ${Manga.TABLE}.*, COALESCE(C.unread, 0) AS ${Manga.COL_UNREAD}
FROM ${Manga.TABLE}
LEFT JOIN (
SELECT ${Chapter.COL_MANGA_ID}, COUNT(*) AS unread
FROM ${Chapter.TABLE}
WHERE ${Chapter.COL_READ} = 0
GROUP BY ${Chapter.COL_MANGA_ID}
) AS C
ON ${Manga.COL_ID} = C.${Chapter.COL_MANGA_ID}
WHERE ${Manga.COL_FAVORITE} = 1
GROUP BY ${Manga.COL_ID}
SELECT ${Manga.TABLE}.*, COALESCE(C.unread, 0) AS ${Manga.COL_UNREAD}, COALESCE(R.read, 0) AS ${Manga.COL_READ}
FROM ${Manga.TABLE}
LEFT JOIN (
SELECT ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}, COUNT(*) AS unread
FROM ${Chapter.TABLE}
WHERE ${Chapter.COL_READ} = 0
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
) AS C
ON ${Manga.TABLE}.${Manga.COL_ID} = C.${Chapter.COL_MANGA_ID}
LEFT JOIN (
SELECT ${Chapter.COL_MANGA_ID}, COUNT(*) AS read
FROM ${Chapter.TABLE}
WHERE ${Chapter.COL_READ} = 1
GROUP BY ${Chapter.COL_MANGA_ID}
) AS R
ON ${Manga.TABLE}.${Manga.COL_ID} = R.${Chapter.COL_MANGA_ID}
WHERE ${Manga.COL_FAVORITE} = 1 AND ${Manga.COL_SOURCE} <> $MERGED_SOURCE_ID
GROUP BY ${Manga.TABLE}.${Manga.COL_ID}
UNION
SELECT ${Manga.TABLE}.*, COALESCE(C.unread, 0) AS ${Manga.COL_UNREAD}, COALESCE(R.read, 0) AS ${Manga.COL_READ}
FROM ${Manga.TABLE}
LEFT JOIN (
SELECT ${Merged.TABLE}.${Merged.COL_MERGE_ID}, COUNT(*) as unread
FROM ${Merged.TABLE}
JOIN ${Chapter.TABLE}
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = ${Merged.TABLE}.${Merged.COL_MANGA_ID}
WHERE ${Chapter.TABLE}.${Chapter.COL_READ} = 0
GROUP BY ${Merged.TABLE}.${Merged.COL_MERGE_ID}
) AS C
ON ${Manga.TABLE}.${Manga.COL_ID} = C.${Merged.COL_MERGE_ID}
LEFT JOIN (
SELECT ${Merged.TABLE}.${Merged.COL_MERGE_ID}, COUNT(*) as read
FROM ${Merged.TABLE}
JOIN ${Chapter.TABLE}
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = ${Merged.TABLE}.${Merged.COL_MANGA_ID}
WHERE ${Chapter.TABLE}.${Chapter.COL_READ} = 1
GROUP BY ${Merged.TABLE}.${Merged.COL_MERGE_ID}
) AS R
ON ${Manga.TABLE}.${Manga.COL_ID} = R.${Merged.COL_MERGE_ID}
WHERE ${Manga.COL_FAVORITE} = 1 AND ${Manga.COL_SOURCE} = $MERGED_SOURCE_ID
GROUP BY ${Manga.TABLE}.${Manga.COL_ID}
ORDER BY ${Manga.COL_TITLE}
) AS M
LEFT JOIN (
SELECT * FROM ${MangaCategory.TABLE}) AS MC
ON MC.${MangaCategory.COL_MANGA_ID} = M.${Manga.COL_ID}
SELECT * FROM ${MangaCategory.TABLE}
) AS MC
ON MC.${MangaCategory.COL_MANGA_ID} = M.${Manga.COL_ID};
"""
// SY <--
/**
* Query to get the recent chapters of manga from the library up to a date.
@@ -78,36 +148,8 @@ fun getRecentsQuery() =
* The max_last_read table contains the most recent chapters grouped by manga
* The select statement returns all information of chapters that have the same id as the chapter in max_last_read
* and are read after the given time period
* @return return limit is 25
*/
// SY -->
fun getRecentMangasQuery(offset: Int = 0, search: String = "") =
"""
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
FROM ${Manga.TABLE}
JOIN ${Chapter.TABLE}
ON ${Manga.TABLE}.${Manga.COL_ID} = ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
JOIN ${History.TABLE}
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
JOIN (
SELECT ${Chapter.TABLE}.${Chapter.COL_MANGA_ID},${Chapter.TABLE}.${Chapter.COL_ID} as ${History.COL_CHAPTER_ID}, MAX(${History.TABLE}.${History.COL_LAST_READ}) as ${History.COL_LAST_READ}
FROM ${Chapter.TABLE} JOIN ${History.TABLE}
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}) AS max_last_read
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = max_last_read.${Chapter.COL_MANGA_ID}
WHERE ${History.TABLE}.${History.COL_LAST_READ} > ? AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%$search%'
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
LIMIT 25 OFFSET $offset
"""
/**
* Query to get the recently read chapters of manga from the library up to a date.
* The max_last_read table contains the most recent chapters grouped by manga
* The select statement returns all information of chapters that have the same id as the chapter in max_last_read
* and are read after the given time period
*/
fun getRecentMangasLimitQuery(limit: Int = 25, search: String = "") =
fun getRecentMangasQuery(search: String = "") =
"""
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
FROM ${Manga.TABLE}
@@ -125,9 +167,8 @@ fun getRecentMangasLimitQuery(limit: Int = 25, search: String = "") =
AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%$search%'
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
LIMIT $limit
LIMIT ? OFFSET ?
"""
// SY <--
fun getHistoryByMangaId() =
"""
@@ -10,6 +10,15 @@ import eu.kanade.tachiyomi.data.track.TrackService
interface TrackQueries : DbProvider {
fun getTracks() = db.get()
.listOfObjects(Track::class.java)
.withQuery(
Query.builder()
.table(TrackTable.TABLE)
.build()
)
.prepare()
fun getTracks(manga: Manga) = db.get()
.listOfObjects(Track::class.java)
.withQuery(
@@ -1,6 +1,6 @@
package eu.kanade.tachiyomi.data.database.resolvers
import android.content.ContentValues
import androidx.core.content.contentValuesOf
import com.pushtorefresh.storio.sqlite.StorIOSQLite
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
@@ -25,9 +25,10 @@ class ChapterBackupPutResolver : PutResolver<Chapter>() {
.whereArgs(chapter.url)
.build()
fun mapToContentValues(chapter: Chapter) = ContentValues(3).apply {
put(ChapterTable.COL_READ, chapter.read)
put(ChapterTable.COL_BOOKMARK, chapter.bookmark)
put(ChapterTable.COL_LAST_PAGE_READ, chapter.last_page_read)
}
fun mapToContentValues(chapter: Chapter) =
contentValuesOf(
ChapterTable.COL_READ to chapter.read,
ChapterTable.COL_BOOKMARK to chapter.bookmark,
ChapterTable.COL_LAST_PAGE_READ to chapter.last_page_read
)
}
@@ -0,0 +1,34 @@
package eu.kanade.tachiyomi.data.database.resolvers
import androidx.core.content.contentValuesOf
import com.pushtorefresh.storio.sqlite.StorIOSQLite
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
import eu.kanade.tachiyomi.data.database.inTransactionReturn
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
class ChapterKnownBackupPutResolver : PutResolver<Chapter>() {
override fun performPut(db: StorIOSQLite, chapter: Chapter) = db.inTransactionReturn {
val updateQuery = mapToUpdateQuery(chapter)
val contentValues = mapToContentValues(chapter)
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues)
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
}
fun mapToUpdateQuery(chapter: Chapter) = UpdateQuery.builder()
.table(ChapterTable.TABLE)
.where("${ChapterTable.COL_ID} = ?")
.whereArgs(chapter.id)
.build()
fun mapToContentValues(chapter: Chapter) =
contentValuesOf(
ChapterTable.COL_READ to chapter.read,
ChapterTable.COL_BOOKMARK to chapter.bookmark,
ChapterTable.COL_LAST_PAGE_READ to chapter.last_page_read
)
}
@@ -1,6 +1,6 @@
package eu.kanade.tachiyomi.data.database.resolvers
import android.content.ContentValues
import androidx.core.content.contentValuesOf
import com.pushtorefresh.storio.sqlite.StorIOSQLite
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
@@ -25,9 +25,10 @@ class ChapterProgressPutResolver : PutResolver<Chapter>() {
.whereArgs(chapter.id)
.build()
fun mapToContentValues(chapter: Chapter) = ContentValues(3).apply {
put(ChapterTable.COL_READ, chapter.read)
put(ChapterTable.COL_BOOKMARK, chapter.bookmark)
put(ChapterTable.COL_LAST_PAGE_READ, chapter.last_page_read)
}
fun mapToContentValues(chapter: Chapter) =
contentValuesOf(
ChapterTable.COL_READ to chapter.read,
ChapterTable.COL_BOOKMARK to chapter.bookmark,
ChapterTable.COL_LAST_PAGE_READ to chapter.last_page_read
)
}
@@ -1,6 +1,6 @@
package eu.kanade.tachiyomi.data.database.resolvers
import android.content.ContentValues
import androidx.core.content.contentValuesOf
import com.pushtorefresh.storio.sqlite.StorIOSQLite
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
@@ -25,7 +25,8 @@ class ChapterSourceOrderPutResolver : PutResolver<Chapter>() {
.whereArgs(chapter.url, chapter.manga_id)
.build()
fun mapToContentValues(chapter: Chapter) = ContentValues(1).apply {
put(ChapterTable.COL_SOURCE_ORDER, chapter.source_order)
}
fun mapToContentValues(chapter: Chapter) =
contentValuesOf(
ChapterTable.COL_SOURCE_ORDER to chapter.source_order
)
}
@@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.data.database.resolvers
import android.content.ContentValues
import androidx.annotation.NonNull
import androidx.core.content.contentValuesOf
import com.pushtorefresh.storio.sqlite.StorIOSQLite
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
import com.pushtorefresh.storio.sqlite.queries.Query
@@ -57,7 +57,8 @@ class HistoryLastReadPutResolver : HistoryPutResolver() {
* Create content query
* @param history object
*/
fun mapToUpdateContentValues(history: History) = ContentValues(1).apply {
put(HistoryTable.COL_LAST_READ, history.last_read)
}
fun mapToUpdateContentValues(history: History) =
contentValuesOf(
HistoryTable.COL_LAST_READ to history.last_read
)
}
@@ -18,6 +18,9 @@ class LibraryMangaGetResolver : DefaultGetResolver<LibraryManga>(), BaseMangaGet
mapBaseFromCursor(manga, cursor)
manga.unread = cursor.getInt(cursor.getColumnIndex(MangaTable.COL_UNREAD))
manga.category = cursor.getInt(cursor.getColumnIndex(MangaTable.COL_CATEGORY))
// SY -->
manga.read = cursor.getInt(cursor.getColumnIndex(MangaTable.COL_READ))
// SY <--
return manga
}
@@ -1,6 +1,6 @@
package eu.kanade.tachiyomi.data.database.resolvers
import android.content.ContentValues
import androidx.core.content.contentValuesOf
import com.pushtorefresh.storio.sqlite.StorIOSQLite
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
@@ -25,7 +25,8 @@ class MangaCoverLastModifiedPutResolver : PutResolver<Manga>() {
.whereArgs(manga.id)
.build()
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
put(MangaTable.COL_COVER_LAST_MODIFIED, manga.cover_last_modified)
}
fun mapToContentValues(manga: Manga) =
contentValuesOf(
MangaTable.COL_COVER_LAST_MODIFIED to manga.cover_last_modified
)
}

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