Highlight suspicious genres
This commit is contained in:
@@ -3,15 +3,16 @@ package org.koitharu.kotatsu.base.ui.widgets
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.View.OnClickListener
|
import android.view.View.OnClickListener
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.ColorRes
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.children
|
import androidx.core.view.children
|
||||||
import com.google.android.material.R as materialR
|
|
||||||
import com.google.android.material.chip.Chip
|
import com.google.android.material.chip.Chip
|
||||||
import com.google.android.material.chip.ChipDrawable
|
import com.google.android.material.chip.ChipDrawable
|
||||||
import com.google.android.material.chip.ChipGroup
|
import com.google.android.material.chip.ChipGroup
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.utils.ext.castOrNull
|
import org.koitharu.kotatsu.utils.ext.castOrNull
|
||||||
import org.koitharu.kotatsu.utils.ext.getThemeColorStateList
|
import org.koitharu.kotatsu.utils.ext.getThemeColorStateList
|
||||||
|
import com.google.android.material.R as materialR
|
||||||
|
|
||||||
class ChipsView @JvmOverloads constructor(
|
class ChipsView @JvmOverloads constructor(
|
||||||
context: Context,
|
context: Context,
|
||||||
@@ -75,12 +76,12 @@ class ChipsView @JvmOverloads constructor(
|
|||||||
|
|
||||||
private fun bindChip(chip: Chip, model: ChipModel) {
|
private fun bindChip(chip: Chip, model: ChipModel) {
|
||||||
chip.text = model.title
|
chip.text = model.title
|
||||||
if (model.icon == 0) {
|
val tint = if (model.tint == 0) {
|
||||||
chip.isChipIconVisible = false
|
null
|
||||||
} else {
|
} else {
|
||||||
chip.isChipIconVisible = true
|
ContextCompat.getColorStateList(context, model.tint)
|
||||||
chip.setChipIconResource(model.icon)
|
|
||||||
}
|
}
|
||||||
|
chip.buttonTintList = tint
|
||||||
chip.isClickable = onChipClickListener != null || model.isCheckable
|
chip.isClickable = onChipClickListener != null || model.isCheckable
|
||||||
chip.isCheckable = model.isCheckable
|
chip.isCheckable = model.isCheckable
|
||||||
chip.isChecked = model.isChecked
|
chip.isChecked = model.isChecked
|
||||||
@@ -92,6 +93,7 @@ class ChipsView @JvmOverloads constructor(
|
|||||||
val drawable = ChipDrawable.createFromAttributes(context, null, 0, R.style.Widget_Kotatsu_Chip)
|
val drawable = ChipDrawable.createFromAttributes(context, null, 0, R.style.Widget_Kotatsu_Chip)
|
||||||
chip.setChipDrawable(drawable)
|
chip.setChipDrawable(drawable)
|
||||||
chip.isCheckedIconVisible = true
|
chip.isCheckedIconVisible = true
|
||||||
|
chip.isChipIconVisible = false
|
||||||
chip.setCheckedIconResource(R.drawable.ic_check)
|
chip.setCheckedIconResource(R.drawable.ic_check)
|
||||||
chip.checkedIconTint = context.getThemeColorStateList(materialR.attr.colorControlNormal)
|
chip.checkedIconTint = context.getThemeColorStateList(materialR.attr.colorControlNormal)
|
||||||
chip.isCloseIconVisible = onChipCloseClickListener != null
|
chip.isCloseIconVisible = onChipCloseClickListener != null
|
||||||
@@ -113,7 +115,7 @@ class ChipsView @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ChipModel(
|
class ChipModel(
|
||||||
@DrawableRes val icon: Int,
|
@ColorRes val tint: Int,
|
||||||
val title: CharSequence,
|
val title: CharSequence,
|
||||||
val isCheckable: Boolean,
|
val isCheckable: Boolean,
|
||||||
val isChecked: Boolean,
|
val isChecked: Boolean,
|
||||||
@@ -126,7 +128,7 @@ class ChipsView @JvmOverloads constructor(
|
|||||||
|
|
||||||
other as ChipModel
|
other as ChipModel
|
||||||
|
|
||||||
if (icon != other.icon) return false
|
if (tint != other.tint) return false
|
||||||
if (title != other.title) return false
|
if (title != other.title) return false
|
||||||
if (isCheckable != other.isCheckable) return false
|
if (isCheckable != other.isCheckable) return false
|
||||||
if (isChecked != other.isChecked) return false
|
if (isChecked != other.isChecked) return false
|
||||||
@@ -136,7 +138,7 @@ class ChipsView @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
var result = icon
|
var result = tint.hashCode()
|
||||||
result = 31 * result + title.hashCode()
|
result = 31 * result + title.hashCode()
|
||||||
result = 31 * result + isCheckable.hashCode()
|
result = 31 * result + isCheckable.hashCode()
|
||||||
result = 31 * result + isChecked.hashCode()
|
result = 31 * result + isChecked.hashCode()
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
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 = context.resources.getStringArray(R.array.genres_warnlist).toSet()
|
||||||
|
|
||||||
|
@ColorRes
|
||||||
|
fun getTint(tag: MangaTag): Int {
|
||||||
|
return if (tag.title.lowercase() in dict) {
|
||||||
|
R.color.warning
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ import org.koitharu.kotatsu.base.ui.list.decor.SpacingItemDecoration
|
|||||||
import org.koitharu.kotatsu.base.ui.widgets.ChipsView
|
import org.koitharu.kotatsu.base.ui.widgets.ChipsView
|
||||||
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.parser.MangaTagHighlighter
|
||||||
import org.koitharu.kotatsu.databinding.FragmentDetailsBinding
|
import org.koitharu.kotatsu.databinding.FragmentDetailsBinding
|
||||||
import org.koitharu.kotatsu.details.ui.model.ChapterListItem
|
import org.koitharu.kotatsu.details.ui.model.ChapterListItem
|
||||||
import org.koitharu.kotatsu.details.ui.model.HistoryInfo
|
import org.koitharu.kotatsu.details.ui.model.HistoryInfo
|
||||||
@@ -69,6 +70,9 @@ class DetailsFragment :
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var coil: ImageLoader
|
lateinit var coil: ImageLoader
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var tagHighlighter: MangaTagHighlighter
|
||||||
|
|
||||||
private val viewModel by activityViewModels<DetailsViewModel>()
|
private val viewModel by activityViewModels<DetailsViewModel>()
|
||||||
|
|
||||||
override fun onInflateView(
|
override fun onInflateView(
|
||||||
@@ -321,7 +325,7 @@ class DetailsFragment :
|
|||||||
manga.tags.map { tag ->
|
manga.tags.map { tag ->
|
||||||
ChipsView.ChipModel(
|
ChipsView.ChipModel(
|
||||||
title = tag.title,
|
title = tag.title,
|
||||||
icon = 0,
|
tint = tagHighlighter.getTint(tag),
|
||||||
data = tag,
|
data = tag,
|
||||||
isCheckable = false,
|
isCheckable = false,
|
||||||
isChecked = false,
|
isChecked = false,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import kotlinx.coroutines.flow.map
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.base.ui.util.ReversibleAction
|
import org.koitharu.kotatsu.base.ui.util.ReversibleAction
|
||||||
|
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.favourites.domain.FavouritesRepository
|
import org.koitharu.kotatsu.favourites.domain.FavouritesRepository
|
||||||
import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment.Companion.NO_ID
|
import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment.Companion.NO_ID
|
||||||
@@ -36,6 +37,7 @@ class FavouritesListViewModel @AssistedInject constructor(
|
|||||||
private val trackingRepository: TrackingRepository,
|
private val trackingRepository: TrackingRepository,
|
||||||
private val historyRepository: HistoryRepository,
|
private val historyRepository: HistoryRepository,
|
||||||
private val settings: AppSettings,
|
private val settings: AppSettings,
|
||||||
|
private val tagHighlighter: MangaTagHighlighter,
|
||||||
) : MangaListViewModel(settings), ListExtraProvider {
|
) : MangaListViewModel(settings), ListExtraProvider {
|
||||||
|
|
||||||
var categoryName: String? = null
|
var categoryName: String? = null
|
||||||
@@ -71,7 +73,7 @@ class FavouritesListViewModel @AssistedInject constructor(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> list.toUi(mode, this)
|
else -> list.toUi(mode, this, tagHighlighter)
|
||||||
}
|
}
|
||||||
}.catch {
|
}.catch {
|
||||||
emit(listOf(it.toErrorState(canRetry = false)))
|
emit(listOf(it.toErrorState(canRetry = false)))
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import kotlinx.coroutines.flow.onEach
|
|||||||
import kotlinx.coroutines.flow.onStart
|
import kotlinx.coroutines.flow.onStart
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.base.ui.util.ReversibleAction
|
import org.koitharu.kotatsu.base.ui.util.ReversibleAction
|
||||||
|
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.observeAsFlow
|
import org.koitharu.kotatsu.core.prefs.observeAsFlow
|
||||||
@@ -38,6 +39,7 @@ 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 trackingRepository: TrackingRepository,
|
||||||
|
private val tagHighlighter: MangaTagHighlighter,
|
||||||
) : MangaListViewModel(settings) {
|
) : MangaListViewModel(settings) {
|
||||||
|
|
||||||
val isGroupingEnabled = MutableLiveData<Boolean>()
|
val isGroupingEnabled = MutableLiveData<Boolean>()
|
||||||
@@ -118,7 +120,7 @@ class HistoryListViewModel @Inject constructor(
|
|||||||
val percent = if (showPercent) history.percent else PROGRESS_NONE
|
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(counter, percent)
|
||||||
ListMode.DETAILED_LIST -> manga.toListDetailedModel(counter, percent)
|
ListMode.DETAILED_LIST -> manga.toListDetailedModel(counter, percent, tagHighlighter)
|
||||||
ListMode.GRID -> manga.toGridModel(counter, percent)
|
ListMode.GRID -> manga.toGridModel(counter, percent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.koitharu.kotatsu.R
|
|||||||
import org.koitharu.kotatsu.base.ui.widgets.ChipsView
|
import org.koitharu.kotatsu.base.ui.widgets.ChipsView
|
||||||
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.history.domain.PROGRESS_NONE
|
import org.koitharu.kotatsu.history.domain.PROGRESS_NONE
|
||||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
||||||
@@ -13,7 +14,10 @@ import org.koitharu.kotatsu.utils.ext.ifZero
|
|||||||
import java.net.SocketTimeoutException
|
import java.net.SocketTimeoutException
|
||||||
import java.net.UnknownHostException
|
import java.net.UnknownHostException
|
||||||
|
|
||||||
fun Manga.toListModel(counter: Int, progress: Float) = MangaListModel(
|
fun Manga.toListModel(
|
||||||
|
counter: Int,
|
||||||
|
progress: Float,
|
||||||
|
) = MangaListModel(
|
||||||
id = id,
|
id = id,
|
||||||
title = title,
|
title = title,
|
||||||
subtitle = tags.joinToString(", ") { it.title },
|
subtitle = tags.joinToString(", ") { it.title },
|
||||||
@@ -23,7 +27,11 @@ fun Manga.toListModel(counter: Int, progress: Float) = MangaListModel(
|
|||||||
progress = progress,
|
progress = progress,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun Manga.toListDetailedModel(counter: Int, progress: Float) = MangaListDetailedModel(
|
fun Manga.toListDetailedModel(
|
||||||
|
counter: Int,
|
||||||
|
progress: Float,
|
||||||
|
tagHighlighter: MangaTagHighlighter?,
|
||||||
|
) = MangaListDetailedModel(
|
||||||
id = id,
|
id = id,
|
||||||
title = title,
|
title = title,
|
||||||
subtitle = altTitle,
|
subtitle = altTitle,
|
||||||
@@ -31,7 +39,15 @@ fun Manga.toListDetailedModel(counter: Int, progress: Float) = MangaListDetailed
|
|||||||
manga = this,
|
manga = this,
|
||||||
counter = counter,
|
counter = counter,
|
||||||
progress = progress,
|
progress = progress,
|
||||||
tags = tags.map { ChipsView.ChipModel(0, it.title, false, false, it) },
|
tags = tags.map {
|
||||||
|
ChipsView.ChipModel(
|
||||||
|
tint = tagHighlighter?.getTint(it) ?: 0,
|
||||||
|
title = it.title,
|
||||||
|
isCheckable = false,
|
||||||
|
isChecked = false,
|
||||||
|
data = it,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
fun Manga.toGridModel(counter: Int, progress: Float) = MangaGridModel(
|
fun Manga.toGridModel(counter: Int, progress: Float) = MangaGridModel(
|
||||||
@@ -46,18 +62,21 @@ fun Manga.toGridModel(counter: Int, progress: Float) = MangaGridModel(
|
|||||||
suspend fun List<Manga>.toUi(
|
suspend fun List<Manga>.toUi(
|
||||||
mode: ListMode,
|
mode: ListMode,
|
||||||
extraProvider: ListExtraProvider,
|
extraProvider: ListExtraProvider,
|
||||||
): List<MangaItemModel> = toUi(ArrayList(size), mode, extraProvider)
|
tagHighlighter: MangaTagHighlighter?,
|
||||||
|
): List<MangaItemModel> = toUi(ArrayList(size), mode, extraProvider, tagHighlighter)
|
||||||
|
|
||||||
fun List<Manga>.toUi(
|
fun List<Manga>.toUi(
|
||||||
mode: ListMode,
|
mode: ListMode,
|
||||||
): List<MangaItemModel> = toUi(ArrayList(size), mode)
|
tagHighlighter: MangaTagHighlighter?,
|
||||||
|
): List<MangaItemModel> = toUi(ArrayList(size), mode, tagHighlighter)
|
||||||
|
|
||||||
fun <C : MutableCollection<in MangaItemModel>> List<Manga>.toUi(
|
fun <C : MutableCollection<in MangaItemModel>> List<Manga>.toUi(
|
||||||
destination: C,
|
destination: C,
|
||||||
mode: ListMode,
|
mode: ListMode,
|
||||||
|
tagHighlighter: MangaTagHighlighter?,
|
||||||
): C = when (mode) {
|
): C = when (mode) {
|
||||||
ListMode.LIST -> mapTo(destination) { it.toListModel(0, PROGRESS_NONE) }
|
ListMode.LIST -> mapTo(destination) { it.toListModel(0, PROGRESS_NONE) }
|
||||||
ListMode.DETAILED_LIST -> mapTo(destination) { it.toListDetailedModel(0, PROGRESS_NONE) }
|
ListMode.DETAILED_LIST -> mapTo(destination) { it.toListDetailedModel(0, PROGRESS_NONE, tagHighlighter) }
|
||||||
ListMode.GRID -> mapTo(destination) { it.toGridModel(0, PROGRESS_NONE) }
|
ListMode.GRID -> mapTo(destination) { it.toGridModel(0, PROGRESS_NONE) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,13 +84,14 @@ 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.getCounter(it.id), extraProvider.getProgress(it.id))
|
it.toListModel(extraProvider.getCounter(it.id), extraProvider.getProgress(it.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
ListMode.DETAILED_LIST -> mapTo(destination) {
|
ListMode.DETAILED_LIST -> mapTo(destination) {
|
||||||
it.toListDetailedModel(extraProvider.getCounter(it.id), extraProvider.getProgress(it.id))
|
it.toListDetailedModel(extraProvider.getCounter(it.id), extraProvider.getProgress(it.id), tagHighlighter)
|
||||||
}
|
}
|
||||||
|
|
||||||
ListMode.GRID -> mapTo(destination) {
|
ListMode.GRID -> mapTo(destination) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.base.ui.widgets.ChipsView
|
import org.koitharu.kotatsu.base.ui.widgets.ChipsView
|
||||||
|
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.download.ui.service.DownloadService
|
import org.koitharu.kotatsu.download.ui.service.DownloadService
|
||||||
import org.koitharu.kotatsu.history.domain.HistoryRepository
|
import org.koitharu.kotatsu.history.domain.HistoryRepository
|
||||||
@@ -46,6 +47,7 @@ class LocalListViewModel @Inject constructor(
|
|||||||
private val historyRepository: HistoryRepository,
|
private val historyRepository: HistoryRepository,
|
||||||
private val trackingRepository: TrackingRepository,
|
private val trackingRepository: TrackingRepository,
|
||||||
private val settings: AppSettings,
|
private val settings: AppSettings,
|
||||||
|
private val tagHighlighter: MangaTagHighlighter,
|
||||||
) : MangaListViewModel(settings), ListExtraProvider {
|
) : MangaListViewModel(settings), ListExtraProvider {
|
||||||
|
|
||||||
val onMangaRemoved = SingleLiveEvent<Unit>()
|
val onMangaRemoved = SingleLiveEvent<Unit>()
|
||||||
@@ -76,7 +78,7 @@ class LocalListViewModel @Inject constructor(
|
|||||||
|
|
||||||
else -> buildList(list.size + 1) {
|
else -> buildList(list.size + 1) {
|
||||||
add(createHeader(list, tags, order))
|
add(createHeader(list, tags, order))
|
||||||
list.toUi(this, mode, this@LocalListViewModel)
|
list.toUi(this, mode, this@LocalListViewModel, tagHighlighter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default, listOf(LoadingState))
|
}.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default, listOf(LoadingState))
|
||||||
@@ -170,7 +172,7 @@ class LocalListViewModel @Inject constructor(
|
|||||||
val chips = LinkedList<ChipsView.ChipModel>()
|
val chips = LinkedList<ChipsView.ChipModel>()
|
||||||
for ((tag, _) in topTags) {
|
for ((tag, _) in topTags) {
|
||||||
val model = ChipsView.ChipModel(
|
val model = ChipsView.ChipModel(
|
||||||
icon = 0,
|
tint = 0,
|
||||||
title = tag.title,
|
title = tag.title,
|
||||||
isCheckable = true,
|
isCheckable = true,
|
||||||
isChecked = tag in selectedTags,
|
isChecked = tag in selectedTags,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.koitharu.kotatsu.R
|
|||||||
import org.koitharu.kotatsu.base.domain.MangaDataRepository
|
import org.koitharu.kotatsu.base.domain.MangaDataRepository
|
||||||
import org.koitharu.kotatsu.base.ui.widgets.ChipsView
|
import org.koitharu.kotatsu.base.ui.widgets.ChipsView
|
||||||
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.parser.RemoteMangaRepository
|
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
||||||
@@ -49,6 +50,7 @@ class RemoteListViewModel @AssistedInject constructor(
|
|||||||
private val searchRepository: MangaSearchRepository,
|
private val searchRepository: MangaSearchRepository,
|
||||||
settings: AppSettings,
|
settings: AppSettings,
|
||||||
dataRepository: MangaDataRepository,
|
dataRepository: MangaDataRepository,
|
||||||
|
private val tagHighlighter: MangaTagHighlighter,
|
||||||
) : MangaListViewModel(settings), OnFilterChangedListener {
|
) : MangaListViewModel(settings), OnFilterChangedListener {
|
||||||
|
|
||||||
private val repository = mangaRepositoryFactory.create(source) as RemoteMangaRepository
|
private val repository = mangaRepositoryFactory.create(source) as RemoteMangaRepository
|
||||||
@@ -75,7 +77,7 @@ class RemoteListViewModel @AssistedInject constructor(
|
|||||||
list == null -> add(LoadingState)
|
list == null -> add(LoadingState)
|
||||||
list.isEmpty() -> add(createEmptyState(header.hasSelectedTags))
|
list.isEmpty() -> add(createEmptyState(header.hasSelectedTags))
|
||||||
else -> {
|
else -> {
|
||||||
list.toUi(this, mode)
|
list.toUi(this, mode, tagHighlighter)
|
||||||
when {
|
when {
|
||||||
error != null -> add(error.toErrorFooter())
|
error != null -> add(error.toErrorFooter())
|
||||||
hasNext -> add(LoadingFooter)
|
hasNext -> add(LoadingFooter)
|
||||||
@@ -192,7 +194,7 @@ class RemoteListViewModel @AssistedInject constructor(
|
|||||||
val result = LinkedList<ChipsView.ChipModel>()
|
val result = LinkedList<ChipsView.ChipModel>()
|
||||||
for (tag in tags) {
|
for (tag in tags) {
|
||||||
val model = ChipsView.ChipModel(
|
val model = ChipsView.ChipModel(
|
||||||
icon = 0,
|
tint = 0,
|
||||||
title = tag.title,
|
title = tag.title,
|
||||||
isCheckable = true,
|
isCheckable = true,
|
||||||
isChecked = selectedTags.remove(tag),
|
isChecked = selectedTags.remove(tag),
|
||||||
@@ -206,7 +208,7 @@ class RemoteListViewModel @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
for (tag in selectedTags) {
|
for (tag in selectedTags) {
|
||||||
val model = ChipsView.ChipModel(
|
val model = ChipsView.ChipModel(
|
||||||
icon = 0,
|
tint = 0,
|
||||||
title = tag.title,
|
title = tag.title,
|
||||||
isCheckable = true,
|
isCheckable = true,
|
||||||
isChecked = true,
|
isChecked = true,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
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.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
|
||||||
@@ -29,6 +30,7 @@ class SearchViewModel @AssistedInject constructor(
|
|||||||
@Assisted private val query: String,
|
@Assisted private val query: String,
|
||||||
repositoryFactory: MangaRepository.Factory,
|
repositoryFactory: MangaRepository.Factory,
|
||||||
settings: AppSettings,
|
settings: AppSettings,
|
||||||
|
private val tagHighlighter: MangaTagHighlighter,
|
||||||
) : MangaListViewModel(settings) {
|
) : MangaListViewModel(settings) {
|
||||||
|
|
||||||
private val repository = repositoryFactory.create(source)
|
private val repository = repositoryFactory.create(source)
|
||||||
@@ -57,7 +59,7 @@ class SearchViewModel @AssistedInject constructor(
|
|||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
val result = ArrayList<ListModel>(list.size + 1)
|
val result = ArrayList<ListModel>(list.size + 1)
|
||||||
list.toUi(result, mode)
|
list.toUi(result, mode, tagHighlighter)
|
||||||
when {
|
when {
|
||||||
error != null -> result += error.toErrorFooter()
|
error != null -> result += error.toErrorFooter()
|
||||||
hasNext -> result += LoadingFooter
|
hasNext -> result += LoadingFooter
|
||||||
|
|||||||
@@ -6,7 +6,12 @@ import androidx.lifecycle.viewModelScope
|
|||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.CancellationException
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.cancelAndJoin
|
||||||
|
import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
@@ -16,7 +21,12 @@ import org.koitharu.kotatsu.core.exceptions.CompositeException
|
|||||||
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.prefs.AppSettings
|
||||||
import org.koitharu.kotatsu.core.prefs.ListMode
|
import org.koitharu.kotatsu.core.prefs.ListMode
|
||||||
import org.koitharu.kotatsu.list.ui.model.*
|
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.LoadingFooter
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||||
|
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.utils.ext.asLiveDataDistinct
|
import org.koitharu.kotatsu.utils.ext.asLiveDataDistinct
|
||||||
import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
|
import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
|
||||||
@@ -104,7 +114,7 @@ class MultiSearchViewModel @AssistedInject 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)
|
.toUi(ListMode.GRID, null)
|
||||||
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 {
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ class SearchSuggestionViewModel @Inject constructor(
|
|||||||
|
|
||||||
private fun mapTags(tags: List<MangaTag>): List<ChipsView.ChipModel> = tags.map { tag ->
|
private fun mapTags(tags: List<MangaTag>): List<ChipsView.ChipModel> = tags.map { tag ->
|
||||||
ChipsView.ChipModel(
|
ChipsView.ChipModel(
|
||||||
icon = 0,
|
tint = 0,
|
||||||
title = tag.title,
|
title = tag.title,
|
||||||
data = tag,
|
data = tag,
|
||||||
isCheckable = false,
|
isCheckable = false,
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ class ShelfViewModel @Inject constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
destination += ShelfSectionModel.Local(
|
destination += ShelfSectionModel.Local(
|
||||||
items = local.toUi(ListMode.GRID, this),
|
items = local.toUi(ListMode.GRID, this, null),
|
||||||
showAllButtonText = R.string.show_all,
|
showAllButtonText = R.string.show_all,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -251,7 +251,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),
|
items = list.toUi(ListMode.GRID, this, null),
|
||||||
category = category,
|
category = category,
|
||||||
showAllButtonText = R.string.show_all,
|
showAllButtonText = R.string.show_all,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import kotlinx.coroutines.flow.catch
|
|||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.onStart
|
import kotlinx.coroutines.flow.onStart
|
||||||
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.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
|
||||||
@@ -22,6 +23,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,
|
||||||
) : MangaListViewModel(settings) {
|
) : MangaListViewModel(settings) {
|
||||||
|
|
||||||
override val content = combine(
|
override val content = combine(
|
||||||
@@ -38,7 +40,7 @@ class SuggestionsViewModel @Inject constructor(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> list.toUi(mode)
|
else -> list.toUi(mode, tagHighlighter)
|
||||||
}
|
}
|
||||||
}.onStart {
|
}.onStart {
|
||||||
loadingCounter.increment()
|
loadingCounter.increment()
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import kotlinx.coroutines.flow.catch
|
|||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.onStart
|
import kotlinx.coroutines.flow.onStart
|
||||||
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.history.domain.HistoryRepository
|
import org.koitharu.kotatsu.history.domain.HistoryRepository
|
||||||
@@ -30,6 +31,7 @@ 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,
|
||||||
) : MangaListViewModel(settings) {
|
) : MangaListViewModel(settings) {
|
||||||
|
|
||||||
override val content = combine(
|
override val content = combine(
|
||||||
@@ -69,7 +71,7 @@ class UpdatesViewModel @Inject constructor(
|
|||||||
val percent = if (showPercent) historyRepository.getProgress(manga.id) else PROGRESS_NONE
|
val percent = if (showPercent) historyRepository.getProgress(manga.id) else PROGRESS_NONE
|
||||||
when (mode) {
|
when (mode) {
|
||||||
ListMode.LIST -> manga.toListModel(counter, percent)
|
ListMode.LIST -> manga.toListModel(counter, percent)
|
||||||
ListMode.DETAILED_LIST -> manga.toListDetailedModel(counter, percent)
|
ListMode.DETAILED_LIST -> manga.toListDetailedModel(counter, percent, tagHighlighter)
|
||||||
ListMode.GRID -> manga.toGridModel(counter, percent)
|
ListMode.GRID -> manga.toGridModel(counter, percent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,5 +9,5 @@
|
|||||||
<color name="selector_foreground">#29FFFFFF</color>
|
<color name="selector_foreground">#29FFFFFF</color>
|
||||||
<color name="divider_default">#1FFFFFFF</color>
|
<color name="divider_default">#1FFFFFFF</color>
|
||||||
<color name="status_bar_incognito">#260052</color>
|
<color name="status_bar_incognito">#260052</color>
|
||||||
|
<color name="warning">#EF6C00</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -22,4 +22,5 @@
|
|||||||
<color name="selector_foreground">#29000000</color>
|
<color name="selector_foreground">#29000000</color>
|
||||||
<color name="divider_default">#1F000000</color>
|
<color name="divider_default">#1F000000</color>
|
||||||
<color name="status_bar_incognito">#334800E0</color>
|
<color name="status_bar_incognito">#334800E0</color>
|
||||||
|
<color name="warning">#FFA726</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -38,4 +38,10 @@
|
|||||||
<item>2</item>
|
<item>2</item>
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
<string-array name="genres_warnlist" translatable="false">
|
||||||
|
<item>yaoi</item>
|
||||||
|
<item>яой</item>
|
||||||
|
<item>yuri</item>
|
||||||
|
<item>юри</item>
|
||||||
|
</string-array>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user