From 8a322ea28ec6e2bdf74c5603fef05b06a04944a4 Mon Sep 17 00:00:00 2001 From: Andreas Date: Fri, 16 Sep 2022 00:12:27 +0200 Subject: [PATCH] Extract source api from app module (#8014) * Extract source api from app module * Extract source online api from app module (cherry picked from commit 86fe85079413f8ed6e1109b46e6131a9b788b988) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt # core/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt # source-api/src/main/java/eu/kanade/tachiyomi/source/Source.kt # source-api/src/main/java/eu/kanade/tachiyomi/source/model/SManga.kt --- app/build.gradle.kts | 2 + .../java/eu/kanade/domain/SYDomainModule.kt | 7 ++ .../manga/interactor/GetFlatMetadataById.kt | 5 +- .../domain/manga/interactor/GetManga.kt | 9 ++- .../manga/interactor/InsertFlatMetadata.kt | 5 +- .../kanade/presentation/manga/MangaScreen.kt | 68 +++++++++++++++-- .../tachiyomi/data/backup/BackupManager.kt | 1 + .../data/database/models/MangaImpl.kt | 29 ++++++++ .../data/preference/PreferencesHelper.kt | 1 + .../tachiyomi/source/SourceExtensions.kt | 58 +++++++++++++++ .../kanade/tachiyomi/source/SourceManager.kt | 3 + .../source/model/SChapterExtensions.kt | 11 +++ .../source/model/SMangaExtensions.kt | 46 ++++++++++++ .../source/online/BrowseSourceFilterHeader.kt | 9 --- .../tachiyomi/source/online/all/EHentai.kt | 8 -- .../tachiyomi/source/online/all/Hitomi.kt | 8 -- .../tachiyomi/source/online/all/MangaDex.kt | 21 +----- .../tachiyomi/source/online/all/NHentai.kt | 8 -- .../tachiyomi/source/online/all/PervEden.kt | 8 -- .../source/online/english/EightMuses.kt | 8 -- .../source/online/english/HBrowse.kt | 8 -- .../source/online/english/Pururin.kt | 8 -- .../source/online/english/Tsumino.kt | 8 -- .../browse/source/browse/SourceFilterSheet.kt | 11 ++- .../ui/browse/source/filter/AutoComplete.kt | 4 +- .../setting/SettingsAppearanceController.kt | 1 + .../util/system/ContextExtensions.kt | 25 ------- .../util/system/DeviceUtilExtensions.kt | 8 ++ .../adapters/EHentaiDescriptionAdapter.kt | 6 +- .../adapters/EightMusesDescriptionAdapter.kt | 2 +- .../adapters/HBrowseDescriptionAdapter.kt | 2 +- .../adapters/HitomiDescriptionAdapter.kt | 4 +- .../adapters/MangaDexDescriptionAdapter.kt | 4 +- .../metadata/adapters/MetadataUIUtil.kt} | 73 +++---------------- .../adapters/NHentaiDescriptionAdapter.kt | 4 +- .../adapters/PervEdenDescriptionAdapter.kt | 7 +- .../adapters/PururinDescriptionAdapter.kt | 7 +- .../adapters/TsuminoDescriptionAdapter.kt | 7 +- app/src/main/java/exh/util/SourceTagsUtil.kt | 8 +- app/src/main/java/exh/util/String.kt | 12 --- core/.gitignore | 1 + core/build.gradle.kts | 50 +++++++++++++ core/src/main/AndroidManifest.xml | 2 + .../tachiyomi/network/AndroidCookieJar.kt | 0 .../kanade/tachiyomi/network/DohProviders.kt | 0 .../kanade/tachiyomi/network/NetworkHelper.kt | 12 +-- .../tachiyomi/network/OkHttpExtensions.kt | 0 .../tachiyomi/network/ProgressListener.kt | 0 .../tachiyomi/network/ProgressResponseBody.kt | 0 .../eu/kanade/tachiyomi/network/Requests.kt | 2 +- .../interceptor/CloudflareInterceptor.kt | 2 +- .../network/interceptor/Http103Interceptor.kt | 0 .../interceptor/RateLimitInterceptor.kt | 0 .../SpecificHostRateLimitInterceptor.kt | 0 .../interceptor/UserAgentInterceptor.kt | 0 .../network/interceptor/WebViewInterceptor.kt | 2 +- .../util/lang/CoroutinesExtensions.kt | 0 .../tachiyomi/util/lang/RxCoroutineBridge.kt | 2 + .../tachiyomi/util/system/DeviceUtil.kt | 5 -- .../tachiyomi/util/system/LogcatExtensions.kt | 0 .../tachiyomi/util/system/ToastExtensions.kt | 28 +++++++ .../util/system/WebViewClientCompat.kt | 0 .../tachiyomi/util/system/WebViewUtil.kt | 0 .../src/main/java/exh/log/EHLogLevel.kt | 5 +- .../src/main/java/exh/log/EHNetworkLogging.kt | 0 .../src/main/java/exh/log/Logging.kt | 0 .../src/main/java/exh/util/ListUtil.kt | 0 .../java/exh/util/StringBuilderExtensions.kt | 0 .../src/main/java/exh/util/StringUtil.kt | 5 ++ settings.gradle.kts | 2 + source-api/.gitignore | 1 + source-api/build.gradle.kts | 44 +++++++++++ source-api/src/main/AndroidManifest.xml | 2 + .../tachiyomi/source/CatalogueSource.kt | 0 .../tachiyomi/source/ConfigurableSource.kt | 0 .../tachiyomi/source/PagePreviewSource.kt | 0 .../java/eu/kanade/tachiyomi/source/Source.kt | 56 -------------- .../kanade/tachiyomi/source/SourceFactory.kt | 0 .../tachiyomi/source/UnmeteredSource.kt | 0 .../kanade/tachiyomi/source/model/Filter.kt | 0 .../tachiyomi/source/model/FilterList.kt | 0 .../tachiyomi/source/model/MangasPage.kt | 0 .../eu/kanade/tachiyomi/source/model/Page.kt | 0 .../kanade/tachiyomi/source/model/SChapter.kt | 9 --- .../tachiyomi/source/model/SChapterImpl.kt | 0 .../kanade/tachiyomi/source/model/SManga.kt | 56 -------------- .../tachiyomi/source/model/SMangaImpl.kt | 15 ++++ .../tachiyomi/source/online/FollowsSource.kt | 12 --- .../tachiyomi/source/online/HttpSource.kt | 8 +- .../source/online/HttpSourceFetcher.kt | 0 .../tachiyomi/source/online/LoginSource.kt | 0 .../tachiyomi/source/online/MetadataSource.kt | 22 +++--- .../source/online/NamespaceSource.kt | 0 .../source/online/ParsedHttpSource.kt | 1 + .../source/online/RandomMangaSource.kt | 0 .../source/online/UrlImportableSource.kt | 0 .../kanade/tachiyomi/util/JsoupExtensions.kt | 0 .../java/exh/md/utils/MangaDexRelation.kt | 2 +- .../main/java/exh/metadata/MetadataUtil.kt | 60 +++++++++++++++ .../metadata/EHentaiSearchMetadata.kt | 6 +- .../metadata/EightMusesSearchMetadata.kt | 2 +- .../metadata/HBrowseSearchMetadata.kt | 2 +- .../metadata/metadata/HitomiSearchMetadata.kt | 2 +- .../metadata/MangaDexSearchMetadata.kt | 9 +-- .../metadata/NHentaiSearchMetadata.kt | 2 +- .../metadata/PervEdenSearchMetadata.kt | 2 +- .../metadata/PururinSearchMetadata.kt | 2 +- .../metadata/TsuminoSearchMetadata.kt | 2 +- .../metadata/metadata/base/FlatMetadata.kt | 0 .../metadata/base/RaisedSearchMetadata.kt | 4 +- .../exh/metadata/metadata/base/RaisedTag.kt | 0 .../exh/metadata/metadata/base/RaisedTitle.kt | 0 .../exh/metadata/sql/models/SearchMetadata.kt | 0 .../java/exh/metadata/sql/models/SearchTag.kt | 0 .../exh/metadata/sql/models/SearchTitle.kt | 0 .../java/exh/source/DelegatedHttpSource.kt | 0 .../java/exh/source/EnhancedHttpSource.kt | 6 +- 117 files changed, 547 insertions(+), 422 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/source/SourceExtensions.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/source/model/SChapterExtensions.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/source/model/SMangaExtensions.kt delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/source/online/BrowseSourceFilterHeader.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/util/system/DeviceUtilExtensions.kt rename app/src/main/java/exh/{metadata/MetadataUtil.kt => ui/metadata/adapters/MetadataUIUtil.kt} (55%) mode change 100755 => 100644 delete mode 100644 app/src/main/java/exh/util/String.kt create mode 100644 core/.gitignore create mode 100644 core/build.gradle.kts create mode 100644 core/src/main/AndroidManifest.xml rename {app => core}/src/main/java/eu/kanade/tachiyomi/network/AndroidCookieJar.kt (100%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/network/DohProviders.kt (100%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt (86%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt (100%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/network/ProgressListener.kt (100%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/network/ProgressResponseBody.kt (100%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/network/Requests.kt (95%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt (99%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/network/interceptor/Http103Interceptor.kt (100%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/network/interceptor/RateLimitInterceptor.kt (100%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/network/interceptor/SpecificHostRateLimitInterceptor.kt (100%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/network/interceptor/UserAgentInterceptor.kt (100%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/network/interceptor/WebViewInterceptor.kt (98%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/util/lang/CoroutinesExtensions.kt (100%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/util/lang/RxCoroutineBridge.kt (97%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/util/system/DeviceUtil.kt (86%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/util/system/LogcatExtensions.kt (100%) create mode 100644 core/src/main/java/eu/kanade/tachiyomi/util/system/ToastExtensions.kt rename {app => core}/src/main/java/eu/kanade/tachiyomi/util/system/WebViewClientCompat.kt (100%) rename {app => core}/src/main/java/eu/kanade/tachiyomi/util/system/WebViewUtil.kt (100%) rename {app => core}/src/main/java/exh/log/EHLogLevel.kt (85%) rename {app => core}/src/main/java/exh/log/EHNetworkLogging.kt (100%) rename {app => core}/src/main/java/exh/log/Logging.kt (100%) rename {app => core}/src/main/java/exh/util/ListUtil.kt (100%) rename {app => core}/src/main/java/exh/util/StringBuilderExtensions.kt (100%) rename {app => core}/src/main/java/exh/util/StringUtil.kt (72%) create mode 100644 source-api/.gitignore create mode 100644 source-api/build.gradle.kts create mode 100644 source-api/src/main/AndroidManifest.xml rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/CatalogueSource.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/ConfigurableSource.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/PagePreviewSource.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/Source.kt (53%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/SourceFactory.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/UnmeteredSource.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/model/Filter.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/model/FilterList.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/model/MangasPage.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/model/SChapter.kt (82%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/model/SChapterImpl.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/model/SManga.kt (67%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/model/SMangaImpl.kt (53%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/online/FollowsSource.kt (61%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/online/HttpSource.kt (98%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/online/LoginSource.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/online/MetadataSource.kt (87%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/online/NamespaceSource.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/online/ParsedHttpSource.kt (99%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/online/RandomMangaSource.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/source/online/UrlImportableSource.kt (100%) rename {app => source-api}/src/main/java/eu/kanade/tachiyomi/util/JsoupExtensions.kt (100%) rename {app => source-api}/src/main/java/exh/md/utils/MangaDexRelation.kt (97%) create mode 100644 source-api/src/main/java/exh/metadata/MetadataUtil.kt rename {app => source-api}/src/main/java/exh/metadata/metadata/EHentaiSearchMetadata.kt (96%) rename {app => source-api}/src/main/java/exh/metadata/metadata/EightMusesSearchMetadata.kt (97%) rename {app => source-api}/src/main/java/exh/metadata/metadata/HBrowseSearchMetadata.kt (98%) rename {app => source-api}/src/main/java/exh/metadata/metadata/HitomiSearchMetadata.kt (98%) rename {app => source-api}/src/main/java/exh/metadata/metadata/MangaDexSearchMetadata.kt (92%) rename {app => source-api}/src/main/java/exh/metadata/metadata/NHentaiSearchMetadata.kt (99%) rename {app => source-api}/src/main/java/exh/metadata/metadata/PervEdenSearchMetadata.kt (98%) rename {app => source-api}/src/main/java/exh/metadata/metadata/PururinSearchMetadata.kt (98%) rename {app => source-api}/src/main/java/exh/metadata/metadata/TsuminoSearchMetadata.kt (98%) rename {app => source-api}/src/main/java/exh/metadata/metadata/base/FlatMetadata.kt (100%) rename {app => source-api}/src/main/java/exh/metadata/metadata/base/RaisedSearchMetadata.kt (99%) rename {app => source-api}/src/main/java/exh/metadata/metadata/base/RaisedTag.kt (100%) rename {app => source-api}/src/main/java/exh/metadata/metadata/base/RaisedTitle.kt (100%) rename {app => source-api}/src/main/java/exh/metadata/sql/models/SearchMetadata.kt (100%) rename {app => source-api}/src/main/java/exh/metadata/sql/models/SearchTag.kt (100%) rename {app => source-api}/src/main/java/exh/metadata/sql/models/SearchTitle.kt (100%) rename {app => source-api}/src/main/java/exh/source/DelegatedHttpSource.kt (100%) rename {app => source-api}/src/main/java/exh/source/EnhancedHttpSource.kt (97%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a66736471..f947bf55d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -133,6 +133,8 @@ android { dependencies { implementation(project(":i18n")) + implementation(project(":core")) + implementation(project(":source-api")) // Compose implementation(compose.activity) diff --git a/app/src/main/java/eu/kanade/domain/SYDomainModule.kt b/app/src/main/java/eu/kanade/domain/SYDomainModule.kt index bbca37b21..b4ca627de 100644 --- a/app/src/main/java/eu/kanade/domain/SYDomainModule.kt +++ b/app/src/main/java/eu/kanade/domain/SYDomainModule.kt @@ -20,6 +20,7 @@ import eu.kanade.domain.manga.interactor.GetExhFavoriteMangaWithMetadata import eu.kanade.domain.manga.interactor.GetFavoriteEntries import eu.kanade.domain.manga.interactor.GetFlatMetadataById import eu.kanade.domain.manga.interactor.GetIdsOfFavoriteMangaWithMetadata +import eu.kanade.domain.manga.interactor.GetManga import eu.kanade.domain.manga.interactor.GetMangaBySource import eu.kanade.domain.manga.interactor.GetMergedManga import eu.kanade.domain.manga.interactor.GetMergedMangaById @@ -65,6 +66,7 @@ import eu.kanade.domain.source.interactor.ToggleExcludeFromDataSaver import eu.kanade.domain.source.interactor.ToggleSources import eu.kanade.domain.source.repository.FeedSavedSearchRepository import eu.kanade.domain.source.repository.SavedSearchRepository +import eu.kanade.tachiyomi.source.online.MetadataSource import uy.kohesive.injekt.api.InjektModule import uy.kohesive.injekt.api.InjektRegistrar import uy.kohesive.injekt.api.addFactory @@ -100,6 +102,11 @@ class SYDomainModule : InjektModule { addFactory { ReorderSortTag(get(), get()) } addFactory { GetPagePreviews(get()) } + // Required for [MetadataSource] + addFactory { GetManga(get()) } + addFactory { GetFlatMetadataById(get()) } + addFactory { InsertFlatMetadata(get()) } + addSingletonFactory { MangaMetadataRepositoryImpl(get()) } addFactory { GetFlatMetadataById(get()) } addFactory { InsertFlatMetadata(get()) } diff --git a/app/src/main/java/eu/kanade/domain/manga/interactor/GetFlatMetadataById.kt b/app/src/main/java/eu/kanade/domain/manga/interactor/GetFlatMetadataById.kt index 5e07a6383..905b42911 100644 --- a/app/src/main/java/eu/kanade/domain/manga/interactor/GetFlatMetadataById.kt +++ b/app/src/main/java/eu/kanade/domain/manga/interactor/GetFlatMetadataById.kt @@ -1,6 +1,7 @@ package eu.kanade.domain.manga.interactor import eu.kanade.domain.manga.repository.MangaMetadataRepository +import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.util.system.logcat import exh.metadata.metadata.base.FlatMetadata import kotlinx.coroutines.flow.Flow @@ -9,9 +10,9 @@ import logcat.LogPriority class GetFlatMetadataById( private val mangaMetadataRepository: MangaMetadataRepository, -) { +) : MetadataSource.GetFlatMetadataById { - suspend fun await(id: Long): FlatMetadata? { + override suspend fun await(id: Long): FlatMetadata? { return try { val meta = mangaMetadataRepository.getMetadataById(id) return if (meta != null) { diff --git a/app/src/main/java/eu/kanade/domain/manga/interactor/GetManga.kt b/app/src/main/java/eu/kanade/domain/manga/interactor/GetManga.kt index e2c54b993..41352921a 100644 --- a/app/src/main/java/eu/kanade/domain/manga/interactor/GetManga.kt +++ b/app/src/main/java/eu/kanade/domain/manga/interactor/GetManga.kt @@ -2,13 +2,14 @@ package eu.kanade.domain.manga.interactor import eu.kanade.domain.manga.model.Manga import eu.kanade.domain.manga.repository.MangaRepository +import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.util.system.logcat import kotlinx.coroutines.flow.Flow import logcat.LogPriority class GetManga( private val mangaRepository: MangaRepository, -) { +) : MetadataSource.GetMangaId { suspend fun await(id: Long): Manga? { return try { @@ -30,4 +31,10 @@ class GetManga( fun subscribe(url: String, sourceId: Long): Flow { return mangaRepository.getMangaByUrlAndSourceIdAsFlow(url, sourceId) } + + // SY --> + override suspend fun awaitId(url: String, sourceId: Long): Long? { + return await(url, sourceId)?.id + } + // SY <-- } diff --git a/app/src/main/java/eu/kanade/domain/manga/interactor/InsertFlatMetadata.kt b/app/src/main/java/eu/kanade/domain/manga/interactor/InsertFlatMetadata.kt index 849f5248f..6d0968a1c 100644 --- a/app/src/main/java/eu/kanade/domain/manga/interactor/InsertFlatMetadata.kt +++ b/app/src/main/java/eu/kanade/domain/manga/interactor/InsertFlatMetadata.kt @@ -1,6 +1,7 @@ package eu.kanade.domain.manga.interactor import eu.kanade.domain.manga.repository.MangaMetadataRepository +import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.util.system.logcat import exh.metadata.metadata.base.FlatMetadata import exh.metadata.metadata.base.RaisedSearchMetadata @@ -8,7 +9,7 @@ import logcat.LogPriority class InsertFlatMetadata( private val mangaMetadataRepository: MangaMetadataRepository, -) { +) : MetadataSource.InsertFlatMetadata { suspend fun await(flatMetadata: FlatMetadata) { try { @@ -18,7 +19,7 @@ class InsertFlatMetadata( } } - suspend fun await(metadata: RaisedSearchMetadata) { + override suspend fun await(metadata: RaisedSearchMetadata) { try { mangaMetadataRepository.insertMetadata(metadata) } catch (e: Exception) { diff --git a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt index f25913f74..1acbeb43c 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt @@ -72,14 +72,33 @@ import eu.kanade.presentation.util.isScrollingUp import eu.kanade.presentation.util.plus import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.download.model.Download +import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.getNameForMangaInfo import eu.kanade.tachiyomi.source.online.MetadataSource +import eu.kanade.tachiyomi.source.online.all.EHentai +import eu.kanade.tachiyomi.source.online.all.Hitomi +import eu.kanade.tachiyomi.source.online.all.MangaDex +import eu.kanade.tachiyomi.source.online.all.NHentai +import eu.kanade.tachiyomi.source.online.all.PervEden +import eu.kanade.tachiyomi.source.online.english.EightMuses +import eu.kanade.tachiyomi.source.online.english.HBrowse +import eu.kanade.tachiyomi.source.online.english.Pururin +import eu.kanade.tachiyomi.source.online.english.Tsumino import eu.kanade.tachiyomi.ui.manga.ChapterItem import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.ui.manga.PagePreviewState import exh.source.MERGED_SOURCE_ID import exh.source.getMainSource +import exh.ui.metadata.adapters.EHentaiDescription +import exh.ui.metadata.adapters.EightMusesDescription +import exh.ui.metadata.adapters.HBrowseDescription +import exh.ui.metadata.adapters.HitomiDescription +import exh.ui.metadata.adapters.MangaDexDescription +import exh.ui.metadata.adapters.NHentaiDescription +import exh.ui.metadata.adapters.PervEdenDescription +import exh.ui.metadata.adapters.PururinDescription +import exh.ui.metadata.adapters.TsuminoDescription @Composable fun MangaScreen( @@ -255,7 +274,7 @@ private fun MangaScreenSmallImpl( val chapters = remember(state) { state.processedChapters.toList() } // SY --> - val metadataSource = remember(state.source.id) { state.source.getMainSource>() } + val metadataDescription = metadataDescription(state.source) // SY <-- val internalOnBackPressed = { @@ -408,12 +427,12 @@ private fun MangaScreenSmallImpl( } // SY --> - if (metadataSource != null) { + if (metadataDescription != null) { item( key = MangaScreenItem.METADATA_INFO, contentType = MangaScreenItem.METADATA_INFO, ) { - metadataSource.DescriptionComposable( + metadataDescription( state = state, openMetadataViewer = onMetadataViewerClicked, search = { onSearch(it, false) }, @@ -540,7 +559,7 @@ fun MangaScreenLargeImpl( val chapters = remember(state) { state.processedChapters.toList() } // SY --> - val metadataSource = remember(state.source.id) { state.source.getMainSource>() } + val metadataDescription = metadataDescription(state.source) // SY <-- val insetPadding = WindowInsets.systemBars.only(WindowInsetsSides.Horizontal).asPaddingValues() @@ -681,7 +700,7 @@ fun MangaScreenLargeImpl( // SY <-- ) // SY --> - metadataSource?.DescriptionComposable( + metadataDescription?.invoke( state = state, openMetadataViewer = onMetadataViewerClicked, search = { onSearch(it, false) }, @@ -847,3 +866,42 @@ private fun onChapterItemClick( else -> onChapterClicked(chapterItem.chapter) } } + +typealias MetadataDescriptionComposable = @Composable (state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) -> Unit + +@Composable +fun metadataDescription(source: Source): MetadataDescriptionComposable? { + val metadataSource = remember(source.id) { source.getMainSource>() } + return remember(metadataSource) { + when (metadataSource) { + is EHentai -> { state, openMetadataViewer, search -> + EHentaiDescription(state, openMetadataViewer, search) + } + is Hitomi -> { state, openMetadataViewer, _ -> + HitomiDescription(state, openMetadataViewer) + } + is MangaDex -> { state, openMetadataViewer, _ -> + MangaDexDescription(state, openMetadataViewer) + } + is NHentai -> { state, openMetadataViewer, _ -> + NHentaiDescription(state, openMetadataViewer) + } + is PervEden -> { state, openMetadataViewer, _ -> + PervEdenDescription(state, openMetadataViewer) + } + is EightMuses -> { state, openMetadataViewer, _ -> + EightMusesDescription(state, openMetadataViewer) + } + is HBrowse -> { state, openMetadataViewer, _ -> + HBrowseDescription(state, openMetadataViewer) + } + is Pururin -> { state, openMetadataViewer, _ -> + PururinDescription(state, openMetadataViewer) + } + is Tsumino -> { state, openMetadataViewer, _ -> + TsuminoDescription(state, openMetadataViewer) + } + else -> null + } + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt index 5767da850..c5e83a077 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt @@ -48,6 +48,7 @@ import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.library.CustomMangaManager import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.source.SourceManager +import eu.kanade.tachiyomi.source.model.copyFrom import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.toLong diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/MangaImpl.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/MangaImpl.kt index 930da74e2..589850d8d 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/MangaImpl.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/MangaImpl.kt @@ -1,6 +1,10 @@ package eu.kanade.tachiyomi.data.database.models +import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.library.CustomMangaManager +import eu.kanade.tachiyomi.source.model.SManga +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy open class MangaImpl : Manga { @@ -77,6 +81,19 @@ open class MangaImpl : Manga { private set var ogStatus: Int = 0 private set + + override val originalTitle: String + get() = ogTitle + override val originalAuthor: String? + get() = ogAuthor ?: author + override val originalArtist: String? + get() = ogArtist ?: artist + override val originalDescription: String? + get() = ogDesc ?: description + override val originalGenre: String? + get() = ogGenre ?: genre + override val originalStatus: Int + get() = ogStatus // SY <-- override fun equals(other: Any?): Boolean { @@ -93,6 +110,18 @@ open class MangaImpl : Manga { } // SY --> + override fun copyFrom(other: SManga) { + // EXH --> + if (other.title.isNotBlank() && originalTitle != other.title) { + val source = (this as? Manga)?.source + if (source != null) { + Injekt.get().renameMangaDir(originalTitle, other.originalTitle, source) + } + } + // EXH <-- + super.copyFrom(other) + } + companion object { private val customMangaManager: CustomMangaManager by injectLazy() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 0cc531cbd..67a41bb13 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -22,6 +22,7 @@ import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig import eu.kanade.tachiyomi.util.system.DeviceUtil import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.system.isDevFlavor +import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable import eu.kanade.tachiyomi.widget.ExtendedNavigationView import java.io.File import java.text.DateFormat diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/SourceExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/source/SourceExtensions.kt new file mode 100644 index 000000000..de32d2628 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/source/SourceExtensions.kt @@ -0,0 +1,58 @@ +package eu.kanade.tachiyomi.source + +import android.graphics.drawable.Drawable +import eu.kanade.domain.source.model.SourceData +import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.extension.ExtensionManager +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get + +fun Source.icon(): Drawable? = Injekt.get().getAppIconForSource(this) + +fun Source.getPreferenceKey(): String = "source_$id" + +fun Source.toSourceData(): SourceData = SourceData(id = id, lang = lang, name = name) + +fun Source.getNameForMangaInfo(mergeSources: List?): String { + val preferences = Injekt.get() + val enabledLanguages = preferences.enabledLanguages().get() + .filterNot { it in listOf("all", "other") } + val hasOneActiveLanguages = enabledLanguages.size == 1 + val isInEnabledLanguages = lang in enabledLanguages + return when { + // SY --> + !mergeSources.isNullOrEmpty() -> getMergedSourcesString( + mergeSources, + enabledLanguages, + hasOneActiveLanguages, + ) + // SY <-- + // For edge cases where user disables a source they got manga of in their library. + hasOneActiveLanguages && !isInEnabledLanguages -> toString() + // Hide the language tag when only one language is used. + hasOneActiveLanguages && isInEnabledLanguages -> name + else -> toString() + } +} + +// SY --> +private fun getMergedSourcesString( + mergeSources: List, + enabledLangs: List, + onlyName: Boolean, +): String { + return if (onlyName) { + mergeSources.joinToString { source -> + if (source.lang !in enabledLangs) { + source.toString() + } else { + source.name + } + } + } else { + mergeSources.joinToString() + } +} +// SY <-- + +fun Source.isLocalOrStub(): Boolean = id == LocalSource.ID || this is SourceManager.StubSource diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt b/app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt index 2b70cc3b3..440fd47c0 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt @@ -133,6 +133,7 @@ class SourceManager( val enhancedSource = EnhancedHttpSource( this, delegate.newSourceClass.constructors.find { it.parameters.size == 2 }!!.call(this, context), + ::delegateSources, ) currentDelegatedSources[enhancedSource.originalSource.id] = DelegatedSource( @@ -156,6 +157,8 @@ class SourceManager( // EXH <-- } + private fun delegateSources() = preferences.delegateSources().get() + fun get(sourceKey: Long): Source? { return sourcesMap[sourceKey] } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/model/SChapterExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/source/model/SChapterExtensions.kt new file mode 100644 index 000000000..c54f78234 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/source/model/SChapterExtensions.kt @@ -0,0 +1,11 @@ +package eu.kanade.tachiyomi.source.model + +import data.Chapters + +fun SChapter.copyFrom(other: Chapters) { + name = other.name + url = other.url + date_upload = other.date_upload + chapter_number = other.chapter_number + scanlator = other.scanlator +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/model/SMangaExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/source/model/SMangaExtensions.kt new file mode 100644 index 000000000..f719c9fbf --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/source/model/SMangaExtensions.kt @@ -0,0 +1,46 @@ +package eu.kanade.tachiyomi.source.model + +import data.Mangas +import eu.kanade.tachiyomi.data.database.models.Manga +import eu.kanade.tachiyomi.data.download.DownloadManager +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get + +fun SManga.copyFrom(other: Mangas) { + // EXH --> + if (other.title.isNotBlank() && originalTitle != other.title) { + val oldTitle = originalTitle + title = other.title + val source = (this as? Manga)?.source + if (source != null) { + Injekt.get().renameMangaDir(oldTitle, other.title, source) + } + } + // EXH <-- + + if (other.author != null) { + author = other.author + } + + if (other.artist != null) { + artist = other.artist + } + + if (other.description != null) { + description = other.description + } + + if (other.genre != null) { + genre = other.genre.joinToString(separator = ", ") + } + + if (other.thumbnail_url != null) { + thumbnail_url = other.thumbnail_url + } + + status = other.status.toInt() + + if (!initialized) { + initialized = other.initialized + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/BrowseSourceFilterHeader.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/BrowseSourceFilterHeader.kt deleted file mode 100644 index d1fd39a8a..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/BrowseSourceFilterHeader.kt +++ /dev/null @@ -1,9 +0,0 @@ -package eu.kanade.tachiyomi.source.online - -import androidx.recyclerview.widget.RecyclerView -import eu.kanade.tachiyomi.source.CatalogueSource -import eu.kanade.tachiyomi.ui.base.controller.BaseController - -interface BrowseSourceFilterHeader : CatalogueSource { - fun getFilterHeader(controller: BaseController<*>, onClick: () -> Unit): RecyclerView.Adapter<*> -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt index d84192424..3ead3d1e6 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt @@ -4,7 +4,6 @@ import android.content.Context import android.graphics.Bitmap import android.graphics.BitmapFactory import android.net.Uri -import androidx.compose.runtime.Composable import androidx.core.net.toUri import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.MangaImpl @@ -28,7 +27,6 @@ import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.source.online.NamespaceSource import eu.kanade.tachiyomi.source.online.UrlImportableSource -import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.lang.runAsObservable import eu.kanade.tachiyomi.util.lang.withIOContext @@ -51,7 +49,6 @@ import exh.metadata.metadata.base.RaisedSearchMetadata.Companion.TAG_TYPE_VIRTUA import exh.metadata.metadata.base.RaisedSearchMetadata.Companion.toGenreString import exh.metadata.metadata.base.RaisedTag import exh.ui.login.EhLoginActivity -import exh.ui.metadata.adapters.EHentaiDescription import exh.util.UriFilter import exh.util.UriGroup import exh.util.asObservableWithAsyncStacktrace @@ -1127,11 +1124,6 @@ class EHentai( return "${uri.scheme}://${uri.host}/g/${obj["gid"]!!.jsonPrimitive.int}/${obj["token"]!!.jsonPrimitive.content}/" } - @Composable - override fun DescriptionComposable(state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) { - EHentaiDescription(state, openMetadataViewer, search) - } - override suspend fun getPagePreviewList( manga: SManga, page: Int, diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/Hitomi.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/Hitomi.kt index 7bee91f62..dae8278a7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/Hitomi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/Hitomi.kt @@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.source.online.all import android.content.Context import android.net.Uri import android.os.Build -import androidx.compose.runtime.Composable import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.SManga @@ -11,13 +10,11 @@ import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.source.online.NamespaceSource import eu.kanade.tachiyomi.source.online.UrlImportableSource -import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.asJsoup import exh.metadata.metadata.HitomiSearchMetadata import exh.metadata.metadata.base.RaisedSearchMetadata import exh.metadata.metadata.base.RaisedTag import exh.source.DelegatedHttpSource -import exh.ui.metadata.adapters.HitomiDescription import exh.util.urlImportFetchSearchManga import org.jsoup.nodes.Document import java.text.SimpleDateFormat @@ -136,11 +133,6 @@ class Hitomi(delegate: HttpSource, val context: Context) : return "https://hitomi.la/manga/${uri.pathSegments[1].substringBefore('.')}.html" } - @Composable - override fun DescriptionComposable(state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) { - HitomiDescription(state, openMetadataViewer) - } - companion object { const val otherId = 2703068117101782422L private val DATE_FORMAT by lazy { diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt index c3250a8cd..1252a02cb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt @@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.source.online.all import android.content.Context import android.content.SharedPreferences import android.net.Uri -import androidx.compose.runtime.Composable import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.track.TrackManager @@ -14,7 +13,6 @@ import eu.kanade.tachiyomi.source.model.MetadataMangasPage import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga -import eu.kanade.tachiyomi.source.online.BrowseSourceFilterHeader import eu.kanade.tachiyomi.source.online.FollowsSource import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.LoginSource @@ -22,10 +20,7 @@ import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.source.online.NamespaceSource import eu.kanade.tachiyomi.source.online.RandomMangaSource import eu.kanade.tachiyomi.source.online.UrlImportableSource -import eu.kanade.tachiyomi.ui.base.controller.BaseController -import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.lang.runAsObservable -import exh.md.MangaDexFabHeaderAdapter import exh.md.dto.MangaDto import exh.md.dto.StatisticsMangaDto import exh.md.handlers.ApiMangaParser @@ -49,7 +44,6 @@ import exh.md.utils.MdLang import exh.md.utils.MdUtil import exh.metadata.metadata.MangaDexSearchMetadata import exh.source.DelegatedHttpSource -import exh.ui.metadata.adapters.MangaDexDescription import okhttp3.OkHttpClient import okhttp3.Response import rx.Observable @@ -64,7 +58,6 @@ class MangaDex(delegate: HttpSource, val context: Context) : UrlImportableSource, FollowsSource, LoginSource, - BrowseSourceFilterHeader, RandomMangaSource, NamespaceSource { override val lang: String = delegate.lang @@ -217,11 +210,6 @@ class MangaDex(delegate: HttpSource, val context: Context) : // MetadataSource methods override val metaClass: KClass = MangaDexSearchMetadata::class - @Composable - override fun DescriptionComposable(state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) { - MangaDexDescription(state, openMetadataViewer) - } - override suspend fun parseIntoMetadata(metadata: MangaDexSearchMetadata, input: Triple, StatisticsMangaDto>) { apiMangaParser.parseIntoMetadata(metadata, input.first, input.second, input.third) } @@ -272,11 +260,11 @@ class MangaDex(delegate: HttpSource, val context: Context) : return followsHandler.fetchAllFollows() } - override suspend fun updateFollowStatus(mangaID: String, followStatus: FollowStatus): Boolean { + suspend fun updateFollowStatus(mangaID: String, followStatus: FollowStatus): Boolean { return followsHandler.updateFollowStatus(mangaID, followStatus) } - override suspend fun fetchTrackingInfo(url: String): Track { + suspend fun fetchTrackingInfo(url: String): Track { return followsHandler.fetchTrackingInfo(url) } @@ -293,11 +281,6 @@ class MangaDex(delegate: HttpSource, val context: Context) : return mangaHandler.getTrackingInfo(track) } - // BrowseSourceFilterHeader method - override fun getFilterHeader(controller: BaseController<*>, onClick: () -> Unit): MangaDexFabHeaderAdapter { - return MangaDexFabHeaderAdapter(controller, this, onClick) - } - // RandomMangaSource method override suspend fun fetchRandomMangaUrl(): String { return mangaHandler.fetchRandomMangaId() diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/NHentai.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/NHentai.kt index 0ca49ec03..47be1dc9b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/NHentai.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/NHentai.kt @@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.source.online.all import android.content.Context import android.content.SharedPreferences import android.net.Uri -import androidx.compose.runtime.Composable import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.newCallWithProgress @@ -16,12 +15,10 @@ import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.source.online.NamespaceSource import eu.kanade.tachiyomi.source.online.UrlImportableSource -import eu.kanade.tachiyomi.ui.manga.MangaScreenState import exh.metadata.metadata.NHentaiSearchMetadata import exh.metadata.metadata.base.RaisedSearchMetadata import exh.metadata.metadata.base.RaisedTag import exh.source.DelegatedHttpSource -import exh.ui.metadata.adapters.NHentaiDescription import exh.util.trimOrNull import exh.util.urlImportFetchSearchManga import kotlinx.serialization.SerialName @@ -175,11 +172,6 @@ class NHentai(delegate: HttpSource, val context: Context) : return "$baseUrl/g/${uri.pathSegments[1]}/" } - @Composable - override fun DescriptionComposable(state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) { - NHentaiDescription(state, openMetadataViewer) - } - override suspend fun getPagePreviewList(manga: SManga, page: Int): PagePreviewPage { val metadata = fetchOrLoadMetadata(manga.id()) { client.newCall(mangaDetailsRequest(manga)).await() diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/PervEden.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/PervEden.kt index a41ce13f9..878447a79 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/PervEden.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/PervEden.kt @@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.source.online.all import android.content.Context import android.net.Uri -import androidx.compose.runtime.Composable import androidx.core.net.toUri import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.source.model.FilterList @@ -10,13 +9,11 @@ import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.source.online.UrlImportableSource -import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.asJsoup import exh.metadata.metadata.PervEdenSearchMetadata import exh.metadata.metadata.base.RaisedSearchMetadata import exh.metadata.metadata.base.RaisedTag import exh.source.DelegatedHttpSource -import exh.ui.metadata.adapters.PervEdenDescription import exh.util.urlImportFetchSearchManga import org.jsoup.nodes.Document import org.jsoup.nodes.Element @@ -132,9 +129,4 @@ class PervEden(delegate: HttpSource, val context: Context) : } return newUri.toString() } - - @Composable - override fun DescriptionComposable(state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) { - PervEdenDescription(state, openMetadataViewer) - } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/EightMuses.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/EightMuses.kt index 1e8174b4f..36940380a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/EightMuses.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/EightMuses.kt @@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.source.online.english import android.content.Context import android.net.Uri -import androidx.compose.runtime.Composable import androidx.core.net.toUri import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.source.model.FilterList @@ -11,12 +10,10 @@ import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.source.online.NamespaceSource import eu.kanade.tachiyomi.source.online.UrlImportableSource -import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.asJsoup import exh.metadata.metadata.EightMusesSearchMetadata import exh.metadata.metadata.base.RaisedTag import exh.source.DelegatedHttpSource -import exh.ui.metadata.adapters.EightMusesDescription import exh.util.urlImportFetchSearchManga import org.jsoup.nodes.Document import org.jsoup.nodes.Element @@ -96,9 +93,4 @@ class EightMuses(delegate: HttpSource, val context: Context) : } return "/comics/album/${path.joinToString("/")}" } - - @Composable - override fun DescriptionComposable(state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) { - EightMusesDescription(state, openMetadataViewer) - } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/HBrowse.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/HBrowse.kt index a93b60028..c3ea795e6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/HBrowse.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/HBrowse.kt @@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.source.online.english import android.content.Context import android.net.Uri -import androidx.compose.runtime.Composable import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.SManga @@ -10,12 +9,10 @@ import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.source.online.NamespaceSource import eu.kanade.tachiyomi.source.online.UrlImportableSource -import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.asJsoup import exh.metadata.metadata.HBrowseSearchMetadata import exh.metadata.metadata.base.RaisedTag import exh.source.DelegatedHttpSource -import exh.ui.metadata.adapters.HBrowseDescription import exh.util.urlImportFetchSearchManga import org.jsoup.nodes.Document import org.jsoup.nodes.Element @@ -84,9 +81,4 @@ class HBrowse(delegate: HttpSource, val context: Context) : override suspend fun mapUrlToMangaUrl(uri: Uri): String? { return uri.pathSegments.firstOrNull()?.let { "/$it/c00001/" } } - - @Composable - override fun DescriptionComposable(state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) { - HBrowseDescription(state, openMetadataViewer) - } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Pururin.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Pururin.kt index ee0f341d8..2287e614d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Pururin.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Pururin.kt @@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.source.online.english import android.content.Context import android.net.Uri -import androidx.compose.runtime.Composable import androidx.core.net.toUri import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.source.model.FilterList @@ -12,13 +11,11 @@ import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.source.online.NamespaceSource import eu.kanade.tachiyomi.source.online.UrlImportableSource -import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.asJsoup import exh.metadata.metadata.PururinSearchMetadata import exh.metadata.metadata.base.RaisedSearchMetadata import exh.metadata.metadata.base.RaisedTag import exh.source.DelegatedHttpSource -import exh.ui.metadata.adapters.PururinDescription import exh.util.dropBlank import exh.util.trimAll import exh.util.urlImportFetchSearchManga @@ -116,9 +113,4 @@ class Pururin(delegate: HttpSource, val context: Context) : override suspend fun mapUrlToMangaUrl(uri: Uri): String { return "${PururinSearchMetadata.BASE_URL}/gallery/${uri.pathSegments.getOrNull(1)}/${uri.lastPathSegment}" } - - @Composable - override fun DescriptionComposable(state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) { - PururinDescription(state, openMetadataViewer) - } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Tsumino.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Tsumino.kt index 44680216e..b53e170e5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Tsumino.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Tsumino.kt @@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.source.online.english import android.content.Context import android.net.Uri -import androidx.compose.runtime.Composable import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.MangasPage @@ -11,14 +10,12 @@ import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.source.online.NamespaceSource import eu.kanade.tachiyomi.source.online.UrlImportableSource -import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.asJsoup import exh.metadata.metadata.TsuminoSearchMetadata import exh.metadata.metadata.TsuminoSearchMetadata.Companion.TAG_TYPE_DEFAULT import exh.metadata.metadata.base.RaisedSearchMetadata.Companion.TAG_TYPE_VIRTUAL import exh.metadata.metadata.base.RaisedTag import exh.source.DelegatedHttpSource -import exh.ui.metadata.adapters.TsuminoDescription import exh.util.dropBlank import exh.util.trimAll import exh.util.urlImportFetchSearchManga @@ -141,9 +138,4 @@ class Tsumino(delegate: HttpSource, val context: Context) : val RATING_USERS_REGEX = "\\(([0-9].*) users".toRegex() val RATING_FAVORITES_REGEX = "/ ([0-9].*) favs".toRegex() } - - @Composable - override fun DescriptionComposable(state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) { - TsuminoDescription(state, openMetadataViewer) - } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceFilterSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceFilterSheet.kt index a498c27ae..129402dcd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceFilterSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceFilterSheet.kt @@ -13,10 +13,11 @@ import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.databinding.SourceFilterSheetBinding import eu.kanade.tachiyomi.source.CatalogueSource -import eu.kanade.tachiyomi.source.online.BrowseSourceFilterHeader +import eu.kanade.tachiyomi.source.online.all.MangaDex import eu.kanade.tachiyomi.ui.base.controller.BaseController import eu.kanade.tachiyomi.widget.SimpleNavigationView import eu.kanade.tachiyomi.widget.sheet.BaseBottomSheetDialog +import exh.md.MangaDexFabHeaderAdapter import exh.savedsearches.EXHSavedSearch import exh.source.getMainSource @@ -117,8 +118,12 @@ class SourceFilterSheet( recycler.adapter = ConcatAdapter( listOfNotNull( controller?.let { - source?.getMainSource() - ?.getFilterHeader(it) { dismissSheet?.invoke() } + source?.getMainSource() + ?.let { + MangaDexFabHeaderAdapter(controller, it) { + dismissSheet?.invoke() + } + } }, savedSearchesAdapter, adapter, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/filter/AutoComplete.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/filter/AutoComplete.kt index 3f972e8b3..443d62d40 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/filter/AutoComplete.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/filter/AutoComplete.kt @@ -46,7 +46,7 @@ open class AutoComplete(val filter: Filter.AutoComplete) : AbstractFlexibleItem< // select from auto complete holder.autoComplete.setOnItemClickListener { adapterView, _, chipPosition, _ -> val name = adapterView.getItemAtPosition(chipPosition) as String - if (name !in if (filter.excludePrefix != null && name.startsWith(filter.excludePrefix)) filter.skipAutoFillTags.map { filter.excludePrefix + it } else filter.skipAutoFillTags) { + if (name !in if (filter.excludePrefix != null && name.startsWith(filter.excludePrefix!!)) filter.skipAutoFillTags.map { filter.excludePrefix + it } else filter.skipAutoFillTags) { holder.autoComplete.text = null addTag(name, holder) } @@ -54,7 +54,7 @@ open class AutoComplete(val filter: Filter.AutoComplete) : AbstractFlexibleItem< // done keyboard button is pressed holder.autoComplete.setOnEditorActionListener { textView, actionId, _ -> - if (actionId == EditorInfo.IME_ACTION_DONE && textView.text.toString() !in if (filter.excludePrefix != null && textView.text.toString().startsWith(filter.excludePrefix)) filter.skipAutoFillTags.map { filter.excludePrefix + it } else filter.skipAutoFillTags) { + if (actionId == EditorInfo.IME_ACTION_DONE && textView.text.toString() !in if (filter.excludePrefix != null && textView.text.toString().startsWith(filter.excludePrefix!!)) filter.skipAutoFillTags.map { filter.excludePrefix + it } else filter.skipAutoFillTags) { textView.text = null addTag(textView.text.toString(), holder) return@setOnEditorActionListener true diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAppearanceController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAppearanceController.kt index b2f607f1a..7a19ca5a1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAppearanceController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAppearanceController.kt @@ -17,6 +17,7 @@ import eu.kanade.tachiyomi.util.preference.preferenceCategory import eu.kanade.tachiyomi.util.preference.switchPreference import eu.kanade.tachiyomi.util.preference.titleRes import eu.kanade.tachiyomi.util.system.DeviceUtil +import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable import eu.kanade.tachiyomi.util.system.isTablet import eu.kanade.tachiyomi.widget.preference.ThemesPreference import java.util.Date diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt index cb6b12483..3c3e4b847 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt @@ -24,10 +24,8 @@ import android.util.TypedValue import android.view.Display import android.view.View import android.view.WindowManager -import android.widget.Toast import androidx.annotation.AttrRes import androidx.annotation.ColorInt -import androidx.annotation.StringRes import androidx.appcompat.view.ContextThemeWrapper import androidx.core.app.NotificationCompat import androidx.core.content.ContextCompat @@ -52,29 +50,6 @@ import kotlin.math.roundToInt private const val TABLET_UI_MIN_SCREEN_WIDTH_DP = 720 -/** - * Display a toast in this context. - * - * @param resource the text resource. - * @param duration the duration of the toast. Defaults to short. - */ -fun Context.toast(@StringRes resource: Int, duration: Int = Toast.LENGTH_SHORT, block: (Toast) -> Unit = {}): Toast { - return toast(getString(resource), duration, block) -} - -/** - * Display a toast in this context. - * - * @param text the text to display. - * @param duration the duration of the toast. Defaults to short. - */ -fun Context.toast(text: String?, duration: Int = Toast.LENGTH_SHORT, block: (Toast) -> Unit = {}): Toast { - return Toast.makeText(applicationContext, text.orEmpty(), duration).also { - block(it) - it.show() - } -} - /** * Copies a string to clipboard * diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/DeviceUtilExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/system/DeviceUtilExtensions.kt new file mode 100644 index 000000000..396ba3fd7 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/util/system/DeviceUtilExtensions.kt @@ -0,0 +1,8 @@ +package eu.kanade.tachiyomi.util.system + +import android.os.Build +import com.google.android.material.color.DynamicColors + +val DeviceUtil.isDynamicColorAvailable by lazy { + DynamicColors.isDynamicColorAvailable() || (DeviceUtil.isSamsung && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) +} diff --git a/app/src/main/java/exh/ui/metadata/adapters/EHentaiDescriptionAdapter.kt b/app/src/main/java/exh/ui/metadata/adapters/EHentaiDescriptionAdapter.kt index 05f0f297f..383d22209 100644 --- a/app/src/main/java/exh/ui/metadata/adapters/EHentaiDescriptionAdapter.kt +++ b/app/src/main/java/exh/ui/metadata/adapters/EHentaiDescriptionAdapter.kt @@ -12,8 +12,8 @@ import eu.kanade.tachiyomi.databinding.DescriptionAdapterEhBinding import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.system.copyToClipboard import exh.metadata.MetadataUtil -import exh.metadata.bindDrawable import exh.metadata.metadata.EHentaiSearchMetadata +import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable @Composable fun EHentaiDescription(state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) { @@ -29,7 +29,7 @@ fun EHentaiDescription(state: MangaScreenState.Success, openMetadataViewer: () - val binding = DescriptionAdapterEhBinding.bind(it) binding.genre.text = - meta.genre?.let { MetadataUtil.getGenreAndColour(context, it) } + meta.genre?.let { MetadataUIUtil.getGenreAndColour(context, it) } ?.let { binding.genre.setBackgroundColor(it.first) it.second @@ -61,7 +61,7 @@ fun EHentaiDescription(state: MangaScreenState.Success, openMetadataViewer: () - val ratingFloat = meta.averageRating?.toFloat() binding.ratingBar.rating = ratingFloat ?: 0F @SuppressLint("SetTextI18n") - binding.rating.text = (ratingFloat ?: 0F).toString() + " - " + MetadataUtil.getRatingString(context, ratingFloat?.times(2)) + binding.rating.text = (ratingFloat ?: 0F).toString() + " - " + MetadataUIUtil.getRatingString(context, ratingFloat?.times(2)) binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp) diff --git a/app/src/main/java/exh/ui/metadata/adapters/EightMusesDescriptionAdapter.kt b/app/src/main/java/exh/ui/metadata/adapters/EightMusesDescriptionAdapter.kt index b916f576b..98772068f 100644 --- a/app/src/main/java/exh/ui/metadata/adapters/EightMusesDescriptionAdapter.kt +++ b/app/src/main/java/exh/ui/metadata/adapters/EightMusesDescriptionAdapter.kt @@ -10,8 +10,8 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.databinding.DescriptionAdapter8mBinding import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.system.copyToClipboard -import exh.metadata.bindDrawable import exh.metadata.metadata.EightMusesSearchMetadata +import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable @Composable fun EightMusesDescription(state: MangaScreenState.Success, openMetadataViewer: () -> Unit) { diff --git a/app/src/main/java/exh/ui/metadata/adapters/HBrowseDescriptionAdapter.kt b/app/src/main/java/exh/ui/metadata/adapters/HBrowseDescriptionAdapter.kt index 26f18bd73..98a367a5e 100644 --- a/app/src/main/java/exh/ui/metadata/adapters/HBrowseDescriptionAdapter.kt +++ b/app/src/main/java/exh/ui/metadata/adapters/HBrowseDescriptionAdapter.kt @@ -10,8 +10,8 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.databinding.DescriptionAdapterHbBinding import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.system.copyToClipboard -import exh.metadata.bindDrawable import exh.metadata.metadata.HBrowseSearchMetadata +import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable @Composable fun HBrowseDescription(state: MangaScreenState.Success, openMetadataViewer: () -> Unit) { diff --git a/app/src/main/java/exh/ui/metadata/adapters/HitomiDescriptionAdapter.kt b/app/src/main/java/exh/ui/metadata/adapters/HitomiDescriptionAdapter.kt index 2c26269d6..9cf65f2c4 100644 --- a/app/src/main/java/exh/ui/metadata/adapters/HitomiDescriptionAdapter.kt +++ b/app/src/main/java/exh/ui/metadata/adapters/HitomiDescriptionAdapter.kt @@ -11,8 +11,8 @@ import eu.kanade.tachiyomi.databinding.DescriptionAdapterHiBinding import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.system.copyToClipboard import exh.metadata.MetadataUtil -import exh.metadata.bindDrawable import exh.metadata.metadata.HitomiSearchMetadata +import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable import java.util.Date @Composable @@ -28,7 +28,7 @@ fun HitomiDescription(state: MangaScreenState.Success, openMetadataViewer: () -> if (meta == null || meta !is HitomiSearchMetadata) return@AndroidView val binding = DescriptionAdapterHiBinding.bind(it) - binding.genre.text = meta.genre?.let { MetadataUtil.getGenreAndColour(context, it) }?.let { + binding.genre.text = meta.genre?.let { MetadataUIUtil.getGenreAndColour(context, it) }?.let { binding.genre.setBackgroundColor(it.first) it.second } ?: meta.genre ?: context.getString(R.string.unknown) diff --git a/app/src/main/java/exh/ui/metadata/adapters/MangaDexDescriptionAdapter.kt b/app/src/main/java/exh/ui/metadata/adapters/MangaDexDescriptionAdapter.kt index ad7324d06..da2653766 100644 --- a/app/src/main/java/exh/ui/metadata/adapters/MangaDexDescriptionAdapter.kt +++ b/app/src/main/java/exh/ui/metadata/adapters/MangaDexDescriptionAdapter.kt @@ -12,9 +12,9 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.databinding.DescriptionAdapterMdBinding import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.system.copyToClipboard -import exh.metadata.MetadataUtil.getRatingString -import exh.metadata.bindDrawable import exh.metadata.metadata.MangaDexSearchMetadata +import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable +import exh.ui.metadata.adapters.MetadataUIUtil.getRatingString import kotlin.math.round @Composable diff --git a/app/src/main/java/exh/metadata/MetadataUtil.kt b/app/src/main/java/exh/ui/metadata/adapters/MetadataUIUtil.kt old mode 100755 new mode 100644 similarity index 55% rename from app/src/main/java/exh/metadata/MetadataUtil.kt rename to app/src/main/java/exh/ui/metadata/adapters/MetadataUIUtil.kt index bb82752be..42c0712bc --- a/app/src/main/java/exh/metadata/MetadataUtil.kt +++ b/app/src/main/java/exh/ui/metadata/adapters/MetadataUIUtil.kt @@ -1,72 +1,17 @@ -package exh.metadata +package exh.ui.metadata.adapters import android.content.Context import android.widget.TextView import androidx.annotation.DrawableRes import androidx.annotation.FloatRange import androidx.core.content.ContextCompat -import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.source.R import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.getResourceColor import exh.util.SourceTagsUtil -import java.text.SimpleDateFormat -import java.util.Locale -import kotlin.math.ln -import kotlin.math.pow import kotlin.math.roundToInt -/** - * Metadata utils - */ -object MetadataUtil { - fun humanReadableByteCount(bytes: Long, si: Boolean): String { - val unit = if (si) 1000 else 1024 - if (bytes < unit) return "$bytes B" - val exp = (ln(bytes.toDouble()) / ln(unit.toDouble())).toInt() - val pre = (if (si) "kMGTPE" else "KMGTPE")[exp - 1] + if (si) "" else "i" - return String.format("%.1f %sB", bytes / unit.toDouble().pow(exp.toDouble()), pre) - } - - private const val KB_FACTOR: Long = 1000 - private const val KIB_FACTOR: Long = 1024 - private const val MB_FACTOR = 1000 * KB_FACTOR - private const val MIB_FACTOR = 1024 * KIB_FACTOR - private const val GB_FACTOR = 1000 * MB_FACTOR - private const val GIB_FACTOR = 1024 * MIB_FACTOR - - fun parseHumanReadableByteCount(bytes: String): Double? { - val ret = bytes.substringBefore(' ').toDouble() - return when (bytes.substringAfter(' ')) { - "GB" -> ret * GB_FACTOR - "GiB" -> ret * GIB_FACTOR - "MB" -> ret * MB_FACTOR - "MiB" -> ret * MIB_FACTOR - "KB" -> ret * KB_FACTOR - "KiB" -> ret * KIB_FACTOR - else -> null - } - } - - val ONGOING_SUFFIX = arrayOf( - "[ongoing]", - "(ongoing)", - "{ongoing}", - "", - "ongoing", - "[incomplete]", - "(incomplete)", - "{incomplete}", - "", - "incomplete", - "[wip]", - "(wip)", - "{wip}", - "", - "wip", - ) - - val EX_DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US) - +object MetadataUIUtil { fun getRatingString(context: Context, @FloatRange(from = 0.0, to = 10.0) rating: Float? = null) = when (rating?.roundToInt()) { 0 -> R.string.rating0 1 -> R.string.rating1 @@ -103,12 +48,12 @@ object MetadataUtil { }?.let { (genreColor, stringId) -> genreColor.color to context.getString(stringId) } -} -fun TextView.bindDrawable(context: Context, @DrawableRes drawable: Int) { - ContextCompat.getDrawable(context, drawable)?.apply { - setTint(context.getResourceColor(R.attr.colorAccent)) - setBounds(0, 0, 20.dpToPx, 20.dpToPx) - setCompoundDrawables(this, null, null, null) + fun TextView.bindDrawable(context: Context, @DrawableRes drawable: Int) { + ContextCompat.getDrawable(context, drawable)?.apply { + setTint(context.getResourceColor(R.attr.colorAccent)) + setBounds(0, 0, 20.dpToPx, 20.dpToPx) + setCompoundDrawables(this, null, null, null) + } } } diff --git a/app/src/main/java/exh/ui/metadata/adapters/NHentaiDescriptionAdapter.kt b/app/src/main/java/exh/ui/metadata/adapters/NHentaiDescriptionAdapter.kt index c3eb68a08..8c389eb5f 100644 --- a/app/src/main/java/exh/ui/metadata/adapters/NHentaiDescriptionAdapter.kt +++ b/app/src/main/java/exh/ui/metadata/adapters/NHentaiDescriptionAdapter.kt @@ -12,8 +12,8 @@ import eu.kanade.tachiyomi.databinding.DescriptionAdapterNhBinding import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.system.copyToClipboard import exh.metadata.MetadataUtil -import exh.metadata.bindDrawable import exh.metadata.metadata.NHentaiSearchMetadata +import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable import java.util.Date @Composable @@ -32,7 +32,7 @@ fun NHentaiDescription(state: MangaScreenState.Success, openMetadataViewer: () - binding.genre.text = meta.tags.filter { it.namespace == NHentaiSearchMetadata.NHENTAI_CATEGORIES_NAMESPACE }.let { tags -> if (tags.isNotEmpty()) tags.joinToString(transform = { it.name }) else null }.let { categoriesString -> - categoriesString?.let { MetadataUtil.getGenreAndColour(context, it) }?.let { + categoriesString?.let { MetadataUIUtil.getGenreAndColour(context, it) }?.let { binding.genre.setBackgroundColor(it.first) it.second } ?: categoriesString ?: context.getString(R.string.unknown) diff --git a/app/src/main/java/exh/ui/metadata/adapters/PervEdenDescriptionAdapter.kt b/app/src/main/java/exh/ui/metadata/adapters/PervEdenDescriptionAdapter.kt index f5ab16cdb..0a4f5b293 100644 --- a/app/src/main/java/exh/ui/metadata/adapters/PervEdenDescriptionAdapter.kt +++ b/app/src/main/java/exh/ui/metadata/adapters/PervEdenDescriptionAdapter.kt @@ -11,9 +11,8 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.databinding.DescriptionAdapterPeBinding import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.system.copyToClipboard -import exh.metadata.MetadataUtil -import exh.metadata.bindDrawable import exh.metadata.metadata.PervEdenSearchMetadata +import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable import java.util.Locale import kotlin.math.round @@ -30,7 +29,7 @@ fun PervEdenDescription(state: MangaScreenState.Success, openMetadataViewer: () if (meta == null || meta !is PervEdenSearchMetadata) return@AndroidView val binding = DescriptionAdapterPeBinding.bind(it) - binding.genre.text = meta.genre?.let { MetadataUtil.getGenreAndColour(context, it) }?.let { + binding.genre.text = meta.genre?.let { MetadataUIUtil.getGenreAndColour(context, it) }?.let { binding.genre.setBackgroundColor(it.first) it.second } ?: meta.genre ?: context.getString(R.string.unknown) @@ -45,7 +44,7 @@ fun PervEdenDescription(state: MangaScreenState.Success, openMetadataViewer: () binding.ratingBar.rating = meta.rating ?: 0F @SuppressLint("SetTextI18n") - binding.rating.text = (round((meta.rating ?: 0F) * 100.0) / 100.0).toString() + " - " + MetadataUtil.getRatingString(context, meta.rating?.times(2)) + binding.rating.text = (round((meta.rating ?: 0F) * 100.0) / 100.0).toString() + " - " + MetadataUIUtil.getRatingString(context, meta.rating?.times(2)) binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp) diff --git a/app/src/main/java/exh/ui/metadata/adapters/PururinDescriptionAdapter.kt b/app/src/main/java/exh/ui/metadata/adapters/PururinDescriptionAdapter.kt index 29b1dc326..43801fce4 100644 --- a/app/src/main/java/exh/ui/metadata/adapters/PururinDescriptionAdapter.kt +++ b/app/src/main/java/exh/ui/metadata/adapters/PururinDescriptionAdapter.kt @@ -11,9 +11,8 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.databinding.DescriptionAdapterPuBinding import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.system.copyToClipboard -import exh.metadata.MetadataUtil -import exh.metadata.bindDrawable import exh.metadata.metadata.PururinSearchMetadata +import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable import kotlin.math.round @Composable @@ -30,7 +29,7 @@ fun PururinDescription(state: MangaScreenState.Success, openMetadataViewer: () - val binding = DescriptionAdapterPuBinding.bind(it) binding.genre.text = meta.tags.find { it.namespace == PururinSearchMetadata.TAG_NAMESPACE_CATEGORY }.let { genre -> - genre?.let { MetadataUtil.getGenreAndColour(context, it.name) }?.let { + genre?.let { MetadataUIUtil.getGenreAndColour(context, it.name) }?.let { binding.genre.setBackgroundColor(it.first) it.second } ?: genre?.name ?: context.getString(R.string.unknown) @@ -47,7 +46,7 @@ fun PururinDescription(state: MangaScreenState.Success, openMetadataViewer: () - val ratingFloat = meta.averageRating?.toFloat() binding.ratingBar.rating = ratingFloat ?: 0F @SuppressLint("SetTextI18n") - binding.rating.text = (round((ratingFloat ?: 0F) * 100.0) / 100.0).toString() + " - " + MetadataUtil.getRatingString(context, ratingFloat?.times(2)) + binding.rating.text = (round((ratingFloat ?: 0F) * 100.0) / 100.0).toString() + " - " + MetadataUIUtil.getRatingString(context, ratingFloat?.times(2)) binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp) diff --git a/app/src/main/java/exh/ui/metadata/adapters/TsuminoDescriptionAdapter.kt b/app/src/main/java/exh/ui/metadata/adapters/TsuminoDescriptionAdapter.kt index 690ae5f6e..16ef75116 100644 --- a/app/src/main/java/exh/ui/metadata/adapters/TsuminoDescriptionAdapter.kt +++ b/app/src/main/java/exh/ui/metadata/adapters/TsuminoDescriptionAdapter.kt @@ -11,9 +11,8 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.databinding.DescriptionAdapterTsBinding import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.system.copyToClipboard -import exh.metadata.MetadataUtil -import exh.metadata.bindDrawable import exh.metadata.metadata.TsuminoSearchMetadata +import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable import java.util.Date import kotlin.math.round @@ -30,7 +29,7 @@ fun TsuminoDescription(state: MangaScreenState.Success, openMetadataViewer: () - if (meta == null || meta !is TsuminoSearchMetadata) return@AndroidView val binding = DescriptionAdapterTsBinding.bind(it) - binding.genre.text = meta.category?.let { MetadataUtil.getGenreAndColour(context, it) }?.let { + binding.genre.text = meta.category?.let { MetadataUIUtil.getGenreAndColour(context, it) }?.let { binding.genre.setBackgroundColor(it.first) it.second } ?: meta.category ?: context.getString(R.string.unknown) @@ -47,7 +46,7 @@ fun TsuminoDescription(state: MangaScreenState.Success, openMetadataViewer: () - binding.ratingBar.rating = meta.averageRating ?: 0F @SuppressLint("SetTextI18n") - binding.rating.text = (round((meta.averageRating ?: 0F) * 100.0) / 100.0).toString() + " - " + MetadataUtil.getRatingString(context, meta.averageRating?.times(2)) + binding.rating.text = (round((meta.averageRating ?: 0F) * 100.0) / 100.0).toString() + " - " + MetadataUIUtil.getRatingString(context, meta.averageRating?.times(2)) binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp) diff --git a/app/src/main/java/exh/util/SourceTagsUtil.kt b/app/src/main/java/exh/util/SourceTagsUtil.kt index 17bf85308..5ccbf7747 100644 --- a/app/src/main/java/exh/util/SourceTagsUtil.kt +++ b/app/src/main/java/exh/util/SourceTagsUtil.kt @@ -34,12 +34,12 @@ object SourceTagsUtil { } if (parsed?.namespace != null) { when (sourceId) { - in hitomiSourceIds -> wrapTagHitomi(parsed.namespace, parsed.name.substringBefore('|').trim()) - in nHentaiSourceIds -> wrapTagNHentai(parsed.namespace, parsed.name.substringBefore('|').trim()) + in hitomiSourceIds -> wrapTagHitomi(parsed.namespace!!, parsed.name.substringBefore('|').trim()) + in nHentaiSourceIds -> wrapTagNHentai(parsed.namespace!!, parsed.name.substringBefore('|').trim()) in mangaDexSourceIds -> parsed.name PURURIN_SOURCE_ID -> parsed.name.substringBefore('|').trim() - TSUMINO_SOURCE_ID -> wrapTagTsumino(parsed.namespace, parsed.name.substringBefore('|').trim()) - else -> wrapTag(parsed.namespace, parsed.name.substringBefore('|').trim()) + TSUMINO_SOURCE_ID -> wrapTagTsumino(parsed.namespace!!, parsed.name.substringBefore('|').trim()) + else -> wrapTag(parsed.namespace!!, parsed.name.substringBefore('|').trim()) } } else { null diff --git a/app/src/main/java/exh/util/String.kt b/app/src/main/java/exh/util/String.kt deleted file mode 100644 index 23cf2b79d..000000000 --- a/app/src/main/java/exh/util/String.kt +++ /dev/null @@ -1,12 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package exh.util - -import java.util.Locale - -fun String.capitalize(locale: Locale = Locale.getDefault()) = - replaceFirstChar { if (it.isLowerCase()) it.titlecase(locale) else it.toString() } diff --git a/core/.gitignore b/core/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/core/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/core/build.gradle.kts b/core/build.gradle.kts new file mode 100644 index 000000000..2c50a0ca5 --- /dev/null +++ b/core/build.gradle.kts @@ -0,0 +1,50 @@ +plugins { + id("com.android.library") + kotlin("android") + kotlin("plugin.serialization") +} + +android { + namespace = "eu.kanade.tachiyomi.core" + compileSdk = AndroidConfig.compileSdk + + defaultConfig { + minSdk = AndroidConfig.minSdk + targetSdk = AndroidConfig.targetSdk + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8.toString() + } +} + +dependencies { + implementation(project(":i18n")) + + api(libs.logcat) + + api(libs.rxjava) + + api(libs.okhttp.core) + api(libs.okhttp.logging) + api(libs.okhttp.dnsoverhttps) + api(libs.okio) + + api(kotlinx.coroutines.core) + api(kotlinx.serialization.json) + + api(libs.injekt.core) + + api(libs.preferencektx) + + implementation(androidx.corektx) + + // SY --> + implementation(sylibs.xlog) + // SY <-- +} diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml new file mode 100644 index 000000000..568741e54 --- /dev/null +++ b/core/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/AndroidCookieJar.kt b/core/src/main/java/eu/kanade/tachiyomi/network/AndroidCookieJar.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/network/AndroidCookieJar.kt rename to core/src/main/java/eu/kanade/tachiyomi/network/AndroidCookieJar.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/DohProviders.kt b/core/src/main/java/eu/kanade/tachiyomi/network/DohProviders.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/network/DohProviders.kt rename to core/src/main/java/eu/kanade/tachiyomi/network/DohProviders.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt b/core/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt similarity index 86% rename from app/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt rename to core/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt index a0cb01274..0eb42e802 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt +++ b/core/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt @@ -1,22 +1,22 @@ package eu.kanade.tachiyomi.network import android.content.Context -import eu.kanade.tachiyomi.BuildConfig -import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import androidx.preference.PreferenceManager +import eu.kanade.tachiyomi.i18n.BuildConfig import eu.kanade.tachiyomi.network.interceptor.CloudflareInterceptor import eu.kanade.tachiyomi.network.interceptor.Http103Interceptor import eu.kanade.tachiyomi.network.interceptor.UserAgentInterceptor import okhttp3.Cache import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor -import uy.kohesive.injekt.injectLazy import java.io.File import java.util.concurrent.TimeUnit /* SY --> */ open /* SY <-- */ class NetworkHelper(context: Context) { - private val preferences: PreferencesHelper by injectLazy() + // TODO: Abstract preferences similar to 1.x + val preferences = PreferenceManager.getDefaultSharedPreferences(context) private val cacheDir = File(context.cacheDir, "network_cache") private val cacheSize = 5L * 1024 * 1024 // 5 MiB @@ -46,7 +46,7 @@ open /* SY <-- */ class NetworkHelper(context: Context) { builder.addNetworkInterceptor(httpLoggingInterceptor) } - when (preferences.dohProvider()) { + when (preferences.getInt("doh_provider", -1)) { PREF_DOH_CLOUDFLARE -> builder.dohCloudflare() PREF_DOH_GOOGLE -> builder.dohGoogle() PREF_DOH_ADGUARD -> builder.dohAdGuard() @@ -74,6 +74,6 @@ open /* SY <-- */ class NetworkHelper(context: Context) { } val defaultUserAgent by lazy { - preferences.defaultUserAgent().get() + preferences.getString("default_user_agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0")!! } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt b/core/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt rename to core/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/ProgressListener.kt b/core/src/main/java/eu/kanade/tachiyomi/network/ProgressListener.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/network/ProgressListener.kt rename to core/src/main/java/eu/kanade/tachiyomi/network/ProgressListener.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/ProgressResponseBody.kt b/core/src/main/java/eu/kanade/tachiyomi/network/ProgressResponseBody.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/network/ProgressResponseBody.kt rename to core/src/main/java/eu/kanade/tachiyomi/network/ProgressResponseBody.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/Requests.kt b/core/src/main/java/eu/kanade/tachiyomi/network/Requests.kt similarity index 95% rename from app/src/main/java/eu/kanade/tachiyomi/network/Requests.kt rename to core/src/main/java/eu/kanade/tachiyomi/network/Requests.kt index 694f7f47e..082543dc4 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/network/Requests.kt +++ b/core/src/main/java/eu/kanade/tachiyomi/network/Requests.kt @@ -10,7 +10,7 @@ import java.util.concurrent.TimeUnit.MINUTES private val DEFAULT_CACHE_CONTROL = CacheControl.Builder().maxAge(10, MINUTES).build() private val DEFAULT_HEADERS = Headers.Builder().build() private val DEFAULT_BODY: RequestBody = FormBody.Builder().build() -internal val CACHE_CONTROL_NO_STORE = CacheControl.Builder().noStore().build() +val CACHE_CONTROL_NO_STORE = CacheControl.Builder().noStore().build() fun GET( url: String, diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt b/core/src/main/java/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt similarity index 99% rename from app/src/main/java/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt rename to core/src/main/java/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt index 683732a74..b467beac0 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt +++ b/core/src/main/java/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt @@ -5,7 +5,7 @@ import android.content.Context import android.webkit.WebView import android.widget.Toast import androidx.core.content.ContextCompat -import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.core.R import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.util.system.WebViewClientCompat import eu.kanade.tachiyomi.util.system.isOutdated diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/interceptor/Http103Interceptor.kt b/core/src/main/java/eu/kanade/tachiyomi/network/interceptor/Http103Interceptor.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/network/interceptor/Http103Interceptor.kt rename to core/src/main/java/eu/kanade/tachiyomi/network/interceptor/Http103Interceptor.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/interceptor/RateLimitInterceptor.kt b/core/src/main/java/eu/kanade/tachiyomi/network/interceptor/RateLimitInterceptor.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/network/interceptor/RateLimitInterceptor.kt rename to core/src/main/java/eu/kanade/tachiyomi/network/interceptor/RateLimitInterceptor.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/interceptor/SpecificHostRateLimitInterceptor.kt b/core/src/main/java/eu/kanade/tachiyomi/network/interceptor/SpecificHostRateLimitInterceptor.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/network/interceptor/SpecificHostRateLimitInterceptor.kt rename to core/src/main/java/eu/kanade/tachiyomi/network/interceptor/SpecificHostRateLimitInterceptor.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/interceptor/UserAgentInterceptor.kt b/core/src/main/java/eu/kanade/tachiyomi/network/interceptor/UserAgentInterceptor.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/network/interceptor/UserAgentInterceptor.kt rename to core/src/main/java/eu/kanade/tachiyomi/network/interceptor/UserAgentInterceptor.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/interceptor/WebViewInterceptor.kt b/core/src/main/java/eu/kanade/tachiyomi/network/interceptor/WebViewInterceptor.kt similarity index 98% rename from app/src/main/java/eu/kanade/tachiyomi/network/interceptor/WebViewInterceptor.kt rename to core/src/main/java/eu/kanade/tachiyomi/network/interceptor/WebViewInterceptor.kt index 4955c47f5..13e6bdb51 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/network/interceptor/WebViewInterceptor.kt +++ b/core/src/main/java/eu/kanade/tachiyomi/network/interceptor/WebViewInterceptor.kt @@ -5,7 +5,7 @@ import android.os.Build import android.webkit.WebSettings import android.webkit.WebView import android.widget.Toast -import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.core.R import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.util.lang.launchUI import eu.kanade.tachiyomi.util.system.DeviceUtil diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/lang/CoroutinesExtensions.kt b/core/src/main/java/eu/kanade/tachiyomi/util/lang/CoroutinesExtensions.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/util/lang/CoroutinesExtensions.kt rename to core/src/main/java/eu/kanade/tachiyomi/util/lang/CoroutinesExtensions.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/lang/RxCoroutineBridge.kt b/core/src/main/java/eu/kanade/tachiyomi/util/lang/RxCoroutineBridge.kt similarity index 97% rename from app/src/main/java/eu/kanade/tachiyomi/util/lang/RxCoroutineBridge.kt rename to core/src/main/java/eu/kanade/tachiyomi/util/lang/RxCoroutineBridge.kt index ceef8a2e8..73dc7c89b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/lang/RxCoroutineBridge.kt +++ b/core/src/main/java/eu/kanade/tachiyomi/util/lang/RxCoroutineBridge.kt @@ -5,6 +5,7 @@ import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.InternalCoroutinesApi import kotlinx.coroutines.launch import kotlinx.coroutines.suspendCancellableCoroutine import rx.Emitter @@ -20,6 +21,7 @@ import kotlin.coroutines.resumeWithException suspend fun Observable.awaitSingle(): T = single().awaitOne() +@OptIn(InternalCoroutinesApi::class) private suspend fun Observable.awaitOne(): T = suspendCancellableCoroutine { cont -> cont.unsubscribeOnCancellation( subscribe( diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/DeviceUtil.kt b/core/src/main/java/eu/kanade/tachiyomi/util/system/DeviceUtil.kt similarity index 86% rename from app/src/main/java/eu/kanade/tachiyomi/util/system/DeviceUtil.kt rename to core/src/main/java/eu/kanade/tachiyomi/util/system/DeviceUtil.kt index 3da54c1eb..def364682 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/system/DeviceUtil.kt +++ b/core/src/main/java/eu/kanade/tachiyomi/util/system/DeviceUtil.kt @@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.util.system import android.annotation.SuppressLint import android.os.Build -import com.google.android.material.color.DynamicColors import logcat.LogPriority object DeviceUtil { @@ -31,10 +30,6 @@ object DeviceUtil { Build.MANUFACTURER.equals("samsung", ignoreCase = true) } - val isDynamicColorAvailable by lazy { - DynamicColors.isDynamicColorAvailable() || (isSamsung && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) - } - val invalidDefaultBrowsers = listOf("android", "com.huawei.android.internal.app") @SuppressLint("PrivateApi") diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/LogcatExtensions.kt b/core/src/main/java/eu/kanade/tachiyomi/util/system/LogcatExtensions.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/util/system/LogcatExtensions.kt rename to core/src/main/java/eu/kanade/tachiyomi/util/system/LogcatExtensions.kt diff --git a/core/src/main/java/eu/kanade/tachiyomi/util/system/ToastExtensions.kt b/core/src/main/java/eu/kanade/tachiyomi/util/system/ToastExtensions.kt new file mode 100644 index 000000000..4901e7463 --- /dev/null +++ b/core/src/main/java/eu/kanade/tachiyomi/util/system/ToastExtensions.kt @@ -0,0 +1,28 @@ +package eu.kanade.tachiyomi.util.system + +import android.content.Context +import android.widget.Toast +import androidx.annotation.StringRes + +/** + * Display a toast in this context. + * + * @param resource the text resource. + * @param duration the duration of the toast. Defaults to short. + */ +fun Context.toast(@StringRes resource: Int, duration: Int = Toast.LENGTH_SHORT, block: (Toast) -> Unit = {}): Toast { + return toast(getString(resource), duration, block) +} + +/** + * Display a toast in this context. + * + * @param text the text to display. + * @param duration the duration of the toast. Defaults to short. + */ +fun Context.toast(text: String?, duration: Int = Toast.LENGTH_SHORT, block: (Toast) -> Unit = {}): Toast { + return Toast.makeText(applicationContext, text.orEmpty(), duration).also { + block(it) + it.show() + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/WebViewClientCompat.kt b/core/src/main/java/eu/kanade/tachiyomi/util/system/WebViewClientCompat.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/util/system/WebViewClientCompat.kt rename to core/src/main/java/eu/kanade/tachiyomi/util/system/WebViewClientCompat.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/WebViewUtil.kt b/core/src/main/java/eu/kanade/tachiyomi/util/system/WebViewUtil.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/util/system/WebViewUtil.kt rename to core/src/main/java/eu/kanade/tachiyomi/util/system/WebViewUtil.kt diff --git a/app/src/main/java/exh/log/EHLogLevel.kt b/core/src/main/java/exh/log/EHLogLevel.kt similarity index 85% rename from app/src/main/java/exh/log/EHLogLevel.kt rename to core/src/main/java/exh/log/EHLogLevel.kt index 6051a4ba3..3f591b838 100644 --- a/app/src/main/java/exh/log/EHLogLevel.kt +++ b/core/src/main/java/exh/log/EHLogLevel.kt @@ -3,8 +3,7 @@ package exh.log import android.content.Context import androidx.annotation.StringRes import androidx.preference.PreferenceManager -import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.preference.PreferenceKeys +import eu.kanade.tachiyomi.core.R enum class EHLogLevel(@StringRes val nameRes: Int, @StringRes val description: Int) { MINIMAL(R.string.log_minimal, R.string.log_minimal_desc), @@ -19,7 +18,7 @@ enum class EHLogLevel(@StringRes val nameRes: Int, @StringRes val description: I fun init(context: Context) { curLogLevel = PreferenceManager.getDefaultSharedPreferences(context) - .getInt(PreferenceKeys.eh_logLevel, 0) + .getInt("eh_log_level", 0) // todo } fun shouldLog(requiredLogLevel: EHLogLevel): Boolean { diff --git a/app/src/main/java/exh/log/EHNetworkLogging.kt b/core/src/main/java/exh/log/EHNetworkLogging.kt similarity index 100% rename from app/src/main/java/exh/log/EHNetworkLogging.kt rename to core/src/main/java/exh/log/EHNetworkLogging.kt diff --git a/app/src/main/java/exh/log/Logging.kt b/core/src/main/java/exh/log/Logging.kt similarity index 100% rename from app/src/main/java/exh/log/Logging.kt rename to core/src/main/java/exh/log/Logging.kt diff --git a/app/src/main/java/exh/util/ListUtil.kt b/core/src/main/java/exh/util/ListUtil.kt similarity index 100% rename from app/src/main/java/exh/util/ListUtil.kt rename to core/src/main/java/exh/util/ListUtil.kt diff --git a/app/src/main/java/exh/util/StringBuilderExtensions.kt b/core/src/main/java/exh/util/StringBuilderExtensions.kt similarity index 100% rename from app/src/main/java/exh/util/StringBuilderExtensions.kt rename to core/src/main/java/exh/util/StringBuilderExtensions.kt diff --git a/app/src/main/java/exh/util/StringUtil.kt b/core/src/main/java/exh/util/StringUtil.kt similarity index 72% rename from app/src/main/java/exh/util/StringUtil.kt rename to core/src/main/java/exh/util/StringUtil.kt index a0d5cbea2..143c8b240 100644 --- a/app/src/main/java/exh/util/StringUtil.kt +++ b/core/src/main/java/exh/util/StringUtil.kt @@ -1,5 +1,7 @@ package exh.util +import java.util.Locale + fun Collection.trimAll() = map { it.trim() } fun Collection.dropBlank() = filter { it.isNotBlank() } fun Collection.dropEmpty() = filter { it.isNotEmpty() } @@ -13,3 +15,6 @@ fun String.removeArticles(): String { fun String.trimOrNull() = trim().nullIfBlank() fun String.nullIfBlank(): String? = ifBlank { null } + +fun String.capitalize(locale: Locale = Locale.getDefault()) = + replaceFirstChar { if (it.isLowerCase()) it.titlecase(locale) else it.toString() } diff --git a/settings.gradle.kts b/settings.gradle.kts index d0ee80cf3..cb0b42de1 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -40,3 +40,5 @@ dependencyResolutionManagement { rootProject.name = "TachiyomiSY" include(":app") include(":i18n") +include(":source-api") +include(":core") diff --git a/source-api/.gitignore b/source-api/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/source-api/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/source-api/build.gradle.kts b/source-api/build.gradle.kts new file mode 100644 index 000000000..eeb23edb7 --- /dev/null +++ b/source-api/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + id("com.android.library") + kotlin("android") + kotlin("plugin.serialization") +} + +android { + namespace = "eu.kanade.tachiyomi.source" + compileSdk = AndroidConfig.compileSdk + + defaultConfig { + minSdk = AndroidConfig.minSdk + targetSdk = AndroidConfig.targetSdk + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8.toString() + } +} + +dependencies { + + implementation(project(":core")) + + api(kotlinx.serialization.json) + + api(libs.rxjava) + + api(libs.preferencektx) + + api(libs.jsoup) + + implementation(androidx.corektx) + + // SY --> + implementation(project(":i18n")) + implementation(kotlinx.reflect) + // SY <-- +} diff --git a/source-api/src/main/AndroidManifest.xml b/source-api/src/main/AndroidManifest.xml new file mode 100644 index 000000000..568741e54 --- /dev/null +++ b/source-api/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/CatalogueSource.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/CatalogueSource.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/CatalogueSource.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/CatalogueSource.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/ConfigurableSource.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/ConfigurableSource.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/ConfigurableSource.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/ConfigurableSource.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/PagePreviewSource.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/PagePreviewSource.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/PagePreviewSource.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/PagePreviewSource.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/Source.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/Source.kt similarity index 53% rename from app/src/main/java/eu/kanade/tachiyomi/source/Source.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/Source.kt index a7f51df6d..32dccbb73 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/source/Source.kt +++ b/source-api/src/main/java/eu/kanade/tachiyomi/source/Source.kt @@ -1,16 +1,10 @@ package eu.kanade.tachiyomi.source -import android.graphics.drawable.Drawable -import eu.kanade.domain.source.model.SourceData -import eu.kanade.tachiyomi.data.preference.PreferencesHelper -import eu.kanade.tachiyomi.extension.ExtensionManager import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.util.lang.awaitSingle import rx.Observable -import uy.kohesive.injekt.Injekt -import uy.kohesive.injekt.api.get /** * A basic interface for creating a source. It could be an online source, a local source, etc... @@ -88,53 +82,3 @@ interface Source { return fetchPageList(chapter).awaitSingle() } } - -fun Source.icon(): Drawable? = Injekt.get().getAppIconForSource(this) - -fun Source.getPreferenceKey(): String = "source_$id" - -fun Source.toSourceData(): SourceData = SourceData(id = id, lang = lang, name = name) - -fun Source.getNameForMangaInfo(mergeSources: List?): String { - val preferences = Injekt.get() - val enabledLanguages = preferences.enabledLanguages().get() - .filterNot { it in listOf("all", "other") } - val hasOneActiveLanguages = enabledLanguages.size == 1 - val isInEnabledLanguages = lang in enabledLanguages - return when { - // SY --> - !mergeSources.isNullOrEmpty() -> getMergedSourcesString( - mergeSources, - enabledLanguages, - hasOneActiveLanguages, - ) - // SY <-- - // For edge cases where user disables a source they got manga of in their library. - hasOneActiveLanguages && !isInEnabledLanguages -> toString() - // Hide the language tag when only one language is used. - hasOneActiveLanguages && isInEnabledLanguages -> name - else -> toString() - } -} - -// SY --> -private fun getMergedSourcesString( - mergeSources: List, - enabledLangs: List, - onlyName: Boolean, -): String { - return if (onlyName) { - mergeSources.joinToString { source -> - if (source.lang !in enabledLangs) { - source.toString() - } else { - source.name - } - } - } else { - mergeSources.joinToString() - } -} -// SY <-- - -fun Source.isLocalOrStub(): Boolean = id == LocalSource.ID || this is SourceManager.StubSource diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/SourceFactory.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/SourceFactory.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/SourceFactory.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/SourceFactory.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/UnmeteredSource.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/UnmeteredSource.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/UnmeteredSource.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/UnmeteredSource.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/model/Filter.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/model/Filter.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/model/Filter.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/model/Filter.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/model/FilterList.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/model/FilterList.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/model/FilterList.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/model/FilterList.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/model/MangasPage.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/model/MangasPage.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/model/MangasPage.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/model/MangasPage.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/model/SChapter.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/model/SChapter.kt similarity index 82% rename from app/src/main/java/eu/kanade/tachiyomi/source/model/SChapter.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/model/SChapter.kt index 6a0aa9b51..f6fafe53b 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/source/model/SChapter.kt +++ b/source-api/src/main/java/eu/kanade/tachiyomi/source/model/SChapter.kt @@ -1,6 +1,5 @@ package eu.kanade.tachiyomi.source.model -import data.Chapters import java.io.Serializable interface SChapter : Serializable { @@ -23,14 +22,6 @@ interface SChapter : Serializable { scanlator = other.scanlator } - fun copyFrom(other: Chapters) { - name = other.name - url = other.url - date_upload = other.date_upload - chapter_number = other.chapter_number - scanlator = other.scanlator - } - companion object { fun create(): SChapter { return SChapterImpl() diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/model/SChapterImpl.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/model/SChapterImpl.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/model/SChapterImpl.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/model/SChapterImpl.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/model/SManga.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/model/SManga.kt similarity index 67% rename from app/src/main/java/eu/kanade/tachiyomi/source/model/SManga.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/model/SManga.kt index e9a1f0672..671f04afd 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/source/model/SManga.kt +++ b/source-api/src/main/java/eu/kanade/tachiyomi/source/model/SManga.kt @@ -1,11 +1,5 @@ package eu.kanade.tachiyomi.source.model -import data.Mangas -import eu.kanade.tachiyomi.data.database.models.Manga -import eu.kanade.tachiyomi.data.database.models.MangaImpl -import eu.kanade.tachiyomi.data.download.DownloadManager -import uy.kohesive.injekt.Injekt -import uy.kohesive.injekt.api.get import java.io.Serializable interface SManga : Serializable { @@ -35,28 +29,17 @@ interface SManga : Serializable { // SY --> val originalTitle: String - get() = (this as? MangaImpl)?.ogTitle ?: title val originalAuthor: String? - get() = (this as? MangaImpl)?.ogAuthor ?: author val originalArtist: String? - get() = (this as? MangaImpl)?.ogArtist ?: artist val originalDescription: String? - get() = (this as? MangaImpl)?.ogDesc ?: description val originalGenre: String? - get() = (this as? MangaImpl)?.ogGenre ?: genre val originalStatus: Int - get() = (this as? MangaImpl)?.ogStatus ?: status // SY <-- fun copyFrom(other: SManga) { // EXH --> if (other.title.isNotBlank() && originalTitle != other.title) { - val oldTitle = originalTitle title = other.originalTitle - val source = (this as? Manga)?.source - if (source != null) { - Injekt.get().renameMangaDir(oldTitle, other.originalTitle, source) - } } // EXH <-- @@ -87,45 +70,6 @@ interface SManga : Serializable { } } - fun copyFrom(other: Mangas) { - // EXH --> - if (other.title.isNotBlank() && originalTitle != other.title) { - val oldTitle = originalTitle - title = other.title - val source = (this as? Manga)?.source - if (source != null) { - Injekt.get().renameMangaDir(oldTitle, other.title, source) - } - } - // EXH <-- - - if (other.author != null) { - author = other.author - } - - if (other.artist != null) { - artist = other.artist - } - - if (other.description != null) { - description = other.description - } - - if (other.genre != null) { - genre = other.genre.joinToString(separator = ", ") - } - - if (other.thumbnail_url != null) { - thumbnail_url = other.thumbnail_url - } - - status = other.status.toInt() - - if (!initialized) { - initialized = other.initialized - } - } - fun copy() = create().also { it.url = url // SY --> diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/model/SMangaImpl.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/model/SMangaImpl.kt similarity index 53% rename from app/src/main/java/eu/kanade/tachiyomi/source/model/SMangaImpl.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/model/SMangaImpl.kt index efa59243a..4791ef12f 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/source/model/SMangaImpl.kt +++ b/source-api/src/main/java/eu/kanade/tachiyomi/source/model/SMangaImpl.kt @@ -21,4 +21,19 @@ class SMangaImpl : SManga { override var thumbnail_url: String? = null override var initialized: Boolean = false + + // SY --> + override val originalTitle: String + get() = title + override val originalAuthor: String? + get() = author + override val originalArtist: String? + get() = artist + override val originalDescription: String? + get() = description + override val originalGenre: String? + get() = genre + override val originalStatus: Int + get() = status + // SY <-- } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/FollowsSource.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/online/FollowsSource.kt similarity index 61% rename from app/src/main/java/eu/kanade/tachiyomi/source/online/FollowsSource.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/online/FollowsSource.kt index 191038549..b3b32c2db 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/FollowsSource.kt +++ b/source-api/src/main/java/eu/kanade/tachiyomi/source/online/FollowsSource.kt @@ -1,10 +1,8 @@ package eu.kanade.tachiyomi.source.online -import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.SManga -import exh.md.utils.FollowStatus import exh.metadata.metadata.base.RaisedSearchMetadata interface FollowsSource : CatalogueSource { @@ -16,14 +14,4 @@ interface FollowsSource : CatalogueSource { * @param SManga all smanga found for user */ suspend fun fetchAllFollows(): List> - - /** - * updates the follow status for a manga - */ - suspend fun updateFollowStatus(mangaID: String, followStatus: FollowStatus): Boolean - - /** - * Get a MdList Track of the manga - */ - suspend fun fetchTrackingInfo(url: String): Track } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/HttpSource.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/online/HttpSource.kt similarity index 98% rename from app/src/main/java/eu/kanade/tachiyomi/source/online/HttpSource.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/online/HttpSource.kt index 20676e7a9..9ede350b1 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/HttpSource.kt +++ b/source-api/src/main/java/eu/kanade/tachiyomi/source/online/HttpSource.kt @@ -1,7 +1,6 @@ package eu.kanade.tachiyomi.source.online import android.app.Application -import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.network.AndroidCookieJar import eu.kanade.tachiyomi.network.CACHE_CONTROL_NO_STORE import eu.kanade.tachiyomi.network.GET @@ -15,7 +14,6 @@ import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga import exh.log.maybeInjectEHLogger -import exh.patch.injectPatches import exh.source.DelegatedHttpSource import okhttp3.Headers import okhttp3.OkHttpClient @@ -43,14 +41,14 @@ abstract class HttpSource : CatalogueSource { override val client: OkHttpClient get() = delegate?.networkHttpClient ?: network.client .newBuilder() - .injectPatches { id } + //.injectPatches { id } todo .maybeInjectEHLogger() .build() override val cloudflareClient: OkHttpClient get() = delegate?.networkCloudflareClient ?: network.cloudflareClient .newBuilder() - .injectPatches { id } + //.injectPatches { id } todo .maybeInjectEHLogger() .build() @@ -411,7 +409,7 @@ abstract class HttpSource : CatalogueSource { // EXH --> private var delegate: DelegatedHttpSource? = null - get() = if (Injekt.get().delegateSources().get()) { + get() = if (Injekt.get().preferences.getBoolean("eh_delegate_sources", true)) { // todo field } else { null diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/LoginSource.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/online/LoginSource.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/online/LoginSource.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/online/LoginSource.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/MetadataSource.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/online/MetadataSource.kt similarity index 87% rename from app/src/main/java/eu/kanade/tachiyomi/source/online/MetadataSource.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/online/MetadataSource.kt index 9fe453fb5..6585bab97 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/MetadataSource.kt +++ b/source-api/src/main/java/eu/kanade/tachiyomi/source/online/MetadataSource.kt @@ -1,14 +1,10 @@ package eu.kanade.tachiyomi.source.online -import androidx.compose.runtime.Composable -import eu.kanade.domain.manga.interactor.GetFlatMetadataById -import eu.kanade.domain.manga.interactor.GetManga -import eu.kanade.domain.manga.interactor.InsertFlatMetadata import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.model.SManga -import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.util.lang.awaitSingle import eu.kanade.tachiyomi.util.lang.runAsObservable +import exh.metadata.metadata.base.FlatMetadata import exh.metadata.metadata.base.RaisedSearchMetadata import rx.Completable import rx.Single @@ -20,7 +16,16 @@ import kotlin.reflect.KClass * LEWD! */ interface MetadataSource : CatalogueSource { - val getManga: GetManga get() = Injekt.get() + interface GetMangaId { + suspend fun awaitId(url: String, sourceId: Long): Long? + } + interface InsertFlatMetadata { + suspend fun await(metadata: RaisedSearchMetadata) + } + interface GetFlatMetadataById { + suspend fun await(id: Long): FlatMetadata? + } + val getMangaId: GetMangaId get() = Injekt.get() val insertFlatMetadata: InsertFlatMetadata get() = Injekt.get() val getFlatMetadataById: GetFlatMetadataById get() = Injekt.get() @@ -111,8 +116,5 @@ interface MetadataSource : CatalogueSource { } } - @Composable - fun DescriptionComposable(state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) - - suspend fun SManga.id() = getManga.await(url, id)?.id + suspend fun SManga.id() = getMangaId.awaitId(url, id) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/NamespaceSource.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/online/NamespaceSource.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/online/NamespaceSource.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/online/NamespaceSource.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/ParsedHttpSource.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/online/ParsedHttpSource.kt similarity index 99% rename from app/src/main/java/eu/kanade/tachiyomi/source/online/ParsedHttpSource.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/online/ParsedHttpSource.kt index 941a3167a..34376f847 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/ParsedHttpSource.kt +++ b/source-api/src/main/java/eu/kanade/tachiyomi/source/online/ParsedHttpSource.kt @@ -12,6 +12,7 @@ import org.jsoup.nodes.Element /** * A simple implementation for sources from a website using Jsoup, an HTML parser. */ +@Suppress("unused") abstract class ParsedHttpSource : HttpSource() { /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/RandomMangaSource.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/online/RandomMangaSource.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/online/RandomMangaSource.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/online/RandomMangaSource.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/UrlImportableSource.kt b/source-api/src/main/java/eu/kanade/tachiyomi/source/online/UrlImportableSource.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/source/online/UrlImportableSource.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/source/online/UrlImportableSource.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/JsoupExtensions.kt b/source-api/src/main/java/eu/kanade/tachiyomi/util/JsoupExtensions.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/util/JsoupExtensions.kt rename to source-api/src/main/java/eu/kanade/tachiyomi/util/JsoupExtensions.kt diff --git a/app/src/main/java/exh/md/utils/MangaDexRelation.kt b/source-api/src/main/java/exh/md/utils/MangaDexRelation.kt similarity index 97% rename from app/src/main/java/exh/md/utils/MangaDexRelation.kt rename to source-api/src/main/java/exh/md/utils/MangaDexRelation.kt index 12a9ee64c..a56700c1b 100644 --- a/app/src/main/java/exh/md/utils/MangaDexRelation.kt +++ b/source-api/src/main/java/exh/md/utils/MangaDexRelation.kt @@ -1,7 +1,7 @@ package exh.md.utils import androidx.annotation.StringRes -import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.source.R enum class MangaDexRelation(@StringRes val resId: Int, val mdString: String?) { SIMILAR(R.string.relation_similar, null), diff --git a/source-api/src/main/java/exh/metadata/MetadataUtil.kt b/source-api/src/main/java/exh/metadata/MetadataUtil.kt new file mode 100644 index 000000000..38b5307f0 --- /dev/null +++ b/source-api/src/main/java/exh/metadata/MetadataUtil.kt @@ -0,0 +1,60 @@ +package exh.metadata + +import java.text.SimpleDateFormat +import java.util.Locale +import kotlin.math.ln +import kotlin.math.pow + +/** + * Metadata utils + */ +object MetadataUtil { + fun humanReadableByteCount(bytes: Long, si: Boolean): String { + val unit = if (si) 1000 else 1024 + if (bytes < unit) return "$bytes B" + val exp = (ln(bytes.toDouble()) / ln(unit.toDouble())).toInt() + val pre = (if (si) "kMGTPE" else "KMGTPE")[exp - 1] + if (si) "" else "i" + return String.format("%.1f %sB", bytes / unit.toDouble().pow(exp.toDouble()), pre) + } + + private const val KB_FACTOR: Long = 1000 + private const val KIB_FACTOR: Long = 1024 + private const val MB_FACTOR = 1000 * KB_FACTOR + private const val MIB_FACTOR = 1024 * KIB_FACTOR + private const val GB_FACTOR = 1000 * MB_FACTOR + private const val GIB_FACTOR = 1024 * MIB_FACTOR + + fun parseHumanReadableByteCount(bytes: String): Double? { + val ret = bytes.substringBefore(' ').toDouble() + return when (bytes.substringAfter(' ')) { + "GB" -> ret * GB_FACTOR + "GiB" -> ret * GIB_FACTOR + "MB" -> ret * MB_FACTOR + "MiB" -> ret * MIB_FACTOR + "KB" -> ret * KB_FACTOR + "KiB" -> ret * KIB_FACTOR + else -> null + } + } + + val ONGOING_SUFFIX = arrayOf( + "[ongoing]", + "(ongoing)", + "{ongoing}", + "", + "ongoing", + "[incomplete]", + "(incomplete)", + "{incomplete}", + "", + "incomplete", + "[wip]", + "(wip)", + "{wip}", + "", + "wip", + ) + + val EX_DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US) +} + diff --git a/app/src/main/java/exh/metadata/metadata/EHentaiSearchMetadata.kt b/source-api/src/main/java/exh/metadata/metadata/EHentaiSearchMetadata.kt similarity index 96% rename from app/src/main/java/exh/metadata/metadata/EHentaiSearchMetadata.kt rename to source-api/src/main/java/exh/metadata/metadata/EHentaiSearchMetadata.kt index 7ffa46801..a619cfefd 100644 --- a/app/src/main/java/exh/metadata/metadata/EHentaiSearchMetadata.kt +++ b/source-api/src/main/java/exh/metadata/metadata/EHentaiSearchMetadata.kt @@ -2,8 +2,8 @@ package exh.metadata.metadata import android.content.Context import androidx.core.net.toUri -import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.network.NetworkHelper +import eu.kanade.tachiyomi.source.R import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.copy import exh.metadata.MetadataUtil @@ -53,7 +53,7 @@ class EHentaiSearchMetadata : RaisedSearchMetadata() { // No title bug? val title = altTitle - ?.takeIf { Injekt.get().useJapaneseTitle().get() } + ?.takeIf { Injekt.get().preferences.getBoolean("use_jp_title", false) } // todo ?: title // Set artist (if we can find one) diff --git a/app/src/main/java/exh/metadata/metadata/EightMusesSearchMetadata.kt b/source-api/src/main/java/exh/metadata/metadata/EightMusesSearchMetadata.kt similarity index 97% rename from app/src/main/java/exh/metadata/metadata/EightMusesSearchMetadata.kt rename to source-api/src/main/java/exh/metadata/metadata/EightMusesSearchMetadata.kt index 51f7a8f6d..37609dd31 100644 --- a/app/src/main/java/exh/metadata/metadata/EightMusesSearchMetadata.kt +++ b/source-api/src/main/java/exh/metadata/metadata/EightMusesSearchMetadata.kt @@ -1,7 +1,7 @@ package exh.metadata.metadata import android.content.Context -import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.source.R import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.copy import exh.metadata.metadata.base.RaisedSearchMetadata diff --git a/app/src/main/java/exh/metadata/metadata/HBrowseSearchMetadata.kt b/source-api/src/main/java/exh/metadata/metadata/HBrowseSearchMetadata.kt similarity index 98% rename from app/src/main/java/exh/metadata/metadata/HBrowseSearchMetadata.kt rename to source-api/src/main/java/exh/metadata/metadata/HBrowseSearchMetadata.kt index f217d818f..bf6bc8820 100644 --- a/app/src/main/java/exh/metadata/metadata/HBrowseSearchMetadata.kt +++ b/source-api/src/main/java/exh/metadata/metadata/HBrowseSearchMetadata.kt @@ -1,7 +1,7 @@ package exh.metadata.metadata import android.content.Context -import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.source.R import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.copy import exh.metadata.metadata.base.RaisedSearchMetadata diff --git a/app/src/main/java/exh/metadata/metadata/HitomiSearchMetadata.kt b/source-api/src/main/java/exh/metadata/metadata/HitomiSearchMetadata.kt similarity index 98% rename from app/src/main/java/exh/metadata/metadata/HitomiSearchMetadata.kt rename to source-api/src/main/java/exh/metadata/metadata/HitomiSearchMetadata.kt index 8d018a8cf..c92fac0a7 100644 --- a/app/src/main/java/exh/metadata/metadata/HitomiSearchMetadata.kt +++ b/source-api/src/main/java/exh/metadata/metadata/HitomiSearchMetadata.kt @@ -1,7 +1,7 @@ package exh.metadata.metadata import android.content.Context -import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.source.R import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.copy import exh.metadata.MetadataUtil diff --git a/app/src/main/java/exh/metadata/metadata/MangaDexSearchMetadata.kt b/source-api/src/main/java/exh/metadata/metadata/MangaDexSearchMetadata.kt similarity index 92% rename from app/src/main/java/exh/metadata/metadata/MangaDexSearchMetadata.kt rename to source-api/src/main/java/exh/metadata/metadata/MangaDexSearchMetadata.kt index c02865ae8..310bc2891 100644 --- a/app/src/main/java/exh/metadata/metadata/MangaDexSearchMetadata.kt +++ b/source-api/src/main/java/exh/metadata/metadata/MangaDexSearchMetadata.kt @@ -1,11 +1,10 @@ package exh.metadata.metadata import android.content.Context -import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.source.R import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.copy import exh.md.utils.MangaDexRelation -import exh.md.utils.MdUtil import exh.metadata.metadata.base.RaisedSearchMetadata import kotlinx.serialization.Serializable @@ -47,15 +46,15 @@ class MangaDexSearchMetadata : RaisedSearchMetadata() { // var maxChapterNumber: Int? = null override fun createMangaInfo(manga: SManga): SManga { - val key = mdUuid?.let { MdUtil.buildMangaUrl(it) } + val key = mdUuid?.let { "/manga/$it" } val title = title val cover = cover - val author = authors?.joinToString()?.let { MdUtil.cleanString(it) } + val author = authors?.joinToString() - val artist = artists?.joinToString()?.let { MdUtil.cleanString(it) } + val artist = artists?.joinToString() val status = status diff --git a/app/src/main/java/exh/metadata/metadata/NHentaiSearchMetadata.kt b/source-api/src/main/java/exh/metadata/metadata/NHentaiSearchMetadata.kt similarity index 99% rename from app/src/main/java/exh/metadata/metadata/NHentaiSearchMetadata.kt rename to source-api/src/main/java/exh/metadata/metadata/NHentaiSearchMetadata.kt index 30a735327..f4fc2b043 100644 --- a/app/src/main/java/exh/metadata/metadata/NHentaiSearchMetadata.kt +++ b/source-api/src/main/java/exh/metadata/metadata/NHentaiSearchMetadata.kt @@ -1,7 +1,7 @@ package exh.metadata.metadata import android.content.Context -import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.source.R import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.copy import exh.metadata.MetadataUtil diff --git a/app/src/main/java/exh/metadata/metadata/PervEdenSearchMetadata.kt b/source-api/src/main/java/exh/metadata/metadata/PervEdenSearchMetadata.kt similarity index 98% rename from app/src/main/java/exh/metadata/metadata/PervEdenSearchMetadata.kt rename to source-api/src/main/java/exh/metadata/metadata/PervEdenSearchMetadata.kt index 1e2a21ce9..bfa2faf75 100644 --- a/app/src/main/java/exh/metadata/metadata/PervEdenSearchMetadata.kt +++ b/source-api/src/main/java/exh/metadata/metadata/PervEdenSearchMetadata.kt @@ -2,7 +2,7 @@ package exh.metadata.metadata import android.content.Context import androidx.core.net.toUri -import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.source.R import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.copy import exh.metadata.metadata.base.RaisedSearchMetadata diff --git a/app/src/main/java/exh/metadata/metadata/PururinSearchMetadata.kt b/source-api/src/main/java/exh/metadata/metadata/PururinSearchMetadata.kt similarity index 98% rename from app/src/main/java/exh/metadata/metadata/PururinSearchMetadata.kt rename to source-api/src/main/java/exh/metadata/metadata/PururinSearchMetadata.kt index b04b6bf58..4e8f5bf2e 100644 --- a/app/src/main/java/exh/metadata/metadata/PururinSearchMetadata.kt +++ b/source-api/src/main/java/exh/metadata/metadata/PururinSearchMetadata.kt @@ -1,7 +1,7 @@ package exh.metadata.metadata import android.content.Context -import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.source.R import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.copy import exh.metadata.metadata.base.RaisedSearchMetadata diff --git a/app/src/main/java/exh/metadata/metadata/TsuminoSearchMetadata.kt b/source-api/src/main/java/exh/metadata/metadata/TsuminoSearchMetadata.kt similarity index 98% rename from app/src/main/java/exh/metadata/metadata/TsuminoSearchMetadata.kt rename to source-api/src/main/java/exh/metadata/metadata/TsuminoSearchMetadata.kt index ac882607f..9d0b1f0da 100644 --- a/app/src/main/java/exh/metadata/metadata/TsuminoSearchMetadata.kt +++ b/source-api/src/main/java/exh/metadata/metadata/TsuminoSearchMetadata.kt @@ -2,7 +2,7 @@ package exh.metadata.metadata import android.content.Context import androidx.core.net.toUri -import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.source.R import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.copy import exh.metadata.MetadataUtil diff --git a/app/src/main/java/exh/metadata/metadata/base/FlatMetadata.kt b/source-api/src/main/java/exh/metadata/metadata/base/FlatMetadata.kt similarity index 100% rename from app/src/main/java/exh/metadata/metadata/base/FlatMetadata.kt rename to source-api/src/main/java/exh/metadata/metadata/base/FlatMetadata.kt diff --git a/app/src/main/java/exh/metadata/metadata/base/RaisedSearchMetadata.kt b/source-api/src/main/java/exh/metadata/metadata/base/RaisedSearchMetadata.kt similarity index 99% rename from app/src/main/java/exh/metadata/metadata/base/RaisedSearchMetadata.kt rename to source-api/src/main/java/exh/metadata/metadata/base/RaisedSearchMetadata.kt index 302845147..a2fe8ae12 100644 --- a/app/src/main/java/exh/metadata/metadata/base/RaisedSearchMetadata.kt +++ b/source-api/src/main/java/exh/metadata/metadata/base/RaisedSearchMetadata.kt @@ -60,10 +60,10 @@ abstract class RaisedSearchMetadata { return block(item) to toString(item) } - open fun copyTo(manga: SManga) { + /*open fun copyTo(manga: SManga) { val infoManga = createMangaInfo(manga.copy()) manga.copyFrom(infoManga) - } + }*/ abstract fun createMangaInfo(manga: SManga): SManga diff --git a/app/src/main/java/exh/metadata/metadata/base/RaisedTag.kt b/source-api/src/main/java/exh/metadata/metadata/base/RaisedTag.kt similarity index 100% rename from app/src/main/java/exh/metadata/metadata/base/RaisedTag.kt rename to source-api/src/main/java/exh/metadata/metadata/base/RaisedTag.kt diff --git a/app/src/main/java/exh/metadata/metadata/base/RaisedTitle.kt b/source-api/src/main/java/exh/metadata/metadata/base/RaisedTitle.kt similarity index 100% rename from app/src/main/java/exh/metadata/metadata/base/RaisedTitle.kt rename to source-api/src/main/java/exh/metadata/metadata/base/RaisedTitle.kt diff --git a/app/src/main/java/exh/metadata/sql/models/SearchMetadata.kt b/source-api/src/main/java/exh/metadata/sql/models/SearchMetadata.kt similarity index 100% rename from app/src/main/java/exh/metadata/sql/models/SearchMetadata.kt rename to source-api/src/main/java/exh/metadata/sql/models/SearchMetadata.kt diff --git a/app/src/main/java/exh/metadata/sql/models/SearchTag.kt b/source-api/src/main/java/exh/metadata/sql/models/SearchTag.kt similarity index 100% rename from app/src/main/java/exh/metadata/sql/models/SearchTag.kt rename to source-api/src/main/java/exh/metadata/sql/models/SearchTag.kt diff --git a/app/src/main/java/exh/metadata/sql/models/SearchTitle.kt b/source-api/src/main/java/exh/metadata/sql/models/SearchTitle.kt similarity index 100% rename from app/src/main/java/exh/metadata/sql/models/SearchTitle.kt rename to source-api/src/main/java/exh/metadata/sql/models/SearchTitle.kt diff --git a/app/src/main/java/exh/source/DelegatedHttpSource.kt b/source-api/src/main/java/exh/source/DelegatedHttpSource.kt similarity index 100% rename from app/src/main/java/exh/source/DelegatedHttpSource.kt rename to source-api/src/main/java/exh/source/DelegatedHttpSource.kt diff --git a/app/src/main/java/exh/source/EnhancedHttpSource.kt b/source-api/src/main/java/exh/source/EnhancedHttpSource.kt similarity index 97% rename from app/src/main/java/exh/source/EnhancedHttpSource.kt rename to source-api/src/main/java/exh/source/EnhancedHttpSource.kt index e44192c32..018cc7aaa 100644 --- a/app/src/main/java/exh/source/EnhancedHttpSource.kt +++ b/source-api/src/main/java/exh/source/EnhancedHttpSource.kt @@ -1,6 +1,5 @@ package exh.source -import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.Page @@ -8,14 +7,13 @@ import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.HttpSource import okhttp3.Response -import uy.kohesive.injekt.injectLazy @Suppress("OverridingDeprecatedMember", "DEPRECATION") class EnhancedHttpSource( val originalSource: HttpSource, val enhancedSource: HttpSource, + val delegateSources:() -> Boolean ) : HttpSource() { - private val prefs: PreferencesHelper by injectLazy() /** * Returns the request for the popular manga given the page. @@ -249,7 +247,7 @@ class EnhancedHttpSource( override fun getFilterList() = source().getFilterList() fun source(): HttpSource { - return if (prefs.delegateSources().get()) { + return if (delegateSources()) { enhancedSource } else { originalSource