Show related manga
This commit is contained in:
@@ -188,6 +188,7 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView,
|
||||
tab.text = when (position) {
|
||||
0 -> getString(R.string.details)
|
||||
1 -> getString(R.string.chapters)
|
||||
2 -> getString(R.string.related)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,12 @@ import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
|
||||
class MangaDetailsAdapter(activity: FragmentActivity) : FragmentStateAdapter(activity) {
|
||||
|
||||
override fun getItemCount() = 2
|
||||
override fun getItemCount() = 3
|
||||
|
||||
override fun createFragment(position: Int): Fragment = when(position) {
|
||||
0 -> MangaDetailsFragment()
|
||||
1 -> ChaptersFragment()
|
||||
2 -> RelatedMangaFragment()
|
||||
else -> throw IndexOutOfBoundsException("No fragment for position $position")
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.ui.details
|
||||
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import moxy.InjectViewState
|
||||
@@ -13,6 +14,7 @@ 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
|
||||
import org.koitharu.kotatsu.domain.history.HistoryRepository
|
||||
@@ -30,6 +32,7 @@ class MangaDetailsPresenter private constructor() : BasePresenter<MangaDetailsVi
|
||||
private lateinit var historyRepository: HistoryRepository
|
||||
private lateinit var favouritesRepository: FavouritesRepository
|
||||
private lateinit var trackingRepository: TrackingRepository
|
||||
private lateinit var searchRepository: MangaSearchRepository
|
||||
|
||||
private var manga: Manga? = null
|
||||
|
||||
@@ -37,6 +40,7 @@ class MangaDetailsPresenter private constructor() : BasePresenter<MangaDetailsVi
|
||||
historyRepository = HistoryRepository()
|
||||
favouritesRepository = FavouritesRepository()
|
||||
trackingRepository = TrackingRepository()
|
||||
searchRepository = MangaSearchRepository()
|
||||
super.onFirstViewAttach()
|
||||
HistoryRepository.subscribe(this)
|
||||
FavouritesRepository.subscribe(this)
|
||||
@@ -147,6 +151,38 @@ class MangaDetailsPresenter private constructor() : BasePresenter<MangaDetailsVi
|
||||
}
|
||||
}
|
||||
|
||||
fun loadRelated() {
|
||||
val manga = this.manga ?: return
|
||||
presenterScope.launch {
|
||||
viewState.onLoadingStateChanged(isLoading = true)
|
||||
var isFirstCall = true
|
||||
searchRepository.globalSearch(manga.title)
|
||||
.map { list ->
|
||||
list.filter { x -> x.id != manga.id }
|
||||
}.filterNot { x -> x.isEmpty() }
|
||||
.flowOn(Dispatchers.IO)
|
||||
.catch { e ->
|
||||
if (e is IOException) {
|
||||
viewState.onError(e)
|
||||
}
|
||||
}
|
||||
.onEmpty {
|
||||
viewState.onListChanged(emptyList())
|
||||
viewState.onLoadingStateChanged(isLoading = false)
|
||||
}.onCompletion {
|
||||
viewState.onListAppended(emptyList())
|
||||
}.collect {
|
||||
if (isFirstCall) {
|
||||
isFirstCall = false
|
||||
viewState.onListChanged(it)
|
||||
viewState.onLoadingStateChanged(isLoading = false)
|
||||
} else {
|
||||
viewState.onListAppended(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onHistoryChanged() {
|
||||
loadHistory(manga ?: return)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package org.koitharu.kotatsu.ui.details
|
||||
|
||||
import moxy.viewstate.strategy.AddToEndSingleTagStrategy
|
||||
import moxy.viewstate.strategy.AddToEndStrategy
|
||||
import moxy.viewstate.strategy.StateStrategyType
|
||||
import moxy.viewstate.strategy.alias.AddToEndSingle
|
||||
import moxy.viewstate.strategy.alias.SingleState
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
@@ -23,4 +26,13 @@ interface MangaDetailsView : BaseMvpView {
|
||||
|
||||
@AddToEndSingle
|
||||
fun onNewChaptersChanged(newChapters: Int)
|
||||
|
||||
@StateStrategyType(AddToEndSingleTagStrategy::class, tag = "content")
|
||||
fun onListChanged(list: List<Manga>) = Unit
|
||||
|
||||
@StateStrategyType(AddToEndStrategy::class, tag = "content")
|
||||
fun onListAppended(list: List<Manga>) = Unit
|
||||
|
||||
@StateStrategyType(AddToEndSingleTagStrategy::class, tag = "content")
|
||||
fun onListError(e: Throwable) = Unit
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.koitharu.kotatsu.ui.details
|
||||
|
||||
import moxy.ktx.moxyPresenter
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
import org.koitharu.kotatsu.core.model.MangaHistory
|
||||
import org.koitharu.kotatsu.ui.list.MangaListFragment
|
||||
|
||||
class RelatedMangaFragment : MangaListFragment<Unit>(), MangaDetailsView {
|
||||
|
||||
private val presenter by moxyPresenter(factory = MangaDetailsPresenter.Companion::getInstance)
|
||||
|
||||
override fun onRequestMoreItems(offset: Int) {
|
||||
if (offset == 0) {
|
||||
presenter.loadRelated()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMangaUpdated(manga: Manga) = Unit
|
||||
|
||||
override fun onHistoryChanged(history: MangaHistory?) = Unit
|
||||
|
||||
override fun onFavouriteChanged(categories: List<FavouriteCategory>) = Unit
|
||||
|
||||
override fun onMangaRemoved(manga: Manga) = Unit
|
||||
|
||||
override fun onNewChaptersChanged(newChapters: Int) = Unit
|
||||
|
||||
override fun onListChanged(list: List<Manga>) = super<MangaListFragment>.onListChanged(list)
|
||||
|
||||
override fun onListAppended(list: List<Manga>) = super<MangaListFragment>.onListAppended(list)
|
||||
|
||||
override fun onListError(e: Throwable) = super<MangaListFragment>.onListError(e)
|
||||
}
|
||||
@@ -18,7 +18,6 @@ class GlobalSearchPresenter : BasePresenter<MangaListView<Unit>>() {
|
||||
super.onFirstViewAttach()
|
||||
}
|
||||
|
||||
@Suppress("EXPERIMENTAL_API_USAGE")
|
||||
fun startSearch(query: String) {
|
||||
presenterScope.launch {
|
||||
viewState.onLoadingStateChanged(isLoading = true)
|
||||
|
||||
@@ -134,6 +134,7 @@
|
||||
<string name="favourites_category_empty">В этой категории ничего нет</string>
|
||||
<string name="read_later">Прочитать позже</string>
|
||||
<string name="updates">Обновления</string>
|
||||
<string name="text_feed_holder">Here you will see manga updates</string>
|
||||
<string name="text_feed_holder">Здесь будут отображаться обновления манги, которую Вы читаете</string>
|
||||
<string name="search_results">Результаты поиска</string>
|
||||
<string name="related">Похожие</string>
|
||||
</resources>
|
||||
@@ -135,6 +135,7 @@
|
||||
<string name="favourites_category_empty">This category is empty</string>
|
||||
<string name="read_later">Read later</string>
|
||||
<string name="updates">Updates</string>
|
||||
<string name="text_feed_holder">Here you will see manga updates</string>
|
||||
<string name="text_feed_holder">Here you will see the new chapters of the manga you are reading</string>
|
||||
<string name="search_results">Search results</string>
|
||||
<string name="related">Related</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user