Fix pages thumbnails loading
This commit is contained in:
@@ -2,9 +2,9 @@ package org.koitharu.kotatsu.core.model
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import java.util.Date
|
||||
|
||||
@Parcelize
|
||||
@@ -12,7 +12,7 @@ data class FavouriteCategory(
|
||||
val id: Long,
|
||||
val title: String,
|
||||
val sortKey: Int,
|
||||
val order: SortOrder,
|
||||
val order: ListSortOrder,
|
||||
val createdAt: Date,
|
||||
val isTrackingEnabled: Boolean,
|
||||
val isVisibleInLibrary: Boolean,
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.putEnumValue
|
||||
import org.koitharu.kotatsu.core.util.ext.takeIfReadable
|
||||
import org.koitharu.kotatsu.core.util.ext.toUriOrNull
|
||||
import org.koitharu.kotatsu.history.domain.model.HistoryOrder
|
||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.util.find
|
||||
import org.koitharu.kotatsu.parsers.util.mapNotNullToSet
|
||||
@@ -76,6 +76,10 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
||||
get() = prefs.getEnumValue(KEY_LIST_MODE_HISTORY, listMode)
|
||||
set(value) = prefs.edit { putEnumValue(KEY_LIST_MODE_HISTORY, value) }
|
||||
|
||||
var suggestionsListMode: ListMode
|
||||
get() = prefs.getEnumValue(KEY_LIST_MODE_SUGGESTIONS, listMode)
|
||||
set(value) = prefs.edit { putEnumValue(KEY_LIST_MODE_SUGGESTIONS, value) }
|
||||
|
||||
var favoritesListMode: ListMode
|
||||
get() = prefs.getEnumValue(KEY_LIST_MODE_FAVORITES, listMode)
|
||||
set(value) = prefs.edit { putEnumValue(KEY_LIST_MODE_FAVORITES, value) }
|
||||
@@ -315,8 +319,8 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
||||
get() = prefs.getEnumValue(KEY_LOCAL_LIST_ORDER, SortOrder.NEWEST)
|
||||
set(value) = prefs.edit { putEnumValue(KEY_LOCAL_LIST_ORDER, value) }
|
||||
|
||||
var historySortOrder: HistoryOrder
|
||||
get() = prefs.getEnumValue(KEY_HISTORY_ORDER, HistoryOrder.UPDATED)
|
||||
var historySortOrder: ListSortOrder
|
||||
get() = prefs.getEnumValue(KEY_HISTORY_ORDER, ListSortOrder.UPDATED)
|
||||
set(value) = prefs.edit { putEnumValue(KEY_HISTORY_ORDER, value) }
|
||||
|
||||
val isRelatedMangaEnabled: Boolean
|
||||
@@ -417,6 +421,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
||||
const val KEY_LIST_MODE = "list_mode_2"
|
||||
const val KEY_LIST_MODE_HISTORY = "list_mode_history"
|
||||
const val KEY_LIST_MODE_FAVORITES = "list_mode_favorites"
|
||||
const val KEY_LIST_MODE_SUGGESTIONS = "list_mode_suggestions"
|
||||
const val KEY_THEME = "theme"
|
||||
const val KEY_COLOR_THEME = "color_theme"
|
||||
const val KEY_THEME_AMOLED = "amoled_theme"
|
||||
|
||||
@@ -55,3 +55,5 @@ inline fun <reified E : Enum<E>> Collection<E>.toEnumSet(): EnumSet<E> = if (isE
|
||||
} else {
|
||||
EnumSet.copyOf(this)
|
||||
}
|
||||
|
||||
fun <E : Enum<E>> Collection<E>.sortedByOrdinal() = sortedBy { it.ordinal }
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
package org.koitharu.kotatsu.favourites.data
|
||||
|
||||
import org.koitharu.kotatsu.core.db.entity.SortOrder
|
||||
import org.koitharu.kotatsu.core.db.entity.toManga
|
||||
import org.koitharu.kotatsu.core.db.entity.toMangaTags
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||
import java.util.Date
|
||||
|
||||
fun FavouriteCategoryEntity.toFavouriteCategory(id: Long = categoryId.toLong()) = FavouriteCategory(
|
||||
id = id,
|
||||
title = title,
|
||||
sortKey = sortKey,
|
||||
order = SortOrder(order, SortOrder.NEWEST),
|
||||
order = ListSortOrder(order, ListSortOrder.NEWEST),
|
||||
createdAt = Date(createdAt),
|
||||
isTrackingEnabled = track,
|
||||
isVisibleInLibrary = isVisibleInLibrary,
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
package org.koitharu.kotatsu.favourites.data
|
||||
|
||||
import androidx.room.*
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.RawQuery
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Upsert
|
||||
import androidx.sqlite.db.SimpleSQLiteQuery
|
||||
import androidx.sqlite.db.SupportSQLiteQuery
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.koitharu.kotatsu.core.db.entity.MangaEntity
|
||||
import org.koitharu.kotatsu.favourites.domain.model.Cover
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||
|
||||
@Dao
|
||||
abstract class FavouritesDao {
|
||||
@@ -22,7 +28,7 @@ abstract class FavouritesDao {
|
||||
@Query("SELECT * FROM favourites WHERE deleted_at = 0 GROUP BY manga_id ORDER BY created_at DESC LIMIT :limit")
|
||||
abstract suspend fun findLast(limit: Int): List<FavouriteManga>
|
||||
|
||||
fun observeAll(order: SortOrder): Flow<List<FavouriteManga>> {
|
||||
fun observeAll(order: ListSortOrder): Flow<List<FavouriteManga>> {
|
||||
val orderBy = getOrderBy(order)
|
||||
|
||||
@Language("RoomSql")
|
||||
@@ -47,7 +53,7 @@ abstract class FavouritesDao {
|
||||
)
|
||||
abstract suspend fun findAll(categoryId: Long): List<FavouriteManga>
|
||||
|
||||
fun observeAll(categoryId: Long, order: SortOrder): Flow<List<FavouriteManga>> {
|
||||
fun observeAll(categoryId: Long, order: ListSortOrder): Flow<List<FavouriteManga>> {
|
||||
val orderBy = getOrderBy(order)
|
||||
|
||||
@Language("RoomSql")
|
||||
@@ -72,7 +78,7 @@ abstract class FavouritesDao {
|
||||
)
|
||||
abstract suspend fun findAllManga(categoryId: Int): List<MangaEntity>
|
||||
|
||||
suspend fun findCovers(categoryId: Long, order: SortOrder): List<Cover> {
|
||||
suspend fun findCovers(categoryId: Long, order: ListSortOrder): List<Cover> {
|
||||
val orderBy = getOrderBy(order)
|
||||
|
||||
@Language("RoomSql")
|
||||
@@ -157,13 +163,13 @@ abstract class FavouritesDao {
|
||||
@Query("UPDATE favourites SET deleted_at = :deletedAt WHERE category_id = :categoryId AND deleted_at = 0")
|
||||
protected abstract suspend fun setDeletedAtAll(categoryId: Long, deletedAt: Long)
|
||||
|
||||
private fun getOrderBy(sortOrder: SortOrder) = when (sortOrder) {
|
||||
SortOrder.RATING -> "rating DESC"
|
||||
SortOrder.NEWEST,
|
||||
SortOrder.UPDATED,
|
||||
private fun getOrderBy(sortOrder: ListSortOrder) = when (sortOrder) {
|
||||
ListSortOrder.RATING -> "rating DESC"
|
||||
ListSortOrder.NEWEST,
|
||||
ListSortOrder.UPDATED,
|
||||
-> "created_at DESC"
|
||||
|
||||
SortOrder.ALPHABETICAL -> "title ASC"
|
||||
ListSortOrder.ALPHABETIC -> "title ASC"
|
||||
else -> throw IllegalArgumentException("Sort order $sortOrder is not supported")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.db.entity.SortOrder
|
||||
import org.koitharu.kotatsu.core.db.entity.toEntities
|
||||
import org.koitharu.kotatsu.core.db.entity.toEntity
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
@@ -20,8 +19,8 @@ import org.koitharu.kotatsu.favourites.data.toFavouriteCategory
|
||||
import org.koitharu.kotatsu.favourites.data.toManga
|
||||
import org.koitharu.kotatsu.favourites.data.toMangaList
|
||||
import org.koitharu.kotatsu.favourites.domain.model.Cover
|
||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.tracker.work.TrackerNotificationChannels
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -41,7 +40,7 @@ class FavouritesRepository @Inject constructor(
|
||||
return entities.toMangaList()
|
||||
}
|
||||
|
||||
fun observeAll(order: SortOrder): Flow<List<Manga>> {
|
||||
fun observeAll(order: ListSortOrder): Flow<List<Manga>> {
|
||||
return db.favouritesDao.observeAll(order)
|
||||
.mapItems { it.toManga() }
|
||||
}
|
||||
@@ -51,7 +50,7 @@ class FavouritesRepository @Inject constructor(
|
||||
return entities.toMangaList()
|
||||
}
|
||||
|
||||
fun observeAll(categoryId: Long, order: SortOrder): Flow<List<Manga>> {
|
||||
fun observeAll(categoryId: Long, order: ListSortOrder): Flow<List<Manga>> {
|
||||
return db.favouritesDao.observeAll(categoryId, order)
|
||||
.mapItems { it.toManga() }
|
||||
}
|
||||
@@ -105,7 +104,7 @@ class FavouritesRepository @Inject constructor(
|
||||
|
||||
suspend fun createCategory(
|
||||
title: String,
|
||||
sortOrder: SortOrder,
|
||||
sortOrder: ListSortOrder,
|
||||
isTrackerEnabled: Boolean,
|
||||
isVisibleOnShelf: Boolean,
|
||||
): FavouriteCategory {
|
||||
@@ -128,7 +127,7 @@ class FavouritesRepository @Inject constructor(
|
||||
suspend fun updateCategory(
|
||||
id: Long,
|
||||
title: String,
|
||||
sortOrder: SortOrder,
|
||||
sortOrder: ListSortOrder,
|
||||
isTrackerEnabled: Boolean,
|
||||
isVisibleOnShelf: Boolean,
|
||||
) {
|
||||
@@ -156,7 +155,7 @@ class FavouritesRepository @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun setCategoryOrder(id: Long, order: SortOrder) {
|
||||
suspend fun setCategoryOrder(id: Long, order: ListSortOrder) {
|
||||
db.favouriteCategoriesDao.updateOrder(id, order.name)
|
||||
}
|
||||
|
||||
@@ -205,10 +204,10 @@ class FavouritesRepository @Inject constructor(
|
||||
return ReversibleHandle { recoverToCategory(categoryId, ids) }
|
||||
}
|
||||
|
||||
private fun observeOrder(categoryId: Long): Flow<SortOrder> {
|
||||
private fun observeOrder(categoryId: Long): Flow<ListSortOrder> {
|
||||
return db.favouriteCategoriesDao.observe(categoryId)
|
||||
.filterNotNull()
|
||||
.map { x -> SortOrder(x.order, SortOrder.NEWEST) }
|
||||
.map { x -> ListSortOrder(x.order, ListSortOrder.NEWEST) }
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ import org.koitharu.kotatsu.favourites.ui.categories.edit.FavouritesCategoryEdit
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener
|
||||
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
@@ -176,12 +175,6 @@ class FavouriteCategoriesActivity :
|
||||
|
||||
companion object {
|
||||
|
||||
val SORT_ORDERS = arrayOf(
|
||||
SortOrder.ALPHABETICAL,
|
||||
SortOrder.NEWEST,
|
||||
SortOrder.RATING,
|
||||
)
|
||||
|
||||
fun newIntent(context: Context) = Intent(context, FavouriteCategoriesActivity::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,16 +18,15 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.core.ui.model.titleRes
|
||||
import org.koitharu.kotatsu.core.ui.util.DefaultTextWatcher
|
||||
import org.koitharu.kotatsu.core.util.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.core.util.ext.getSerializableCompat
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
||||
import org.koitharu.kotatsu.core.util.ext.setChecked
|
||||
import org.koitharu.kotatsu.core.util.ext.sortedByOrdinal
|
||||
import org.koitharu.kotatsu.databinding.ActivityCategoryEditBinding
|
||||
import org.koitharu.kotatsu.favourites.ui.categories.FavouriteCategoriesActivity
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||
import com.google.android.material.R as materialR
|
||||
|
||||
@AndroidEntryPoint
|
||||
@@ -38,7 +37,8 @@ class FavouritesCategoryEditActivity :
|
||||
DefaultTextWatcher {
|
||||
|
||||
private val viewModel by viewModels<FavouritesCategoryEditViewModel>()
|
||||
private var selectedSortOrder: SortOrder? = null
|
||||
private var selectedSortOrder: ListSortOrder? = null
|
||||
private val sortOrders = ListSortOrder.FAVORITES.sortedByOrdinal()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -68,7 +68,7 @@ class FavouritesCategoryEditActivity :
|
||||
|
||||
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
|
||||
super.onRestoreInstanceState(savedInstanceState)
|
||||
val order = savedInstanceState.getSerializableCompat<SortOrder>(KEY_SORT_ORDER)
|
||||
val order = savedInstanceState.getSerializableCompat<ListSortOrder>(KEY_SORT_ORDER)
|
||||
if (order != null) {
|
||||
selectedSortOrder = order
|
||||
}
|
||||
@@ -103,7 +103,7 @@ class FavouritesCategoryEditActivity :
|
||||
}
|
||||
|
||||
override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
selectedSortOrder = FavouriteCategoriesActivity.SORT_ORDERS.getOrNull(position)
|
||||
selectedSortOrder = sortOrders.getOrNull(position)
|
||||
}
|
||||
|
||||
private fun onCategoryChanged(category: FavouriteCategory?) {
|
||||
@@ -113,7 +113,7 @@ class FavouritesCategoryEditActivity :
|
||||
}
|
||||
viewBinding.editName.setText(category?.title)
|
||||
selectedSortOrder = category?.order
|
||||
val sortText = getString((category?.order ?: SortOrder.NEWEST).titleRes)
|
||||
val sortText = getString((category?.order ?: ListSortOrder.NEWEST).titleResId)
|
||||
viewBinding.editSort.setText(sortText, false)
|
||||
viewBinding.switchTracker.setChecked(category?.isTrackingEnabled ?: true, false)
|
||||
viewBinding.switchShelf.setChecked(category?.isVisibleInLibrary ?: true, false)
|
||||
@@ -135,17 +135,17 @@ class FavouritesCategoryEditActivity :
|
||||
}
|
||||
|
||||
private fun initSortSpinner() {
|
||||
val entries = FavouriteCategoriesActivity.SORT_ORDERS.map { getString(it.titleRes) }
|
||||
val entries = sortOrders.map { getString(it.titleResId) }
|
||||
val adapter = SortAdapter(this, entries)
|
||||
viewBinding.editSort.setAdapter(adapter)
|
||||
viewBinding.editSort.onItemClickListener = this
|
||||
}
|
||||
|
||||
private fun getSelectedSortOrder(): SortOrder {
|
||||
private fun getSelectedSortOrder(): ListSortOrder {
|
||||
selectedSortOrder?.let { return it }
|
||||
val entries = FavouriteCategoriesActivity.SORT_ORDERS.map { getString(it.titleRes) }
|
||||
val entries = sortOrders.map { getString(it.titleResId) }
|
||||
val index = entries.indexOf(viewBinding.editSort.text.toString())
|
||||
return FavouriteCategoriesActivity.SORT_ORDERS.getOrNull(index) ?: SortOrder.NEWEST
|
||||
return sortOrders.getOrNull(index) ?: ListSortOrder.NEWEST
|
||||
}
|
||||
|
||||
private class SortAdapter(
|
||||
|
||||
@@ -17,7 +17,7 @@ import org.koitharu.kotatsu.core.util.ext.call
|
||||
import org.koitharu.kotatsu.favourites.domain.FavouritesRepository
|
||||
import org.koitharu.kotatsu.favourites.ui.categories.edit.FavouritesCategoryEditActivity.Companion.EXTRA_ID
|
||||
import org.koitharu.kotatsu.favourites.ui.categories.edit.FavouritesCategoryEditActivity.Companion.NO_ID
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
@@ -48,7 +48,7 @@ class FavouritesCategoryEditViewModel @Inject constructor(
|
||||
|
||||
fun save(
|
||||
title: String,
|
||||
sortOrder: SortOrder,
|
||||
sortOrder: ListSortOrder,
|
||||
isTrackerEnabled: Boolean,
|
||||
isVisibleOnShelf: Boolean,
|
||||
) {
|
||||
|
||||
@@ -10,13 +10,11 @@ import androidx.fragment.app.viewModels
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
||||
import org.koitharu.kotatsu.core.ui.model.titleRes
|
||||
import org.koitharu.kotatsu.core.ui.util.MenuInvalidator
|
||||
import org.koitharu.kotatsu.core.util.ext.addMenuProvider
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.sortedByOrdinal
|
||||
import org.koitharu.kotatsu.core.util.ext.withArgs
|
||||
import org.koitharu.kotatsu.databinding.FragmentListBinding
|
||||
import org.koitharu.kotatsu.favourites.ui.categories.FavouriteCategoriesActivity
|
||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
|
||||
@@ -27,12 +25,14 @@ class FavouritesListFragment : MangaListFragment(), PopupMenu.OnMenuItemClickLis
|
||||
|
||||
override val isSwipeRefreshEnabled = false
|
||||
|
||||
val categoryId
|
||||
get() = viewModel.categoryId
|
||||
|
||||
override fun onViewBindingCreated(binding: FragmentListBinding, savedInstanceState: Bundle?) {
|
||||
super.onViewBindingCreated(binding, savedInstanceState)
|
||||
if (viewModel.categoryId != NO_ID) {
|
||||
addMenuProvider(FavouritesListMenuProvider(binding.root.context, viewModel))
|
||||
}
|
||||
viewModel.sortOrder.observe(viewLifecycleOwner, MenuInvalidator(requireActivity()))
|
||||
}
|
||||
|
||||
override fun onScrolledToEnd() = Unit
|
||||
@@ -40,14 +40,15 @@ class FavouritesListFragment : MangaListFragment(), PopupMenu.OnMenuItemClickLis
|
||||
override fun onFilterClick(view: View?) {
|
||||
val menu = PopupMenu(view?.context ?: return, view)
|
||||
menu.setOnMenuItemClickListener(this)
|
||||
for ((i, item) in FavouriteCategoriesActivity.SORT_ORDERS.withIndex()) {
|
||||
menu.menu.add(Menu.NONE, Menu.NONE, i, item.titleRes)
|
||||
val orders = ListSortOrder.FAVORITES.sortedByOrdinal()
|
||||
for ((i, item) in orders.withIndex()) {
|
||||
menu.menu.add(Menu.NONE, Menu.NONE, i, item.titleResId)
|
||||
}
|
||||
menu.show()
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(item: MenuItem): Boolean {
|
||||
val order = FavouriteCategoriesActivity.SORT_ORDERS.getOrNull(item.order) ?: return false
|
||||
val order = ListSortOrder.FAVORITES.sortedByOrdinal().getOrNull(item.order) ?: return false
|
||||
viewModel.setSortOrder(order)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -5,12 +5,8 @@ import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.core.view.forEach
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.model.titleRes
|
||||
import org.koitharu.kotatsu.favourites.ui.categories.FavouriteCategoriesActivity
|
||||
import org.koitharu.kotatsu.favourites.ui.categories.edit.FavouritesCategoryEditActivity
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
|
||||
class FavouritesListMenuProvider(
|
||||
private val context: Context,
|
||||
@@ -19,29 +15,9 @@ class FavouritesListMenuProvider(
|
||||
|
||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||
menuInflater.inflate(R.menu.opt_favourites, menu)
|
||||
val subMenu = menu.findItem(R.id.action_order)?.subMenu ?: return
|
||||
for (order in FavouriteCategoriesActivity.SORT_ORDERS) {
|
||||
subMenu.add(R.id.group_order, Menu.NONE, order.ordinal, order.titleRes)
|
||||
}
|
||||
subMenu.setGroupCheckable(R.id.group_order, true, true)
|
||||
}
|
||||
|
||||
override fun onPrepareMenu(menu: Menu) {
|
||||
super.onPrepareMenu(menu)
|
||||
val order = viewModel.sortOrder.value ?: return
|
||||
menu.findItem(R.id.action_order)?.subMenu?.forEach { item ->
|
||||
if (item.order == order.ordinal) {
|
||||
item.isChecked = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||
if (menuItem.groupId == R.id.group_order) {
|
||||
val order = SortOrder.entries[menuItem.order]
|
||||
viewModel.setSortOrder(order)
|
||||
return true
|
||||
}
|
||||
return when (menuItem.itemId) {
|
||||
R.id.action_edit -> {
|
||||
context.startActivity(FavouritesCategoryEditActivity.newIntent(context, viewModel.categoryId))
|
||||
|
||||
@@ -22,12 +22,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.NO_ID
|
||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||
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.SortOrder
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
@@ -44,7 +44,7 @@ class FavouritesListViewModel @Inject constructor(
|
||||
override val listMode = settings.observeAsFlow(AppSettings.KEY_LIST_MODE_FAVORITES) { favoritesListMode }
|
||||
.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, settings.favoritesListMode)
|
||||
|
||||
val sortOrder: StateFlow<SortOrder?> = if (categoryId == NO_ID) {
|
||||
val sortOrder: StateFlow<ListSortOrder?> = if (categoryId == NO_ID) {
|
||||
MutableStateFlow(null)
|
||||
} else {
|
||||
repository.observeCategory(categoryId)
|
||||
@@ -54,7 +54,7 @@ class FavouritesListViewModel @Inject constructor(
|
||||
|
||||
override val content = combine(
|
||||
if (categoryId == NO_ID) {
|
||||
repository.observeAll(SortOrder.NEWEST)
|
||||
repository.observeAll(ListSortOrder.NEWEST)
|
||||
} else {
|
||||
repository.observeAll(categoryId)
|
||||
},
|
||||
@@ -98,7 +98,7 @@ class FavouritesListViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun setSortOrder(order: SortOrder) {
|
||||
fun setSortOrder(order: ListSortOrder) {
|
||||
if (categoryId == NO_ID) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.koitharu.kotatsu.core.ui.widgets.ChipsView
|
||||
import org.koitharu.kotatsu.core.util.ext.lifecycleScope
|
||||
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
|
||||
import org.koitharu.kotatsu.core.util.ext.require
|
||||
import org.koitharu.kotatsu.core.util.ext.sortedByOrdinal
|
||||
import org.koitharu.kotatsu.filter.ui.model.FilterHeaderModel
|
||||
import org.koitharu.kotatsu.filter.ui.model.FilterItem
|
||||
import org.koitharu.kotatsu.filter.ui.model.FilterState
|
||||
@@ -207,7 +208,7 @@ class FilterCoordinator @Inject constructor(
|
||||
state: FilterState,
|
||||
query: String,
|
||||
): List<ListModel> {
|
||||
val sortOrders = repository.sortOrders.sortedBy { it.ordinal }
|
||||
val sortOrders = repository.sortOrders.sortedByOrdinal()
|
||||
val tags = mergeTags(state.tags, allTags.tags).toList()
|
||||
val list = ArrayList<ListModel>(tags.size + sortOrders.size + 3)
|
||||
if (query.isEmpty()) {
|
||||
|
||||
@@ -12,7 +12,7 @@ import kotlinx.coroutines.flow.Flow
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.koitharu.kotatsu.core.db.entity.MangaEntity
|
||||
import org.koitharu.kotatsu.core.db.entity.TagEntity
|
||||
import org.koitharu.kotatsu.history.domain.model.HistoryOrder
|
||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||
|
||||
@Dao
|
||||
abstract class HistoryDao {
|
||||
@@ -33,12 +33,13 @@ abstract class HistoryDao {
|
||||
@Query("SELECT * FROM history WHERE deleted_at = 0 ORDER BY updated_at DESC LIMIT :limit")
|
||||
abstract fun observeAll(limit: Int): Flow<List<HistoryWithManga>>
|
||||
|
||||
fun observeAll(order: HistoryOrder): Flow<List<HistoryWithManga>> {
|
||||
fun observeAll(order: ListSortOrder): Flow<List<HistoryWithManga>> {
|
||||
val orderBy = when (order) {
|
||||
HistoryOrder.UPDATED -> "history.updated_at DESC"
|
||||
HistoryOrder.CREATED -> "history.created_at DESC"
|
||||
HistoryOrder.PROGRESS -> "history.percent DESC"
|
||||
HistoryOrder.ALPHABETIC -> "manga.title"
|
||||
ListSortOrder.UPDATED -> "history.updated_at DESC"
|
||||
ListSortOrder.NEWEST -> "history.created_at DESC"
|
||||
ListSortOrder.PROGRESS -> "history.percent DESC"
|
||||
ListSortOrder.ALPHABETIC -> "manga.title"
|
||||
else -> throw IllegalArgumentException("Sort order $order is not supported")
|
||||
}
|
||||
|
||||
@Language("RoomSql")
|
||||
|
||||
@@ -18,8 +18,8 @@ import org.koitharu.kotatsu.core.model.findById
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.core.ui.util.ReversibleHandle
|
||||
import org.koitharu.kotatsu.core.util.ext.mapItems
|
||||
import org.koitharu.kotatsu.history.domain.model.HistoryOrder
|
||||
import org.koitharu.kotatsu.history.domain.model.MangaWithHistory
|
||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.Scrobbler
|
||||
@@ -66,7 +66,7 @@ class HistoryRepository @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun observeAllWithHistory(order: HistoryOrder): Flow<List<MangaWithHistory>> {
|
||||
fun observeAllWithHistory(order: ListSortOrder): Flow<List<MangaWithHistory>> {
|
||||
return db.historyDao.observeAll(order).mapItems {
|
||||
MangaWithHistory(
|
||||
it.manga.toManga(it.tags.toMangaTags()),
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package org.koitharu.kotatsu.history.domain.model
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import org.koitharu.kotatsu.R
|
||||
|
||||
enum class HistoryOrder(
|
||||
@StringRes val titleResId: Int,
|
||||
) {
|
||||
|
||||
UPDATED(R.string.updated),
|
||||
CREATED(R.string.order_added),
|
||||
PROGRESS(R.string.progress),
|
||||
ALPHABETIC(R.string.by_name);
|
||||
|
||||
fun isGroupingSupported() = this == UPDATED || this == CREATED || this == PROGRESS
|
||||
}
|
||||
@@ -26,9 +26,9 @@ import org.koitharu.kotatsu.core.util.ext.daysDiff
|
||||
import org.koitharu.kotatsu.core.util.ext.onFirst
|
||||
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
||||
import org.koitharu.kotatsu.history.data.HistoryRepository
|
||||
import org.koitharu.kotatsu.history.domain.model.HistoryOrder
|
||||
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.ui.MangaListViewModel
|
||||
import org.koitharu.kotatsu.list.ui.model.EmptyHint
|
||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||
@@ -54,7 +54,7 @@ class HistoryListViewModel @Inject constructor(
|
||||
downloadScheduler: DownloadWorker.Scheduler,
|
||||
) : MangaListViewModel(settings, downloadScheduler) {
|
||||
|
||||
private val sortOrder: StateFlow<HistoryOrder> = settings.observeAsStateFlow(
|
||||
private val sortOrder: StateFlow<ListSortOrder> = settings.observeAsStateFlow(
|
||||
scope = viewModelScope + Dispatchers.IO,
|
||||
key = AppSettings.KEY_HISTORY_ORDER,
|
||||
valueProducer = { historySortOrder },
|
||||
@@ -123,10 +123,6 @@ class HistoryListViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun setGrouping(isGroupingEnabled: Boolean) {
|
||||
settings.isHistoryGroupingEnabled = isGroupingEnabled
|
||||
}
|
||||
|
||||
private suspend fun mapList(
|
||||
list: List<MangaWithHistory>,
|
||||
grouped: Boolean,
|
||||
@@ -168,10 +164,10 @@ class HistoryListViewModel @Inject constructor(
|
||||
return result
|
||||
}
|
||||
|
||||
private fun MangaHistory.header(order: HistoryOrder): ListHeader? = when (order) {
|
||||
HistoryOrder.UPDATED -> ListHeader(timeAgo(updatedAt))
|
||||
HistoryOrder.CREATED -> ListHeader(timeAgo(createdAt))
|
||||
HistoryOrder.PROGRESS -> ListHeader(
|
||||
private fun MangaHistory.header(order: ListSortOrder): ListHeader? = when (order) {
|
||||
ListSortOrder.UPDATED -> ListHeader(timeAgo(updatedAt))
|
||||
ListSortOrder.NEWEST -> ListHeader(timeAgo(createdAt))
|
||||
ListSortOrder.PROGRESS -> ListHeader(
|
||||
when (percent) {
|
||||
1f -> R.string.status_completed
|
||||
in 0f..0.01f -> R.string.status_planned
|
||||
@@ -180,7 +176,9 @@ class HistoryListViewModel @Inject constructor(
|
||||
},
|
||||
)
|
||||
|
||||
HistoryOrder.ALPHABETIC -> null
|
||||
ListSortOrder.ALPHABETIC,
|
||||
ListSortOrder.RELEVANCE,
|
||||
ListSortOrder.RATING -> null
|
||||
}
|
||||
|
||||
private fun timeAgo(date: Date): DateTimeAgo {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.koitharu.kotatsu.list.domain
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.parsers.util.find
|
||||
import java.util.EnumSet
|
||||
|
||||
enum class ListSortOrder(
|
||||
@StringRes val titleResId: Int,
|
||||
) {
|
||||
|
||||
UPDATED(R.string.updated),
|
||||
NEWEST(R.string.order_added),
|
||||
PROGRESS(R.string.progress),
|
||||
ALPHABETIC(R.string.by_name),
|
||||
RATING(R.string.by_rating),
|
||||
RELEVANCE(R.string.by_relevance),
|
||||
;
|
||||
|
||||
fun isGroupingSupported() = this == UPDATED || this == NEWEST || this == PROGRESS
|
||||
|
||||
companion object {
|
||||
|
||||
val HISTORY = EnumSet.of(UPDATED, NEWEST, PROGRESS, ALPHABETIC)
|
||||
val FAVORITES = EnumSet.of(ALPHABETIC, NEWEST, RATING)
|
||||
val SUGGESTIONS = EnumSet.of(RELEVANCE)
|
||||
|
||||
operator fun invoke(value: String, fallback: ListSortOrder) = entries.find(value) ?: fallback
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,11 @@ import android.view.MenuItem
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.fragment.app.Fragment
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment
|
||||
import org.koitharu.kotatsu.history.ui.HistoryListFragment
|
||||
import org.koitharu.kotatsu.list.ui.config.ListConfigBottomSheet
|
||||
import org.koitharu.kotatsu.list.ui.config.ListConfigSection
|
||||
import org.koitharu.kotatsu.suggestions.ui.SuggestionsFragment
|
||||
|
||||
class MangaListMenuProvider(
|
||||
private val fragment: Fragment,
|
||||
@@ -18,7 +22,13 @@ class MangaListMenuProvider(
|
||||
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) {
|
||||
R.id.action_list_mode -> {
|
||||
ListConfigBottomSheet.show(fragment.childFragmentManager)
|
||||
val section: ListConfigSection = when (fragment) {
|
||||
is HistoryListFragment -> ListConfigSection.History
|
||||
is SuggestionsFragment -> ListConfigSection.Suggestions
|
||||
is FavouritesListFragment -> ListConfigSection.Favorites(fragment.categoryId)
|
||||
else -> ListConfigSection.General
|
||||
}
|
||||
ListConfigBottomSheet.show(fragment.childFragmentManager, section)
|
||||
true
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import android.widget.ArrayAdapter
|
||||
import android.widget.CompoundButton
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.android.material.button.MaterialButtonToggleGroup
|
||||
import com.google.android.material.slider.Slider
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
@@ -18,11 +19,9 @@ import org.koitharu.kotatsu.core.prefs.ListMode
|
||||
import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet
|
||||
import org.koitharu.kotatsu.core.util.ext.setValueRounded
|
||||
import org.koitharu.kotatsu.core.util.ext.showDistinct
|
||||
import org.koitharu.kotatsu.core.util.ext.withArgs
|
||||
import org.koitharu.kotatsu.core.util.progress.IntPercentLabelFormatter
|
||||
import org.koitharu.kotatsu.databinding.SheetListModeBinding
|
||||
import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment
|
||||
import org.koitharu.kotatsu.history.domain.model.HistoryOrder
|
||||
import org.koitharu.kotatsu.history.ui.HistoryListFragment
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
@@ -33,8 +32,11 @@ class ListConfigBottomSheet :
|
||||
AdapterView.OnItemSelectedListener {
|
||||
|
||||
@Inject
|
||||
@Deprecated("")
|
||||
lateinit var settings: AppSettings
|
||||
|
||||
private val viewModel by viewModels<ListConfigViewModel>()
|
||||
|
||||
override fun onCreateViewBinding(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
@@ -42,12 +44,7 @@ class ListConfigBottomSheet :
|
||||
|
||||
override fun onViewBindingCreated(binding: SheetListModeBinding, savedInstanceState: Bundle?) {
|
||||
super.onViewBindingCreated(binding, savedInstanceState)
|
||||
val section = getSection()
|
||||
val mode = when (section) {
|
||||
Section.GENERAL -> settings.listMode
|
||||
Section.HISTORY -> settings.historyListMode
|
||||
Section.FAVORITES -> settings.favoritesListMode
|
||||
}
|
||||
val mode = viewModel.listMode
|
||||
binding.buttonList.isChecked = mode == ListMode.LIST
|
||||
binding.buttonListDetailed.isChecked = mode == ListMode.DETAILED_LIST
|
||||
binding.buttonGrid.isChecked = mode == ListMode.GRID
|
||||
@@ -55,27 +52,31 @@ class ListConfigBottomSheet :
|
||||
binding.sliderGrid.isVisible = mode == ListMode.GRID
|
||||
|
||||
binding.sliderGrid.setLabelFormatter(IntPercentLabelFormatter(binding.root.context))
|
||||
binding.sliderGrid.setValueRounded(settings.gridSize.toFloat())
|
||||
binding.sliderGrid.setValueRounded(viewModel.gridSize.toFloat())
|
||||
binding.sliderGrid.addOnChangeListener(this)
|
||||
|
||||
binding.checkableGroup.addOnButtonCheckedListener(this)
|
||||
|
||||
binding.switchGrouping.isVisible = section == Section.HISTORY
|
||||
if (section == Section.HISTORY) {
|
||||
binding.switchGrouping.isVisible = viewModel.isGroupingAvailable
|
||||
if (viewModel.isGroupingAvailable) {
|
||||
binding.switchGrouping.isEnabled = settings.historySortOrder.isGroupingSupported()
|
||||
}
|
||||
binding.switchGrouping.isChecked = settings.isHistoryGroupingEnabled
|
||||
binding.switchGrouping.setOnCheckedChangeListener(this)
|
||||
|
||||
if (section == Section.HISTORY) {
|
||||
val sortOrders = viewModel.getSortOrders()
|
||||
if (sortOrders != null) {
|
||||
binding.textViewOrderTitle.isVisible = true
|
||||
binding.spinnerOrder.adapter = ArrayAdapter(
|
||||
binding.spinnerOrder.context,
|
||||
android.R.layout.simple_spinner_dropdown_item,
|
||||
android.R.id.text1,
|
||||
HistoryOrder.entries.map { getString(it.titleResId) },
|
||||
sortOrders.map { binding.spinnerOrder.context.getString(it.titleResId) },
|
||||
)
|
||||
binding.spinnerOrder.setSelection(settings.historySortOrder.ordinal, false)
|
||||
val selected = sortOrders.indexOf(viewModel.getSelectedSortOrder())
|
||||
if (selected >= 0) {
|
||||
binding.spinnerOrder.setSelection(selected, false)
|
||||
}
|
||||
binding.spinnerOrder.onItemSelectedListener = this
|
||||
binding.cardOrder.isVisible = true
|
||||
}
|
||||
@@ -93,11 +94,7 @@ class ListConfigBottomSheet :
|
||||
}
|
||||
requireViewBinding().textViewGridTitle.isVisible = mode == ListMode.GRID
|
||||
requireViewBinding().sliderGrid.isVisible = mode == ListMode.GRID
|
||||
when (getSection()) {
|
||||
Section.GENERAL -> settings.listMode = mode
|
||||
Section.HISTORY -> settings.historyListMode = mode
|
||||
Section.FAVORITES -> settings.favoritesListMode = mode
|
||||
}
|
||||
viewModel.listMode = mode
|
||||
}
|
||||
|
||||
override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) {
|
||||
@@ -108,36 +105,28 @@ class ListConfigBottomSheet :
|
||||
|
||||
override fun onValueChange(slider: Slider, value: Float, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
settings.gridSize = value.toInt()
|
||||
viewModel.gridSize = value.toInt()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>, view: View?, position: Int, id: Long) {
|
||||
when (parent.id) {
|
||||
R.id.spinner_order -> {
|
||||
val value = HistoryOrder.entries[position]
|
||||
settings.historySortOrder = value
|
||||
viewBinding?.switchGrouping?.isEnabled = value.isGroupingSupported()
|
||||
viewModel.setSortOrder(position)
|
||||
viewBinding?.switchGrouping?.isEnabled = settings.historySortOrder.isGroupingSupported()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) = Unit
|
||||
|
||||
private fun getSection(): Section = when (parentFragment) {
|
||||
is HistoryListFragment -> Section.HISTORY
|
||||
is FavouritesListFragment -> Section.FAVORITES
|
||||
else -> Section.GENERAL
|
||||
}
|
||||
|
||||
enum class Section {
|
||||
GENERAL, HISTORY, FAVORITES;
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val TAG = "ListModeSelectDialog"
|
||||
const val ARG_SECTION = "section"
|
||||
|
||||
fun show(fm: FragmentManager) = ListConfigBottomSheet().showDistinct(fm, TAG)
|
||||
fun show(fm: FragmentManager, section: ListConfigSection) = ListConfigBottomSheet().withArgs(1) {
|
||||
putParcelable(ARG_SECTION, section)
|
||||
}.showDistinct(fm, TAG)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.koitharu.kotatsu.list.ui.config
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
sealed interface ListConfigSection : Parcelable {
|
||||
|
||||
@Parcelize
|
||||
data object History : ListConfigSection
|
||||
|
||||
@Parcelize
|
||||
data object General : ListConfigSection
|
||||
|
||||
@Parcelize
|
||||
data class Favorites(
|
||||
val categoryId: Long,
|
||||
) : ListConfigSection
|
||||
|
||||
@Parcelize
|
||||
data object Suggestions : ListConfigSection
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package org.koitharu.kotatsu.list.ui.config
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.core.prefs.ListMode
|
||||
import org.koitharu.kotatsu.core.ui.BaseViewModel
|
||||
import org.koitharu.kotatsu.core.util.ext.require
|
||||
import org.koitharu.kotatsu.core.util.ext.sortedByOrdinal
|
||||
import org.koitharu.kotatsu.favourites.domain.FavouritesRepository
|
||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ListConfigViewModel @Inject constructor(
|
||||
savedStateHandle: SavedStateHandle,
|
||||
private val settings: AppSettings,
|
||||
private val favouritesRepository: FavouritesRepository,
|
||||
) : BaseViewModel() {
|
||||
|
||||
val section = savedStateHandle.require<ListConfigSection>(ListConfigBottomSheet.ARG_SECTION)
|
||||
|
||||
var listMode: ListMode
|
||||
get() = when (section) {
|
||||
is ListConfigSection.Favorites -> settings.favoritesListMode
|
||||
ListConfigSection.General -> settings.listMode
|
||||
ListConfigSection.History -> settings.historyListMode
|
||||
ListConfigSection.Suggestions -> settings.suggestionsListMode
|
||||
}
|
||||
set(value) {
|
||||
when (section) {
|
||||
is ListConfigSection.Favorites -> settings.favoritesListMode = value
|
||||
ListConfigSection.General -> settings.listMode = value
|
||||
ListConfigSection.History -> settings.historyListMode = value
|
||||
ListConfigSection.Suggestions -> settings.suggestionsListMode = value
|
||||
}
|
||||
}
|
||||
|
||||
var gridSize: Int
|
||||
get() = settings.gridSize
|
||||
set(value) {
|
||||
settings.gridSize = value
|
||||
}
|
||||
|
||||
val isGroupingAvailable: Boolean
|
||||
get() = section == ListConfigSection.History
|
||||
|
||||
fun getSortOrders(): List<ListSortOrder>? = when (section) {
|
||||
is ListConfigSection.Favorites -> ListSortOrder.FAVORITES
|
||||
ListConfigSection.General -> null
|
||||
ListConfigSection.History -> ListSortOrder.HISTORY
|
||||
ListConfigSection.Suggestions -> ListSortOrder.SUGGESTIONS
|
||||
}?.sortedByOrdinal()
|
||||
|
||||
fun getSelectedSortOrder(): ListSortOrder? = when (section) {
|
||||
is ListConfigSection.Favorites -> runBlocking { favouritesRepository.getCategory(section.categoryId).order }
|
||||
ListConfigSection.General -> null
|
||||
ListConfigSection.History -> settings.historySortOrder
|
||||
ListConfigSection.Suggestions -> ListSortOrder.RELEVANCE // TODO
|
||||
}
|
||||
|
||||
fun setSortOrder(position: Int) {
|
||||
val value = getSortOrders()?.getOrNull(position) ?: return
|
||||
when (section) {
|
||||
is ListConfigSection.Favorites -> launchJob {
|
||||
favouritesRepository.setCategoryOrder(section.categoryId, value)
|
||||
}
|
||||
|
||||
ListConfigSection.General -> Unit
|
||||
ListConfigSection.History -> settings.historySortOrder = value
|
||||
|
||||
ListConfigSection.Suggestions -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.last
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import org.koitharu.kotatsu.core.model.findById
|
||||
@@ -52,7 +52,7 @@ class PagesThumbnailsViewModel @Inject constructor(
|
||||
|
||||
init {
|
||||
loadingJob = launchLoadingJob(Dispatchers.Default) {
|
||||
chaptersLoader.init(checkNotNull(mangaDetails.last()))
|
||||
chaptersLoader.init(checkNotNull(mangaDetails.first { x -> x?.isLoaded == true }))
|
||||
chaptersLoader.loadSingleChapter(initialChapterId)
|
||||
updateList()
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.plus
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.core.prefs.observeAsFlow
|
||||
import org.koitharu.kotatsu.core.util.ext.onFirst
|
||||
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
||||
@@ -31,6 +32,9 @@ class SuggestionsViewModel @Inject constructor(
|
||||
private val suggestionsScheduler: SuggestionsWorker.Scheduler,
|
||||
) : MangaListViewModel(settings, downloadScheduler) {
|
||||
|
||||
override val listMode = settings.observeAsFlow(AppSettings.KEY_LIST_MODE_SUGGESTIONS) { suggestionsListMode }
|
||||
.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, settings.suggestionsListMode)
|
||||
|
||||
override val content = combine(
|
||||
repository.observeAll(),
|
||||
listMode,
|
||||
|
||||
@@ -2,22 +2,9 @@
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_order"
|
||||
android:orderInCategory="50"
|
||||
android:title="@string/sort_order">
|
||||
|
||||
<menu>
|
||||
|
||||
<group android:id="@+id/group_order" />
|
||||
|
||||
</menu>
|
||||
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_edit"
|
||||
android:orderInCategory="50"
|
||||
android:orderInCategory="20"
|
||||
android:title="@string/edit_category"
|
||||
android:titleCondensed="@string/edit" />
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<item
|
||||
android:id="@+id/action_manage"
|
||||
android:orderInCategory="48"
|
||||
android:title="@string/manage_categories"
|
||||
android:titleCondensed="@string/manage" />
|
||||
android:title="@string/favourites_categories"
|
||||
android:titleCondensed="@string/categories" />
|
||||
|
||||
</menu>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
<item
|
||||
android:id="@+id/action_list_mode"
|
||||
android:orderInCategory="20"
|
||||
android:orderInCategory="40"
|
||||
android:title="@string/list_options"
|
||||
app:showAsAction="never" />
|
||||
|
||||
|
||||
@@ -497,4 +497,6 @@
|
||||
<string name="suggest_new_sources">Suggest new sources after app update</string>
|
||||
<string name="suggest_new_sources_summary">Prompt to enable newly added sources after updating the application</string>
|
||||
<string name="list_options">List options</string>
|
||||
<string name="by_relevance">Relevance</string>
|
||||
<string name="categories">Categories</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user