Refactor list extra provider

This commit is contained in:
Koitharu
2023-06-04 17:37:54 +03:00
parent 02d5dfb375
commit 1847759ec3
21 changed files with 143 additions and 257 deletions

View File

@@ -40,8 +40,6 @@ import org.koitharu.kotatsu.core.util.IncognitoModeIndicator
import org.koitharu.kotatsu.core.util.ext.activityManager import org.koitharu.kotatsu.core.util.ext.activityManager
import org.koitharu.kotatsu.core.util.ext.connectivityManager import org.koitharu.kotatsu.core.util.ext.connectivityManager
import org.koitharu.kotatsu.core.util.ext.isLowRamDevice import org.koitharu.kotatsu.core.util.ext.isLowRamDevice
import org.koitharu.kotatsu.list.domain.ListExtraProvider
import org.koitharu.kotatsu.list.domain.ListExtraProviderImpl
import org.koitharu.kotatsu.local.data.CacheDir import org.koitharu.kotatsu.local.data.CacheDir
import org.koitharu.kotatsu.local.data.CbzFetcher import org.koitharu.kotatsu.local.data.CbzFetcher
import org.koitharu.kotatsu.local.data.LocalStorageChanges import org.koitharu.kotatsu.local.data.LocalStorageChanges
@@ -65,9 +63,6 @@ interface AppModule {
@Binds @Binds
fun bindImageGetter(coilImageGetter: CoilImageGetter): Html.ImageGetter fun bindImageGetter(coilImageGetter: CoilImageGetter): Html.ImageGetter
@Binds
fun bindListExtraProvider(impl: ListExtraProviderImpl): ListExtraProvider
companion object { companion object {
@Provides @Provides

View File

@@ -1,37 +0,0 @@
package org.koitharu.kotatsu.core.parser
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.parsers.model.MangaTag
import javax.inject.Inject
@Reusable
class MangaTagHighlighter @Inject constructor(
@ApplicationContext context: Context,
) {
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
}
}
@ColorRes
fun getTint(tag: MangaTag): Int {
return if (tag.title.lowercase() in dict) {
R.color.warning
} else {
0
}
}
}

View File

@@ -23,7 +23,6 @@ import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.bookmarks.domain.Bookmark import org.koitharu.kotatsu.bookmarks.domain.Bookmark
import org.koitharu.kotatsu.bookmarks.ui.adapter.BookmarksAdapter import org.koitharu.kotatsu.bookmarks.ui.adapter.BookmarksAdapter
import org.koitharu.kotatsu.core.model.countChaptersByBranch import org.koitharu.kotatsu.core.model.countChaptersByBranch
import org.koitharu.kotatsu.core.parser.MangaTagHighlighter
import org.koitharu.kotatsu.core.ui.BaseFragment import org.koitharu.kotatsu.core.ui.BaseFragment
import org.koitharu.kotatsu.core.ui.image.CoverSizeResolver import org.koitharu.kotatsu.core.ui.image.CoverSizeResolver
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
@@ -45,6 +44,7 @@ import org.koitharu.kotatsu.details.ui.scrobbling.ScrobblingItemDecoration
import org.koitharu.kotatsu.details.ui.scrobbling.ScrollingInfoAdapter import org.koitharu.kotatsu.details.ui.scrobbling.ScrollingInfoAdapter
import org.koitharu.kotatsu.history.data.PROGRESS_NONE import org.koitharu.kotatsu.history.data.PROGRESS_NONE
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.main.ui.owners.NoModalBottomSheetOwner import org.koitharu.kotatsu.main.ui.owners.NoModalBottomSheetOwner
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
@@ -67,7 +67,7 @@ class DetailsFragment :
lateinit var coil: ImageLoader lateinit var coil: ImageLoader
@Inject @Inject
lateinit var tagHighlighter: MangaTagHighlighter lateinit var tagHighlighter: ListExtraProvider
private val viewModel by activityViewModels<DetailsViewModel>() private val viewModel by activityViewModels<DetailsViewModel>()
@@ -283,7 +283,7 @@ class DetailsFragment :
manga.tags.map { tag -> manga.tags.map { tag ->
ChipsView.ChipModel( ChipsView.ChipModel(
title = tag.title, title = tag.title,
tint = tagHighlighter.getTint(tag), tint = tagHighlighter.getTagTint(tag),
icon = 0, icon = 0,
data = tag, data = tag,
isCheckable = false, isCheckable = false,

View File

@@ -13,7 +13,6 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.plus import kotlinx.coroutines.plus
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.parser.MangaTagHighlighter
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.util.ReversibleAction import org.koitharu.kotatsu.core.ui.util.ReversibleAction
import org.koitharu.kotatsu.core.util.ext.call import org.koitharu.kotatsu.core.util.ext.call
@@ -21,8 +20,6 @@ import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
import org.koitharu.kotatsu.favourites.domain.FavouritesRepository 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.data.HistoryRepository
import org.koitharu.kotatsu.history.data.PROGRESS_NONE
import org.koitharu.kotatsu.list.domain.ListExtraProvider import org.koitharu.kotatsu.list.domain.ListExtraProvider
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
@@ -30,19 +27,16 @@ 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.list.ui.model.toUi
import org.koitharu.kotatsu.parsers.model.SortOrder import org.koitharu.kotatsu.parsers.model.SortOrder
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
class FavouritesListViewModel @Inject constructor( class FavouritesListViewModel @Inject constructor(
savedStateHandle: SavedStateHandle, savedStateHandle: SavedStateHandle,
private val repository: FavouritesRepository, private val repository: FavouritesRepository,
private val trackingRepository: TrackingRepository, private val listExtraProvider: ListExtraProvider,
private val historyRepository: HistoryRepository, settings: AppSettings,
private val settings: AppSettings,
private val tagHighlighter: MangaTagHighlighter,
downloadScheduler: DownloadWorker.Scheduler, downloadScheduler: DownloadWorker.Scheduler,
) : MangaListViewModel(settings, downloadScheduler), ListExtraProvider { ) : MangaListViewModel(settings, downloadScheduler) {
val categoryId: Long = savedStateHandle[ARG_CATEGORY_ID] ?: NO_ID val categoryId: Long = savedStateHandle[ARG_CATEGORY_ID] ?: NO_ID
@@ -76,7 +70,7 @@ class FavouritesListViewModel @Inject constructor(
), ),
) )
else -> list.toUi(mode, this, tagHighlighter) else -> list.toUi(mode, listExtraProvider)
} }
}.catch { }.catch {
emit(listOf(it.toErrorState(canRetry = false))) emit(listOf(it.toErrorState(canRetry = false)))
@@ -108,20 +102,4 @@ class FavouritesListViewModel @Inject constructor(
repository.setCategoryOrder(categoryId, order) repository.setCategoryOrder(categoryId, order)
} }
} }
override suspend fun getCounter(mangaId: Long): Int {
return if (settings.isTrackerEnabled) {
trackingRepository.getNewChaptersCount(mangaId)
} else {
0
}
}
override suspend fun getProgress(mangaId: Long): Float {
return if (settings.isReadingIndicatorsEnabled) {
historyRepository.getProgress(mangaId)
} else {
PROGRESS_NONE
}
}
} }

View File

@@ -1,6 +1,10 @@
package org.koitharu.kotatsu.history.data package org.koitharu.kotatsu.history.data
import androidx.room.* import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import org.koitharu.kotatsu.core.db.entity.MangaEntity import org.koitharu.kotatsu.core.db.entity.MangaEntity
import org.koitharu.kotatsu.core.db.entity.TagEntity import org.koitharu.kotatsu.core.db.entity.TagEntity
@@ -20,6 +24,10 @@ abstract class HistoryDao {
@Query("SELECT * FROM history WHERE deleted_at = 0 ORDER BY updated_at DESC") @Query("SELECT * FROM history WHERE deleted_at = 0 ORDER BY updated_at DESC")
abstract fun observeAll(): Flow<List<HistoryWithManga>> abstract fun observeAll(): Flow<List<HistoryWithManga>>
@Transaction
@Query("SELECT * FROM history WHERE deleted_at = 0 ORDER BY updated_at DESC LIMIT :limit")
abstract fun observeAll(limit: Int): Flow<List<HistoryWithManga>>
@Query("SELECT * FROM manga WHERE manga_id IN (SELECT manga_id FROM history WHERE deleted_at = 0)") @Query("SELECT * FROM manga WHERE manga_id IN (SELECT manga_id FROM history WHERE deleted_at = 0)")
abstract suspend fun findAllManga(): List<MangaEntity> abstract suspend fun findAllManga(): List<MangaEntity>

View File

@@ -51,6 +51,12 @@ class HistoryRepository @Inject constructor(
} }
} }
fun observeAll(limit: Int): Flow<List<Manga>> {
return db.historyDao.observeAll(limit).mapItems {
it.manga.toManga(it.tags.toMangaTags())
}
}
fun observeAllWithHistory(): Flow<List<MangaWithHistory>> { fun observeAllWithHistory(): Flow<List<MangaWithHistory>> {
return db.historyDao.observeAll().mapItems { return db.historyDao.observeAll().mapItems {
MangaWithHistory( MangaWithHistory(

View File

@@ -10,7 +10,6 @@ import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.plus import kotlinx.coroutines.plus
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.parser.MangaTagHighlighter
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.prefs.ListMode import org.koitharu.kotatsu.core.prefs.ListMode
import org.koitharu.kotatsu.core.prefs.observeAsStateFlow import org.koitharu.kotatsu.core.prefs.observeAsStateFlow
@@ -21,8 +20,8 @@ import org.koitharu.kotatsu.core.util.ext.daysDiff
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.history.data.HistoryRepository import org.koitharu.kotatsu.history.data.HistoryRepository
import org.koitharu.kotatsu.history.data.PROGRESS_NONE
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.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
@@ -31,7 +30,6 @@ import org.koitharu.kotatsu.list.ui.model.toErrorState
import org.koitharu.kotatsu.list.ui.model.toGridModel import org.koitharu.kotatsu.list.ui.model.toGridModel
import org.koitharu.kotatsu.list.ui.model.toListDetailedModel import org.koitharu.kotatsu.list.ui.model.toListDetailedModel
import org.koitharu.kotatsu.list.ui.model.toListModel import org.koitharu.kotatsu.list.ui.model.toListModel
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
import java.util.Date import java.util.Date
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
@@ -40,8 +38,7 @@ import javax.inject.Inject
class HistoryListViewModel @Inject constructor( class HistoryListViewModel @Inject constructor(
private val repository: HistoryRepository, private val repository: HistoryRepository,
private val settings: AppSettings, private val settings: AppSettings,
private val trackingRepository: TrackingRepository, private val extraProvider: ListExtraProvider,
private val tagHighlighter: MangaTagHighlighter,
downloadScheduler: DownloadWorker.Scheduler, downloadScheduler: DownloadWorker.Scheduler,
) : MangaListViewModel(settings, downloadScheduler) { ) : MangaListViewModel(settings, downloadScheduler) {
@@ -106,7 +103,6 @@ class HistoryListViewModel @Inject constructor(
mode: ListMode, mode: ListMode,
): List<ListModel> { ): List<ListModel> {
val result = ArrayList<ListModel>(if (grouped) (list.size * 1.4).toInt() else list.size + 1) val result = ArrayList<ListModel>(if (grouped) (list.size * 1.4).toInt() else list.size + 1)
val showPercent = settings.isReadingIndicatorsEnabled
var prevDate: DateTimeAgo? = null var prevDate: DateTimeAgo? = null
for ((manga, history) in list) { for ((manga, history) in list) {
if (grouped) { if (grouped) {
@@ -116,16 +112,10 @@ class HistoryListViewModel @Inject constructor(
} }
prevDate = date prevDate = date
} }
val counter = if (settings.isTrackerEnabled) {
trackingRepository.getNewChaptersCount(manga.id)
} else {
0
}
val percent = if (showPercent) history.percent else PROGRESS_NONE
result += when (mode) { result += when (mode) {
ListMode.LIST -> manga.toListModel(counter, percent) ListMode.LIST -> manga.toListModel(extraProvider)
ListMode.DETAILED_LIST -> manga.toListDetailedModel(counter, percent, tagHighlighter) ListMode.DETAILED_LIST -> manga.toListDetailedModel(extraProvider)
ListMode.GRID -> manga.toGridModel(counter, percent) ListMode.GRID -> manga.toGridModel(extraProvider)
} }
} }
return result return result

View File

@@ -1,8 +1,60 @@
package org.koitharu.kotatsu.list.domain package org.koitharu.kotatsu.list.domain
interface ListExtraProvider { 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
suspend fun getCounter(mangaId: Long): Int @Reusable
class ListExtraProvider @Inject constructor(
@ApplicationContext context: Context,
private val settings: AppSettings,
private val trackingRepository: TrackingRepository,
private val historyRepository: HistoryRepository,
) {
suspend fun getProgress(mangaId: Long): Float 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
}
}
}

View File

@@ -1,32 +0,0 @@
package org.koitharu.kotatsu.list.domain
import dagger.Reusable
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.tracker.domain.TrackingRepository
import javax.inject.Inject
@Reusable
class ListExtraProviderImpl @Inject constructor(
private val settings: AppSettings,
private val trackingRepository: TrackingRepository,
private val historyRepository: HistoryRepository,
) : ListExtraProvider {
override suspend fun getCounter(mangaId: Long): Int {
return if (settings.isTrackerEnabled) {
trackingRepository.getNewChaptersCount(mangaId)
} else {
0
}
}
override suspend fun getProgress(mangaId: Long): Float {
return if (settings.isReadingIndicatorsEnabled) {
historyRepository.getProgress(mangaId)
} else {
PROGRESS_NONE
}
}
}

View File

@@ -3,7 +3,6 @@ package org.koitharu.kotatsu.list.ui.model
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
import org.koitharu.kotatsu.core.parser.MangaTagHighlighter
import org.koitharu.kotatsu.core.prefs.ListMode import org.koitharu.kotatsu.core.prefs.ListMode
import org.koitharu.kotatsu.core.ui.widgets.ChipsView import org.koitharu.kotatsu.core.ui.widgets.ChipsView
import org.koitharu.kotatsu.core.util.ext.ifZero import org.koitharu.kotatsu.core.util.ext.ifZero
@@ -14,34 +13,31 @@ import org.koitharu.kotatsu.parsers.model.Manga
import java.net.SocketTimeoutException import java.net.SocketTimeoutException
import java.net.UnknownHostException import java.net.UnknownHostException
fun Manga.toListModel( suspend fun Manga.toListModel(
counter: Int, extraProvider: ListExtraProvider?
progress: Float,
) = MangaListModel( ) = MangaListModel(
id = id, id = id,
title = title, title = title,
subtitle = tags.joinToString(", ") { it.title }, subtitle = tags.joinToString(", ") { it.title },
coverUrl = coverUrl, coverUrl = coverUrl,
manga = this, manga = this,
counter = counter, counter = extraProvider?.getCounter(id) ?: 0,
progress = progress, progress = extraProvider?.getProgress(id) ?: PROGRESS_NONE,
) )
fun Manga.toListDetailedModel( suspend fun Manga.toListDetailedModel(
counter: Int, extraProvider: ListExtraProvider?,
progress: Float,
tagHighlighter: MangaTagHighlighter?,
) = MangaListDetailedModel( ) = MangaListDetailedModel(
id = id, id = id,
title = title, title = title,
subtitle = altTitle, subtitle = altTitle,
coverUrl = coverUrl, coverUrl = coverUrl,
manga = this, manga = this,
counter = counter, counter = extraProvider?.getCounter(id) ?: 0,
progress = progress, progress = extraProvider?.getProgress(id) ?: PROGRESS_NONE,
tags = tags.map { tags = tags.map {
ChipsView.ChipModel( ChipsView.ChipModel(
tint = tagHighlighter?.getTint(it) ?: 0, tint = extraProvider?.getTagTint(it) ?: 0,
title = it.title, title = it.title,
icon = 0, icon = 0,
isCheckable = false, isCheckable = false,
@@ -51,53 +47,30 @@ fun Manga.toListDetailedModel(
}, },
) )
fun Manga.toGridModel(counter: Int, progress: Float) = MangaGridModel( suspend fun Manga.toGridModel(
extraProvider: ListExtraProvider?,
) = MangaGridModel(
id = id, id = id,
title = title, title = title,
coverUrl = coverUrl, coverUrl = coverUrl,
manga = this, manga = this,
counter = counter, counter = extraProvider?.getCounter(id) ?: 0,
progress = progress, progress = extraProvider?.getProgress(id) ?: PROGRESS_NONE,
) )
suspend fun List<Manga>.toUi( suspend fun List<Manga>.toUi(
mode: ListMode, mode: ListMode,
extraProvider: ListExtraProvider, extraProvider: ListExtraProvider,
tagHighlighter: MangaTagHighlighter?, ): List<MangaItemModel> = toUi(ArrayList(size), mode, extraProvider)
): List<MangaItemModel> = toUi(ArrayList(size), mode, extraProvider, tagHighlighter)
fun List<Manga>.toUi(
mode: ListMode,
tagHighlighter: MangaTagHighlighter?,
): List<MangaItemModel> = toUi(ArrayList(size), mode, tagHighlighter)
fun <C : MutableCollection<in MangaItemModel>> List<Manga>.toUi(
destination: C,
mode: ListMode,
tagHighlighter: MangaTagHighlighter?,
): C = when (mode) {
ListMode.LIST -> mapTo(destination) { it.toListModel(0, PROGRESS_NONE) }
ListMode.DETAILED_LIST -> mapTo(destination) { it.toListDetailedModel(0, PROGRESS_NONE, tagHighlighter) }
ListMode.GRID -> mapTo(destination) { it.toGridModel(0, PROGRESS_NONE) }
}
suspend fun <C : MutableCollection<in MangaItemModel>> List<Manga>.toUi( suspend fun <C : MutableCollection<in MangaItemModel>> List<Manga>.toUi(
destination: C, destination: C,
mode: ListMode, mode: ListMode,
extraProvider: ListExtraProvider, extraProvider: ListExtraProvider,
tagHighlighter: MangaTagHighlighter?,
): C = when (mode) { ): C = when (mode) {
ListMode.LIST -> mapTo(destination) { ListMode.LIST -> mapTo(destination) { it.toListModel(extraProvider) }
it.toListModel(extraProvider.getCounter(it.id), extraProvider.getProgress(it.id)) ListMode.DETAILED_LIST -> mapTo(destination) { it.toListDetailedModel(extraProvider) }
} ListMode.GRID -> mapTo(destination) { it.toGridModel(extraProvider) }
ListMode.DETAILED_LIST -> mapTo(destination) {
it.toListDetailedModel(extraProvider.getCounter(it.id), extraProvider.getProgress(it.id), tagHighlighter)
}
ListMode.GRID -> mapTo(destination) {
it.toGridModel(extraProvider.getCounter(it.id), extraProvider.getProgress(it.id))
}
} }
fun Throwable.toErrorState(canRetry: Boolean = true) = ErrorState( fun Throwable.toErrorState(canRetry: Boolean = true) = ErrorState(

View File

@@ -6,7 +6,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharedFlow
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.core.parser.MangaTagHighlighter
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
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
@@ -25,7 +24,6 @@ class LocalListViewModel @Inject constructor(
savedStateHandle: SavedStateHandle, savedStateHandle: SavedStateHandle,
mangaRepositoryFactory: MangaRepository.Factory, mangaRepositoryFactory: MangaRepository.Factory,
filter: FilterCoordinator, filter: FilterCoordinator,
tagHighlighter: MangaTagHighlighter,
settings: AppSettings, settings: AppSettings,
downloadScheduler: DownloadWorker.Scheduler, downloadScheduler: DownloadWorker.Scheduler,
listExtraProvider: ListExtraProvider, listExtraProvider: ListExtraProvider,
@@ -35,7 +33,6 @@ class LocalListViewModel @Inject constructor(
savedStateHandle, savedStateHandle,
mangaRepositoryFactory, mangaRepositoryFactory,
filter, filter,
tagHighlighter,
settings, settings,
listExtraProvider, listExtraProvider,
downloadScheduler, downloadScheduler,

View File

@@ -18,7 +18,6 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.plus import kotlinx.coroutines.plus
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.core.parser.MangaTagHighlighter
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
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
@@ -47,7 +46,6 @@ open class RemoteListViewModel @Inject constructor(
savedStateHandle: SavedStateHandle, savedStateHandle: SavedStateHandle,
mangaRepositoryFactory: MangaRepository.Factory, mangaRepositoryFactory: MangaRepository.Factory,
private val filter: FilterCoordinator, private val filter: FilterCoordinator,
private val tagHighlighter: MangaTagHighlighter,
settings: AppSettings, settings: AppSettings,
listExtraProvider: ListExtraProvider, listExtraProvider: ListExtraProvider,
downloadScheduler: DownloadWorker.Scheduler, downloadScheduler: DownloadWorker.Scheduler,
@@ -72,7 +70,7 @@ open class RemoteListViewModel @Inject constructor(
list == null -> add(LoadingState) list == null -> add(LoadingState)
list.isEmpty() -> add(createEmptyState(header.value.hasSelectedTags)) list.isEmpty() -> add(createEmptyState(header.value.hasSelectedTags))
else -> { else -> {
list.toUi(this, mode, listExtraProvider, tagHighlighter) list.toUi(this, mode, listExtraProvider)
when { when {
error != null -> add(error.toErrorFooter()) error != null -> add(error.toErrorFooter())
hasNext -> add(LoadingFooter()) hasNext -> add(LoadingFooter())

View File

@@ -13,10 +13,10 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.plus import kotlinx.coroutines.plus
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.core.parser.MangaTagHighlighter
import org.koitharu.kotatsu.core.prefs.AppSettings 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.download.ui.worker.DownloadWorker import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
import org.koitharu.kotatsu.list.domain.ListExtraProvider
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
@@ -33,7 +33,7 @@ class SearchViewModel @Inject constructor(
savedStateHandle: SavedStateHandle, savedStateHandle: SavedStateHandle,
repositoryFactory: MangaRepository.Factory, repositoryFactory: MangaRepository.Factory,
settings: AppSettings, settings: AppSettings,
private val tagHighlighter: MangaTagHighlighter, private val extraProvider: ListExtraProvider,
downloadScheduler: DownloadWorker.Scheduler, downloadScheduler: DownloadWorker.Scheduler,
) : MangaListViewModel(settings, downloadScheduler) { ) : MangaListViewModel(settings, downloadScheduler) {
@@ -64,7 +64,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, tagHighlighter) list.toUi(result, mode, extraProvider)
when { when {
error != null -> result += error.toErrorFooter() error != null -> result += error.toErrorFooter()
hasNext -> result += LoadingFooter() hasNext -> result += LoadingFooter()

View File

@@ -25,6 +25,7 @@ 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.download.ui.worker.DownloadWorker import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
import org.koitharu.kotatsu.list.domain.ListExtraProvider
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
@@ -42,6 +43,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 settings: AppSettings, private val settings: AppSettings,
private val mangaRepositoryFactory: MangaRepository.Factory, private val mangaRepositoryFactory: MangaRepository.Factory,
private val downloadScheduler: DownloadWorker.Scheduler, private val downloadScheduler: DownloadWorker.Scheduler,
@@ -128,7 +130,7 @@ class MultiSearchViewModel @Inject constructor(
async(dispatcher) { async(dispatcher) {
runCatchingCancellable { runCatchingCancellable {
val list = mangaRepositoryFactory.create(source).getList(offset = 0, query = q) val list = mangaRepositoryFactory.create(source).getList(offset = 0, query = q)
.toUi(ListMode.GRID, null) .toUi(ListMode.GRID, extraProvider)
if (list.isNotEmpty()) { if (list.isNotEmpty()) {
MultiSearchListModel(source, list.size > MIN_HAS_MORE_ITEMS, list) MultiSearchListModel(source, list.size > MIN_HAS_MORE_ITEMS, list)
} else { } else {

View File

@@ -25,6 +25,7 @@ import org.koitharu.kotatsu.suggestions.domain.SuggestionRepository
import org.koitharu.kotatsu.tracker.domain.TrackingRepository import org.koitharu.kotatsu.tracker.domain.TrackingRepository
import javax.inject.Inject import javax.inject.Inject
@Suppress("SameParameterValue")
class ShelfContentObserveUseCase @Inject constructor( class ShelfContentObserveUseCase @Inject constructor(
private val localMangaRepository: LocalMangaRepository, private val localMangaRepository: LocalMangaRepository,
private val historyRepository: HistoryRepository, private val historyRepository: HistoryRepository,
@@ -35,20 +36,20 @@ class ShelfContentObserveUseCase @Inject constructor(
) { ) {
operator fun invoke(): Flow<ShelfContent> = combine( operator fun invoke(): Flow<ShelfContent> = combine(
historyRepository.observeAllWithHistory(), historyRepository.observeAll(20),
observeLocalManga(SortOrder.UPDATED), observeLocalManga(SortOrder.UPDATED, 20),
observeFavourites(), observeFavourites(),
trackingRepository.observeUpdatedManga(), trackingRepository.observeUpdatedManga(),
suggestionRepository.observeAll(16), suggestionRepository.observeAll(20),
) { history, local, favorites, updated, suggestions -> ) { history, local, favorites, updated, suggestions ->
ShelfContent(history, favorites, updated, local, suggestions) ShelfContent(history, favorites, updated, local, suggestions)
} }
private fun observeLocalManga(sortOrder: SortOrder): Flow<List<Manga>> { private fun observeLocalManga(sortOrder: SortOrder, limit: Int): Flow<List<Manga>> {
return localStorageChanges return localStorageChanges
.onStart { emit(null) } .onStart { emit(null) }
.mapLatest { .mapLatest {
localMangaRepository.getList(0, null, sortOrder) localMangaRepository.getList(0, null, sortOrder).take(limit)
}.distinctUntilChanged() }.distinctUntilChanged()
} }

View File

@@ -1,13 +1,12 @@
package org.koitharu.kotatsu.shelf.domain.model package org.koitharu.kotatsu.shelf.domain.model
import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.core.model.FavouriteCategory
import org.koitharu.kotatsu.history.domain.model.MangaWithHistory
import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.Manga
class ShelfContent( class ShelfContent(
val history: List<MangaWithHistory>, val history: List<Manga>,
val favourites: Map<FavouriteCategory, List<Manga>>, val favourites: Map<FavouriteCategory, List<Manga>>,
val updated: Map<Manga, Int>, val updated: List<Manga>,
val local: List<Manga>, val local: List<Manga>,
val suggestions: List<Manga>, val suggestions: List<Manga>,
) { ) {

View File

@@ -23,8 +23,6 @@ import org.koitharu.kotatsu.core.util.ext.call
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
import org.koitharu.kotatsu.favourites.domain.FavouritesRepository import org.koitharu.kotatsu.favourites.domain.FavouritesRepository
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.domain.model.MangaWithHistory
import org.koitharu.kotatsu.list.domain.ListExtraProvider import org.koitharu.kotatsu.list.domain.ListExtraProvider
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
@@ -41,21 +39,20 @@ import org.koitharu.kotatsu.shelf.domain.model.ShelfContent
import org.koitharu.kotatsu.shelf.domain.model.ShelfSection import org.koitharu.kotatsu.shelf.domain.model.ShelfSection
import org.koitharu.kotatsu.shelf.ui.model.ShelfSectionModel import org.koitharu.kotatsu.shelf.ui.model.ShelfSectionModel
import org.koitharu.kotatsu.sync.domain.SyncController import org.koitharu.kotatsu.sync.domain.SyncController
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
class ShelfViewModel @Inject constructor( class ShelfViewModel @Inject constructor(
private val historyRepository: HistoryRepository, private val historyRepository: HistoryRepository,
private val favouritesRepository: FavouritesRepository, private val favouritesRepository: FavouritesRepository,
private val trackingRepository: TrackingRepository,
private val settings: AppSettings, private val settings: AppSettings,
private val downloadScheduler: DownloadWorker.Scheduler, private val downloadScheduler: DownloadWorker.Scheduler,
private val deleteLocalMangaUseCase: DeleteLocalMangaUseCase, private val deleteLocalMangaUseCase: DeleteLocalMangaUseCase,
private val listExtraProvider: ListExtraProvider,
shelfContentObserveUseCase: ShelfContentObserveUseCase, shelfContentObserveUseCase: ShelfContentObserveUseCase,
syncController: SyncController, syncController: SyncController,
networkState: NetworkState, networkState: NetworkState,
) : BaseViewModel(), ListExtraProvider { ) : BaseViewModel() {
val onActionDone = MutableEventFlow<ReversibleAction>() val onActionDone = MutableEventFlow<ReversibleAction>()
val onDownloadStarted = MutableEventFlow<Unit>() val onDownloadStarted = MutableEventFlow<Unit>()
@@ -78,22 +75,6 @@ class ShelfViewModel @Inject constructor(
} }
} }
override suspend fun getCounter(mangaId: Long): Int {
return if (settings.isTrackerEnabled) {
trackingRepository.getNewChaptersCount(mangaId)
} else {
0
}
}
override suspend fun getProgress(mangaId: Long): Float {
return if (settings.isReadingIndicatorsEnabled) {
historyRepository.getProgress(mangaId)
} else {
PROGRESS_NONE
}
}
fun removeFromFavourites(category: FavouriteCategory, ids: Set<Long>) { fun removeFromFavourites(category: FavouriteCategory, ids: Set<Long>) {
if (ids.isEmpty()) { if (ids.isEmpty()) {
return return
@@ -194,7 +175,7 @@ class ShelfViewModel @Inject constructor(
when (section) { when (section) {
ShelfSection.HISTORY -> mapHistory( ShelfSection.HISTORY -> mapHistory(
result, result,
content.history.filter { it.manga.source == MangaSource.LOCAL }, content.history.filter { it.source == MangaSource.LOCAL },
) )
ShelfSection.LOCAL -> mapLocal(result, content.local) ShelfSection.LOCAL -> mapLocal(result, content.local)
@@ -222,17 +203,14 @@ class ShelfViewModel @Inject constructor(
private suspend fun mapHistory( private suspend fun mapHistory(
destination: MutableList<in ShelfSectionModel.History>, destination: MutableList<in ShelfSectionModel.History>,
list: List<MangaWithHistory>, list: List<Manga>,
) { ) {
if (list.isEmpty()) { if (list.isEmpty()) {
return return
} }
val showPercent = settings.isReadingIndicatorsEnabled
destination += ShelfSectionModel.History( destination += ShelfSectionModel.History(
items = list.map { (manga, history) -> items = list.map { manga ->
val counter = getCounter(manga.id) manga.toGridModel(listExtraProvider)
val percent = if (showPercent) history.percent else PROGRESS_NONE
manga.toGridModel(counter, percent)
}, },
showAllButtonText = R.string.show_all, showAllButtonText = R.string.show_all,
) )
@@ -240,16 +218,15 @@ class ShelfViewModel @Inject constructor(
private suspend fun mapUpdated( private suspend fun mapUpdated(
destination: MutableList<in ShelfSectionModel.Updated>, destination: MutableList<in ShelfSectionModel.Updated>,
updated: Map<Manga, Int>, updated: List<Manga>,
) { ) {
if (updated.isEmpty()) { if (updated.isEmpty()) {
return return
} }
val showPercent = settings.isReadingIndicatorsEnabled settings.isReadingIndicatorsEnabled
destination += ShelfSectionModel.Updated( destination += ShelfSectionModel.Updated(
items = updated.map { (manga, counter) -> items = updated.map { manga ->
val percent = if (showPercent) getProgress(manga.id) else PROGRESS_NONE manga.toGridModel(listExtraProvider)
manga.toGridModel(counter, percent)
}, },
showAllButtonText = R.string.show_all, showAllButtonText = R.string.show_all,
) )
@@ -263,7 +240,7 @@ class ShelfViewModel @Inject constructor(
return return
} }
destination += ShelfSectionModel.Local( destination += ShelfSectionModel.Local(
items = local.toUi(ListMode.GRID, this, null), items = local.toUi(ListMode.GRID, listExtraProvider),
showAllButtonText = R.string.show_all, showAllButtonText = R.string.show_all,
) )
} }
@@ -276,7 +253,7 @@ class ShelfViewModel @Inject constructor(
return return
} }
destination += ShelfSectionModel.Suggestions( destination += ShelfSectionModel.Suggestions(
items = suggestions.toUi(ListMode.GRID, this, null), items = suggestions.toUi(ListMode.GRID, listExtraProvider),
showAllButtonText = R.string.show_all, showAllButtonText = R.string.show_all,
) )
} }
@@ -291,7 +268,7 @@ class ShelfViewModel @Inject constructor(
for ((category, list) in favourites) { for ((category, list) in favourites) {
if (list.isNotEmpty()) { if (list.isNotEmpty()) {
destination += ShelfSectionModel.Favourites( destination += ShelfSectionModel.Favourites(
items = list.toUi(ListMode.GRID, this, null), items = list.toUi(ListMode.GRID, listExtraProvider),
category = category, category = category,
showAllButtonText = R.string.show_all, showAllButtonText = R.string.show_all,
) )

View File

@@ -10,10 +10,10 @@ import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.plus import kotlinx.coroutines.plus
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.parser.MangaTagHighlighter
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
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.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
@@ -26,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 tagHighlighter: MangaTagHighlighter, private val extraProvider: ListExtraProvider,
downloadScheduler: DownloadWorker.Scheduler, downloadScheduler: DownloadWorker.Scheduler,
) : MangaListViewModel(settings, downloadScheduler) { ) : MangaListViewModel(settings, downloadScheduler) {
@@ -44,7 +44,7 @@ class SuggestionsViewModel @Inject constructor(
), ),
) )
else -> list.toUi(mode, tagHighlighter) else -> list.toUi(mode, extraProvider)
} }
}.onStart { }.onStart {
loadingCounter.increment() loadingCounter.increment()

View File

@@ -34,9 +34,8 @@ abstract class TracksDao {
abstract fun observeNewChapters(mangaId: Long): Flow<Int?> abstract fun observeNewChapters(mangaId: Long): Flow<Int?>
@Transaction @Transaction
@MapInfo(valueColumn = "chapters_new") @Query("SELECT manga.* FROM tracks LEFT JOIN manga ON manga.manga_id = tracks.manga_id WHERE chapters_new > 0 ORDER BY chapters_new DESC")
@Query("SELECT manga.*, chapters_new FROM tracks LEFT JOIN manga ON manga.manga_id = tracks.manga_id WHERE chapters_new > 0 ORDER BY chapters_new DESC") abstract fun observeUpdatedManga(): Flow<List<MangaWithTags>>
abstract fun observeUpdatedManga(): Flow<Map<MangaWithTags, Int>>
@Query("DELETE FROM tracks") @Query("DELETE FROM tracks")
abstract suspend fun clear() abstract suspend fun clear()

View File

@@ -12,6 +12,7 @@ import org.koitharu.kotatsu.core.db.MangaDatabase
import org.koitharu.kotatsu.core.db.entity.MangaEntity import org.koitharu.kotatsu.core.db.entity.MangaEntity
import org.koitharu.kotatsu.core.db.entity.toManga import org.koitharu.kotatsu.core.db.entity.toManga
import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.core.model.FavouriteCategory
import org.koitharu.kotatsu.core.util.ext.mapItems
import org.koitharu.kotatsu.favourites.data.toFavouriteCategory import org.koitharu.kotatsu.favourites.data.toFavouriteCategory
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
@@ -44,9 +45,9 @@ class TrackingRepository @Inject constructor(
return db.tracksDao.observeNewChapters().map { list -> list.count { it > 0 } } return db.tracksDao.observeNewChapters().map { list -> list.count { it > 0 } }
} }
fun observeUpdatedManga(): Flow<Map<Manga, Int>> { fun observeUpdatedManga(): Flow<List<Manga>> {
return db.tracksDao.observeUpdatedManga() return db.tracksDao.observeUpdatedManga()
.map { x -> x.mapKeys { it.key.toManga() } } .mapItems { it.toManga() }
.distinctUntilChanged() .distinctUntilChanged()
} }

View File

@@ -10,22 +10,16 @@ import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.plus import kotlinx.coroutines.plus
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.parser.MangaTagHighlighter
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.prefs.ListMode
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.history.data.HistoryRepository import org.koitharu.kotatsu.history.data.HistoryRepository
import org.koitharu.kotatsu.history.data.PROGRESS_NONE import org.koitharu.kotatsu.list.domain.ListExtraProvider
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.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.toUi
import org.koitharu.kotatsu.list.ui.model.toListDetailedModel
import org.koitharu.kotatsu.list.ui.model.toListModel
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.tracker.domain.TrackingRepository import org.koitharu.kotatsu.tracker.domain.TrackingRepository
import javax.inject.Inject import javax.inject.Inject
@@ -34,16 +28,16 @@ class UpdatesViewModel @Inject constructor(
private val repository: TrackingRepository, private val repository: TrackingRepository,
private val settings: AppSettings, private val settings: AppSettings,
private val historyRepository: HistoryRepository, private val historyRepository: HistoryRepository,
private val tagHighlighter: MangaTagHighlighter, private val extraProvider: ListExtraProvider,
downloadScheduler: DownloadWorker.Scheduler, downloadScheduler: DownloadWorker.Scheduler,
) : MangaListViewModel(settings, downloadScheduler) { ) : MangaListViewModel(settings, downloadScheduler) {
override val content = combine( override val content = combine(
repository.observeUpdatedManga(), repository.observeUpdatedManga(),
listMode, listMode,
) { mangaMap, mode -> ) { mangaList, mode ->
when { when {
mangaMap.isEmpty() -> listOf( mangaList.isEmpty() -> listOf(
EmptyState( EmptyState(
icon = R.drawable.ic_empty_history, icon = R.drawable.ic_empty_history,
textPrimary = R.string.text_history_holder_primary, textPrimary = R.string.text_history_holder_primary,
@@ -52,7 +46,7 @@ class UpdatesViewModel @Inject constructor(
), ),
) )
else -> mapList(mangaMap, mode) else -> mangaList.toUi(mode, extraProvider)
} }
}.onStart { }.onStart {
loadingCounter.increment() loadingCounter.increment()
@@ -65,19 +59,4 @@ class UpdatesViewModel @Inject constructor(
override fun onRefresh() = Unit override fun onRefresh() = Unit
override fun onRetry() = Unit override fun onRetry() = Unit
private suspend fun mapList(
mangaMap: Map<Manga, Int>,
mode: ListMode,
): List<ListModel> {
val showPercent = settings.isReadingIndicatorsEnabled
return mangaMap.map { (manga, counter) ->
val percent = if (showPercent) historyRepository.getProgress(manga.id) else PROGRESS_NONE
when (mode) {
ListMode.LIST -> manga.toListModel(counter, percent)
ListMode.DETAILED_LIST -> manga.toListDetailedModel(counter, percent, tagHighlighter)
ListMode.GRID -> manga.toGridModel(counter, percent)
}
}
}
} }