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
This commit is contained in:
parent
64c95305b9
commit
60890147c3
@ -30,7 +30,7 @@ android {
|
||||
minSdkVersion(AndroidConfig.minSdk)
|
||||
targetSdkVersion(AndroidConfig.targetSdk)
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
versionCode = 63
|
||||
versionCode = 64
|
||||
versionName = "0.11.1"
|
||||
|
||||
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
||||
|
@ -12,6 +12,8 @@ import eu.kanade.tachiyomi.data.updater.UpdaterJob
|
||||
import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
|
||||
import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE
|
||||
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.util.system.toast
|
||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
||||
@ -96,9 +98,15 @@ object Migrations {
|
||||
}
|
||||
if (oldVersion < 44) {
|
||||
// Reset sorting preference if using removed sort by source
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
||||
val oldSortingMode = prefs.getInt(PreferenceKeys.librarySortingMode, 0)
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
if (preferences.librarySortingMode().get() == LibrarySort.SOURCE) {
|
||||
preferences.librarySortingMode().set(LibrarySort.ALPHA)
|
||||
if (oldSortingMode == LibrarySort.SOURCE) {
|
||||
prefs.edit {
|
||||
putInt(PreferenceKeys.librarySortingMode, LibrarySort.ALPHA)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oldVersion < 52) {
|
||||
@ -190,6 +198,40 @@ object Migrations {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
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
|
||||
|
||||
interface Category : Serializable {
|
||||
@ -17,16 +20,19 @@ interface Category : Serializable {
|
||||
}
|
||||
|
||||
var displayMode: Int
|
||||
get() = flags and MASK
|
||||
set(mode) = setFlags(mode, MASK)
|
||||
get() = flags and DisplayModeSetting.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 {
|
||||
|
||||
const val COMPACT_GRID = 0b00000000
|
||||
const val COMFORTABLE_GRID = 0b00000001
|
||||
const val LIST = 0b00000010
|
||||
const val MASK = 0b00000011
|
||||
|
||||
fun create(name: String): Category = CategoryImpl().apply {
|
||||
this.name = name
|
||||
}
|
||||
|
@ -147,6 +147,7 @@ object PreferenceKeys {
|
||||
const val filterTracked = "pref_filter_library_tracked"
|
||||
|
||||
const val librarySortingMode = "library_sorting_mode"
|
||||
const val librarySortingDirection = "library_sorting_ascending"
|
||||
|
||||
const val automaticExtUpdates = "automatic_ext_updates"
|
||||
|
||||
|
@ -37,12 +37,6 @@ object PreferenceValues {
|
||||
|
||||
/* ktlint-enable experimental:enum-entry-name-case */
|
||||
|
||||
enum class DisplayMode {
|
||||
COMPACT_GRID,
|
||||
COMFORTABLE_GRID,
|
||||
LIST,
|
||||
}
|
||||
|
||||
enum class TappingInvertMode(val shouldInvertHorizontal: Boolean = false, val shouldInvertVertical: Boolean = false) {
|
||||
NONE,
|
||||
HORIZONTAL(shouldInvertHorizontal = true),
|
||||
|
@ -10,10 +10,12 @@ import com.tfcporciuncula.flow.FlowSharedPreferences
|
||||
import com.tfcporciuncula.flow.Preference
|
||||
import eu.kanade.tachiyomi.R
|
||||
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.track.TrackService
|
||||
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.ReadingModeType
|
||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
||||
@ -184,7 +186,7 @@ class PreferencesHelper(val context: Context) {
|
||||
|
||||
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("en", Locale.getDefault().language))
|
||||
|
||||
@ -235,7 +237,7 @@ class PreferencesHelper(val context: Context) {
|
||||
|
||||
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)
|
||||
|
||||
@ -257,9 +259,8 @@ class PreferencesHelper(val context: Context) {
|
||||
|
||||
fun filterTracking(name: Int) = flowPrefs.getInt("${Keys.filterTracked}_$name", ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
|
||||
|
||||
fun librarySortingMode() = flowPrefs.getInt(Keys.librarySortingMode, 0)
|
||||
|
||||
fun librarySortingAscending() = flowPrefs.getBoolean("library_sorting_ascending", true)
|
||||
fun librarySortingMode() = flowPrefs.getEnum(Keys.librarySortingMode, SortModeSetting.ALPHABETICAL)
|
||||
fun librarySortingAscending() = flowPrefs.getEnum(Keys.librarySortingDirection, SortDirectionSetting.ASCENDING)
|
||||
|
||||
fun automaticExtUpdates() = flowPrefs.getBoolean(Keys.automaticExtUpdates, true)
|
||||
|
||||
|
@ -24,7 +24,6 @@ import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
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.asImmediateFlow
|
||||
import eu.kanade.tachiyomi.databinding.SourceControllerBinding
|
||||
@ -37,6 +36,7 @@ import eu.kanade.tachiyomi.ui.base.controller.SearchableNucleusController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
||||
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.manga.MangaController
|
||||
import eu.kanade.tachiyomi.ui.more.MoreController
|
||||
@ -205,7 +205,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||
binding.catalogueView.removeView(oldRecycler)
|
||||
}
|
||||
|
||||
val recycler = if (preferences.sourceDisplayMode().get() == DisplayMode.LIST) {
|
||||
val recycler = if (preferences.sourceDisplayMode().get() == DisplayModeSetting.LIST) {
|
||||
RecyclerView(view.context).apply {
|
||||
id = R.id.recycler
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
@ -273,9 +273,9 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||
)
|
||||
|
||||
val displayItem = when (preferences.sourceDisplayMode().get()) {
|
||||
DisplayMode.COMPACT_GRID -> R.id.action_compact_grid
|
||||
DisplayMode.COMFORTABLE_GRID -> R.id.action_comfortable_grid
|
||||
DisplayMode.LIST -> R.id.action_list
|
||||
DisplayModeSetting.COMPACT_GRID -> R.id.action_compact_grid
|
||||
DisplayModeSetting.COMFORTABLE_GRID -> R.id.action_comfortable_grid
|
||||
DisplayModeSetting.LIST -> R.id.action_list
|
||||
}
|
||||
menu.findItem(displayItem).isChecked = true
|
||||
}
|
||||
@ -297,9 +297,9 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.action_search -> expandActionViewFromInteraction = true
|
||||
R.id.action_compact_grid -> setDisplayMode(DisplayMode.COMPACT_GRID)
|
||||
R.id.action_comfortable_grid -> setDisplayMode(DisplayMode.COMFORTABLE_GRID)
|
||||
R.id.action_list -> setDisplayMode(DisplayMode.LIST)
|
||||
R.id.action_compact_grid -> setDisplayMode(DisplayModeSetting.COMPACT_GRID)
|
||||
R.id.action_comfortable_grid -> setDisplayMode(DisplayModeSetting.COMFORTABLE_GRID)
|
||||
R.id.action_list -> setDisplayMode(DisplayModeSetting.LIST)
|
||||
R.id.action_open_in_web_view -> openInWebView()
|
||||
R.id.action_local_source_help -> openLocalSourceHelpGuide()
|
||||
}
|
||||
@ -446,7 +446,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||
*
|
||||
* @param mode the mode to change to
|
||||
*/
|
||||
private fun setDisplayMode(mode: DisplayMode) {
|
||||
private fun setDisplayMode(mode: DisplayModeSetting) {
|
||||
val view = view ?: return
|
||||
val adapter = adapter ?: return
|
||||
|
||||
|
@ -12,19 +12,19 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
|
||||
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
|
||||
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
|
||||
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
|
||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||
|
||||
class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMode>) :
|
||||
class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayModeSetting>) :
|
||||
AbstractFlexibleItem<SourceHolder<*>>() {
|
||||
|
||||
override fun getLayoutRes(): Int {
|
||||
return when (displayMode.get()) {
|
||||
DisplayMode.COMPACT_GRID -> R.layout.source_compact_grid_item
|
||||
DisplayMode.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item
|
||||
DisplayMode.LIST -> R.layout.source_list_item
|
||||
DisplayModeSetting.COMPACT_GRID -> R.layout.source_compact_grid_item
|
||||
DisplayModeSetting.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item
|
||||
DisplayModeSetting.LIST -> R.layout.source_list_item
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
|
||||
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>
|
||||
): SourceHolder<*> {
|
||||
return when (displayMode.get()) {
|
||||
DisplayMode.COMPACT_GRID -> {
|
||||
DisplayModeSetting.COMPACT_GRID -> {
|
||||
val binding = SourceCompactGridItemBinding.bind(view)
|
||||
val parent = adapter.recyclerView as AutofitRecyclerView
|
||||
val coverHeight = parent.itemWidth / 3 * 4
|
||||
@ -50,7 +50,7 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
|
||||
}
|
||||
SourceGridHolder(view, adapter)
|
||||
}
|
||||
DisplayMode.COMFORTABLE_GRID -> {
|
||||
DisplayModeSetting.COMFORTABLE_GRID -> {
|
||||
val binding = SourceComfortableGridItemBinding.bind(view)
|
||||
val parent = adapter.recyclerView as AutofitRecyclerView
|
||||
val coverHeight = parent.itemWidth / 3 * 4
|
||||
@ -62,7 +62,7 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
|
||||
}
|
||||
SourceComfortableGridHolder(view, adapter)
|
||||
}
|
||||
DisplayMode.LIST -> {
|
||||
DisplayModeSetting.LIST -> {
|
||||
SourceListHolder(view, adapter)
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.databinding.LibraryCategoryBinding
|
||||
import eu.kanade.tachiyomi.util.lang.plusAssign
|
||||
@ -28,6 +27,7 @@ import reactivecircus.flowbinding.swiperefreshlayout.refreshes
|
||||
import rx.subscriptions.CompositeSubscription
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.util.ArrayDeque
|
||||
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting as DisplayMode
|
||||
|
||||
/**
|
||||
* Fragment containing the library manga for a certain category.
|
||||
@ -125,7 +125,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
|
||||
// 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)) {
|
||||
recycler.spanCount = if (DisplayMode.fromFlag(category.displayMode) == DisplayMode.LIST || (preferences.libraryDisplayMode().get() == DisplayMode.LIST && category.id == 0)) {
|
||||
1
|
||||
} else {
|
||||
controller.mangaPerRow
|
||||
|
@ -295,6 +295,11 @@ class LibraryController(
|
||||
.map { (it.id ?: -1) to (mangaMap[it.id]?.size ?: 0) }
|
||||
.toMap()
|
||||
|
||||
if (preferences.categorisedDisplaySettings().get()) {
|
||||
// Reattach adapter so it doesn't get de-synced
|
||||
reattachAdapter()
|
||||
}
|
||||
|
||||
// Restore active category.
|
||||
binding.libraryPager.setCurrentItem(activeCat, false)
|
||||
|
||||
|
@ -13,10 +13,10 @@ import eu.davidea.flexibleadapter.items.IFilterable
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
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.SourceCompactGridItemBinding
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
|
||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
@ -24,7 +24,7 @@ import uy.kohesive.injekt.api.get
|
||||
class LibraryItem(
|
||||
val manga: LibraryManga,
|
||||
private val shouldSetFromCategory: Preference<Boolean>,
|
||||
private val defaultLibraryDisplayMode: Preference<DisplayMode>
|
||||
private val defaultLibraryDisplayMode: Preference<DisplayModeSetting>
|
||||
) :
|
||||
AbstractFlexibleItem<LibraryHolder<*>>(), IFilterable<String> {
|
||||
|
||||
@ -35,13 +35,9 @@ class LibraryItem(
|
||||
var unreadCount = -1
|
||||
var isLocal = false
|
||||
|
||||
private fun getDisplayMode(): DisplayMode {
|
||||
private fun getDisplayMode(): DisplayModeSetting {
|
||||
return if (shouldSetFromCategory.get() && manga.category != 0) {
|
||||
if (displayMode != -1) {
|
||||
DisplayMode.values()[displayMode]
|
||||
} else {
|
||||
DisplayMode.COMPACT_GRID
|
||||
}
|
||||
DisplayModeSetting.fromFlag(displayMode)
|
||||
} else {
|
||||
defaultLibraryDisplayMode.get()
|
||||
}
|
||||
@ -49,15 +45,15 @@ class LibraryItem(
|
||||
|
||||
override fun getLayoutRes(): Int {
|
||||
return when (getDisplayMode()) {
|
||||
DisplayMode.COMPACT_GRID -> R.layout.source_compact_grid_item
|
||||
DisplayMode.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item
|
||||
DisplayMode.LIST -> R.layout.source_list_item
|
||||
DisplayModeSetting.COMPACT_GRID -> R.layout.source_compact_grid_item
|
||||
DisplayModeSetting.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item
|
||||
DisplayModeSetting.LIST -> R.layout.source_list_item
|
||||
}
|
||||
}
|
||||
|
||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder<*> {
|
||||
return when (getDisplayMode()) {
|
||||
DisplayMode.COMPACT_GRID -> {
|
||||
DisplayModeSetting.COMPACT_GRID -> {
|
||||
val binding = SourceCompactGridItemBinding.bind(view)
|
||||
val parent = adapter.recyclerView as AutofitRecyclerView
|
||||
val coverHeight = parent.itemWidth / 3 * 4
|
||||
@ -71,7 +67,7 @@ class LibraryItem(
|
||||
}
|
||||
LibraryCompactGridHolder(view, adapter)
|
||||
}
|
||||
DisplayMode.COMFORTABLE_GRID -> {
|
||||
DisplayModeSetting.COMFORTABLE_GRID -> {
|
||||
val binding = SourceComfortableGridItemBinding.bind(view)
|
||||
val parent = adapter.recyclerView as AutofitRecyclerView
|
||||
val coverHeight = parent.itemWidth / 3 * 4
|
||||
@ -83,7 +79,7 @@ class LibraryItem(
|
||||
}
|
||||
LibraryComfortableGridHolder(view, adapter)
|
||||
}
|
||||
DisplayMode.LIST -> {
|
||||
DisplayModeSetting.LIST -> {
|
||||
LibraryListHolder(view, adapter)
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
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.lang.combineLatest
|
||||
import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed
|
||||
@ -98,7 +100,7 @@ class LibraryPresenter(
|
||||
lib.copy(mangaMap = applyFilters(lib.mangaMap, tracks))
|
||||
}
|
||||
.combineLatest(sortTriggerRelay.observeOn(Schedulers.io())) { lib, _ ->
|
||||
lib.copy(mangaMap = applySort(lib.mangaMap))
|
||||
lib.copy(mangaMap = applySort(lib.categories, lib.mangaMap))
|
||||
}
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeLatestCache({ view, (categories, mangaMap) ->
|
||||
@ -228,9 +230,7 @@ class LibraryPresenter(
|
||||
*
|
||||
* @param map the map to sort.
|
||||
*/
|
||||
private fun applySort(map: LibraryMap): LibraryMap {
|
||||
val sortingMode = preferences.librarySortingMode().get()
|
||||
|
||||
private fun applySort(categories: List<Category>, map: LibraryMap): LibraryMap {
|
||||
val lastReadManga by lazy {
|
||||
var counter = 0
|
||||
db.getLastReadManga().executeAsBlocking().associate { it.id!! to counter++ }
|
||||
@ -248,55 +248,67 @@ class LibraryPresenter(
|
||||
db.getChapterFetchDateManga().executeAsBlocking().associate { it.id!! to counter++ }
|
||||
}
|
||||
|
||||
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 sortingMode = sortingModes[i1.manga.category]!!
|
||||
val sortAscending = sortAscending[i1.manga.category]!! == SortDirectionSetting.ASCENDING
|
||||
when (sortingMode) {
|
||||
LibrarySort.ALPHA -> i1.manga.title.compareTo(i2.manga.title, true)
|
||||
LibrarySort.LAST_READ -> {
|
||||
SortModeSetting.ALPHABETICAL -> i1.manga.title.compareTo(i2.manga.title, true)
|
||||
SortModeSetting.LAST_READ -> {
|
||||
// Get index of manga, set equal to list if size unknown.
|
||||
val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size
|
||||
val manga2LastRead = lastReadManga[i2.manga.id!!] ?: lastReadManga.size
|
||||
manga1LastRead.compareTo(manga2LastRead)
|
||||
}
|
||||
LibrarySort.LAST_CHECKED -> i2.manga.last_update.compareTo(i1.manga.last_update)
|
||||
LibrarySort.UNREAD -> when {
|
||||
SortModeSetting.LAST_CHECKED -> i2.manga.last_update.compareTo(i1.manga.last_update)
|
||||
SortModeSetting.UNREAD -> when {
|
||||
// Ensure unread content comes first
|
||||
i1.manga.unread == i2.manga.unread -> 0
|
||||
i1.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)
|
||||
}
|
||||
LibrarySort.TOTAL -> {
|
||||
SortModeSetting.TOTAL_CHAPTERS -> {
|
||||
val manga1TotalChapter = totalChapterManga[i1.manga.id!!] ?: 0
|
||||
val mange2TotalChapter = totalChapterManga[i2.manga.id!!] ?: 0
|
||||
manga1TotalChapter.compareTo(mange2TotalChapter)
|
||||
}
|
||||
LibrarySort.LATEST_CHAPTER -> {
|
||||
SortModeSetting.LATEST_CHAPTER -> {
|
||||
val manga1latestChapter = latestChapterManga[i1.manga.id!!]
|
||||
?: latestChapterManga.size
|
||||
val manga2latestChapter = latestChapterManga[i2.manga.id!!]
|
||||
?: latestChapterManga.size
|
||||
manga1latestChapter.compareTo(manga2latestChapter)
|
||||
}
|
||||
LibrarySort.CHAPTER_FETCH_DATE -> {
|
||||
SortModeSetting.DATE_FETCHED -> {
|
||||
val manga1chapterFetchDate = chapterFetchDateManga[i1.manga.id!!]
|
||||
?: chapterFetchDateManga.size
|
||||
val manga2chapterFetchDate = chapterFetchDateManga[i2.manga.id!!]
|
||||
?: chapterFetchDateManga.size
|
||||
manga1chapterFetchDate.compareTo(manga2chapterFetchDate)
|
||||
}
|
||||
LibrarySort.DATE_ADDED -> i2.manga.date_added.compareTo(i1.manga.date_added)
|
||||
else -> throw Exception("Unknown sorting mode")
|
||||
SortModeSetting.DATE_ADDED -> i2.manga.date_added.compareTo(i1.manga.date_added)
|
||||
}
|
||||
}
|
||||
|
||||
return map.mapValues { entry ->
|
||||
val sortAscending = sortAscending[entry.key]!! == SortDirectionSetting.ASCENDING
|
||||
|
||||
val comparator = if (sortAscending) {
|
||||
Comparator(sortFn)
|
||||
} else {
|
||||
Collections.reverseOrder(sortFn)
|
||||
}
|
||||
|
||||
return map.mapValues { entry -> entry.value.sortedWith(comparator) }
|
||||
entry.value.sortedWith(comparator)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,10 +7,12 @@ 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
|
||||
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.Item.TriStateGroup.State
|
||||
import eu.kanade.tachiyomi.widget.sheet.TabbedBottomSheetDialog
|
||||
@ -45,6 +47,8 @@ class LibrarySettingsSheet(
|
||||
* @param currentCategory ID of currently shown category
|
||||
*/
|
||||
fun show(currentCategory: Category) {
|
||||
sort.currentCategory = currentCategory
|
||||
sort.adjustDisplaySelection()
|
||||
display.currentCategory = currentCategory
|
||||
display.adjustDisplaySelection()
|
||||
super.show()
|
||||
@ -158,8 +162,16 @@ class LibrarySettingsSheet(
|
||||
inner class Sort @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||
Settings(context, attrs) {
|
||||
|
||||
private val sort = SortGroup()
|
||||
|
||||
init {
|
||||
setGroups(listOf(SortGroup()))
|
||||
setGroups(listOf(sort))
|
||||
}
|
||||
|
||||
// Refreshes Display Setting selections
|
||||
fun adjustDisplaySelection() {
|
||||
sort.initModels()
|
||||
sort.items.forEach { adapter.notifyItemChanged(it) }
|
||||
}
|
||||
|
||||
inner class SortGroup : Group {
|
||||
@ -179,29 +191,29 @@ class LibrarySettingsSheet(
|
||||
override val footer = null
|
||||
|
||||
override fun initModels() {
|
||||
val sorting = preferences.librarySortingMode().get()
|
||||
val order = if (preferences.librarySortingAscending().get()) {
|
||||
val sorting = SortModeSetting.get(preferences, currentCategory)
|
||||
val order = if (SortDirectionSetting.get(preferences, currentCategory) == SortDirectionSetting.ASCENDING) {
|
||||
Item.MultiSort.SORT_ASC
|
||||
} else {
|
||||
Item.MultiSort.SORT_DESC
|
||||
}
|
||||
|
||||
alphabetically.state =
|
||||
if (sorting == LibrarySort.ALPHA) order else Item.MultiSort.SORT_NONE
|
||||
if (sorting == SortModeSetting.ALPHABETICAL) order else Item.MultiSort.SORT_NONE
|
||||
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 =
|
||||
if (sorting == LibrarySort.LAST_CHECKED) order else Item.MultiSort.SORT_NONE
|
||||
if (sorting == SortModeSetting.LAST_CHECKED) order else Item.MultiSort.SORT_NONE
|
||||
unread.state =
|
||||
if (sorting == LibrarySort.UNREAD) order else Item.MultiSort.SORT_NONE
|
||||
if (sorting == SortModeSetting.UNREAD) order else Item.MultiSort.SORT_NONE
|
||||
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 =
|
||||
if (sorting == LibrarySort.LATEST_CHAPTER) order else Item.MultiSort.SORT_NONE
|
||||
if (sorting == SortModeSetting.LATEST_CHAPTER) order else Item.MultiSort.SORT_NONE
|
||||
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 =
|
||||
if (sorting == LibrarySort.DATE_ADDED) order else Item.MultiSort.SORT_NONE
|
||||
if (sorting == SortModeSetting.DATE_ADDED) order else Item.MultiSort.SORT_NONE
|
||||
}
|
||||
|
||||
override fun onItemClicked(item: Item) {
|
||||
@ -219,23 +231,50 @@ class LibrarySettingsSheet(
|
||||
else -> throw Exception("Unknown state")
|
||||
}
|
||||
|
||||
preferences.librarySortingMode().set(
|
||||
when (item) {
|
||||
alphabetically -> LibrarySort.ALPHA
|
||||
lastRead -> LibrarySort.LAST_READ
|
||||
lastChecked -> LibrarySort.LAST_CHECKED
|
||||
unread -> LibrarySort.UNREAD
|
||||
total -> LibrarySort.TOTAL
|
||||
latestChapter -> LibrarySort.LATEST_CHAPTER
|
||||
chapterFetchDate -> LibrarySort.CHAPTER_FETCH_DATE
|
||||
dateAdded -> LibrarySort.DATE_ADDED
|
||||
else -> throw Exception("Unknown sorting")
|
||||
}
|
||||
)
|
||||
preferences.librarySortingAscending().set(item.state == Item.MultiSort.SORT_ASC)
|
||||
setSortModePreference(item)
|
||||
|
||||
setSortDirectionPrefernece(item)
|
||||
|
||||
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) {
|
||||
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
|
||||
else -> throw NotImplementedError("Unknown display mode")
|
||||
}
|
||||
|
||||
if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
|
||||
currentCategory?.sortMode = flag.flag
|
||||
|
||||
db.insertCategory(currentCategory!!).executeAsBlocking()
|
||||
} else {
|
||||
preferences.librarySortingMode().set(flag)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -264,9 +303,9 @@ class LibrarySettingsSheet(
|
||||
}
|
||||
|
||||
// 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) {
|
||||
DisplayMode.values()[currentCategory?.displayMode ?: 0]
|
||||
DisplayModeSetting.fromFlag(currentCategory?.displayMode)
|
||||
} else {
|
||||
preferences.libraryDisplayMode().get()
|
||||
}
|
||||
@ -300,33 +339,26 @@ class LibrarySettingsSheet(
|
||||
}
|
||||
|
||||
// Sets display group selections based on given mode
|
||||
fun setGroupSelections(mode: DisplayMode) {
|
||||
compactGrid.checked = mode == DisplayMode.COMPACT_GRID
|
||||
comfortableGrid.checked = mode == DisplayMode.COMFORTABLE_GRID
|
||||
list.checked = mode == DisplayMode.LIST
|
||||
fun setGroupSelections(mode: DisplayModeSetting) {
|
||||
compactGrid.checked = mode == DisplayModeSetting.COMPACT_GRID
|
||||
comfortableGrid.checked = mode == DisplayModeSetting.COMFORTABLE_GRID
|
||||
list.checked = mode == DisplayModeSetting.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
|
||||
list -> Category.LIST
|
||||
compactGrid -> DisplayModeSetting.COMPACT_GRID
|
||||
comfortableGrid -> DisplayModeSetting.COMFORTABLE_GRID
|
||||
list -> DisplayModeSetting.LIST
|
||||
else -> throw NotImplementedError("Unknown display mode")
|
||||
}
|
||||
|
||||
currentCategory?.displayMode = flag
|
||||
if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
|
||||
currentCategory?.displayMode = flag.flag
|
||||
|
||||
db.insertCategory(currentCategory!!).executeAsBlocking()
|
||||
} else {
|
||||
preferences.libraryDisplayMode().set(
|
||||
when (item) {
|
||||
compactGrid -> DisplayMode.COMPACT_GRID
|
||||
comfortableGrid -> DisplayMode.COMFORTABLE_GRID
|
||||
list -> DisplayMode.LIST
|
||||
else -> throw NotImplementedError("Unknown display mode")
|
||||
}
|
||||
)
|
||||
preferences.libraryDisplayMode().set(flag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package eu.kanade.tachiyomi.ui.library
|
||||
|
||||
@Deprecated("Deprecated in favor for SortModeSetting")
|
||||
object LibrarySort {
|
||||
|
||||
const val ALPHA = 0
|
||||
|
@ -0,0 +1,16 @@
|
||||
package eu.kanade.tachiyomi.ui.library.setting
|
||||
|
||||
enum class DisplayModeSetting(val flag: Int) {
|
||||
COMPACT_GRID(0b00000000),
|
||||
COMFORTABLE_GRID(0b00000001),
|
||||
LIST(0b00000010);
|
||||
|
||||
companion object {
|
||||
const val MASK = 0b00000011
|
||||
|
||||
fun fromFlag(flag: Int?): DisplayModeSetting {
|
||||
return values()
|
||||
.find { mode -> mode.flag == flag } ?: COMPACT_GRID
|
||||
}
|
||||
}
|
||||
}
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
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);
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -84,6 +84,8 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val didMigration = if (savedInstanceState == null) Migrations.upgrade(preferences) else false
|
||||
|
||||
binding = MainActivityBinding.inflate(layoutInflater)
|
||||
|
||||
// Do not let the launcher create a new activity http://stackoverflow.com/questions/16283079
|
||||
@ -224,7 +226,7 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
|
||||
preferences.incognitoMode().set(false)
|
||||
|
||||
// Show changelog prompt on update
|
||||
if (Migrations.upgrade(preferences) && !BuildConfig.DEBUG) {
|
||||
if (didMigration && !BuildConfig.DEBUG) {
|
||||
WhatsNewDialogController().showDialog(router)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user