Sort per category (#5408)

* Add flags for sorting per category

* Add logic to LibrarySettingsSheet

* Add  logic to LibraryPresenter

* Minor tweaks

* Use enum instead of variables

Also deprecates LibrarySort in favour of the new enum classes

* Remove debug log and suppress deprecation

* Convert DisplayMode setting to enum

Also fix bug were adapter would get de-synced with the current per category setting

* Fix migration crashing app due to values being access before migration

(cherry picked from commit 60890147c3c24ac30a75bfb8c4fab7b8cccd60be)

# Conflicts:
#	app/build.gradle.kts
#	app/src/main/java/eu/kanade/tachiyomi/data/database/models/Category.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceItem.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
This commit is contained in:
Andreas 2021-06-26 19:30:16 +02:00 committed by Jobobby04
parent 32e7750b7d
commit 6f6e6ad326
20 changed files with 400 additions and 210 deletions

View File

@ -12,6 +12,8 @@ import eu.kanade.tachiyomi.data.updater.UpdaterJob
import eu.kanade.tachiyomi.extension.ExtensionUpdateJob import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE
import eu.kanade.tachiyomi.ui.library.LibrarySort import eu.kanade.tachiyomi.ui.library.LibrarySort
import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting
import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.widget.ExtendedNavigationView import eu.kanade.tachiyomi.widget.ExtendedNavigationView
@ -98,9 +100,15 @@ object Migrations {
} }
if (oldVersion < 44) { if (oldVersion < 44) {
// Reset sorting preference if using removed sort by source // Reset sorting preference if using removed sort by source
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val oldSortingMode = prefs.getInt(PreferenceKeys.librarySortingMode, 0)
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
if (preferences.librarySortingMode().get() == LibrarySort.SOURCE) { if (oldSortingMode == LibrarySort.SOURCE) {
preferences.librarySortingMode().set(LibrarySort.ALPHA) prefs.edit {
putInt(PreferenceKeys.librarySortingMode, LibrarySort.ALPHA)
}
} }
} }
if (oldVersion < 52) { if (oldVersion < 52) {
@ -187,6 +195,40 @@ object Migrations {
LibraryUpdateJob.setupTask(context, 3) LibraryUpdateJob.setupTask(context, 3)
} }
} }
if (oldVersion < 64) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val oldSortingMode = prefs.getInt(PreferenceKeys.librarySortingMode, 0)
val oldSortingDirection = prefs.getBoolean(PreferenceKeys.librarySortingDirection, true)
@Suppress("DEPRECATION")
val newSortingMode = when (oldSortingMode) {
LibrarySort.ALPHA -> SortModeSetting.ALPHABETICAL
LibrarySort.LAST_READ -> SortModeSetting.LAST_READ
LibrarySort.LAST_CHECKED -> SortModeSetting.LAST_CHECKED
LibrarySort.UNREAD -> SortModeSetting.UNREAD
LibrarySort.TOTAL -> SortModeSetting.TOTAL_CHAPTERS
LibrarySort.LATEST_CHAPTER -> SortModeSetting.LATEST_CHAPTER
LibrarySort.CHAPTER_FETCH_DATE -> SortModeSetting.DATE_FETCHED
LibrarySort.DATE_ADDED -> SortModeSetting.DATE_ADDED
else -> SortModeSetting.ALPHABETICAL
}
val newSortingDirection = when (oldSortingDirection) {
true -> SortDirectionSetting.ASCENDING
else -> SortDirectionSetting.DESCENDING
}
prefs.edit(commit = true) {
remove(PreferenceKeys.librarySortingMode)
remove(PreferenceKeys.librarySortingDirection)
}
prefs.edit {
putString(PreferenceKeys.librarySortingMode, newSortingMode.name)
putString(PreferenceKeys.librarySortingDirection, newSortingDirection.name)
}
}
return true return true
} }

View File

@ -1,5 +1,8 @@
package eu.kanade.tachiyomi.data.database.models package eu.kanade.tachiyomi.data.database.models
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting
import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting
import java.io.Serializable import java.io.Serializable
interface Category : Serializable { interface Category : Serializable {
@ -21,21 +24,19 @@ interface Category : Serializable {
} }
var displayMode: Int var displayMode: Int
get() = flags and MASK get() = flags and DisplayModeSetting.MASK
set(mode) = setFlags(mode, MASK) set(mode) = setFlags(mode, DisplayModeSetting.MASK)
var sortMode: Int
get() = flags and SortModeSetting.MASK
set(mode) = setFlags(mode, SortModeSetting.MASK)
var sortDirection: Int
get() = flags and SortDirectionSetting.MASK
set(mode) = setFlags(mode, SortDirectionSetting.MASK)
companion object { 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 { fun create(name: String): Category = CategoryImpl().apply {
this.name = name this.name = name
} }

View File

@ -153,6 +153,7 @@ object PreferenceKeys {
const val filterLewd = "pref_filter_library_lewd" const val filterLewd = "pref_filter_library_lewd"
const val librarySortingMode = "library_sorting_mode" const val librarySortingMode = "library_sorting_mode"
const val librarySortingDirection = "library_sorting_ascending"
const val automaticExtUpdates = "automatic_ext_updates" const val automaticExtUpdates = "automatic_ext_updates"

View File

@ -39,16 +39,6 @@ object PreferenceValues {
/* ktlint-enable experimental:enum-entry-name-case */ /* ktlint-enable experimental:enum-entry-name-case */
enum class DisplayMode {
COMPACT_GRID,
COMFORTABLE_GRID,
LIST,
// SY -->
NO_TITLE_GRID,
// SY <--
}
enum class TappingInvertMode(val shouldInvertHorizontal: Boolean = false, val shouldInvertVertical: Boolean = false) { enum class TappingInvertMode(val shouldInvertHorizontal: Boolean = false, val shouldInvertVertical: Boolean = false) {
NONE, NONE,
HORIZONTAL(shouldInvertHorizontal = true), HORIZONTAL(shouldInvertHorizontal = true),

View File

@ -10,10 +10,12 @@ import com.tfcporciuncula.flow.FlowSharedPreferences
import com.tfcporciuncula.flow.Preference import com.tfcporciuncula.flow.Preference
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
import eu.kanade.tachiyomi.data.preference.PreferenceValues.ThemeMode.* import eu.kanade.tachiyomi.data.preference.PreferenceValues.ThemeMode.*
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.anilist.Anilist import eu.kanade.tachiyomi.data.track.anilist.Anilist
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting
import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
import eu.kanade.tachiyomi.ui.reader.setting.ReaderBottomButton import eu.kanade.tachiyomi.ui.reader.setting.ReaderBottomButton
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
@ -188,7 +190,7 @@ class PreferencesHelper(val context: Context) {
fun lastVersionCode() = flowPrefs.getInt("last_version_code", 0) fun lastVersionCode() = flowPrefs.getInt("last_version_code", 0)
fun sourceDisplayMode() = flowPrefs.getEnum(Keys.sourceDisplayMode, DisplayMode.COMPACT_GRID) fun sourceDisplayMode() = flowPrefs.getEnum(Keys.sourceDisplayMode, DisplayModeSetting.COMPACT_GRID)
fun enabledLanguages() = flowPrefs.getStringSet(Keys.enabledLanguages, setOf("all", "en", Locale.getDefault().language)) fun enabledLanguages() = flowPrefs.getStringSet(Keys.enabledLanguages, setOf("all", "en", Locale.getDefault().language))
@ -239,7 +241,7 @@ class PreferencesHelper(val context: Context) {
fun libraryUpdatePrioritization() = flowPrefs.getInt(Keys.libraryUpdatePrioritization, 0) fun libraryUpdatePrioritization() = flowPrefs.getInt(Keys.libraryUpdatePrioritization, 0)
fun libraryDisplayMode() = flowPrefs.getEnum(Keys.libraryDisplayMode, DisplayMode.COMPACT_GRID) fun libraryDisplayMode() = flowPrefs.getEnum(Keys.libraryDisplayMode, DisplayModeSetting.COMPACT_GRID)
fun downloadBadge() = flowPrefs.getBoolean(Keys.downloadBadge, false) fun downloadBadge() = flowPrefs.getBoolean(Keys.downloadBadge, false)
@ -265,9 +267,8 @@ class PreferencesHelper(val context: Context) {
fun filterLewd() = flowPrefs.getInt(Keys.filterLewd, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value) fun filterLewd() = flowPrefs.getInt(Keys.filterLewd, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
fun librarySortingMode() = flowPrefs.getInt(Keys.librarySortingMode, 0) fun librarySortingMode() = flowPrefs.getEnum(Keys.librarySortingMode, SortModeSetting.ALPHABETICAL)
fun librarySortingAscending() = flowPrefs.getEnum(Keys.librarySortingDirection, SortDirectionSetting.ASCENDING)
fun librarySortingAscending() = flowPrefs.getBoolean("library_sorting_ascending", true)
fun automaticExtUpdates() = flowPrefs.getBoolean(Keys.automaticExtUpdates, true) fun automaticExtUpdates() = flowPrefs.getBoolean(Keys.automaticExtUpdates, true)

View File

@ -25,7 +25,6 @@ import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.asImmediateFlow import eu.kanade.tachiyomi.data.preference.asImmediateFlow
import eu.kanade.tachiyomi.databinding.SourceControllerBinding import eu.kanade.tachiyomi.databinding.SourceControllerBinding
@ -43,6 +42,7 @@ import eu.kanade.tachiyomi.ui.browse.source.SourceController
import eu.kanade.tachiyomi.ui.browse.source.browse.SourceFilterSheet.FilterNavigationView.Companion.MAX_SAVED_SEARCHES import eu.kanade.tachiyomi.ui.browse.source.browse.SourceFilterSheet.FilterNavigationView.Companion.MAX_SAVED_SEARCHES
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.more.MoreController import eu.kanade.tachiyomi.ui.more.MoreController
@ -346,7 +346,7 @@ open class BrowseSourceController(bundle: Bundle) :
binding.catalogueView.removeView(oldRecycler) binding.catalogueView.removeView(oldRecycler)
} }
val recycler = if (preferences.sourceDisplayMode().get() == DisplayMode.LIST /* SY --> */ || (preferences.enhancedEHentaiView().get() && presenter.source.isEhBasedSource()) /* SY <-- */) { val recycler = if (preferences.sourceDisplayMode().get() == DisplayModeSetting.LIST /* SY --> */ || (preferences.enhancedEHentaiView().get() && presenter.source.isEhBasedSource()) /* SY <-- */) {
RecyclerView(view.context).apply { RecyclerView(view.context).apply {
id = R.id.recycler id = R.id.recycler
layoutManager = LinearLayoutManager(context) layoutManager = LinearLayoutManager(context)
@ -414,12 +414,12 @@ open class BrowseSourceController(bundle: Bundle) :
) )
val displayItem = when (preferences.sourceDisplayMode().get()) { val displayItem = when (preferences.sourceDisplayMode().get()) {
DisplayMode.COMPACT_GRID -> R.id.action_compact_grid DisplayModeSetting.COMPACT_GRID -> R.id.action_compact_grid
DisplayMode.COMFORTABLE_GRID -> R.id.action_comfortable_grid DisplayModeSetting.COMFORTABLE_GRID -> R.id.action_comfortable_grid
// SY --> // SY -->
DisplayMode.NO_TITLE_GRID -> R.id.action_no_title_grid DisplayModeSetting.NO_TITLE_GRID -> R.id.action_no_title_grid
// SY <-- // SY <--
DisplayMode.LIST -> R.id.action_list DisplayModeSetting.LIST -> R.id.action_list
} }
menu.findItem(displayItem).isChecked = true menu.findItem(displayItem).isChecked = true
// SY --> // SY -->
@ -450,12 +450,12 @@ open class BrowseSourceController(bundle: Bundle) :
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
R.id.action_search -> expandActionViewFromInteraction = true R.id.action_search -> expandActionViewFromInteraction = true
R.id.action_compact_grid -> setDisplayMode(DisplayMode.COMPACT_GRID) R.id.action_compact_grid -> setDisplayMode(DisplayModeSetting.COMPACT_GRID)
R.id.action_comfortable_grid -> setDisplayMode(DisplayMode.COMFORTABLE_GRID) R.id.action_comfortable_grid -> setDisplayMode(DisplayModeSetting.COMFORTABLE_GRID)
// SY --> // SY -->
R.id.action_no_title_grid -> setDisplayMode(DisplayMode.NO_TITLE_GRID) R.id.action_no_title_grid -> setDisplayMode(DisplayModeSetting.NO_TITLE_GRID)
// SY <-- // SY <--
R.id.action_list -> setDisplayMode(DisplayMode.LIST) R.id.action_list -> setDisplayMode(DisplayModeSetting.LIST)
R.id.action_open_in_web_view -> openInWebView() R.id.action_open_in_web_view -> openInWebView()
// SY --> // SY -->
R.id.action_settings -> openSourceSettings() R.id.action_settings -> openSourceSettings()
@ -621,7 +621,7 @@ open class BrowseSourceController(bundle: Bundle) :
* *
* @param mode the mode to change to * @param mode the mode to change to
*/ */
private fun setDisplayMode(mode: DisplayMode) { private fun setDisplayMode(mode: DisplayModeSetting) {
val view = view ?: return val view = view ?: return
val adapter = adapter ?: return val adapter = adapter ?: return

View File

@ -28,13 +28,13 @@ import java.util.Date
* @param adapter the adapter handling this holder. * @param adapter the adapter handling this holder.
* @constructor creates a new catalogue holder. * @constructor creates a new catalogue holder.
*/ */
class SourceEnhancedEHentaiListHolder(private val view: View, adapter: FlexibleAdapter<*>) : class SourceEnhancedEHentaiListHolder(view: View, adapter: FlexibleAdapter<*>) :
SourceHolder<SourceEnhancedEhentaiListItemBinding>(view, adapter) { SourceHolder<SourceEnhancedEhentaiListItemBinding>(view, adapter) {
override val binding = SourceEnhancedEhentaiListItemBinding.bind(view) override val binding = SourceEnhancedEhentaiListItemBinding.bind(itemView)
private val favoriteColor = view.context.getResourceColor(R.attr.colorOnSurface, 0.38f) private val favoriteColor = itemView.context.getResourceColor(R.attr.colorOnSurface, 0.38f)
private val unfavoriteColor = view.context.getResourceColor(R.attr.colorOnSurface) private val unfavoriteColor = itemView.context.getResourceColor(R.attr.colorOnSurface)
/** /**
* Method called from [CatalogueAdapter.onBindViewHolder]. It updates the data for this * Method called from [CatalogueAdapter.onBindViewHolder]. It updates the data for this
@ -81,7 +81,7 @@ class SourceEnhancedEHentaiListHolder(private val view: View, adapter: FlexibleA
if (pair != null) { if (pair != null) {
binding.genre.setBackgroundColor(pair.first.color) binding.genre.setBackgroundColor(pair.first.color)
binding.genre.text = view.context.getString(pair.second) binding.genre.text = itemView.context.getString(pair.second)
} else binding.genre.text = metadata.genre } else binding.genre.text = metadata.genre
metadata.datePosted?.let { binding.datePosted.text = MetadataUtil.EX_DATE_FORMAT.format(Date(it)) } metadata.datePosted?.let { binding.datePosted.text = MetadataUtil.EX_DATE_FORMAT.format(Date(it)) }
@ -96,9 +96,9 @@ class SourceEnhancedEHentaiListHolder(private val view: View, adapter: FlexibleA
val pageCount = metadata.length val pageCount = metadata.length
binding.language.text = if (locale != null && pageCount != null) { binding.language.text = if (locale != null && pageCount != null) {
view.resources.getQuantityString(R.plurals.browse_language_and_pages, pageCount, pageCount, locale.toLanguageTag().uppercase()) itemView.resources.getQuantityString(R.plurals.browse_language_and_pages, pageCount, pageCount, locale.toLanguageTag().uppercase())
} else if (pageCount != null) { } else if (pageCount != null) {
view.resources.getQuantityString(R.plurals.num_pages, pageCount, pageCount) itemView.resources.getQuantityString(R.plurals.num_pages, pageCount, pageCount)
} else locale?.toLanguageTag()?.uppercase() } else locale?.toLanguageTag()?.uppercase()
} }
@ -108,10 +108,10 @@ class SourceEnhancedEHentaiListHolder(private val view: View, adapter: FlexibleA
binding.thumbnail.clear() binding.thumbnail.clear()
if (!manga.thumbnail_url.isNullOrEmpty()) { if (!manga.thumbnail_url.isNullOrEmpty()) {
val crossfadeDuration = view.context.imageLoader.defaults.transition.let { val crossfadeDuration = itemView.context.imageLoader.defaults.transition.let {
if (it is CrossfadeTransition) it.durationMillis else 0 if (it is CrossfadeTransition) it.durationMillis else 0
} }
val request = ImageRequest.Builder(view.context) val request = ImageRequest.Builder(itemView.context)
.data(manga) .data(manga)
.setParameter(MangaCoverFetcher.USE_CUSTOM_COVER, false) .setParameter(MangaCoverFetcher.USE_CUSTOM_COVER, false)
.diskCachePolicy(CachePolicy.DISABLED) .diskCachePolicy(CachePolicy.DISABLED)

View File

@ -12,16 +12,16 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
import eu.kanade.tachiyomi.widget.AutofitRecyclerView import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import exh.metadata.metadata.base.RaisedSearchMetadata import exh.metadata.metadata.base.RaisedSearchMetadata
import exh.source.isEhBasedManga import exh.source.isEhBasedManga
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMode> /* SY --> */, private val metadata: RaisedSearchMetadata? = null /* SY <-- */) : class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayModeSetting> /* SY --> */, private val metadata: RaisedSearchMetadata? = null /* SY <-- */) :
AbstractFlexibleItem<SourceHolder<*>>() { AbstractFlexibleItem<SourceHolder<*>>() {
// SY --> // SY -->
val preferences: PreferencesHelper by injectLazy() val preferences: PreferencesHelper by injectLazy()
@ -30,9 +30,9 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
override fun getLayoutRes(): Int { override fun getLayoutRes(): Int {
return /* SY --> */ if (manga.isEhBasedManga() && preferences.enhancedEHentaiView().get()) R.layout.source_enhanced_ehentai_list_item return /* SY --> */ if (manga.isEhBasedManga() && preferences.enhancedEHentaiView().get()) R.layout.source_enhanced_ehentai_list_item
else /* SY <-- */ when (displayMode.get()) { else /* SY <-- */ when (displayMode.get()) {
DisplayMode.COMPACT_GRID -> R.layout.source_compact_grid_item DisplayModeSetting.COMPACT_GRID -> R.layout.source_compact_grid_item
DisplayMode.COMFORTABLE_GRID, /* SY --> */ DisplayMode.NO_TITLE_GRID /* SY <-- */ -> R.layout.source_comfortable_grid_item DisplayModeSetting.COMFORTABLE_GRID, /* SY --> */ DisplayModeSetting.NO_TITLE_GRID /* SY <-- */ -> R.layout.source_comfortable_grid_item
DisplayMode.LIST -> R.layout.source_list_item DisplayModeSetting.LIST -> R.layout.source_list_item
} }
} }
@ -43,7 +43,7 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
return /* SY --> */ if (manga.isEhBasedManga() && preferences.enhancedEHentaiView().get()) { return /* SY --> */ if (manga.isEhBasedManga() && preferences.enhancedEHentaiView().get()) {
SourceEnhancedEHentaiListHolder(view, adapter) SourceEnhancedEHentaiListHolder(view, adapter)
} else /* SY <-- */ when (displayMode.get()) { } else /* SY <-- */ when (displayMode.get()) {
DisplayMode.COMPACT_GRID -> { DisplayModeSetting.COMPACT_GRID -> {
val binding = SourceCompactGridItemBinding.bind(view) val binding = SourceCompactGridItemBinding.bind(view)
val parent = adapter.recyclerView as AutofitRecyclerView val parent = adapter.recyclerView as AutofitRecyclerView
val coverHeight = parent.itemWidth / 3 * 4 val coverHeight = parent.itemWidth / 3 * 4
@ -60,7 +60,7 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
} }
SourceGridHolder(view, adapter) SourceGridHolder(view, adapter)
} }
DisplayMode.COMFORTABLE_GRID /* SY --> */, DisplayMode.NO_TITLE_GRID /* SY <-- */ -> { DisplayModeSetting.COMFORTABLE_GRID /* SY --> */, DisplayModeSetting.NO_TITLE_GRID /* SY <-- */ -> {
val binding = SourceComfortableGridItemBinding.bind(view) val binding = SourceComfortableGridItemBinding.bind(view)
val parent = adapter.recyclerView as AutofitRecyclerView val parent = adapter.recyclerView as AutofitRecyclerView
val coverHeight = parent.itemWidth / 3 * 4 val coverHeight = parent.itemWidth / 3 * 4
@ -70,9 +70,9 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
coverHeight coverHeight
) )
} }
SourceComfortableGridHolder(view, adapter, displayMode.get() != DisplayMode.NO_TITLE_GRID) SourceComfortableGridHolder(view, adapter, displayMode.get() != DisplayModeSetting.NO_TITLE_GRID)
} }
DisplayMode.LIST -> { DisplayModeSetting.LIST -> {
SourceListHolder(view, adapter) SourceListHolder(view, adapter)
} }
} }

View File

@ -15,10 +15,11 @@ import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.library.LibraryUpdateService import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.data.preference.PreferenceValues import eu.kanade.tachiyomi.data.preference.PreferenceValues
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.LibraryCategoryBinding import eu.kanade.tachiyomi.databinding.LibraryCategoryBinding
import eu.kanade.tachiyomi.ui.category.CategoryAdapter import eu.kanade.tachiyomi.ui.category.CategoryAdapter
import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting
import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting
import eu.kanade.tachiyomi.util.lang.plusAssign import eu.kanade.tachiyomi.util.lang.plusAssign
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.inflate import eu.kanade.tachiyomi.util.view.inflate
@ -38,6 +39,7 @@ import rx.subscriptions.CompositeSubscription
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.util.ArrayDeque import java.util.ArrayDeque
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting as DisplayMode
/** /**
* Fragment containing the library manga for a certain category. * Fragment containing the library manga for a certain category.
@ -158,7 +160,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
// If displayMode should be set from category adjust manga count per row // If displayMode should be set from category adjust manga count per row
if (preferences.categorisedDisplaySettings().get()) { if (preferences.categorisedDisplaySettings().get()) {
recycler.spanCount = if (category.displayMode == Category.LIST || (preferences.libraryDisplayMode().get() == DisplayMode.LIST && category.id == 0)) { recycler.spanCount = if (DisplayMode.fromFlag(category.displayMode) == DisplayMode.LIST || (preferences.libraryDisplayMode().get() == DisplayMode.LIST && category.id == 0)) {
1 1
} else { } else {
controller.mangaPerRow controller.mangaPerRow
@ -264,10 +266,15 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
private suspend fun onNextLibraryManga(cScope: CoroutineScope, event: LibraryMangaEvent) { private suspend fun onNextLibraryManga(cScope: CoroutineScope, event: LibraryMangaEvent) {
// Get the manga list for this category. // Get the manga list for this category.
// SY --> // SY -->
val sortingMode = preferences.librarySortingMode().get()
adapter.isLongPressDragEnabled = adapter.canDrag() adapter.isLongPressDragEnabled = adapter.canDrag()
var mangaForCategory = event.getMangaForCategory(category).orEmpty() var mangaForCategory = event.getMangaForCategory(category).orEmpty()
if (sortingMode == LibrarySort.DRAG_AND_DROP) { if (preferences.categorisedDisplaySettings().get() && category.id != 0) {
if (SortModeSetting.fromFlag(category.sortMode) == SortModeSetting.DRAG_AND_DROP) {
mangaForCategory = mangaForCategory.sortedBy {
category.mangaOrder.indexOf(it.manga.id)
}
}
} else if (preferences.librarySortingMode().get() == SortModeSetting.DRAG_AND_DROP) {
if (category.id == 0) { if (category.id == 0) {
category.mangaOrder = preferences.defaultMangaOrder().get() category.mangaOrder = preferences.defaultMangaOrder().get()
.split("/") .split("/")
@ -435,10 +442,15 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
} else { } else {
db.insertCategory(category).asRxObservable().subscribe() db.insertCategory(category).asRxObservable().subscribe()
} }
if (preferences.librarySortingMode().get() != LibrarySort.DRAG_AND_DROP) { if (preferences.categorisedDisplaySettings().get() && category.id != 0) {
preferences.librarySortingAscending().set(true) if (SortModeSetting.fromFlag(category.sortMode) != SortModeSetting.DRAG_AND_DROP) {
preferences.librarySortingMode().set(LibrarySort.DRAG_AND_DROP) category.sortMode = SortModeSetting.DRAG_AND_DROP.flag
controller.refreshSort() category.sortDirection = SortDirectionSetting.ASCENDING.flag
db.insertCategory(category).asRxObservable().subscribe()
}
} else if (preferences.librarySortingMode().get() != SortModeSetting.DRAG_AND_DROP) {
preferences.librarySortingAscending().set(SortDirectionSetting.ASCENDING)
preferences.librarySortingMode().set(SortModeSetting.DRAG_AND_DROP)
} }
} }
// SY <-- // SY <--

View File

@ -333,6 +333,11 @@ class LibraryController(
.map { (it.id ?: -1) to (mangaMap[it.id]?.size ?: 0) } .map { (it.id ?: -1) to (mangaMap[it.id]?.size ?: 0) }
.toMap() .toMap()
if (preferences.categorisedDisplaySettings().get()) {
// Reattach adapter so it doesn't get de-synced
reattachAdapter()
}
// Restore active category. // Restore active category.
binding.libraryPager.setCurrentItem(activeCat, false) binding.libraryPager.setCurrentItem(activeCat, false)
@ -852,9 +857,5 @@ class LibraryController(
destroyActionModeIfNeeded() destroyActionModeIfNeeded()
startActivity(intent) startActivity(intent)
} }
fun refreshSort() {
settingsSheet?.refreshSort()
}
// <-- EXH // <-- EXH
} }

View File

@ -13,10 +13,10 @@ import eu.davidea.flexibleadapter.items.IFilterable
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.LibraryManga import eu.kanade.tachiyomi.data.database.models.LibraryManga
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
import eu.kanade.tachiyomi.widget.AutofitRecyclerView import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -24,7 +24,7 @@ import uy.kohesive.injekt.api.get
class LibraryItem( class LibraryItem(
val manga: LibraryManga, val manga: LibraryManga,
private val shouldSetFromCategory: Preference<Boolean>, private val shouldSetFromCategory: Preference<Boolean>,
private val defaultLibraryDisplayMode: Preference<DisplayMode> private val defaultLibraryDisplayMode: Preference<DisplayModeSetting>
) : ) :
AbstractFlexibleItem<LibraryHolder<*>>(), IFilterable<String> { AbstractFlexibleItem<LibraryHolder<*>>(), IFilterable<String> {
@ -39,13 +39,9 @@ class LibraryItem(
var startReadingButton = false var startReadingButton = false
// SY <-- // SY <--
private fun getDisplayMode(): DisplayMode { private fun getDisplayMode(): DisplayModeSetting {
return if (shouldSetFromCategory.get() && manga.category != 0) { return if (shouldSetFromCategory.get() && manga.category != 0) {
if (displayMode != -1) { DisplayModeSetting.fromFlag(displayMode)
DisplayMode.values()[displayMode]
} else {
DisplayMode.COMPACT_GRID
}
} else { } else {
defaultLibraryDisplayMode.get() defaultLibraryDisplayMode.get()
} }
@ -53,15 +49,15 @@ class LibraryItem(
override fun getLayoutRes(): Int { override fun getLayoutRes(): Int {
return when (getDisplayMode()) { return when (getDisplayMode()) {
DisplayMode.COMPACT_GRID -> R.layout.source_compact_grid_item DisplayModeSetting.COMPACT_GRID -> R.layout.source_compact_grid_item
DisplayMode.COMFORTABLE_GRID /* SY --> */, DisplayMode.NO_TITLE_GRID /* SY <-- */ -> R.layout.source_comfortable_grid_item DisplayModeSetting.COMFORTABLE_GRID /* SY --> */, DisplayModeSetting.NO_TITLE_GRID /* SY <-- */ -> R.layout.source_comfortable_grid_item
DisplayMode.LIST -> R.layout.source_list_item DisplayModeSetting.LIST -> R.layout.source_list_item
} }
} }
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder<*> { override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder<*> {
return when (val displayMode = getDisplayMode()) { return when (val displayMode = getDisplayMode()) {
DisplayMode.COMPACT_GRID -> { DisplayModeSetting.COMPACT_GRID -> {
val binding = SourceCompactGridItemBinding.bind(view) val binding = SourceCompactGridItemBinding.bind(view)
val parent = adapter.recyclerView as AutofitRecyclerView val parent = adapter.recyclerView as AutofitRecyclerView
val coverHeight = parent.itemWidth / 3 * 4 val coverHeight = parent.itemWidth / 3 * 4
@ -75,7 +71,7 @@ class LibraryItem(
} }
LibraryCompactGridHolder(view, adapter) LibraryCompactGridHolder(view, adapter)
} }
DisplayMode.COMFORTABLE_GRID /* SY --> */, DisplayMode.NO_TITLE_GRID /* SY <-- */ -> { DisplayModeSetting.COMFORTABLE_GRID /* SY --> */, DisplayModeSetting.NO_TITLE_GRID /* SY <-- */ -> {
val binding = SourceComfortableGridItemBinding.bind(view) val binding = SourceComfortableGridItemBinding.bind(view)
val parent = adapter.recyclerView as AutofitRecyclerView val parent = adapter.recyclerView as AutofitRecyclerView
val coverHeight = parent.itemWidth / 3 * 4 val coverHeight = parent.itemWidth / 3 * 4
@ -85,9 +81,9 @@ class LibraryItem(
coverHeight coverHeight
) )
} }
LibraryComfortableGridHolder(view, adapter, displayMode != DisplayMode.NO_TITLE_GRID) LibraryComfortableGridHolder(view, adapter, displayMode != DisplayModeSetting.NO_TITLE_GRID)
} }
DisplayMode.LIST -> { DisplayModeSetting.LIST -> {
LibraryListHolder(view, adapter) LibraryListHolder(view, adapter)
} }
} }

View File

@ -18,6 +18,8 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.all.MergedSource import eu.kanade.tachiyomi.source.online.all.MergedSource
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting
import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting
import eu.kanade.tachiyomi.util.isLocal import eu.kanade.tachiyomi.util.isLocal
import eu.kanade.tachiyomi.util.lang.combineLatest import eu.kanade.tachiyomi.util.lang.combineLatest
import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed
@ -142,7 +144,7 @@ class LibraryPresenter(
lib.copy(mangaMap = applyFilters(lib.mangaMap, tracks)) lib.copy(mangaMap = applyFilters(lib.mangaMap, tracks))
} }
.combineLatest(sortTriggerRelay.observeOn(Schedulers.io())) { lib, _ -> .combineLatest(sortTriggerRelay.observeOn(Schedulers.io())) { lib, _ ->
lib.copy(mangaMap = applySort(lib.mangaMap)) lib.copy(mangaMap = applySort(lib.categories, lib.mangaMap))
} }
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribeLatestCache({ view, (categories, mangaMap) -> .subscribeLatestCache({ view, (categories, mangaMap) ->
@ -318,9 +320,7 @@ class LibraryPresenter(
* *
* @param map the map to sort. * @param map the map to sort.
*/ */
private fun applySort(map: LibraryMap): LibraryMap { private fun applySort(categories: List<Category>, map: LibraryMap): LibraryMap {
val sortingMode = preferences.librarySortingMode().get()
val lastReadManga by lazy { val lastReadManga by lazy {
var counter = 0 var counter = 0
db.getLastReadManga().executeAsBlocking().associate { it.id!! to counter++ } db.getLastReadManga().executeAsBlocking().associate { it.id!! to counter++ }
@ -352,65 +352,77 @@ class LibraryPresenter(
} }
// SY <-- // SY <--
val sortAscending = preferences.librarySortingAscending().get() val sortingModes = categories.associate { category ->
(category.id ?: 0) to SortModeSetting.get(preferences, category)
}
val sortAscending = categories.associate { category ->
(category.id ?: 0) to SortDirectionSetting.get(preferences, category)
}
val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 -> val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 ->
val sortingMode = sortingModes[i1.manga.category]!!
val sortAscending = sortAscending[i1.manga.category]!! == SortDirectionSetting.ASCENDING
when (sortingMode) { when (sortingMode) {
LibrarySort.ALPHA -> i1.manga.title.compareTo(i2.manga.title, true) SortModeSetting.ALPHABETICAL -> i1.manga.title.compareTo(i2.manga.title, true)
LibrarySort.LAST_READ -> { SortModeSetting.LAST_READ -> {
// Get index of manga, set equal to list if size unknown. // Get index of manga, set equal to list if size unknown.
val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size
val manga2LastRead = lastReadManga[i2.manga.id!!] ?: lastReadManga.size val manga2LastRead = lastReadManga[i2.manga.id!!] ?: lastReadManga.size
manga1LastRead.compareTo(manga2LastRead) manga1LastRead.compareTo(manga2LastRead)
} }
LibrarySort.LAST_CHECKED -> i2.manga.last_update.compareTo(i1.manga.last_update) SortModeSetting.LAST_CHECKED -> i2.manga.last_update.compareTo(i1.manga.last_update)
LibrarySort.UNREAD -> when { SortModeSetting.UNREAD -> when {
// Ensure unread content comes first // Ensure unread content comes first
i1.manga.unread == i2.manga.unread -> 0 i1.manga.unread == i2.manga.unread -> 0
i1.manga.unread == 0 -> if (sortAscending) 1 else -1 i1.manga.unread == 0 -> if (sortAscending) 1 else -1
i2.manga.unread == 0 -> if (sortAscending) -1 else 1 i2.manga.unread == 0 -> if (sortAscending) -1 else 1
else -> i1.manga.unread.compareTo(i2.manga.unread) else -> i1.manga.unread.compareTo(i2.manga.unread)
} }
LibrarySort.TOTAL -> { SortModeSetting.TOTAL_CHAPTERS -> {
val manga1TotalChapter = totalChapterManga[i1.manga.id!!] ?: 0 val manga1TotalChapter = totalChapterManga[i1.manga.id!!] ?: 0
val mange2TotalChapter = totalChapterManga[i2.manga.id!!] ?: 0 val mange2TotalChapter = totalChapterManga[i2.manga.id!!] ?: 0
manga1TotalChapter.compareTo(mange2TotalChapter) manga1TotalChapter.compareTo(mange2TotalChapter)
} }
LibrarySort.LATEST_CHAPTER -> { SortModeSetting.LATEST_CHAPTER -> {
val manga1latestChapter = latestChapterManga[i1.manga.id!!] val manga1latestChapter = latestChapterManga[i1.manga.id!!]
?: latestChapterManga.size ?: latestChapterManga.size
val manga2latestChapter = latestChapterManga[i2.manga.id!!] val manga2latestChapter = latestChapterManga[i2.manga.id!!]
?: latestChapterManga.size ?: latestChapterManga.size
manga1latestChapter.compareTo(manga2latestChapter) manga1latestChapter.compareTo(manga2latestChapter)
} }
LibrarySort.CHAPTER_FETCH_DATE -> { SortModeSetting.DATE_FETCHED -> {
val manga1chapterFetchDate = chapterFetchDateManga[i1.manga.id!!] val manga1chapterFetchDate = chapterFetchDateManga[i1.manga.id!!]
?: chapterFetchDateManga.size ?: chapterFetchDateManga.size
val manga2chapterFetchDate = chapterFetchDateManga[i2.manga.id!!] val manga2chapterFetchDate = chapterFetchDateManga[i2.manga.id!!]
?: chapterFetchDateManga.size ?: chapterFetchDateManga.size
manga1chapterFetchDate.compareTo(manga2chapterFetchDate) manga1chapterFetchDate.compareTo(manga2chapterFetchDate)
} }
LibrarySort.DATE_ADDED -> i2.manga.date_added.compareTo(i1.manga.date_added) SortModeSetting.DATE_ADDED -> i2.manga.date_added.compareTo(i1.manga.date_added)
// SY --> // SY -->
LibrarySort.DRAG_AND_DROP -> { SortModeSetting.DRAG_AND_DROP -> {
0 0
} }
LibrarySort.TAG_LIST -> { SortModeSetting.TAG_LIST -> {
val manga1IndexOfTag = listOfTags.indexOfFirst { i1.manga.getGenres()?.contains(it) ?: false } val manga1IndexOfTag = listOfTags.indexOfFirst { i1.manga.getGenres()?.contains(it) ?: false }
val manga2IndexOfTag = listOfTags.indexOfFirst { i2.manga.getGenres()?.contains(it) ?: false } val manga2IndexOfTag = listOfTags.indexOfFirst { i2.manga.getGenres()?.contains(it) ?: false }
manga1IndexOfTag.compareTo(manga2IndexOfTag) manga1IndexOfTag.compareTo(manga2IndexOfTag)
} }
// SY <-- // SY <--
else -> throw Exception("Unknown sorting mode")
} }
} }
val comparator = if (sortAscending) { return map.mapValues { entry ->
Comparator(sortFn) val sortAscending = sortAscending[entry.key]!! == SortDirectionSetting.ASCENDING
} else {
Collections.reverseOrder(sortFn)
}
return map.mapValues { entry -> entry.value.sortedWith(comparator) } val comparator = if (sortAscending) {
Comparator(sortFn)
} else {
Collections.reverseOrder(sortFn)
}
entry.value.sortedWith(comparator)
}
} }
/** /**
@ -441,7 +453,7 @@ class LibraryPresenter(
// SY --> // SY -->
private fun applyGrouping(map: LibraryMap, categories: List<Category>): Pair<LibraryMap, List<Category>> { private fun applyGrouping(map: LibraryMap, categories: List<Category>): Pair<LibraryMap, List<Category>> {
groupType = preferences.groupLibraryBy().get() groupType = preferences.groupLibraryBy().get()
var editedCategories: List<Category> = categories var editedCategories = categories
val libraryMangaAsList = map.flatMap { it.value }.distinctBy { it.manga.id } val libraryMangaAsList = map.flatMap { it.value }.distinctBy { it.manga.id }
val items = if (groupType == LibraryGroup.BY_DEFAULT) { val items = if (groupType == LibraryGroup.BY_DEFAULT) {
map map

View File

@ -7,10 +7,12 @@ import com.bluelinelabs.conductor.Router
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Category 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.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting
import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting
import eu.kanade.tachiyomi.widget.ExtendedNavigationView import eu.kanade.tachiyomi.widget.ExtendedNavigationView
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State
import eu.kanade.tachiyomi.widget.sheet.TabbedBottomSheetDialog import eu.kanade.tachiyomi.widget.sheet.TabbedBottomSheetDialog
@ -44,15 +46,13 @@ class LibrarySettingsSheet(
grouping.onGroupClicked = onGroupClickListener grouping.onGroupClicked = onGroupClickListener
} }
fun refreshSort() {
sort.refreshMode()
}
/** /**
* adjusts selected button to match real state. * adjusts selected button to match real state.
* @param currentCategory ID of currently shown category * @param currentCategory ID of currently shown category
*/ */
fun show(currentCategory: Category) { fun show(currentCategory: Category) {
sort.currentCategory = currentCategory
sort.adjustDisplaySelection()
display.currentCategory = currentCategory display.currentCategory = currentCategory
display.adjustDisplaySelection() display.adjustDisplaySelection()
super.show() super.show()
@ -182,17 +182,17 @@ class LibrarySettingsSheet(
inner class Sort @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : inner class Sort @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
Settings(context, attrs) { Settings(context, attrs) {
private val sort = SortGroup()
init { init {
setGroups(listOf(SortGroup())) setGroups(listOf(sort))
} }
// SY --> // Refreshes Display Setting selections
fun refreshMode() { fun adjustDisplaySelection() {
recycler.adapter = null sort.initModels()
removeView(recycler) sort.items.forEach { adapter.notifyItemChanged(it) }
setGroups(listOf(SortGroup()))
} }
// SY <--
inner class SortGroup : Group { inner class SortGroup : Group {
@ -217,33 +217,34 @@ class LibrarySettingsSheet(
override val footer = null override val footer = null
override fun initModels() { override fun initModels() {
val sorting = preferences.librarySortingMode().get() val sorting = SortModeSetting.get(preferences, currentCategory)
val order = if (preferences.librarySortingAscending().get()) { val order = if (SortDirectionSetting.get(preferences, currentCategory) == SortDirectionSetting.ASCENDING) {
Item.MultiSort.SORT_ASC Item.MultiSort.SORT_ASC
} else { } else {
Item.MultiSort.SORT_DESC Item.MultiSort.SORT_DESC
} }
alphabetically.state = alphabetically.state =
if (sorting == LibrarySort.ALPHA) order else Item.MultiSort.SORT_NONE if (sorting == SortModeSetting.ALPHABETICAL) order else Item.MultiSort.SORT_NONE
lastRead.state = lastRead.state =
if (sorting == LibrarySort.LAST_READ) order else Item.MultiSort.SORT_NONE if (sorting == SortModeSetting.LAST_READ) order else Item.MultiSort.SORT_NONE
lastChecked.state = lastChecked.state =
if (sorting == LibrarySort.LAST_CHECKED) order else Item.MultiSort.SORT_NONE if (sorting == SortModeSetting.LAST_CHECKED) order else Item.MultiSort.SORT_NONE
unread.state = unread.state =
if (sorting == LibrarySort.UNREAD) order else Item.MultiSort.SORT_NONE if (sorting == SortModeSetting.UNREAD) order else Item.MultiSort.SORT_NONE
total.state = total.state =
if (sorting == LibrarySort.TOTAL) order else Item.MultiSort.SORT_NONE if (sorting == SortModeSetting.TOTAL_CHAPTERS) order else Item.MultiSort.SORT_NONE
latestChapter.state = latestChapter.state =
if (sorting == LibrarySort.LATEST_CHAPTER) order else Item.MultiSort.SORT_NONE if (sorting == SortModeSetting.LATEST_CHAPTER) order else Item.MultiSort.SORT_NONE
chapterFetchDate.state = chapterFetchDate.state =
if (sorting == LibrarySort.CHAPTER_FETCH_DATE) order else Item.MultiSort.SORT_NONE if (sorting == SortModeSetting.DATE_FETCHED) order else Item.MultiSort.SORT_NONE
dateAdded.state = dateAdded.state =
if (sorting == LibrarySort.DATE_ADDED) order else Item.MultiSort.SORT_NONE if (sorting == SortModeSetting.DATE_ADDED) order else Item.MultiSort.SORT_NONE
// SY --> // SY -->
dragAndDrop.state = if (sorting == LibrarySort.DRAG_AND_DROP) order else Item.MultiSort.SORT_NONE dragAndDrop.state =
if (sorting == SortModeSetting.DRAG_AND_DROP) order else Item.MultiSort.SORT_NONE
tagList.state = tagList.state =
if (sorting == LibrarySort.TAG_LIST) order else Item.MultiSort.SORT_NONE if (sorting == SortModeSetting.TAG_LIST) order else Item.MultiSort.SORT_NONE
// SY <-- // SY <--
} }
@ -271,27 +272,61 @@ class LibrarySettingsSheet(
} }
// SY <-- // SY <--
preferences.librarySortingMode().set( item.state = when (prevState) {
when (item) { Item.MultiSort.SORT_NONE -> Item.MultiSort.SORT_ASC
alphabetically -> LibrarySort.ALPHA Item.MultiSort.SORT_ASC -> Item.MultiSort.SORT_DESC
lastRead -> LibrarySort.LAST_READ Item.MultiSort.SORT_DESC -> Item.MultiSort.SORT_ASC
lastChecked -> LibrarySort.LAST_CHECKED else -> throw Exception("Unknown state")
unread -> LibrarySort.UNREAD }
total -> LibrarySort.TOTAL
latestChapter -> LibrarySort.LATEST_CHAPTER setSortModePreference(item)
chapterFetchDate -> LibrarySort.CHAPTER_FETCH_DATE
dateAdded -> LibrarySort.DATE_ADDED setSortDirectionPrefernece(item)
// SY -->
dragAndDrop -> LibrarySort.DRAG_AND_DROP
tagList -> LibrarySort.TAG_LIST
// SY <--
else -> throw Exception("Unknown sorting")
}
)
preferences.librarySortingAscending().set(item.state == Item.MultiSort.SORT_ASC)
item.group.items.forEach { adapter.notifyItemChanged(it) } item.group.items.forEach { adapter.notifyItemChanged(it) }
} }
private fun setSortDirectionPrefernece(item: Item.MultiStateGroup) {
val flag = if (item.state == Item.MultiSort.SORT_ASC) {
SortDirectionSetting.ASCENDING
} else {
SortDirectionSetting.DESCENDING
}
if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0 /* SY --> */ && preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT /* SY <-- */) {
currentCategory?.sortDirection = flag.flag
db.insertCategory(currentCategory!!).executeAsBlocking()
} else {
preferences.librarySortingAscending().set(flag)
}
}
private fun setSortModePreference(item: Item) {
val flag = when (item) {
alphabetically -> SortModeSetting.ALPHABETICAL
lastRead -> SortModeSetting.LAST_READ
lastChecked -> SortModeSetting.LAST_CHECKED
unread -> SortModeSetting.UNREAD
total -> SortModeSetting.TOTAL_CHAPTERS
latestChapter -> SortModeSetting.LATEST_CHAPTER
chapterFetchDate -> SortModeSetting.DATE_FETCHED
dateAdded -> SortModeSetting.DATE_ADDED
// SY -->
dragAndDrop -> SortModeSetting.DRAG_AND_DROP
tagList -> SortModeSetting.TAG_LIST
// SY <--
else -> throw NotImplementedError("Unknown display mode")
}
if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0 /* SY --> */ && preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT /* SY <-- */) {
currentCategory?.sortMode = flag.flag
db.insertCategory(currentCategory!!).executeAsBlocking()
} else {
preferences.librarySortingMode().set(flag)
}
}
} }
} }
@ -328,9 +363,9 @@ class LibrarySettingsSheet(
} }
// Gets user preference of currently selected display mode at current category // Gets user preference of currently selected display mode at current category
private fun getDisplayModePreference(): DisplayMode { private fun getDisplayModePreference(): DisplayModeSetting {
return if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { return if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0 /* SY --> */ && preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT /* SY <-- */) {
DisplayMode.values()[currentCategory?.displayMode ?: 0] DisplayModeSetting.fromFlag(currentCategory?.displayMode)
} else { } else {
preferences.libraryDisplayMode().get() preferences.libraryDisplayMode().get()
} }
@ -369,42 +404,32 @@ class LibrarySettingsSheet(
} }
// Sets display group selections based on given mode // Sets display group selections based on given mode
fun setGroupSelections(mode: DisplayMode) { fun setGroupSelections(mode: DisplayModeSetting) {
compactGrid.checked = mode == DisplayMode.COMPACT_GRID compactGrid.checked = mode == DisplayModeSetting.COMPACT_GRID
comfortableGrid.checked = mode == DisplayMode.COMFORTABLE_GRID comfortableGrid.checked = mode == DisplayModeSetting.COMFORTABLE_GRID
// SY --> // SY -->
noTitleGrid.checked = mode == DisplayMode.NO_TITLE_GRID noTitleGrid.checked = mode == DisplayModeSetting.NO_TITLE_GRID
// SY <-- // SY <--
list.checked = mode == DisplayMode.LIST list.checked = mode == DisplayModeSetting.LIST
} }
private fun setDisplayModePreference(item: Item) { private fun setDisplayModePreference(item: Item) {
if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { val flag = when (item) {
val flag = when (item) { compactGrid -> DisplayModeSetting.COMPACT_GRID
compactGrid -> Category.COMPACT_GRID comfortableGrid -> DisplayModeSetting.COMFORTABLE_GRID
comfortableGrid -> Category.COMFORTABLE_GRID // SY -->
// SY --> noTitleGrid -> DisplayModeSetting.NO_TITLE_GRID
noTitleGrid -> Category.NO_TITLE_GRID // SY <--
// SY <-- list -> DisplayModeSetting.LIST
list -> Category.LIST else -> throw NotImplementedError("Unknown display mode")
else -> throw NotImplementedError("Unknown display mode") }
}
currentCategory?.displayMode = flag if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0 /* SY --> */ && preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT /* SY <-- */) {
currentCategory?.displayMode = flag.flag
db.insertCategory(currentCategory!!).executeAsBlocking() db.insertCategory(currentCategory!!).executeAsBlocking()
} else { } else {
preferences.libraryDisplayMode().set( preferences.libraryDisplayMode().set(flag)
when (item) {
compactGrid -> DisplayMode.COMPACT_GRID
comfortableGrid -> DisplayMode.COMFORTABLE_GRID
// SY -->
noTitleGrid -> DisplayMode.NO_TITLE_GRID
// SY <--
list -> DisplayMode.LIST
else -> throw NotImplementedError("Unknown display mode")
}
)
} }
} }
} }
@ -494,9 +519,8 @@ class LibrarySettingsSheet(
inner class InternalGroup : Group { inner class InternalGroup : Group {
private val groupItems = mutableListOf<Item.DrawableSelection>() private val groupItems = mutableListOf<Item.DrawableSelection>()
private val db: DatabaseHelper = Injekt.get()
private val trackManager: TrackManager = Injekt.get() private val trackManager: TrackManager = Injekt.get()
private val hasCategories = db.getCategories().executeAsBlocking().size != 0 private val hasCategories = Injekt.get<DatabaseHelper>().getCategories().executeAsBlocking().size != 0
init { init {
val groupingItems = mutableListOf( val groupingItems = mutableListOf(
@ -538,10 +562,10 @@ class LibrarySettingsSheet(
override fun onItemClicked(item: Item) { override fun onItemClicked(item: Item) {
item as Item.DrawableSelection item as Item.DrawableSelection
if (item.id != LibraryGroup.BY_DEFAULT && preferences.librarySortingMode().get() == LibrarySort.DRAG_AND_DROP) { if (item.id != LibraryGroup.BY_DEFAULT && preferences.librarySortingMode().get() == SortModeSetting.DRAG_AND_DROP) {
preferences.librarySortingMode().set(LibrarySort.ALPHA) preferences.librarySortingMode().set(SortModeSetting.ALPHABETICAL)
preferences.librarySortingAscending().set(true) preferences.librarySortingAscending().set(SortDirectionSetting.ASCENDING)
refreshSort() sort.adjustDisplaySelection()
} }
item.group.items.forEach { item.group.items.forEach {

View File

@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.ui.library package eu.kanade.tachiyomi.ui.library
@Deprecated("Deprecated in favor for SortModeSetting")
object LibrarySort { object LibrarySort {
const val ALPHA = 0 const val ALPHA = 0

View File

@ -0,0 +1,20 @@
package eu.kanade.tachiyomi.ui.library.setting
enum class DisplayModeSetting(val flag: Int) {
COMPACT_GRID(0b00000000),
COMFORTABLE_GRID(0b00000001),
LIST(0b00000010),
// SY -->
NO_TITLE_GRID(0b00000011);
// SY <--;
companion object {
const val MASK = 0b00000011
fun fromFlag(flag: Int?): DisplayModeSetting {
return values()
.find { mode -> mode.flag == flag } ?: COMPACT_GRID
}
}
}

View File

@ -0,0 +1,25 @@
package eu.kanade.tachiyomi.ui.library.setting
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
enum class SortDirectionSetting(val flag: Int) {
ASCENDING(0b01000000),
DESCENDING(0b00000000);
companion object {
const val MASK = 0b01000000
fun fromFlag(flag: Int?): SortDirectionSetting {
return values().find { mode -> mode.flag == flag } ?: ASCENDING
}
fun get(preferences: PreferencesHelper, category: Category?): SortDirectionSetting {
return if (preferences.categorisedDisplaySettings().get() && category != null && category.id != 0) {
fromFlag(category.sortDirection)
} else {
preferences.librarySortingAscending().get()
}
}
}
}

View File

@ -0,0 +1,34 @@
package eu.kanade.tachiyomi.ui.library.setting
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
enum class SortModeSetting(val flag: Int) {
ALPHABETICAL(0b00000000),
LAST_READ(0b00000100),
LAST_CHECKED(0b00001000),
UNREAD(0b00001100),
TOTAL_CHAPTERS(0b00010000),
LATEST_CHAPTER(0b00010100),
DATE_FETCHED(0b00011000),
DATE_ADDED(0b00011100),
DRAG_AND_DROP(0b00100000),
TAG_LIST(0b00100100);
companion object {
// Mask supports for more sorting flags if necessary
const val MASK = 0b00111100
fun fromFlag(flag: Int?): SortModeSetting {
return values().find { mode -> mode.flag == flag } ?: ALPHABETICAL
}
fun get(preferences: PreferencesHelper, category: Category?): SortModeSetting {
return if (preferences.categorisedDisplaySettings().get() && category != null && category.id != 0) {
fromFlag(category.sortMode)
} else {
preferences.librarySortingMode().get()
}
}
}
}

View File

@ -110,6 +110,8 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val didMigration = if (savedInstanceState == null) EXHMigrations.upgrade(preferences) else false
binding = MainActivityBinding.inflate(layoutInflater) binding = MainActivityBinding.inflate(layoutInflater)
// Do not let the launcher create a new activity http://stackoverflow.com/questions/16283079 // Do not let the launcher create a new activity http://stackoverflow.com/questions/16283079
@ -250,14 +252,7 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
preferences.incognitoMode().set(false) preferences.incognitoMode().set(false)
// Show changelog prompt on update // Show changelog prompt on update
// TODO if (didMigration) {
// if (Migrations.upgrade(preferences) && !BuildConfig.DEBUG) {
// WhatsNewDialogController().showDialog(router)
// }
// EXH -->
// Perform EXH specific migrations
if (EXHMigrations.upgrade(preferences)) {
WhatsNewDialogController().showDialog(router) WhatsNewDialogController().showDialog(router)
} }
// EXH <-- // EXH <--

View File

@ -26,6 +26,9 @@ import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.all.Hitomi import eu.kanade.tachiyomi.source.online.all.Hitomi
import eu.kanade.tachiyomi.source.online.all.NHentai import eu.kanade.tachiyomi.source.online.all.NHentai
import eu.kanade.tachiyomi.ui.library.LibrarySort
import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting
import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
import exh.log.xLogE import exh.log.xLogE
import exh.log.xLogW import exh.log.xLogW
@ -288,6 +291,40 @@ object EXHMigrations {
} }
if (oldVersion under 20) { if (oldVersion under 20) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context) val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val oldSortingMode = prefs.getInt(PreferenceKeys.librarySortingMode, 0)
val oldSortingDirection = prefs.getBoolean(PreferenceKeys.librarySortingDirection, true)
@Suppress("DEPRECATION")
val newSortingMode = when (oldSortingMode) {
LibrarySort.ALPHA -> SortModeSetting.ALPHABETICAL
LibrarySort.LAST_READ -> SortModeSetting.LAST_READ
LibrarySort.LAST_CHECKED -> SortModeSetting.LAST_CHECKED
LibrarySort.UNREAD -> SortModeSetting.UNREAD
LibrarySort.TOTAL -> SortModeSetting.TOTAL_CHAPTERS
LibrarySort.LATEST_CHAPTER -> SortModeSetting.LATEST_CHAPTER
LibrarySort.CHAPTER_FETCH_DATE -> SortModeSetting.DATE_FETCHED
LibrarySort.DATE_ADDED -> SortModeSetting.DATE_ADDED
LibrarySort.DRAG_AND_DROP -> SortModeSetting.DRAG_AND_DROP
LibrarySort.TAG_LIST -> SortModeSetting.TAG_LIST
else -> SortModeSetting.ALPHABETICAL
}
val newSortingDirection = when (oldSortingDirection) {
true -> SortDirectionSetting.ASCENDING
else -> SortDirectionSetting.DESCENDING
}
prefs.edit(commit = true) {
remove(PreferenceKeys.librarySortingMode)
remove(PreferenceKeys.librarySortingDirection)
}
prefs.edit {
putString(PreferenceKeys.librarySortingMode, newSortingMode.name)
putString(PreferenceKeys.librarySortingDirection, newSortingDirection.name)
}
if (prefs.getString(PreferenceKeys.themeDark, null) == "amoledblue") { if (prefs.getString(PreferenceKeys.themeDark, null) == "amoledblue") {
prefs.edit { prefs.edit {
putString(PreferenceKeys.themeDark, "amoled") putString(PreferenceKeys.themeDark, "amoled")

View File

@ -4,11 +4,9 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="140dp" android:layout_height="140dp"
android:layout_gravity="center_vertical" android:background="@drawable/library_item_selector"
android:background="@drawable/list_item_selector" android:foreground="@drawable/library_item_selector_overlay"
android:paddingEnd="8dp" android:padding="4dp">
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="25dp">
<FrameLayout <FrameLayout
android:id="@+id/card" android:id="@+id/card"
@ -19,6 +17,14 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:scaleType="centerCrop"
tools:src="@mipmap/ic_launcher" />
<LinearLayout <LinearLayout
android:id="@+id/badges" android:id="@+id/badges"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -44,14 +50,6 @@
tools:visibility="visible" /> tools:visibility="visible" />
</LinearLayout> </LinearLayout>
<ImageView
android:id="@+id/thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:scaleType="centerCrop"
tools:src="@mipmap/ic_launcher" />
<com.google.android.material.progressindicator.CircularProgressIndicator <com.google.android.material.progressindicator.CircularProgressIndicator
android:id="@+id/progress" android:id="@+id/progress"
style="@style/Widget.Tachiyomi.CircularProgressIndicator.Small" style="@style/Widget.Tachiyomi.CircularProgressIndicator.Small"
@ -89,7 +87,7 @@
app:layout_constraintTop_toBottomOf="@+id/title" app:layout_constraintTop_toBottomOf="@+id/title"
tools:text="Manga title for the life of me I cant think yes totally" /> tools:text="Manga title for the life of me I cant think yes totally" />
<androidx.cardview.widget.CardView <com.google.android.material.card.MaterialCardView
android:id="@+id/cardView" android:id="@+id/cardView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -110,7 +108,7 @@
android:paddingEnd="8dp" android:paddingEnd="8dp"
android:paddingBottom="4dp" /> android:paddingBottom="4dp" />
</androidx.cardview.widget.CardView> </com.google.android.material.card.MaterialCardView>
<me.zhanghai.android.materialratingbar.MaterialRatingBar <me.zhanghai.android.materialratingbar.MaterialRatingBar
android:id="@+id/rating_bar" android:id="@+id/rating_bar"