diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 6ffe05c47..358bcccff 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -28,7 +28,7 @@ android { applicationId = "eu.kanade.tachiyomi.sy" minSdk = AndroidConfig.minSdk targetSdk = AndroidConfig.targetSdk - versionCode = 38 + versionCode = 39 versionName = "1.8.5" buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"") diff --git a/app/src/main/java/eu/kanade/data/category/CategoryRepositoryImpl.kt b/app/src/main/java/eu/kanade/data/category/CategoryRepositoryImpl.kt index d62069d1a..5bb792ff7 100644 --- a/app/src/main/java/eu/kanade/data/category/CategoryRepositoryImpl.kt +++ b/app/src/main/java/eu/kanade/data/category/CategoryRepositoryImpl.kt @@ -11,6 +11,10 @@ class CategoryRepositoryImpl( private val handler: DatabaseHandler, ) : CategoryRepository { + override suspend fun get(id: Long): Category? { + return handler.awaitOneOrNull { categoriesQueries.getCategory(id, categoryMapper) } + } + override suspend fun getAll(): List { return handler.awaitList { categoriesQueries.getCategories(categoryMapper) } } diff --git a/app/src/main/java/eu/kanade/domain/category/interactor/CreateCategoryWithName.kt b/app/src/main/java/eu/kanade/domain/category/interactor/CreateCategoryWithName.kt index 892baff76..eacf6f0ea 100644 --- a/app/src/main/java/eu/kanade/domain/category/interactor/CreateCategoryWithName.kt +++ b/app/src/main/java/eu/kanade/domain/category/interactor/CreateCategoryWithName.kt @@ -16,9 +16,10 @@ class CreateCategoryWithName( private val initialFlags: Long get() { + val sort = preferences.librarySortingMode().get() return preferences.libraryDisplayMode().get().flag or - preferences.librarySortingMode().get().flag or - preferences.librarySortingAscending().get().flag + sort.type.flag or + sort.direction.flag } suspend fun await(name: String): Result = withContext(NonCancellable) { diff --git a/app/src/main/java/eu/kanade/domain/category/interactor/ResetCategoryFlags.kt b/app/src/main/java/eu/kanade/domain/category/interactor/ResetCategoryFlags.kt index 21504eddd..7e92e557d 100644 --- a/app/src/main/java/eu/kanade/domain/category/interactor/ResetCategoryFlags.kt +++ b/app/src/main/java/eu/kanade/domain/category/interactor/ResetCategoryFlags.kt @@ -2,9 +2,7 @@ package eu.kanade.domain.category.interactor import eu.kanade.domain.category.repository.CategoryRepository import eu.kanade.tachiyomi.data.preference.PreferencesHelper -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.library.setting.plus class ResetCategoryFlags( private val preferences: PreferencesHelper, @@ -14,12 +12,6 @@ class ResetCategoryFlags( suspend fun await() { val display = preferences.libraryDisplayMode().get() val sort = preferences.librarySortingMode().get() - val sortDirection = preferences.librarySortingAscending().get() - - var flags = 0L - flags = flags and DisplayModeSetting.MASK.inv() or (display.flag and DisplayModeSetting.MASK) - flags = flags and SortModeSetting.MASK.inv() or (sort.flag and SortModeSetting.MASK) - flags = flags and SortDirectionSetting.MASK.inv() or (sortDirection.flag and SortDirectionSetting.MASK) - categoryRepository.updateAllFlags(flags) + categoryRepository.updateAllFlags(display + sort.type + sort.direction) } } diff --git a/app/src/main/java/eu/kanade/domain/category/interactor/SetDisplayModeForCategory.kt b/app/src/main/java/eu/kanade/domain/category/interactor/SetDisplayModeForCategory.kt index 37cd115c6..1a4fa6257 100644 --- a/app/src/main/java/eu/kanade/domain/category/interactor/SetDisplayModeForCategory.kt +++ b/app/src/main/java/eu/kanade/domain/category/interactor/SetDisplayModeForCategory.kt @@ -5,19 +5,24 @@ import eu.kanade.domain.category.model.CategoryUpdate import eu.kanade.domain.category.repository.CategoryRepository import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.ui.library.LibraryGroup -import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting +import eu.kanade.tachiyomi.ui.library.setting.LibraryDisplayMode +import eu.kanade.tachiyomi.ui.library.setting.plus class SetDisplayModeForCategory( private val preferences: PreferencesHelper, private val categoryRepository: CategoryRepository, ) { - suspend fun await(category: Category, displayModeSetting: DisplayModeSetting) { - val flags = category.flags and DisplayModeSetting.MASK.inv() or (displayModeSetting.flag and DisplayModeSetting.MASK) + suspend fun await(categoryId: Long, display: LibraryDisplayMode) { // SY --> - val isDefaultGroup = preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT + if (preferences.groupLibraryBy().get() != LibraryGroup.BY_DEFAULT) { + preferences.libraryDisplayMode().set(display) + return + } // SY <-- - if (preferences.categorizedDisplaySettings().get() /* SY --> */ && isDefaultGroup/* SY <-- */) { + val category = categoryRepository.get(categoryId) ?: return + val flags = category.flags + display + if (preferences.categorizedDisplaySettings().get()) { categoryRepository.updatePartial( CategoryUpdate( id = category.id, @@ -25,14 +30,12 @@ class SetDisplayModeForCategory( ), ) } else { - preferences.libraryDisplayMode().set(displayModeSetting) - // SY --> - if (isDefaultGroup) { - // SY <-- - categoryRepository.updateAllFlags(flags) - // SY --> - } - // SY <-- + preferences.libraryDisplayMode().set(display) + categoryRepository.updateAllFlags(flags) } } + + suspend fun await(category: Category, display: LibraryDisplayMode) { + await(category.id, display) + } } diff --git a/app/src/main/java/eu/kanade/domain/category/interactor/SetSortModeForCategory.kt b/app/src/main/java/eu/kanade/domain/category/interactor/SetSortModeForCategory.kt index bba4b2987..06d0d2c8d 100644 --- a/app/src/main/java/eu/kanade/domain/category/interactor/SetSortModeForCategory.kt +++ b/app/src/main/java/eu/kanade/domain/category/interactor/SetSortModeForCategory.kt @@ -5,25 +5,23 @@ import eu.kanade.domain.category.model.CategoryUpdate import eu.kanade.domain.category.repository.CategoryRepository import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.ui.library.LibraryGroup -import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting -import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting +import eu.kanade.tachiyomi.ui.library.setting.LibrarySort +import eu.kanade.tachiyomi.ui.library.setting.plus class SetSortModeForCategory( private val preferences: PreferencesHelper, private val categoryRepository: CategoryRepository, ) { - suspend fun await(category: Category, sortModeSetting: SortModeSetting, sortDirectionSetting: SortDirectionSetting) { + suspend fun await(categoryId: Long, type: LibrarySort.Type, direction: LibrarySort.Direction) { // SY --> if (preferences.groupLibraryBy().get() != LibraryGroup.BY_DEFAULT) { - preferences.librarySortingMode().set(sortModeSetting) - preferences.librarySortingAscending().set(sortDirectionSetting) + preferences.librarySortingMode().set(LibrarySort(type, direction)) return } // SY <-- - var flags = category.flags and SortModeSetting.MASK.inv() or (sortModeSetting.flag and SortModeSetting.MASK) - flags = flags and SortDirectionSetting.MASK.inv() or (sortDirectionSetting.flag and SortDirectionSetting.MASK) - + val category = categoryRepository.get(categoryId) ?: return + val flags = category.flags + type + direction if (preferences.categorizedDisplaySettings().get()) { categoryRepository.updatePartial( CategoryUpdate( @@ -32,9 +30,12 @@ class SetSortModeForCategory( ), ) } else { - preferences.librarySortingMode().set(sortModeSetting) - preferences.librarySortingAscending().set(sortDirectionSetting) + preferences.librarySortingMode().set(LibrarySort(type, direction)) categoryRepository.updateAllFlags(flags) } } + + suspend fun await(category: Category, type: LibrarySort.Type, direction: LibrarySort.Direction) { + await(category.id, type, direction) + } } diff --git a/app/src/main/java/eu/kanade/domain/category/model/Category.kt b/app/src/main/java/eu/kanade/domain/category/model/Category.kt index 1b8b1d14b..870cab2b6 100644 --- a/app/src/main/java/eu/kanade/domain/category/model/Category.kt +++ b/app/src/main/java/eu/kanade/domain/category/model/Category.kt @@ -1,8 +1,5 @@ package eu.kanade.domain.category.model -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 data class Category( @@ -14,15 +11,6 @@ data class Category( val isSystemCategory: Boolean = id == UNCATEGORIZED_ID - val displayMode: Long - get() = flags and DisplayModeSetting.MASK - - val sortMode: Long - get() = flags and SortModeSetting.MASK - - val sortDirection: Long - get() = flags and SortDirectionSetting.MASK - companion object { const val UNCATEGORIZED_ID = 0L diff --git a/app/src/main/java/eu/kanade/domain/category/repository/CategoryRepository.kt b/app/src/main/java/eu/kanade/domain/category/repository/CategoryRepository.kt index 917b21d50..c252eeb07 100644 --- a/app/src/main/java/eu/kanade/domain/category/repository/CategoryRepository.kt +++ b/app/src/main/java/eu/kanade/domain/category/repository/CategoryRepository.kt @@ -6,6 +6,8 @@ import kotlinx.coroutines.flow.Flow interface CategoryRepository { + suspend fun get(id: Long): Category? + suspend fun getAll(): List fun getAllAsFlow(): Flow> diff --git a/app/src/main/java/eu/kanade/presentation/library/components/LibraryContent.kt b/app/src/main/java/eu/kanade/presentation/library/components/LibraryContent.kt index 90f87c49e..418fc180d 100644 --- a/app/src/main/java/eu/kanade/presentation/library/components/LibraryContent.kt +++ b/app/src/main/java/eu/kanade/presentation/library/components/LibraryContent.kt @@ -27,7 +27,7 @@ import eu.kanade.presentation.library.LibraryState import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.LibraryManga import eu.kanade.tachiyomi.ui.library.LibraryItem -import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting +import eu.kanade.tachiyomi.ui.library.setting.LibraryDisplayMode import eu.kanade.tachiyomi.widget.EmptyView import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -48,7 +48,7 @@ fun LibraryContent( onRefresh: (Category?) -> Boolean, onGlobalSearchClicked: () -> Unit, getNumberOfMangaForCategory: @Composable (Long) -> State, - getDisplayModeForPage: @Composable (Int) -> State, + getDisplayModeForPage: @Composable (Int) -> State, getColumnsForOrientation: (Boolean) -> PreferenceMutableState, getLibraryForPage: @Composable (Int) -> State>, // SY --> diff --git a/app/src/main/java/eu/kanade/presentation/library/components/LibraryPager.kt b/app/src/main/java/eu/kanade/presentation/library/components/LibraryPager.kt index 972a98054..0b55e7797 100644 --- a/app/src/main/java/eu/kanade/presentation/library/components/LibraryPager.kt +++ b/app/src/main/java/eu/kanade/presentation/library/components/LibraryPager.kt @@ -15,7 +15,7 @@ import com.google.accompanist.pager.PagerState import eu.kanade.core.prefs.PreferenceMutableState import eu.kanade.tachiyomi.data.database.models.LibraryManga import eu.kanade.tachiyomi.ui.library.LibraryItem -import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting +import eu.kanade.tachiyomi.ui.library.setting.LibraryDisplayMode @Composable fun LibraryPager( @@ -24,7 +24,7 @@ fun LibraryPager( selectedManga: List, searchQuery: String?, onGlobalSearchClicked: () -> Unit, - getDisplayModeForPage: @Composable (Int) -> State, + getDisplayModeForPage: @Composable (Int) -> State, getColumnsForOrientation: (Boolean) -> PreferenceMutableState, getLibraryForPage: @Composable (Int) -> State>, onClickManga: (LibraryManga) -> Unit, @@ -45,7 +45,7 @@ fun LibraryPager( } val library by getLibraryForPage(page) val displayMode by getDisplayModeForPage(page) - val columns by if (displayMode != DisplayModeSetting.LIST) { + val columns by if (displayMode != LibraryDisplayMode.List) { val configuration = LocalConfiguration.current val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE @@ -55,7 +55,7 @@ fun LibraryPager( } when (displayMode) { - DisplayModeSetting.LIST -> { + LibraryDisplayMode.List -> { LibraryList( items = library, selection = selectedManga, @@ -65,7 +65,7 @@ fun LibraryPager( onGlobalSearchClicked = onGlobalSearchClicked, ) } - DisplayModeSetting.COMPACT_GRID -> { + LibraryDisplayMode.CompactGrid -> { LibraryCompactGrid( items = library, columns = columns, @@ -79,7 +79,7 @@ fun LibraryPager( // SY <-- ) } - DisplayModeSetting.COMFORTABLE_GRID -> { + LibraryDisplayMode.ComfortableGrid -> { LibraryComfortableGrid( items = library, columns = columns, @@ -93,7 +93,7 @@ fun LibraryPager( // SY <-- ) } - DisplayModeSetting.COVER_ONLY_GRID -> { + LibraryDisplayMode.CoverOnlyGrid -> { LibraryCoverOnlyGrid( items = library, columns = columns, diff --git a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt index ed7148f9b..9e868c72e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt @@ -13,8 +13,6 @@ import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.updater.AppUpdateJob import eu.kanade.tachiyomi.extension.ExtensionUpdateJob import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE -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.preference.minusAssign import eu.kanade.tachiyomi.util.preference.plusAssign @@ -198,34 +196,34 @@ object Migrations { } if (oldVersion < 64) { val oldSortingMode = prefs.getInt(PreferenceKeys.librarySortingMode, 0) - val oldSortingDirection = prefs.getBoolean(PreferenceKeys.librarySortingDirection, true) + val oldSortingDirection = prefs.getBoolean("library_sorting_ascending", true) @Suppress("DEPRECATION") val newSortingMode = when (oldSortingMode) { - 0 -> SortModeSetting.ALPHABETICAL - 1 -> SortModeSetting.LAST_READ - 2 -> SortModeSetting.LAST_CHECKED - 3 -> SortModeSetting.UNREAD - 4 -> SortModeSetting.TOTAL_CHAPTERS - 6 -> SortModeSetting.LATEST_CHAPTER - 8 -> SortModeSetting.DATE_FETCHED - 7 -> SortModeSetting.DATE_ADDED - else -> SortModeSetting.ALPHABETICAL + 0 -> "ALPHABETICAL" + 1 -> "LAST_READ" + 2 -> "LAST_CHECKED" + 3 -> "UNREAD" + 4 -> "TOTAL_CHAPTERS" + 6 -> "LATEST_CHAPTER" + 8 -> "DATE_FETCHED" + 7 -> "DATE_ADDED" + else -> "ALPHABETICAL" } val newSortingDirection = when (oldSortingDirection) { - true -> SortDirectionSetting.ASCENDING - else -> SortDirectionSetting.DESCENDING + true -> "ASCENDING" + else -> "DESCENDING" } prefs.edit(commit = true) { remove(PreferenceKeys.librarySortingMode) - remove(PreferenceKeys.librarySortingDirection) + remove("library_sorting_ascending") } prefs.edit { - putString(PreferenceKeys.librarySortingMode, newSortingMode.name) - putString(PreferenceKeys.librarySortingDirection, newSortingDirection.name) + putString(PreferenceKeys.librarySortingMode, newSortingMode) + putString("library_sorting_ascending", newSortingDirection) } } if (oldVersion < 70) { @@ -268,16 +266,24 @@ object Migrations { } if (oldVersion < 81) { // Handle renamed enum values - @Suppress("DEPRECATION") - val newSortingMode = when (val oldSortingMode = preferences.librarySortingMode().get()) { - SortModeSetting.LAST_CHECKED -> SortModeSetting.LAST_MANGA_UPDATE - SortModeSetting.UNREAD -> SortModeSetting.UNREAD_COUNT - SortModeSetting.DATE_FETCHED -> SortModeSetting.CHAPTER_FETCH_DATE - else -> oldSortingMode + prefs.edit { + val newSortingMode = when (val oldSortingMode = prefs.getString(PreferenceKeys.librarySortingMode, "ALPHABETICAL")) { + "LAST_CHECKED" -> "LAST_MANGA_UPDATE" + "UNREAD" -> "UNREAD_COUNT" + "DATE_FETCHED" -> "CHAPTER_FETCH_DATE" + else -> oldSortingMode + } + putString(PreferenceKeys.librarySortingMode, newSortingMode) + } + } + if (oldVersion < 82) { + prefs.edit { + val sort = prefs.getString(PreferenceKeys.librarySortingMode, null) ?: return@edit + val direction = prefs.getString("library_sorting_ascending", "ASCENDING")!! + putString(PreferenceKeys.librarySortingMode, "$sort,$direction") + remove("library_sorting_ascending") } - preferences.librarySortingMode().set(newSortingMode) } - return true } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index a82c3cc11..1338ec2d1 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -38,7 +38,6 @@ object PreferenceKeys { const val filterLewd = "pref_filter_library_lewd" const val librarySortingMode = "library_sorting_mode" - const val librarySortingDirection = "library_sorting_ascending" const val migrationSortingMode = "pref_migration_sorting" const val migrationSortingDirection = "pref_migration_direction" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 132d85dd5..648d32dbc 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -13,9 +13,8 @@ import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.anilist.Anilist import eu.kanade.tachiyomi.ui.library.LibraryGroup -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.library.setting.LibraryDisplayMode +import eu.kanade.tachiyomi.ui.library.setting.LibrarySort import eu.kanade.tachiyomi.ui.reader.setting.OrientationType import eu.kanade.tachiyomi.ui.reader.setting.ReaderBottomButton import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType @@ -178,7 +177,7 @@ class PreferencesHelper(val context: Context) { fun lastVersionCode() = flowPrefs.getInt("last_version_code", 0) - fun sourceDisplayMode() = flowPrefs.getEnum("pref_display_mode_catalogue", DisplayModeSetting.COMPACT_GRID) + fun sourceDisplayMode() = flowPrefs.getObject("pref_display_mode_catalogue", LibraryDisplayMode.Serializer, LibraryDisplayMode.default) fun enabledLanguages() = flowPrefs.getStringSet("source_languages", setOf("all", "en", Locale.getDefault().language)) @@ -239,7 +238,7 @@ class PreferencesHelper(val context: Context) { fun libraryUpdateCategories() = flowPrefs.getStringSet("library_update_categories", emptySet()) fun libraryUpdateCategoriesExclude() = flowPrefs.getStringSet("library_update_categories_exclude", emptySet()) - fun libraryDisplayMode() = flowPrefs.getEnum("pref_display_mode_library", DisplayModeSetting.COMPACT_GRID) + fun libraryDisplayMode() = flowPrefs.getObject("pref_display_mode_library", LibraryDisplayMode.Serializer, LibraryDisplayMode.default) fun downloadBadge() = flowPrefs.getBoolean("display_download_badge", false) @@ -267,8 +266,7 @@ class PreferencesHelper(val context: Context) { fun filterLewd() = flowPrefs.getInt(Keys.filterLewd, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value) - fun librarySortingMode() = flowPrefs.getEnum(Keys.librarySortingMode, SortModeSetting.ALPHABETICAL) - fun librarySortingAscending() = flowPrefs.getEnum(Keys.librarySortingDirection, SortDirectionSetting.ASCENDING) + fun librarySortingMode() = flowPrefs.getObject(Keys.librarySortingMode, LibrarySort.Serializer, LibrarySort.default) fun migrationSortingMode() = flowPrefs.getEnum(Keys.migrationSortingMode, SetMigrateSorting.Mode.ALPHABETICAL) fun migrationSortingDirection() = flowPrefs.getEnum(Keys.migrationSortingDirection, SetMigrateSorting.Direction.ASCENDING) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt index 8f20c9c48..7ef833149 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt @@ -41,7 +41,7 @@ import eu.kanade.tachiyomi.ui.browse.extension.details.SourcePreferencesControll import eu.kanade.tachiyomi.ui.browse.source.SourcesController 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.library.setting.LibraryDisplayMode import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.manga.AddDuplicateMangaDialog import eu.kanade.tachiyomi.ui.manga.MangaController @@ -369,7 +369,7 @@ open class BrowseSourceController(bundle: Bundle) : binding.catalogueView.removeView(oldRecycler) } - val recycler = if (preferences.sourceDisplayMode().get() == DisplayModeSetting.LIST /* SY --> */ || (preferences.enhancedEHentaiView().get() && presenter.source.isEhBasedSource()) /* SY <-- */) { + val recycler = if (preferences.sourceDisplayMode().get() == LibraryDisplayMode.List /* SY --> */ || (preferences.enhancedEHentaiView().get() && presenter.source.isEhBasedSource()) /* SY <-- */) { RecyclerView(view.context).apply { id = R.id.recycler layoutManager = LinearLayoutManager(context) @@ -437,8 +437,8 @@ open class BrowseSourceController(bundle: Bundle) : ) val displayItem = when (preferences.sourceDisplayMode().get()) { - DisplayModeSetting.LIST -> R.id.action_list - DisplayModeSetting.COMFORTABLE_GRID -> R.id.action_comfortable_grid + LibraryDisplayMode.List -> R.id.action_list + LibraryDisplayMode.ComfortableGrid -> R.id.action_comfortable_grid else -> R.id.action_compact_grid } menu.findItem(displayItem).isChecked = true @@ -470,9 +470,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(DisplayModeSetting.COMPACT_GRID) - R.id.action_comfortable_grid -> setDisplayMode(DisplayModeSetting.COMFORTABLE_GRID) - R.id.action_list -> setDisplayMode(DisplayModeSetting.LIST) + R.id.action_compact_grid -> setDisplayMode(LibraryDisplayMode.CompactGrid) + R.id.action_comfortable_grid -> setDisplayMode(LibraryDisplayMode.ComfortableGrid) + R.id.action_list -> setDisplayMode(LibraryDisplayMode.List) R.id.action_open_in_web_view -> openInWebView() // SY --> R.id.action_settings -> openSourceSettings() @@ -687,7 +687,7 @@ open class BrowseSourceController(bundle: Bundle) : * * @param mode the mode to change to */ - private fun setDisplayMode(mode: DisplayModeSetting) { + private fun setDisplayMode(mode: LibraryDisplayMode) { val view = view ?: return val adapter = adapter ?: return diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceItem.kt index 681e2865c..1c769bfcd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceItem.kt @@ -11,12 +11,12 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding -import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting +import eu.kanade.tachiyomi.ui.library.setting.LibraryDisplayMode import exh.metadata.metadata.base.RaisedSearchMetadata import exh.source.isEhBasedManga import uy.kohesive.injekt.injectLazy -class SourceItem(val manga: Manga, private val displayMode: Preference /* SY --> */, private val metadata: RaisedSearchMetadata? = null /* SY <-- */) : +class SourceItem(val manga: Manga, private val displayMode: Preference /* SY --> */, private val metadata: RaisedSearchMetadata? = null /* SY <-- */) : AbstractFlexibleItem>() { // SY --> val preferences: PreferencesHelper by injectLazy() @@ -29,9 +29,9 @@ class SourceItem(val manga: Manga, private val displayMode: Preference R.layout.source_compact_grid_item - DisplayModeSetting.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item - DisplayModeSetting.LIST -> R.layout.source_list_item + LibraryDisplayMode.CompactGrid, LibraryDisplayMode.CoverOnlyGrid -> R.layout.source_compact_grid_item + LibraryDisplayMode.ComfortableGrid -> R.layout.source_comfortable_grid_item + LibraryDisplayMode.List -> R.layout.source_list_item } } @@ -45,13 +45,13 @@ class SourceItem(val manga: Manga, private val displayMode: Preference { + LibraryDisplayMode.CompactGrid, LibraryDisplayMode.CoverOnlyGrid -> { SourceCompactGridHolder(SourceCompactGridItemBinding.bind(view), adapter) } - DisplayModeSetting.COMFORTABLE_GRID -> { + LibraryDisplayMode.ComfortableGrid -> { SourceComfortableGridHolder(SourceComfortableGridItemBinding.bind(view), adapter) } - DisplayModeSetting.LIST -> { + LibraryDisplayMode.List -> { SourceListHolder(view, adapter) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt index 3708156f0..f766aa3ec 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt @@ -57,9 +57,10 @@ import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.all.MergedSource import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter -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.library.setting.LibraryDisplayMode +import eu.kanade.tachiyomi.ui.library.setting.LibrarySort +import eu.kanade.tachiyomi.ui.library.setting.display +import eu.kanade.tachiyomi.ui.library.setting.sort import eu.kanade.tachiyomi.util.lang.combineLatest import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.withIOContext @@ -480,17 +481,13 @@ class LibraryPresenter( // SY <-- // SY --> - val defaultSortingMode = preferences.librarySortingMode().get() + val groupType = preferences.groupLibraryBy().get() + val groupSort = preferences.librarySortingMode().get() // SY <-- - val sortingModes = categories.associate { category -> - category.id to SortModeSetting.get(preferences, category) - } - - // SY --> - val defaultSortDirection = preferences.librarySortingAscending().get() - // SY <-- - val sortDirections = categories.associate { category -> - category.id to SortDirectionSetting.get(preferences, category) + val sortModes = categories.associate { category -> + // SY --> + category.id to category.sort + // SY <-- } val locale = Locale.getDefault() @@ -499,74 +496,68 @@ class LibraryPresenter( } val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 -> // SY --> - val sortingMode = if (groupType == LibraryGroup.BY_DEFAULT) { - sortingModes[i1.manga.category.toLong()] ?: defaultSortingMode - } else { - defaultSortingMode + val sort = when (groupType) { + LibraryGroup.BY_DEFAULT -> sortModes[i1.manga.category.toLong()]!! + else -> groupSort } - val sortAscending = if (groupType == LibraryGroup.BY_DEFAULT) { - sortDirections[i1.manga.category.toLong()] ?: defaultSortDirection - } else { - defaultSortDirection - } == SortDirectionSetting.ASCENDING // SY <-- - - when (sortingMode) { - SortModeSetting.ALPHABETICAL -> { + when (sort.type) { + LibrarySort.Type.Alphabetical -> { collator.compare(i1.manga.title.lowercase(locale), i2.manga.title.lowercase(locale)) } - SortModeSetting.LAST_READ -> { + LibrarySort.Type.LastRead -> { val manga1LastRead = lastReadManga[i1.manga.id!!] ?: 0 val manga2LastRead = lastReadManga[i2.manga.id!!] ?: 0 manga1LastRead.compareTo(manga2LastRead) } - SortModeSetting.LAST_MANGA_UPDATE -> { + LibrarySort.Type.LastUpdate -> { i1.manga.last_update.compareTo(i2.manga.last_update) } - SortModeSetting.UNREAD_COUNT -> when { + LibrarySort.Type.UnreadCount -> when { // Ensure unread content comes first i1.manga.unreadCount == i2.manga.unreadCount -> 0 - i1.manga.unreadCount == 0 -> if (sortAscending) 1 else -1 - i2.manga.unreadCount == 0 -> if (sortAscending) -1 else 1 + i1.manga.unreadCount == 0 -> if (sort.isAscending) 1 else -1 + i2.manga.unreadCount == 0 -> if (sort.isAscending) -1 else 1 else -> i1.manga.unreadCount.compareTo(i2.manga.unreadCount) } - SortModeSetting.TOTAL_CHAPTERS -> { + LibrarySort.Type.TotalChapters -> { i1.manga.totalChapters.compareTo(i2.manga.totalChapters) } - SortModeSetting.LATEST_CHAPTER -> { + LibrarySort.Type.LatestChapter -> { val manga1latestChapter = latestChapterManga[i1.manga.id!!] ?: latestChapterManga.size val manga2latestChapter = latestChapterManga[i2.manga.id!!] ?: latestChapterManga.size manga1latestChapter.compareTo(manga2latestChapter) } - SortModeSetting.CHAPTER_FETCH_DATE -> { + LibrarySort.Type.ChapterFetchDate -> { val manga1chapterFetchDate = chapterFetchDateManga[i1.manga.id!!] ?: 0 val manga2chapterFetchDate = chapterFetchDateManga[i2.manga.id!!] ?: 0 manga1chapterFetchDate.compareTo(manga2chapterFetchDate) } - SortModeSetting.DATE_ADDED -> { + LibrarySort.Type.DateAdded -> { i1.manga.date_added.compareTo(i2.manga.date_added) } // SY --> - SortModeSetting.TAG_LIST -> { + LibrarySort.Type.TagList -> { val manga1IndexOfTag = listOfTags.indexOfFirst { i1.manga.getGenres()?.contains(it) ?: false } val manga2IndexOfTag = listOfTags.indexOfFirst { i2.manga.getGenres()?.contains(it) ?: false } manga1IndexOfTag.compareTo(manga2IndexOfTag) } // SY <-- - else -> throw IllegalStateException("Invalid SortModeSetting: $sortingMode") + else -> throw IllegalStateException("Invalid SortModeSetting: ${sort.type}") } } return map.mapValues { entry -> - val sortAscending = if (groupType == LibraryGroup.BY_DEFAULT) { - sortDirections[entry.key.toLong()] ?: defaultSortDirection + // SY --> + val isAscending = if (groupType == LibraryGroup.BY_DEFAULT) { + sortModes[entry.key]!!.isAscending } else { - defaultSortDirection - } == SortDirectionSetting.ASCENDING - - val comparator = if (sortAscending) { + groupSort.isAscending + } + // SY <-- + val comparator = if ( /* SY --> */ isAscending /* SY <-- */) { Comparator(sortFn) } else { Collections.reverseOrder(sortFn) @@ -589,13 +580,6 @@ class LibraryPresenter( dbCategories } - libraryManga.forEach { (categoryId, libraryManga) -> - val category = categories.first { category -> category.id == categoryId } - libraryManga.forEach { libraryItem -> - libraryItem.displayMode = category.displayMode - } - } - // SY --> state.ogCategories = categories // SY <-- @@ -1117,18 +1101,18 @@ class LibraryPresenter( } } - private val currentCategory by preferences.libraryDisplayMode().asState() + private val libraryDisplayMode by preferences.libraryDisplayMode().asState() // SY <-- @Composable - fun getDisplayMode(index: Int): androidx.compose.runtime.State { + fun getDisplayMode(index: Int): androidx.compose.runtime.State { val category = categories[index] return derivedStateOf { // SY --> if (groupType != LibraryGroup.BY_DEFAULT) { - currentCategory + libraryDisplayMode } else { - DisplayModeSetting.fromFlag(category.displayMode) + category.display } // SY <-- } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt index 9217d65ff..87287d218 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt @@ -12,9 +12,10 @@ import eu.kanade.tachiyomi.R 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.ui.library.setting.LibraryDisplayMode +import eu.kanade.tachiyomi.ui.library.setting.LibrarySort +import eu.kanade.tachiyomi.ui.library.setting.display +import eu.kanade.tachiyomi.ui.library.setting.sort import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.widget.ExtendedNavigationView import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State @@ -226,32 +227,34 @@ class LibrarySettingsSheet( override val footer = null override fun initModels() { - val sorting = SortModeSetting.get(preferences, currentCategory) - val order = if (SortDirectionSetting.get(preferences, currentCategory) == SortDirectionSetting.ASCENDING) { - Item.MultiSort.SORT_ASC + // SY --> + val sort = if (preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT) { + currentCategory?.sort ?: LibrarySort.default } else { - Item.MultiSort.SORT_DESC + preferences.librarySortingMode().get() } + // SY <-- + val order = if (sort.isAscending) Item.MultiSort.SORT_ASC else Item.MultiSort.SORT_DESC alphabetically.state = - if (sorting == SortModeSetting.ALPHABETICAL) order else Item.MultiSort.SORT_NONE + if (sort.type == LibrarySort.Type.Alphabetical) order else Item.MultiSort.SORT_NONE lastRead.state = - if (sorting == SortModeSetting.LAST_READ) order else Item.MultiSort.SORT_NONE + if (sort.type == LibrarySort.Type.LastRead) order else Item.MultiSort.SORT_NONE lastChecked.state = - if (sorting == SortModeSetting.LAST_MANGA_UPDATE) order else Item.MultiSort.SORT_NONE + if (sort.type == LibrarySort.Type.LastUpdate) order else Item.MultiSort.SORT_NONE unread.state = - if (sorting == SortModeSetting.UNREAD_COUNT) order else Item.MultiSort.SORT_NONE + if (sort.type == LibrarySort.Type.UnreadCount) order else Item.MultiSort.SORT_NONE total.state = - if (sorting == SortModeSetting.TOTAL_CHAPTERS) order else Item.MultiSort.SORT_NONE + if (sort.type == LibrarySort.Type.TotalChapters) order else Item.MultiSort.SORT_NONE latestChapter.state = - if (sorting == SortModeSetting.LATEST_CHAPTER) order else Item.MultiSort.SORT_NONE + if (sort.type == LibrarySort.Type.LatestChapter) order else Item.MultiSort.SORT_NONE chapterFetchDate.state = - if (sorting == SortModeSetting.CHAPTER_FETCH_DATE) order else Item.MultiSort.SORT_NONE + if (sort.type == LibrarySort.Type.ChapterFetchDate) order else Item.MultiSort.SORT_NONE dateAdded.state = - if (sorting == SortModeSetting.DATE_ADDED) order else Item.MultiSort.SORT_NONE + if (sort.type == LibrarySort.Type.DateAdded) order else Item.MultiSort.SORT_NONE // SY --> tagList.state = - if (sorting == SortModeSetting.TAG_LIST) order else Item.MultiSort.SORT_NONE + if (sort.type == LibrarySort.Type.TagList) order else Item.MultiSort.SORT_NONE // SY <-- } @@ -285,23 +288,23 @@ class LibrarySettingsSheet( private fun setSortPreference(item: Item.MultiStateGroup) { val mode = when (item) { - alphabetically -> SortModeSetting.ALPHABETICAL - lastRead -> SortModeSetting.LAST_READ - lastChecked -> SortModeSetting.LAST_MANGA_UPDATE - unread -> SortModeSetting.UNREAD_COUNT - total -> SortModeSetting.TOTAL_CHAPTERS - latestChapter -> SortModeSetting.LATEST_CHAPTER - chapterFetchDate -> SortModeSetting.CHAPTER_FETCH_DATE - dateAdded -> SortModeSetting.DATE_ADDED + alphabetically -> LibrarySort.Type.Alphabetical + lastRead -> LibrarySort.Type.LastRead + lastChecked -> LibrarySort.Type.LastUpdate + unread -> LibrarySort.Type.UnreadCount + total -> LibrarySort.Type.TotalChapters + latestChapter -> LibrarySort.Type.LatestChapter + chapterFetchDate -> LibrarySort.Type.ChapterFetchDate + dateAdded -> LibrarySort.Type.DateAdded // SY --> - tagList -> SortModeSetting.TAG_LIST + tagList -> LibrarySort.Type.TagList // SY <-- else -> throw NotImplementedError("Unknown display mode") } val direction = if (item.state == Item.MultiSort.SORT_ASC) { - SortDirectionSetting.ASCENDING + LibrarySort.Direction.Ascending } else { - SortDirectionSetting.DESCENDING + LibrarySort.Direction.Descending } sheetScope.launchIO { @@ -344,12 +347,14 @@ class LibrarySettingsSheet( } // Gets user preference of currently selected display mode at current category - private fun getDisplayModePreference(): DisplayModeSetting { - return if (currentCategory != null && preferences.categorizedDisplaySettings().get()/* SY --> */ && preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT /* SY <-- */) { - DisplayModeSetting.fromFlag(currentCategory!!.displayMode) + private fun getDisplayModePreference(): LibraryDisplayMode { + // SY --> + return if (preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT) { + currentCategory?.display ?: LibraryDisplayMode.default } else { preferences.libraryDisplayMode().get() } + // SY <-- } inner class DisplayGroup : Group { @@ -381,19 +386,19 @@ class LibrarySettingsSheet( } // Sets display group selections based on given mode - fun setGroupSelections(mode: DisplayModeSetting) { - compactGrid.checked = mode == DisplayModeSetting.COMPACT_GRID - comfortableGrid.checked = mode == DisplayModeSetting.COMFORTABLE_GRID - coverOnlyGrid.checked = mode == DisplayModeSetting.COVER_ONLY_GRID - list.checked = mode == DisplayModeSetting.LIST + fun setGroupSelections(mode: LibraryDisplayMode) { + compactGrid.checked = mode == LibraryDisplayMode.CompactGrid + comfortableGrid.checked = mode == LibraryDisplayMode.ComfortableGrid + coverOnlyGrid.checked = mode == LibraryDisplayMode.CoverOnlyGrid + list.checked = mode == LibraryDisplayMode.List } private fun setDisplayModePreference(item: Item) { val flag = when (item) { - compactGrid -> DisplayModeSetting.COMPACT_GRID - comfortableGrid -> DisplayModeSetting.COMFORTABLE_GRID - coverOnlyGrid -> DisplayModeSetting.COVER_ONLY_GRID - list -> DisplayModeSetting.LIST + compactGrid -> LibraryDisplayMode.CompactGrid + comfortableGrid -> LibraryDisplayMode.ComfortableGrid + coverOnlyGrid -> LibraryDisplayMode.CoverOnlyGrid + list -> LibraryDisplayMode.List else -> throw NotImplementedError("Unknown display mode") } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/DisplayModeSetting.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/DisplayModeSetting.kt deleted file mode 100644 index 1e00dd088..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/DisplayModeSetting.kt +++ /dev/null @@ -1,17 +0,0 @@ -package eu.kanade.tachiyomi.ui.library.setting - -enum class DisplayModeSetting(val flag: Long) { - COMPACT_GRID(0b00000000), - COMFORTABLE_GRID(0b00000001), - LIST(0b00000010), - COVER_ONLY_GRID(0b00000011); - - companion object { - const val MASK = 0b00000011L - - fun fromFlag(flag: Long?): DisplayModeSetting { - return values() - .find { mode -> mode.flag == flag } ?: COMPACT_GRID - } - } -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/Flag.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/Flag.kt new file mode 100644 index 000000000..a8653059b --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/Flag.kt @@ -0,0 +1,35 @@ +package eu.kanade.tachiyomi.ui.library.setting + +interface Flag { + val flag: Long +} + +interface Mask { + val mask: Long +} + +interface FlagWithMask : Flag, Mask + +operator fun Long.contains(other: Flag): Boolean { + return if (other is Mask) { + other.flag == this and other.mask + } else { + other.flag == this + } +} + +operator fun Long.plus(other: Flag): Long { + return if (other is Mask) { + this and other.mask.inv() or (other.flag and other.mask) + } else { + this or other.flag + } +} + +operator fun Flag.plus(other: Flag): Long { + return if (other is Mask) { + this.flag and other.mask.inv() or (other.flag and other.mask) + } else { + this.flag or other.flag + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/LibraryDisplayMode.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/LibraryDisplayMode.kt new file mode 100644 index 000000000..5f5b0b15b --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/LibraryDisplayMode.kt @@ -0,0 +1,60 @@ +package eu.kanade.tachiyomi.ui.library.setting + +import eu.kanade.domain.category.model.Category +import com.fredporciuncula.flow.preferences.Serializer as PreferencesSerializer + +sealed class LibraryDisplayMode( + override val flag: Long, +) : FlagWithMask { + + override val mask: Long = 0b00000011L + + object CompactGrid : LibraryDisplayMode(0b00000000) + object ComfortableGrid : LibraryDisplayMode(0b00000001) + object List : LibraryDisplayMode(0b00000010) + object CoverOnlyGrid : LibraryDisplayMode(0b00000011) + + object Serializer : PreferencesSerializer { + override fun deserialize(serialized: String): LibraryDisplayMode { + return LibraryDisplayMode.deserialize(serialized) + } + + override fun serialize(value: LibraryDisplayMode): String { + return value.serialize() + } + } + + companion object { + val values = setOf(CompactGrid, ComfortableGrid, List, CoverOnlyGrid) + val default = CompactGrid + + fun valueOf(flag: Long?): LibraryDisplayMode { + if (flag == null) return default + return values + .find { mode -> mode.flag == flag and mode.mask } + ?: default + } + + fun deserialize(serialized: String): LibraryDisplayMode { + return when (serialized) { + "COMFORTABLE_GRID" -> ComfortableGrid + "COMPACT_GRID" -> CompactGrid + "COVER_ONLY_GRID" -> CoverOnlyGrid + "LIST" -> List + else -> default + } + } + } + + fun serialize(): String { + return when (this) { + ComfortableGrid -> "COMFORTABLE_GRID" + CompactGrid -> "COMPACT_GRID" + CoverOnlyGrid -> "COVER_ONLY_GRID" + List -> "LIST" + } + } +} + +val Category.display: LibraryDisplayMode + get() = LibraryDisplayMode.valueOf(flags) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/LibrarySort.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/LibrarySort.kt new file mode 100644 index 000000000..f5b4c4c24 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/LibrarySort.kt @@ -0,0 +1,130 @@ +package eu.kanade.tachiyomi.ui.library.setting + +import eu.kanade.domain.category.model.Category +import com.fredporciuncula.flow.preferences.Serializer as PreferencesSerializer + +data class LibrarySort( + val type: Type, + val direction: Direction, +) : FlagWithMask { + + override val flag: Long + get() = type + direction + + override val mask: Long + get() = type.mask or direction.mask + + val isAscending: Boolean + get() = direction == Direction.Ascending + + sealed class Type( + override val flag: Long, + ) : FlagWithMask { + + override val mask: Long = 0b00111100L + + object Alphabetical : Type(0b00000000) + object LastRead : Type(0b00000100) + object LastUpdate : Type(0b00001000) + object UnreadCount : Type(0b00001100) + object TotalChapters : Type(0b00010000) + object LatestChapter : Type(0b00010100) + object ChapterFetchDate : Type(0b00011000) + object DateAdded : Type(0b00011100) + + // SY --> + object TagList : Type(0b00100100) + // SY <-- + + companion object { + + fun valueOf(flag: Long): Type { + return types.find { type -> type.flag == flag and type.mask } ?: default.type + } + } + } + + sealed class Direction( + override val flag: Long, + ) : FlagWithMask { + + override val mask: Long = 0b01000000L + + object Ascending : Direction(0b01000000) + object Descending : Direction(0b00000000) + + companion object { + + fun valueOf(flag: Long): Direction { + return directions.find { direction -> direction.flag == flag and direction.mask } ?: default.direction + } + } + } + + object Serializer : PreferencesSerializer { + override fun deserialize(serialized: String): LibrarySort { + return LibrarySort.deserialize(serialized) + } + + override fun serialize(value: LibrarySort): String { + return value.serialize() + } + } + + companion object { + val types = setOf(Type.Alphabetical, Type.LastRead, Type.LastUpdate, Type.UnreadCount, Type.TotalChapters, Type.LatestChapter, Type.ChapterFetchDate, Type.DateAdded) + val directions = setOf(Direction.Ascending, Direction.Descending) + val default = LibrarySort(Type.Alphabetical, Direction.Ascending) + + fun valueOf(flag: Long): LibrarySort { + return LibrarySort( + Type.valueOf(flag), + Direction.valueOf(flag), + ) + } + + fun deserialize(serialized: String): LibrarySort { + if (serialized.isEmpty()) return default + return try { + val values = serialized.split(",") + val type = when (values[0]) { + "ALPHABETICAL" -> Type.Alphabetical + "LAST_READ" -> Type.LastRead + "LAST_MANGA_UPDATE" -> Type.LastUpdate + "UNREAD_COUNT" -> Type.UnreadCount + "TOTAL_CHAPTERS" -> Type.TotalChapters + "LATEST_CHAPTER" -> Type.LatestChapter + "CHAPTER_FETCH_DATE" -> Type.ChapterFetchDate + "DATE_ADDED" -> Type.DateAdded + // SY --> + "TAG_LIST" -> Type.TagList + // SY <-- + else -> Type.Alphabetical + } + val ascending = if (values[1] == "ASCENDING") Direction.Ascending else Direction.Descending + LibrarySort(type, ascending) + } catch (e: Exception) { + default + } + } + } + + fun serialize(): String { + val type = when (type) { + Type.Alphabetical -> "ALPHABETICAL" + Type.LastRead -> "LAST_READ" + Type.LastUpdate -> "LAST_MANGA_UPDATE" + Type.UnreadCount -> "UNREAD_COUNT" + Type.TotalChapters -> "TOTAL_CHAPTERS" + Type.LatestChapter -> "LATEST_CHAPTER" + Type.ChapterFetchDate -> "CHAPTER_FETCH_DATE" + Type.DateAdded -> "DATE_ADDED" + Type.TagList -> "TAG_LIST" + } + val direction = if (direction == Direction.Ascending) "ASCENDING" else "DESCENDING" + return "$type,$direction" + } +} + +val Category.sort: LibrarySort + get() = LibrarySort.valueOf(flags) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/SortDirectionSetting.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/SortDirectionSetting.kt deleted file mode 100644 index 719ff54f4..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/SortDirectionSetting.kt +++ /dev/null @@ -1,26 +0,0 @@ -package eu.kanade.tachiyomi.ui.library.setting - -import eu.kanade.domain.category.model.Category -import eu.kanade.tachiyomi.data.preference.PreferencesHelper -import eu.kanade.tachiyomi.ui.library.LibraryGroup - -enum class SortDirectionSetting(val flag: Long) { - ASCENDING(0b01000000), - DESCENDING(0b00000000); - - companion object { - const val MASK = 0b01000000L - - private fun fromFlag(flag: Long?): SortDirectionSetting { - return values().find { mode -> mode.flag == flag } ?: ASCENDING - } - - fun get(preferences: PreferencesHelper, category: Category?): SortDirectionSetting { - return if (/* SY --> */ preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT/* SY <-- */) { - fromFlag(category?.sortDirection) - } else { - preferences.librarySortingAscending().get() - } - } - } -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/SortModeSetting.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/SortModeSetting.kt deleted file mode 100644 index 2901ad6d6..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/SortModeSetting.kt +++ /dev/null @@ -1,49 +0,0 @@ -package eu.kanade.tachiyomi.ui.library.setting - -import eu.kanade.domain.category.model.Category -import eu.kanade.tachiyomi.data.preference.PreferencesHelper -import eu.kanade.tachiyomi.ui.library.LibraryGroup - -enum class SortModeSetting(val flag: Long) { - ALPHABETICAL(0b00000000), - LAST_READ(0b00000100), - LAST_MANGA_UPDATE(0b00001000), - UNREAD_COUNT(0b00001100), - TOTAL_CHAPTERS(0b00010000), - LATEST_CHAPTER(0b00010100), - CHAPTER_FETCH_DATE(0b00011000), - DATE_ADDED(0b00011100), - - // SY --> - @Deprecated("Was unused") - DRAG_AND_DROP(0b00100000), - TAG_LIST(0b00100100), - // SY <-- - - @Deprecated("Use LAST_MANGA_UPDATE") - LAST_CHECKED(0b00001000), - - @Deprecated("Use UNREAD_COUNT") - UNREAD(0b00001100), - - @Deprecated("Use CHAPTER_FETCH_DATE") - DATE_FETCHED(0b00011000), - ; - - companion object { - // Mask supports for more sorting flags if necessary - const val MASK = 0b00111100L - - fun fromFlag(flag: Long?): SortModeSetting { - return values().find { mode -> mode.flag == flag } ?: ALPHABETICAL - } - - fun get(preferences: PreferencesHelper, category: Category?): SortModeSetting { - return if (category != null && preferences.categorizedDisplaySettings().get() /* SY --> */ && preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT/* SY <-- */) { - fromFlag(category.sortMode) - } else { - preferences.librarySortingMode().get() - } - } - } -} diff --git a/app/src/main/java/exh/EXHMigrations.kt b/app/src/main/java/exh/EXHMigrations.kt index 3db562a36..a35a9481d 100644 --- a/app/src/main/java/exh/EXHMigrations.kt +++ b/app/src/main/java/exh/EXHMigrations.kt @@ -33,9 +33,6 @@ import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.online.all.Hitomi import eu.kanade.tachiyomi.source.online.all.NHentai -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.util.preference.minusAssign import eu.kanade.tachiyomi.util.system.DeviceUtil @@ -271,35 +268,35 @@ object EXHMigrations { if (oldVersion under 20) { try { val oldSortingMode = prefs.getInt(PreferenceKeys.librarySortingMode, 0 /* ALPHABETICAL */) - val oldSortingDirection = prefs.getBoolean(PreferenceKeys.librarySortingDirection, true) + val oldSortingDirection = prefs.getBoolean("library_sorting_ascending", true) val newSortingMode = when (oldSortingMode) { - 0 -> SortModeSetting.ALPHABETICAL - 1 -> SortModeSetting.LAST_READ - 2 -> SortModeSetting.LAST_MANGA_UPDATE - 3 -> SortModeSetting.UNREAD_COUNT - 4 -> SortModeSetting.TOTAL_CHAPTERS - 6 -> SortModeSetting.LATEST_CHAPTER - 7 -> SortModeSetting.DRAG_AND_DROP - 8 -> SortModeSetting.DATE_ADDED - 9 -> SortModeSetting.TAG_LIST - 10 -> SortModeSetting.CHAPTER_FETCH_DATE - else -> SortModeSetting.ALPHABETICAL + 0 -> "ALPHABETICAL" + 1 -> "LAST_READ" + 2 -> "LAST_MANGA_UPDATE" + 3 -> "UNREAD_COUNT" + 4 -> "TOTAL_CHAPTERS" + 6 -> "LATEST_CHAPTER" + 7 -> "DRAG_AND_DROP" + 8 -> "DATE_ADDED" + 9 -> "TAG_LIST" + 10 -> "CHAPTER_FETCH_DATE" + else -> "ALPHABETICAL" } val newSortingDirection = when (oldSortingDirection) { - true -> SortDirectionSetting.ASCENDING - else -> SortDirectionSetting.DESCENDING + true -> "ASCENDING" + else -> "DESCENDING" } prefs.edit(commit = true) { remove(PreferenceKeys.librarySortingMode) - remove(PreferenceKeys.librarySortingDirection) + remove("library_sorting_ascending") } prefs.edit { - putString(PreferenceKeys.librarySortingMode, newSortingMode.name) - putString(PreferenceKeys.librarySortingDirection, newSortingDirection.name) + putString(PreferenceKeys.librarySortingMode, newSortingMode) + putString("library_sorting_ascending", newSortingDirection) } } catch (e: Exception) { logcat(throwable = e) { "Already done migration" } @@ -358,12 +355,16 @@ object EXHMigrations { } if (oldVersion under 28) { if (prefs.getString("pref_display_mode_library", null) == "NO_TITLE_GRID") { - preferences.libraryDisplayMode().set(DisplayModeSetting.COVER_ONLY_GRID) + prefs.edit(commit = true) { + putString("pref_display_mode_library", "COVER_ONLY_GRID") + } } } if (oldVersion under 29) { if (prefs.getString("pref_display_mode_catalogue", null) == "NO_TITLE_GRID") { - preferences.sourceDisplayMode().set(DisplayModeSetting.COMPACT_GRID) + prefs.edit(commit = true) { + putString("pref_display_mode_catalogue", "COMPACT_GRID") + } } } if (oldVersion under 30) { @@ -414,22 +415,24 @@ object EXHMigrations { if (oldVersion under 38) { // Handle renamed enum values @Suppress("DEPRECATION") - val newSortingMode = when (val oldSortingMode = preferences.librarySortingMode().get()) { - SortModeSetting.LAST_CHECKED -> SortModeSetting.LAST_MANGA_UPDATE - SortModeSetting.UNREAD -> SortModeSetting.UNREAD_COUNT - SortModeSetting.DATE_FETCHED -> SortModeSetting.CHAPTER_FETCH_DATE - SortModeSetting.DRAG_AND_DROP -> SortModeSetting.ALPHABETICAL + val newSortingMode = when (val oldSortingMode = prefs.getString(PreferenceKeys.librarySortingMode, "ALPHABETICAL")) { + "LAST_CHECKED" -> "LAST_MANGA_UPDATE" + "UNREAD" -> "UNREAD_COUNT" + "DATE_FETCHED" -> "CHAPTER_FETCH_DATE" + "DRAG_AND_DROP" -> "ALPHABETICAL" else -> oldSortingMode } - preferences.librarySortingMode().set(newSortingMode) + prefs.edit { + putString(PreferenceKeys.librarySortingMode, newSortingMode) + } runBlocking { handler.await(true) { categoriesQueries.getCategories(categoryMapper).executeAsList() - .filter { SortModeSetting.fromFlag(it.flags and SortModeSetting.MASK) == SortModeSetting.DRAG_AND_DROP } + .filter { (it.flags and 0b00111100L) == 0b00100000L } .forEach { categoriesQueries.update( categoryId = it.id, - flags = it.flags xor SortModeSetting.DRAG_AND_DROP.flag, + flags = it.flags and 0b00111100L.inv(), name = null, order = null, ) @@ -437,6 +440,14 @@ object EXHMigrations { } } } + if (oldVersion under 39) { + prefs.edit { + val sort = prefs.getString(PreferenceKeys.librarySortingMode, null) ?: return@edit + val direction = prefs.getString("library_sorting_ascending", "ASCENDING")!! + putString(PreferenceKeys.librarySortingMode, "$sort,$direction") + remove("library_sorting_ascending") + } + } // if (oldVersion under 1) { } (1 is current release version) // do stuff here when releasing changed crap diff --git a/app/src/main/sqldelight/data/categories.sq b/app/src/main/sqldelight/data/categories.sq index b20b9f1b7..628ddc3af 100644 --- a/app/src/main/sqldelight/data/categories.sq +++ b/app/src/main/sqldelight/data/categories.sq @@ -19,6 +19,12 @@ BEGIN SELECT CASE END; END; +getCategory: +SELECT _id,name,sort,flags +FROM categories +WHERE _id = :id +LIMIT 1; + getCategories: SELECT _id AS id, diff --git a/app/src/test/java/eu/kanade/tachiyomi/util/chapter/LibraryFlagsTest.kt b/app/src/test/java/eu/kanade/tachiyomi/util/chapter/LibraryFlagsTest.kt new file mode 100644 index 000000000..873dbf680 --- /dev/null +++ b/app/src/test/java/eu/kanade/tachiyomi/util/chapter/LibraryFlagsTest.kt @@ -0,0 +1,69 @@ +package eu.kanade.tachiyomi.util.chapter + +import eu.kanade.tachiyomi.ui.library.setting.LibraryDisplayMode +import eu.kanade.tachiyomi.ui.library.setting.LibrarySort +import eu.kanade.tachiyomi.ui.library.setting.plus +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotEquals +import org.junit.jupiter.api.Test + +class LibraryFlagsTest { + + @Test + fun `Check the amount of flags`() { + assertEquals(4, LibraryDisplayMode.values.size) + assertEquals(8, LibrarySort.types.size) + assertEquals(2, LibrarySort.directions.size) + } + + @Test + fun `Test Flag plus operator (LibraryDisplayMode)`() { + val current = LibraryDisplayMode.List + val new = LibraryDisplayMode.CoverOnlyGrid + val flag = current + new + + assertEquals(0b00000011, flag) + } + + @Test + fun `Test Flag plus operator (LibrarySort)`() { + val current = LibrarySort(LibrarySort.Type.LastRead, LibrarySort.Direction.Ascending) + val new = LibrarySort(LibrarySort.Type.DateAdded, LibrarySort.Direction.Ascending) + val flag = current + new + + assertEquals(0b01011100, flag) + } + + @Test + fun `Test Flag plus operator`() { + val display = LibraryDisplayMode.CoverOnlyGrid + val sort = LibrarySort(LibrarySort.Type.DateAdded, LibrarySort.Direction.Ascending) + val flag = display + sort + + assertEquals(0b01011111, flag) + } + + @Test + fun `Test Flag plus operator with old flag as base`() { + val currentDisplay = LibraryDisplayMode.List + val currentSort = LibrarySort(LibrarySort.Type.UnreadCount, LibrarySort.Direction.Descending) + val currentFlag = currentDisplay + currentSort + + val display = LibraryDisplayMode.CoverOnlyGrid + val sort = LibrarySort(LibrarySort.Type.DateAdded, LibrarySort.Direction.Ascending) + val flag = currentFlag + display + sort + + assertEquals(0b00001110, currentFlag) + assertEquals(0b01011111, flag) + assertNotEquals(currentFlag, flag) + } + + @Test + fun `Test default flags`() { + val sort = LibrarySort.default + val display = LibraryDisplayMode.default + val flag = display + sort.type + sort.direction + + assertEquals(0b01000000, flag) + } +}