diff --git a/app/build.gradle b/app/build.gradle index 2d058198e..b08f1898a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -60,7 +60,7 @@ dependencies { implementation 'androidx.core:core-ktx:1.3.0-alpha01' implementation "androidx.fragment:fragment-ktx:1.2.2" implementation 'androidx.appcompat:appcompat:1.2.0-alpha02' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha03' implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha01' implementation 'androidx.preference:preference:1.1.0' @@ -70,17 +70,17 @@ dependencies { implementation 'androidx.room:room-ktx:2.2.4' kapt 'androidx.room:room-compiler:2.2.4' - implementation 'com.github.moxy-community:moxy:2.0.2' - implementation 'com.github.moxy-community:moxy-androidx:2.0.2' - implementation 'com.github.moxy-community:moxy-material:2.0.2' - implementation 'com.github.moxy-community:moxy-ktx:2.0.2' - kapt 'com.github.moxy-community:moxy-compiler:2.0.2' + implementation 'com.github.moxy-community:moxy:2.1.1' + implementation 'com.github.moxy-community:moxy-androidx:2.1.1' + implementation 'com.github.moxy-community:moxy-material:2.1.1' + implementation 'com.github.moxy-community:moxy-ktx:2.1.1' + kapt 'com.github.moxy-community:moxy-compiler:2.1.1' implementation 'com.squareup.okhttp3:okhttp:4.4.0' implementation 'com.squareup.okio:okio:2.4.3' implementation 'org.jsoup:jsoup:1.12.2' - implementation 'org.koin:koin-android:2.0.1' + implementation 'org.koin:koin-android:2.1.0' implementation 'io.coil-kt:coil:0.9.5' implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0' implementation 'com.tomclaw.cache:cache:1.0' diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/common/BasePresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/common/BasePresenter.kt index de5b61a0b..8b92be6dd 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/common/BasePresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/common/BasePresenter.kt @@ -1,22 +1,7 @@ package org.koitharu.kotatsu.ui.common -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob import moxy.MvpPresenter import moxy.MvpView import org.koin.core.KoinComponent -import kotlin.coroutines.CoroutineContext -abstract class BasePresenter : MvpPresenter(), KoinComponent, CoroutineScope { - - private val job = SupervisorJob() - - override val coroutineContext: CoroutineContext - get() = Dispatchers.Main + job - - override fun onDestroy() { - job.cancel() - super.onDestroy() - } -} \ No newline at end of file +abstract class BasePresenter : MvpPresenter(), KoinComponent \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/ChaptersFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/details/ChaptersFragment.kt index 78f19ffc7..0b7e4d6a0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/ChaptersFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/details/ChaptersFragment.kt @@ -22,7 +22,7 @@ class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), MangaDetailsV OnRecyclerItemClickListener { @Suppress("unused") - private val presenter by moxyPresenter { (activity as MangaDetailsActivity).presenter } + private val presenter by moxyPresenter(factory = MangaDetailsPresenter.Companion::getInstance) private var manga: Manga? = null diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt index 33855e322..a7599d4c4 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt @@ -28,7 +28,7 @@ import org.koitharu.kotatsu.utils.ext.getDisplayMessage class MangaDetailsActivity : BaseActivity(), MangaDetailsView { - val presenter by moxyPresenter(factory = ::MangaDetailsPresenter) + private val presenter by moxyPresenter(factory = MangaDetailsPresenter.Companion::getInstance) private var manga: Manga? = null diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsFragment.kt index 3965dcb41..2b2be4a1b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsFragment.kt @@ -19,7 +19,7 @@ import kotlin.math.roundToInt class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetailsView { @Suppress("unused") - private val presenter by moxyPresenter { (activity as MangaDetailsActivity).presenter } + private val presenter by moxyPresenter(factory = MangaDetailsPresenter.Companion::getInstance) private var manga: Manga? = null private var history: MangaHistory? = 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 13b3d57fa..659324531 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 @@ -4,6 +4,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import moxy.InjectViewState +import moxy.presenterScope import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.domain.MangaProviderFactory @@ -14,7 +15,7 @@ import org.koitharu.kotatsu.domain.history.OnHistoryChangeListener import org.koitharu.kotatsu.ui.common.BasePresenter @InjectViewState -class MangaDetailsPresenter : BasePresenter(), OnHistoryChangeListener, +class MangaDetailsPresenter private constructor(): BasePresenter(), OnHistoryChangeListener, OnFavouritesChangeListener { private lateinit var historyRepository: HistoryRepository @@ -37,7 +38,7 @@ class MangaDetailsPresenter : BasePresenter(), OnHistoryChange loadHistory(manga) viewState.onMangaUpdated(manga) loadFavourite(manga) - launch { + presenterScope.launch { try { viewState.onLoadingStateChanged(true) val data = withContext(Dispatchers.IO) { @@ -57,7 +58,7 @@ class MangaDetailsPresenter : BasePresenter(), OnHistoryChange } private fun loadHistory(manga: Manga) { - launch { + presenterScope.launch { try { val history = withContext(Dispatchers.IO) { historyRepository.getOne(manga) @@ -72,7 +73,7 @@ class MangaDetailsPresenter : BasePresenter(), OnHistoryChange } private fun loadFavourite(manga: Manga) { - launch { + presenterScope.launch { try { val categories = withContext(Dispatchers.IO) { favouritesRepository.getCategories(manga.id) @@ -99,6 +100,18 @@ class MangaDetailsPresenter : BasePresenter(), OnHistoryChange override fun onDestroy() { HistoryRepository.unsubscribe(this) FavouritesRepository.unsubscribe(this) + instance = null super.onDestroy() } + + companion object { + + private var instance: MangaDetailsPresenter? = null + + fun getInstance(): MangaDetailsPresenter = instance ?: synchronized(this) { + MangaDetailsPresenter().also { + instance = it + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/FavouritesListPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/FavouritesListPresenter.kt index 9356fe005..e6d746c75 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/FavouritesListPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/FavouritesListPresenter.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import moxy.InjectViewState +import moxy.presenterScope import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.domain.favourites.FavouritesRepository import org.koitharu.kotatsu.ui.common.BasePresenter @@ -20,7 +21,7 @@ class FavouritesListPresenter : BasePresenter>() { } fun loadList(offset: Int) { - launch { + presenterScope.launch { viewState.onLoadingChanged(true) try { val list = withContext(Dispatchers.IO) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesPresenter.kt index fa4a13eed..41794cffb 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesPresenter.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import moxy.InjectViewState +import moxy.presenterScope import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.domain.favourites.FavouritesRepository @@ -21,7 +22,7 @@ class FavouriteCategoriesPresenter : BasePresenter() { } fun loadAllCategories() { - launch { + presenterScope.launch { try { val categories = withContext(Dispatchers.IO) { repository.getAllCategories() @@ -37,7 +38,7 @@ class FavouriteCategoriesPresenter : BasePresenter() { } fun loadMangaCategories(manga: Manga) { - launch { + presenterScope.launch { try { val categories = withContext(Dispatchers.IO) { repository.getCategories(manga.id) @@ -53,7 +54,7 @@ class FavouriteCategoriesPresenter : BasePresenter() { } fun createCategory(name: String) { - launch { + presenterScope.launch { try { val categories = withContext(Dispatchers.IO) { repository.addCategory(name) @@ -70,7 +71,7 @@ class FavouriteCategoriesPresenter : BasePresenter() { } fun addToCategory(manga: Manga, categoryId: Long) { - launch { + presenterScope.launch { try { val categories = withContext(Dispatchers.IO) { repository.addToCategory(manga,categoryId) @@ -85,7 +86,7 @@ class FavouriteCategoriesPresenter : BasePresenter() { } fun removeFromCategory(manga: Manga, categoryId: Long) { - launch { + presenterScope.launch { try { val categories = withContext(Dispatchers.IO) { repository.removeFromCategory(manga, categoryId) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/history/HistoryListPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/history/HistoryListPresenter.kt index ef2d166a1..1caf2034e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/history/HistoryListPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/history/HistoryListPresenter.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import moxy.InjectViewState +import moxy.presenterScope import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaHistory @@ -22,7 +23,7 @@ class HistoryListPresenter : BasePresenter>() { } fun loadList(offset: Int) { - launch { + presenterScope.launch { viewState.onLoadingChanged(true) try { val list = withContext(Dispatchers.IO) { @@ -45,7 +46,7 @@ class HistoryListPresenter : BasePresenter>() { } fun clearHistory() { - launch { + presenterScope.launch { viewState.onLoadingChanged(true) try { withContext(Dispatchers.IO) { @@ -64,7 +65,7 @@ class HistoryListPresenter : BasePresenter>() { } fun removeFromHistory(manga: Manga) { - launch { + presenterScope.launch { try { withContext(Dispatchers.IO) { repository.delete(manga) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/local/LocalListPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/local/LocalListPresenter.kt index 2f29850b3..8f4436d5a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/local/LocalListPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/local/LocalListPresenter.kt @@ -7,6 +7,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import moxy.InjectViewState +import moxy.presenterScope import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.core.exceptions.UnsupportedFileException import org.koitharu.kotatsu.core.model.Manga @@ -33,7 +34,7 @@ class LocalListPresenter : BasePresenter>() { } fun loadList() { - launch { + presenterScope.launch { viewState.onLoadingChanged(true) try { val list = withContext(Dispatchers.IO) { @@ -53,7 +54,7 @@ class LocalListPresenter : BasePresenter>() { } fun importFile(context: Context, uri: Uri) { - launch(Dispatchers.IO) { + presenterScope.launch(Dispatchers.IO) { try { val name = MediaStoreCompat.getName(context, uri) ?: throw IOException("Cannot fetch name from uri: $uri") @@ -84,7 +85,7 @@ class LocalListPresenter : BasePresenter>() { } fun delete(manga: Manga) { - launch { + presenterScope.launch { try { withContext(Dispatchers.IO) { repository.delete(manga) || throw IOException("Unable to delete file") diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/remote/RemoteListPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/remote/RemoteListPresenter.kt index 2702cfda1..08d0c215b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/remote/RemoteListPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/remote/RemoteListPresenter.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import moxy.InjectViewState +import moxy.presenterScope import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.core.model.MangaFilter import org.koitharu.kotatsu.core.model.MangaSource @@ -18,7 +19,7 @@ class RemoteListPresenter : BasePresenter>() { private var filter: MangaFilter? = null fun loadList(source: MangaSource, offset: Int) { - launch { + presenterScope.launch { viewState.onLoadingChanged(true) try { val list = withContext(Dispatchers.IO) { @@ -55,7 +56,7 @@ class RemoteListPresenter : BasePresenter>() { private fun loadFilter(source: MangaSource) { isFilterInitialized = true - launch { + presenterScope.launch { try { val (sorts, tags) = withContext(Dispatchers.IO) { val repo = MangaProviderFactory.create(source) 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 f30b6873f..d4cf69085 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 @@ -7,6 +7,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import moxy.InjectViewState +import moxy.presenterScope import okhttp3.OkHttpClient import okhttp3.Request import org.koitharu.kotatsu.BuildConfig @@ -23,7 +24,7 @@ import org.koitharu.kotatsu.utils.ext.mimeType class ReaderPresenter : BasePresenter() { fun loadChapter(state: ReaderState) { - launch { + presenterScope.launch { viewState.onLoadingStateChanged(isLoading = true) try { val pages = withContext(Dispatchers.IO) { @@ -46,7 +47,7 @@ class ReaderPresenter : BasePresenter() { } fun saveState(state: ReaderState) { - launch(Dispatchers.IO) { + presenterScope.launch(Dispatchers.IO) { HistoryRepository().addOrUpdate( manga = state.manga, chapterId = state.chapterId, @@ -56,7 +57,7 @@ class ReaderPresenter : BasePresenter() { } fun savePage(resolver: ContentResolver, page: MangaPage) { - launch(Dispatchers.IO) { + presenterScope.launch(Dispatchers.IO) { try { val repo = MangaProviderFactory.create(page.source) val url = repo.getPageFullUrl(page) 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 c0b909aff..b9db5ca6d 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,6 +4,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import moxy.InjectViewState +import moxy.presenterScope import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.domain.MangaProviderFactory @@ -21,7 +22,7 @@ class SearchPresenter : BasePresenter>() { } fun loadList(query: String, offset: Int) { - launch { + presenterScope.launch { viewState.onLoadingChanged(true) try { //TODO select source