Added category-wise display setting (#5232)

* Added category-wise display setting

Co-authored-by: Rogavactive <30288842+Rogavactive@users.noreply.github.com>

* Use flag instead of preference

* Remove database call in LibraryItem

* Remove unnecessary code

Co-authored-by: Rogavactive <30288842+Rogavactive@users.noreply.github.com>
(cherry picked from commit a906e9b302f4aa4ce0d5c30b2a52d266b44eaaf5)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/database/models/Category.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt
This commit is contained in:
Andreas 2021-06-05 16:25:34 +02:00 committed by Jobobby04
parent 9b85b009a4
commit 89249c9895
12 changed files with 176 additions and 33 deletions

View File

@ -16,8 +16,26 @@ interface Category : Serializable {
var mangaOrder: List<Long>
// SY <--
private fun setFlags(flag: Int, mask: Int) {
flags = flags and mask.inv() or (flag and mask)
}
var displayMode: Int
get() = flags and MASK
set(mode) = setFlags(mode, MASK)
companion object {
const val COMPACT_GRID = 0b00000000
const val COMFORTABLE_GRID = 0b00000001
const val LIST = 0b00000010
// SY -->
const val NO_TITLE_GRID = 0b00000011
// SY <--
const val MASK = 0b00000011
fun create(name: String): Category = CategoryImpl().apply {
this.name = name
}

View File

@ -191,6 +191,8 @@ object PreferenceKeys {
const val defaultCategory = "default_category"
const val categorizedDisplay = "categorized_display"
const val skipRead = "skip_read"
const val skipFiltered = "skip_filtered"

View File

@ -41,12 +41,11 @@ object PreferenceValues {
enum class DisplayMode {
COMPACT_GRID,
COMFORTABLE_GRID,
LIST,
// SY -->
NO_TITLE_GRID,
// SY <--
LIST,
}
enum class TappingInvertMode(val shouldInvertHorizontal: Boolean = false, val shouldInvertVertical: Boolean = false) {

View File

@ -292,6 +292,8 @@ class PreferencesHelper(val context: Context) {
fun defaultCategory() = prefs.getInt(Keys.defaultCategory, -1)
fun categorisedDisplaySettings() = flowPrefs.getBoolean(Keys.categorizedDisplay, false)
fun skipRead() = prefs.getBoolean(Keys.skipRead, false)
fun skipFiltered() = prefs.getBoolean(Keys.skipFiltered, true)

View File

@ -71,7 +71,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
/**
* Recycler view of the list of manga.
*/
private lateinit var recycler: RecyclerView
private lateinit var recycler: AutofitRecyclerView
/**
* Adapter to hold the manga in this category.
@ -92,9 +92,11 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
fun onCreate(controller: LibraryController, binding: LibraryCategoryBinding) {
this.controller = controller
recycler = if (preferences.libraryDisplayMode().get() == DisplayMode.LIST) {
(binding.swipeRefresh.inflate(R.layout.library_list_recycler) as RecyclerView).apply {
layoutManager = LinearLayoutManager(context)
recycler = if (preferences.libraryDisplayMode().get() == DisplayMode.LIST &&
!preferences.categorisedDisplaySettings().get()
) {
(binding.swipeRefresh.inflate(R.layout.library_list_recycler) as AutofitRecyclerView).apply {
spanCount = 1
}
} else {
(binding.swipeRefresh.inflate(R.layout.library_grid_recycler) as AutofitRecyclerView).apply {
@ -154,6 +156,15 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
fun onBind(category: Category) {
this.category = category
// If displayMode should be set from category adjust manga count per row
if (preferences.categorisedDisplaySettings().get()) {
recycler.spanCount = if (category.displayMode == Category.LIST || (preferences.libraryDisplayMode().get() == DisplayMode.LIST && category.id == 0)) {
1
} else {
controller.mangaPerRow
}
}
adapter.mode = if (controller.selectedMangas.isNotEmpty()) {
SelectableAdapter.Mode.MULTI
} else {

View File

@ -297,7 +297,9 @@ class LibraryController(
}
fun showSettingsSheet() {
settingsSheet?.show()
adapter?.categories?.get(binding.libraryPager.currentItem)?.let { category ->
settingsSheet?.show(category)
}
}
fun onNextLibraryUpdate(categories: List<Category>, mangaMap: Map<Int, List<LibraryItem>>) {

View File

@ -21,11 +21,16 @@ import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class LibraryItem(val manga: LibraryManga, private val libraryDisplayMode: Preference<DisplayMode>) :
class LibraryItem(
val manga: LibraryManga,
private val shouldSetFromCategory: Preference<Boolean>,
private val defaultLibraryDisplayMode: Preference<DisplayMode>
) :
AbstractFlexibleItem<LibraryHolder<*>>(), IFilterable<String> {
private val sourceManager: SourceManager = Injekt.get()
var displayMode: Int = -1
var downloadCount = -1
var unreadCount = -1
var isLocal = false
@ -34,8 +39,20 @@ class LibraryItem(val manga: LibraryManga, private val libraryDisplayMode: Prefe
var startReadingButton = false
// SY <--
private fun getDisplayMode(): DisplayMode {
return if (shouldSetFromCategory.get() && manga.category != 0) {
if (displayMode != -1) {
DisplayMode.values()[displayMode]
} else {
DisplayMode.COMPACT_GRID
}
} else {
defaultLibraryDisplayMode.get()
}
}
override fun getLayoutRes(): Int {
return when (libraryDisplayMode.get()) {
return when (getDisplayMode()) {
DisplayMode.COMPACT_GRID -> R.layout.source_compact_grid_item
DisplayMode.COMFORTABLE_GRID /* SY --> */, DisplayMode.NO_TITLE_GRID /* SY <-- */ -> R.layout.source_comfortable_grid_item
DisplayMode.LIST -> R.layout.source_list_item
@ -43,7 +60,7 @@ class LibraryItem(val manga: LibraryManga, private val libraryDisplayMode: Prefe
}
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder<*> {
return when (libraryDisplayMode.get()) {
return when (val displayMode = getDisplayMode()) {
DisplayMode.COMPACT_GRID -> {
val binding = SourceCompactGridItemBinding.bind(view)
val parent = adapter.recyclerView as AutofitRecyclerView
@ -68,7 +85,7 @@ class LibraryItem(val manga: LibraryManga, private val libraryDisplayMode: Prefe
coverHeight
)
}
LibraryComfortableGridHolder(view, adapter, libraryDisplayMode.get() != DisplayMode.NO_TITLE_GRID)
LibraryComfortableGridHolder(view, adapter, displayMode != DisplayMode.NO_TITLE_GRID)
}
DisplayMode.LIST -> {
LibraryListHolder(view, adapter)

View File

@ -426,6 +426,13 @@ class LibraryPresenter(
dbCategories
}
libraryManga.forEach { (categoryId, libraryManga) ->
val category = categories.first { category -> category.id == categoryId }
libraryManga.forEach { libraryItem ->
libraryItem.displayMode = category.displayMode
}
}
this.categories = categories
Library(categories, libraryManga)
}
@ -468,10 +475,18 @@ class LibraryPresenter(
* value.
*/
private fun getLibraryMangasObservable(): Observable<LibraryMap> {
val libraryDisplayMode = preferences.libraryDisplayMode()
val defaultLibraryDisplayMode = preferences.libraryDisplayMode()
val shouldSetFromCategory = preferences.categorisedDisplaySettings()
return db.getLibraryMangas().asRxObservable()
.map { list ->
list.map { LibraryItem(it, libraryDisplayMode) }.groupBy { it.manga.category }
list.map { libraryManga ->
// Display mode based on user preference: take it from global library setting or category
LibraryItem(
libraryManga,
shouldSetFromCategory,
defaultLibraryDisplayMode
)
}.groupBy { it.manga.category }
}
}

View File

@ -6,6 +6,7 @@ import android.view.View
import com.bluelinelabs.conductor.Router
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager
@ -27,6 +28,7 @@ class LibrarySettingsSheet(
private val sort: Sort
private val display: Display
private val grouping: Grouping
private val db: DatabaseHelper by injectLazy()
init {
filters = Filter(router.activity!!)
@ -46,6 +48,16 @@ class LibrarySettingsSheet(
sort.refreshMode()
}
/**
* adjusts selected button to match real state.
* @param currentCategory ID of currently shown category
*/
fun show(currentCategory: Category) {
display.currentCategory = currentCategory
display.adjustDisplaySelection()
super.show()
}
override fun getTabViews(): List<View> = listOf(
filters,
sort,
@ -289,8 +301,39 @@ class LibrarySettingsSheet(
inner class Display @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
Settings(context, attrs) {
private val displayGroup: DisplayGroup
private val badgeGroup: BadgeGroup
// SY -->
private val buttonsGroup: ButtonsGroup
// SY <--
private val tabsGroup: TabsGroup
init {
setGroups(listOf(DisplayGroup(), BadgeGroup(), /* SY --> */ ButtonsGroup(), /* SY <-- */ TabsGroup()))
displayGroup = DisplayGroup()
badgeGroup = BadgeGroup()
// SY -->
buttonsGroup = ButtonsGroup()
// SY <--
tabsGroup = TabsGroup()
setGroups(listOf(displayGroup, badgeGroup, /* SY --> */ buttonsGroup, /* SY <-- */ tabsGroup))
}
// Refreshes Display Setting selections
fun adjustDisplaySelection() {
val mode = getDisplayModePreference()
displayGroup.setGroupSelections(mode)
displayGroup.items.forEach { adapter.notifyItemChanged(it) }
}
// Gets user preference of currently selected display mode at current category
private fun getDisplayModePreference(): DisplayMode {
return if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
DisplayMode.values()[currentCategory?.displayMode ?: 0]
} else {
preferences.libraryDisplayMode().get()
}
}
inner class DisplayGroup : Group {
@ -309,13 +352,8 @@ class LibrarySettingsSheet(
override val footer = null
override fun initModels() {
val mode = preferences.libraryDisplayMode().get()
compactGrid.checked = mode == DisplayMode.COMPACT_GRID
comfortableGrid.checked = mode == DisplayMode.COMFORTABLE_GRID
// SY -->
noTitleGrid.checked = mode == DisplayMode.NO_TITLE_GRID
// SY <--
list.checked = mode == DisplayMode.LIST
val mode = getDisplayModePreference()
setGroupSelections(mode)
}
override fun onItemClicked(item: Item) {
@ -325,6 +363,37 @@ class LibrarySettingsSheet(
item.group.items.forEach { (it as Item.Radio).checked = false }
item.checked = true
setDisplayModePreference(item)
item.group.items.forEach { adapter.notifyItemChanged(it) }
}
// Sets display group selections based on given mode
fun setGroupSelections(mode: DisplayMode) {
compactGrid.checked = mode == DisplayMode.COMPACT_GRID
comfortableGrid.checked = mode == DisplayMode.COMFORTABLE_GRID
// SY -->
noTitleGrid.checked = mode == DisplayMode.NO_TITLE_GRID
// SY <--
list.checked = mode == DisplayMode.LIST
}
private fun setDisplayModePreference(item: Item) {
if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
val flag = when (item) {
compactGrid -> Category.COMPACT_GRID
comfortableGrid -> Category.COMFORTABLE_GRID
// SY -->
noTitleGrid -> Category.NO_TITLE_GRID
// SY <--
list -> Category.LIST
else -> throw NotImplementedError("Unknown display mode")
}
currentCategory?.displayMode = flag
db.insertCategory(currentCategory!!).executeAsBlocking()
} else {
preferences.libraryDisplayMode().set(
when (item) {
compactGrid -> DisplayMode.COMPACT_GRID
@ -336,8 +405,7 @@ class LibrarySettingsSheet(
else -> throw NotImplementedError("Unknown display mode")
}
)
item.group.items.forEach { adapter.notifyItemChanged(it) }
}
}
}
@ -501,6 +569,8 @@ class LibrarySettingsSheet(
*/
var onGroupClicked: (Group) -> Unit = {}
var currentCategory: Category? = null
fun setGroups(groups: List<Group>) {
adapter = Adapter(groups.map { it.createItems() }.flatten())
recycler.adapter = adapter

View File

@ -148,6 +148,12 @@ class SettingsLibraryController : SettingsController() {
true
}
}
switchPreference {
key = Keys.categorizedDisplay
titleRes = R.string.categorized_display_settings
defaultValue = false
}
}
preferenceCategory {

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
<eu.kanade.tachiyomi.widget.AutofitRecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/library_list"
android:layout_width="match_parent"

View File

@ -219,6 +219,7 @@
<string name="default_category">Default category</string>
<string name="default_category_summary">Always ask</string>
<string name="categorized_display_settings">Per-category display settings</string>
<plurals name="num_categories">
<item quantity="one">%d category</item>
<item quantity="other">%d categories</item>