Refactor manga list model mapping
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -25,3 +25,4 @@
|
|||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
.cxx
|
.cxx
|
||||||
/.idea/deviceManager.xml
|
/.idea/deviceManager.xml
|
||||||
|
/.kotlin/
|
||||||
|
|||||||
@@ -15,11 +15,13 @@ import org.koitharu.kotatsu.core.model.chaptersCount
|
|||||||
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
||||||
import org.koitharu.kotatsu.core.parser.MangaIntent
|
import org.koitharu.kotatsu.core.parser.MangaIntent
|
||||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||||
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
import org.koitharu.kotatsu.core.ui.BaseViewModel
|
import org.koitharu.kotatsu.core.ui.BaseViewModel
|
||||||
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
|
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
|
||||||
import org.koitharu.kotatsu.core.util.ext.call
|
import org.koitharu.kotatsu.core.util.ext.call
|
||||||
import org.koitharu.kotatsu.core.util.ext.require
|
import org.koitharu.kotatsu.core.util.ext.require
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
import org.koitharu.kotatsu.history.data.HistoryRepository
|
||||||
|
import org.koitharu.kotatsu.history.data.PROGRESS_NONE
|
||||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.LoadingFooter
|
import org.koitharu.kotatsu.list.ui.model.LoadingFooter
|
||||||
@@ -34,7 +36,8 @@ class AlternativesViewModel @Inject constructor(
|
|||||||
private val mangaRepositoryFactory: MangaRepository.Factory,
|
private val mangaRepositoryFactory: MangaRepository.Factory,
|
||||||
private val alternativesUseCase: AlternativesUseCase,
|
private val alternativesUseCase: AlternativesUseCase,
|
||||||
private val migrateUseCase: MigrateUseCase,
|
private val migrateUseCase: MigrateUseCase,
|
||||||
private val extraProvider: ListExtraProvider,
|
private val historyRepository: HistoryRepository,
|
||||||
|
private val settings: AppSettings,
|
||||||
) : BaseViewModel() {
|
) : BaseViewModel() {
|
||||||
|
|
||||||
val manga = savedStateHandle.require<ParcelableManga>(MangaIntent.KEY_MANGA).manga
|
val manga = savedStateHandle.require<ParcelableManga>(MangaIntent.KEY_MANGA).manga
|
||||||
@@ -53,7 +56,7 @@ class AlternativesViewModel @Inject constructor(
|
|||||||
.map {
|
.map {
|
||||||
MangaAlternativeModel(
|
MangaAlternativeModel(
|
||||||
manga = it,
|
manga = it,
|
||||||
progress = extraProvider.getProgress(it.id),
|
progress = getProgress(it.id),
|
||||||
referenceChapters = refCount,
|
referenceChapters = refCount,
|
||||||
)
|
)
|
||||||
}.runningFold<MangaAlternativeModel, List<ListModel>>(listOf(LoadingState)) { acc, item ->
|
}.runningFold<MangaAlternativeModel, List<ListModel>>(listOf(LoadingState)) { acc, item ->
|
||||||
@@ -86,13 +89,11 @@ class AlternativesViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun mapList(list: List<Manga>, refCount: Int): List<MangaAlternativeModel> {
|
private suspend fun getProgress(mangaId: Long): Float {
|
||||||
return list.map {
|
return if (settings.isReadingIndicatorsEnabled) {
|
||||||
MangaAlternativeModel(
|
historyRepository.getProgress(mangaId)
|
||||||
manga = it,
|
} else {
|
||||||
progress = extraProvider.getProgress(it.id),
|
PROGRESS_NONE
|
||||||
referenceChapters = refCount,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,11 +89,11 @@ import org.koitharu.kotatsu.details.ui.scrobbling.ScrollingInfoAdapter
|
|||||||
import org.koitharu.kotatsu.download.ui.worker.DownloadStartedObserver
|
import org.koitharu.kotatsu.download.ui.worker.DownloadStartedObserver
|
||||||
import org.koitharu.kotatsu.favourites.ui.categories.select.FavoriteSheet
|
import org.koitharu.kotatsu.favourites.ui.categories.select.FavoriteSheet
|
||||||
import org.koitharu.kotatsu.image.ui.ImageActivity
|
import org.koitharu.kotatsu.image.ui.ImageActivity
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
||||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||||
import org.koitharu.kotatsu.list.ui.adapter.mangaGridItemAD
|
import org.koitharu.kotatsu.list.ui.adapter.mangaGridItemAD
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.MangaItemModel
|
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
||||||
import org.koitharu.kotatsu.list.ui.size.StaticItemSizeResolver
|
import org.koitharu.kotatsu.list.ui.size.StaticItemSizeResolver
|
||||||
import org.koitharu.kotatsu.local.ui.info.LocalInfoDialog
|
import org.koitharu.kotatsu.local.ui.info.LocalInfoDialog
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
@@ -122,7 +122,7 @@ class DetailsActivity :
|
|||||||
lateinit var coil: ImageLoader
|
lateinit var coil: ImageLoader
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var tagHighlighter: ListExtraProvider
|
lateinit var listMapper: MangaListMapper
|
||||||
|
|
||||||
private val viewModel: DetailsViewModel by viewModels()
|
private val viewModel: DetailsViewModel by viewModels()
|
||||||
private lateinit var menuProvider: DetailsMenuProvider
|
private lateinit var menuProvider: DetailsMenuProvider
|
||||||
@@ -391,7 +391,7 @@ class DetailsActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onRelatedMangaChanged(related: List<MangaItemModel>) {
|
private fun onRelatedMangaChanged(related: List<MangaListModel>) {
|
||||||
if (related.isEmpty()) {
|
if (related.isEmpty()) {
|
||||||
viewBinding.groupRelated.isVisible = false
|
viewBinding.groupRelated.isVisible = false
|
||||||
return
|
return
|
||||||
@@ -613,15 +613,7 @@ class DetailsActivity :
|
|||||||
|
|
||||||
private fun bindTags(manga: Manga) {
|
private fun bindTags(manga: Manga) {
|
||||||
viewBinding.chipsTags.isVisible = manga.tags.isNotEmpty()
|
viewBinding.chipsTags.isVisible = manga.tags.isNotEmpty()
|
||||||
viewBinding.chipsTags.setChips(
|
viewBinding.chipsTags.setChips(listMapper.mapTags(manga.tags))
|
||||||
manga.tags.map { tag ->
|
|
||||||
ChipsView.ChipModel(
|
|
||||||
title = tag.title,
|
|
||||||
tint = tagHighlighter.getTagTint(tag),
|
|
||||||
data = tag,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadCover(manga: Manga) {
|
private fun loadCover(manga: Manga) {
|
||||||
|
|||||||
@@ -50,9 +50,8 @@ import org.koitharu.kotatsu.details.ui.model.HistoryInfo
|
|||||||
import org.koitharu.kotatsu.details.ui.model.MangaBranch
|
import org.koitharu.kotatsu.details.ui.model.MangaBranch
|
||||||
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
||||||
import org.koitharu.kotatsu.history.data.HistoryRepository
|
import org.koitharu.kotatsu.history.data.HistoryRepository
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
||||||
import org.koitharu.kotatsu.list.ui.model.MangaItemModel
|
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.toUi
|
|
||||||
import org.koitharu.kotatsu.local.data.LocalStorageChanges
|
import org.koitharu.kotatsu.local.data.LocalStorageChanges
|
||||||
import org.koitharu.kotatsu.local.domain.DeleteLocalMangaUseCase
|
import org.koitharu.kotatsu.local.domain.DeleteLocalMangaUseCase
|
||||||
import org.koitharu.kotatsu.local.domain.model.LocalManga
|
import org.koitharu.kotatsu.local.domain.model.LocalManga
|
||||||
@@ -76,7 +75,7 @@ class DetailsViewModel @Inject constructor(
|
|||||||
savedStateHandle: SavedStateHandle,
|
savedStateHandle: SavedStateHandle,
|
||||||
private val deleteLocalMangaUseCase: DeleteLocalMangaUseCase,
|
private val deleteLocalMangaUseCase: DeleteLocalMangaUseCase,
|
||||||
private val relatedMangaUseCase: RelatedMangaUseCase,
|
private val relatedMangaUseCase: RelatedMangaUseCase,
|
||||||
private val extraProvider: ListExtraProvider,
|
private val mangaListMapper: MangaListMapper,
|
||||||
private val detailsLoadUseCase: DetailsLoadUseCase,
|
private val detailsLoadUseCase: DetailsLoadUseCase,
|
||||||
private val progressUpdateUseCase: ProgressUpdateUseCase,
|
private val progressUpdateUseCase: ProgressUpdateUseCase,
|
||||||
private val readingTimeUseCase: ReadingTimeUseCase,
|
private val readingTimeUseCase: ReadingTimeUseCase,
|
||||||
@@ -171,9 +170,12 @@ class DetailsViewModel @Inject constructor(
|
|||||||
val scrobblingInfo: StateFlow<List<ScrobblingInfo>> = interactor.observeScrobblingInfo(mangaId)
|
val scrobblingInfo: StateFlow<List<ScrobblingInfo>> = interactor.observeScrobblingInfo(mangaId)
|
||||||
.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, emptyList())
|
.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, emptyList())
|
||||||
|
|
||||||
val relatedManga: StateFlow<List<MangaItemModel>> = manga.mapLatest {
|
val relatedManga: StateFlow<List<MangaListModel>> = manga.mapLatest {
|
||||||
if (it != null && settings.isRelatedMangaEnabled) {
|
if (it != null && settings.isRelatedMangaEnabled) {
|
||||||
relatedMangaUseCase.invoke(it)?.toUi(ListMode.GRID, extraProvider).orEmpty()
|
mangaListMapper.toListModelList(
|
||||||
|
manga = relatedMangaUseCase(it).orEmpty(),
|
||||||
|
mode = ListMode.GRID,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,11 @@ import org.koitharu.kotatsu.core.util.ext.call
|
|||||||
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
|
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
|
||||||
import org.koitharu.kotatsu.core.util.ext.require
|
import org.koitharu.kotatsu.core.util.ext.require
|
||||||
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
||||||
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||||
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toUi
|
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -34,7 +33,7 @@ class RelatedListViewModel @Inject constructor(
|
|||||||
savedStateHandle: SavedStateHandle,
|
savedStateHandle: SavedStateHandle,
|
||||||
mangaRepositoryFactory: MangaRepository.Factory,
|
mangaRepositoryFactory: MangaRepository.Factory,
|
||||||
settings: AppSettings,
|
settings: AppSettings,
|
||||||
private val extraProvider: ListExtraProvider,
|
private val mangaListMapper: MangaListMapper,
|
||||||
downloadScheduler: DownloadWorker.Scheduler,
|
downloadScheduler: DownloadWorker.Scheduler,
|
||||||
) : MangaListViewModel(settings, downloadScheduler) {
|
) : MangaListViewModel(settings, downloadScheduler) {
|
||||||
|
|
||||||
@@ -53,7 +52,7 @@ class RelatedListViewModel @Inject constructor(
|
|||||||
list.isNullOrEmpty() && error != null -> listOf(error.toErrorState(canRetry = true))
|
list.isNullOrEmpty() && error != null -> listOf(error.toErrorState(canRetry = true))
|
||||||
list == null -> listOf(LoadingState)
|
list == null -> listOf(LoadingState)
|
||||||
list.isEmpty() -> listOf(createEmptyState())
|
list.isEmpty() -> listOf(createEmptyState())
|
||||||
else -> list.toUi(mode, extraProvider)
|
else -> mangaListMapper.toListModelList(list, mode)
|
||||||
}
|
}
|
||||||
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, listOf(LoadingState))
|
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, listOf(LoadingState))
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import org.koitharu.kotatsu.list.ui.model.EmptyHint
|
|||||||
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||||
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
import org.koitharu.kotatsu.list.ui.model.MangaCompactListModel
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
|
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
|
||||||
@@ -190,7 +190,7 @@ class ExploreViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun List<Manga>.toRecommendationList() = map { manga ->
|
private fun List<Manga>.toRecommendationList() = map { manga ->
|
||||||
MangaListModel(
|
MangaCompactListModel(
|
||||||
id = manga.id,
|
id = manga.id,
|
||||||
title = manga.title,
|
title = manga.title,
|
||||||
subtitle = manga.tags.joinToString { it.title },
|
subtitle = manga.tags.joinToString { it.title },
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import org.koitharu.kotatsu.explore.ui.model.MangaSourceItem
|
|||||||
import org.koitharu.kotatsu.explore.ui.model.RecommendationsItem
|
import org.koitharu.kotatsu.explore.ui.model.RecommendationsItem
|
||||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
import org.koitharu.kotatsu.list.ui.model.MangaCompactListModel
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
|
|
||||||
fun exploreButtonsAD(
|
fun exploreButtonsAD(
|
||||||
@@ -66,7 +66,7 @@ fun exploreRecommendationItemAD(
|
|||||||
{ layoutInflater, parent -> ItemRecommendationBinding.inflate(layoutInflater, parent, false) },
|
{ layoutInflater, parent -> ItemRecommendationBinding.inflate(layoutInflater, parent, false) },
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val adapter = BaseListAdapter<MangaListModel>()
|
val adapter = BaseListAdapter<MangaCompactListModel>()
|
||||||
.addDelegate(ListItemType.MANGA_LIST, recommendationMangaItemAD(coil, itemClickListener, lifecycleOwner))
|
.addDelegate(ListItemType.MANGA_LIST, recommendationMangaItemAD(coil, itemClickListener, lifecycleOwner))
|
||||||
binding.pager.adapter = adapter
|
binding.pager.adapter = adapter
|
||||||
binding.pager.recyclerView?.isNestedScrollingEnabled = false
|
binding.pager.recyclerView?.isNestedScrollingEnabled = false
|
||||||
@@ -81,7 +81,7 @@ fun recommendationMangaItemAD(
|
|||||||
coil: ImageLoader,
|
coil: ImageLoader,
|
||||||
itemClickListener: OnListItemClickListener<Manga>,
|
itemClickListener: OnListItemClickListener<Manga>,
|
||||||
lifecycleOwner: LifecycleOwner,
|
lifecycleOwner: LifecycleOwner,
|
||||||
) = adapterDelegateViewBinding<MangaListModel, MangaListModel, ItemRecommendationMangaBinding>(
|
) = adapterDelegateViewBinding<MangaCompactListModel, MangaCompactListModel, ItemRecommendationMangaBinding>(
|
||||||
{ layoutInflater, parent -> ItemRecommendationMangaBinding.inflate(layoutInflater, parent, false) },
|
{ layoutInflater, parent -> ItemRecommendationMangaBinding.inflate(layoutInflater, parent, false) },
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package org.koitharu.kotatsu.explore.ui.model
|
package org.koitharu.kotatsu.explore.ui.model
|
||||||
|
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
import org.koitharu.kotatsu.list.ui.model.MangaCompactListModel
|
||||||
|
|
||||||
data class RecommendationsItem(
|
data class RecommendationsItem(
|
||||||
val manga: List<MangaListModel>
|
val manga: List<MangaCompactListModel>
|
||||||
) : ListModel {
|
) : ListModel {
|
||||||
|
|
||||||
override fun areItemsTheSame(other: ListModel): Boolean {
|
override fun areItemsTheSame(other: ListModel): Boolean {
|
||||||
|
|||||||
@@ -24,13 +24,12 @@ import org.koitharu.kotatsu.favourites.domain.FavouritesRepository
|
|||||||
import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment.Companion.ARG_CATEGORY_ID
|
import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment.Companion.ARG_CATEGORY_ID
|
||||||
import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment.Companion.NO_ID
|
import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment.Companion.NO_ID
|
||||||
import org.koitharu.kotatsu.history.domain.MarkAsReadUseCase
|
import org.koitharu.kotatsu.history.domain.MarkAsReadUseCase
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
|
||||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||||
|
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
||||||
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||||
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toUi
|
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -41,7 +40,7 @@ private const val PAGE_SIZE = 20
|
|||||||
class FavouritesListViewModel @Inject constructor(
|
class FavouritesListViewModel @Inject constructor(
|
||||||
savedStateHandle: SavedStateHandle,
|
savedStateHandle: SavedStateHandle,
|
||||||
private val repository: FavouritesRepository,
|
private val repository: FavouritesRepository,
|
||||||
private val listExtraProvider: ListExtraProvider,
|
private val mangaListMapper: MangaListMapper,
|
||||||
private val markAsReadUseCase: MarkAsReadUseCase,
|
private val markAsReadUseCase: MarkAsReadUseCase,
|
||||||
settings: AppSettings,
|
settings: AppSettings,
|
||||||
downloadScheduler: DownloadWorker.Scheduler,
|
downloadScheduler: DownloadWorker.Scheduler,
|
||||||
@@ -86,7 +85,7 @@ class FavouritesListViewModel @Inject constructor(
|
|||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
isReady.set(true)
|
isReady.set(true)
|
||||||
list.toUi(mode, listExtraProvider)
|
mangaListMapper.toListModelList(list, mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.catch {
|
}.catch {
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
|||||||
import org.koitharu.kotatsu.history.data.HistoryRepository
|
import org.koitharu.kotatsu.history.data.HistoryRepository
|
||||||
import org.koitharu.kotatsu.history.domain.MarkAsReadUseCase
|
import org.koitharu.kotatsu.history.domain.MarkAsReadUseCase
|
||||||
import org.koitharu.kotatsu.history.domain.model.MangaWithHistory
|
import org.koitharu.kotatsu.history.domain.model.MangaWithHistory
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
|
||||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||||
|
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
||||||
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.EmptyHint
|
import org.koitharu.kotatsu.list.ui.model.EmptyHint
|
||||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||||
@@ -38,9 +38,6 @@ import org.koitharu.kotatsu.list.ui.model.ListModel
|
|||||||
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||||
import org.koitharu.kotatsu.list.ui.model.TipModel
|
import org.koitharu.kotatsu.list.ui.model.TipModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toGridModel
|
|
||||||
import org.koitharu.kotatsu.list.ui.model.toListDetailedModel
|
|
||||||
import org.koitharu.kotatsu.list.ui.model.toListModel
|
|
||||||
import org.koitharu.kotatsu.local.data.LocalMangaRepository
|
import org.koitharu.kotatsu.local.data.LocalMangaRepository
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -53,7 +50,7 @@ private const val PAGE_SIZE = 20
|
|||||||
class HistoryListViewModel @Inject constructor(
|
class HistoryListViewModel @Inject constructor(
|
||||||
private val repository: HistoryRepository,
|
private val repository: HistoryRepository,
|
||||||
settings: AppSettings,
|
settings: AppSettings,
|
||||||
private val extraProvider: ListExtraProvider,
|
private val mangaListMapper: MangaListMapper,
|
||||||
private val localMangaRepository: LocalMangaRepository,
|
private val localMangaRepository: LocalMangaRepository,
|
||||||
private val markAsReadUseCase: MarkAsReadUseCase,
|
private val markAsReadUseCase: MarkAsReadUseCase,
|
||||||
networkState: NetworkState,
|
networkState: NetworkState,
|
||||||
@@ -203,11 +200,7 @@ class HistoryListViewModel @Inject constructor(
|
|||||||
prevHeader = header
|
prevHeader = header
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result += when (mode) {
|
result += mangaListMapper.toListModel(manga, mode)
|
||||||
ListMode.LIST -> manga.toListModel(extraProvider)
|
|
||||||
ListMode.DETAILED_LIST -> manga.toListDetailedModel(extraProvider)
|
|
||||||
ListMode.GRID -> manga.toGridModel(extraProvider)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.list.domain
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.annotation.ColorRes
|
|
||||||
import dagger.Reusable
|
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
|
||||||
import org.koitharu.kotatsu.R
|
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
|
||||||
import org.koitharu.kotatsu.history.data.HistoryRepository
|
|
||||||
import org.koitharu.kotatsu.history.data.PROGRESS_NONE
|
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
|
||||||
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@Reusable
|
|
||||||
class ListExtraProvider @Inject constructor(
|
|
||||||
@ApplicationContext context: Context,
|
|
||||||
private val settings: AppSettings,
|
|
||||||
private val trackingRepository: TrackingRepository,
|
|
||||||
private val historyRepository: HistoryRepository,
|
|
||||||
) {
|
|
||||||
|
|
||||||
private val dict by lazy {
|
|
||||||
context.resources.openRawResource(R.raw.tags_redlist).use {
|
|
||||||
val set = HashSet<String>()
|
|
||||||
it.bufferedReader().forEachLine { x ->
|
|
||||||
val line = x.trim()
|
|
||||||
if (line.isNotEmpty()) {
|
|
||||||
set.add(line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun getCounter(mangaId: Long): Int {
|
|
||||||
return if (settings.isTrackerEnabled) {
|
|
||||||
trackingRepository.getNewChaptersCount(mangaId)
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun getProgress(mangaId: Long): Float {
|
|
||||||
return if (settings.isReadingIndicatorsEnabled) {
|
|
||||||
historyRepository.getProgress(mangaId)
|
|
||||||
} else {
|
|
||||||
PROGRESS_NONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ColorRes
|
|
||||||
fun getTagTint(tag: MangaTag): Int {
|
|
||||||
return if (tag.title.lowercase() in dict) {
|
|
||||||
R.color.warning
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
package org.koitharu.kotatsu.list.domain
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.annotation.ColorRes
|
||||||
|
import androidx.collection.MutableScatterSet
|
||||||
|
import androidx.collection.ScatterSet
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
|
import org.koitharu.kotatsu.core.prefs.ListMode
|
||||||
|
import org.koitharu.kotatsu.core.ui.widgets.ChipsView
|
||||||
|
import org.koitharu.kotatsu.favourites.domain.FavouritesRepository
|
||||||
|
import org.koitharu.kotatsu.history.data.HistoryRepository
|
||||||
|
import org.koitharu.kotatsu.history.data.PROGRESS_NONE
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.MangaCompactListModel
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.MangaDetailedListModel
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.MangaGridModel
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
||||||
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
|
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||||
|
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class MangaListMapper @Inject constructor(
|
||||||
|
@ApplicationContext context: Context,
|
||||||
|
private val settings: AppSettings,
|
||||||
|
private val trackingRepository: TrackingRepository,
|
||||||
|
private val historyRepository: HistoryRepository,
|
||||||
|
private val favouritesRepository: FavouritesRepository,
|
||||||
|
) {
|
||||||
|
|
||||||
|
private val dict by lazy { readTagsDict(context) }
|
||||||
|
|
||||||
|
suspend fun toListModelList(manga: Collection<Manga>, mode: ListMode): List<MangaListModel> = manga.map {
|
||||||
|
toListModel(it, mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun toListModelList(
|
||||||
|
destination: MutableCollection<in MangaListModel>,
|
||||||
|
manga: Collection<Manga>,
|
||||||
|
mode: ListMode
|
||||||
|
) = manga.mapTo(destination) {
|
||||||
|
toListModel(it, mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun toListModel(manga: Manga, mode: ListMode): MangaListModel = when (mode) {
|
||||||
|
ListMode.LIST -> toCompactListModel(manga)
|
||||||
|
ListMode.DETAILED_LIST -> toDetailedListModel(manga)
|
||||||
|
ListMode.GRID -> toGridModel(manga)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun toCompactListModel(manga: Manga) = MangaCompactListModel(
|
||||||
|
id = manga.id,
|
||||||
|
title = manga.title,
|
||||||
|
subtitle = manga.tags.joinToString(", ") { it.title },
|
||||||
|
coverUrl = manga.coverUrl,
|
||||||
|
manga = manga,
|
||||||
|
counter = getCounter(manga.id),
|
||||||
|
progress = getProgress(manga.id),
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun toDetailedListModel(manga: Manga) = MangaDetailedListModel(
|
||||||
|
id = manga.id,
|
||||||
|
title = manga.title,
|
||||||
|
subtitle = manga.altTitle,
|
||||||
|
coverUrl = manga.coverUrl,
|
||||||
|
manga = manga,
|
||||||
|
counter = getCounter(manga.id),
|
||||||
|
progress = getProgress(manga.id),
|
||||||
|
tags = mapTags(manga.tags),
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun toGridModel(manga: Manga) = MangaGridModel(
|
||||||
|
id = manga.id,
|
||||||
|
title = manga.title,
|
||||||
|
coverUrl = manga.coverUrl,
|
||||||
|
manga = manga,
|
||||||
|
counter = getCounter(manga.id),
|
||||||
|
progress = getProgress(manga.id),
|
||||||
|
)
|
||||||
|
|
||||||
|
fun mapTags(tags: Collection<MangaTag>) = tags.map {
|
||||||
|
ChipsView.ChipModel(
|
||||||
|
tint = getTagTint(it),
|
||||||
|
title = it.title,
|
||||||
|
data = it,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun getCounter(mangaId: Long): Int {
|
||||||
|
return if (settings.isTrackerEnabled) {
|
||||||
|
trackingRepository.getNewChaptersCount(mangaId)
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun getProgress(mangaId: Long): Float {
|
||||||
|
return if (settings.isReadingIndicatorsEnabled) {
|
||||||
|
historyRepository.getProgress(mangaId)
|
||||||
|
} else {
|
||||||
|
PROGRESS_NONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ColorRes
|
||||||
|
private fun getTagTint(tag: MangaTag): Int {
|
||||||
|
return if (tag.title.lowercase() in dict) {
|
||||||
|
R.color.warning
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readTagsDict(context: Context): ScatterSet<String> =
|
||||||
|
context.resources.openRawResource(R.raw.tags_redlist).use {
|
||||||
|
val set = MutableScatterSet<String>()
|
||||||
|
it.bufferedReader().forEachLine { x ->
|
||||||
|
val line = x.trim()
|
||||||
|
if (line.isNotEmpty()) {
|
||||||
|
set.add(line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set.trim()
|
||||||
|
set
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,7 +20,6 @@ import coil.ImageLoader
|
|||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.browser.cloudflare.CaptchaNotifier
|
|
||||||
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
|
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
|
||||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
@@ -51,7 +50,7 @@ import org.koitharu.kotatsu.list.ui.adapter.MangaListListener
|
|||||||
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
|
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.MangaItemModel
|
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
||||||
import org.koitharu.kotatsu.list.ui.size.DynamicItemSizeResolver
|
import org.koitharu.kotatsu.list.ui.size.DynamicItemSizeResolver
|
||||||
import org.koitharu.kotatsu.main.ui.MainActivity
|
import org.koitharu.kotatsu.main.ui.MainActivity
|
||||||
import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
|
import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
|
||||||
@@ -281,7 +280,7 @@ abstract class MangaListFragment :
|
|||||||
return when (item.itemId) {
|
return when (item.itemId) {
|
||||||
R.id.action_select_all -> {
|
R.id.action_select_all -> {
|
||||||
val ids = listAdapter?.items?.mapNotNull {
|
val ids = listAdapter?.items?.mapNotNull {
|
||||||
(it as? MangaItemModel)?.id
|
(it as? MangaListModel)?.id
|
||||||
} ?: return false
|
} ?: return false
|
||||||
selectionController?.addAll(ids)
|
selectionController?.addAll(ids)
|
||||||
true
|
true
|
||||||
@@ -327,7 +326,7 @@ abstract class MangaListFragment :
|
|||||||
val items = listAdapter?.items ?: return emptySet()
|
val items = listAdapter?.items ?: return emptySet()
|
||||||
val result = ArraySet<Manga>(checkedIds.size)
|
val result = ArraySet<Manga>(checkedIds.size)
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
if (item is MangaItemModel && item.id in checkedIds) {
|
if (item is MangaListModel && item.id in checkedIds) {
|
||||||
result.add(item.manga)
|
result.add(item.manga)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import org.koitharu.kotatsu.R
|
|||||||
import org.koitharu.kotatsu.core.ui.list.decor.AbstractSelectionItemDecoration
|
import org.koitharu.kotatsu.core.ui.list.decor.AbstractSelectionItemDecoration
|
||||||
import org.koitharu.kotatsu.core.util.ext.getItem
|
import org.koitharu.kotatsu.core.util.ext.getItem
|
||||||
import org.koitharu.kotatsu.core.util.ext.getThemeColor
|
import org.koitharu.kotatsu.core.util.ext.getThemeColor
|
||||||
import org.koitharu.kotatsu.list.ui.model.MangaItemModel
|
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
||||||
import com.google.android.material.R as materialR
|
import com.google.android.material.R as materialR
|
||||||
|
|
||||||
open class MangaSelectionDecoration(context: Context) : AbstractSelectionItemDecoration() {
|
open class MangaSelectionDecoration(context: Context) : AbstractSelectionItemDecoration() {
|
||||||
@@ -37,7 +37,7 @@ open class MangaSelectionDecoration(context: Context) : AbstractSelectionItemDec
|
|||||||
|
|
||||||
override fun getItemId(parent: RecyclerView, child: View): Long {
|
override fun getItemId(parent: RecyclerView, child: View): Long {
|
||||||
val holder = parent.getChildViewHolder(child) ?: return NO_ID
|
val holder = parent.getChildViewHolder(child) ?: return NO_ID
|
||||||
val item = holder.getItem(MangaItemModel::class.java) ?: return NO_ID
|
val item = holder.getItem(MangaListModel::class.java) ?: return NO_ID
|
||||||
return item.id
|
return item.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ import org.koitharu.kotatsu.core.util.ext.textAndVisible
|
|||||||
import org.koitharu.kotatsu.databinding.ItemMangaListDetailsBinding
|
import org.koitharu.kotatsu.databinding.ItemMangaListDetailsBinding
|
||||||
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.MangaListDetailedModel
|
import org.koitharu.kotatsu.list.ui.model.MangaDetailedListModel
|
||||||
|
|
||||||
fun mangaListDetailedItemAD(
|
fun mangaListDetailedItemAD(
|
||||||
coil: ImageLoader,
|
coil: ImageLoader,
|
||||||
lifecycleOwner: LifecycleOwner,
|
lifecycleOwner: LifecycleOwner,
|
||||||
clickListener: MangaDetailsClickListener,
|
clickListener: MangaDetailsClickListener,
|
||||||
) = adapterDelegateViewBinding<MangaListDetailedModel, ListModel, ItemMangaListDetailsBinding>(
|
) = adapterDelegateViewBinding<MangaDetailedListModel, ListModel, ItemMangaListDetailsBinding>(
|
||||||
{ inflater, parent -> ItemMangaListDetailsBinding.inflate(inflater, parent, false) },
|
{ inflater, parent -> ItemMangaListDetailsBinding.inflate(inflater, parent, false) },
|
||||||
) {
|
) {
|
||||||
var badge: BadgeDrawable? = null
|
var badge: BadgeDrawable? = null
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ import org.koitharu.kotatsu.core.util.ext.source
|
|||||||
import org.koitharu.kotatsu.core.util.ext.textAndVisible
|
import org.koitharu.kotatsu.core.util.ext.textAndVisible
|
||||||
import org.koitharu.kotatsu.databinding.ItemMangaListBinding
|
import org.koitharu.kotatsu.databinding.ItemMangaListBinding
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
import org.koitharu.kotatsu.list.ui.model.MangaCompactListModel
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
|
|
||||||
fun mangaListItemAD(
|
fun mangaListItemAD(
|
||||||
coil: ImageLoader,
|
coil: ImageLoader,
|
||||||
lifecycleOwner: LifecycleOwner,
|
lifecycleOwner: LifecycleOwner,
|
||||||
clickListener: OnListItemClickListener<Manga>,
|
clickListener: OnListItemClickListener<Manga>,
|
||||||
) = adapterDelegateViewBinding<MangaListModel, ListModel, ItemMangaListBinding>(
|
) = adapterDelegateViewBinding<MangaCompactListModel, ListModel, ItemMangaListBinding>(
|
||||||
{ inflater, parent -> ItemMangaListBinding.inflate(inflater, parent, false) },
|
{ inflater, parent -> ItemMangaListBinding.inflate(inflater, parent, false) },
|
||||||
) {
|
) {
|
||||||
var badge: BadgeDrawable? = null
|
var badge: BadgeDrawable? = null
|
||||||
|
|||||||
@@ -3,74 +3,8 @@ package org.koitharu.kotatsu.list.ui.model
|
|||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
|
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
|
||||||
import org.koitharu.kotatsu.core.prefs.ListMode
|
|
||||||
import org.koitharu.kotatsu.core.ui.widgets.ChipsView
|
|
||||||
import org.koitharu.kotatsu.core.util.ext.getDisplayIcon
|
import org.koitharu.kotatsu.core.util.ext.getDisplayIcon
|
||||||
import org.koitharu.kotatsu.core.util.ext.ifZero
|
import org.koitharu.kotatsu.core.util.ext.ifZero
|
||||||
import org.koitharu.kotatsu.history.data.PROGRESS_NONE
|
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
|
||||||
|
|
||||||
suspend fun Manga.toListModel(
|
|
||||||
extraProvider: ListExtraProvider?
|
|
||||||
) = MangaListModel(
|
|
||||||
id = id,
|
|
||||||
title = title,
|
|
||||||
subtitle = tags.joinToString(", ") { it.title },
|
|
||||||
coverUrl = coverUrl,
|
|
||||||
manga = this,
|
|
||||||
counter = extraProvider?.getCounter(id) ?: 0,
|
|
||||||
progress = extraProvider?.getProgress(id) ?: PROGRESS_NONE,
|
|
||||||
)
|
|
||||||
|
|
||||||
suspend fun Manga.toListDetailedModel(
|
|
||||||
extraProvider: ListExtraProvider?,
|
|
||||||
) = MangaListDetailedModel(
|
|
||||||
id = id,
|
|
||||||
title = title,
|
|
||||||
subtitle = altTitle,
|
|
||||||
coverUrl = coverUrl,
|
|
||||||
manga = this,
|
|
||||||
counter = extraProvider?.getCounter(id) ?: 0,
|
|
||||||
progress = extraProvider?.getProgress(id) ?: PROGRESS_NONE,
|
|
||||||
tags = tags.map {
|
|
||||||
ChipsView.ChipModel(
|
|
||||||
tint = extraProvider?.getTagTint(it) ?: 0,
|
|
||||||
title = it.title,
|
|
||||||
data = it,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
suspend fun Manga.toGridModel(
|
|
||||||
extraProvider: ListExtraProvider?,
|
|
||||||
) = MangaGridModel(
|
|
||||||
id = id,
|
|
||||||
title = title,
|
|
||||||
coverUrl = coverUrl,
|
|
||||||
manga = this,
|
|
||||||
counter = extraProvider?.getCounter(id) ?: 0,
|
|
||||||
progress = extraProvider?.getProgress(id) ?: PROGRESS_NONE,
|
|
||||||
)
|
|
||||||
|
|
||||||
suspend fun List<Manga>.toUi(
|
|
||||||
mode: ListMode,
|
|
||||||
extraProvider: ListExtraProvider,
|
|
||||||
): List<MangaItemModel> = if (isEmpty()) {
|
|
||||||
emptyList()
|
|
||||||
} else {
|
|
||||||
toUi(ArrayList(size), mode, extraProvider)
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun <C : MutableCollection<in MangaItemModel>> List<Manga>.toUi(
|
|
||||||
destination: C,
|
|
||||||
mode: ListMode,
|
|
||||||
extraProvider: ListExtraProvider,
|
|
||||||
): C = when (mode) {
|
|
||||||
ListMode.LIST -> mapTo(destination) { it.toListModel(extraProvider) }
|
|
||||||
ListMode.DETAILED_LIST -> mapTo(destination) { it.toListDetailedModel(extraProvider) }
|
|
||||||
ListMode.GRID -> mapTo(destination) { it.toGridModel(extraProvider) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Throwable.toErrorState(canRetry: Boolean = true, @StringRes secondaryAction: Int = 0) = ErrorState(
|
fun Throwable.toErrorState(canRetry: Boolean = true, @StringRes secondaryAction: Int = 0) = ErrorState(
|
||||||
exception = this,
|
exception = this,
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package org.koitharu.kotatsu.list.ui.model
|
||||||
|
|
||||||
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
|
|
||||||
|
data class MangaCompactListModel(
|
||||||
|
override val id: Long,
|
||||||
|
override val title: String,
|
||||||
|
val subtitle: String,
|
||||||
|
override val coverUrl: String,
|
||||||
|
override val manga: Manga,
|
||||||
|
override val counter: Int,
|
||||||
|
override val progress: Float,
|
||||||
|
) : MangaListModel()
|
||||||
@@ -3,7 +3,7 @@ package org.koitharu.kotatsu.list.ui.model
|
|||||||
import org.koitharu.kotatsu.core.ui.widgets.ChipsView
|
import org.koitharu.kotatsu.core.ui.widgets.ChipsView
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
|
|
||||||
data class MangaListDetailedModel(
|
data class MangaDetailedListModel(
|
||||||
override val id: Long,
|
override val id: Long,
|
||||||
override val title: String,
|
override val title: String,
|
||||||
val subtitle: String?,
|
val subtitle: String?,
|
||||||
@@ -12,4 +12,4 @@ data class MangaListDetailedModel(
|
|||||||
override val counter: Int,
|
override val counter: Int,
|
||||||
override val progress: Float,
|
override val progress: Float,
|
||||||
val tags: List<ChipsView.ChipModel>,
|
val tags: List<ChipsView.ChipModel>,
|
||||||
) : MangaItemModel()
|
) : MangaListModel()
|
||||||
@@ -9,4 +9,4 @@ data class MangaGridModel(
|
|||||||
override val manga: Manga,
|
override val manga: Manga,
|
||||||
override val counter: Int,
|
override val counter: Int,
|
||||||
override val progress: Float,
|
override val progress: Float,
|
||||||
) : MangaItemModel()
|
) : MangaListModel()
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.list.ui.model
|
|
||||||
|
|
||||||
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
|
||||||
|
|
||||||
sealed class MangaItemModel : ListModel {
|
|
||||||
|
|
||||||
abstract val id: Long
|
|
||||||
abstract val manga: Manga
|
|
||||||
abstract val title: String
|
|
||||||
abstract val coverUrl: String
|
|
||||||
abstract val counter: Int
|
|
||||||
abstract val progress: Float
|
|
||||||
|
|
||||||
val source: MangaSource
|
|
||||||
get() = manga.source
|
|
||||||
|
|
||||||
override fun areItemsTheSame(other: ListModel): Boolean {
|
|
||||||
return other is MangaItemModel && other.javaClass == javaClass && id == other.id
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getChangePayload(previousState: ListModel): Any? {
|
|
||||||
return when {
|
|
||||||
previousState !is MangaItemModel -> super.getChangePayload(previousState)
|
|
||||||
progress != previousState.progress -> ListModelDiffCallback.PAYLOAD_PROGRESS_CHANGED
|
|
||||||
counter != previousState.counter -> ListModelDiffCallback.PAYLOAD_ANYTHING_CHANGED
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,31 @@
|
|||||||
package org.koitharu.kotatsu.list.ui.model
|
package org.koitharu.kotatsu.list.ui.model
|
||||||
|
|
||||||
|
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
|
|
||||||
data class MangaListModel(
|
sealed class MangaListModel : ListModel {
|
||||||
override val id: Long,
|
|
||||||
override val title: String,
|
abstract val id: Long
|
||||||
val subtitle: String,
|
abstract val manga: Manga
|
||||||
override val coverUrl: String,
|
abstract val title: String
|
||||||
override val manga: Manga,
|
abstract val coverUrl: String
|
||||||
override val counter: Int,
|
abstract val counter: Int
|
||||||
override val progress: Float,
|
abstract val progress: Float
|
||||||
) : MangaItemModel()
|
|
||||||
|
val source: MangaSource
|
||||||
|
get() = manga.source
|
||||||
|
|
||||||
|
override fun areItemsTheSame(other: ListModel): Boolean {
|
||||||
|
return other is MangaListModel && other.javaClass == javaClass && id == other.id
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getChangePayload(previousState: ListModel): Any? {
|
||||||
|
return when {
|
||||||
|
previousState !is MangaListModel -> super.getChangePayload(previousState)
|
||||||
|
progress != previousState.progress -> ListModelDiffCallback.PAYLOAD_PROGRESS_CHANGED
|
||||||
|
counter != previousState.counter -> ListModelDiffCallback.PAYLOAD_ANYTHING_CHANGED
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,18 +25,17 @@ import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
|||||||
import org.koitharu.kotatsu.core.parser.MangaIntent
|
import org.koitharu.kotatsu.core.parser.MangaIntent
|
||||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||||
import org.koitharu.kotatsu.core.ui.BaseViewModel
|
import org.koitharu.kotatsu.core.ui.BaseViewModel
|
||||||
import org.koitharu.kotatsu.core.ui.widgets.ChipsView
|
|
||||||
import org.koitharu.kotatsu.core.util.ext.require
|
import org.koitharu.kotatsu.core.util.ext.require
|
||||||
import org.koitharu.kotatsu.core.util.ext.sanitize
|
import org.koitharu.kotatsu.core.util.ext.sanitize
|
||||||
import org.koitharu.kotatsu.history.data.HistoryRepository
|
import org.koitharu.kotatsu.history.data.HistoryRepository
|
||||||
import org.koitharu.kotatsu.history.data.PROGRESS_NONE
|
import org.koitharu.kotatsu.history.data.PROGRESS_NONE
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class PreviewViewModel @Inject constructor(
|
class PreviewViewModel @Inject constructor(
|
||||||
savedStateHandle: SavedStateHandle,
|
savedStateHandle: SavedStateHandle,
|
||||||
private val extraProvider: ListExtraProvider,
|
private val mangaListMapper: MangaListMapper,
|
||||||
private val repositoryFactory: MangaRepository.Factory,
|
private val repositoryFactory: MangaRepository.Factory,
|
||||||
private val historyRepository: HistoryRepository,
|
private val historyRepository: HistoryRepository,
|
||||||
private val imageGetter: Html.ImageGetter,
|
private val imageGetter: Html.ImageGetter,
|
||||||
@@ -81,13 +80,7 @@ class PreviewViewModel @Inject constructor(
|
|||||||
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.WhileSubscribed(5000), null)
|
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.WhileSubscribed(5000), null)
|
||||||
|
|
||||||
val tagsChips = manga.map {
|
val tagsChips = manga.map {
|
||||||
it.tags.map { tag ->
|
mangaListMapper.mapTags(it.tags)
|
||||||
ChipsView.ChipModel(
|
|
||||||
title = tag.title,
|
|
||||||
tint = extraProvider.getTagTint(tag),
|
|
||||||
data = tag,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, emptyList())
|
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, emptyList())
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
|||||||
import org.koitharu.kotatsu.explore.data.MangaSourcesRepository
|
import org.koitharu.kotatsu.explore.data.MangaSourcesRepository
|
||||||
import org.koitharu.kotatsu.explore.domain.ExploreRepository
|
import org.koitharu.kotatsu.explore.domain.ExploreRepository
|
||||||
import org.koitharu.kotatsu.filter.ui.FilterCoordinator
|
import org.koitharu.kotatsu.filter.ui.FilterCoordinator
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
||||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.MangaItemModel
|
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.TipModel
|
import org.koitharu.kotatsu.list.ui.model.TipModel
|
||||||
import org.koitharu.kotatsu.local.data.LocalStorageChanges
|
import org.koitharu.kotatsu.local.data.LocalStorageChanges
|
||||||
import org.koitharu.kotatsu.local.data.LocalStorageManager
|
import org.koitharu.kotatsu.local.data.LocalStorageManager
|
||||||
@@ -35,7 +35,7 @@ class LocalListViewModel @Inject constructor(
|
|||||||
filter: FilterCoordinator,
|
filter: FilterCoordinator,
|
||||||
private val settings: AppSettings,
|
private val settings: AppSettings,
|
||||||
downloadScheduler: DownloadWorker.Scheduler,
|
downloadScheduler: DownloadWorker.Scheduler,
|
||||||
listExtraProvider: ListExtraProvider,
|
mangaListMapper: MangaListMapper,
|
||||||
private val deleteLocalMangaUseCase: DeleteLocalMangaUseCase,
|
private val deleteLocalMangaUseCase: DeleteLocalMangaUseCase,
|
||||||
exploreRepository: ExploreRepository,
|
exploreRepository: ExploreRepository,
|
||||||
@LocalStorageChanges private val localStorageChanges: SharedFlow<LocalManga?>,
|
@LocalStorageChanges private val localStorageChanges: SharedFlow<LocalManga?>,
|
||||||
@@ -46,7 +46,7 @@ class LocalListViewModel @Inject constructor(
|
|||||||
mangaRepositoryFactory,
|
mangaRepositoryFactory,
|
||||||
filter,
|
filter,
|
||||||
settings,
|
settings,
|
||||||
listExtraProvider,
|
mangaListMapper,
|
||||||
downloadScheduler,
|
downloadScheduler,
|
||||||
exploreRepository,
|
exploreRepository,
|
||||||
sourcesRepository,
|
sourcesRepository,
|
||||||
@@ -70,7 +70,7 @@ class LocalListViewModel @Inject constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for (item in list) {
|
for (item in list) {
|
||||||
if (item !is MangaItemModel) {
|
if (item !is MangaListModel) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
val file = item.manga.url.toUriOrNull()?.toFileOrNull() ?: continue
|
val file = item.manga.url.toUriOrNull()?.toFileOrNull() ?: continue
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import org.koitharu.kotatsu.explore.data.MangaSourcesRepository
|
|||||||
import org.koitharu.kotatsu.explore.domain.ExploreRepository
|
import org.koitharu.kotatsu.explore.domain.ExploreRepository
|
||||||
import org.koitharu.kotatsu.filter.ui.FilterCoordinator
|
import org.koitharu.kotatsu.filter.ui.FilterCoordinator
|
||||||
import org.koitharu.kotatsu.filter.ui.MangaFilter
|
import org.koitharu.kotatsu.filter.ui.MangaFilter
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
||||||
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
@@ -40,7 +40,6 @@ import org.koitharu.kotatsu.list.ui.model.LoadingFooter
|
|||||||
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toErrorFooter
|
import org.koitharu.kotatsu.list.ui.model.toErrorFooter
|
||||||
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toUi
|
|
||||||
import org.koitharu.kotatsu.parsers.exception.NotFoundException
|
import org.koitharu.kotatsu.parsers.exception.NotFoundException
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaListFilter
|
import org.koitharu.kotatsu.parsers.model.MangaListFilter
|
||||||
@@ -55,7 +54,7 @@ open class RemoteListViewModel @Inject constructor(
|
|||||||
mangaRepositoryFactory: MangaRepository.Factory,
|
mangaRepositoryFactory: MangaRepository.Factory,
|
||||||
private val filter: FilterCoordinator,
|
private val filter: FilterCoordinator,
|
||||||
settings: AppSettings,
|
settings: AppSettings,
|
||||||
listExtraProvider: ListExtraProvider,
|
mangaListMapper: MangaListMapper,
|
||||||
downloadScheduler: DownloadWorker.Scheduler,
|
downloadScheduler: DownloadWorker.Scheduler,
|
||||||
private val exploreRepository: ExploreRepository,
|
private val exploreRepository: ExploreRepository,
|
||||||
sourcesRepository: MangaSourcesRepository,
|
sourcesRepository: MangaSourcesRepository,
|
||||||
@@ -96,7 +95,7 @@ open class RemoteListViewModel @Inject constructor(
|
|||||||
list == null -> add(LoadingState)
|
list == null -> add(LoadingState)
|
||||||
list.isEmpty() -> add(createEmptyState(canResetFilter = header.value.isFilterApplied))
|
list.isEmpty() -> add(createEmptyState(canResetFilter = header.value.isFilterApplied))
|
||||||
else -> {
|
else -> {
|
||||||
list.toUi(this, mode, listExtraProvider)
|
mangaListMapper.toListModelList(this, list, mode)
|
||||||
when {
|
when {
|
||||||
error != null -> add(error.toErrorFooter())
|
error != null -> add(error.toErrorFooter())
|
||||||
hasNext -> add(LoadingFooter())
|
hasNext -> add(LoadingFooter())
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import org.koitharu.kotatsu.core.prefs.AppSettings
|
|||||||
import org.koitharu.kotatsu.core.util.ext.require
|
import org.koitharu.kotatsu.core.util.ext.require
|
||||||
import org.koitharu.kotatsu.core.util.ext.sizeOrZero
|
import org.koitharu.kotatsu.core.util.ext.sizeOrZero
|
||||||
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
||||||
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
@@ -28,7 +28,6 @@ import org.koitharu.kotatsu.list.ui.model.LoadingFooter
|
|||||||
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toErrorFooter
|
import org.koitharu.kotatsu.list.ui.model.toErrorFooter
|
||||||
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toUi
|
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaListFilter
|
import org.koitharu.kotatsu.parsers.model.MangaListFilter
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -38,7 +37,7 @@ class SearchViewModel @Inject constructor(
|
|||||||
savedStateHandle: SavedStateHandle,
|
savedStateHandle: SavedStateHandle,
|
||||||
repositoryFactory: MangaRepository.Factory,
|
repositoryFactory: MangaRepository.Factory,
|
||||||
settings: AppSettings,
|
settings: AppSettings,
|
||||||
private val extraProvider: ListExtraProvider,
|
private val mangaListMapper: MangaListMapper,
|
||||||
downloadScheduler: DownloadWorker.Scheduler,
|
downloadScheduler: DownloadWorker.Scheduler,
|
||||||
) : MangaListViewModel(settings, downloadScheduler) {
|
) : MangaListViewModel(settings, downloadScheduler) {
|
||||||
|
|
||||||
@@ -69,7 +68,7 @@ class SearchViewModel @Inject constructor(
|
|||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
val result = ArrayList<ListModel>(list.size + 1)
|
val result = ArrayList<ListModel>(list.size + 1)
|
||||||
list.toUi(result, mode, extraProvider)
|
mangaListMapper.toListModelList(result, list, mode)
|
||||||
when {
|
when {
|
||||||
error != null -> result += error.toErrorFooter()
|
error != null -> result += error.toErrorFooter()
|
||||||
hasNext -> result += LoadingFooter()
|
hasNext -> result += LoadingFooter()
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ package org.koitharu.kotatsu.search.ui.multi
|
|||||||
|
|
||||||
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.MangaItemModel
|
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
|
|
||||||
data class MultiSearchListModel(
|
data class MultiSearchListModel(
|
||||||
val source: MangaSource,
|
val source: MangaSource,
|
||||||
val hasMore: Boolean,
|
val hasMore: Boolean,
|
||||||
val list: List<MangaItemModel>,
|
val list: List<MangaListModel>,
|
||||||
val error: Throwable?,
|
val error: Throwable?,
|
||||||
) : ListModel {
|
) : ListModel {
|
||||||
|
|
||||||
|
|||||||
@@ -29,12 +29,11 @@ import org.koitharu.kotatsu.core.util.ext.call
|
|||||||
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
|
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
|
||||||
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
||||||
import org.koitharu.kotatsu.explore.data.MangaSourcesRepository
|
import org.koitharu.kotatsu.explore.data.MangaSourcesRepository
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
||||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.LoadingFooter
|
import org.koitharu.kotatsu.list.ui.model.LoadingFooter
|
||||||
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toUi
|
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaListFilter
|
import org.koitharu.kotatsu.parsers.model.MangaListFilter
|
||||||
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
|
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
|
||||||
@@ -46,7 +45,7 @@ private const val MIN_HAS_MORE_ITEMS = 8
|
|||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class MultiSearchViewModel @Inject constructor(
|
class MultiSearchViewModel @Inject constructor(
|
||||||
savedStateHandle: SavedStateHandle,
|
savedStateHandle: SavedStateHandle,
|
||||||
private val extraProvider: ListExtraProvider,
|
private val mangaListMapper: MangaListMapper,
|
||||||
private val mangaRepositoryFactory: MangaRepository.Factory,
|
private val mangaRepositoryFactory: MangaRepository.Factory,
|
||||||
private val downloadScheduler: DownloadWorker.Scheduler,
|
private val downloadScheduler: DownloadWorker.Scheduler,
|
||||||
private val sourcesRepository: MangaSourcesRepository,
|
private val sourcesRepository: MangaSourcesRepository,
|
||||||
@@ -121,8 +120,10 @@ class MultiSearchViewModel @Inject constructor(
|
|||||||
launch {
|
launch {
|
||||||
val item = runCatchingCancellable {
|
val item = runCatchingCancellable {
|
||||||
semaphore.withPermit {
|
semaphore.withPermit {
|
||||||
repository.getList(offset = 0, filter = MangaListFilter.Search(q))
|
mangaListMapper.toListModelList(
|
||||||
.toUi(ListMode.GRID, extraProvider)
|
manga = repository.getList(offset = 0, filter = MangaListFilter.Search(q)),
|
||||||
|
mode = ListMode.GRID,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}.fold(
|
}.fold(
|
||||||
onSuccess = { list ->
|
onSuccess = { list ->
|
||||||
|
|||||||
@@ -14,12 +14,11 @@ import org.koitharu.kotatsu.core.prefs.AppSettings
|
|||||||
import org.koitharu.kotatsu.core.prefs.observeAsFlow
|
import org.koitharu.kotatsu.core.prefs.observeAsFlow
|
||||||
import org.koitharu.kotatsu.core.util.ext.onFirst
|
import org.koitharu.kotatsu.core.util.ext.onFirst
|
||||||
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
||||||
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||||
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toUi
|
|
||||||
import org.koitharu.kotatsu.suggestions.domain.SuggestionRepository
|
import org.koitharu.kotatsu.suggestions.domain.SuggestionRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -27,7 +26,7 @@ import javax.inject.Inject
|
|||||||
class SuggestionsViewModel @Inject constructor(
|
class SuggestionsViewModel @Inject constructor(
|
||||||
repository: SuggestionRepository,
|
repository: SuggestionRepository,
|
||||||
settings: AppSettings,
|
settings: AppSettings,
|
||||||
private val extraProvider: ListExtraProvider,
|
private val mangaListMapper: MangaListMapper,
|
||||||
downloadScheduler: DownloadWorker.Scheduler,
|
downloadScheduler: DownloadWorker.Scheduler,
|
||||||
private val suggestionsScheduler: SuggestionsWorker.Scheduler,
|
private val suggestionsScheduler: SuggestionsWorker.Scheduler,
|
||||||
) : MangaListViewModel(settings, downloadScheduler) {
|
) : MangaListViewModel(settings, downloadScheduler) {
|
||||||
@@ -49,7 +48,7 @@ class SuggestionsViewModel @Inject constructor(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> list.toUi(mode, extraProvider)
|
else -> mangaListMapper.toListModelList(list, mode)
|
||||||
}
|
}
|
||||||
}.onStart {
|
}.onStart {
|
||||||
loadingCounter.increment()
|
loadingCounter.increment()
|
||||||
|
|||||||
@@ -20,12 +20,11 @@ import org.koitharu.kotatsu.core.ui.model.DateTimeAgo
|
|||||||
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
|
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
|
||||||
import org.koitharu.kotatsu.core.util.ext.calculateTimeAgo
|
import org.koitharu.kotatsu.core.util.ext.calculateTimeAgo
|
||||||
import org.koitharu.kotatsu.core.util.ext.call
|
import org.koitharu.kotatsu.core.util.ext.call
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
||||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toGridModel
|
|
||||||
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
|
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
|
||||||
import org.koitharu.kotatsu.tracker.domain.model.TrackingLogItem
|
import org.koitharu.kotatsu.tracker.domain.model.TrackingLogItem
|
||||||
import org.koitharu.kotatsu.tracker.ui.feed.model.FeedItem
|
import org.koitharu.kotatsu.tracker.ui.feed.model.FeedItem
|
||||||
@@ -42,7 +41,7 @@ class FeedViewModel @Inject constructor(
|
|||||||
private val settings: AppSettings,
|
private val settings: AppSettings,
|
||||||
private val repository: TrackingRepository,
|
private val repository: TrackingRepository,
|
||||||
private val scheduler: TrackWorker.Scheduler,
|
private val scheduler: TrackWorker.Scheduler,
|
||||||
private val listExtraProvider: ListExtraProvider,
|
private val mangaListMapper: MangaListMapper,
|
||||||
) : BaseViewModel() {
|
) : BaseViewModel() {
|
||||||
|
|
||||||
private val limit = MutableStateFlow(PAGE_SIZE)
|
private val limit = MutableStateFlow(PAGE_SIZE)
|
||||||
@@ -135,7 +134,7 @@ class FeedViewModel @Inject constructor(
|
|||||||
null
|
null
|
||||||
} else {
|
} else {
|
||||||
UpdatedMangaHeader(
|
UpdatedMangaHeader(
|
||||||
mangaList.map { it.manga.toGridModel(listExtraProvider) },
|
mangaList.map { mangaListMapper.toGridModel(it.manga) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ package org.koitharu.kotatsu.tracker.ui.feed.model
|
|||||||
|
|
||||||
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.MangaItemModel
|
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
||||||
|
|
||||||
data class UpdatedMangaHeader(
|
data class UpdatedMangaHeader(
|
||||||
val list: List<MangaItemModel>,
|
val list: List<MangaListModel>,
|
||||||
) : ListModel {
|
) : ListModel {
|
||||||
|
|
||||||
override fun areItemsTheSame(other: ListModel): Boolean {
|
override fun areItemsTheSame(other: ListModel): Boolean {
|
||||||
|
|||||||
@@ -17,16 +17,13 @@ import org.koitharu.kotatsu.core.ui.model.DateTimeAgo
|
|||||||
import org.koitharu.kotatsu.core.util.ext.calculateTimeAgo
|
import org.koitharu.kotatsu.core.util.ext.calculateTimeAgo
|
||||||
import org.koitharu.kotatsu.core.util.ext.onFirst
|
import org.koitharu.kotatsu.core.util.ext.onFirst
|
||||||
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
||||||
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toGridModel
|
|
||||||
import org.koitharu.kotatsu.list.ui.model.toListDetailedModel
|
|
||||||
import org.koitharu.kotatsu.list.ui.model.toListModel
|
|
||||||
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
|
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
|
||||||
import org.koitharu.kotatsu.tracker.domain.model.MangaTracking
|
import org.koitharu.kotatsu.tracker.domain.model.MangaTracking
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -35,7 +32,7 @@ import javax.inject.Inject
|
|||||||
class UpdatesViewModel @Inject constructor(
|
class UpdatesViewModel @Inject constructor(
|
||||||
private val repository: TrackingRepository,
|
private val repository: TrackingRepository,
|
||||||
settings: AppSettings,
|
settings: AppSettings,
|
||||||
private val extraProvider: ListExtraProvider,
|
private val mangaListMapper: MangaListMapper,
|
||||||
downloadScheduler: DownloadWorker.Scheduler,
|
downloadScheduler: DownloadWorker.Scheduler,
|
||||||
) : MangaListViewModel(settings, downloadScheduler) {
|
) : MangaListViewModel(settings, downloadScheduler) {
|
||||||
|
|
||||||
@@ -93,11 +90,7 @@ class UpdatesViewModel @Inject constructor(
|
|||||||
prevHeader = header
|
prevHeader = header
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result += when (mode) {
|
result += mangaListMapper.toListModel(item.manga, mode)
|
||||||
ListMode.LIST -> item.manga.toListModel(extraProvider)
|
|
||||||
ListMode.DETAILED_LIST -> item.manga.toListDetailedModel(extraProvider)
|
|
||||||
ListMode.GRID -> item.manga.toGridModel(extraProvider)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user