diff --git a/app/build.gradle b/app/build.gradle index 4327e9e90..83b1a837d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -103,4 +103,5 @@ dependencies { testImplementation 'junit:junit:4.13.1' testImplementation 'org.json:json:20200518' + testImplementation 'org.koin:koin-test:2.2.0-rc-2' } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt b/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt index 5200ce5d6..1e7ae550d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt +++ b/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt @@ -12,6 +12,7 @@ import org.koitharu.kotatsu.core.github.githubModule import org.koitharu.kotatsu.core.local.PagesCache import org.koitharu.kotatsu.core.network.networkModule import org.koitharu.kotatsu.core.parser.LocalMangaRepository +import org.koitharu.kotatsu.core.parser.parserModule import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.domain.MangaDataRepository import org.koitharu.kotatsu.domain.MangaLoaderContext @@ -59,11 +60,12 @@ class KotatsuApp : Application() { networkModule, databaseModule, githubModule, + parserModule, uiModule, module { single { FavouritesRepository(get()) } single { HistoryRepository(get()) } - single { TrackingRepository(get()) } + single { TrackingRepository(get(), get()) } single { MangaDataRepository(get()) } single { MangaSearchRepository() } single { MangaLoaderContext() } diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt index 136bb1722..9d1c1baa1 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt @@ -2,6 +2,8 @@ package org.koitharu.kotatsu.core.model import android.os.Parcelable import kotlinx.android.parcel.Parcelize +import org.koin.core.context.GlobalContext +import org.koin.core.error.NoBeanDefFoundException import org.koitharu.kotatsu.core.parser.LocalMangaRepository import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.parser.site.* @@ -24,6 +26,10 @@ enum class MangaSource( MANGATOWN("MangaTown", "en", MangaTownRepository::class.java), MANGALIB("MangaLib", "ru", MangaLibRepository::class.java), NUDEMOON("Nude-Moon", "ru", NudeMoonRepository::class.java), - MANGAREAD("MangaRead", "en", MangareadRepository::class.java), + MANGAREAD("MangaRead", "en", MangareadRepository::class.java); // HENTAILIB("HentaiLib", "ru", HentaiLibRepository::class.java) + + @get:Throws(NoBeanDefFoundException::class) + val repository: MangaRepository + get() = GlobalContext.get().get(cls.kotlin) } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/LocalMangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/LocalMangaRepository.kt index e8b5a7ebb..3f3fb0567 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/LocalMangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/LocalMangaRepository.kt @@ -7,8 +7,6 @@ import android.webkit.MimeTypeMap import androidx.collection.ArraySet import androidx.core.net.toFile import androidx.core.net.toUri -import org.koin.core.component.KoinComponent -import org.koin.core.component.inject import org.koitharu.kotatsu.core.local.CbzFilter import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.domain.local.MangaIndex @@ -23,9 +21,7 @@ import java.util.* import java.util.zip.ZipEntry import java.util.zip.ZipFile -class LocalMangaRepository : MangaRepository, KoinComponent { - - private val context by inject() +class LocalMangaRepository(private val context: Context) : MangaRepository { override suspend fun getList( offset: Int, diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/ParserModule.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/ParserModule.kt index 14cddf3b7..5497d1aa0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/ParserModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/ParserModule.kt @@ -2,8 +2,21 @@ package org.koitharu.kotatsu.core.parser import org.koin.dsl.bind import org.koin.dsl.module +import org.koitharu.kotatsu.core.parser.site.* val parserModule get() = module { - single { LocalMangaRepository() } bind MangaRepository::class + single { LocalMangaRepository(get()) } bind MangaRepository::class + + factory { ReadmangaRepository(get()) } bind MangaRepository::class + factory { MintMangaRepository(get()) } bind MangaRepository::class + factory { SelfMangaRepository(get()) } bind MangaRepository::class + factory { MangaChanRepository(get()) } bind MangaRepository::class + factory { DesuMeRepository(get()) } bind MangaRepository::class + factory { HenChanRepository(get()) } bind MangaRepository::class + factory { YaoiChanRepository(get()) } bind MangaRepository::class + factory { MangaTownRepository(get()) } bind MangaRepository::class + factory { MangaLibRepository(get()) } bind MangaRepository::class + factory { NudeMoonRepository(get()) } bind MangaRepository::class + factory { MangareadRepository(get()) } bind MangaRepository::class } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/MangaProviderFactory.kt b/app/src/main/java/org/koitharu/kotatsu/domain/MangaProviderFactory.kt index 7cbb93647..bf0ce25fb 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/MangaProviderFactory.kt +++ b/app/src/main/java/org/koitharu/kotatsu/domain/MangaProviderFactory.kt @@ -2,20 +2,11 @@ package org.koitharu.kotatsu.domain import org.koin.core.component.KoinComponent import org.koin.core.component.get -import org.koin.core.component.inject import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.core.parser.LocalMangaRepository -import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.prefs.AppSettings -import java.lang.ref.WeakReference -import java.util.* object MangaProviderFactory : KoinComponent { - private val loaderContext by inject() - private val cache = - EnumMap>(MangaSource::class.java) - fun getSources(includeHidden: Boolean): List { val settings = get() val list = MangaSource.values().toList() - MangaSource.LOCAL @@ -33,39 +24,4 @@ object MangaProviderFactory : KoinComponent { } } } - - @Deprecated("Use DI") - fun createLocal(): LocalMangaRepository { - var instance = cache[MangaSource.LOCAL]?.get() - if (instance == null) { - synchronized(cache) { - instance = cache[MangaSource.LOCAL]?.get() - if (instance == null) { - instance = LocalMangaRepository() - cache[MangaSource.LOCAL] = WeakReference(instance) - } - } - } - return instance as LocalMangaRepository - } - - @Throws(Throwable::class) - fun create(source: MangaSource): MangaRepository { - var instance = cache[source]?.get() - if (instance == null) { - synchronized(cache) { - instance = cache[source]?.get() - if (instance == null) { - instance = try { - source.cls.getDeclaredConstructor(MangaLoaderContext::class.java) - .newInstance(loaderContext) - } catch (e: NoSuchMethodException) { - source.cls.newInstance() - } - cache[source] = WeakReference(instance!!) - } - } - } - return instance!! - } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/MangaSearchRepository.kt b/app/src/main/java/org/koitharu/kotatsu/domain/MangaSearchRepository.kt index c45c4e967..5e205c0e8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/MangaSearchRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/domain/MangaSearchRepository.kt @@ -18,7 +18,7 @@ class MangaSearchRepository { for (source in sources) { val list = lists.getOrPut(source) { try { - MangaProviderFactory.create(source).getList(0, query, SortOrder.POPULARITY) + source.repository.getList(0, query, SortOrder.POPULARITY) } catch (e: Throwable) { e.printStackTrace() emptyList() diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/MangaUtils.kt b/app/src/main/java/org/koitharu/kotatsu/domain/MangaUtils.kt index a9a261f4b..157efe9f6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/MangaUtils.kt +++ b/app/src/main/java/org/koitharu/kotatsu/domain/MangaUtils.kt @@ -27,7 +27,7 @@ object MangaUtils : KoinComponent { suspend fun determineReaderMode(pages: List): ReaderMode? { try { val page = pages.medianOrNull() ?: return null - val url = MangaProviderFactory.create(page.source).getPageFullUrl(page) + val url = page.source.repository.getPageFullUrl(page) val uri = Uri.parse(url) val size = if (uri.scheme == "cbz") { val zip = ZipFile(uri.schemeSpecificPart) diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/tracking/TrackingRepository.kt b/app/src/main/java/org/koitharu/kotatsu/domain/tracking/TrackingRepository.kt index 1947f19c8..2b19a48dc 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/tracking/TrackingRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/domain/tracking/TrackingRepository.kt @@ -5,10 +5,13 @@ import org.koitharu.kotatsu.core.db.MangaDatabase import org.koitharu.kotatsu.core.db.entity.TrackEntity import org.koitharu.kotatsu.core.db.entity.TrackLogEntity import org.koitharu.kotatsu.core.model.* -import org.koitharu.kotatsu.domain.MangaProviderFactory +import org.koitharu.kotatsu.core.parser.LocalMangaRepository import java.util.* -class TrackingRepository(private val db: MangaDatabase) { +class TrackingRepository( + private val db: MangaDatabase, + private val localMangaRepository: LocalMangaRepository +) { suspend fun getNewChaptersCount(mangaId: Long): Int { val entity = db.tracksDao.find(mangaId) ?: return 0 @@ -28,7 +31,7 @@ class TrackingRepository(private val db: MangaDatabase) { .distinctBy { it.id } .mapNotNull { me -> val manga = if (me.source == MangaSource.LOCAL) { - MangaProviderFactory.createLocal().getRemoteManga(me) + localMangaRepository.getRemoteManga(me) // FIXME duplicating } else { me } ?: return@mapNotNull null diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseFragment.kt index 2ca06c78d..0b94bca26 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseFragment.kt @@ -17,6 +17,7 @@ abstract class BaseFragment( fun stringArg(name: String) = StringArgumentDelegate(name) + @Deprecated("Use extension", replaceWith = ReplaceWith("parcelableArgument(name)")) fun arg(name: String) = ParcelableArgumentDelegate(name) open fun getTitle(): CharSequence? = null diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsPresenter.kt index 108005347..8e6aac244 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsPresenter.kt @@ -7,14 +7,13 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import moxy.InjectViewState import moxy.presenterScope +import org.koin.core.component.get import org.koin.core.component.inject import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.core.exceptions.MangaNotFoundException import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.parser.LocalMangaRepository import org.koitharu.kotatsu.domain.MangaDataRepository -import org.koitharu.kotatsu.domain.MangaProviderFactory import org.koitharu.kotatsu.domain.MangaSearchRepository import org.koitharu.kotatsu.domain.favourites.FavouritesRepository import org.koitharu.kotatsu.domain.favourites.OnFavouritesChangeListener @@ -75,8 +74,8 @@ class MangaDetailsPresenter private constructor(private val key: Int) : presenterScope.launch { try { viewState.onLoadingStateChanged(true) - val data = withContext(Dispatchers.IO) { - MangaProviderFactory.create(manga.source).getDetails(manga) + val data = withContext(Dispatchers.Default) { + manga.source.repository.getDetails(manga) } viewState.onMangaUpdated(data) this@MangaDetailsPresenter.manga = data @@ -98,8 +97,7 @@ class MangaDetailsPresenter private constructor(private val key: Int) : viewState.onLoadingStateChanged(true) try { withContext(Dispatchers.IO) { - val repository = - MangaProviderFactory.create(MangaSource.LOCAL) as LocalMangaRepository + val repository = get() val original = repository.getRemoteManga(manga) repository.delete(manga) || throw IOException("Unable to delete file") safe { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/download/DownloadService.kt b/app/src/main/java/org/koitharu/kotatsu/ui/download/DownloadService.kt index 4ac34bedb..379bc0715 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/download/DownloadService.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/download/DownloadService.kt @@ -14,13 +14,14 @@ import kotlinx.coroutines.sync.Mutex import okhttp3.OkHttpClient import okhttp3.Request import okio.IOException +import org.koin.android.ext.android.get import org.koin.android.ext.android.inject import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.local.PagesCache import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.core.parser.LocalMangaRepository import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.domain.MangaProviderFactory import org.koitharu.kotatsu.domain.local.MangaZip import org.koitharu.kotatsu.ui.base.BaseService import org.koitharu.kotatsu.ui.base.dialog.CheckBoxAlertDialog @@ -87,7 +88,7 @@ class DownloadService : BaseService() { checkNotNull(destination) { getString(R.string.cannot_find_available_storage) } var output: MangaZip? = null try { - val repo = MangaProviderFactory.create(manga.source) + val repo = manga.source.repository val cover = safe { imageLoader.execute( ImageRequest.Builder(this@DownloadService) @@ -146,7 +147,7 @@ class DownloadService : BaseService() { if (!output.compress()) { throw RuntimeException("Cannot create target file") } - val result = MangaProviderFactory.createLocal().getFromFile(output.file) + val result = get().getFromFile(output.file) notification.setDone(result) notification.dismiss() notification.update(manga.id.toInt().absoluteValue) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/MainPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/MainPresenter.kt index 337c9e3c7..4bcd8b9b6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/MainPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/list/MainPresenter.kt @@ -3,7 +3,6 @@ package org.koitharu.kotatsu.ui.list import moxy.InjectViewState import org.koin.core.component.inject import org.koitharu.kotatsu.core.exceptions.EmptyHistoryException -import org.koitharu.kotatsu.domain.MangaProviderFactory import org.koitharu.kotatsu.domain.history.HistoryRepository import org.koitharu.kotatsu.ui.base.BasePresenter import org.koitharu.kotatsu.ui.reader.ReaderState @@ -19,7 +18,7 @@ class MainPresenter : BasePresenter() { ?: throw EmptyHistoryException() val history = historyRepository.getOne(manga) ?: throw EmptyHistoryException() val state = ReaderState( - MangaProviderFactory.create(manga.source).getDetails(manga), + manga.source.repository.getDetails(manga), history.chapterId, history.page, history.scroll ) viewState.onOpenReader(state) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListFragment.kt index 636a9df22..698e5105a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListFragment.kt @@ -9,16 +9,19 @@ import org.koitharu.kotatsu.core.model.MangaFilter import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.ui.list.MangaListFragment import org.koitharu.kotatsu.ui.search.SearchActivity +import org.koitharu.kotatsu.utils.ext.parcelableArgument import org.koitharu.kotatsu.utils.ext.withArgs class RemoteListFragment : MangaListFragment() { - private val presenter by moxyPresenter(factory = ::RemoteListPresenter) + private val presenter by moxyPresenter { + RemoteListPresenter(source) + } - private val source by arg(ARG_SOURCE) + private val source by parcelableArgument(ARG_SOURCE) override fun onRequestMoreItems(offset: Int) { - presenter.loadList(source, offset) + presenter.loadList(offset) } override fun getTitle(): CharSequence? { @@ -26,7 +29,7 @@ class RemoteListFragment : MangaListFragment() { } override fun onFilterChanged(filter: MangaFilter) { - presenter.applyFilter(source, filter) + presenter.applyFilter(filter) super.onFilterChanged(filter) } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListPresenter.kt index 0a422cd86..6b90a9a52 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListPresenter.kt @@ -9,22 +9,29 @@ import moxy.presenterScope import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.core.model.MangaFilter import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.domain.MangaProviderFactory import org.koitharu.kotatsu.ui.base.BasePresenter import org.koitharu.kotatsu.ui.list.MangaListView @InjectViewState -class RemoteListPresenter : BasePresenter>() { +class RemoteListPresenter(source: MangaSource) : BasePresenter>() { + private val repository by lazy(LazyThreadSafetyMode.PUBLICATION) { + source.repository + } private var isFilterInitialized = false private var filter: MangaFilter? = null - fun loadList(source: MangaSource, offset: Int) { + override fun onFirstViewAttach() { + super.onFirstViewAttach() + loadFilter() + } + + fun loadList(offset: Int) { presenterScope.launch { viewState.onLoadingStateChanged(true) try { val list = withContext(Dispatchers.Default) { - MangaProviderFactory.create(source).getList( + repository.getList( offset = offset, sortOrder = filter?.sortOrder, tag = filter?.tag @@ -50,23 +57,23 @@ class RemoteListPresenter : BasePresenter>() { } } if (!isFilterInitialized) { - loadFilter(source) + loadFilter() } } - fun applyFilter(source: MangaSource, filter: MangaFilter) { + fun applyFilter(filter: MangaFilter) { this.filter = filter viewState.onListChanged(emptyList()) - loadList(source, 0) + loadList(0) } - private fun loadFilter(source: MangaSource) { + private fun loadFilter() { isFilterInitialized = true - presenterScope.launch { + launchJob { try { val (sorts, tags) = withContext(Dispatchers.Default) { - val repo = MangaProviderFactory.create(source) - repo.sortOrders.sortedBy { it.ordinal } to repo.getTags().sortedBy { it.title } + repository.sortOrders.sortedBy { it.ordinal } to repository.getTags() + .sortedBy { it.title } } viewState.onInitFilter(sorts, tags, filter) } catch (e: Exception) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderPresenter.kt index ab173c92d..da4424ea3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderPresenter.kt @@ -15,7 +15,6 @@ import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaPage import org.koitharu.kotatsu.core.prefs.ReaderMode import org.koitharu.kotatsu.domain.MangaDataRepository -import org.koitharu.kotatsu.domain.MangaProviderFactory import org.koitharu.kotatsu.domain.MangaUtils import org.koitharu.kotatsu.domain.history.HistoryRepository import org.koitharu.kotatsu.ui.base.BasePresenter @@ -35,7 +34,7 @@ class ReaderPresenter : BasePresenter() { viewState.onLoadingStateChanged(isLoading = true) try { val mode = withContext(Dispatchers.IO) { - val repo = MangaProviderFactory.create(manga.source) + val repo = manga.source.repository val chapter = (manga.chapters ?: throw RuntimeException("Chapters is null")).random() var mode = dataRepository.getReaderMode(manga.id) @@ -77,7 +76,7 @@ class ReaderPresenter : BasePresenter() { fun savePage(resolver: ContentResolver, page: MangaPage) { presenterScope.launch(Dispatchers.IO) { try { - val repo = MangaProviderFactory.create(page.source) + val repo = page.source.repository val url = repo.getPageFullUrl(page) val request = Request.Builder() .url(url) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/AbstractReader.kt b/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/AbstractReader.kt index 2332f278a..e3a0c02c4 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/AbstractReader.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/AbstractReader.kt @@ -11,7 +11,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaPage -import org.koitharu.kotatsu.domain.MangaProviderFactory import org.koitharu.kotatsu.ui.base.BaseFragment import org.koitharu.kotatsu.ui.reader.PageLoader import org.koitharu.kotatsu.ui.reader.ReaderListener @@ -124,7 +123,7 @@ abstract class AbstractReader(contentLayoutId: Int) : BaseFragment(contentLayout val pages = withContext(Dispatchers.IO) { val chapter = manga.chapters?.find { it.id == chapterId } ?: throw RuntimeException("Chapter $chapterId not found") - val repo = MangaProviderFactory.create(manga.source) + val repo = manga.source.repository repo.getPages(chapter) } callback(pages) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/PageHolderDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/PageHolderDelegate.kt index 8fba79213..7e39afffe 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/PageHolderDelegate.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/PageHolderDelegate.kt @@ -5,7 +5,6 @@ import androidx.core.net.toUri import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import kotlinx.coroutines.* import org.koitharu.kotatsu.core.model.MangaPage -import org.koitharu.kotatsu.domain.MangaProviderFactory import org.koitharu.kotatsu.ui.reader.PageLoader import org.koitharu.kotatsu.utils.ext.launchAfter import org.koitharu.kotatsu.utils.ext.launchInstead @@ -72,7 +71,7 @@ class PageHolderDelegate( callback.onLoadingStarted() try { val file = withContext(Dispatchers.IO) { - val pageUrl = MangaProviderFactory.create(data.source).getPageFullUrl(data) + val pageUrl = data.source.repository.getPageFullUrl(data) check(pageUrl.isNotEmpty()) { "Cannot obtain full image url" } loader.loadFile(pageUrl, force) } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/PageThumbnailHolder.kt b/app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/PageThumbnailHolder.kt index 736bd198b..47f7a1527 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/PageThumbnailHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/PageThumbnailHolder.kt @@ -12,7 +12,6 @@ import org.koin.core.component.inject import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.local.PagesCache import org.koitharu.kotatsu.core.model.MangaPage -import org.koitharu.kotatsu.domain.MangaProviderFactory import org.koitharu.kotatsu.ui.base.list.BaseViewHolder import org.koitharu.kotatsu.utils.ext.IgnoreErrors @@ -37,7 +36,7 @@ class PageThumbnailHolder(parent: ViewGroup, private val scope: CoroutineScope) job?.cancel() job = scope.launch(Dispatchers.IO + IgnoreErrors) { val url = data.preview ?: data.url.let { - val pageUrl = MangaProviderFactory.create(data.source).getPageFullUrl(data) + val pageUrl = data.source.repository.getPageFullUrl(data) extra[pageUrl]?.toUri()?.toString() ?: pageUrl } val drawable = coil.execute( diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchPresenter.kt index c6af5e499..713bb2bf1 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchPresenter.kt @@ -4,7 +4,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import moxy.InjectViewState import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.domain.MangaProviderFactory import org.koitharu.kotatsu.ui.base.BasePresenter import org.koitharu.kotatsu.ui.list.MangaListView @@ -14,8 +13,7 @@ class SearchPresenter : BasePresenter>() { fun loadList(source: MangaSource, query: String, offset: Int) { launchLoadingJob { val list = withContext(Dispatchers.Default) { - MangaProviderFactory.create(source) - .getList(offset, query = query) + source.repository.getList(offset, query = query) } if (offset == 0) { viewState.onListChanged(list) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/SourceSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/settings/SourceSettingsFragment.kt index ac559e581..f8d64afd0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/SourceSettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/settings/SourceSettingsFragment.kt @@ -6,7 +6,6 @@ import androidx.preference.PreferenceFragmentCompat import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.parser.RemoteMangaRepository -import org.koitharu.kotatsu.domain.MangaProviderFactory import org.koitharu.kotatsu.ui.settings.utils.EditTextSummaryProvider import org.koitharu.kotatsu.utils.ext.withArgs @@ -23,7 +22,7 @@ class SourceSettingsFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { preferenceManager.sharedPreferencesName = source.name - val repo = MangaProviderFactory.create(source) as? RemoteMangaRepository ?: return + val repo = source.repository as? RemoteMangaRepository ?: return val keys = repo.onCreatePreferences().map(::getString) addPreferencesFromResource(R.xml.pref_source) for (i in 0 until preferenceScreen.preferenceCount) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/tracker/TrackWorker.kt b/app/src/main/java/org/koitharu/kotatsu/ui/tracker/TrackWorker.kt index a7a7b909f..03b6a7dd5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/tracker/TrackWorker.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/tracker/TrackWorker.kt @@ -19,7 +19,6 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaChapter import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.domain.MangaProviderFactory import org.koitharu.kotatsu.domain.tracking.TrackingRepository import org.koitharu.kotatsu.ui.details.MangaDetailsActivity import org.koitharu.kotatsu.utils.ext.safe @@ -53,8 +52,7 @@ class TrackWorker(context: Context, workerParams: WorkerParameters) : var success = 0 for (track in tracks) { val details = safe { - MangaProviderFactory.create(track.manga.source) - .getDetails(track.manga) + track.manga.source.repository.getDetails(track.manga) } val chapters = details?.chapters ?: continue when { diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt index 931d9e199..2297333cc 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt @@ -1,6 +1,7 @@ package org.koitharu.kotatsu.utils.ext import android.os.Bundle +import android.os.Parcelable import androidx.fragment.app.Fragment import androidx.lifecycle.coroutineScope @@ -12,4 +13,11 @@ inline fun T.withArgs(size: Int, block: Bundle.() -> Unit): T { } val Fragment.viewLifecycleScope - get() = viewLifecycleOwner.lifecycle.coroutineScope \ No newline at end of file + get() = viewLifecycleOwner.lifecycle.coroutineScope + +@Suppress("NOTHING_TO_INLINE") +inline fun Fragment.parcelableArgument(name: String) = + lazy(LazyThreadSafetyMode.NONE) { + requireArguments().getParcelable(name) + ?: error("No argument $name passed in ${javaClass.simpleName}") + } \ No newline at end of file diff --git a/app/src/test/java/org/koitharu/kotatsu/parsers/RemoteRepositoryTest.kt b/app/src/test/java/org/koitharu/kotatsu/parsers/RemoteRepositoryTest.kt index c6e5511d5..80bb9cc6a 100644 --- a/app/src/test/java/org/koitharu/kotatsu/parsers/RemoteRepositoryTest.kt +++ b/app/src/test/java/org/koitharu/kotatsu/parsers/RemoteRepositoryTest.kt @@ -9,18 +9,24 @@ import org.junit.runner.RunWith import org.junit.runners.Parameterized import org.koin.core.context.startKoin import org.koin.dsl.module +import org.koin.test.KoinTest +import org.koin.test.get import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.parser.UserAgentInterceptor import org.koitharu.kotatsu.core.prefs.SourceConfig import org.koitharu.kotatsu.domain.MangaLoaderContext -import org.koitharu.kotatsu.domain.MangaProviderFactory import org.koitharu.kotatsu.utils.AssertX import java.util.concurrent.TimeUnit @RunWith(Parameterized::class) -class RemoteRepositoryTest(source: MangaSource) { +class RemoteRepositoryTest(source: MangaSource) : KoinTest { - private val repo = MangaProviderFactory.create(source) + private val repo = try { + source.cls.getDeclaredConstructor(MangaLoaderContext::class.java) + .newInstance(get()) + } catch (e: NoSuchMethodException) { + source.cls.newInstance() + } @Test fun list() {