Compare commits

..

732 Commits

Author SHA1 Message Date
c1064b1ba7 Fix browse comfortable grid 2020-05-24 16:13:52 -04:00
3a9f59b7a5 Finally a working comfortable grid 2020-05-24 15:59:44 -04:00
ccbe240846 Get Started on new Grid, only layout left 2020-05-24 15:59:44 -04:00
2c0d96917f Add multiline sources info for merged sources 2020-05-24 14:13:04 -04:00
0316cf47ed Fix merge with another crash(because of the kotlin dependency update) 2020-05-24 13:37:43 -04:00
e4c8de1145 Lint 2020-05-24 13:34:35 -04:00
9c978c608d Fix hiding the sync favorites option 2020-05-24 13:34:25 -04:00
b4a88926ed Rename EH Settings to Fork Settings 2020-05-24 13:12:51 -04:00
de593f458f Remove language from manga type detection and ignore casing for tags (#26)
* Remove language detection

* Ignore casing for tag detection

Co-authored-by: she11sh0cked <she11sh0cked@users.noreply.github.com>
2020-05-24 19:09:06 +02:00
f3c8b37928 Last few fixes for J2K Auto Migration 2020-05-23 23:30:07 -04:00
91f22c03c0 Multiple fixes for J2K auto migration 2020-05-23 23:15:42 -04:00
Jay
81ee1ce39a Batch select sources for pre migrations
Select none/all, pinned sources, enabled sources from the list

(cherry picked from commit 59c2da3f91052dfb0a292cb23ccb9d39055aadc7)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/PreMigrationController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationListController.kt
#	app/src/main/res/drawable/ic_select_all_24dp.xml
#	app/src/main/res/values/strings.xml
2020-05-23 22:51:34 -04:00
Jay
2ed54eed73 Migration updates
When searching manually, the sources used for auto migration will also be used for searching
Can now migrate to the same source if it is the only source being used for migration (for those who cant stop using kakalot)

(cherry picked from commit a3305171d64a8dc4c2fa52d3e5257f45e92f29f1)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/migration/SearchController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/migration/SearchPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationListController.kt
2020-05-23 22:28:25 -04:00
a9ef4bef8e Small migration change 2020-05-23 22:06:22 -04:00
c9b988aca6 Remove unneded update chapter view 2020-05-23 21:55:56 -04:00
b803dbe3af Update view when chapters read status has changed 2020-05-23 21:39:05 -04:00
35ef07d720 Lint 2020-05-23 16:16:52 -04:00
4f596d68b9 Handle empty thumbnail_url when refreshing covers
(cherry picked from commit ac8f2923e5)
2020-05-23 16:05:05 -04:00
26776f8430 Tweak history card design
(cherry picked from commit e9d3b75e2b)
2020-05-23 16:04:58 -04:00
471eb36a92 Avoid replacing covers with null when updating library (sort of closes #3194)
(cherry picked from commit e6bc181e7a)
2020-05-23 16:04:50 -04:00
8b8b377c29 Group advanced settings
(cherry picked from commit a2ece82197)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
2020-05-23 16:04:21 -04:00
d70d2cdff5 Make metadata updating optional
(cherry picked from commit 259946cf0a)
2020-05-23 15:55:56 -04:00
b0704063f2 Move categories up in library settings
(cherry picked from commit 4fdb4f14a8)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt
2020-05-23 15:53:35 -04:00
dde7254dcf Update drag icon
(cherry picked from commit 914f5e569b)
2020-05-23 15:36:20 -04:00
4edb9ed398 Fix recycled icon in source migration list when source isn't installed
(cherry picked from commit 9b4ffd1cd5)
2020-05-23 15:29:40 -04:00
9d764781c3 Update the coroutine dependency and fix issues that were causing the crash 2020-05-23 00:57:41 -04:00
f7d991ab54 Revert coroutines update because of crashes 2020-05-23 00:31:32 -04:00
59b3b7d79d Fix builder 2020-05-22 17:53:00 -04:00
354bf362c0 Lint 2020-05-22 17:50:08 -04:00
69304466a7 Add icons to extension manager so they appear in more views without manually setting them 2020-05-22 17:50:08 -04:00
6e4d4739a6 Add migrate option from manga info view (closes #1903) (doesnt actually do anything in SY)
(cherry picked from commit 035038a0b6)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt
2020-05-22 17:50:08 -04:00
e8947b3107 Dependency updates
(cherry picked from commit ed87dd89a1)

# Conflicts:
#	app/build.gradle
2020-05-22 17:50:08 -04:00
153641a249 Add explicit refresh icon asset (maybe fixes #3218)
(cherry picked from commit 3b41a78e76)
2020-05-22 17:50:08 -04:00
60706e8b8b Rename downloaded chapters (#3216)
(cherry picked from commit 0fccbbc0ca)
2020-05-22 17:50:08 -04:00
19dc859ef2 Change resume button in history to an icon
(cherry picked from commit 067627b51a)
2020-05-22 17:50:08 -04:00
06ff4444c5 Refactor history_item.xml to use ConstraintLayout
(cherry picked from commit 09816ed5b6)
2020-05-22 17:50:08 -04:00
156cfb0c74 Scroll up/down when tapping top/bottom quarters of webtoon viewer
Includes a fix from J2K: 4e45a337da

(cherry picked from commit b457cdb0c2)
2020-05-22 17:50:08 -04:00
e49a25b604 Add bottom padding to history/sources/extensions (fixes #3192)
(cherry picked from commit 5fd1dec347)
2020-05-22 17:50:08 -04:00
b34a137c07 Make library update error notification optional (closes #3200)
(cherry picked from commit 647391ef73)
2020-05-22 17:50:08 -04:00
1fb6b3775d download new chapters changes (#3193)
* download new chapters changes

* move initialFetchChapters logic into onNextChapters

* refractor download new chapter logic to be more explicit

(cherry picked from commit ed029c52ae)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.kt
2020-05-22 17:50:08 -04:00
b1c9a204c1 Minor edits
(cherry picked from commit d4ffb09a8b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt
2020-05-22 17:50:08 -04:00
8435be1b1f Implemented review changes
Shorter UI text and >= date comparison instead of >

(cherry picked from commit 6ba052d2af)
2020-05-22 17:50:08 -04:00
7affb9ab63 Fix unread badges not hiding in list view
(cherry picked from commit 2fb0969c75)
2020-05-22 17:50:08 -04:00
5627ad0801 Square covers in list view (closes #3121)
(cherry picked from commit 3357e878a5)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListHolder.kt
2020-05-22 17:50:08 -04:00
08017a0cd1 Move cover card outline clipping code from item to holder classes
(cherry picked from commit 471d5d62d5)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceGridHolder.kt
2020-05-22 17:50:08 -04:00
b6603c3425 Specify charset for ZIP chapters when using Android N+ (fixes #905)
(cherry picked from commit e810b343cf)
2020-05-22 17:50:08 -04:00
f63323feab Remove redundant helper function
(cherry picked from commit 620be2617a)
2020-05-22 17:50:08 -04:00
eea5f0ba6a Add fastscroller to migration lists
(cherry picked from commit b8ffb87f01)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt
2020-05-22 17:50:08 -04:00
9f51dfad33 Sort list of sources in migration alphabetically
(cherry picked from commit 39e1e11f99)
2020-05-22 17:50:08 -04:00
c31789c112 Localize tracker not logged in error
(cherry picked from commit 5f9df78ab0)
2020-05-22 17:50:08 -04:00
86043fbb31 Warn about missing sources before restoring backup
(cherry picked from commit a00d11701f)
2020-05-22 17:50:08 -04:00
1136ec2ad4 Add fastscroller to updates and history
(cherry picked from commit 1cf74a5396)
2020-05-22 17:50:07 -04:00
7910f6e420 Minor cleanup
(cherry picked from commit 8cd27a199d)
2020-05-22 17:50:07 -04:00
a087b0bf4b Return job failure if library update actually doesn't start
(cherry picked from commit 772929b5c6)
2020-05-22 17:50:07 -04:00
d0929c1dc5 Slightly simplify AMOLED theme definition
(cherry picked from commit c4ca3606ad)
2020-05-22 17:50:07 -04:00
46500dcb32 Added missing sorting cases handling
Previous commit missed some cases resulting in errors at runtime

(cherry picked from commit 9e830f1c55)
2020-05-22 17:50:07 -04:00
f85c34b807 Added sorting by upload date
Spanish 'strings' contains the proper translation for the new feature.

(cherry picked from commit ee8c71c14a)
2020-05-22 17:50:07 -04:00
dfc3a5df42 Minor show more info button margin adjustment
(cherry picked from commit 39bd823651)
2020-05-22 17:50:07 -04:00
2b78925c68 Add Croatian to settings
(cherry picked from commit a9d16fad34)
2020-05-22 17:50:07 -04:00
eb2fedd669 Fix Chinese plurals
(cherry picked from commit 1da169319d)
2020-05-22 17:50:07 -04:00
b8b5e70151 Translations (Continuous) (#3125)
* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Polish)

Currently translated at 100.0% (531 of 531 strings)

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

Translated using Weblate (Sardinian)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (French)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/

Translated using Weblate (French)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/

Translated using Weblate (Japanese)

Currently translated at 76.2% (405 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ja/

Translated using Weblate (Turkish)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/

Translated using Weblate (Russian)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Spanish)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/

Translated using Weblate (Kannada)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/kn/

Translated using Weblate (Marathi)

Currently translated at 46.8% (249 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/mr/

Translated using Weblate (Finnish)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fi/

Translated using Weblate (Catalan)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ca/

Translated using Weblate (Greek)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Dutch)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nl/

Translated using Weblate (Indonesian)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/

Translated using Weblate (Hindi)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/

Translated using Weblate (German)

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (531 of 531 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Portuguese)

Currently translated at 99.4% (525 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt/

Translated using Weblate (Malay)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/

Translated using Weblate (Turkish)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/

Translated using Weblate (Russian)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Dutch)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nl/

Translated using Weblate (Kannada)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/kn/

Translated using Weblate (Finnish)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fi/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Hindi)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/

Translated using Weblate (German)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Added translation using Weblate (Spanish (Latin America))

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/

Translated using Weblate (Romanian)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ro/

Translated using Weblate (Italian)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/

Translated using Weblate (Italian)

Currently translated at 93.5% (494 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/

Translated using Weblate (Italian)

Currently translated at 93.5% (494 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/

Translated using Weblate (Hungarian)

Currently translated at 34.0% (180 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hu/

Translated using Weblate (Hungarian)

Currently translated at 30.1% (159 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hu/

Translated using Weblate (Kannada)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/kn/

Translated using Weblate (Marathi)

Currently translated at 46.5% (246 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/mr/

Translated using Weblate (Indonesian)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/

Translated using Weblate (Bengali)

Currently translated at 67.9% (359 of 528 strings)

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

Translated using Weblate (Kannada)

Currently translated at 55.8% (295 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/kn/

Translated using Weblate (Sardinian)

Currently translated at 99.8% (527 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/

Translated using Weblate (Portuguese)

Currently translated at 97.9% (517 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Indonesian)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/

Translated using Weblate (Indonesian)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/

Translated using Weblate (Hindi)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/

Translated using Weblate (French)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/

Translated using Weblate (Bulgarian)

Currently translated at 99.8% (527 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/bg/

Translated using Weblate (Indonesian)

Currently translated at 97.7% (516 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/

Translated using Weblate (Kannada)

Currently translated at 27.6% (146 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/kn/

Translated using Weblate (Marathi)

Currently translated at 34.8% (184 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/mr/

Translated using Weblate (Swedish)

Currently translated at 100.0% (528 of 528 strings)

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

Translated using Weblate (Swedish)

Currently translated at 100.0% (528 of 528 strings)

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

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (German)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/

Added translation using Weblate (Kannada)

Translated using Weblate (Marathi)

Currently translated at 18.9% (100 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/mr/

Translated using Weblate (Marathi)

Currently translated at 8.5% (45 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/mr/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Greek)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/

Translated using Weblate (Finnish)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fi/

Translated using Weblate (Catalan)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ca/

Translated using Weblate (Turkish)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/

Translated using Weblate (Russian)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ru/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Polish)

Currently translated at 100.0% (528 of 528 strings)

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

Translated using Weblate (French)

Currently translated at 99.8% (527 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/

Translated using Weblate (Spanish)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/

Translated using Weblate (Romanian)

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ro/

Translated using Weblate (Greek)

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.8% (526 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.8% (526 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/

Translated using Weblate (Finnish)

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fi/

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.8% (526 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/

Translated using Weblate (Malay)

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/

Translated using Weblate (Hindi)

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/

Translated using Weblate (German)

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/

Translated using Weblate (Catalan)

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ca/

Translated using Weblate (Turkish)

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (German)

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Romanian)

Currently translated at 100.0% (526 of 526 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ro/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (526 of 526 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (German)

Currently translated at 100.0% (526 of 526 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/

Translated using Weblate (Catalan)

Currently translated at 100.0% (526 of 526 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ca/

Translated using Weblate (Hindi)

Currently translated at 100.0% (526 of 526 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Dutch)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nl/

Translated using Weblate (Greek)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/

Translated using Weblate (Turkish)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/

Translated using Weblate (French)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/

Translated using Weblate (Finnish)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fi/

Translated using Weblate (Catalan)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ca/

Translated using Weblate (Swedish)

Currently translated at 100.0% (528 of 528 strings)

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

Translated using Weblate (Malay)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/

Translated using Weblate (Hindi)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/

Translated using Weblate (German)

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (528 of 528 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/

Translated using Weblate (Sardinian)

Currently translated at 99.8% (526 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/

Translated using Weblate (French)

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/

Translated using Weblate (Greek)

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/el/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (German)

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (527 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pt_BR/

Translated using Weblate (Czech)

Currently translated at 73.4% (387 of 527 strings)

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/cs/

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Tachiyomi/Strings
Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/

Co-authored-by: Hosted Weblate <hosted@weblate.org>
(cherry picked from commit 2bb1eea2be)
2020-05-22 17:50:07 -04:00
8c00905c99 Move extension preferences to separate controller
(cherry picked from commit 9cb45b92e1)
2020-05-22 17:50:07 -04:00
598af5ebd5 Add lost Croatian translation (#3176)
(cherry picked from commit 4a8d5098da)
2020-05-22 17:50:07 -04:00
8adedee973 Better distinguish between obsolete and unofficial extensions
(cherry picked from commit d875d5ef74)
2020-05-22 17:50:07 -04:00
4dc2143160 Show notification with error log on update failures
(cherry picked from commit fc4e290c49)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt
2020-05-22 17:50:07 -04:00
aded163e0a Reword "Pager" to "Paged"
(cherry picked from commit ccc198e081)
2020-05-22 17:50:07 -04:00
11a553cbf4 Remove unused function
(cherry picked from commit 9f0ed77423)
2020-05-22 17:50:07 -04:00
a0048e9397 Avoid showing uninstalled source as last used
(cherry picked from commit bb3e616890)
2020-05-22 17:50:07 -04:00
a8a22b5803 Null check for local source cover parent dir
(cherry picked from commit 573f3a392a)
2020-05-22 17:50:07 -04:00
Jay
4122af491c Using a float on the progress on app updates
Not sure if needed but I saw some funny behavior with the progress bar

(cherry picked from commit 830a834ea6)
2020-05-22 17:50:07 -04:00
0de42b6654 Don't throw exception to stop restore job
(cherry picked from commit e4ea5d0344)
2020-05-22 17:50:07 -04:00
d7aa1144cf Copy to clipboard when long pressing tracking title (closes #3163)
(cherry picked from commit 97aed045e6)
2020-05-22 17:50:07 -04:00
855f768e29 Add version bumper (#25)
Co-authored-by: she11sh0cked <she11sh0cked@users.noreply.github.com>
2020-05-22 23:39:24 +02:00
87fbda0b29 Recommendations rewrite (#23)
* WIP Rewrite api requests to use a coroutine scope

* Use scope.async instead of scope.launch

* Use onPageReceived to async update Pager; Reimplement api select logic

* Implement seperate classes; Bug fixes

* More bug fixes

* Use timber; Add more logs

Co-authored-by: she11sh0cked <she11sh0cked@users.noreply.github.com>
2020-05-22 11:35:43 -04:00
99dd9a0750 Fix last chapter and last updated info 2020-05-21 21:38:55 -04:00
c8befdd5ea Fix manual refresh for manga, attempt to fix last chapter and last updated 2020-05-21 17:56:58 -04:00
54cf97170d Fix landscape view(jsut replaced it with a minorly edited portrait view) 2020-05-21 15:10:13 -04:00
a5aa89512a Half fixed landscape view 2020-05-21 00:57:49 -04:00
b02813f30a Fix MangaAllInOneHolder lazy vars 2020-05-21 00:57:33 -04:00
51c8430e9c Totally rewrote the all in one manga page, now is a recycler header
It works perfect, there is no lag it all
2020-05-21 00:30:09 -04:00
a846f7da47 Merge pull request #20 from Jacket-Chan/patch-1
Fixed a spelling error
2020-05-20 17:07:37 +02:00
b4e5443e56 Fixed a spelling error
:)
2020-05-19 22:44:37 -10:00
3fdfd91fff Fix the favorite button 2020-05-19 22:57:41 -04:00
e4b52c036a Lint 2020-05-19 22:01:22 -04:00
43098aa61b Added Auto Webtoon Mode 2020-05-19 22:00:58 -04:00
e4d8fea138 Lewd Filter upgrade, almost finished 2020-05-19 18:51:42 -04:00
6da22ea8b0 Fix multiple recommendation bugs (#18)
* Fix multiple recommendation bugs

* Fix typo

* Fix typings

* Remove unused import

Co-authored-by: she11sh0cked <she11sh0cked@users.noreply.github.com>
2020-05-19 18:42:17 -04:00
5e618e0134 Create PullRequestTester.yml 2020-05-19 18:27:40 -04:00
fd09f64fe6 Recommendation bug fixes (#17)
* Return an empty recommendations list instead of throwing an error

* Fix api response find for searched manga

* Fix spelling

Co-authored-by: she11sh0cked <she11sh0cked@users.noreply.github.com>
2020-05-19 16:54:59 -04:00
ef2241e0cb Fix recommendations throwing to early (#16)
* Fix recommendations throwing to early

Co-authored-by: she11sh0cked <she11sh0cked@users.noreply.github.com>
2020-05-19 16:01:48 -04:00
bcfe5af135 Fix filter button 2020-05-19 15:03:49 -04:00
a598afec43 Spelling correction 2020-05-19 13:54:03 -04:00
3c9ec48da3 Implement lewd filter (#15)
Co-authored-by: she11sh0cked <she11sh0cked@users.noreply.github.com>
2020-05-19 13:30:46 -04:00
7ce15caded Improve recommendations (#14)
* Improve anilist recommendations by matching synonyms; Some bug fixes related to anilist

* Fix formatting

* Sort myanimelist results by result.title matching search.title

* Throw an exception if the result is not the manga we searched

Co-authored-by: she11sh0cked <she11sh0cked@users.noreply.github.com>
2020-05-19 13:29:42 -04:00
7e65e0de0e fix tag detection 2020-05-19 00:19:43 -04:00
07a70d8c92 Add a crapton of detection for sources with only a certain type of manga 2020-05-18 21:39:31 -04:00
038574b107 Remove unused val 2020-05-18 20:23:56 -04:00
24067e1e97 Move new smart recommends to use new manga type detection 2020-05-18 20:19:18 -04:00
68b13c6425 Add modified J2k manga type detection 2020-05-18 20:11:09 -04:00
a9de6a123e Smart recommendations (#10)
* Pass manga through to RecommendsPager

* Implement smart recommendations

* Add null checks

* Add more anilistSmart tags

* Add fallback titles

Co-authored-by: she11sh0cked <she11sh0cked@users.noreply.github.com>
2020-05-18 20:10:54 -04:00
b0251b8177 Add support for EH Visited exported data in batch add 2020-05-18 13:00:13 -04:00
c069d75ede Fix Batch Add 2020-05-17 23:22:56 -04:00
5886cb7406 Fix all in one manga page being blank after clicking a button 2020-05-17 21:39:11 -04:00
1713dd4ea0 Made saved searches always available
Replace filtersheet with saved searches version if no filters are avalible
2020-05-17 20:52:51 -04:00
f5f7971cb5 Fix multiple bugs when fetching manga info 2020-05-17 17:11:46 -04:00
5271abbd1f Migrate the rest of the EH prefreches to Flow Prefrences 2020-05-17 17:11:46 -04:00
7d2ded5944 Implement MyAnimeList recommendations (#7)
Co-authored-by: she11sh0cked <she11sh0cked@users.noreply.github.com>
2020-05-17 15:38:38 -04:00
d2b0319d63 Added last debug features, should fix galleries that dont restore properly for the updater 2020-05-16 20:56:45 -04:00
c15f4c7fd0 Update debug functions 2020-05-16 19:44:12 -04:00
3aee05bf26 Enable new tracking features only if tracking is enabled 2020-05-16 18:37:06 -04:00
9d148a70c8 Fix filters 2020-05-16 18:01:11 -04:00
4a64bb250d Mitigate most of the lag problems, should fix all crashes(inspired by J2k code)
Add tracking button the way J2K has it, my own implementation
2020-05-16 17:53:14 -04:00
e6f5ea172a Filter tracker status (#2)
* Implement library filter for tracker status

Co-authored-by: she11sh0cked <she11sh0cked@users.noreply.github.com>
2020-05-13 20:35:01 -04:00
6a0ab3526a Implement library filter for tracked items (#1)
* Implement library filter for tracked items

* Revert formatting

* Move string 'tracked'

Co-authored-by: she11sh0cked <she11sh0cked@users.noreply.github.com>
2020-05-12 14:04:06 -04:00
fa29b914cc Multiple bug fixes and changes
- Fixed options menu

- Fixed merge with another

- Migrate to MaterialFastScroll
2020-05-11 20:10:51 -04:00
3a79f8fb50 Updated E hentai notifications to new system 2020-05-11 17:11:47 -04:00
321eb38f2d Fix Tag searching and Recommendations button 2020-05-11 17:10:29 -04:00
46dccf8a2d Lint fix 2020-05-11 16:31:19 -04:00
7f02a533fa fix regular font family name (#3154)
(cherry picked from commit 46b01c6134)
2020-05-11 16:28:28 -04:00
38d329a601 Temporarily revert concurrent manga updates
(cherry picked from commit e208fa4020)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2020-05-11 16:28:22 -04:00
1c0f08fc5b Cover Update Followup to Address #3139 (#3150)
* update cover logic when thumbnail url becomes null

* always clear cover on refresh even if custom cover is set

* remove concurrency changes

(cherry picked from commit 5723c184b1)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
2020-05-11 16:08:30 -04:00
a076deeb5f Move notification logic out of LibraryUpdateService
(cherry picked from commit 530daeaa3a)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2020-05-11 16:05:16 -04:00
a006bc7d93 Rename EH update notifier 2020-05-11 16:03:32 -04:00
2b215524b6 Replace adapterPosition with bindingAdapterPosition in MigrationProcessHolder 2020-05-11 15:58:26 -04:00
f497e605b4 Style the recommendations buttonm 2020-05-11 15:57:40 -04:00
b09f1fff51 New All In One Manga interface, its optional and can be disabled 2020-05-11 15:33:38 -04:00
92af538b0a Fix Search error 2020-05-11 00:50:15 -04:00
f0b821b122 finish off recommendations
(cherry picked from commit 6473bcd32242abf8ba50b3ac76562ae6b931d0cd)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt
2020-05-11 00:20:51 -04:00
4c5e99142f Display recommendations from AniList
(cherry picked from commit f032667be5d2c9cfa5000ab1e166c7aaedbac701)
2020-05-11 00:05:40 -04:00
b0f39a7d0a add recommendations button to manga info
(cherry picked from commit 0d370004e6c78597957284d67f1af80881e17a49)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt
#	app/src/main/res/layout/manga_info_controller.xml
#	app/src/main/res/values/strings.xml
2020-05-11 00:05:28 -04:00
38b469755f Add simple hentai features option 2020-05-10 23:55:51 -04:00
3bfda338ef Add basic E/Ex-Hentai watched tag settings, possibly more to come 2020-05-10 22:36:52 -04:00
6e1da22353 Convert EH settings to FlowPrefrences 2020-05-10 19:22:10 -04:00
60a0303d7f Minor edits
(cherry picked from commit dd1b5c7ea7)
2020-05-10 16:26:21 -04:00
6135b4daae Animate in/out ActionToolbar
(cherry picked from commit 3cffc6890d)
2020-05-10 16:26:10 -04:00
2fe38192b4 Show date format examples, migrate to FlowPreferences
(cherry picked from commit 04d44f19f5)
2020-05-10 16:25:39 -04:00
ef3f4c2e17 Convert rotation to FlowPreference, remove some unused subscriptions code
Also remove EH lock code(was broken because of RxController changes)

(cherry picked from commit d46a742a43)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
2020-05-10 16:25:07 -04:00
e4e069ccca Default unreadBadge setting to true (closes #3138)
(cherry picked from commit a94fd24fa9)
2020-05-10 14:27:32 -04:00
505d2e4274 Minor wording edits
(cherry picked from commit 8a4c4c346a)
2020-05-10 14:27:21 -04:00
4cdf2f468c Manga cover updates (#3101)
* cover caching overhaul

* add ui for removing custom cover

* skip some loading work

* minor cleanup

* allow refresh library metadata to refresh local manga

* rename metadata_date to cover_last_modified

* rearrange removeMangaFromLibrary

* change custom cover directory
add setting for updating cover when refreshing library

* remove toggle and explicit action for updating covers

(cherry picked from commit dc54299e24)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryGridHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt
2020-05-10 14:27:05 -04:00
8c7a2c4262 Add more info in tracking settings section
(cherry picked from commit 436253dd63)

# Conflicts:
#	app/src/main/res/values/strings.xml
2020-05-10 14:11:52 -04:00
156ce14dd8 Action: Remove Acknowledgement pong 2020-05-10 14:03:08 -04:00
27dc6443ec Fix broken updater 2020-05-10 01:23:41 -04:00
0a5773211d Added preview builds link 2020-05-10 01:19:31 -04:00
b3b0c39163 Fix naming of the preview repo 2020-05-10 01:12:56 -04:00
bc6b4d4be6 Test push 2020-05-10 00:52:02 -04:00
a14e5a99d9 Setup first full beta test 2020-05-10 00:29:43 -04:00
d643b947a9 Add files for new action, should allow automatic updating when finished 2020-05-10 00:20:36 -04:00
2033e82ff0 Update android-debug.yml 2020-05-09 22:16:24 -04:00
c2c872d000 Action: make the file a .apk 2020-05-09 21:44:44 -04:00
ae9377f8be Action: Should Fix uploading 2020-05-09 21:30:44 -04:00
93a84cad34 Action: Test Signed path 2 2020-05-09 21:10:40 -04:00
f9ceb92495 Action: Test this path enviorment variable 2020-05-09 21:09:42 -04:00
bfdd5c9ec3 Action: Remove something I forgot 2020-05-09 20:53:12 -04:00
d800528550 Action: Change write file and attempt to fix app signing 2020-05-09 20:52:27 -04:00
6ec656b094 Action: Change way of attempting to get the needed NDK 2020-05-09 20:30:45 -04:00
29c5da1494 Action: Only assemble release 2020-05-09 20:02:15 -04:00
0a21a9e5f0 Remove validate gson 2020-05-09 19:39:12 -04:00
d3aaa3656b Another way to add the json to the actions 2020-05-09 19:29:32 -04:00
69a8223d06 Fix formatting error in action 2020-05-09 19:18:38 -04:00
6959370087 Use another way to create the file 2020-05-09 19:17:23 -04:00
1d0937397f I think I fixed the actions this time 2020-05-09 19:00:45 -04:00
aeeafe8556 Action for some reason had ; 2020-05-09 18:52:04 -04:00
38c5163ab9 Did removing this break the action? 2020-05-09 18:51:15 -04:00
4646e4b0d9 Hopefully this time fixes it 2020-05-09 18:49:07 -04:00
e9f105c52a Hopfully fix google-services.json copying to app 2020-05-09 18:40:19 -04:00
3b225405cb Add Google-services.json to action 2020-05-09 18:28:35 -04:00
b96a870c4e Attempt to fix build errors 2020-05-09 18:09:21 -04:00
b70d70e82d Make a debug build action 2020-05-09 17:56:45 -04:00
f4d1c27cde Fix tapping manga info button and fix not showing full info when first looking at the manga 2020-05-09 13:10:45 -04:00
4195b00e48 Fix not removing the more button when global search doesnt find anything in that source 2020-05-09 13:06:59 -04:00
0a37dabf4b Release 0.9.2.7 2020-05-09 12:20:57 -04:00
2d5ac20c46 Re-Implement the more button in global search 2020-05-09 12:06:36 -04:00
700fd61f34 Update details metadata along with chapters list
(cherry picked from commit 29feee0095)
2020-05-09 11:49:28 -04:00
a0462fb480 Move DB transaction blocks to only the DB portions of restore logic
(cherry picked from commit 63f3180dff)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt
2020-05-09 11:49:15 -04:00
d9d969406e Revert Nucleus to 3.0.0
Fixes #3028
Fixes #3013
Fixes #3037

(cherry picked from commit 6b3b98cf57)
2020-05-09 11:48:15 -04:00
f19685787f Option to hide unread badges (closes #3095)
(cherry picked from commit 1442e2b53e)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
2020-05-09 11:48:01 -04:00
60caba86a5 Remove redundant DB call in library settings (closes #3128)
(cherry picked from commit 521ebf0678)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt
2020-05-09 11:43:43 -04:00
80fa7ebe6c String Formatting Fixes (#3118)
String Formatting Fixes

(cherry picked from commit a20874f6a1)
2020-05-09 11:41:45 -04:00
9096edfc92 Concurrently refresh trackers
(cherry picked from commit 40776bdc8d)
2020-05-09 11:41:32 -04:00
f30ad78a4c Do library checks from up to 5 sources concurrently
(cherry picked from commit f853158e6b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
2020-05-09 11:40:32 -04:00
ce0d99b78f Download from up to 5 different sources concurrently (closes #2534)
(cherry picked from commit c9035b5df9)
2020-05-09 11:36:04 -04:00
3ffb80c6f1 Concurrently download up to 5 pages at a time
(cherry picked from commit 150132f4dd)
2020-05-09 11:35:52 -04:00
4e3c407583 Replace restore completion string with plurals
(cherry picked from commit fb97ac47bc)
2020-05-09 11:35:43 -04:00
aaf9fc5d92 Translated using Weblate (Swedish) (#3124)
Translations

(cherry picked from commit 5b53b90495)
2020-05-09 11:35:09 -04:00
5043f840a2 Translated using Weblate (Swedish) (#3043)
Translations (Continuous)

(cherry picked from commit c6513d4450)
2020-05-09 11:34:51 -04:00
fac3bd1edd Show icon when chapter is bookmarked
(cherry picked from commit ce6848b3c0)
2020-05-09 11:34:38 -04:00
976cd41a87 MaterialFastScroll updates
(cherry picked from commit d86d861e4b)
2020-05-09 11:34:24 -04:00
4aeaee65c3 Use borderless buttons everywhere for consistency
(cherry picked from commit 3b45fcdb21)
2020-05-09 11:32:48 -04:00
f880a0f1a3 Do some download deletion in coroutines instead of completable
(cherry picked from commit 3d1250f2f8)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
2020-05-09 11:32:31 -04:00
3a886e39fb Remove fdroid flavor
(cherry picked from commit eaf1ef831a)
2020-05-09 11:30:54 -04:00
005d43a3ec Minor cleanup of wakelocks, extension ID backup
(cherry picked from commit b4c7992726)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt
2020-05-09 11:30:38 -04:00
1d760f4728 Destroy action mode after actioning in chapters list (closes #3004)
(cherry picked from commit 03baa21185)
2020-05-09 11:20:53 -04:00
02e3148efe Adopt MaterialFastScroll from J2K fork
de8cb8c1b0
(cherry picked from commit 694de99a3f)
2020-05-09 11:20:42 -04:00
e9ada7e5fb Increase webtoon setting change page refresh range (closes #3088)
(cherry picked from commit 8383f4fb7b)
2020-05-09 11:20:31 -04:00
2ce01a1c86 Alternative way of reading local manga JSON file
(cherry picked from commit eb3fff6c51)
2020-05-09 11:20:21 -04:00
1af8bc95a8 Tweak about manga heading
(cherry picked from commit 4ff3f0bcba)
2020-05-09 11:20:08 -04:00
0046ed879f Convert app updater to foreground service
(cherry picked from commit 788ea052fc)
2020-05-09 11:18:23 -04:00
4f8c6455bc Fix updates/history section headers in RTL locales
(cherry picked from commit 08ba805bbd)
2020-05-09 11:18:03 -04:00
c80b8c8ce9 Refresh page on 32-bit color setting change
(cherry picked from commit dbd14c6dac)
2020-05-09 11:17:49 -04:00
5435c2fb53 Lighter weight method of rounding cover art and removed rounded covers option
(cherry picked from commit dabca5f09e)
2020-05-09 11:17:07 -04:00
88963758b1 Add specific support for dummy extensions so that read chapter history is able to be freely restored without connecting to the source 2020-05-08 21:18:29 -04:00
e4d40c7693 Made migrate and merge with another only visible if the manga is favorited 2020-05-07 22:01:14 -04:00
2f928ac034 Release 2.9.2.6 2020-05-07 15:11:50 -04:00
509d7b20b4 ReImplement history features 2020-05-07 14:50:24 -04:00
35c4d0bf4e Saved searches now work 2020-05-06 15:19:37 -04:00
5e5f2b0f1a hide 'latest' when merging sources
(cherry picked from commit 40c1967f19d0db475acd04025989ded80571565d)
2020-05-05 15:28:36 -04:00
58135c965c Release 0.9.2.5 2020-05-05 14:34:22 -04:00
5a9b84fe00 Fix issue where some sources just wouldnt work at all (examples are Dynasty and Toonily) 2020-05-05 14:28:21 -04:00
c9a10d9033 Update build.grade and lint fixes 2020-05-05 14:27:28 -04:00
730c316e89 Small brackets change, though I dont think logic will(though knowing my luck this might have been the reason) 2020-05-05 00:54:47 -04:00
29a07429df Release 0.9.2.4 2020-05-04 23:52:34 -04:00
e44616fb3c Fix bottom nav opening if opening manga from updates while in action mode
(cherry picked from commit 5977fca6b9)
2020-05-04 23:41:08 -04:00
cb6ca49607 Remove some unneeded regular tachi stuff 2020-05-04 23:40:46 -04:00
ff8b58ee62 [CI SKIP] Add dev branch deploy script configuration
(cherry picked from commit 018dbce57e)
2020-05-04 23:36:42 -04:00
b1350928ee Remove unused import 2020-05-04 23:35:16 -04:00
52641494d3 Test for saved searches (currently doesnt work) 2020-05-04 21:04:58 -04:00
9bfe4ed829 Remove unneeded backup stuff, now almost everything is from stable 2020-05-04 20:33:09 -04:00
d6f0c0837b Fix downloaded only 2020-05-04 19:20:54 -04:00
074a1bbca4 Implement logic for saved searches 2020-05-04 19:17:14 -04:00
178cd2b52d Add my github 2020-05-04 16:44:29 -04:00
e35f807218 Change source migraton icon 2020-05-04 16:17:32 -04:00
63ca5cc66b Remove dev update checker 2020-05-04 16:17:07 -04:00
6b66d4a34c Move strings to external file 2020-05-04 15:35:25 -04:00
49580a7630 Fixed All Sources in Filter list 2020-05-04 13:58:08 -04:00
0300c1057b Release 0.9.2.3 2020-05-04 02:00:42 -04:00
f5b8d3120d Fix anilist jsonnull issue
41c64b7058
(cherry picked from commit abf47deee3)
2020-05-04 01:40:11 -04:00
fd88db37f7 Bunch of crash fixes
(cherry picked from commit ce0090f0ca)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt
2020-05-04 01:39:52 -04:00
39e36f957d More extreme method for enforcing WebView availability
(cherry picked from commit 6cd34614f6)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
2020-05-04 01:34:02 -04:00
e84c39bf7b Hitomi tag fixes(should now work for most tags) 2020-05-04 01:18:40 -04:00
5641b33bdd Add EH and similar specific tag formatting for global and local search 2020-05-04 00:53:38 -04:00
72681bef83 Fix showing hidden sources like the merged source 2020-05-04 00:16:33 -04:00
6de16125f7 Fix cutoff for new buttons if your screen is small 2020-05-04 00:15:56 -04:00
46478546a8 Implement long click global search for tags 2020-05-04 00:06:20 -04:00
d4659ffaae Fix merge with another crash 2020-05-04 00:05:44 -04:00
e192806950 Fix migration and merge buttons now showing up 2020-05-03 23:09:02 -04:00
1170334fde Fix adding a manga to library crash 2020-05-03 23:05:42 -04:00
d368064549 Possibly fix backup restores 2020-05-03 22:36:30 -04:00
ada0703d17 Remove unneeded variable 2020-05-03 21:46:43 -04:00
06d3a753ac Add manga migration and merge buttons 2020-05-03 21:24:00 -04:00
567c6ea8e7 Merging bugfix 2020-05-03 21:23:33 -04:00
bfc0868721 add built-in source icons
(cherry picked from commit f4533d9c7e0f989095bf40198dda59e58e1a6e01)
2020-05-03 19:35:53 -04:00
f5b7a8db1a Setup for install 2020-05-03 19:33:28 -04:00
bef0a44447 It Builds! 2020-05-03 18:34:46 -04:00
e9ff202851 Basic fixes 2020-05-03 15:03:07 -04:00
4a3323f7d0 Revert to old sorting library (fixes #3034)
(cherry picked from commit e29e94a5a1)
2020-05-03 14:41:17 -04:00
0014a0ca6c Migrate to flow 2020-05-03 14:37:31 -04:00
7e99a9f789 Linting Fixes AZ 2020-05-03 14:36:19 -04:00
03e5c5ca10 Linting fixes
(cherry picked from commit 3f63b320c4)
2020-05-03 14:35:49 -04:00
e4ff988f4d Revert some seekbar event listener changes
(cherry picked from commit 134dbd2f1d)
2020-05-03 14:34:40 -04:00
dde2320afc Replace some listeners with flowbindings
(cherry picked from commit dad010a891)
2020-05-03 14:34:40 -04:00
988d508025 Remove option to turn off app update checks, check every 3 days
(cherry picked from commit 8c1ec43500)
2020-05-03 14:34:11 -04:00
24850450cb Migrate more preferences
(cherry picked from commit 53a3be0703)
2020-05-03 14:33:03 -04:00
e97d1ac257 Replace deprecated adapterPosition with bindingAdapterPosition
(cherry picked from commit c967308859)
2020-05-03 14:31:00 -04:00
bc44eee5b7 Merge branch 'master' of https://github.com/az4521/Tachiyomi
necessary,
2020-05-03 14:29:54 -04:00
7a010e3446 Material Dialogs Eh Part 3 2020-05-03 14:29:11 -04:00
cb4fbb19ed Material Dialogs Eh Part 2 2020-05-03 14:29:10 -04:00
ddf0357c5c Material Dialogs Eh Part 1 2020-05-03 14:28:40 -04:00
800c01ea42 Lint fixes and update build.gradle 2020-05-03 14:27:34 -04:00
68bfba486e Added number of pages to preload configuration 2020-05-03 14:26:05 -04:00
c09f6cb20c Lint fixes 2020-05-03 14:25:41 -04:00
959bad0247 Lint fixes, likely nothing broke 2020-05-03 14:25:24 -04:00
efb8555d76 Update to SDK 29 (Android 10) (#2468)
(cherry picked from commit 83d5e458ca)
2020-05-03 14:24:52 -04:00
a393772083 Move things back into the EH package, no need for them to be in the regular app 2020-05-03 14:24:22 -04:00
b4ade8c15d Lint fixes, likely no visible changes 2020-05-03 14:22:13 -04:00
03502f6533 Merge branch 'master' of https://github.com/az4521/Tachiyomi 2020-05-03 14:21:26 -04:00
42c7669bca database changes for mergedsources 2020-05-03 14:21:26 -04:00
1916751f4f Complete RxBindings to FlowBinding migration
(cherry picked from commit 3d10dad780)
2020-05-03 14:19:54 -04:00
e46dd808e7 Remove unused widget styles and animations
(cherry picked from commit 01dd46c5ed)
2020-05-03 14:16:06 -04:00
5e92664761 Replace some old color attribute usages
(cherry picked from commit 11e10f6eff)
2020-05-03 14:15:36 -04:00
aa5fd22db0 Add confirm exist setting (closes #2615)
(cherry picked from commit 321a4b24b9)
2020-05-03 14:14:45 -04:00
56b1c07f58 Refactor databinding fields to parent abstract classes
(cherry picked from commit 6a532b836d)
2020-05-03 14:12:46 -04:00
2ecac08bcc Round manga info cover
(cherry picked from commit e388f0d563)
2020-05-03 14:11:12 -04:00
95002a6e87 More FlowPreferences migrations
(cherry picked from commit b8152dd7f9)
2020-05-03 14:03:50 -04:00
cea2b42b41 More FlowPreferences migrations
(cherry picked from commit 401210da44)
2020-05-03 14:02:47 -04:00
8bc5a7d746 Migrate some RxSharedPreferences to FlowSharedPreferences
(cherry picked from commit beb81b657e)
2020-05-03 14:00:35 -04:00
85723b975b Lint fix 2020-05-03 13:58:54 -04:00
a2e05cf80b Move bitmap images to nodpi
(cherry picked from commit 7118817df7)
2020-05-03 13:58:29 -04:00
87363e47b0 Remove setting that was accidentally added 2020-05-03 13:57:39 -04:00
aefa7a1a4a Fixes and such for integration to AZ 2020-05-03 13:56:36 -04:00
18f90587f2 Added option to migrate manga from manga details
(cherry picked from commit 3a4780e19b79e9afcb3e830cb02c52bd1c66bddf)
2020-05-03 13:34:42 -04:00
f47e9b6e14 Fixed migration crash when getting chapters
(cherry picked from commit a529667257908ddebaa92d36a83380c3c6c40408)
2020-05-03 13:22:40 -04:00
a7e4c1295d More Plurals
(cherry picked from commit bcd6c33ed8aaa1cf81c027f88ce4a954e379a545)
2020-05-03 13:22:40 -04:00
50097eef9f Fixes for merging from upstream
(cherry picked from commit 5f2eb19ea37ba191d414eee4e8f45f20f1a73e89)
2020-05-03 13:22:39 -04:00
949cdccbae Confirm exit for migrations
(cherry picked from commit 640bd8d9babb3ace1d6a370adad35050271aa008)
2020-05-03 13:22:39 -04:00
3d0dc64de1 Mass Migration now shows progress and total manga in the title
(cherry picked from commit 68c3d28b4bc7b5cc4038648d5f187fe4da9a42a9)
2020-05-03 13:22:18 -04:00
2e0102d689 Migrations now shows how many manual migrations were made after skipping the rest
(cherry picked from commit bac01c98073dbee6c09144b6ebc55b6a0d56d0da)
2020-05-03 13:22:17 -04:00
2557111607 Optimzing Mass-Migration
(cherry picked from commit 504a10a6ebc3f28a5dd761db8a90c709c8794153)
2020-05-03 13:22:17 -04:00
46a626d2c5 Fixed crash when rapidly trying to skip manga
(cherry picked from commit 14c80436fcb92d22f0691b7b68caf524fd09cab5)
2020-05-03 13:22:17 -04:00
fb92b1a0b4 Update MigrationProcessHolder.kt
(cherry picked from commit dbbdc4c62e83328fd5d3623e42e56aa74511c320)
2020-05-03 13:22:16 -04:00
8e6ed194a6 Moved migration icons to main
(cherry picked from commit e89853afcfc2dff47a79a5d5aa67d37b049748cd)
2020-05-03 13:22:16 -04:00
01175e687c Another fix for mass migration
Also fixing some deprecated code

(cherry picked from commit 2535ea92ebc97bad9f30e9e48493629df6db28a3)
2020-05-03 13:22:15 -04:00
00d2d4f969 More refactoring + more bug fixes
Such as when a manga picked has 0 chapters

(cherry picked from commit 332e8c9487b2e5e39a3a90705b2def80183bcc04)
2020-05-03 13:20:57 -04:00
43715f9835 Build fixes and remove possibly unneeded settings? 2020-05-03 13:20:56 -04:00
b99229b033 Refactoring + fixes for auto-migrate
(cherry picked from commit 142dc1c12a95534170517deb077c98896214a2d9)
2020-05-03 13:19:12 -04:00
62df1263b1 Cleanup of olf auto migration
(cherry picked from commit d64754e3e09e92b2e65c181b0b5e84b531490662)
2020-05-03 13:18:47 -04:00
a6f0e7f9b9 Part 2 of Auto-Migration Done
(cherry picked from commit c4321e3adfff1bdfdcd8ba209dd20549348be217)
2020-05-03 13:18:02 -04:00
f1472d4f8b Fixes for this new auto migration ui
(cherry picked from commit 6d6ff9598205e11c767cedf2fbe261f746df0624)
2020-05-03 13:08:47 -04:00
52ad282492 Finished Part 1 of new auto source migration
(cherry picked from commit 10206ae7b30fbd521308a6d725e107e708b97dd0)
2020-05-03 13:08:46 -04:00
e7b39f29f2 Implemented J2K Auto Source Migration
(cherry picked from commit 8ba75831e6f51f6472d85f813405ede3f679cfd8)
2020-05-03 13:07:43 -04:00
c62d3abbc5 Fix Migrations 2020-05-03 02:15:54 -04:00
fb3ce226b5 Made rounded library covers configurable 2020-05-03 02:15:54 -04:00
de5f43713f Rename catalogue classes/layouts -> source
(cherry picked from commit a1e7592bd8)
2020-05-03 02:14:08 -04:00
84aba68b96 Add persistent notch display mode
(cherry picked from commit 444cfa7669166edc874da4994396776a90ded465)
2020-05-03 02:08:53 -04:00
1be0171398 fix fingerprint icon in dark themes 2020-05-03 02:08:33 -04:00
82c49a42c3 fix lockscreen 2020-05-03 02:08:33 -04:00
599a4c7b17 Fix unintended change 2020-05-03 02:08:13 -04:00
895dbbdacb Set needed migrations 2020-05-03 02:07:07 -04:00
77026d4eeb Pure Light Theme fixes and adding eh stuff to strings.xml 2020-05-03 02:06:04 -04:00
256b1881f0 Tweak Button Styles Part 2 2020-05-03 01:57:54 -04:00
2a299485cc Add proper AZ Debug Icon 2020-05-03 01:53:59 -04:00
a6909a76ed Fix common toolbar popup menu text color (fixes #2695)
(cherry picked from commit b9ea6e8d96)
2020-05-03 01:52:05 -04:00
1ecba5bb7e Migrate to MaterialComponents themes
(cherry picked from commit 7d0ea614da)
2020-05-03 01:49:44 -04:00
c381b737d3 Use outlined icons in settings
(cherry picked from commit ace54f8175)
2020-05-03 01:48:03 -04:00
70e7974396 Json build fixes 2020-05-03 01:47:35 -04:00
2104b60b81 Run lint 2020-05-03 01:41:34 -04:00
09dcb8029c Add setting to hide manga content from update/download notifications
(cherry picked from commit f3d69599aa)
2020-05-03 01:41:06 -04:00
f2ed26479f Update for Workmanager 2020-05-03 01:40:53 -04:00
d03d9b344a Reenable Proguard
(cherry picked from commit bb7ed73743)
2020-05-03 01:38:48 -04:00
9b5fbda9a2 move jsoupextensions back pt2 2020-05-03 01:37:58 -04:00
647fbd1f4b Move JsoupExtensions back (fixes #2562) 2020-05-03 01:37:58 -04:00
fa6ed901df Optimize more imports 2020-05-03 01:37:25 -04:00
23ac3d18e5 Optimize imports, disallow wildcard imports because of klint, run linter 2020-05-03 01:36:21 -04:00
f18891a07e Move crash reports setting to advanced
(cherry picked from commit 978ac50015)
2020-05-03 01:34:51 -04:00
c85825f3c7 Run default Android Studio formatter on code
(cherry picked from commit 3ecc883944)
2020-05-03 01:33:58 -04:00
319571edf3 Remove EH custom incognito webview in favor of new activity webview from Dev(I could not get it working with the new system.) 2020-05-03 01:08:08 -04:00
1f20d96191 Convert webview into an activity (#2470)
Based on 65804ebb3a

(cherry picked from commit 797553ce16)
2020-05-03 01:06:07 -04:00
c2e50305eb Converted tachiyomi_circle to webp 2020-05-03 01:05:01 -04:00
d00e1284d6 Convert filter mock image to webp
(cherry picked from commit eb56567812)
2020-05-03 01:04:26 -04:00
ef4430216d fix github updater 2020-05-03 01:00:41 -04:00
643f666178 Notification conflict fix 2020-05-03 01:00:41 -04:00
989b968e5b Merge pull request #7 from jobobby04/Extensions_Overhaul_plus_other
Extensions overhaul plus other
2020-05-03 01:00:27 -04:00
92484e26e5 Set manga last update field based on chapter fetch time (closes #2217)
Based on 3c81f60041 (diff-7e5179d048c3dfaf75b444b7277fc840)

(cherry picked from commit ee8a53188c)
2020-05-03 01:00:27 -04:00
429056f2ca Build fixes 2020-05-03 00:48:34 -04:00
fa2b44eeb3 Move edit categories to library settings 2020-05-03 00:44:30 -04:00
52e742049b Reorganize other util files 2020-05-03 00:39:16 -04:00
97a86269e6 change a dependency to try to fix merged sources 2020-05-03 00:31:59 -04:00
654d98b5c4 unhide merged sources 2020-05-03 00:31:43 -04:00
0509db1935 E-Hentai WatchedList checkbox fix (#2) 2020-05-03 00:31:07 -04:00
acf879d28c Added Ehentai Watched list (#1) 2020-05-03 00:31:07 -04:00
cefe45e8cc fixed double-locking, added secure screen, fixed tsumino for real this time 2020-05-03 00:30:52 -04:00
03b44fff22 update changelog and readme, fix hentaicafe tags 2020-05-03 00:27:44 -04:00
71c373926f lock no longer requires usage access 2020-05-03 00:27:32 -04:00
1af11f076f finish adding drag and drop 2020-05-03 00:25:04 -04:00
Jay
41c99c33a6 cherrypick drag and drop sorting 2020-05-03 00:12:54 -04:00
58cce53746 delegate tsumino 2020-05-02 23:52:58 -04:00
df6cafd6d1 bump version, changelog, hide merged sources 2020-05-02 23:52:21 -04:00
cc6c1b5641 add debug for EH aged flags 2020-05-02 23:51:52 -04:00
d61adc0259 nhentai language filtering, added dev build in settings 2020-05-02 23:51:21 -04:00
9ed7ee65c3 unhide and begin working on merged sources 2020-05-02 23:48:30 -04:00
5f94e230f9 adaptive fingerguns icon 2020-05-02 23:45:00 -04:00
4d8f44ddae merge double upstream 2020-05-02 23:39:46 -04:00
b20c028566 skip double upstream androidx migration 2020-01-06 10:57:37 -05:00
9b883b1a09 androidx migration
I DID THIS ONE MYSELF WITHOUT TAKING IT FROM THE OTHER FORKS
YEEEEEEEEEEET
2020-01-06 03:26:31 -05:00
53402459f2 library tag searching and reordering downloads 2020-01-05 12:33:28 -05:00
bc6a1a1da6 add tristate library filters, update to dev 2020-01-04 15:16:49 -05:00
690d2fb15b fixed tsumino for real this time really 2019-11-29 01:18:21 -05:00
7ac188709b tsumino half fixed. mostly usable 2019-11-28 22:52:44 -05:00
93c8773e91 Update Tsumino.kt 2019-11-28 18:46:19 -05:00
eefe95c2ee Update TsuminoSearchMetadata.kt 2019-11-28 18:45:04 -05:00
af9825d369 Update TsuminoSearchMetadata.kt 2019-11-28 18:17:04 -05:00
59f38cb343 Update Tsumino.kt 2019-11-28 17:37:24 -05:00
810d2d4776 fix tsumino for real this time 2019-11-28 17:33:55 -05:00
027cb10d0f fix tsumino 2019-11-28 16:35:58 -05:00
24a6eba94e match upstream 2019-11-28 16:24:51 -05:00
c1c43bb6fb Add minimum/maximum pages filter to E-Hentai/ExHentai source 2019-08-31 17:45:40 -04:00
0804550539 Fix strange behavior when using text filters 2019-08-31 17:44:47 -04:00
3156482334 Upgrade Gradle, Kotlin and KotlinX Coroutines 2019-08-31 00:07:26 -04:00
052317b38a Fix HBrowse namespace correction
Fix HBrowse maleBody and femaleBody namespaces
2019-08-31 00:06:58 -04:00
6ff684f638 Migrate old update jobs 2019-08-13 01:43:07 -04:00
6857c8c1fe Use better job ids for EHentai updater 2019-08-13 01:41:31 -04:00
44d563e689 Use better job ids for EHentai updater 2019-08-13 01:39:01 -04:00
6ce2809450 Use better job ids for EHentai updater 2019-08-13 01:38:49 -04:00
0759036536 Use correct HBrowse source id 2019-08-13 01:31:44 -04:00
6f6490b7ac Bump version number and add changelog 2019-08-13 01:16:33 -04:00
da12a4b17f Speed up migration cancellation
Allow migrating an entire source of manga
2019-08-13 01:10:31 -04:00
1302bc84dd Fix auto-migration UI in dark theme 2019-08-13 00:19:26 -04:00
1c4a8046d0 Allow saving of HBrowse queries 2019-08-13 00:13:04 -04:00
141edac99b Fix EHentai reading progress not carrying over 2019-08-13 00:04:02 -04:00
b64ecfb836 Init notifyLockSecurity when idle
Increase idle-until-urgent delay
2019-08-12 21:16:45 -04:00
d5f4db5eb7 Re-schedule EHentai updater job on app boot
Idle-until-urgent some stuff in app init
Close debug menu onStop
2019-08-12 21:09:39 -04:00
7a3f6e9f63 Fix HBrowse pagination 2019-08-12 19:39:35 -04:00
b3ecc91be9 Fix HBrowse tag search 2019-08-12 19:27:11 -04:00
2a27eacf5e Bump version number and add changelog 2019-08-11 16:23:36 -04:00
e747686ad8 Upgrade realm
Update proguard file so we could potentially enable proguard in the future
Update dependencies
Downgrade duktape to fix MangaPlus
Remove useless dependencies
Remove useless tabGravity
Fix debug version crashing in background
2019-08-11 14:40:01 -04:00
282af20146 Upgrade firebase + glide 2019-08-11 11:38:17 -04:00
f25cd9fdbf Add changelog 2019-08-11 03:41:29 -04:00
2369547d59 Version number bump 2019-08-11 02:24:52 -04:00
d86b8cc78c Remove sidebar help button 2019-08-10 20:30:10 -04:00
b4c1e6a44c Add HBrowse 2019-08-10 20:23:43 -04:00
45fc2f2e0e Optimize SmartSearch system 2019-08-10 20:19:59 -04:00
9cfcacf45e Fix smart search algorithm not using smart queries 2019-08-09 14:07:08 -04:00
801fd83649 Hide MergedSource from source selector screen 2019-08-09 10:14:59 -04:00
16f1dcd922 Fix background updater not updating all galleries 2019-08-09 10:04:06 -04:00
8f36d698cf Fix EHentai gallery update notifications for real 2019-08-09 09:48:31 -04:00
a89a36fd4c Version number bump 2019-08-09 05:21:43 -04:00
8a7f8c4068 Fix incorrect label in auto-migration 2019-08-09 05:20:11 -04:00
9c70e69300 Fix select-all button selecting wrong category 2019-08-09 05:11:25 -04:00
a0b490b10f Fix EH gallery updater crashing 2019-08-09 04:40:44 -04:00
d69dc375a3 Add 8muses 2019-08-09 04:40:30 -04:00
ac6dbbcd89 Add update notifications for EH/EXH galleries 2019-08-08 20:04:31 -04:00
14879c4466 Isolate EH and EXH manga redirects 2019-08-08 14:45:40 -04:00
dce08d4922 Fix false update notifications for lewd sources 2019-08-08 13:49:27 -04:00
5195cb8eda Delegate Pururin.io 2019-08-08 13:31:47 -04:00
68de7b516e Transfer commit 2019-08-08 09:40:41 -04:00
10095205d8 Transfer commit 2019-08-07 20:51:44 -04:00
c4c988f7a4 Add Android 7 broken SSL workaround 2019-08-07 15:47:43 -04:00
333dfbc642 Add nhentai search-by-id 2019-08-07 10:48:17 -04:00
e915fd28cb Migrate to new URL import system 2019-08-07 10:21:18 -04:00
46636b537c Add update frequency restriction debug toggle 2019-08-04 22:55:38 -04:00
cd5545284e Fix reading position not being saved when opening multi-versioned EH manga 2019-08-04 21:27:59 -04:00
3dac6366ff Fix uninstall button 2019-08-04 10:55:09 -04:00
054a26cf65 Fix more button always visible 2019-08-04 01:28:00 -04:00
024c76d480 Fix EH version/chapter sorting shenanigans 2019-08-04 00:15:17 -04:00
9abdfeac77 Hide ability to create merged manga 2019-08-03 22:54:22 -04:00
0f12ae0cf7 Revert "Hide ability to create merged manga"
This reverts commit 7fc6d53c
2019-08-03 22:53:26 -04:00
71182e664a Revert "Open all E-Hentai galleries in ExHentai"
This reverts commit 9ff8235d
2019-08-03 22:47:02 -04:00
7fc6d53cae Hide ability to create merged manga 2019-08-03 22:26:53 -04:00
4f2985469c Finish auto-migration feature 2019-08-03 02:23:21 -04:00
9cc24a3be3 Merge branch 'transfer' of https://github.com/NerdNumber9/TachiyomiEH 2019-08-02 22:54:19 -04:00
7ec18861bf Use semaphores instead of channels where possible
Use correct starting title in auto-migrator
2019-08-02 22:54:06 -04:00
3d1c02136a Transfer commit 2019-08-02 22:32:50 -04:00
aca34155b9 Hide "accept migration" button when migration is not offered 2019-08-01 06:50:03 -04:00
d04ffb7ea9 Fix auto-migration target manga opening wrong manga when clicked 2019-07-31 13:24:05 -04:00
5b3e72db54 Completed most of auto-migration UI 2019-07-31 03:39:51 -04:00
f811cc5c87 Initial work on auto-migrate 2019-07-30 19:29:12 -04:00
e7abe27bb6 Hide internal sources from UI
Change wording on migration button in smartsearch
2019-07-30 10:22:46 -04:00
126d875547 Include language when displaying source-specific chapters in MergedManga 2019-07-30 02:08:27 -04:00
a2b7228e95 Fix infinite reloading after merging manga 2019-07-30 01:49:54 -04:00
10d6b3a6ca Initial MergedSource creation UI 2019-07-30 01:41:30 -04:00
4c9be5557d Initial work on merged sources 2019-07-29 19:36:16 -04:00
37e0ac0895 SmartSearch architecture improvements 2019-07-29 13:27:33 -04:00
8934d251d9 Initial work on SmartSearch 2019-07-29 02:12:30 -04:00
b5263a6968 Do not crash if source provides bad prefs 2019-07-28 03:45:50 -04:00
15bd8e964d Dependency updates 2019-07-28 02:53:25 -04:00
d931027067 Catch and ignore reader page sheet launch exception to prevent it from crashing the app
I have no idea why it happens so often but at this point I will just ignore the error
2019-07-28 02:35:53 -04:00
39ffd3c3bc Fix update worker crashing application 2019-07-28 02:32:10 -04:00
9ff8235de4 Open all E-Hentai galleries in ExHentai 2019-07-27 19:30:25 -04:00
54075733b7 Fix crashes when opening Tsumino captcha 2019-07-27 19:04:25 -04:00
2ea0538825 Remove useless long-press-to-change-category setting as it is now enabled by default 2019-07-27 19:03:35 -04:00
275e20eabd Merge branch 'master' of https://github.com/NerdNumber9/TachiyomiEH 2019-07-27 17:58:27 -04:00
7fe742e6ed Upstream merge 2019-07-27 17:56:31 -04:00
9a6bb69df8 Mark previous as unread now works when 'force ascending sort on gallery versions' is enabled 2019-04-22 09:24:57 -04:00
4c93ca6914 Merge pull request #82 from CarlosEsco/patch-1
update readme to new discord channel
2019-04-22 09:00:43 -04:00
51939ea652 update readme to new discord channel 2019-04-22 06:47:12 -04:00
256a4a2e7f Hide sorting options on EH manga when 'force ascending sort on gallery versions' is enabled 2019-04-22 00:34:43 -04:00
c217cab5db Fix reading progress being lost in some rare cases in galleries opened before v8.4.0 2019-04-22 00:16:38 -04:00
c93b6deaf8 Fix changelog sometimes not showing after update 2019-04-22 00:02:48 -04:00
55196b86b3 Fix chapters not being marked as read when transition pages are hidden 2019-04-21 23:52:40 -04:00
c5ab79f618 Improvements to accuracy of universal captcha detection 2019-04-21 23:01:41 -04:00
59fcfbe9d2 Fix universal captcha detection 2019-04-21 20:46:29 -04:00
6ce70296a6 Fix solve captcha activity not appearing (change that caused this was not released) 2019-04-21 17:28:07 -04:00
fdef687f0c Fix advanced login options for users on old devices
Fix ExHentai login and solve-captcha-window not working for users on old devices
Speed up ExHentai login significantly
2019-04-20 17:48:21 -04:00
cdd7f42532 Show warning when enabling applock on phones that cannot launch the grant-usage-stats-window. 2019-04-20 16:41:23 -04:00
65955fd7dc Remove used variable 2019-04-20 16:21:14 -04:00
b785f68154 Fix captcha solve activity sometimes never appearing 2019-04-20 14:07:52 -04:00
895191814e Fix favorites sync and backup/restore crashing on older devices 2019-04-20 14:01:18 -04:00
b06f253f83 Another attempt to fix autoscroll crashing the reader 2019-04-20 13:59:19 -04:00
0814439886 Include async stacktraces even on errors 2019-04-20 13:52:30 -04:00
a978cb90e8 Bump version and update changelog 2019-04-19 23:03:51 -04:00
39e0d434ad Add throttling when restoring E-Hentai/ExHentai galleries. 2019-04-19 22:59:24 -04:00
6ada3cbf59 Slow down favorites sync even more to prevent bands 2019-04-19 19:15:21 -04:00
4aff768b8e Fix multi-select operations crashing when selection is too large 2019-04-19 17:53:41 -04:00
e08e569135 Fix app crashing on startup for some users 2019-04-19 17:46:04 -04:00
8cac0fca67 Fix autoscroll crashing reader when sometimes 2019-04-19 17:40:05 -04:00
f447b06eff Fix incorrect rendering of seekbar on Android 4/5 2019-04-19 14:36:08 -04:00
78b2045b14 Various crash fixes on older Android versions 2019-04-19 14:26:37 -04:00
a427401d66 Fix EHentai and many other sources breaking 2019-04-19 13:14:41 -04:00
6da6ca710e Fix app crashing when updating library 2019-04-19 13:12:01 -04:00
f46c42f522 Add option to force ascending sort on gallery versions 2019-04-19 04:40:13 -04:00
c4df7b496b More optimizations to library search 2019-04-19 04:19:07 -04:00
6c4332f5c2 Disable aggressive page loading by default 2019-04-19 03:41:20 -04:00
86076d890a Fix wrong version number in new changelog 2019-04-19 03:38:33 -04:00
76a041f504 Add changelog for next release 2019-04-19 03:35:17 -04:00
c9bdc72d5d Upstream merge 2019-04-19 03:35:01 -04:00
f6a8b23498 Allow choosing hitomi.la thumbnail quality 2019-04-19 03:16:09 -04:00
2a60c828d7 Add aggressive page loading 2019-04-19 03:02:30 -04:00
ea7ff432b2 Add MangaDex login 2019-04-19 02:46:34 -04:00
5c2fbec80a Add universal captcha detection 2019-04-18 22:08:09 -04:00
f0109aa796 Fix manga info screen completely breaking on some sources 2019-04-18 21:04:20 -04:00
66b92f3eb7 Only auto-update old format galleries 2019-04-18 20:39:34 -04:00
ec4af65c36 Add universal captcha solver 2019-04-18 20:38:04 -04:00
852c1a423d Auto-update galleries in old format 2019-04-18 17:59:39 -04:00
1904be277d Fix auto-updater job never running 2019-04-18 17:59:17 -04:00
ebb1022100 Backup database in next release 2019-04-18 17:47:13 -04:00
8d85ec3cd9 Update gradle 2019-04-18 17:40:22 -04:00
1d36c3269e Add automatic gallery updating 2019-04-18 17:40:13 -04:00
a218f4a48b Gradle version upgrade 2019-04-16 12:25:53 -04:00
b14c3cc49f Logging tweak in ExtensionManager 2019-04-14 21:43:19 -04:00
cbc4a0f3ab Fix rating search 2019-04-14 21:00:42 -04:00
70a024d3de Minor tweak to debug overlay 2019-04-14 20:59:21 -04:00
28d43bbecc Allow searching by title for lewd galleries with missing metadata 2019-04-14 20:04:53 -04:00
55a3b2f3a1 Use different log filenames for different build types 2019-04-14 19:35:02 -04:00
2545b22ab1 Verify library state before syncing 2019-04-14 19:30:41 -04:00
77c07d13c0 Ignore non-existent galleries during favorites sync 2019-04-14 18:53:34 -04:00
98ac8a69c2 Minor type fix 2019-04-14 18:21:11 -04:00
0e22af7ba0 Hide view hierarchy captures from git 2019-04-14 18:21:00 -04:00
6951ce34c7 Fix deadlocks in gallery adder, favorites sync and backup/restore 2019-04-14 18:20:22 -04:00
24e10d6037 Add Discord link in README 2019-04-14 15:25:19 -04:00
f1b08bf56e Never backup log files 2019-04-14 13:57:14 -04:00
3cc3799ebb Ignore debug mode when choosing logger level 2019-04-14 13:54:31 -04:00
aed20a790e Remove extra line in debug overlay 2019-04-14 13:52:27 -04:00
81b20a23bf Add debug overlay
Disable crash workaround, not worth it
2019-04-14 13:51:20 -04:00
bd27cb74a7 Add extension/source blacklist 2019-04-14 12:48:59 -04:00
07fd3575c5 Better debug menu 2019-04-14 12:12:58 -04:00
6da504c999 Fix crash introduced when upgrading support library 2019-04-14 12:12:46 -04:00
23c1827838 Better importing of backups from Tachiyomi containing E-Hentai/ExHentai/nhentai/PervEden 2019-04-14 12:12:26 -04:00
49833fcc48 Migrate HentaiCafe IDs and nhentai URLs in backups 2019-04-14 11:17:21 -04:00
0e4c0fba5c Fix hitomi.la 2019-04-14 10:52:18 -04:00
bfe67f1cdf Add network inspection logging mode 2019-04-14 10:46:06 -04:00
863e349711 Improve logging 2019-04-14 10:09:43 -04:00
5e13df9bd8 Initialize manga when importing them 2019-04-14 09:30:48 -04:00
65abb8fa6c Fix read positions not being preserved 2019-04-14 09:30:29 -04:00
fe5c0295c3 Allow filter menu to be opened even if no filters to allow for search saving 2019-04-14 09:30:07 -04:00
4d15ac2fa3 Insert metadata in sync and when importing galleries 2019-04-14 09:09:24 -04:00
5e4b9fb15b Fix a crash that could occur in the incognito browser 2019-04-14 00:34:49 -04:00
8a70dffae8 Preserve async stack traces of http requests 2019-04-14 00:27:44 -04:00
8119eb4b34 Fix Tsumino source crashing app in some rare cases when network is unreliable 2019-04-14 00:09:19 -04:00
1bae7ba8f5 Fix app crash in some rare cases in reader 2019-04-13 23:56:40 -04:00
d4f1014df6 Improve logging infrastructure 2019-04-13 23:47:57 -04:00
dce685e711 Use app name as image save location 2019-04-13 23:03:20 -04:00
c4e6668c22 Get new URL on retry on EXH sources 2019-04-13 22:35:23 -04:00
9b5608c86d Fix build 2019-04-13 22:35:06 -04:00
2485a00d34 Upstream merge 2019-04-13 12:36:28 -04:00
8abe2d76b0 Support nhentai aliased tags
Better source ID detection
2019-04-13 12:18:42 -04:00
8e9087226f Add ability to hide transition page between chapters 2019-04-12 22:59:49 -04:00
8ccc3c8b0c Upgrade Kotlin coroutines library version 2019-04-12 18:38:13 -04:00
9b3579acf6 Decrease debounce time for library search
Async library search code cleanup
Rename LoadingTools -> LoaderManager
2019-04-12 12:16:52 -04:00
6f2ff6a77e Hide library progress bar by default 2019-04-12 07:14:42 -04:00
f772501159 Library search is now asynchronous
Library will now display progress bar while loading
More optimizations to library search
2019-04-12 06:50:24 -04:00
cadd389658 Remove unused metadata objects and misc code cleanup 2019-04-12 04:18:57 -04:00
6f36331818 Upgrade Kotlin version 2019-04-12 03:41:10 -04:00
d684eb5147 Misc code cleanup 2019-04-12 03:12:16 -04:00
349546cf87 Build speed improvements 2019-04-12 03:07:29 -04:00
352593ebc6 README update 2019-04-11 03:40:20 -04:00
c6b28cbcaf Upgrade dependencies
Remove Firebase Perf for better build speeds
2019-04-09 21:43:47 -04:00
c5e69d2080 Merge pull request #62 from Scrxtchy/image_path
Update Save Image path
2019-04-09 14:22:31 -04:00
cd4964d086 Update Save Image path 2019-04-09 23:57:07 +10:00
ac3967e997 Decrease favorites sync max throttle by 500ms (should be safe) 2019-04-07 05:32:59 -04:00
5df18f2558 Consider EHentai == ExHentai when performing local deletions while syncing 2019-04-07 05:16:34 -04:00
0b054126bc Attempt to fix strange crash occurring on older Android versions 2019-04-07 05:15:40 -04:00
d4740c57be Fix crash when app is closed while migrating metadata 2019-04-07 04:43:10 -04:00
739fc9f95d Sort saved searches in UI 2019-04-06 17:59:18 -04:00
96b1340aec Revert README update 2019-04-06 09:54:04 -04:00
57d83e3d1b Use TachiWeb filter serializer for saving filters 2019-04-06 09:45:28 -04:00
4e2c9dc083 Various fixes to search presets 2019-04-06 09:05:32 -04:00
fa6f60d454 Fix hentai cafe url import 2019-04-06 08:16:48 -04:00
71fe2bda97 Add release changelog 2019-04-06 07:53:27 -04:00
f24c5e944e Fix various proguard issues 2019-04-06 07:40:27 -04:00
603fd84753 Rewrite tag searching to use SQL
Fix EHentai/ExHentai
Fix hitomi.la
Fix hitomi.la crashing application
Rewrite hitomi.la search engine to be faster, use less CPU and require no preloading
Fix nhentai
Add additional filters to nhentai
Fix PervEden
Introduce delegated sources
Rewrite HentaiCafe to be a delegated source
Introduce ability to save/load search presets
Temporarily disable misbehaving native Tachiyomi migrations
Fix tap-to-search-tag breaking on aliased tags
Add debug menu
Add experimental automatic captcha solver
Add app name to wakelock names
Add ability to interrupt metadata migrator
Fix incognito open-in-browser being zoomed in immediately when it's opened
2019-04-06 07:35:36 -04:00
5fbe1a8614 Upstream merge 2019-03-31 00:23:44 -04:00
42169783e1 Merge branch 'master' of https://github.com/inorichi/tachiyomi 2018-08-27 12:43:45 -04:00
90574937df README update 2018-08-27 12:42:43 -04:00
ec0fe2210d Add ability to ask for category on long press 2018-08-04 10:49:29 -04:00
450fcccaa6 Log result in Tsumino and minor code cleanup 2018-08-03 22:03:51 -04:00
72504ca53f Minor typo fix and code cleanup 2018-08-03 21:34:31 -04:00
6bfddb3ece Bump Kotlin version 2018-08-03 21:34:12 -04:00
b62fcbc2ec Update changelog 2018-07-21 23:26:00 -04:00
411dda0e75 Introduce incognito open-in-browser support 2018-07-21 23:16:10 -04:00
d9d71c8745 Various dependency updates 2018-07-21 15:26:14 -04:00
35239af039 Allow preserving reading position even when manga is read 2018-07-18 22:46:47 -04:00
840e571917 Do not retry loading pages
GIF support in non-vertical pagers
Fix cache being double-opened
2018-07-18 22:17:46 -04:00
2fd4204db8 Reader cache + retry improvements 2018-07-17 22:29:49 -04:00
1fd105ac56 Bump version to next release 2018-07-08 19:49:33 -04:00
6ae90e0a7d Add ability to reverse search result order
Actually activate hath perks
2018-07-08 19:44:49 -04:00
43dc12a0f3 Fix hitomi browse/latest 2018-07-08 18:34:22 -04:00
28d05b629f Add additional advanced options to login screen
Add "more" button into global search results
Retry-all button is now more explicit on what was retried
Minor performance fix in hitomi search
2018-07-08 17:53:03 -04:00
30c12fc9de Get rid of outdated changelog 2018-07-08 15:53:59 -04:00
cdb62f502c Bump Realm version 2018-07-08 15:53:36 -04:00
5cfdbbce7a Merge branch 'master' of https://github.com/inorichi/tachiyomi
# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt
2018-07-08 15:51:26 -04:00
e2af1af656 Bump version to v7.4.1
Fix changelog
2018-06-10 12:19:53 -04:00
a96c25c37c Add retry all and boost page 2018-06-10 12:15:15 -04:00
c1abec3b4c Fix autoscroll scrolling right on right-to-left reader 2018-06-10 10:46:49 -04:00
c5a488ca3f Move ExHentai login to HTTPS 2018-06-10 01:47:17 -04:00
dd4a18a0b2 Prepare for release 2018-06-10 01:26:18 -04:00
34df0759f3 Improved autoscroll 2018-06-10 01:26:01 -04:00
b6a3f6ebd2 Add autoscroll support 2018-06-10 00:50:17 -04:00
ad2819a3bc Various dependency updates 2018-06-09 23:50:51 -04:00
0f2be86d5a Add ability to tune reader threads and instant retry 2018-06-09 23:12:53 -04:00
4342584c32 Minor code cleanup 2018-06-09 19:54:26 -04:00
71c10df270 Merge branch 'master' of https://github.com/inorichi/tachiyomi
# Conflicts:
#	README.md
#	app/.gitignore
#	app/build.gradle
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAboutController.kt
#	app/src/main/res/raw/changelog_release.xml
2018-06-09 19:52:02 -04:00
db90b5d2cb Minor typo fix in Hitomi.la settings 2018-06-09 19:37:12 -04:00
5cc38c1369 Release v7.2.3 2018-04-18 21:15:11 -04:00
e7c48a98df Fix app locking even if app lock is disabled
Hide fingerprint view if fingerprint is disabled
2018-04-18 10:18:32 -04:00
d03c49db58 Fix app lock crashing app on older devices 2018-04-18 10:11:47 -04:00
b69af710ad Release v7.2.2
Fix SimpleDateFormat crashing application on older Android OSes
Rename preference key (typo)
2018-04-17 15:58:49 -04:00
4d3b469c48 Upgrade realm version 2018-04-16 11:50:46 -04:00
8cc6c0171b Increment realm schema version 2018-04-16 09:53:18 -04:00
8be5be4720 Fix possible crash-on-start from getToolbarNavigationItem 2018-04-16 09:50:57 -04:00
995a1155e4 Update changelogs and add hitomi.la URL importing 2018-04-15 14:35:00 -04:00
234c3bb72a Merge branch 'master' of https://github.com/inorichi/tachiyomi
# Conflicts:
#	README.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
2018-04-15 13:39:29 -04:00
aafe863774 Add hitomi.la preferences screen
Add hitomi.la early refresh
Fix some typos in comments
2018-04-15 13:35:38 -04:00
fb1db914aa Fix Tsumino page offset (fixes #27) 2018-04-14 23:37:17 -04:00
7aa8abdd98 Add A-B swapping for hitomi.la search database 2018-04-14 23:23:55 -04:00
4bd965a795 Merge branch 'master' of https://github.com/NerdNumber9/TachiyomiEH 2018-04-14 21:17:50 -04:00
df2a4779bf Merge branch 'master' of https://github.com/inorichi/tachiyomi
# Conflicts:
#	.travis.yml
#	README.md
#	app/build.gradle
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt
#	app/src/main/res/layout/manga_info_controller.xml
#	app/src/main/res/raw/changelog_release.xml
2018-04-14 21:11:29 -04:00
d2dc063c8e More work on Hitomi.la 2018-04-14 15:50:05 -04:00
45f4c63941 Merge branch 'master' of https://github.com/inorichi/tachiyomi 2018-03-15 17:22:49 -04:00
5e968e5651 Fix broken back button in search 2018-03-15 17:04:33 -04:00
3e3c0a1f14 Add option to expand search filters by default 2018-03-15 16:57:16 -04:00
c48bebe0b2 Add option to disable auto lock and add manual locking 2018-03-14 18:39:01 -04:00
0dd9e9e015 Repackage captcha solve activity to UI package 2018-03-14 13:17:55 -04:00
d2a2e17e91 Re-theme lock view to actually match current theme 2018-03-14 13:13:57 -04:00
09dbd723e4 Fix Tsumino captcha appearing multiple times 2018-03-14 12:22:28 -04:00
eb965542cc Update changelog
Code cleanup
2018-03-13 20:49:17 -04:00
615fa05a75 Merge branch 'master' of https://github.com/inorichi/tachiyomi
# Conflicts:
#	README.md
#	app/build.gradle
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt
#	app/src/main/res/layout/manga_info_controller.xml
#	app/src/main/res/raw/changelog_release.xml
2018-03-13 15:58:47 -04:00
87a2ac7887 Attempt to add hitomi.la source (still broken) and code cleanup 2018-03-13 15:21:31 -04:00
07ce90ab8c Add Tsumino captcha display and merge branch 'master' of upstream
# Conflicts:
#	.github/readme-images/app-icon.png
#	.github/readme-images/screens.png
#	.travis.yml
#	README.md
#	app/build.gradle
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/online/YamlHttpSource.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/online/YamlHttpSourceMappings.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/util/DynamicConcurrentMergeOperator.java
2018-02-25 15:34:19 -05:00
a71ae29c98 Add Tsumino captcha display and merge branch 'master' of upstream
# Conflicts:
#	.github/readme-images/app-icon.png
#	.github/readme-images/screens.png
#	.travis.yml
#	README.md
#	app/build.gradle
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/online/YamlHttpSource.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/online/YamlHttpSourceMappings.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/util/DynamicConcurrentMergeOperator.java
2018-02-24 11:13:43 -05:00
117214c671 Implement lenient sync 2018-02-23 18:57:19 -05:00
c54d26d6ba Fix broken favorites sync
Release v6.8.2
2018-02-15 17:21:33 -05:00
5447bd098b Release v6.8.1 2018-02-14 17:21:29 -05:00
2b7c0e8e80 Fix gallery browsing 2018-02-12 16:22:54 -05:00
47966d89f2 Fix typo in sync throttle message 2018-02-03 11:22:59 -05:00
b28a2c3bd4 Fix sync sometimes crashing when ran multiple times without reopening the app 2018-02-02 12:48:09 -05:00
8f51abfc97 Sync is now essentially fully atomic on the client side
Sync now aborts on most errors instead of continuing
Sync now holds screen, CPU and WIFI locks
2018-02-02 12:11:09 -05:00
e9bea8ed47 Fix minor issue in sync intro screen 2018-02-01 14:39:21 -05:00
c2c1b6d2e8 Update changelog 2018-02-01 14:11:47 -05:00
ded22f1717 Finish favorites sync 2018-02-01 13:46:33 -05:00
126da3979c Merge branch 'master' of https://github.com/inorichi/tachiyomi 2018-01-31 22:40:17 -05:00
d892f2f7f4 Initial implementation of favorites syncing
General code cleanup
Fix some cases of duplicate galleries (not completely fixed)
2018-01-31 22:39:55 -05:00
f18b32626a Rewrite link intercept activity
Fix compatibility issues between lewd sources and manga info screen
2018-01-29 15:39:34 -05:00
8c8f2585aa Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	README.md
#	app/build.gradle
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdateDownloaderReceiver.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt
#	app/src/main/res/menu/library.xml
#	app/src/main/res/values/strings.xml
#	app/src/test/java/eu/kanade/tachiyomi/data/database/ChapterRecognitionTest.kt
2018-01-29 12:16:32 -05:00
1a811d0917 Code cleanup
Release v6.6.0
Cleanup changelog
2017-12-08 18:21:26 -05:00
9af552c15a Merge branch 'master' of https://github.com/inorichi/tachiyomi
# Conflicts:
#	README.md
#	app/build.gradle
#	app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/NoResultsException.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/latest_updates/LatestUpdatesPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
2017-12-07 23:20:27 -05:00
263cc1d97c See CHANGELOG.md for this commit 2017-12-07 22:25:27 -05:00
dec4471871 Second attempt to update changelog
Fix wording in metadata fetch dialog
2017-11-30 21:07:26 -05:00
c8122ebd68 Update changelog 2017-11-29 22:14:02 -05:00
b766ddea54 Merge branch 'master' of https://github.com/inorichi/tachiyomi
Fix back button in library search
2017-11-29 21:41:05 -05:00
5cb219d83e Various changes 2017-11-29 21:44:35 -05:00
908128b55d Merge upstream changes 2017-11-29 21:53:02 -05:00
b240960a8a Update dependencies
Remove travis config as we don't use travis
2017-11-29 21:55:56 -05:00
b91d8e4c19 Release 0.6.5 2017-11-29 18:49:22 +01:00
4853ff7eee Resubscribe to library when a change of type enter occurs. Resolves #1093 2017-11-29 10:05:33 +01:00
e1582bd73a Minor changes to download cache. Also keep the library view, as recreation is expensive 2017-11-28 23:58:37 +01:00
ac17335dbe Fix automatic backups (#1074)
* Fix automatic backups

* Small fixes

* small fixes
2017-11-28 22:55:50 +01:00
7053777997 Release version v6.1.4
Offload metadata check to background thread
Add search cache
2017-08-28 03:20:35 -04:00
1107b95ebd Remove leftover code 2017-08-26 03:52:52 -04:00
36003fd622 Remove leftover TODO 2017-08-26 03:48:12 -04:00
84121ff901 Release v6.1.3
Make search engine synchronous
Offload some search engine tasks to background threads
Minor search engine speedups
2017-08-26 03:40:59 -04:00
bcc2ec1668 Fix migration dialog showing on startup even with no manga 2017-08-25 22:26:57 -04:00
08dffda2a1 Fix NHentai and PervEden sources
Version bump to v6.1.2
2017-08-25 19:08:33 -04:00
9f4540a4f1 Fallback to normal library searching when metadata is not available 2017-08-25 18:52:32 -04:00
f19ef9aa01 Fix proguard rules 2017-08-25 18:51:25 -04:00
f10a06341b More changelog entries 2017-08-25 18:50:57 -04:00
67ac95f15f Merge branch 'master' of https://github.com/inorichi/tachiyomi 2017-08-25 17:39:22 -04:00
cd291f0a27 Migrate to realm for metadata 2017-08-25 17:31:38 -04:00
bb6b88a703 Make drawerArrow private again (as it was in upstream) 2017-08-24 18:31:45 -04:00
239b36c31a Add nhentai URL importing
Allow fast importing of single URLs by inputting the URL into the source's search bar
2017-08-24 18:31:08 -04:00
dcb6ae44dd Fix intercept activity 2017-08-24 17:33:03 -04:00
5ed365cf0d Remove outdated declarations from AndroidManifest 2017-08-24 17:13:09 -04:00
b20b3d6f5c Add fingerprint to lock UI
Migrate login UI to conductor
Fix batch add controller not saving EditText content onResume
Prevent double-locking of lock UI
Remove back button from lock UI
Fix login preference not updating
2017-08-24 17:11:43 -04:00
32d02f9329 Migrate to Tachiyomi 6.1
Rewrite batch add UI
Rewrite lock UI
2017-08-24 12:28:54 -04:00
3da7c47bf5 Merge branch 'master' of https://github.com/inorichi/tachiyomi
# Conflicts:
#	app/build.gradle
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/ActivityMixin.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/adapter/FlexibleViewHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/adapter/SmartFragmentStatePagerAdapter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/fragment/BaseFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/fragment/BaseRxFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/fragment/FragmentMixin.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/latest_updates/LatestUpdatesFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/ChangelogDialogFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaEvent.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/ChapterCountEvent.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaFavoriteEvent.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAboutFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadsFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsTrackingFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/util/AndroidComponentUtil.java
#	app/src/main/java/eu/kanade/tachiyomi/widget/preference/LibraryColumnsDialog.kt
#	app/src/main/java/eu/kanade/tachiyomi/widget/preference/SimpleDialogPreference.kt
#	app/src/main/res/layout/activity_download_manager.xml
#	app/src/main/res/layout/activity_edit_categories.xml
#	app/src/main/res/layout/activity_manga.xml
#	app/src/main/res/layout/activity_preferences.xml
#	app/src/main/res/layout/fragment_backup.xml
#	app/src/main/res/layout/fragment_download_queue.xml
#	app/src/main/res/layout/fragment_library.xml
#	app/src/main/res/layout/fragment_library_category.xml
#	app/src/main/res/layout/item_chapter.xml
#	app/src/main/res/layout/item_recent_chapters.xml
#	app/src/main/res/layout/toolbar.xml
#	app/src/main/res/raw/changelog_release.xml
#	app/src/main/res/values/arrays.xml
#	app/src/main/res/xml/pref_about.xml
#	app/src/main/res/xml/pref_advanced.xml
#	app/src/main/res/xml/pref_downloads.xml
#	app/src/main/res/xml/pref_general.xml
#	app/src/main/res/xml/pref_reader.xml
#	app/src/main/res/xml/pref_sources.xml
#	app/src/main/res/xml/pref_tracking.xml

Migrate to Tachiyomi 6.1
Rewrite batch add UI
2017-08-24 11:24:23 -04:00
029f159aea Add the ability to import galleries by specifying the URL of one of it's pages 2017-05-08 20:03:20 -04:00
0a300822a4 Fix NoClassDefFoundError in E-Hentai/ExHentai source. 2017-05-05 00:41:10 -04:00
8d48e0289a Merge origin branch (I messed up the repo) 2017-05-04 23:54:18 -04:00
9dbb59f337 Upstream merge
Internal permission change
Fix url adder
2017-05-04 23:38:17 -04:00
a243aeafba Release v5.0.2. 2017-03-16 23:12:38 -04:00
5c671de29e Fix NHentai source only showing first page. 2017-03-16 22:54:55 -04:00
e161e5d30d Release version 5.0.1. 2017-03-15 15:03:36 -04:00
2fd64d0ca7 Fix download notifier breaking on some weird titles. 2017-03-15 14:56:34 -04:00
d981c75600 Add favorites downloader. 2017-03-15 14:39:09 -04:00
492adb7035 Release version 5.0.0. 2017-03-09 20:53:28 -05:00
811bca18d9 Yolo 2017-03-09 20:47:06 -05:00
3222e0646d Various bug fixes. 2017-03-09 20:46:24 -05:00
fa6790856d Fixed SourceManager creating sources multiple times on app launch. 2017-03-09 18:49:52 -05:00
38a15d4158 Fix lock preference observing on wrong thread. 2017-03-09 18:23:45 -05:00
77cd459c51 Retry button now uses a different H@H server. 2017-03-09 18:18:53 -05:00
fa115ed9a0 Fix null scanlator text.
Fix nhentai "Open in Browser" and "Share" buttons.
2017-03-09 17:31:17 -05:00
30a2b572ab Enable text selection in manga info window. 2017-03-09 17:21:11 -05:00
b1ab77188d Add apk files to gitignore. 2017-03-09 17:17:30 -05:00
e212e4581d Fix user being asked for lock permissions when lock is not enabled. 2017-03-09 17:17:18 -05:00
1b8daa7e09 Another attempt to fix proguard config. 2017-03-09 16:53:13 -05:00
99d126fd3a Fix typo in proguard config. 2017-03-09 16:50:31 -05:00
9fee7c6b19 Fix proguard rules. 2017-03-09 16:47:55 -05:00
1b5a83563f Hopefully fix stackoverflow crash. 2017-03-09 16:31:28 -05:00
c8a8eb0a4d Add nhentai source. 2017-03-09 16:01:34 -05:00
0a7812bb2c Remove old debugging code and useless comments. 2017-03-08 18:58:56 -05:00
061b434687 Fix crashes when opening invalid manga. 2017-03-08 17:14:12 -05:00
f3be1a6d09 Fix crash due to empty page list. 2017-03-07 23:03:07 -05:00
1e797bfe8a Add PIN feature to README.
Remove hint from PIN setup dialog.
2017-03-07 22:50:40 -05:00
97435dbe0f Fix readme. 2017-03-07 22:48:27 -05:00
3fdbb95b15 More documentation. 2017-03-07 22:44:22 -05:00
961a6c0b4f Code cleanup. 2017-03-07 22:44:08 -05:00
c42f011a05 Implement Perv Eden source. 2017-03-07 22:02:16 -05:00
957c50088d Add cancel button to lock preference. 2017-03-05 12:49:56 -05:00
3b129176d6 Code cleanup. 2017-03-05 12:41:34 -05:00
f36327ecc9 Add application lock functionality. 2017-03-05 12:36:52 -05:00
5f48bb8e7d Merge branch 'master' of https://github.com/inorichi/tachiyomi
# Conflicts:
#	README.md
#	app/build.gradle
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/source/SourceManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/backup/BackupPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/ChangelogDialogFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
#	app/src/main/res/raw/changelog_release.xml
#	app/src/main/res/values/arrays.xml
#	app/src/main/res/values/strings.xml
2017-03-04 22:54:00 -05:00
aba8d01818 Merge branch 'master' of https://github.com/inorichi/tachiyomi 2017-03-04 22:46:56 -05:00
03cb7062f2 Merge branch 'master' of https://github.com/inorichi/tachiyomi
# Conflicts:
#	README.md
#	app/build.gradle
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/source/SourceManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/backup/BackupPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/ChangelogDialogFragment.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
#	app/src/main/res/raw/changelog_release.xml
#	app/src/main/res/values/arrays.xml
#	app/src/main/res/values/strings.xml
2017-03-04 22:43:06 -05:00
d4b35736c0 Gallery chapter metadata will now be automatically downloaded when importing galleries. 2017-02-28 17:37:51 -05:00
c30aa710f3 Change baseUrl from g.e-hentai.org -> e-hentai.org 2017-02-28 17:21:00 -05:00
0adac4217e Fix share button adding extra "/" onto end of URL
Fixed by removing "/" from end of baseUrl.
2017-02-28 17:09:13 -05:00
7e102edd0a Increase memory allocated to gradle 2017-02-28 16:57:09 -05:00
adefe87129 Minor code cleanup 2017-02-28 16:56:47 -05:00
8a05fc8966 Add local namespace searching. 2017-02-28 16:56:29 -05:00
8fa798cf63 Update README. 2017-01-09 18:11:51 -05:00
01b20b2acb Add some branding. 2017-01-09 18:10:06 -05:00
a8d72dd6f8 Whoops missed the changelog. 2017-01-09 17:37:38 -05:00
84042c61e0 Release 4.0.1. 2017-01-09 17:33:47 -05:00
407ba6c628 Fix duplicate galleries. 2017-01-09 17:27:58 -05:00
16a3c676ef Update README.md 2017-01-07 12:08:32 -05:00
9b3a99432b Update README.md 2017-01-07 12:07:17 -05:00
036f757086 Update README.md 2017-01-07 12:06:47 -05:00
a391529b32 Fix updater. 2017-01-07 11:55:16 -05:00
d10b782308 Merge remote-tracking branch 'origin/master' 2017-01-07 10:47:53 -05:00
a58f780452 Remove ACRA. 2017-01-07 10:07:37 -05:00
606de03c7c Various bug fixes. 2017-01-06 20:57:50 -05:00
2b988c51ad Add migration system. 2017-01-06 18:01:40 -05:00
cb73e55db1 Deduplicate some code.
Change package name.
2017-01-05 18:26:32 -05:00
8fb4093dc6 Various bug fixes and code cleanup. 2017-01-04 23:34:47 -05:00
f5c4535cb0 Add migration ability.
Various bug fixes and code cleanup.
2017-01-04 22:56:24 -05:00
e4f2bffbc2 Various bug fixes and code cleanup. 2017-01-04 20:19:44 -05:00
5c942460f9 Various bug fixes. 2017-01-04 16:24:21 -05:00
cce1f2c20d Finish batch add screen. 2017-01-04 14:37:28 -05:00
516a3bd017 Integrate tag searching into library. 2017-01-04 11:17:12 -05:00
63d58c7a4f Add uploader faux-namespace to search engine. 2017-01-04 10:30:44 -05:00
c49b865ee7 Regexes are now compiled only once by search engine. 2017-01-04 00:06:53 -05:00
097a83e3ba Fix some bugs in the search engine. 2017-01-03 23:45:44 -05:00
02c70d868d Implement search engine. 2017-01-03 16:57:51 -05:00
c836f52460 Implement most gallery settings. 2017-01-03 11:27:10 -05:00
caa1e1ef09 Add EH code. 2017-01-02 18:02:10 -05:00
5c63531066 Add logged in property reporting. 2016-10-18 22:13:43 -04:00
15b2bbc6d1 Merge changes.
Various changes.
2016-10-18 21:58:00 -04:00
3cafbd9141 Merge changes.
Various changes.
2016-10-18 21:50:48 -04:00
dc0405a373 More build fixes. 2016-08-05 20:25:48 -04:00
f84832716a Remove unused classes and clean up build. 2016-08-05 20:19:27 -04:00
200aa4042f Fix table in README. 2016-08-05 20:08:35 -04:00
f44c5adcc0 Update README with correct data. 2016-08-05 20:05:20 -04:00
3c43bebe64 Integrate TachiyomiEH changes. 2016-08-05 19:42:36 -04:00
1694 changed files with 79891 additions and 117481 deletions

View File

@ -1,7 +0,0 @@
[*.{kt,kts}]
indent_size=4
insert_final_newline=true
ij_kotlin_allow_trailing_comma=true
ij_kotlin_allow_trailing_comma_on_call_site=true
ij_kotlin_name_count_to_use_star_import = 2147483647
ij_kotlin_name_count_to_use_star_import_for_members = 2147483647

33
.github/CONTRIBUTING.md vendored Executable file
View File

@ -0,0 +1,33 @@
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 (Setting > About > Version)
* If not latest, try updating, it may have already been solved
* Dev 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)

1
.github/FUNDING.yml vendored
View File

@ -1 +1,2 @@
github: inorichi
ko_fi: inorichi

16
.github/ISSUE_TEMPLATE.md vendored Normal file → Executable file
View File

@ -2,21 +2,15 @@
I acknowledge that:
- I have updated:
- To the latest version of the app (stable is v0.14.0)
- All extensions
- I have tried the troubleshooting guide: https://tachiyomi.org/help/guides/troubleshooting-problems/
- If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions
- I have searched the existing issues and this is new ticket **NOT** a duplicate or related to another open or closed issue
- I will fill out the title and the information in this template
Note that the issue will be automatically closed if you do not fill out the title or requested information.
- I have updated to the latest version of the app (stable is v0.9.2)
- 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
**DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT**
---
## Device information
### Device information
* Tachiyomi version: ?
* Android version: ?
* Device: ?
@ -30,5 +24,3 @@ Note that the issue will be automatically closed if you do not fill out the titl
## Other details
Additional details and attachments.
If you're experiencing crashes, share the crash logs from More → Settings → Advanced → Dump crash logs.

36
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,36 @@
---
name: "🐞 Bug report"
about: Report a bug
title: "[Bug] Write short description here"
labels: "bug"
---
**PLEASE READ THIS**
I acknowledge that:
- I have updated to the latest version of the app (stable is v0.9.2)
- 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
**DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT**
---
### Device information
* Tachiyomi version: ?
* Android version: ?
* Device: ?
## Steps to reproduce
1. First step
2. Second step
### Expected behavior
This should happen.
### Actual behavior
This happened instead.
### Other details
Additional details and attachments.

View File

@ -1,11 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: ⚠️ Extension/source issue
url: https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose
about: Issues and requests for extensions and sources should be opened in the tachiyomi-extensions repository instead
- name: 📦 Tachiyomi extensions
url: https://tachiyomi.org/extensions
about: List of all available extensions with download links
- name: 🖥️ Tachiyomi website
url: https://tachiyomi.org/help/
about: Guides, troubleshooting, and answers to common questions

View File

@ -0,0 +1,24 @@
---
name: "🌟 Feature request"
about: Suggest a feature to improve Tachiyomi
title: "[Feature Request] Write short description here"
labels: "feature"
---
**PLEASE READ THIS**
I acknowledge that:
- I have updated to the latest version of the app (stable is v0.9.2)
- 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
**DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT**
---
### Why/User Benefit/User Problem
(explain why this feature should be added)
### What/Requirements
(explain how this feature would behave)

View File

@ -1,106 +0,0 @@
name: 🐞 Issue report
description: Report an issue in Tachiyomi
labels: [Bug]
body:
- type: textarea
id: reproduce-steps
attributes:
label: Steps to reproduce
description: Provide an example of the issue.
placeholder: |
Example:
1. First step
2. Second step
3. Issue here
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: Explain what you should expect to happen.
placeholder: |
Example:
"This should happen..."
validations:
required: true
- type: textarea
id: actual-behavior
attributes:
label: Actual behavior
description: Explain what actually happens.
placeholder: |
Example:
"This happened instead..."
validations:
required: true
- type: textarea
id: crash-logs
attributes:
label: Crash logs
description: |
If you're experiencing crashes, share the crash logs from **More → Settings → Advanced** then press **Dump crash logs**.
placeholder: |
You can paste the crash logs in plain text or upload it as an attachment.
- type: input
id: tachiyomi-version
attributes:
label: Tachiyomi version
description: You can find your Tachiyomi version in **More → About**.
placeholder: |
Example: "0.14.0"
validations:
required: true
- type: input
id: android-version
attributes:
label: Android version
description: You can find this somewhere in your Android settings.
placeholder: |
Example: "Android 11"
validations:
required: true
- type: input
id: device
attributes:
label: Device
description: List your device and model.
placeholder: |
Example: "Google Pixel 5"
validations:
required: true
- type: textarea
id: other-details
attributes:
label: Other details
placeholder: |
Additional details and attachments.
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Read this carefully, we will close and ignore your issue if you skimmed through this.
options:
- label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open or closed issue.
required: true
- label: I have written a short but informative title.
required: true
- label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose).
required: true
- label: I have tried the [troubleshooting guide](https://tachiyomi.org/help/guides/troubleshooting/).
required: true
- label: I have updated the app to version **[0.14.0](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**.
required: true
- label: I have updated all installed extensions.
required: true
- label: I will fill out all of the requested information in this form.
required: true

View File

@ -1,39 +0,0 @@
name: ⭐ Feature request
description: Suggest a feature to improve Tachiyomi
labels: [Feature request]
body:
- type: textarea
id: feature-description
attributes:
label: Describe your suggested feature
description: How can Tachiyomi be improved?
placeholder: |
Example:
"It should work like this..."
validations:
required: true
- type: textarea
id: other-details
attributes:
label: Other details
placeholder: |
Additional details and attachments.
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Read this carefully, we will close and ignore your issue if you skimmed through this.
options:
- label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open or closed issue.
required: true
- label: I have written a short but informative title.
required: true
- label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose).
required: true
- label: I have updated the app to version **[0.14.0](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**.
required: true
- label: I will fill out all of the requested information in this form.
required: true

View File

@ -0,0 +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"
labels: "catalog"
---
DO NOT OPEN AN ISSUE IN THIS REPO. SEE https://github.com/inorichi/tachiyomi-extensions

10
.github/mergify.yml vendored
View File

@ -1,10 +0,0 @@
#pull_request_rules:
# - name: Automatically merge translations
# conditions:
# - "author = weblate"
# - "-conflict"
# - "current-day-of-week = Sat"
# - "created-at < 1 day ago"
# actions:
# merge:
# method: squash

View File

@ -1,12 +0,0 @@
<!--
Please include a summary of the change and which issue is fixed.
Also make sure you've tested your code and also done a self-review of it.
Don't forget to check all base themes and tablet mode for relevant changes.
If your changes are visual, please provide images below:
### Images
| Image 1 | Image 2 |
| ------- | ------- |
| ![](https://github.githubassets.com/images/modules/logos_page/Octocat.png) | ![](https://github.githubassets.com/images/modules/logos_page/Octocat.png) |
-->

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
.github/readme-images/screens.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

14
.github/renovate.json vendored
View File

@ -1,14 +0,0 @@
{
"extends": [
"config:base"
],
"schedule": ["every sunday"],
"ignoreDeps": [
"androidx.core:core-splashscreen",
"androidx.work:work-runtime-ktx",
"info.android15.nucleus:nucleus-support-v7",
"info.android15.nucleus:nucleus",
"com.android.tools:r8",
"com.google.guava:guava"
]
}

25
.github/workflows/PullRequestTester.yml vendored Normal file
View File

@ -0,0 +1,25 @@
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;20.0.5594570"
- 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

View File

@ -0,0 +1,31 @@
name: Remote Dispatch Action Initiator
on:
push:
repository_dispatch:
jobs:
ping-pong:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
with:
fetch-depth: '0'
- name: TAG - Bump version and push tag
uses: anothrNick/github-tag-action@1.17.2
if: github.event.action != 'pong'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WITH_V: true
RELEASE_BRANCHES: master
- name: PING - Dispatch initiating repository event
if: github.event.action != 'pong'
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 }}'"

View File

@ -1,39 +0,0 @@
name: PR build check
on:
pull_request:
paths-ignore:
- '**.md'
- 'i18n/src/main/res/**/strings.xml'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build:
name: Build app
runs-on: ubuntu-latest
steps:
- name: Clone repo
uses: actions/checkout@v3
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
- name: Dependency Review
uses: actions/dependency-review-action@v2
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: 11
distribution: adopt
- name: Build app and run unit tests
uses: gradle/gradle-command-action@v2
with:
arguments: assembleStandardRelease testStandardReleaseUnitTest

View File

@ -1,106 +0,0 @@
name: CI
on:
push:
branches:
- master
tags:
- v*
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Build app
runs-on: ubuntu-latest
steps:
- name: Clone repo
uses: actions/checkout@v3
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: 11
distribution: adopt
- name: Build app and run unit tests
uses: gradle/gradle-command-action@v2
with:
arguments: assembleStandardRelease testStandardReleaseUnitTest
# Sign APK and create release for tags
- name: Get tag name
if: startsWith(github.ref, 'refs/tags/') && github.repository == 'tachiyomiorg/tachiyomi'
run: |
set -x
echo "VERSION_TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
- name: Sign APK
if: startsWith(github.ref, 'refs/tags/') && github.repository == 'tachiyomiorg/tachiyomi'
uses: r0adkll/sign-android-release@v1
with:
releaseDirectory: app/build/outputs/apk/standard/release
signingKeyBase64: ${{ secrets.SIGNING_KEY }}
alias: ${{ secrets.ALIAS }}
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
keyPassword: ${{ secrets.KEY_PASSWORD }}
- name: Clean up build artifacts
if: startsWith(github.ref, 'refs/tags/') && github.repository == 'tachiyomiorg/tachiyomi'
run: |
set -e
mv app/build/outputs/apk/standard/release/app-standard-universal-release-unsigned-signed.apk tachiyomi-${{ env.VERSION_TAG }}.apk
sha=`sha256sum tachiyomi-${{ env.VERSION_TAG }}.apk | awk '{ print $1 }'`
echo "APK_UNIVERSAL_SHA=$sha" >> $GITHUB_ENV
cp app/build/outputs/apk/standard/release/app-standard-arm64-v8a-release-unsigned-signed.apk tachiyomi-arm64-v8a-${{ env.VERSION_TAG }}.apk
sha=`sha256sum tachiyomi-arm64-v8a-${{ env.VERSION_TAG }}.apk | awk '{ print $1 }'`
echo "APK_ARM64_V8A_SHA=$sha" >> $GITHUB_ENV
cp app/build/outputs/apk/standard/release/app-standard-armeabi-v7a-release-unsigned-signed.apk tachiyomi-armeabi-v7a-${{ env.VERSION_TAG }}.apk
sha=`sha256sum tachiyomi-armeabi-v7a-${{ env.VERSION_TAG }}.apk | awk '{ print $1 }'`
echo "APK_ARMEABI_V7A_SHA=$sha" >> $GITHUB_ENV
cp app/build/outputs/apk/standard/release/app-standard-x86-release-unsigned-signed.apk tachiyomi-x86-${{ env.VERSION_TAG }}.apk
sha=`sha256sum tachiyomi-x86-${{ env.VERSION_TAG }}.apk | awk '{ print $1 }'`
echo "APK_X86_SHA=$sha" >> $GITHUB_ENV
cp app/build/outputs/apk/standard/release/app-standard-x86_64-release-unsigned-signed.apk tachiyomi-x86_64-${{ env.VERSION_TAG }}.apk
sha=`sha256sum tachiyomi-x86_64-${{ env.VERSION_TAG }}.apk | awk '{ print $1 }'`
echo "APK_X86_64_SHA=$sha" >> $GITHUB_ENV
- name: Create Release
if: startsWith(github.ref, 'refs/tags/') && github.repository == 'tachiyomiorg/tachiyomi'
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ env.VERSION_TAG }}
name: Tachiyomi ${{ env.VERSION_TAG }}
body: |
---
### Checksums
| Variant | SHA-256 |
| ------- | ------- |
| Universal | ${{ env.APK_UNIVERSAL_SHA }}
| arm64-v8a | ${{ env.APK_ARM64_V8A_SHA }}
| armeabi-v7a | ${{ env.APK_ARMEABI_V7A_SHA }}
| x86 | ${{ env.APK_X86_SHA }} |
| x86_64 | ${{ env.APK_X86_64_SHA }} |
files: |
tachiyomi-${{ env.VERSION_TAG }}.apk
tachiyomi-arm64-v8a-${{ env.VERSION_TAG }}.apk
tachiyomi-armeabi-v7a-${{ env.VERSION_TAG }}.apk
tachiyomi-x86-${{ env.VERSION_TAG }}.apk
tachiyomi-x86_64-${{ env.VERSION_TAG }}.apk
draft: true
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

13
.github/workflows/issue_closer.yml vendored Normal file
View File

@ -0,0 +1,13 @@
name: Issue closer
on: [issues]
jobs:
autoclose:
runs-on: ubuntu-latest
steps:
- name: Autoclose issue
uses: arkon/issue-closer-action@v1.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
issue-close-message: "@${issue.user.login} this issue was automatically closed because it was not filled in correctly or the acknowledgment section was not removed."
issue-title-pattern: ".*THIS ISSUE IS IN THE WRONG REPO.*"
issue-body-pattern: ".*DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT.*"

View File

@ -1,35 +0,0 @@
name: Issue moderator
on:
issues:
types: [opened, edited, reopened]
issue_comment:
types: [created]
jobs:
moderate:
runs-on: ubuntu-latest
steps:
- name: Moderate issues
uses: tachiyomiorg/issue-moderator-action@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
auto-close-rules: |
[
{
"type": "body",
"regex": ".*DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT.*",
"message": "The acknowledgment section was not removed."
},
{
"type": "body",
"regex": ".*\\* (Tachiyomi version|Android version|Device): \\?.*",
"message": "Requested information in the template was not filled out."
},
{
"type": "both",
"regex": "^(?!.*myanimelist.*).*(aniyomi|anime).*$",
"ignoreCase": true,
"message": "Tachiyomi does not support anime, and has no plans to support anime. In addition Tachiyomi is not affiliated with Aniyomi https://github.com/jmir1/aniyomi"
}
]

View File

@ -1,19 +0,0 @@
name: Lock threads
on:
# Daily
schedule:
- cron: '0 0 * * *'
# Manual trigger
workflow_dispatch:
inputs:
jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v3
with:
github-token: ${{ github.token }}
issue-inactive-days: '2'
pr-inactive-days: '2'

12
.gitignore vendored Normal file → Executable file
View File

@ -5,9 +5,19 @@
.idea/
*iml
*.iml
/mainframer
/.mainframer
# Built files
*/build
/build
*.apk
app/**/output.json
app/**/output.json
# Hebrew assets are copied on build
app/src/main/res/values-iw/
TODO.md
CHANGELOG.md
/captures
build.sh

81
.travis.yml Normal file
View File

@ -0,0 +1,81 @@
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=

View File

@ -1,126 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community moderators are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community moderators have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community moderators responsible for enforcement at
the [Tachiyomi Discord server](https://discord.gg/tachiyomi).
All complaints will be reviewed and investigated promptly and fairly.
All community moderators are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community moderators will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community moderators, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/),
version 2.1, available at
[v2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html).
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
For answers to common questions about this code of conduct, see the FAQ at
[FAQ](https://www.contributor-covenant.org/faq). Translations are available
at [translations](https://www.contributor-covenant.org/translations).

View File

@ -1,50 +0,0 @@
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.
You do not need to ask for permission nor an assignment.
## Prerequisites
Before you start, please note that the ability to use following technologies is **required** and that existing contributors will not actively teach them to you.
- Basic [Android development](https://developer.android.com/)
- [Kotlin](https://kotlinlang.org/)
### Tools
- [Android Studio](https://developer.android.com/studio)
- Emulator or phone with developer options enabled to test changes.
## Getting help
- Join [the Discord server](https://discord.gg/tachiyomi) for online help and to ask questions while developing.
# 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/AppUpdateChecker.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
LICENSE Normal file → Executable file
View File

@ -174,3 +174,29 @@
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.

View File

@ -1,94 +1,3 @@
| Build | Stable | Weekly Preview | Contribute | Support Server |
|-------|----------|---------|------------|---------|
| ![CI](https://github.com/tachiyomiorg/tachiyomi/workflows/CI/badge.svg?branch=dev&event=push) | [![stable release](https://img.shields.io/github/release/tachiyomiorg/tachiyomi.svg?maxAge=3600&label=download)](https://github.com/tachiyomiorg/tachiyomi/releases) | [![latest preview build](https://img.shields.io/github/v/release/tachiyomiorg/tachiyomi-preview.svg?maxAge=3600&label=download)](https://github.com/tachiyomiorg/tachiyomi-preview/releases) | [![Translation status](https://hosted.weblate.org/widgets/tachiyomi/-/svg-badge.svg)](https://hosted.weblate.org/engage/tachiyomi/?utm_source=widget) | [![Discord](https://img.shields.io/discord/349436576037732353.svg?label=discord&labelColor=7289da&color=2c2f33&style=flat)](https://discord.gg/tachiyomi) |
I haven't started a readme
# ![app icon](./.github/readme-images/app-icon.png)Tachiyomi
Tachiyomi is a free and open source manga reader for Android 6.0 and above.
## Features
Features include:
* Online reading from a variety of sources
* Local reading of downloaded content
* A configurable reader with multiple viewers, reading directions and other settings.
* Tracker support: [MyAnimeList](https://myanimelist.net/), [AniList](https://anilist.co/), [Kitsu](https://kitsu.io/), [MangaUpdates](https://mangaupdates.com), [Shikimori](https://shikimori.one), and [Bangumi](https://bgm.tv/) support
* Categories to organize your library
* Light and dark themes
* Schedule updating your library for new chapters
* Create backups locally to read offline or to your desired cloud service
## Download
Get the app from our [releases page](https://github.com/tachiyomiorg/tachiyomi/releases).
If you want to try new features before they get to the stable release, you can download the preview version [here](https://github.com/tachiyomiorg/tachiyomi-preview/releases).
## Issues, Feature Requests and Contributing
Please make sure to read the full guidelines. Your issue may be closed without warning if you do not.
<details><summary>Issues</summary>
1. **Before reporting a new issue, take a look at the [FAQ](https://tachiyomi.org/help/faq/), the [changelog](https://github.com/tachiyomiorg/tachiyomi/releases) and the already opened [issues](https://github.com/tachiyomiorg/tachiyomi/issues).**
2. If you are unsure, ask here: [![Discord](https://img.shields.io/discord/349436576037732353.svg)](https://discord.gg/tachiyomi)
</details>
<details><summary>Bugs</summary>
* 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)
* Don't group unrelated requests into one issue
DO: https://github.com/tachiyomiorg/tachiyomi/issues/24 https://github.com/tachiyomiorg/tachiyomi/issues/71
DON'T: https://github.com/tachiyomiorg/tachiyomi/issues/75
</details>
<details><summary>Feature Requests</summary>
* Write a detailed issue, explaining what it should do or how. Avoid writing just "like X app does"
* Include screenshot (if needed)
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](./CONTRIBUTING.md).
</details>
<details><summary>Code of Conduct</summary>
See [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md).
</details>
## FAQ
[See our website.](https://tachiyomi.org/)
You can also reach out to us on [Discord](https://discord.gg/tachiyomi).
## License
Copyright 2015 Javier Tomás
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.
## Disclaimer
The developer of this application does not have any affiliation with the content providers available.
Automated Preview Builds(with updater): https://github.com/jobobby04/TachiyomiSYPreview/releases

2
app/.gitignore vendored Normal file → Executable file
View File

@ -2,3 +2,5 @@
*iml
*.iml
custom.gradle
google-services.json
output.json

374
app/build.gradle Executable file
View File

@ -0,0 +1,374 @@
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
//noinspection GradleDependency
import java.text.SimpleDateFormat
apply plugin: 'com.android.application'
apply plugin: 'com.google.android.gms.oss-licenses-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 29
buildToolsVersion '29.0.3'
publishNonDefault true
defaultConfig {
applicationId "eu.kanade.tachiyomi.sy"
minSdkVersion 21
targetSdkVersion 29
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
versionCode 1
versionName "0.9.2.7"
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"
}
}
viewBinding {
enabled = 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"
}
dev {
resConfigs "en", "xxhdpi"
dimension "default"
}
}
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
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'
}
lintOptions {
abortOnError false
checkReleaseBuilds false
}
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
androidExtensions {
experimental = true
}
dependencies {
// Modified dependencies
implementation 'com.github.inorichi:subsampling-scale-image-view:ac0dae7'
implementation 'com.github.inorichi:junrar-android:634c1f5'
// Android support library
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.browser:browser:1.2.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.biometric:biometric:1.0.1'
final lifecycle_version = '2.2.0'
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
// UI library
implementation 'com.google.android.material:material:1.1.0'
standardImplementation 'com.google.firebase:firebase-core:17.4.1'
// 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.7.2'
implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
implementation "com.squareup.okhttp3:logging-interceptor:$okhttp_version"
implementation 'com.squareup.okio:okio:2.6.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.2.0' // Stuck on 1.2.0 to fix MangaPlus extension
// Disk
implementation 'com.jakewharton:disklrucache:2.0.2'
implementation 'com.github.inorichi:unifile:e9ee588'
// HTML parser
implementation 'org.jsoup:jsoup:1.13.1'
// Job scheduling
final work_version = '2.3.4'
implementation "androidx.work:work-runtime:$work_version"
implementation "androidx.work:work-runtime-ktx:$work_version"
// [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.31.0'
// Preferences
implementation 'com.f2prateek.rx.preferences:rx-preferences:1.0.2'
implementation 'com.github.tfcporciuncula:flow-preferences:1.1.1'
// 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.10.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"
// Logging
implementation 'com.jakewharton.timber:timber:4.7.1'
// Crash reports
final acra_version = '5.5.0'
implementation "ch.acra:acra-http:$acra_version"
// 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.inorichi:conductor-support-preference:a32c357'
// FlowBinding
final flowbinding_version = '0.11.1'
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"
// 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.7'
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"
implementation 'com.google.android.gms:play-services-oss-licenses:17.0.0'
// Text distance (EH)
implementation 'info.debatty:java-string-similarity:1.2.1'
// Pin lock view (EH)
implementation 'com.github.jawnnypoo:pinlockview:2.2.0'
// 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'
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("Standard")) {
apply plugin: 'com.google.gms.google-services'
// Firebase (EH)
apply plugin: 'io.fabric'
}

View File

@ -1,344 +0,0 @@
import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("com.android.application")
id("com.mikepenz.aboutlibraries.plugin")
kotlin("android")
kotlin("plugin.serialization")
id("com.github.zellius.shortcut-helper")
id("com.squareup.sqldelight")
}
if (gradle.startParameter.taskRequests.toString().contains("Standard")) {
apply<com.google.gms.googleservices.GoogleServicesPlugin>()
}
shortcutHelper.setFilePath("./shortcuts.xml")
val SUPPORTED_ABIS = setOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
android {
namespace = "eu.kanade.tachiyomi"
compileSdk = AndroidConfig.compileSdk
ndkVersion = AndroidConfig.ndk
defaultConfig {
applicationId = "eu.kanade.tachiyomi"
minSdk = AndroidConfig.minSdk
targetSdk = AndroidConfig.targetSdk
versionCode = 89
versionName = "0.14.0"
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"")
buildConfigField("String", "BUILD_TIME", "\"${getBuildTime()}\"")
buildConfigField("boolean", "INCLUDE_UPDATER", "false")
buildConfigField("boolean", "PREVIEW", "false")
// Please disable ACRA or use your own instance in forked versions of the project
buildConfigField("String", "ACRA_URI", "\"https://tachiyomi.kanade.eu/crash_report\"")
ndk {
abiFilters += SUPPORTED_ABIS
}
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
splits {
abi {
isEnable = true
reset()
include(*SUPPORTED_ABIS.toTypedArray())
isUniversalApk = true
}
}
buildTypes {
named("debug") {
versionNameSuffix = "-${getCommitCount()}"
applicationIdSuffix = ".debug"
}
named("release") {
isShrinkResources = true
isMinifyEnabled = true
proguardFiles("proguard-android-optimize.txt", "proguard-rules.pro")
}
create("preview") {
initWith(getByName("release"))
buildConfigField("boolean", "PREVIEW", "true")
val debugType = getByName("debug")
signingConfig = debugType.signingConfig
versionNameSuffix = debugType.versionNameSuffix
applicationIdSuffix = debugType.applicationIdSuffix
matchingFallbacks.add("release")
}
create("benchmark") {
initWith(getByName("release"))
signingConfig = signingConfigs.getByName("debug")
matchingFallbacks.add("release")
isDebuggable = false
versionNameSuffix = "-benchmark"
applicationIdSuffix = ".benchmark"
}
}
sourceSets {
getByName("preview").res.srcDirs("src/debug/res")
getByName("benchmark").res.srcDirs("src/debug/res")
}
flavorDimensions.add("default")
productFlavors {
create("standard") {
buildConfigField("boolean", "INCLUDE_UPDATER", "true")
dimension = "default"
}
create("dev") {
resourceConfigurations.addAll(listOf("en", "xxhdpi"))
dimension = "default"
}
}
packagingOptions {
resources.excludes.addAll(listOf(
"META-INF/DEPENDENCIES",
"LICENSE.txt",
"META-INF/LICENSE",
"META-INF/LICENSE.txt",
"META-INF/README.md",
"META-INF/NOTICE",
"META-INF/*.kotlin_module",
"META-INF/*.version",
))
}
dependenciesInfo {
includeInApk = false
}
buildFeatures {
viewBinding = true
compose = true
// Disable some unused things
aidl = false
renderScript = false
shaders = false
}
lint {
abortOnError = false
checkReleaseBuilds = false
}
composeOptions {
kotlinCompilerExtensionVersion = compose.versions.compiler.get()
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
sqldelight {
database("Database") {
packageName = "eu.kanade.tachiyomi"
dialect = "sqlite:3.24"
}
}
}
dependencies {
implementation(project(":i18n"))
implementation(project(":core"))
implementation(project(":source-api"))
// Compose
implementation(platform(compose.bom))
implementation(compose.activity)
implementation(compose.foundation)
implementation(compose.material3.core)
implementation(compose.material3.adapter)
implementation(compose.material.icons)
implementation(compose.animation)
implementation(compose.animation.graphics)
implementation(compose.ui.tooling)
implementation(compose.ui.util)
implementation(compose.accompanist.webview)
implementation(compose.accompanist.swiperefresh)
implementation(compose.accompanist.flowlayout)
implementation(compose.accompanist.pager.core)
implementation(compose.accompanist.pager.indicators)
implementation(compose.accompanist.permissions)
implementation(androidx.paging.runtime)
implementation(androidx.paging.compose)
implementation(libs.bundles.sqlite)
implementation(androidx.sqlite)
implementation(libs.sqldelight.android.driver)
implementation(libs.sqldelight.coroutines)
implementation(libs.sqldelight.android.paging)
implementation(kotlinx.reflect)
implementation(kotlinx.bundles.coroutines)
// AndroidX libraries
implementation(androidx.annotation)
implementation(androidx.appcompat)
implementation(androidx.biometricktx)
implementation(androidx.constraintlayout)
implementation(androidx.coordinatorlayout)
implementation(androidx.corektx)
implementation(androidx.splashscreen)
implementation(androidx.recyclerview)
implementation(androidx.viewpager)
implementation(androidx.glance)
implementation(androidx.profileinstaller)
implementation(androidx.bundles.lifecycle)
// Job scheduling
implementation(androidx.bundles.workmanager)
// RX
implementation(libs.bundles.reactivex)
implementation(libs.flowreactivenetwork)
// Network client
implementation(libs.bundles.okhttp)
implementation(libs.okio)
// TLS 1.3 support for Android < 10
implementation(libs.conscrypt.android)
// Data serialization (JSON, protobuf)
implementation(kotlinx.bundles.serialization)
// HTML parser
implementation(libs.jsoup)
// Disk
implementation(libs.disklrucache)
implementation(libs.unifile)
implementation(libs.junrar)
// Preferences
implementation(libs.preferencektx)
// Model View Presenter
implementation(libs.bundles.nucleus)
// Dependency injection
implementation(libs.injekt.core)
// Image loading
implementation(libs.bundles.coil)
implementation(libs.subsamplingscaleimageview) {
exclude(module = "image-decoder")
}
implementation(libs.image.decoder)
// Sort
implementation(libs.natural.comparator)
// UI libraries
implementation(libs.material)
implementation(libs.flexible.adapter.core)
implementation(libs.flexible.adapter.ui)
implementation(libs.photoview)
implementation(libs.directionalviewpager) {
exclude(group = "androidx.viewpager", module = "viewpager")
}
implementation(libs.insetter)
implementation(libs.markwon)
implementation(libs.aboutLibraries.compose)
implementation(libs.cascade)
implementation(libs.numberpicker)
implementation(libs.bundles.voyager)
// Conductor
implementation(libs.bundles.conductor)
// FlowBinding
implementation(libs.bundles.flowbinding)
// Logging
implementation(libs.logcat)
// Crash reports/analytics
implementation(libs.acra.http)
"standardImplementation"(libs.firebase.analytics)
// Shizuku
implementation(libs.bundles.shizuku)
// Tests
testImplementation(libs.junit)
// For detecting memory leaks; see https://square.github.io/leakcanary/
// debugImplementation(libs.leakcanary.android)
implementation(libs.leakcanary.plumber)
}
androidComponents {
beforeVariants { variantBuilder ->
// Disables standardBenchmark
if (variantBuilder.buildType == "benchmark") {
variantBuilder.enable = variantBuilder.productFlavors.containsAll(listOf("default" to "dev"))
}
}
}
tasks {
withType<Test> {
useJUnitPlatform()
testLogging {
events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
}
}
withType<org.jmailen.gradle.kotlinter.tasks.LintTask>().configureEach {
exclude { it.file.path.contains("generated[\\\\/]".toRegex()) }
}
// See https://kotlinlang.org/docs/reference/experimental.html#experimental-status-of-experimental-api(-markers)
withType<KotlinCompile> {
kotlinOptions.freeCompilerArgs += listOf(
"-opt-in=coil.annotation.ExperimentalCoilApi",
"-opt-in=com.google.accompanist.pager.ExperimentalPagerApi",
"-opt-in=com.google.accompanist.permissions.ExperimentalPermissionsApi",
"-opt-in=androidx.compose.material.ExperimentalMaterialApi",
"-opt-in=androidx.compose.material3.ExperimentalMaterial3Api",
"-opt-in=androidx.compose.ui.ExperimentalComposeUiApi",
"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
"-opt-in=androidx.compose.animation.ExperimentalAnimationApi",
"-opt-in=androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi",
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=kotlinx.coroutines.FlowPreview",
"-opt-in=kotlinx.coroutines.InternalCoroutinesApi",
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi",
)
}
preBuild {
val ktlintTask = if (System.getenv("GITHUB_BASE_REF") == null) formatKotlin else lintKotlin
dependsOn(ktlintTask)
}
}
buildscript {
dependencies {
classpath(kotlinx.gradle)
}
}

View File

@ -1,33 +0,0 @@
-dontusemixedcaseclassnames
-verbose
-keepattributes *Annotation*
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements android.os.Parcelable {
public static final ** CREATOR;
}
-keep class androidx.annotation.Keep
-keep @androidx.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
@androidx.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
@androidx.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
@androidx.annotation.Keep <init>(...);
}

247
app/proguard-rules.pro vendored
View File

@ -1,26 +1,37 @@
-dontobfuscate
# Keep common dependencies used in extensions
-keep,allowoptimization class androidx.preference.** { public protected *; }
-keep,allowoptimization class kotlin.** { public protected *; }
-keep,allowoptimization class kotlinx.coroutines.** { public protected *; }
-keep,allowoptimization class kotlinx.serialization.** { public protected *; }
-keep,allowoptimization class okhttp3.** { public protected *; }
-keep,allowoptimization class okio.** { public protected *; }
-keep,allowoptimization class rx.** { public protected *; }
-keep,allowoptimization class org.jsoup.** { public protected *; }
-keep,allowoptimization class app.cash.quickjs.** { public protected *; }
-keep,allowoptimization class uy.kohesive.injekt.** { public protected *; }
# Extensions may require methods unused in the core app
-dontwarn eu.kanade.tachiyomi.**
-keep class eu.kanade.tachiyomi.** { public protected private *; }
# From extensions-lib
-keep,allowoptimization class eu.kanade.tachiyomi.network.interceptor.RateLimitInterceptorKt { public protected *; }
-keep,allowoptimization class eu.kanade.tachiyomi.network.interceptor.SpecificHostRateLimitInterceptorKt { public protected *; }
-keep,allowoptimization class eu.kanade.tachiyomi.network.NetworkHelper { public protected *; }
-keep,allowoptimization class eu.kanade.tachiyomi.network.OkHttpExtensionsKt { public protected *; }
-keep,allowoptimization class eu.kanade.tachiyomi.network.RequestsKt { public protected *; }
-keep,allowoptimization class eu.kanade.tachiyomi.AppInfo { public protected *; }
-keep class org.jsoup.** { *; }
-keep class kotlin.** { *; }
-keep class okhttp3.** { *; }
-keep class com.google.gson.** { *; }
-keep class com.github.salomonbrys.kotson.** { *; }
-keep class com.squareup.duktape.** { *; }
##---------------Begin: proguard configuration for RxJava 1.x ----------
# === Keep EH classes
-keep class exh.** { *; }
-keep class xyz.nulldev.** { *; }
# === Keep RxAndroid, https://github.com/ReactiveX/RxAndroid/issues/350
-keep class rx.android.** { *; }
# Design library
-dontwarn com.google.android.material.**
-keep class com.google.android.material.** { *; }
-keep interface com.google.android.material.** { *; }
-keep public class com.google.android.material.R$* { *; }
-keep class com.hippo.image.** { *; }
-keep interface com.hippo.image.** { *; }
-keepclassmembers class * extends nucleus.presenter.Presenter {
<init>();
}
# RxJava 1.1.0
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
@ -37,33 +48,185 @@
}
-dontnote rx.internal.util.PlatformDependent
##---------------End: proguard configuration for RxJava 1.x ----------
##---------------Begin: proguard configuration for kotlinx.serialization ----------
-keepattributes *Annotation*, InnerClasses
-dontnote kotlinx.serialization.AnnotationsKt # core serialization annotations
# === Reactive network: https://github.com/pwittchen/ReactiveNetwork/tree/v0.12.4#proguard-configuration
-dontwarn com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
-dontwarn io.reactivex.functions.Function
-dontwarn rx.internal.util.**
-dontwarn sun.misc.Unsafe
# 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(...);
# === Okhttp: https://github.com/square/okhttp/blob/3637fc56f70f87da696847defd311dbfb28e87b5/okhttp/src/main/resources/META-INF/proguard/okhttp3.pro
# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**
# A resource is loaded with a relative path so the package of this class must be preserved.
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*
# OkHttp platform used only on JVM and when Conscrypt dependency is available.
-dontwarn okhttp3.internal.platform.ConscryptPlatform
# === Okio: https://github.com/square/okio/tree/9b8545e7fa267c9d89753283990f24a35cd69cd6#proguard
-dontwarn okio.**
# === GSON: https://raw.githubusercontent.com/google/gson/master/examples/android-proguard-example/proguard.cfg
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { <fields>; }
# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}
-keep,includedescriptorclasses class eu.kanade.**$$serializer { *; }
-keepclassmembers class eu.kanade.** {
*** Companion;
}
-keepclasseswithmembers class eu.kanade.** {
kotlinx.serialization.KSerializer serializer(...);
# == Nucleus
-keepclassmembers class * extends nucleus.presenter.Presenter {
<init>();
}
-keep class kotlinx.serialization.**
-keepclassmembers class kotlinx.serialization.** {
<methods>;
}
##---------------End: proguard configuration for kotlinx.serialization ----------
# TODO Changeloglib? Does it need proguard?
# XmlUtil
-keep public enum nl.adaptivity.xmlutil.EventType { *; }
# === Injekt
## From original config: "Attempt to fix: java.lang.NoClassDefFoundError: uy.kohesive.injekt.registry.default.DefaultRegistrar$NOKEY$1"
-keep class uy.kohesive.injekt.** { *; }
# === Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
-dontwarn com.bumptech.glide.load.resource.bitmap.VideoDecoder
# === Glide-transformations: https://github.com/wasabeef/glide-transformations/blob/3aa8e53c6a51b8351d312f802ba1354c5b115168/transformations/proguard-rules.txt
-dontwarn jp.co.cyberagent.android.gpuimage.**
# === Conductor
# This isn't in the consumer proguard rules yet: https://github.com/bluelinelabs/Conductor/pull/550/files
-keepclassmembers public class * extends com.bluelinelabs.conductor.ControllerChangeHandler {
public <init>();
}
# === RxBinding
-dontwarn com.google.auto.value.AutoValue
# === Crashlytics
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable
-keep class com.crashlytics.** { *; }
-dontwarn com.crashlytics.**
# === Humanize + Guava: https://github.com/google/guava/wiki/UsingProGuardWithGuava
-dontwarn javax.lang.model.element.Modifier
-keep class org.ocpsoft.prettytime.i18n.**
# Note: We intentionally don't add the flags we'd need to make Enums work.
# That's because the Proguard configuration required to make it work on
# optimized code would preclude lots of optimization, like converting enums
# into ints.
# Throwables uses internal APIs for lazy stack trace resolution
-dontnote sun.misc.SharedSecrets
-keep class sun.misc.SharedSecrets {
*** getJavaLangAccess(...);
}
-dontnote sun.misc.JavaLangAccess
-keep class sun.misc.JavaLangAccess {
*** getStackTraceElement(...);
*** getStackTraceDepth(...);
}
# FinalizableReferenceQueue calls this reflectively
# Proguard is intelligent enough to spot the use of reflection onto this, so we
# only need to keep the names, and allow it to be stripped out if
# FinalizableReferenceQueue is unused.
-keepnames class com.google.common.base.internal.Finalizer {
*** startFinalizer(...);
}
# However, it cannot "spot" that this method needs to be kept IF the class is.
-keepclassmembers class com.google.common.base.internal.Finalizer {
*** startFinalizer(...);
}
-keepnames class com.google.common.base.FinalizableReference {
void finalizeReferent();
}
-keepclassmembers class com.google.common.base.FinalizableReference {
void finalizeReferent();
}
# Striped64, LittleEndianByteArray, UnsignedBytes, AbstractFuture
-dontwarn sun.misc.Unsafe
# Striped64 appears to make some assumptions about object layout that
# really might not be safe. This should be investigated.
-keepclassmembers class com.google.common.cache.Striped64 {
*** base;
*** busy;
}
-keepclassmembers class com.google.common.cache.Striped64$Cell {
<fields>;
}
-dontwarn java.lang.SafeVarargs
-keep class java.lang.Throwable {
*** addSuppressed(...);
}
# Futures.getChecked, in both of its variants, is incompatible with proguard.
# Used by AtomicReferenceFieldUpdater and sun.misc.Unsafe
-keepclassmembers class com.google.common.util.concurrent.AbstractFuture** {
*** waiters;
*** value;
*** listeners;
*** thread;
*** next;
}
-keepclassmembers class com.google.common.util.concurrent.AtomicDouble {
*** value;
}
-keepclassmembers class com.google.common.util.concurrent.AggregateFutureState {
*** remaining;
*** seenExceptions;
}
# Since Unsafe is using the field offsets of these inner classes, we don't want
# to have class merging or similar tricks applied to these classes and their
# fields. It's safe to allow obfuscation, since the by-name references are
# already preserved in the -keep statement above.
-keep,allowshrinking,allowobfuscation class com.google.common.util.concurrent.AbstractFuture** {
<fields>;
}
# Futures.getChecked (which often won't work with Proguard anyway) uses this. It
# has a fallback, but again, don't use Futures.getChecked on Android regardless.
-dontwarn java.lang.ClassValue
# MoreExecutors references AppEngine
-dontnote com.google.appengine.api.ThreadManager
-keep class com.google.appengine.api.ThreadManager {
static *** currentRequestThreadFactory(...);
}
-dontnote com.google.apphosting.api.ApiProxy
-keep class com.google.apphosting.api.ApiProxy {
static *** getCurrentEnvironment (...);
}

View File

@ -17,7 +17,7 @@
android:shortcutDisabledMessage="@string/app_not_available"
android:shortcutId="show_recently_updated"
android:shortcutLongLabel="@string/label_recent_updates"
android:shortcutShortLabel="@string/label_recent_updates">
android:shortcutShortLabel="@string/short_recent_updates">
<intent
android:action="eu.kanade.tachiyomi.SHOW_RECENTLY_UPDATED"
android:targetClass="eu.kanade.tachiyomi.ui.main.MainActivity" />

View File

@ -1,27 +1,97 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108.0"
android:viewportHeight="108.0">
android:width="108dp"
android:height="108dp"
android:viewportWidth="108.0"
android:viewportHeight="108.0">
<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"/>
<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"/>
<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"/>
<path
android:pathData="M54,54.5m-25.5,0a25.5,25.5 0,1 1,51 0a25.5,25.5 0,1 1,-51 0"
android:fillColor="#000"/>
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="#000"
android:fillType="evenOdd"/>
<path
android:pathData="M54,54.5m-25.5,0a25.5,25.5 0,1 1,51 0a25.5,25.5 0,1 1,-51 0"
android:fillColor="#CE2828"/>
android:name="path_4"
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"/>
<path
android:pathData="M54,54.5m-19.94,0a19.94,19.94 0,1 1,39.87 0a19.94,19.94 0,1 1,-39.87 0"
android:fillColor="#FFF"/>
android:name="path_5"
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="#FFF"
android:fillType="evenOdd"/>
<path
android:pathData="M52.04,46.3L47.42,46.3C46.14,46.3 44.93,46.23 44.2,46.14L44.2,49.76C45,49.65 46.16,49.6 47.42,49.6L60.58,49.6C61.86,49.6 63.02,49.65 63.82,49.76L63.82,46.14C63.09,46.23 61.86,46.3 60.58,46.3L55.69,46.3L55.69,45.07C55.69,44.43 55.73,43.95 55.82,43.45L51.9,43.45C51.99,44 52.04,44.43 52.04,45.07L52.04,46.3ZM46.78,60.68C45.46,60.68 44.29,60.63 43.45,60.52L43.45,64.14C44.34,64.03 45.46,63.98 46.78,63.98L61.29,63.98C62.57,63.98 63.71,64.03 64.57,64.14L64.57,60.52C63.73,60.63 62.57,60.68 61.29,60.68L58.24,60.68C59.33,58.06 59.99,56.23 60.7,53.91C61.34,51.81 61.34,51.81 61.56,51.13L57.58,50.06C57.51,50.93 57.37,51.52 56.89,53.41C56.19,56.14 55.32,58.74 54.5,60.68L46.78,60.68ZM46.48,51.36C47.55,54.02 48.28,56.53 49.03,60.15L52.66,58.9C51.65,54.98 50.92,52.66 49.94,50.11L46.48,51.36Z"
android:fillColor="#000"/>
android:name="path_6"
android:pathData="M 54.174 36.266 C 64.147 36.266 72.234 44.397 72.234 54.426 C 72.234 64.459 64.147 72.593 54.174 72.593 C 44.197 72.593 36.113 64.459 36.113 54.426 C 36.113 44.397 44.197 36.266 54.174 36.266 Z"
android:fillColor="#ffcc4d"
android:strokeColor="#ffcc4d"
android:strokeWidth="4.628571428571428"
android:strokeLineCap="round"
android:strokeLineJoin="round"/>
<path
android:name="path_7"
android:pathData="M 48.774 45.158 C 49.988 45.158 50.973 46.452 50.973 48.05 C 50.973 49.65 49.988 50.946 48.774 50.946 C 47.559 50.946 46.576 49.65 46.576 48.05 C 46.576 46.452 47.559 45.158 48.774 45.158 Z"
android:fillColor="#674600"
android:strokeColor="#674600"
android:strokeWidth="0.1"
android:strokeLineJoin="round"/>
<path
android:name="path_8"
android:pathData="M 62.02 45.158 C 63.235 45.158 64.219 46.452 64.219 48.05 C 64.219 49.65 63.235 50.946 62.02 50.946 C 60.805 50.946 59.821 49.65 59.821 48.05 C 59.821 46.452 60.805 45.158 62.02 45.158 Z"
android:fillColor="#674600"
android:strokeColor="#674600"
android:strokeWidth="0.1"
android:strokeLineJoin="round"/>
<path
android:name="path_9"
android:pathData="M 44.687 42.102 C 44.687 42.102 48.404 40.049 53.119 42.102"
android:strokeColor="#674600"
android:strokeWidth="2"
android:strokeLineCap="round"
android:strokeLineJoin="round"
android:fillType="evenOdd"/>
<path
android:name="path_10"
android:pathData="M 58.035 42.102 C 58.035 42.102 61.751 40.049 66.465 42.102"
android:strokeColor="#674600"
android:strokeWidth="2"
android:strokeLineCap="round"
android:strokeLineJoin="round"
android:fillType="evenOdd"/>
<path
android:name="path_11"
android:pathData="M 49.191 56.685 C 49.191 56.685 51.703 59.685 56.992 59.685"
android:strokeColor="#674600"
android:strokeWidth="2"
android:strokeLineCap="round"
android:strokeLineJoin="round"
android:fillType="evenOdd"/>
<path
android:name="path_12"
android:pathData="M 34.072 67.511 C 34.072 67.511 34.524 66.248 37.476 63.634 C 37.476 63.634 39.143 61.991 37.876 58.114 C 37.876 58.114 37.534 56.06 39.681 57.255 C 39.681 57.255 44.129 60.46 40.871 65 C 40.871 65 40.241 66.117 41.652 65.78 L 53.939 63.103 C 53.939 63.103 55.275 62.752 55.535 64.163 C 55.535 64.163 55.696 65.372 54.641 65.672 L 47.742 67.378 C 47.742 67.378 50.72 69.597 47.742 70.825 C 47.742 70.825 50.294 72.779 47.336 74.268 C 47.336 74.268 49.276 76.015 46.407 77.019 C 46.407 77.019 42.525 78.474 39.209 77.831 C 35.509 77.103 31.947 72.114 34.072 67.511 Z"
android:fillColor="#f4900c"
android:strokeColor="#f4900c"
android:strokeLineCap="round"
android:strokeLineJoin="round"
android:strokeWidth="0.1"
android:fillType="evenOdd"/>
<path
android:name="path_13"
android:pathData="M 56.182 67.511 C 56.182 67.511 56.633 66.248 59.585 63.634 C 59.585 63.634 61.253 61.991 59.985 58.114 C 59.985 58.114 59.642 56.06 61.789 57.255 C 61.789 57.255 66.239 60.46 62.98 65 C 62.98 65 62.351 66.117 63.761 65.78 L 76.066 63.103 C 76.066 63.103 77.386 62.752 77.641 64.163 C 77.641 64.163 77.812 65.372 76.746 65.672 L 69.85 67.378 C 69.85 67.378 72.829 69.597 69.85 70.825 C 69.85 70.825 72.404 72.779 69.446 74.268 C 69.446 74.268 71.387 76.015 68.516 77.019 C 68.516 77.019 64.633 78.474 61.317 77.831 C 57.618 77.103 54.057 72.114 56.182 67.511 Z"
android:fillColor="#f4900c"
android:strokeColor="#f4900c"
android:strokeLineCap="round"
android:strokeLineJoin="round"
android:strokeWidth="0.1"
android:fillType="evenOdd"/>
</vector>

View File

@ -0,0 +1,6 @@
<vector android:height="100dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="100dp" xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="?attr/colorControlNormal">
<path android:fillColor="@android:color/white" android:pathData="M7,10l5,5 -5,5z"/>
</vector>

View File

@ -2,5 +2,4 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@android:color/transparent"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_tachi_monochrome_launcher" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 18 KiB

345
app/src/main/AndroidManifest.xml Normal file → Executable file
View File

@ -1,57 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools"
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.UPDATE_PACKAGES_WITHOUT_USER_ACTION" />
<!-- To view extension packages in API 30+ -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- Remove permission from Firebase dependency -->
<uses-permission android:name="com.google.android.gms.permission.AD_ID"
tools:node="remove" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
<!-- Lock vibrate -->
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name=".App"
android:allowBackup="false"
android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules"
android:hardwareAccelerated="true"
android:hasFragileUserData="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:localeConfig="@xml/locales_config"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/Theme.Tachiyomi"
android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config">
<!-- enable profiling by macrobenchmark -->
<profileable
android:shell="true"
tools:targetApi="q" />
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/Theme.Tachiyomi.Light"
android:usesCleartextTraffic="true">
<activity
android:name=".ui.main.MainActivity"
android:launchMode="singleTop"
android:theme="@style/Theme.Tachiyomi.SplashScreen"
android:exported="true">
android:theme="@style/Theme.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@ -61,18 +49,15 @@
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>
<activity
android:process=":error_handler"
android:name=".crash.CrashActivity"
android:exported="false" />
android:name=".ui.main.ForceCloseActivity"
android:clearTaskOnLaunch="true"
android:noHistory="true"
android:theme="@android:style/Theme.NoDisplay" />
<activity
android:name=".ui.main.DeepLinkActivity"
android:launchMode="singleTask"
android:theme="@android:style/Theme.NoDisplay"
android:label="@string/action_global_search"
android:exported="true">
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<action android:name="com.google.android.gms.actions.SEARCH_ACTION" />
@ -83,48 +68,27 @@
<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"
android:resource="@xml/searchable" />
</activity>
<activity
android:name=".ui.reader.ReaderActivity"
android:launchMode="singleTask"
android:exported="false">
<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>
android:launchMode="singleTask" />
<activity
android:name=".ui.security.UnlockActivity"
android:theme="@style/Theme.Tachiyomi"
android:exported="false" />
android:name=".ui.security.BiometricUnlockActivity"
android:theme="@style/Theme.Splash" />
<activity
android:name=".ui.webview.WebViewActivity"
android:configChanges="uiMode|orientation|screenSize"
android:exported="false" />
android:configChanges="uiMode|orientation|screenSize" />
<activity
android:name=".extension.util.ExtensionInstallActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:exported="false" />
android:name=".widget.CustomLayoutPickerActivity"
android:label="@string/app_name"
android:theme="@style/FilePickerTheme" />
<activity
android:name=".ui.setting.track.AnilistLoginActivity"
android:label="Anilist"
android:exported="true">
android:label="Anilist">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@ -136,25 +100,9 @@
android:scheme="tachiyomi" />
</intent-filter>
</activity>
<activity
android:name=".ui.setting.track.MyAnimeListLoginActivity"
android:label="MyAnimeList"
android:exported="true">
<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"
android:exported="true">
android:label="Shikimori">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@ -168,8 +116,7 @@
</activity>
<activity
android:name=".ui.setting.track.BangumiLoginActivity"
android:label="Bangumi"
android:exported="true">
android:label="Bangumi">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@ -182,51 +129,16 @@
</intent-filter>
</activity>
<receiver
android:name=".data.notification.NotificationReceiver"
android:exported="false" />
<activity
android:name=".extension.util.ExtensionInstallActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<receiver
android:name=".glance.UpdatesGridGlanceReceiver"
android:enabled="@bool/glance_appwidget_available"
android:exported="false"
android:label="@string/label_recent_updates">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/updates_grid_glance_widget_info" />
</receiver>
<service
android:name=".data.library.LibraryUpdateService"
android:exported="false" />
<service
android:name=".data.download.DownloadService"
android:exported="false" />
<service
android:name=".data.updater.AppUpdateService"
android:exported="false" />
<service
android:name=".data.backup.BackupRestoreService"
android:exported="false" />
<service android:name=".extension.util.ExtensionInstallService"
android:exported="false" />
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
<activity
android:name="com.google.android.gms.oss.licenses.OssLicensesMenuActivity"
android:theme="@style/Theme.MaterialComponents" />
<activity
android:name="com.google.android.gms.oss.licenses.OssLicensesActivity"
android:theme="@style/Theme.MaterialComponents" />
<provider
android:name="androidx.core.content.FileProvider"
@ -238,26 +150,163 @@
android:resource="@xml/provider_paths" />
</provider>
<provider
android:name="rikka.shizuku.ShizukuProvider"
android:authorities="${applicationId}.shizuku"
android:multiprocess="false"
android:enabled="true"
android:exported="true"
android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" />
<receiver
android:name=".data.notification.NotificationReceiver"
android:exported="false" />
<meta-data
android:name="android.webkit.WebView.EnableSafeBrowsing"
android:value="false" />
<meta-data
android:name="android.webkit.WebView.MetricsOptOut"
android:value="true" />
<service
android:name=".data.library.LibraryUpdateService"
android:exported="false" />
<!-- Disable advertising ID collection for Firebase -->
<meta-data
android:name="google_analytics_adid_collection_enabled"
android:value="false" />
<service
android:name=".data.download.DownloadService"
android:exported="false" />
<service
android:name=".data.updater.UpdaterService"
android:exported="false" />
<service
android:name=".data.backup.BackupCreateService"
android:exported="false" />
<service
android:name=".data.backup.BackupRestoreService"
android:exported="false" />
<!-- EH -->
<service
android:name="exh.eh.EHentaiUpdateWorker"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true" />
<activity
android:name="exh.ui.intercept.InterceptActivity"
android:label="TachiyomiEH"
android:theme="@style/Theme.EHActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- EH -->
<data
android:host="g.e-hentai.org"
android:pathPrefix="/g/"
android:scheme="http" />
<data
android:host="g.e-hentai.org"
android:pathPrefix="/g/"
android:scheme="https" />
<data
android:host="e-hentai.org"
android:pathPrefix="/g/"
android:scheme="http" />
<data
android:host="e-hentai.org"
android:pathPrefix="/g/"
android:scheme="https" />
<!-- EXH -->
<data
android:host="exhentai.org"
android:pathPrefix="/g/"
android:scheme="http" />
<data
android:host="exhentai.org"
android:pathPrefix="/g/"
android:scheme="https" />
<!-- nhentai -->
<data
android:host="nhentai.net"
android:pathPrefix="/g/"
android:scheme="http" />
<data
android:host="nhentai.net"
android:pathPrefix="/g/"
android:scheme="https" />
<!-- Perv Eden -->
<data
android:host="www.perveden.com"
android:pathPattern="/.*/.*-manga/.*"
android:scheme="http" />
<data
android:host="www.perveden.com"
android:pathPattern="/.*/.*-manga/.*"
android:scheme="https" />
<!-- Hentai Cafe -->
<data
android:host="hentai.cafe"
android:pathPattern="/.*/.*"
android:scheme="http" />
<data
android:host="hentai.cafe"
android:pathPattern="/.*/.*"
android:scheme="https" />
<!-- Tsumino -->
<data
android:host="www.tsumino.com"
android:pathPrefix="/Book/Info/"
android:scheme="http" />
<data
android:host="www.tsumino.com"
android:pathPrefix="/Book/Info/"
android:scheme="https" />
<data
android:host="www.tsumino.com"
android:pathPrefix="/Read/View/"
android:scheme="http" />
<data
android:host="www.tsumino.com"
android:pathPrefix="/Read/View/"
android:scheme="https" />
<!-- Hitomi.la -->
<data
android:host="hitomi.la"
android:pathPrefix="/galleries/"
android:scheme="http" />
<data
android:host="hitomi.la"
android:pathPrefix="/reader/"
android:scheme="http" />
<data
android:host="hitomi.la"
android:pathPrefix="/galleries/"
android:scheme="https" />
<data
android:host="hitomi.la"
android:pathPrefix="/reader/"
android:scheme="https" />
<!-- Pururin.io -->
<data
android:host="pururin.io"
android:pathPrefix="/gallery/"
android:scheme="http" />
<data
android:host="pururin.io"
android:pathPrefix="/gallery/"
android:scheme="https" />
<!-- HBrowse -->
<data
android:host="www.hbrowse.com"
android:pathPrefix="/"
android:scheme="http" />
<data
android:host="www.hbrowse.com"
android:pathPrefix="/"
android:scheme="https" />
</intent-filter>
</activity>
<activity
android:name="exh.ui.captcha.BrowserActionActivity"
android:theme="@style/Theme.EHActivity" />
</application>
</manifest>

File diff suppressed because it is too large Load Diff

0
app/src/main/ic_launcher-web.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,55 +0,0 @@
package eu.kanade.core.prefs
import androidx.compose.ui.state.ToggleableState
sealed class CheckboxState<T>(open val value: T) {
abstract fun next(): CheckboxState<T>
sealed class State<T>(override val value: T) : CheckboxState<T>(value) {
data class Checked<T>(override val value: T) : State<T>(value)
data class None<T>(override val value: T) : State<T>(value)
val isChecked: Boolean
get() = this is Checked
override fun next(): CheckboxState<T> {
return when (this) {
is Checked -> None(value)
is None -> Checked(value)
}
}
}
sealed class TriState<T>(override val value: T) : CheckboxState<T>(value) {
data class Include<T>(override val value: T) : TriState<T>(value)
data class Exclude<T>(override val value: T) : TriState<T>(value)
data class None<T>(override val value: T) : TriState<T>(value)
override fun next(): CheckboxState<T> {
return when (this) {
is Exclude -> None(value)
is Include -> Exclude(value)
is None -> Include(value)
}
}
fun asState(): ToggleableState {
return when (this) {
is Exclude -> ToggleableState.Indeterminate
is Include -> ToggleableState.On
is None -> ToggleableState.Off
}
}
}
}
inline fun <T> T.asCheckboxState(condition: (T) -> Boolean): CheckboxState.State<T> {
return if (condition(this)) {
CheckboxState.State.Checked(this)
} else {
CheckboxState.State.None(this)
}
}
inline fun <T> List<T>.mapAsCheckboxState(condition: (T) -> Boolean): List<CheckboxState.State<T>> {
return this.map { it.asCheckboxState(condition) }
}

View File

@ -1,36 +0,0 @@
package eu.kanade.core.prefs
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import eu.kanade.tachiyomi.core.preference.Preference
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
class PreferenceMutableState<T>(
private val preference: Preference<T>,
scope: CoroutineScope,
) : MutableState<T> {
private val state = mutableStateOf(preference.get())
init {
preference.changes()
.onEach { state.value = it }
.launchIn(scope)
}
override var value: T
get() = state.value
set(value) {
preference.set(value)
}
override fun component1(): T {
return state.value
}
override fun component2(): (T) -> Unit {
return { preference.set(it) }
}
}

View File

@ -1,16 +0,0 @@
package eu.kanade.core.util
fun <T : R, R : Any> List<T>.insertSeparators(
generator: (T?, T?) -> R?,
): List<R> {
if (isEmpty()) return emptyList()
val newList = mutableListOf<R>()
for (i in -1..lastIndex) {
val before = getOrNull(i)
before?.let { newList.add(it) }
val after = getOrNull(i + 1)
val separator = generator.invoke(before, after)
separator?.let { newList.add(it) }
}
return newList
}

View File

@ -1,61 +0,0 @@
package eu.kanade.core.util
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.launch
import rx.Emitter
import rx.Observable
import rx.Observer
import kotlin.coroutines.CoroutineContext
fun <T : Any> Observable<T>.asFlow(): Flow<T> = callbackFlow {
val observer = object : Observer<T> {
override fun onNext(t: T) {
trySend(t)
}
override fun onError(e: Throwable) {
close(e)
}
override fun onCompleted() {
close()
}
}
val subscription = subscribe(observer)
awaitClose { subscription.unsubscribe() }
}
fun <T : Any> Flow<T>.asObservable(
context: CoroutineContext = Dispatchers.Unconfined,
backpressureMode: Emitter.BackpressureMode = Emitter.BackpressureMode.NONE,
): Observable<T> {
return Observable.create(
{ emitter ->
/*
* ATOMIC is used here to provide stable behaviour of subscribe+dispose pair even if
* asObservable is already invoked from unconfined
*/
val job = GlobalScope.launch(context = context, start = CoroutineStart.ATOMIC) {
try {
collect { emitter.onNext(it) }
emitter.onCompleted()
} catch (e: Throwable) {
// Ignore `CancellationException` as error, since it indicates "normal cancellation"
if (e !is CancellationException) {
emitter.onError(e)
} else {
emitter.onCompleted()
}
}
}
emitter.setCancellation { job.cancel() }
},
backpressureMode,
)
}

View File

@ -1,90 +0,0 @@
package eu.kanade.data
import androidx.paging.PagingSource
import com.squareup.sqldelight.Query
import com.squareup.sqldelight.db.SqlDriver
import com.squareup.sqldelight.runtime.coroutines.asFlow
import com.squareup.sqldelight.runtime.coroutines.mapToList
import com.squareup.sqldelight.runtime.coroutines.mapToOne
import com.squareup.sqldelight.runtime.coroutines.mapToOneOrNull
import eu.kanade.tachiyomi.Database
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.withContext
class AndroidDatabaseHandler(
val db: Database,
private val driver: SqlDriver,
val queryDispatcher: CoroutineDispatcher = Dispatchers.IO,
val transactionDispatcher: CoroutineDispatcher = queryDispatcher,
) : DatabaseHandler {
val suspendingTransactionId = ThreadLocal<Int>()
override suspend fun <T> await(inTransaction: Boolean, block: suspend Database.() -> T): T {
return dispatch(inTransaction, block)
}
override suspend fun <T : Any> awaitList(
inTransaction: Boolean,
block: suspend Database.() -> Query<T>,
): List<T> {
return dispatch(inTransaction) { block(db).executeAsList() }
}
override suspend fun <T : Any> awaitOne(
inTransaction: Boolean,
block: suspend Database.() -> Query<T>,
): T {
return dispatch(inTransaction) { block(db).executeAsOne() }
}
override suspend fun <T : Any> awaitOneOrNull(
inTransaction: Boolean,
block: suspend Database.() -> Query<T>,
): T? {
return dispatch(inTransaction) { block(db).executeAsOneOrNull() }
}
override fun <T : Any> subscribeToList(block: Database.() -> Query<T>): Flow<List<T>> {
return block(db).asFlow().mapToList(queryDispatcher)
}
override fun <T : Any> subscribeToOne(block: Database.() -> Query<T>): Flow<T> {
return block(db).asFlow().mapToOne(queryDispatcher)
}
override fun <T : Any> subscribeToOneOrNull(block: Database.() -> Query<T>): Flow<T?> {
return block(db).asFlow().mapToOneOrNull(queryDispatcher)
}
override fun <T : Any> subscribeToPagingSource(
countQuery: Database.() -> Query<Long>,
queryProvider: Database.(Long, Long) -> Query<T>,
): PagingSource<Long, T> {
return QueryPagingSource(
handler = this,
countQuery = countQuery,
queryProvider = { limit, offset ->
queryProvider.invoke(db, limit, offset)
},
)
}
private suspend fun <T> dispatch(inTransaction: Boolean, block: suspend Database.() -> T): T {
// Create a transaction if needed and run the calling block inside it.
if (inTransaction) {
return withTransaction { block(db) }
}
// If we're currently in the transaction thread, there's no need to dispatch our query.
if (driver.currentTransaction() != null) {
return block(db)
}
// Get the current database context and run the calling block.
val context = getCurrentDatabaseContext()
return withContext(context) { block(db) }
}
}

View File

@ -1,30 +0,0 @@
package eu.kanade.data
import com.squareup.sqldelight.ColumnAdapter
import eu.kanade.tachiyomi.source.model.UpdateStrategy
import java.util.Date
val dateAdapter = object : ColumnAdapter<Date, Long> {
override fun decode(databaseValue: Long): Date = Date(databaseValue)
override fun encode(value: Date): Long = value.time
}
private const val listOfStringsSeparator = ", "
val listOfStringsAdapter = object : ColumnAdapter<List<String>, String> {
override fun decode(databaseValue: String) =
if (databaseValue.isEmpty()) {
listOf()
} else {
databaseValue.split(listOfStringsSeparator)
}
override fun encode(value: List<String>) = value.joinToString(separator = listOfStringsSeparator)
}
val updateStrategyAdapter = object : ColumnAdapter<UpdateStrategy, Long> {
private val enumValues by lazy { UpdateStrategy.values() }
override fun decode(databaseValue: Long): UpdateStrategy =
enumValues.getOrElse(databaseValue.toInt()) { UpdateStrategy.ALWAYS_UPDATE }
override fun encode(value: UpdateStrategy): Long = value.ordinal.toLong()
}

View File

@ -1,37 +0,0 @@
package eu.kanade.data
import androidx.paging.PagingSource
import com.squareup.sqldelight.Query
import eu.kanade.tachiyomi.Database
import kotlinx.coroutines.flow.Flow
interface DatabaseHandler {
suspend fun <T> await(inTransaction: Boolean = false, block: suspend Database.() -> T): T
suspend fun <T : Any> awaitList(
inTransaction: Boolean = false,
block: suspend Database.() -> Query<T>,
): List<T>
suspend fun <T : Any> awaitOne(
inTransaction: Boolean = false,
block: suspend Database.() -> Query<T>,
): T
suspend fun <T : Any> awaitOneOrNull(
inTransaction: Boolean = false,
block: suspend Database.() -> Query<T>,
): T?
fun <T : Any> subscribeToList(block: Database.() -> Query<T>): Flow<List<T>>
fun <T : Any> subscribeToOne(block: Database.() -> Query<T>): Flow<T>
fun <T : Any> subscribeToOneOrNull(block: Database.() -> Query<T>): Flow<T?>
fun <T : Any> subscribeToPagingSource(
countQuery: Database.() -> Query<Long>,
queryProvider: Database.(Long, Long) -> Query<T>,
): PagingSource<Long, T>
}

View File

@ -1,72 +0,0 @@
package eu.kanade.data
import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.squareup.sqldelight.Query
import eu.kanade.tachiyomi.Database
import kotlin.properties.Delegates
class QueryPagingSource<RowType : Any>(
val handler: DatabaseHandler,
val countQuery: Database.() -> Query<Long>,
val queryProvider: Database.(Long, Long) -> Query<RowType>,
) : PagingSource<Long, RowType>(), Query.Listener {
override val jumpingSupported: Boolean = true
private var currentQuery: Query<RowType>? by Delegates.observable(null) { _, old, new ->
old?.removeListener(this)
new?.addListener(this)
}
init {
registerInvalidatedCallback {
currentQuery?.removeListener(this)
currentQuery = null
}
}
override suspend fun load(params: LoadParams<Long>): LoadResult<Long, RowType> {
try {
val key = params.key ?: 0L
val loadSize = params.loadSize
val count = handler.awaitOne { countQuery() }
val (offset, limit) = when (params) {
is LoadParams.Prepend -> key - loadSize to loadSize.toLong()
else -> key to loadSize.toLong()
}
val data = handler.awaitList {
queryProvider(limit, offset)
.also { currentQuery = it }
}
val (prevKey, nextKey) = when (params) {
is LoadParams.Append -> { offset - loadSize to offset + loadSize }
else -> { offset to offset + loadSize }
}
return LoadResult.Page(
data = data,
prevKey = if (offset <= 0L || prevKey < 0L) null else prevKey,
nextKey = if (offset + loadSize >= count) null else nextKey,
itemsBefore = maxOf(0L, offset).toInt(),
itemsAfter = maxOf(0L, count - (offset + loadSize)).toInt(),
)
} catch (e: Exception) {
return LoadResult.Error(throwable = e)
}
}
override fun getRefreshKey(state: PagingState<Long, RowType>): Long? {
return state.anchorPosition?.let { anchorPosition ->
val anchorPage = state.closestPageToPosition(anchorPosition)
anchorPage?.prevKey ?: anchorPage?.nextKey
}
}
override fun queryResultsChanged() {
invalidate()
}
}

View File

@ -1,161 +0,0 @@
package eu.kanade.data
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Job
import kotlinx.coroutines.asContextElement
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
import java.util.concurrent.RejectedExecutionException
import java.util.concurrent.atomic.AtomicInteger
import kotlin.coroutines.ContinuationInterceptor
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.coroutineContext
import kotlin.coroutines.resume
/**
* Returns the transaction dispatcher if we are on a transaction, or the database dispatchers.
*/
internal suspend fun AndroidDatabaseHandler.getCurrentDatabaseContext(): CoroutineContext {
return coroutineContext[TransactionElement]?.transactionDispatcher ?: queryDispatcher
}
/**
* Calls the specified suspending [block] in a database transaction. The transaction will be
* marked as successful unless an exception is thrown in the suspending [block] or the coroutine
* is cancelled.
*
* SQLDelight will only perform at most one transaction at a time, additional transactions are queued
* and executed on a first come, first serve order.
*
* Performing blocking database operations is not permitted in a coroutine scope other than the
* one received by the suspending block. It is recommended that all [Dao] function invoked within
* the [block] be suspending functions.
*
* The dispatcher used to execute the given [block] will utilize threads from SQLDelight's query executor.
*/
internal suspend fun <T> AndroidDatabaseHandler.withTransaction(block: suspend () -> T): T {
// Use inherited transaction context if available, this allows nested suspending transactions.
val transactionContext =
coroutineContext[TransactionElement]?.transactionDispatcher ?: createTransactionContext()
return withContext(transactionContext) {
val transactionElement = coroutineContext[TransactionElement]!!
transactionElement.acquire()
try {
db.transactionWithResult {
runBlocking(transactionContext) {
block()
}
}
} finally {
transactionElement.release()
}
}
}
/**
* Creates a [CoroutineContext] for performing database operations within a coroutine transaction.
*
* The context is a combination of a dispatcher, a [TransactionElement] and a thread local element.
*
* * The dispatcher will dispatch coroutines to a single thread that is taken over from the SQLDelight
* query executor. If the coroutine context is switched, suspending DAO functions will be able to
* dispatch to the transaction thread.
*
* * The [TransactionElement] serves as an indicator for inherited context, meaning, if there is a
* switch of context, suspending DAO methods will be able to use the indicator to dispatch the
* database operation to the transaction thread.
*
* * The thread local element serves as a second indicator and marks threads that are used to
* execute coroutines within the coroutine transaction, more specifically it allows us to identify
* if a blocking DAO method is invoked within the transaction coroutine. Never assign meaning to
* this value, for now all we care is if its present or not.
*/
private suspend fun AndroidDatabaseHandler.createTransactionContext(): CoroutineContext {
val controlJob = Job()
// make sure to tie the control job to this context to avoid blocking the transaction if
// context get cancelled before we can even start using this job. Otherwise, the acquired
// transaction thread will forever wait for the controlJob to be cancelled.
// see b/148181325
coroutineContext[Job]?.invokeOnCompletion {
controlJob.cancel()
}
val dispatcher = transactionDispatcher.acquireTransactionThread(controlJob)
val transactionElement = TransactionElement(controlJob, dispatcher)
val threadLocalElement =
suspendingTransactionId.asContextElement(System.identityHashCode(controlJob))
return dispatcher + transactionElement + threadLocalElement
}
/**
* Acquires a thread from the executor and returns a [ContinuationInterceptor] to dispatch
* coroutines to the acquired thread. The [controlJob] is used to control the release of the
* thread by cancelling the job.
*/
private suspend fun CoroutineDispatcher.acquireTransactionThread(
controlJob: Job,
): ContinuationInterceptor {
return suspendCancellableCoroutine { continuation ->
continuation.invokeOnCancellation {
// We got cancelled while waiting to acquire a thread, we can't stop our attempt to
// acquire a thread, but we can cancel the controlling job so once it gets acquired it
// is quickly released.
controlJob.cancel()
}
try {
dispatch(EmptyCoroutineContext) {
runBlocking {
// Thread acquired, resume coroutine.
continuation.resume(coroutineContext[ContinuationInterceptor]!!)
controlJob.join()
}
}
} catch (ex: RejectedExecutionException) {
// Couldn't acquire a thread, cancel coroutine.
continuation.cancel(
IllegalStateException(
"Unable to acquire a thread to perform the database transaction.",
ex,
),
)
}
}
}
/**
* A [CoroutineContext.Element] that indicates there is an on-going database transaction.
*/
private class TransactionElement(
private val transactionThreadControlJob: Job,
val transactionDispatcher: ContinuationInterceptor,
) : CoroutineContext.Element {
companion object Key : CoroutineContext.Key<TransactionElement>
override val key: CoroutineContext.Key<TransactionElement>
get() = TransactionElement
/**
* Number of transactions (including nested ones) started with this element.
* Call [acquire] to increase the count and [release] to decrease it. If the count reaches zero
* when [release] is invoked then the transaction job is cancelled and the transaction thread
* is released.
*/
private val referenceCount = AtomicInteger(0)
fun acquire() {
referenceCount.incrementAndGet()
}
fun release() {
val count = referenceCount.decrementAndGet()
if (count < 0) {
throw IllegalStateException("Transaction was never started or was already released.")
} else if (count == 0) {
// Cancel the job that controls the transaction thread, causing it to be released.
transactionThreadControlJob.cancel()
}
}
}

View File

@ -1,12 +0,0 @@
package eu.kanade.data.category
import eu.kanade.domain.category.model.Category
val categoryMapper: (Long, String, Long, Long) -> Category = { id, name, order, flags ->
Category(
id = id,
name = name,
order = order,
flags = flags,
)
}

View File

@ -1,84 +0,0 @@
package eu.kanade.data.category
import eu.kanade.data.DatabaseHandler
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.category.model.CategoryUpdate
import eu.kanade.domain.category.repository.CategoryRepository
import eu.kanade.tachiyomi.Database
import kotlinx.coroutines.flow.Flow
class CategoryRepositoryImpl(
private val handler: DatabaseHandler,
) : CategoryRepository {
override suspend fun get(id: Long): Category? {
return handler.awaitOneOrNull { categoriesQueries.getCategory(id, categoryMapper) }
}
override suspend fun getAll(): List<Category> {
return handler.awaitList { categoriesQueries.getCategories(categoryMapper) }
}
override fun getAllAsFlow(): Flow<List<Category>> {
return handler.subscribeToList { categoriesQueries.getCategories(categoryMapper) }
}
override suspend fun getCategoriesByMangaId(mangaId: Long): List<Category> {
return handler.awaitList {
categoriesQueries.getCategoriesByMangaId(mangaId, categoryMapper)
}
}
override fun getCategoriesByMangaIdAsFlow(mangaId: Long): Flow<List<Category>> {
return handler.subscribeToList {
categoriesQueries.getCategoriesByMangaId(mangaId, categoryMapper)
}
}
override suspend fun insert(category: Category) {
handler.await {
categoriesQueries.insert(
name = category.name,
order = category.order,
flags = category.flags,
)
}
}
override suspend fun updatePartial(update: CategoryUpdate) {
handler.await {
updatePartialBlocking(update)
}
}
override suspend fun updatePartial(updates: List<CategoryUpdate>) {
handler.await(inTransaction = true) {
for (update in updates) {
updatePartialBlocking(update)
}
}
}
private fun Database.updatePartialBlocking(update: CategoryUpdate) {
categoriesQueries.update(
name = update.name,
order = update.order,
flags = update.flags,
categoryId = update.id,
)
}
override suspend fun updateAllFlags(flags: Long?) {
handler.await {
categoriesQueries.updateAllFlags(flags)
}
}
override suspend fun delete(categoryId: Long) {
handler.await {
categoriesQueries.delete(
categoryId = categoryId,
)
}
}
}

View File

@ -1,21 +0,0 @@
package eu.kanade.data.chapter
import eu.kanade.domain.chapter.model.Chapter
val chapterMapper: (Long, Long, String, String, String?, Boolean, Boolean, Long, Float, Long, Long, Long) -> Chapter =
{ id, mangaId, url, name, scanlator, read, bookmark, lastPageRead, chapterNumber, sourceOrder, dateFetch, dateUpload ->
Chapter(
id = id,
mangaId = mangaId,
read = read,
bookmark = bookmark,
lastPageRead = lastPageRead,
dateFetch = dateFetch,
sourceOrder = sourceOrder,
url = url,
name = name,
dateUpload = dateUpload,
chapterNumber = chapterNumber,
scanlator = scanlator,
)
}

View File

@ -1,99 +0,0 @@
package eu.kanade.data.chapter
import eu.kanade.data.DatabaseHandler
import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.chapter.model.ChapterUpdate
import eu.kanade.domain.chapter.repository.ChapterRepository
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toLong
import kotlinx.coroutines.flow.Flow
import logcat.LogPriority
class ChapterRepositoryImpl(
private val handler: DatabaseHandler,
) : ChapterRepository {
override suspend fun addAll(chapters: List<Chapter>): List<Chapter> {
return try {
handler.await(inTransaction = true) {
chapters.map { chapter ->
chaptersQueries.insert(
chapter.mangaId,
chapter.url,
chapter.name,
chapter.scanlator,
chapter.read,
chapter.bookmark,
chapter.lastPageRead,
chapter.chapterNumber,
chapter.sourceOrder,
chapter.dateFetch,
chapter.dateUpload,
)
val lastInsertId = chaptersQueries.selectLastInsertedRowId().executeAsOne()
chapter.copy(id = lastInsertId)
}
}
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
emptyList()
}
}
override suspend fun update(chapterUpdate: ChapterUpdate) {
partialUpdate(chapterUpdate)
}
override suspend fun updateAll(chapterUpdates: List<ChapterUpdate>) {
partialUpdate(*chapterUpdates.toTypedArray())
}
private suspend fun partialUpdate(vararg chapterUpdates: ChapterUpdate) {
handler.await(inTransaction = true) {
chapterUpdates.forEach { chapterUpdate ->
chaptersQueries.update(
mangaId = chapterUpdate.mangaId,
url = chapterUpdate.url,
name = chapterUpdate.name,
scanlator = chapterUpdate.scanlator,
read = chapterUpdate.read?.toLong(),
bookmark = chapterUpdate.bookmark?.toLong(),
lastPageRead = chapterUpdate.lastPageRead,
chapterNumber = chapterUpdate.chapterNumber?.toDouble(),
sourceOrder = chapterUpdate.sourceOrder,
dateFetch = chapterUpdate.dateFetch,
dateUpload = chapterUpdate.dateUpload,
chapterId = chapterUpdate.id,
)
}
}
}
override suspend fun removeChaptersWithIds(chapterIds: List<Long>) {
try {
handler.await { chaptersQueries.removeChaptersWithIds(chapterIds) }
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
}
}
override suspend fun getChapterByMangaId(mangaId: Long): List<Chapter> {
return handler.awaitList { chaptersQueries.getChaptersByMangaId(mangaId, chapterMapper) }
}
override suspend fun getBookmarkedChaptersByMangaId(mangaId: Long): List<Chapter> {
return handler.awaitList { chaptersQueries.getBookmarkedChaptersByMangaId(mangaId, chapterMapper) }
}
override suspend fun getChapterById(id: Long): Chapter? {
return handler.awaitOneOrNull { chaptersQueries.getChapterById(id, chapterMapper) }
}
override suspend fun getChapterByMangaIdAsFlow(mangaId: Long): Flow<List<Chapter>> {
return handler.subscribeToList { chaptersQueries.getChaptersByMangaId(mangaId, chapterMapper) }
}
override suspend fun getChapterByUrlAndMangaId(url: String, mangaId: Long): Chapter? {
return handler.awaitOneOrNull { chaptersQueries.getChapterByUrlAndMangaId(url, mangaId, chapterMapper) }
}
}

View File

@ -1,47 +0,0 @@
package eu.kanade.data.chapter
object CleanupChapterName {
fun await(chapterName: String, mangaTitle: String): String {
return chapterName
.trim()
.removePrefix(mangaTitle)
.trim(*CHAPTER_TRIM_CHARS)
}
private val CHAPTER_TRIM_CHARS = arrayOf(
// Whitespace
' ',
'\u0009',
'\u000A',
'\u000B',
'\u000C',
'\u000D',
'\u0020',
'\u0085',
'\u00A0',
'\u1680',
'\u2000',
'\u2001',
'\u2002',
'\u2003',
'\u2004',
'\u2005',
'\u2006',
'\u2007',
'\u2008',
'\u2009',
'\u200A',
'\u2028',
'\u2029',
'\u202F',
'\u205F',
'\u3000',
// Separators
'-',
'_',
',',
':',
).toCharArray()
}

View File

@ -1,3 +0,0 @@
package eu.kanade.data.chapter
class NoChaptersException : Exception()

View File

@ -1,35 +0,0 @@
package eu.kanade.data.history
import eu.kanade.domain.history.model.History
import eu.kanade.domain.history.model.HistoryWithRelations
import eu.kanade.domain.manga.model.MangaCover
import java.util.Date
val historyMapper: (Long, Long, Date?, Long) -> History = { id, chapterId, readAt, readDuration ->
History(
id = id,
chapterId = chapterId,
readAt = readAt,
readDuration = readDuration,
)
}
val historyWithRelationsMapper: (Long, Long, Long, String, String?, Long, Boolean, Long, Float, Date?, Long) -> HistoryWithRelations = {
historyId, mangaId, chapterId, title, thumbnailUrl, sourceId, isFavorite, coverLastModified, chapterNumber, readAt, readDuration ->
HistoryWithRelations(
id = historyId,
chapterId = chapterId,
mangaId = mangaId,
title = title,
chapterNumber = chapterNumber,
readAt = readAt,
readDuration = readDuration,
coverData = MangaCover(
mangaId = mangaId,
sourceId = sourceId,
isMangaFavorite = isFavorite,
url = thumbnailUrl,
lastModified = coverLastModified,
),
)
}

View File

@ -1,66 +0,0 @@
package eu.kanade.data.history
import eu.kanade.data.DatabaseHandler
import eu.kanade.domain.history.model.HistoryUpdate
import eu.kanade.domain.history.model.HistoryWithRelations
import eu.kanade.domain.history.repository.HistoryRepository
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.flow.Flow
import logcat.LogPriority
class HistoryRepositoryImpl(
private val handler: DatabaseHandler,
) : HistoryRepository {
override fun getHistory(query: String): Flow<List<HistoryWithRelations>> {
return handler.subscribeToList {
historyViewQueries.history(query, historyWithRelationsMapper)
}
}
override suspend fun getLastHistory(): HistoryWithRelations? {
return handler.awaitOneOrNull {
historyViewQueries.getLatestHistory(historyWithRelationsMapper)
}
}
override suspend fun resetHistory(historyId: Long) {
try {
handler.await { historyQueries.resetHistoryById(historyId) }
} catch (e: Exception) {
logcat(LogPriority.ERROR, throwable = e)
}
}
override suspend fun resetHistoryByMangaId(mangaId: Long) {
try {
handler.await { historyQueries.resetHistoryByMangaId(mangaId) }
} catch (e: Exception) {
logcat(LogPriority.ERROR, throwable = e)
}
}
override suspend fun deleteAllHistory(): Boolean {
return try {
handler.await { historyQueries.removeAllHistory() }
true
} catch (e: Exception) {
logcat(LogPriority.ERROR, throwable = e)
false
}
}
override suspend fun upsertHistory(historyUpdate: HistoryUpdate) {
try {
handler.await {
historyQueries.upsert(
historyUpdate.chapterId,
historyUpdate.readAt,
historyUpdate.sessionReadDuration,
)
}
} catch (e: Exception) {
logcat(LogPriority.ERROR, throwable = e)
}
}
}

View File

@ -1,63 +0,0 @@
package eu.kanade.data.manga
import eu.kanade.domain.library.model.LibraryManga
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.source.model.UpdateStrategy
val mangaMapper: (Long, Long, String, String?, String?, String?, List<String>?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, UpdateStrategy) -> Manga =
{ id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, _, initialized, viewerFlags, chapterFlags, coverLastModified, dateAdded, updateStrategy ->
Manga(
id = id,
source = source,
favorite = favorite,
lastUpdate = lastUpdate ?: 0,
dateAdded = dateAdded,
viewerFlags = viewerFlags,
chapterFlags = chapterFlags,
coverLastModified = coverLastModified,
url = url,
title = title,
artist = artist,
author = author,
description = description,
genre = genre,
status = status,
thumbnailUrl = thumbnailUrl,
updateStrategy = updateStrategy,
initialized = initialized,
)
}
val libraryManga: (Long, Long, String, String?, String?, String?, List<String>?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, UpdateStrategy, Long, Long, Long, Long, Long, Long, Long) -> LibraryManga =
{ id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, nextUpdate, initialized, viewerFlags, chapterFlags, coverLastModified, dateAdded, updateStrategy, totalCount, readCount, latestUpload, chapterFetchedAt, lastRead, bookmarkCount, category ->
LibraryManga(
manga = mangaMapper(
id,
source,
url,
artist,
author,
description,
genre,
title,
status,
thumbnailUrl,
favorite,
lastUpdate,
nextUpdate,
initialized,
viewerFlags,
chapterFlags,
coverLastModified,
dateAdded,
updateStrategy,
),
category = category,
totalChapters = totalCount,
readCount = readCount,
bookmarkCount = bookmarkCount,
latestUpload = latestUpload,
chapterFetchedAt = chapterFetchedAt,
lastRead = lastRead,
)
}

View File

@ -1,148 +0,0 @@
package eu.kanade.data.manga
import eu.kanade.data.DatabaseHandler
import eu.kanade.data.listOfStringsAdapter
import eu.kanade.data.updateStrategyAdapter
import eu.kanade.domain.library.model.LibraryManga
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.MangaUpdate
import eu.kanade.domain.manga.repository.MangaRepository
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toLong
import kotlinx.coroutines.flow.Flow
import logcat.LogPriority
class MangaRepositoryImpl(
private val handler: DatabaseHandler,
) : MangaRepository {
override suspend fun getMangaById(id: Long): Manga {
return handler.awaitOne { mangasQueries.getMangaById(id, mangaMapper) }
}
override suspend fun getMangaByIdAsFlow(id: Long): Flow<Manga> {
return handler.subscribeToOne { mangasQueries.getMangaById(id, mangaMapper) }
}
override suspend fun getMangaByUrlAndSourceId(url: String, sourceId: Long): Manga? {
return handler.awaitOneOrNull(inTransaction = true) { mangasQueries.getMangaByUrlAndSource(url, sourceId, mangaMapper) }
}
override fun getMangaByUrlAndSourceIdAsFlow(url: String, sourceId: Long): Flow<Manga?> {
return handler.subscribeToOneOrNull { mangasQueries.getMangaByUrlAndSource(url, sourceId, mangaMapper) }
}
override suspend fun getFavorites(): List<Manga> {
return handler.awaitList { mangasQueries.getFavorites(mangaMapper) }
}
override suspend fun getLibraryManga(): List<LibraryManga> {
return handler.awaitList { libraryViewQueries.library(libraryManga) }
}
override fun getLibraryMangaAsFlow(): Flow<List<LibraryManga>> {
return handler.subscribeToList { libraryViewQueries.library(libraryManga) }
}
override fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>> {
return handler.subscribeToList { mangasQueries.getFavoriteBySourceId(sourceId, mangaMapper) }
}
override suspend fun getDuplicateLibraryManga(title: String, sourceId: Long): Manga? {
return handler.awaitOneOrNull {
mangasQueries.getDuplicateLibraryManga(title, sourceId, mangaMapper)
}
}
override suspend fun resetViewerFlags(): Boolean {
return try {
handler.await { mangasQueries.resetViewerFlags() }
true
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
false
}
}
override suspend fun setMangaCategories(mangaId: Long, categoryIds: List<Long>) {
handler.await(inTransaction = true) {
mangas_categoriesQueries.deleteMangaCategoryByMangaId(mangaId)
categoryIds.map { categoryId ->
mangas_categoriesQueries.insert(mangaId, categoryId)
}
}
}
override suspend fun insert(manga: Manga): Long? {
return handler.awaitOneOrNull(inTransaction = true) {
mangasQueries.insert(
source = manga.source,
url = manga.url,
artist = manga.artist,
author = manga.author,
description = manga.description,
genre = manga.genre,
title = manga.title,
status = manga.status,
thumbnailUrl = manga.thumbnailUrl,
favorite = manga.favorite,
lastUpdate = manga.lastUpdate,
nextUpdate = null,
initialized = manga.initialized,
viewerFlags = manga.viewerFlags,
chapterFlags = manga.chapterFlags,
coverLastModified = manga.coverLastModified,
dateAdded = manga.dateAdded,
updateStrategy = manga.updateStrategy,
)
mangasQueries.selectLastInsertedRowId()
}
}
override suspend fun update(update: MangaUpdate): Boolean {
return try {
partialUpdate(update)
true
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
false
}
}
override suspend fun updateAll(mangaUpdates: List<MangaUpdate>): Boolean {
return try {
partialUpdate(*mangaUpdates.toTypedArray())
true
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
false
}
}
private suspend fun partialUpdate(vararg mangaUpdates: MangaUpdate) {
handler.await(inTransaction = true) {
mangaUpdates.forEach { value ->
mangasQueries.update(
source = value.source,
url = value.url,
artist = value.artist,
author = value.author,
description = value.description,
genre = value.genre?.let(listOfStringsAdapter::encode),
title = value.title,
status = value.status,
thumbnailUrl = value.thumbnailUrl,
favorite = value.favorite?.toLong(),
lastUpdate = value.lastUpdate,
initialized = value.initialized?.toLong(),
viewer = value.viewerFlags,
chapterFlags = value.chapterFlags,
coverLastModified = value.coverLastModified,
dateAdded = value.dateAdded,
mangaId = value.id,
updateStrategy = value.updateStrategy?.let(updateStrategyAdapter::encode),
)
}
}
}
}

View File

@ -1,3 +0,0 @@
package eu.kanade.data.source
class NoResultsException : Exception()

View File

@ -1,23 +0,0 @@
package eu.kanade.data.source
import eu.kanade.data.DatabaseHandler
import eu.kanade.domain.source.model.SourceData
import eu.kanade.domain.source.repository.SourceDataRepository
import kotlinx.coroutines.flow.Flow
class SourceDataRepositoryImpl(
private val handler: DatabaseHandler,
) : SourceDataRepository {
override fun subscribeAll(): Flow<List<SourceData>> {
return handler.subscribeToList { sourcesQueries.findAll(sourceDataMapper) }
}
override suspend fun getSourceData(id: Long): SourceData? {
return handler.awaitOneOrNull { sourcesQueries.findOne(id, sourceDataMapper) }
}
override suspend fun upsertSourceData(id: Long, lang: String, name: String) {
handler.await { sourcesQueries.upsert(id, lang, name) }
}
}

View File

@ -1,24 +0,0 @@
package eu.kanade.data.source
import eu.kanade.domain.source.model.Source
import eu.kanade.domain.source.model.SourceData
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.SourceManager
val sourceMapper: (eu.kanade.tachiyomi.source.Source) -> Source = { source ->
Source(
source.id,
source.lang,
source.name,
supportsLatest = false,
isStub = source is SourceManager.StubSource,
)
}
val catalogueSourceMapper: (CatalogueSource) -> Source = { source ->
sourceMapper(source).copy(supportsLatest = source.supportsLatest)
}
val sourceDataMapper: (Long, String, String) -> SourceData = { id, lang, name ->
SourceData(id, lang, name)
}

View File

@ -1,62 +0,0 @@
package eu.kanade.data.source
import androidx.paging.PagingState
import eu.kanade.domain.source.model.SourcePagingSourceType
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.lang.awaitSingle
import eu.kanade.tachiyomi.util.lang.withIOContext
abstract class SourcePagingSource(
protected val source: CatalogueSource,
) : SourcePagingSourceType() {
abstract suspend fun requestNextPage(currentPage: Int): MangasPage
override suspend fun load(params: LoadParams<Long>): LoadResult<Long, SManga> {
val page = params.key ?: 1
val mangasPage = try {
withIOContext {
requestNextPage(page.toInt())
.takeIf { it.mangas.isNotEmpty() }
?: throw NoResultsException()
}
} catch (e: Exception) {
return LoadResult.Error(e)
}
return LoadResult.Page(
data = mangasPage.mangas,
prevKey = null,
nextKey = if (mangasPage.hasNextPage) page + 1 else null,
)
}
override fun getRefreshKey(state: PagingState<Long, SManga>): Long? {
return state.anchorPosition?.let { anchorPosition ->
val anchorPage = state.closestPageToPosition(anchorPosition)
anchorPage?.prevKey ?: anchorPage?.nextKey
}
}
}
class SourceSearchPagingSource(source: CatalogueSource, val query: String, val filters: FilterList) : SourcePagingSource(source) {
override suspend fun requestNextPage(currentPage: Int): MangasPage {
return source.fetchSearchManga(currentPage, query, filters).awaitSingle()
}
}
class SourcePopularPagingSource(source: CatalogueSource) : SourcePagingSource(source) {
override suspend fun requestNextPage(currentPage: Int): MangasPage {
return source.fetchPopularManga(currentPage).awaitSingle()
}
}
class SourceLatestPagingSource(source: CatalogueSource) : SourcePagingSource(source) {
override suspend fun requestNextPage(currentPage: Int): MangasPage {
return source.fetchLatestUpdates(currentPage).awaitSingle()
}
}

View File

@ -1,74 +0,0 @@
package eu.kanade.data.source
import eu.kanade.data.DatabaseHandler
import eu.kanade.domain.source.model.Source
import eu.kanade.domain.source.model.SourcePagingSourceType
import eu.kanade.domain.source.model.SourceWithCount
import eu.kanade.domain.source.repository.SourceRepository
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.FilterList
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
class SourceRepositoryImpl(
private val sourceManager: SourceManager,
private val handler: DatabaseHandler,
) : SourceRepository {
override fun getSources(): Flow<List<Source>> {
return sourceManager.catalogueSources.map { sources ->
sources.map(catalogueSourceMapper)
}
}
override fun getOnlineSources(): Flow<List<Source>> {
return sourceManager.onlineSources.map { sources ->
sources.map(sourceMapper)
}
}
override fun getSourcesWithFavoriteCount(): Flow<List<Pair<Source, Long>>> {
val sourceIdWithFavoriteCount = handler.subscribeToList { mangasQueries.getSourceIdWithFavoriteCount() }
return sourceIdWithFavoriteCount.map { sourceIdsWithCount ->
sourceIdsWithCount
.filterNot { it.source == LocalSource.ID }
.map { (sourceId, count) ->
val source = sourceManager.getOrStub(sourceId).run {
sourceMapper(this)
}
source to count
}
}
}
override fun getSourcesWithNonLibraryManga(): Flow<List<SourceWithCount>> {
val sourceIdWithNonLibraryManga = handler.subscribeToList { mangasQueries.getSourceIdsWithNonLibraryManga() }
return sourceIdWithNonLibraryManga.map { sourceId ->
sourceId.map { (sourceId, count) ->
val source = sourceManager.getOrStub(sourceId)
SourceWithCount(sourceMapper(source), count)
}
}
}
override fun search(
sourceId: Long,
query: String,
filterList: FilterList,
): SourcePagingSourceType {
val source = sourceManager.get(sourceId) as CatalogueSource
return SourceSearchPagingSource(source, query, filterList)
}
override fun getPopular(sourceId: Long): SourcePagingSourceType {
val source = sourceManager.get(sourceId) as CatalogueSource
return SourcePopularPagingSource(source)
}
override fun getLatest(sourceId: Long): SourcePagingSourceType {
val source = sourceManager.get(sourceId) as CatalogueSource
return SourceLatestPagingSource(source)
}
}

View File

@ -1,22 +0,0 @@
package eu.kanade.data.track
import eu.kanade.domain.track.model.Track
val trackMapper: (Long, Long, Long, Long, Long?, String, Double, Long, Long, Float, String, Long, Long) -> Track =
{ id, mangaId, syncId, remoteId, libraryId, title, lastChapterRead, totalChapters, status, score, remoteUrl, startDate, finishDate ->
Track(
id = id,
mangaId = mangaId,
syncId = syncId,
remoteId = remoteId,
libraryId = libraryId,
title = title,
lastChapterRead = lastChapterRead,
totalChapters = totalChapters,
status = status,
score = score,
remoteUrl = remoteUrl,
startDate = startDate,
finishDate = finishDate,
)
}

View File

@ -1,67 +0,0 @@
package eu.kanade.data.track
import eu.kanade.data.DatabaseHandler
import eu.kanade.domain.track.model.Track
import eu.kanade.domain.track.repository.TrackRepository
import kotlinx.coroutines.flow.Flow
class TrackRepositoryImpl(
private val handler: DatabaseHandler,
) : TrackRepository {
override suspend fun getTracksByMangaId(mangaId: Long): List<Track> {
return handler.awaitList {
manga_syncQueries.getTracksByMangaId(mangaId, trackMapper)
}
}
override fun getTracksAsFlow(): Flow<List<Track>> {
return handler.subscribeToList {
manga_syncQueries.getTracks(trackMapper)
}
}
override fun getTracksByMangaIdAsFlow(mangaId: Long): Flow<List<Track>> {
return handler.subscribeToList {
manga_syncQueries.getTracksByMangaId(mangaId, trackMapper)
}
}
override suspend fun delete(mangaId: Long, syncId: Long) {
handler.await {
manga_syncQueries.delete(
mangaId = mangaId,
syncId = syncId,
)
}
}
override suspend fun insert(track: Track) {
insertValues(track)
}
override suspend fun insertAll(tracks: List<Track>) {
insertValues(*tracks.toTypedArray())
}
private suspend fun insertValues(vararg tracks: Track) {
handler.await(inTransaction = true) {
tracks.forEach { mangaTrack ->
manga_syncQueries.insert(
mangaId = mangaTrack.mangaId,
syncId = mangaTrack.syncId,
remoteId = mangaTrack.remoteId,
libraryId = mangaTrack.libraryId,
title = mangaTrack.title,
lastChapterRead = mangaTrack.lastChapterRead,
totalChapters = mangaTrack.totalChapters,
status = mangaTrack.status,
score = mangaTrack.score,
remoteUrl = mangaTrack.remoteUrl,
startDate = mangaTrack.startDate,
finishDate = mangaTrack.finishDate,
)
}
}
}
}

View File

@ -1,26 +0,0 @@
package eu.kanade.data.updates
import eu.kanade.domain.manga.model.MangaCover
import eu.kanade.domain.updates.model.UpdatesWithRelations
val updateWithRelationMapper: (Long, String, Long, String, String?, Boolean, Boolean, Long, Boolean, String?, Long, Long, Long) -> UpdatesWithRelations = {
mangaId, mangaTitle, chapterId, chapterName, scanlator, read, bookmark, sourceId, favorite, thumbnailUrl, coverLastModified, _, dateFetch ->
UpdatesWithRelations(
mangaId = mangaId,
mangaTitle = mangaTitle,
chapterId = chapterId,
chapterName = chapterName,
scanlator = scanlator,
read = read,
bookmark = bookmark,
sourceId = sourceId,
dateFetch = dateFetch,
coverData = MangaCover(
mangaId = mangaId,
sourceId = sourceId,
isMangaFavorite = favorite,
url = thumbnailUrl,
lastModified = coverLastModified,
),
)
}

View File

@ -1,17 +0,0 @@
package eu.kanade.data.updates
import eu.kanade.data.DatabaseHandler
import eu.kanade.domain.updates.model.UpdatesWithRelations
import eu.kanade.domain.updates.repository.UpdatesRepository
import kotlinx.coroutines.flow.Flow
class UpdatesRepositoryImpl(
val databaseHandler: DatabaseHandler,
) : UpdatesRepository {
override fun subscribeAll(after: Long): Flow<List<UpdatesWithRelations>> {
return databaseHandler.subscribeToList {
updatesViewQueries.updates(after, updateWithRelationMapper)
}
}
}

View File

@ -1,147 +0,0 @@
package eu.kanade.domain
import eu.kanade.data.category.CategoryRepositoryImpl
import eu.kanade.data.chapter.ChapterRepositoryImpl
import eu.kanade.data.history.HistoryRepositoryImpl
import eu.kanade.data.manga.MangaRepositoryImpl
import eu.kanade.data.source.SourceDataRepositoryImpl
import eu.kanade.data.source.SourceRepositoryImpl
import eu.kanade.data.track.TrackRepositoryImpl
import eu.kanade.data.updates.UpdatesRepositoryImpl
import eu.kanade.domain.category.interactor.CreateCategoryWithName
import eu.kanade.domain.category.interactor.DeleteCategory
import eu.kanade.domain.category.interactor.GetCategories
import eu.kanade.domain.category.interactor.RenameCategory
import eu.kanade.domain.category.interactor.ReorderCategory
import eu.kanade.domain.category.interactor.ResetCategoryFlags
import eu.kanade.domain.category.interactor.SetDisplayModeForCategory
import eu.kanade.domain.category.interactor.SetMangaCategories
import eu.kanade.domain.category.interactor.SetSortModeForCategory
import eu.kanade.domain.category.interactor.UpdateCategory
import eu.kanade.domain.category.repository.CategoryRepository
import eu.kanade.domain.chapter.interactor.GetChapter
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
import eu.kanade.domain.chapter.interactor.SetMangaDefaultChapterFlags
import eu.kanade.domain.chapter.interactor.SetReadStatus
import eu.kanade.domain.chapter.interactor.ShouldUpdateDbChapter
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
import eu.kanade.domain.chapter.interactor.UpdateChapter
import eu.kanade.domain.chapter.repository.ChapterRepository
import eu.kanade.domain.download.interactor.DeleteDownload
import eu.kanade.domain.extension.interactor.GetExtensionLanguages
import eu.kanade.domain.extension.interactor.GetExtensionSources
import eu.kanade.domain.extension.interactor.GetExtensionsByType
import eu.kanade.domain.history.interactor.DeleteAllHistory
import eu.kanade.domain.history.interactor.GetHistory
import eu.kanade.domain.history.interactor.GetNextChapter
import eu.kanade.domain.history.interactor.RemoveHistoryById
import eu.kanade.domain.history.interactor.RemoveHistoryByMangaId
import eu.kanade.domain.history.interactor.UpsertHistory
import eu.kanade.domain.history.repository.HistoryRepository
import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
import eu.kanade.domain.manga.interactor.GetFavorites
import eu.kanade.domain.manga.interactor.GetLibraryManga
import eu.kanade.domain.manga.interactor.GetManga
import eu.kanade.domain.manga.interactor.GetMangaWithChapters
import eu.kanade.domain.manga.interactor.NetworkToLocalManga
import eu.kanade.domain.manga.interactor.ResetViewerFlags
import eu.kanade.domain.manga.interactor.SetMangaChapterFlags
import eu.kanade.domain.manga.interactor.SetMangaViewerFlags
import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.repository.MangaRepository
import eu.kanade.domain.source.interactor.GetEnabledSources
import eu.kanade.domain.source.interactor.GetLanguagesWithSources
import eu.kanade.domain.source.interactor.GetRemoteManga
import eu.kanade.domain.source.interactor.GetSourcesWithFavoriteCount
import eu.kanade.domain.source.interactor.GetSourcesWithNonLibraryManga
import eu.kanade.domain.source.interactor.SetMigrateSorting
import eu.kanade.domain.source.interactor.ToggleLanguage
import eu.kanade.domain.source.interactor.ToggleSource
import eu.kanade.domain.source.interactor.ToggleSourcePin
import eu.kanade.domain.source.repository.SourceDataRepository
import eu.kanade.domain.source.repository.SourceRepository
import eu.kanade.domain.track.interactor.DeleteTrack
import eu.kanade.domain.track.interactor.GetTracks
import eu.kanade.domain.track.interactor.InsertTrack
import eu.kanade.domain.track.repository.TrackRepository
import eu.kanade.domain.updates.interactor.GetUpdates
import eu.kanade.domain.updates.repository.UpdatesRepository
import uy.kohesive.injekt.api.InjektModule
import uy.kohesive.injekt.api.InjektRegistrar
import uy.kohesive.injekt.api.addFactory
import uy.kohesive.injekt.api.addSingletonFactory
import uy.kohesive.injekt.api.get
class DomainModule : InjektModule {
override fun InjektRegistrar.registerInjectables() {
addSingletonFactory<CategoryRepository> { CategoryRepositoryImpl(get()) }
addFactory { GetCategories(get()) }
addFactory { ResetCategoryFlags(get(), get()) }
addFactory { SetDisplayModeForCategory(get(), get()) }
addFactory { SetSortModeForCategory(get(), get()) }
addFactory { CreateCategoryWithName(get(), get()) }
addFactory { RenameCategory(get()) }
addFactory { ReorderCategory(get()) }
addFactory { UpdateCategory(get()) }
addFactory { DeleteCategory(get()) }
addSingletonFactory<MangaRepository> { MangaRepositoryImpl(get()) }
addFactory { GetDuplicateLibraryManga(get()) }
addFactory { GetFavorites(get()) }
addFactory { GetLibraryManga(get()) }
addFactory { GetMangaWithChapters(get(), get()) }
addFactory { GetManga(get()) }
addFactory { GetNextChapter(get(), get(), get(), get()) }
addFactory { ResetViewerFlags(get()) }
addFactory { SetMangaChapterFlags(get()) }
addFactory { SetMangaDefaultChapterFlags(get(), get(), get()) }
addFactory { SetMangaViewerFlags(get()) }
addFactory { NetworkToLocalManga(get()) }
addFactory { UpdateManga(get()) }
addFactory { SetMangaCategories(get()) }
addSingletonFactory<TrackRepository> { TrackRepositoryImpl(get()) }
addFactory { DeleteTrack(get()) }
addFactory { GetTracks(get()) }
addFactory { InsertTrack(get()) }
addSingletonFactory<ChapterRepository> { ChapterRepositoryImpl(get()) }
addFactory { GetChapter(get()) }
addFactory { GetChapterByMangaId(get()) }
addFactory { UpdateChapter(get()) }
addFactory { SetReadStatus(get(), get(), get(), get()) }
addFactory { ShouldUpdateDbChapter() }
addFactory { SyncChaptersWithSource(get(), get(), get(), get()) }
addFactory { SyncChaptersWithTrackServiceTwoWay(get(), get()) }
addSingletonFactory<HistoryRepository> { HistoryRepositoryImpl(get()) }
addFactory { DeleteAllHistory(get()) }
addFactory { GetHistory(get()) }
addFactory { UpsertHistory(get()) }
addFactory { RemoveHistoryById(get()) }
addFactory { RemoveHistoryByMangaId(get()) }
addFactory { DeleteDownload(get(), get()) }
addFactory { GetExtensionsByType(get(), get()) }
addFactory { GetExtensionSources(get()) }
addFactory { GetExtensionLanguages(get(), get()) }
addSingletonFactory<UpdatesRepository> { UpdatesRepositoryImpl(get()) }
addFactory { GetUpdates(get(), get()) }
addSingletonFactory<SourceRepository> { SourceRepositoryImpl(get(), get()) }
addSingletonFactory<SourceDataRepository> { SourceDataRepositoryImpl(get()) }
addFactory { GetEnabledSources(get(), get()) }
addFactory { GetLanguagesWithSources(get(), get()) }
addFactory { GetRemoteManga(get()) }
addFactory { GetSourcesWithFavoriteCount(get(), get()) }
addFactory { GetSourcesWithNonLibraryManga(get()) }
addFactory { SetMigrateSorting(get()) }
addFactory { ToggleLanguage(get()) }
addFactory { ToggleSource(get()) }
addFactory { ToggleSourcePin(get()) }
}
}

View File

@ -1,16 +0,0 @@
package eu.kanade.domain.backup.service
import eu.kanade.tachiyomi.core.preference.PreferenceStore
import eu.kanade.tachiyomi.core.provider.FolderProvider
class BackupPreferences(
private val folderProvider: FolderProvider,
private val preferenceStore: PreferenceStore,
) {
fun backupsDirectory() = preferenceStore.getString("backup_directory", folderProvider.path())
fun numberOfBackups() = preferenceStore.getInt("backup_slots", 2)
fun backupInterval() = preferenceStore.getInt("backup_interval", 12)
}

View File

@ -1,30 +0,0 @@
package eu.kanade.domain.base
import android.content.Context
import eu.kanade.tachiyomi.core.preference.PreferenceStore
import eu.kanade.tachiyomi.core.preference.getEnum
import eu.kanade.tachiyomi.data.preference.PreferenceValues
import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
import eu.kanade.tachiyomi.util.system.isReleaseBuildType
class BasePreferences(
val context: Context,
private val preferenceStore: PreferenceStore,
) {
fun confirmExit() = preferenceStore.getBoolean("pref_confirm_exit", false)
fun downloadedOnly() = preferenceStore.getBoolean("pref_downloaded_only", false)
fun incognitoMode() = preferenceStore.getBoolean("incognito_mode", false)
fun automaticExtUpdates() = preferenceStore.getBoolean("automatic_ext_updates", true)
fun extensionInstaller() = preferenceStore.getEnum(
"extension_installer",
if (DeviceUtil.isMiui) PreferenceValues.ExtensionInstaller.LEGACY else PreferenceValues.ExtensionInstaller.PACKAGEINSTALLER,
)
fun acraEnabled() = preferenceStore.getBoolean("acra.enable", isPreviewBuildType || isReleaseBuildType)
}

View File

@ -1,52 +0,0 @@
package eu.kanade.domain.category.interactor
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.category.model.anyWithName
import eu.kanade.domain.category.repository.CategoryRepository
import eu.kanade.domain.library.service.LibraryPreferences
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
class CreateCategoryWithName(
private val categoryRepository: CategoryRepository,
private val preferences: LibraryPreferences,
) {
private val initialFlags: Long
get() {
val sort = preferences.librarySortingMode().get()
return preferences.libraryDisplayMode().get().flag or
sort.type.flag or
sort.direction.flag
}
suspend fun await(name: String): Result = withNonCancellableContext {
val categories = categoryRepository.getAll()
if (categories.anyWithName(name)) {
return@withNonCancellableContext Result.NameAlreadyExistsError
}
val nextOrder = categories.maxOfOrNull { it.order }?.plus(1) ?: 0
val newCategory = Category(
id = 0,
name = name,
order = nextOrder,
flags = initialFlags,
)
try {
categoryRepository.insert(newCategory)
Result.Success
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
Result.InternalError(e)
}
}
sealed class Result {
object Success : Result()
object NameAlreadyExistsError : Result()
data class InternalError(val error: Throwable) : Result()
}
}

View File

@ -1,42 +0,0 @@
package eu.kanade.domain.category.interactor
import eu.kanade.domain.category.model.CategoryUpdate
import eu.kanade.domain.category.repository.CategoryRepository
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
class DeleteCategory(
private val categoryRepository: CategoryRepository,
) {
suspend fun await(categoryId: Long) = withNonCancellableContext {
try {
categoryRepository.delete(categoryId)
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
return@withNonCancellableContext Result.InternalError(e)
}
val categories = categoryRepository.getAll()
val updates = categories.mapIndexed { index, category ->
CategoryUpdate(
id = category.id,
order = index.toLong(),
)
}
try {
categoryRepository.updatePartial(updates)
Result.Success
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
Result.InternalError(e)
}
}
sealed class Result {
object Success : Result()
data class InternalError(val error: Throwable) : Result()
}
}

View File

@ -1,26 +0,0 @@
package eu.kanade.domain.category.interactor
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.category.repository.CategoryRepository
import kotlinx.coroutines.flow.Flow
class GetCategories(
private val categoryRepository: CategoryRepository,
) {
fun subscribe(): Flow<List<Category>> {
return categoryRepository.getAllAsFlow()
}
fun subscribe(mangaId: Long): Flow<List<Category>> {
return categoryRepository.getCategoriesByMangaIdAsFlow(mangaId)
}
suspend fun await(): List<Category> {
return categoryRepository.getAll()
}
suspend fun await(mangaId: Long): List<Category> {
return categoryRepository.getCategoriesByMangaId(mangaId)
}
}

View File

@ -1,42 +0,0 @@
package eu.kanade.domain.category.interactor
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.category.model.CategoryUpdate
import eu.kanade.domain.category.model.anyWithName
import eu.kanade.domain.category.repository.CategoryRepository
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
class RenameCategory(
private val categoryRepository: CategoryRepository,
) {
suspend fun await(categoryId: Long, name: String) = withNonCancellableContext {
val categories = categoryRepository.getAll()
if (categories.anyWithName(name)) {
return@withNonCancellableContext Result.NameAlreadyExistsError
}
val update = CategoryUpdate(
id = categoryId,
name = name,
)
try {
categoryRepository.updatePartial(update)
Result.Success
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
Result.InternalError(e)
}
}
suspend fun await(category: Category, name: String) = await(category.id, name)
sealed class Result {
object Success : Result()
object NameAlreadyExistsError : Result()
data class InternalError(val error: Throwable) : Result()
}
}

View File

@ -1,50 +0,0 @@
package eu.kanade.domain.category.interactor
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.category.model.CategoryUpdate
import eu.kanade.domain.category.repository.CategoryRepository
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
class ReorderCategory(
private val categoryRepository: CategoryRepository,
) {
suspend fun await(categoryId: Long, newPosition: Int) = withNonCancellableContext {
val categories = categoryRepository.getAll().filterNot(Category::isSystemCategory)
val currentIndex = categories.indexOfFirst { it.id == categoryId }
if (currentIndex == newPosition) {
return@withNonCancellableContext Result.Unchanged
}
val reorderedCategories = categories.toMutableList()
val reorderedCategory = reorderedCategories.removeAt(currentIndex)
reorderedCategories.add(newPosition, reorderedCategory)
val updates = reorderedCategories.mapIndexed { index, category ->
CategoryUpdate(
id = category.id,
order = index.toLong(),
)
}
try {
categoryRepository.updatePartial(updates)
Result.Success
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
Result.InternalError(e)
}
}
suspend fun await(category: Category, newPosition: Long): Result =
await(category.id, newPosition.toInt())
sealed class Result {
object Success : Result()
object Unchanged : Result()
data class InternalError(val error: Throwable) : Result()
}
}

View File

@ -1,17 +0,0 @@
package eu.kanade.domain.category.interactor
import eu.kanade.domain.category.repository.CategoryRepository
import eu.kanade.domain.library.model.plus
import eu.kanade.domain.library.service.LibraryPreferences
class ResetCategoryFlags(
private val preferences: LibraryPreferences,
private val categoryRepository: CategoryRepository,
) {
suspend fun await() {
val display = preferences.libraryDisplayMode().get()
val sort = preferences.librarySortingMode().get()
categoryRepository.updateAllFlags(display + sort.type + sort.direction)
}
}

View File

@ -1,34 +0,0 @@
package eu.kanade.domain.category.interactor
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.category.model.CategoryUpdate
import eu.kanade.domain.category.repository.CategoryRepository
import eu.kanade.domain.library.model.LibraryDisplayMode
import eu.kanade.domain.library.model.plus
import eu.kanade.domain.library.service.LibraryPreferences
class SetDisplayModeForCategory(
private val preferences: LibraryPreferences,
private val categoryRepository: CategoryRepository,
) {
suspend fun await(categoryId: Long, display: LibraryDisplayMode) {
val category = categoryRepository.get(categoryId) ?: return
val flags = category.flags + display
if (preferences.categorizedDisplaySettings().get()) {
categoryRepository.updatePartial(
CategoryUpdate(
id = category.id,
flags = flags,
),
)
} else {
preferences.libraryDisplayMode().set(display)
categoryRepository.updateAllFlags(flags)
}
}
suspend fun await(category: Category, display: LibraryDisplayMode) {
await(category.id, display)
}
}

View File

@ -1,18 +0,0 @@
package eu.kanade.domain.category.interactor
import eu.kanade.domain.manga.repository.MangaRepository
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
class SetMangaCategories(
private val mangaRepository: MangaRepository,
) {
suspend fun await(mangaId: Long, categoryIds: List<Long>) {
try {
mangaRepository.setMangaCategories(mangaId, categoryIds)
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
}
}
}

View File

@ -1,34 +0,0 @@
package eu.kanade.domain.category.interactor
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.category.model.CategoryUpdate
import eu.kanade.domain.category.repository.CategoryRepository
import eu.kanade.domain.library.model.LibrarySort
import eu.kanade.domain.library.model.plus
import eu.kanade.domain.library.service.LibraryPreferences
class SetSortModeForCategory(
private val preferences: LibraryPreferences,
private val categoryRepository: CategoryRepository,
) {
suspend fun await(categoryId: Long, type: LibrarySort.Type, direction: LibrarySort.Direction) {
val category = categoryRepository.get(categoryId) ?: return
val flags = category.flags + type + direction
if (preferences.categorizedDisplaySettings().get()) {
categoryRepository.updatePartial(
CategoryUpdate(
id = category.id,
flags = flags,
),
)
} else {
preferences.librarySortingMode().set(LibrarySort(type, direction))
categoryRepository.updateAllFlags(flags)
}
}
suspend fun await(category: Category, type: LibrarySort.Type, direction: LibrarySort.Direction) {
await(category.id, type, direction)
}
}

View File

@ -1,24 +0,0 @@
package eu.kanade.domain.category.interactor
import eu.kanade.domain.category.model.CategoryUpdate
import eu.kanade.domain.category.repository.CategoryRepository
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
class UpdateCategory(
private val categoryRepository: CategoryRepository,
) {
suspend fun await(payload: CategoryUpdate): Result = withNonCancellableContext {
try {
categoryRepository.updatePartial(payload)
Result.Success
} catch (e: Exception) {
Result.Error(e)
}
}
sealed class Result {
object Success : Result()
data class Error(val error: Exception) : Result()
}
}

View File

@ -1,22 +0,0 @@
package eu.kanade.domain.category.model
import java.io.Serializable
data class Category(
val id: Long,
val name: String,
val order: Long,
val flags: Long,
) : Serializable {
val isSystemCategory: Boolean = id == UNCATEGORIZED_ID
companion object {
const val UNCATEGORIZED_ID = 0L
}
}
internal fun List<Category>.anyWithName(name: String): Boolean {
return any { name == it.name }
}

View File

@ -1,8 +0,0 @@
package eu.kanade.domain.category.model
data class CategoryUpdate(
val id: Long,
val name: String? = null,
val order: Long? = null,
val flags: Long? = null,
)

View File

@ -1,28 +0,0 @@
package eu.kanade.domain.category.repository
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.category.model.CategoryUpdate
import kotlinx.coroutines.flow.Flow
interface CategoryRepository {
suspend fun get(id: Long): Category?
suspend fun getAll(): List<Category>
fun getAllAsFlow(): Flow<List<Category>>
suspend fun getCategoriesByMangaId(mangaId: Long): List<Category>
fun getCategoriesByMangaIdAsFlow(mangaId: Long): Flow<List<Category>>
suspend fun insert(category: Category)
suspend fun updatePartial(update: CategoryUpdate)
suspend fun updatePartial(updates: List<CategoryUpdate>)
suspend fun updateAllFlags(flags: Long?)
suspend fun delete(categoryId: Long)
}

View File

@ -1,29 +0,0 @@
package eu.kanade.domain.chapter.interactor
import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.chapter.repository.ChapterRepository
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
class GetChapter(
private val chapterRepository: ChapterRepository,
) {
suspend fun await(id: Long): Chapter? {
return try {
chapterRepository.getChapterById(id)
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
null
}
}
suspend fun await(url: String, mangaId: Long): Chapter? {
return try {
chapterRepository.getChapterByUrlAndMangaId(url, mangaId)
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
null
}
}
}

View File

@ -1,20 +0,0 @@
package eu.kanade.domain.chapter.interactor
import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.chapter.repository.ChapterRepository
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
class GetChapterByMangaId(
private val chapterRepository: ChapterRepository,
) {
suspend fun await(mangaId: Long): List<Chapter> {
return try {
chapterRepository.getChapterByMangaId(mangaId)
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
emptyList()
}
}
}

View File

@ -1,36 +0,0 @@
package eu.kanade.domain.chapter.interactor
import eu.kanade.domain.library.service.LibraryPreferences
import eu.kanade.domain.manga.interactor.GetFavorites
import eu.kanade.domain.manga.interactor.SetMangaChapterFlags
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
class SetMangaDefaultChapterFlags(
private val libraryPreferences: LibraryPreferences,
private val setMangaChapterFlags: SetMangaChapterFlags,
private val getFavorites: GetFavorites,
) {
suspend fun await(manga: Manga) {
withNonCancellableContext {
with(libraryPreferences) {
setMangaChapterFlags.awaitSetAllFlags(
mangaId = manga.id,
unreadFilter = filterChapterByRead().get(),
downloadedFilter = filterChapterByDownloaded().get(),
bookmarkedFilter = filterChapterByBookmarked().get(),
sortingMode = sortChapterBySourceOrNumber().get(),
sortingDirection = sortChapterByAscendingOrDescending().get(),
displayMode = displayChapterByNameOrNumber().get(),
)
}
}
}
suspend fun awaitAll() {
withNonCancellableContext {
getFavorites.await().forEach { await(it) }
}
}
}

View File

@ -1,75 +0,0 @@
package eu.kanade.domain.chapter.interactor
import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.chapter.model.ChapterUpdate
import eu.kanade.domain.chapter.repository.ChapterRepository
import eu.kanade.domain.download.interactor.DeleteDownload
import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.repository.MangaRepository
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
class SetReadStatus(
private val downloadPreferences: DownloadPreferences,
private val deleteDownload: DeleteDownload,
private val mangaRepository: MangaRepository,
private val chapterRepository: ChapterRepository,
) {
private val mapper = { chapter: Chapter, read: Boolean ->
ChapterUpdate(
read = read,
lastPageRead = if (!read) 0 else null,
id = chapter.id,
)
}
suspend fun await(read: Boolean, vararg chapters: Chapter): Result = withNonCancellableContext {
val chaptersToUpdate = chapters.filterNot { it.read == read }
if (chaptersToUpdate.isEmpty()) {
return@withNonCancellableContext Result.NoChapters
}
try {
chapterRepository.updateAll(
chaptersToUpdate.map { mapper(it, read) },
)
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
return@withNonCancellableContext Result.InternalError(e)
}
if (read && downloadPreferences.removeAfterMarkedAsRead().get()) {
chaptersToUpdate
.groupBy { it.mangaId }
.forEach { (mangaId, chapters) ->
deleteDownload.awaitAll(
manga = mangaRepository.getMangaById(mangaId),
chapters = chapters.toTypedArray(),
)
}
}
Result.Success
}
suspend fun await(mangaId: Long, read: Boolean): Result = withNonCancellableContext {
await(
read = read,
chapters = chapterRepository
.getChapterByMangaId(mangaId)
.toTypedArray(),
)
}
suspend fun await(manga: Manga, read: Boolean) =
await(manga.id, read)
sealed class Result {
object Success : Result()
object NoChapters : Result()
data class InternalError(val error: Throwable) : Result()
}
}

View File

@ -1,13 +0,0 @@
package eu.kanade.domain.chapter.interactor
import eu.kanade.domain.chapter.model.Chapter
class ShouldUpdateDbChapter {
fun await(dbChapter: Chapter, sourceChapter: Chapter): Boolean {
return dbChapter.scanlator != sourceChapter.scanlator || dbChapter.name != sourceChapter.name ||
dbChapter.dateUpload != sourceChapter.dateUpload ||
dbChapter.chapterNumber != sourceChapter.chapterNumber ||
dbChapter.sourceOrder != sourceChapter.sourceOrder
}
}

View File

@ -1,195 +0,0 @@
package eu.kanade.domain.chapter.interactor
import eu.kanade.data.chapter.CleanupChapterName
import eu.kanade.data.chapter.NoChaptersException
import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.chapter.model.toChapterUpdate
import eu.kanade.domain.chapter.model.toDbChapter
import eu.kanade.domain.chapter.repository.ChapterRepository
import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadProvider
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.isLocal
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.chapter.ChapterRecognition
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.lang.Long.max
import java.util.Date
import java.util.TreeSet
class SyncChaptersWithSource(
private val downloadManager: DownloadManager = Injekt.get(),
private val downloadProvider: DownloadProvider = Injekt.get(),
private val chapterRepository: ChapterRepository = Injekt.get(),
private val shouldUpdateDbChapter: ShouldUpdateDbChapter = Injekt.get(),
private val updateManga: UpdateManga = Injekt.get(),
private val updateChapter: UpdateChapter = Injekt.get(),
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
) {
/**
* Method to synchronize db chapters with source ones
*
* @param rawSourceChapters the chapters from the source.
* @param manga the manga the chapters belong to.
* @param source the source the manga belongs to.
* @return Newly added chapters
*/
suspend fun await(
rawSourceChapters: List<SChapter>,
manga: Manga,
source: Source,
): List<Chapter> {
if (rawSourceChapters.isEmpty() && !source.isLocal()) {
throw NoChaptersException()
}
val sourceChapters = rawSourceChapters
.distinctBy { it.url }
.mapIndexed { i, sChapter ->
Chapter.create()
.copyFromSChapter(sChapter)
.copy(name = CleanupChapterName.await(sChapter.name, manga.title))
.copy(mangaId = manga.id, sourceOrder = i.toLong())
}
// Chapters from db.
val dbChapters = getChapterByMangaId.await(manga.id)
// Chapters from the source not in db.
val toAdd = mutableListOf<Chapter>()
// Chapters whose metadata have changed.
val toChange = mutableListOf<Chapter>()
// Chapters from the db not in source.
val toDelete = dbChapters.filterNot { dbChapter ->
sourceChapters.any { sourceChapter ->
dbChapter.url == sourceChapter.url
}
}
val rightNow = Date().time
// Used to not set upload date of older chapters
// to a higher value than newer chapters
var maxSeenUploadDate = 0L
val sManga = manga.toSManga()
for (sourceChapter in sourceChapters) {
var chapter = sourceChapter
// Update metadata from source if necessary.
if (source is HttpSource) {
val sChapter = chapter.toSChapter()
source.prepareNewChapter(sChapter, sManga)
chapter = chapter.copyFromSChapter(sChapter)
}
// Recognize chapter number for the chapter.
val chapterNumber = ChapterRecognition.parseChapterNumber(manga.title, chapter.name, chapter.chapterNumber)
chapter = chapter.copy(chapterNumber = chapterNumber)
val dbChapter = dbChapters.find { it.url == chapter.url }
if (dbChapter == null) {
val toAddChapter = if (chapter.dateUpload == 0L) {
val altDateUpload = if (maxSeenUploadDate == 0L) rightNow else maxSeenUploadDate
chapter.copy(dateUpload = altDateUpload)
} else {
maxSeenUploadDate = max(maxSeenUploadDate, sourceChapter.dateUpload)
chapter
}
toAdd.add(toAddChapter)
} else {
if (shouldUpdateDbChapter.await(dbChapter, chapter)) {
val shouldRenameChapter = downloadProvider.isChapterDirNameChanged(dbChapter, chapter) &&
downloadManager.isChapterDownloaded(dbChapter.name, dbChapter.scanlator, manga.title, manga.source)
if (shouldRenameChapter) {
downloadManager.renameChapter(source, manga, dbChapter.toDbChapter(), chapter.toDbChapter())
}
var toChangeChapter = dbChapter.copy(
name = chapter.name,
chapterNumber = chapter.chapterNumber,
scanlator = chapter.scanlator,
sourceOrder = chapter.sourceOrder,
)
if (chapter.dateUpload != 0L) {
toChangeChapter = toChangeChapter.copy(dateUpload = chapter.dateUpload)
}
toChange.add(toChangeChapter)
}
}
}
// Return if there's nothing to add, delete or change, avoiding unnecessary db transactions.
if (toAdd.isEmpty() && toDelete.isEmpty() && toChange.isEmpty()) {
return emptyList()
}
val reAdded = mutableListOf<Chapter>()
val deletedChapterNumbers = TreeSet<Float>()
val deletedReadChapterNumbers = TreeSet<Float>()
val deletedBookmarkedChapterNumbers = TreeSet<Float>()
toDelete.forEach { chapter ->
if (chapter.read) deletedReadChapterNumbers.add(chapter.chapterNumber)
if (chapter.bookmark) deletedBookmarkedChapterNumbers.add(chapter.chapterNumber)
deletedChapterNumbers.add(chapter.chapterNumber)
}
val deletedChapterNumberDateFetchMap = toDelete.sortedByDescending { it.dateFetch }
.associate { it.chapterNumber to it.dateFetch }
// Date fetch is set in such a way that the upper ones will have bigger value than the lower ones
// Sources MUST return the chapters from most to less recent, which is common.
var itemCount = toAdd.size
var updatedToAdd = toAdd.map { toAddItem ->
var chapter = toAddItem.copy(dateFetch = rightNow + itemCount--)
if (chapter.isRecognizedNumber.not() || chapter.chapterNumber !in deletedChapterNumbers) return@map chapter
chapter = chapter.copy(
read = chapter.chapterNumber in deletedReadChapterNumbers,
bookmark = chapter.chapterNumber in deletedBookmarkedChapterNumbers,
)
// Try to to use the fetch date of the original entry to not pollute 'Updates' tab
deletedChapterNumberDateFetchMap[chapter.chapterNumber]?.let {
chapter = chapter.copy(dateFetch = it)
}
reAdded.add(chapter)
chapter
}
if (toDelete.isNotEmpty()) {
val toDeleteIds = toDelete.map { it.id }
chapterRepository.removeChaptersWithIds(toDeleteIds)
}
if (updatedToAdd.isNotEmpty()) {
updatedToAdd = chapterRepository.addAll(updatedToAdd)
}
if (toChange.isNotEmpty()) {
val chapterUpdates = toChange.map { it.toChapterUpdate() }
updateChapter.awaitAll(chapterUpdates)
}
// Set this manga as updated since chapters were changed
// Note that last_update actually represents last time the chapter list changed at all
updateManga.awaitUpdateLastUpdate(manga.id)
val reAddedUrls = reAdded.map { it.url }.toHashSet()
return updatedToAdd.filterNot { it.url in reAddedUrls }
}
}

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