mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	Tweak flag classes for Library (#7829)
* Tweak flag classes for Library - Add interface for Flag and Mask - Merge Sort Type and Direction into one class - Use custom serializers for preferences - Mainly to not break the old * Review changes
This commit is contained in:
		| @@ -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<Category> { | ||||
|         return handler.awaitList { categoriesQueries.getCategories(categoryMapper) } | ||||
|     } | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -4,15 +4,17 @@ import eu.kanade.domain.category.model.Category | ||||
| 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.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) { | ||||
|         val category = categoryRepository.get(categoryId) ?: return | ||||
|         val flags = category.flags + display | ||||
|         if (preferences.categorizedDisplaySettings().get()) { | ||||
|             categoryRepository.updatePartial( | ||||
|                 CategoryUpdate( | ||||
| @@ -21,8 +23,12 @@ class SetDisplayModeForCategory( | ||||
|                 ), | ||||
|             ) | ||||
|         } else { | ||||
|             preferences.libraryDisplayMode().set(displayModeSetting) | ||||
|             preferences.libraryDisplayMode().set(display) | ||||
|             categoryRepository.updateAllFlags(flags) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     suspend fun await(category: Category, display: LibraryDisplayMode) { | ||||
|         await(category.id, display) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -4,17 +4,17 @@ import eu.kanade.domain.category.model.Category | ||||
| 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.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) { | ||||
|         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) | ||||
|     suspend fun await(categoryId: Long, type: LibrarySort.Type, direction: LibrarySort.Direction) { | ||||
|         val category = categoryRepository.get(categoryId) ?: return | ||||
|         val flags = category.flags + type + direction | ||||
|         if (preferences.categorizedDisplaySettings().get()) { | ||||
|             categoryRepository.updatePartial( | ||||
|                 CategoryUpdate( | ||||
| @@ -23,9 +23,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) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -6,6 +6,8 @@ import kotlinx.coroutines.flow.Flow | ||||
|  | ||||
| interface CategoryRepository { | ||||
|  | ||||
|     suspend fun get(id: Long): Category? | ||||
|  | ||||
|     suspend fun getAll(): List<Category> | ||||
|  | ||||
|     fun getAllAsFlow(): Flow<List<Category>> | ||||
|   | ||||
| @@ -24,7 +24,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 | ||||
| @@ -45,7 +45,7 @@ fun LibraryContent( | ||||
|     onRefresh: (Category?) -> Boolean, | ||||
|     onGlobalSearchClicked: () -> Unit, | ||||
|     getNumberOfMangaForCategory: @Composable (Long) -> State<Int?>, | ||||
|     getDisplayModeForPage: @Composable (Int) -> State<DisplayModeSetting>, | ||||
|     getDisplayModeForPage: @Composable (Int) -> State<LibraryDisplayMode>, | ||||
|     getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>, | ||||
|     getLibraryForPage: @Composable (Int) -> State<List<LibraryItem>>, | ||||
| ) { | ||||
|   | ||||
| @@ -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<LibraryManga>, | ||||
|     searchQuery: String?, | ||||
|     onGlobalSearchClicked: () -> Unit, | ||||
|     getDisplayModeForPage: @Composable (Int) -> State<DisplayModeSetting>, | ||||
|     getDisplayModeForPage: @Composable (Int) -> State<LibraryDisplayMode>, | ||||
|     getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>, | ||||
|     getLibraryForPage: @Composable (Int) -> State<List<LibraryItem>>, | ||||
|     onClickManga: (LibraryManga) -> Unit, | ||||
| @@ -42,7 +42,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 | ||||
|  | ||||
| @@ -52,7 +52,7 @@ fun LibraryPager( | ||||
|         } | ||||
|  | ||||
|         when (displayMode) { | ||||
|             DisplayModeSetting.LIST -> { | ||||
|             LibraryDisplayMode.List -> { | ||||
|                 LibraryList( | ||||
|                     items = library, | ||||
|                     selection = selectedManga, | ||||
| @@ -62,7 +62,7 @@ fun LibraryPager( | ||||
|                     onGlobalSearchClicked = onGlobalSearchClicked, | ||||
|                 ) | ||||
|             } | ||||
|             DisplayModeSetting.COMPACT_GRID -> { | ||||
|             LibraryDisplayMode.CompactGrid -> { | ||||
|                 LibraryCompactGrid( | ||||
|                     items = library, | ||||
|                     columns = columns, | ||||
| @@ -73,7 +73,7 @@ fun LibraryPager( | ||||
|                     onGlobalSearchClicked = onGlobalSearchClicked, | ||||
|                 ) | ||||
|             } | ||||
|             DisplayModeSetting.COMFORTABLE_GRID -> { | ||||
|             LibraryDisplayMode.ComfortableGrid -> { | ||||
|                 LibraryComfortableGrid( | ||||
|                     items = library, | ||||
|                     columns = columns, | ||||
| @@ -84,7 +84,7 @@ fun LibraryPager( | ||||
|                     onGlobalSearchClicked = onGlobalSearchClicked, | ||||
|                 ) | ||||
|             } | ||||
|             DisplayModeSetting.COVER_ONLY_GRID -> { | ||||
|             LibraryDisplayMode.CoverOnlyGrid -> { | ||||
|                 LibraryCoverOnlyGrid( | ||||
|                     items = library, | ||||
|                     columns = columns, | ||||
|   | ||||
| @@ -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 | ||||
| @@ -196,33 +194,33 @@ 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) | ||||
|  | ||||
|                 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) { | ||||
| @@ -265,16 +263,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 | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -36,7 +36,6 @@ object PreferenceKeys { | ||||
|     const val filterTracked = "pref_filter_library_tracked" | ||||
|  | ||||
|     const val librarySortingMode = "library_sorting_mode" | ||||
|     const val librarySortingDirection = "library_sorting_ascending" | ||||
|  | ||||
|     const val migrationSortingMode = "pref_migration_sorting" | ||||
|     const val migrationSortingDirection = "pref_migration_direction" | ||||
|   | ||||
| @@ -12,9 +12,8 @@ import eu.kanade.tachiyomi.R | ||||
| 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.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.ReadingModeType | ||||
| import eu.kanade.tachiyomi.util.system.DeviceUtil | ||||
| @@ -169,7 +168,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)) | ||||
|  | ||||
| @@ -230,7 +229,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) | ||||
|  | ||||
| @@ -256,8 +255,7 @@ class PreferencesHelper(val context: Context) { | ||||
|  | ||||
|     fun filterTracking(name: Int) = flowPrefs.getInt("${Keys.filterTracked}_$name", 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) | ||||
|   | ||||
| @@ -37,7 +37,7 @@ import eu.kanade.tachiyomi.ui.base.controller.SearchableNucleusController | ||||
| import eu.kanade.tachiyomi.ui.base.controller.pushController | ||||
| 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 | ||||
| @@ -212,7 +212,7 @@ open class BrowseSourceController(bundle: Bundle) : | ||||
|             binding.catalogueView.removeView(oldRecycler) | ||||
|         } | ||||
|  | ||||
|         val recycler = if (preferences.sourceDisplayMode().get() == DisplayModeSetting.LIST) { | ||||
|         val recycler = if (preferences.sourceDisplayMode().get() == LibraryDisplayMode.List) { | ||||
|             RecyclerView(view.context).apply { | ||||
|                 id = R.id.recycler | ||||
|                 layoutManager = LinearLayoutManager(context) | ||||
| @@ -280,8 +280,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 | ||||
| @@ -304,9 +304,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() | ||||
|             R.id.action_local_source_help -> openLocalSourceHelpGuide() | ||||
|         } | ||||
| @@ -503,7 +503,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 | ||||
|  | ||||
|   | ||||
| @@ -10,16 +10,16 @@ import eu.kanade.domain.manga.model.Manga | ||||
| import eu.kanade.tachiyomi.R | ||||
| 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 | ||||
|  | ||||
| class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayModeSetting>) : | ||||
| class SourceItem(val manga: Manga, private val displayMode: Preference<LibraryDisplayMode>) : | ||||
|     AbstractFlexibleItem<SourceHolder<*>>() { | ||||
|  | ||||
|     override fun getLayoutRes(): Int { | ||||
|         return when (displayMode.get()) { | ||||
|             DisplayModeSetting.COMPACT_GRID, DisplayModeSetting.COVER_ONLY_GRID -> 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 | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -28,13 +28,13 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo | ||||
|         adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>, | ||||
|     ): SourceHolder<*> { | ||||
|         return when (displayMode.get()) { | ||||
|             DisplayModeSetting.COMPACT_GRID, DisplayModeSetting.COVER_ONLY_GRID -> { | ||||
|             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) | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -43,9 +43,10 @@ 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.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.removeCovers | ||||
| @@ -334,12 +335,8 @@ class LibraryPresenter( | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         val sortingModes = categories.associate { category -> | ||||
|             category.id to SortModeSetting.get(preferences, category) | ||||
|         } | ||||
|  | ||||
|         val sortDirections = categories.associate { category -> | ||||
|             category.id to SortDirectionSetting.get(category) | ||||
|         val sortModes = categories.associate { category -> | ||||
|             category.id to category.sort | ||||
|         } | ||||
|  | ||||
|         val locale = Locale.getDefault() | ||||
| @@ -347,53 +344,50 @@ class LibraryPresenter( | ||||
|             strength = Collator.PRIMARY | ||||
|         } | ||||
|         val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 -> | ||||
|             val sortingMode = sortingModes[i1.manga.category.toLong()]!! | ||||
|             val sortAscending = sortDirections[i1.manga.category.toLong()]!! == SortDirectionSetting.ASCENDING | ||||
|             when (sortingMode) { | ||||
|                 SortModeSetting.ALPHABETICAL -> { | ||||
|             val sort = sortModes[i1.manga.category.toLong()]!! | ||||
|             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) | ||||
|                 } | ||||
|                 else -> throw IllegalStateException("Invalid SortModeSetting: $sortingMode") | ||||
|                 else -> throw IllegalStateException("Invalid SortModeSetting: ${sort.type}") | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return map.mapValues { entry -> | ||||
|             val sortAscending = sortDirections[entry.key.toLong()]!! == SortDirectionSetting.ASCENDING | ||||
|  | ||||
|             val comparator = if (sortAscending) { | ||||
|             val comparator = if (sortModes[entry.key]!!.isAscending) { | ||||
|                 Comparator(sortFn) | ||||
|             } else { | ||||
|                 Collections.reverseOrder(sortFn) | ||||
| @@ -416,13 +410,6 @@ class LibraryPresenter( | ||||
|                 dbCategories | ||||
|             } | ||||
|  | ||||
|             libraryManga.forEach { (categoryId, libraryManga) -> | ||||
|                 val category = categories.first { category -> category.id == categoryId } | ||||
|                 libraryManga.forEach { libraryItem -> | ||||
|                     libraryItem.displayMode = category.displayMode | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             state.categories = categories | ||||
|             Library(categories, libraryManga) | ||||
|         }.asObservable() | ||||
| @@ -680,10 +667,10 @@ class LibraryPresenter( | ||||
|     } | ||||
|  | ||||
|     @Composable | ||||
|     fun getDisplayMode(index: Int): androidx.compose.runtime.State<DisplayModeSetting> { | ||||
|     fun getDisplayMode(index: Int): androidx.compose.runtime.State<LibraryDisplayMode> { | ||||
|         val category = categories[index] | ||||
|         return derivedStateOf { | ||||
|             DisplayModeSetting.fromFlag(category.displayMode) | ||||
|             category.display | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -11,9 +11,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 | ||||
| @@ -202,29 +203,25 @@ class LibrarySettingsSheet( | ||||
|             override val footer = null | ||||
|  | ||||
|             override fun initModels() { | ||||
|                 val sorting = SortModeSetting.get(preferences, currentCategory) | ||||
|                 val order = if (SortDirectionSetting.get(currentCategory) == SortDirectionSetting.ASCENDING) { | ||||
|                     Item.MultiSort.SORT_ASC | ||||
|                 } else { | ||||
|                     Item.MultiSort.SORT_DESC | ||||
|                 } | ||||
|                 val sort = currentCategory?.sort ?: LibrarySort.default | ||||
|                 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 | ||||
|             } | ||||
|  | ||||
|             override fun onItemClicked(item: Item) { | ||||
| @@ -249,20 +246,20 @@ 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 | ||||
|                     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 { | ||||
| @@ -297,12 +294,8 @@ class LibrarySettingsSheet( | ||||
|         } | ||||
|  | ||||
|         // Gets user preference of currently selected display mode at current category | ||||
|         private fun getDisplayModePreference(): DisplayModeSetting { | ||||
|             return if (currentCategory != null && preferences.categorizedDisplaySettings().get()) { | ||||
|                 DisplayModeSetting.fromFlag(currentCategory!!.displayMode) | ||||
|             } else { | ||||
|                 preferences.libraryDisplayMode().get() | ||||
|             } | ||||
|         private fun getDisplayModePreference(): LibraryDisplayMode { | ||||
|             return currentCategory?.display ?: LibraryDisplayMode.default | ||||
|         } | ||||
|  | ||||
|         inner class DisplayGroup : Group { | ||||
| @@ -334,19 +327,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") | ||||
|                 } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -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 | ||||
|     } | ||||
| } | ||||
| @@ -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<LibraryDisplayMode> { | ||||
|         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) | ||||
| @@ -0,0 +1,122 @@ | ||||
| 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) | ||||
|  | ||||
|         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<LibrarySort> { | ||||
|         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 | ||||
|                     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" | ||||
|         } | ||||
|         val direction = if (direction == Direction.Ascending) "ASCENDING" else "DESCENDING" | ||||
|         return "$type,$direction" | ||||
|     } | ||||
| } | ||||
|  | ||||
| val Category.sort: LibrarySort | ||||
|     get() = LibrarySort.valueOf(flags) | ||||
| @@ -1,20 +0,0 @@ | ||||
| package eu.kanade.tachiyomi.ui.library.setting | ||||
|  | ||||
| import eu.kanade.domain.category.model.Category | ||||
|  | ||||
| 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(category: Category?): SortDirectionSetting { | ||||
|             return fromFlag(category?.sortDirection) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,42 +0,0 @@ | ||||
| package eu.kanade.tachiyomi.ui.library.setting | ||||
|  | ||||
| import eu.kanade.domain.category.model.Category | ||||
| import eu.kanade.tachiyomi.data.preference.PreferencesHelper | ||||
|  | ||||
| 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), | ||||
|  | ||||
|     @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()) { | ||||
|                 fromFlag(category.sortMode) | ||||
|             } else { | ||||
|                 preferences.librarySortingMode().get() | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user