mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 14:27:57 +01:00 
			
		
		
		
	Move default category into database (#7676)
This commit is contained in:
		| @@ -64,6 +64,12 @@ class CategoryRepositoryImpl( | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     override suspend fun updateAllFlags(flags: Long?) { | ||||
|         handler.await { | ||||
|             categoriesQueries.updateAllFlags(flags) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override suspend fun delete(categoryId: Long) { | ||||
|         handler.await { | ||||
|             categoriesQueries.delete( | ||||
|   | ||||
| @@ -13,7 +13,10 @@ import eu.kanade.domain.category.interactor.DeleteCategory | ||||
| import eu.kanade.domain.category.interactor.GetCategories | ||||
| import eu.kanade.domain.category.interactor.RenameCategory | ||||
| import eu.kanade.domain.category.interactor.ReorderCategory | ||||
| import eu.kanade.domain.category.interactor.ResetCategoryFlags | ||||
| import eu.kanade.domain.category.interactor.SetDisplayModeForCategory | ||||
| import eu.kanade.domain.category.interactor.SetMangaCategories | ||||
| import eu.kanade.domain.category.interactor.SetSortModeForCategory | ||||
| import eu.kanade.domain.category.interactor.UpdateCategory | ||||
| import eu.kanade.domain.category.repository.CategoryRepository | ||||
| import eu.kanade.domain.chapter.interactor.GetChapter | ||||
| @@ -73,6 +76,9 @@ class DomainModule : InjektModule { | ||||
|     override fun InjektRegistrar.registerInjectables() { | ||||
|         addSingletonFactory<CategoryRepository> { CategoryRepositoryImpl(get()) } | ||||
|         addFactory { GetCategories(get()) } | ||||
|         addFactory { ResetCategoryFlags(get(), get()) } | ||||
|         addFactory { SetDisplayModeForCategory(get(), get()) } | ||||
|         addFactory { SetSortModeForCategory(get(), get()) } | ||||
|         addFactory { CreateCategoryWithName(get()) } | ||||
|         addFactory { RenameCategory(get()) } | ||||
|         addFactory { ReorderCategory(get()) } | ||||
|   | ||||
| @@ -13,7 +13,7 @@ class ReorderCategory( | ||||
| ) { | ||||
|  | ||||
|     suspend fun await(categoryId: Long, newPosition: Int) = withContext(NonCancellable) await@{ | ||||
|         val categories = categoryRepository.getAll() | ||||
|         val categories = categoryRepository.getAll().filterNot(Category::isSystemCategory) | ||||
|  | ||||
|         val currentIndex = categories.indexOfFirst { it.id == categoryId } | ||||
|         if (currentIndex == newPosition) { | ||||
|   | ||||
| @@ -0,0 +1,25 @@ | ||||
| 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 | ||||
|  | ||||
| class ResetCategoryFlags( | ||||
|     private val preferences: PreferencesHelper, | ||||
|     private val categoryRepository: CategoryRepository, | ||||
| ) { | ||||
|  | ||||
|     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) | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,28 @@ | ||||
| package eu.kanade.domain.category.interactor | ||||
|  | ||||
| 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 | ||||
|  | ||||
| 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) | ||||
|         if (preferences.categorizedDisplaySettings().get()) { | ||||
|             categoryRepository.updatePartial( | ||||
|                 CategoryUpdate( | ||||
|                     id = category.id, | ||||
|                     flags = flags, | ||||
|                 ), | ||||
|             ) | ||||
|         } else { | ||||
|             preferences.libraryDisplayMode().set(displayModeSetting) | ||||
|             categoryRepository.updateAllFlags(flags) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,49 @@ | ||||
| package eu.kanade.domain.category.interactor | ||||
|  | ||||
| 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 | ||||
|  | ||||
| class SetSortModeForCategory( | ||||
|     private val preferences: PreferencesHelper, | ||||
|     private val categoryRepository: CategoryRepository, | ||||
| ) { | ||||
|  | ||||
|     suspend fun await(category: Category, sortDirectionSetting: SortDirectionSetting) { | ||||
|         val sort = if (preferences.categorizedDisplaySettings().get()) { | ||||
|             SortModeSetting.fromFlag(category.flags) | ||||
|         } else { | ||||
|             preferences.librarySortingMode().get() | ||||
|         } | ||||
|         await(category, sort, sortDirectionSetting) | ||||
|     } | ||||
|  | ||||
|     suspend fun await(category: Category, sortModeSetting: SortModeSetting) { | ||||
|         val direction = if (preferences.categorizedDisplaySettings().get()) { | ||||
|             SortDirectionSetting.fromFlag(category.flags) | ||||
|         } else { | ||||
|             preferences.librarySortingAscending().get() | ||||
|         } | ||||
|         await(category, sortModeSetting, direction) | ||||
|     } | ||||
|  | ||||
|     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) | ||||
|         if (preferences.categorizedDisplaySettings().get()) { | ||||
|             categoryRepository.updatePartial( | ||||
|                 CategoryUpdate( | ||||
|                     id = category.id, | ||||
|                     flags = flags, | ||||
|                 ), | ||||
|             ) | ||||
|         } else { | ||||
|             preferences.librarySortingMode().set(sortModeSetting) | ||||
|             preferences.librarySortingAscending().set(sortDirectionSetting) | ||||
|             categoryRepository.updateAllFlags(flags) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,13 +1,9 @@ | ||||
| package eu.kanade.domain.category.model | ||||
|  | ||||
| import android.content.Context | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.database.models.CategoryImpl | ||||
| import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting | ||||
| import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting | ||||
| import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting | ||||
| import java.io.Serializable | ||||
| import eu.kanade.tachiyomi.data.database.models.Category as DbCategory | ||||
|  | ||||
| data class Category( | ||||
|     val id: Long, | ||||
| @@ -16,6 +12,8 @@ data class Category( | ||||
|     val flags: Long, | ||||
| ) : Serializable { | ||||
|  | ||||
|     val isSystemCategory: Boolean = id == UNCATEGORIZED_ID | ||||
|  | ||||
|     val displayMode: Long | ||||
|         get() = flags and DisplayModeSetting.MASK | ||||
|  | ||||
| @@ -26,24 +24,11 @@ data class Category( | ||||
|         get() = flags and SortDirectionSetting.MASK | ||||
|  | ||||
|     companion object { | ||||
|         val default = { context: Context -> | ||||
|             Category( | ||||
|                 id = 0, | ||||
|                 name = context.getString(R.string.label_default), | ||||
|                 order = 0, | ||||
|                 flags = 0, | ||||
|             ) | ||||
|         } | ||||
|  | ||||
|         const val UNCATEGORIZED_ID = 0L | ||||
|     } | ||||
| } | ||||
|  | ||||
| internal fun List<Category>.anyWithName(name: String): Boolean { | ||||
|     return any { name.equals(it.name, ignoreCase = true) } | ||||
| } | ||||
|  | ||||
| fun Category.toDbCategory(): DbCategory = CategoryImpl().also { | ||||
|     it.name = name | ||||
|     it.id = id.toInt() | ||||
|     it.order = order.toInt() | ||||
|     it.flags = flags.toInt() | ||||
| } | ||||
|   | ||||
| @@ -20,5 +20,7 @@ interface CategoryRepository { | ||||
|  | ||||
|     suspend fun updatePartial(updates: List<CategoryUpdate>) | ||||
|  | ||||
|     suspend fun updateAllFlags(flags: Long?) | ||||
|  | ||||
|     suspend fun delete(categoryId: Long) | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,20 @@ | ||||
| package eu.kanade.presentation.category | ||||
|  | ||||
| import android.content.Context | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.ui.res.stringResource | ||||
| import eu.kanade.domain.category.model.Category | ||||
| import eu.kanade.tachiyomi.R | ||||
|  | ||||
| val Category.visualName: String | ||||
|     @Composable | ||||
|     get() = when (id) { | ||||
|         Category.UNCATEGORIZED_ID -> stringResource(id = R.string.label_default) | ||||
|         else -> name | ||||
|     } | ||||
|  | ||||
| fun Category.visualName(context: Context): String = | ||||
|     when (id) { | ||||
|         Category.UNCATEGORIZED_ID -> context.getString(R.string.label_default) | ||||
|         else -> name | ||||
|     } | ||||
| @@ -23,6 +23,7 @@ import androidx.compose.ui.unit.dp | ||||
| import androidx.compose.ui.unit.sp | ||||
| import com.google.accompanist.pager.PagerState | ||||
| import eu.kanade.domain.category.model.Category | ||||
| import eu.kanade.presentation.category.visualName | ||||
| import eu.kanade.presentation.components.DownloadedOnlyModeBanner | ||||
| import eu.kanade.presentation.components.IncognitoModeBanner | ||||
| import eu.kanade.presentation.components.Pill | ||||
| @@ -67,7 +68,7 @@ fun LibraryTabs( | ||||
|                             verticalAlignment = Alignment.CenterVertically, | ||||
|                         ) { | ||||
|                             Text( | ||||
|                                 text = category.name, | ||||
|                                 text = category.visualName, | ||||
|                                 color = if (state.currentPage == index) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground, | ||||
|                             ) | ||||
|                             if (count != null) { | ||||
|   | ||||
| @@ -5,6 +5,8 @@ import android.net.Uri | ||||
| import com.hippo.unifile.UniFile | ||||
| import data.Manga_sync | ||||
| import data.Mangas | ||||
| import eu.kanade.data.category.categoryMapper | ||||
| import eu.kanade.domain.category.model.Category | ||||
| import eu.kanade.domain.history.model.HistoryUpdate | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.backup.AbstractBackupManager | ||||
| @@ -138,7 +140,9 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) { | ||||
|     private suspend fun backupCategories(options: Int): List<BackupCategory> { | ||||
|         // Check if user wants category information in backup | ||||
|         return if (options and BACKUP_CATEGORY_MASK == BACKUP_CATEGORY) { | ||||
|             handler.awaitList { categoriesQueries.getCategories(backupCategoryMapper) } | ||||
|             handler.awaitList { categoriesQueries.getCategories(categoryMapper) } | ||||
|                 .filterNot(Category::isSystemCategory) | ||||
|                 .map(backupCategoryMapper) | ||||
|         } else { | ||||
|             emptyList() | ||||
|         } | ||||
| @@ -224,34 +228,37 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) { | ||||
|      */ | ||||
|     internal suspend fun restoreCategories(backupCategories: List<BackupCategory>) { | ||||
|         // Get categories from file and from db | ||||
|         val dbCategories = handler.awaitList { categoriesQueries.getCategories() } | ||||
|         val dbCategories = handler.awaitList { categoriesQueries.getCategories(categoryMapper) } | ||||
|  | ||||
|         // Iterate over them | ||||
|         backupCategories | ||||
|             .map { it.getCategoryImpl() } | ||||
|             .forEach { category -> | ||||
|                 // Used to know if the category is already in the db | ||||
|                 var found = false | ||||
|                 for (dbCategory in dbCategories) { | ||||
|                     // If the category is already in the db, assign the id to the file's category | ||||
|                     // and do nothing | ||||
|                     if (category.name == dbCategory.name) { | ||||
|                         category.id = dbCategory.id.toInt() | ||||
|                         found = true | ||||
|                         break | ||||
|                     } | ||||
|                 } | ||||
|                 // If the category isn't in the db, remove the id and insert a new category | ||||
|                 // Store the inserted id in the category | ||||
|                 if (!found) { | ||||
|                     // Let the db assign the id | ||||
|                     category.id = null | ||||
|                     category.id = handler.awaitOne { | ||||
|                         categoriesQueries.insert(category.name, category.order.toLong(), category.flags.toLong()) | ||||
|                         categoriesQueries.selectLastInsertedRowId() | ||||
|                     }.toInt() | ||||
|         val categories = backupCategories.map { | ||||
|             var category = it.getCategory() | ||||
|             var found = false | ||||
|             for (dbCategory in dbCategories) { | ||||
|                 // If the category is already in the db, assign the id to the file's category | ||||
|                 // and do nothing | ||||
|                 if (category.name == dbCategory.name) { | ||||
|                     category = category.copy(id = dbCategory.id) | ||||
|                     found = true | ||||
|                     break | ||||
|                 } | ||||
|             } | ||||
|             if (!found) { | ||||
|                 // Let the db assign the id | ||||
|                 val id = handler.awaitOne { | ||||
|                     categoriesQueries.insert(category.name, category.order, category.flags) | ||||
|                     categoriesQueries.selectLastInsertedRowId() | ||||
|                 } | ||||
|                 category = category.copy(id = id) | ||||
|             } | ||||
|  | ||||
|             category | ||||
|         } | ||||
|  | ||||
|         preferences.categorizedDisplaySettings().set( | ||||
|             (dbCategories + categories) | ||||
|                 .distinctBy { it.flags } | ||||
|                 .size > 1, | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| package eu.kanade.tachiyomi.data.backup.full.models | ||||
|  | ||||
| import eu.kanade.tachiyomi.data.database.models.CategoryImpl | ||||
| import eu.kanade.domain.category.model.Category | ||||
| import kotlinx.serialization.Serializable | ||||
| import kotlinx.serialization.protobuf.ProtoNumber | ||||
|  | ||||
| @@ -12,19 +12,20 @@ class BackupCategory( | ||||
|     // Bump by 100 to specify this is a 0.x value | ||||
|     @ProtoNumber(100) var flags: Long = 0, | ||||
| ) { | ||||
|     fun getCategoryImpl(): CategoryImpl { | ||||
|         return CategoryImpl().apply { | ||||
|             name = this@BackupCategory.name | ||||
|             flags = this@BackupCategory.flags.toInt() | ||||
|             order = this@BackupCategory.order.toInt() | ||||
|         } | ||||
|     fun getCategory(): Category { | ||||
|         return Category( | ||||
|             id = 0, | ||||
|             name = this@BackupCategory.name, | ||||
|             flags = this@BackupCategory.flags, | ||||
|             order = this@BackupCategory.order, | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|  | ||||
| val backupCategoryMapper = { _: Long, name: String, order: Long, flags: Long -> | ||||
| val backupCategoryMapper = { category: Category -> | ||||
|     BackupCategory( | ||||
|         name = name, | ||||
|         order = order, | ||||
|         flags = flags, | ||||
|         name = category.name, | ||||
|         order = category.order, | ||||
|         flags = category.flags, | ||||
|     ) | ||||
| } | ||||
|   | ||||
| @@ -1,44 +0,0 @@ | ||||
| package eu.kanade.tachiyomi.data.database.models | ||||
|  | ||||
| import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting | ||||
| import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting | ||||
| import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting | ||||
| import java.io.Serializable | ||||
| import eu.kanade.domain.category.model.Category as DomainCategory | ||||
|  | ||||
| interface Category : Serializable { | ||||
|  | ||||
|     var id: Int? | ||||
|  | ||||
|     var name: String | ||||
|  | ||||
|     var order: Int | ||||
|  | ||||
|     var flags: Int | ||||
|  | ||||
|     private fun setFlags(flag: Int, mask: Int) { | ||||
|         flags = flags and mask.inv() or (flag and mask) | ||||
|     } | ||||
|  | ||||
|     var displayMode: Int | ||||
|         get() = flags and DisplayModeSetting.MASK.toInt() | ||||
|         set(mode) = setFlags(mode, DisplayModeSetting.MASK.toInt()) | ||||
|  | ||||
|     var sortMode: Int | ||||
|         get() = flags and SortModeSetting.MASK.toInt() | ||||
|         set(mode) = setFlags(mode, SortModeSetting.MASK.toInt()) | ||||
|  | ||||
|     var sortDirection: Int | ||||
|         get() = flags and SortDirectionSetting.MASK.toInt() | ||||
|         set(mode) = setFlags(mode, SortDirectionSetting.MASK.toInt()) | ||||
| } | ||||
|  | ||||
| fun Category.toDomainCategory(): DomainCategory? { | ||||
|     val categoryId = id ?: return null | ||||
|     return DomainCategory( | ||||
|         id = categoryId.toLong(), | ||||
|         name = this.name, | ||||
|         order = this.order.toLong(), | ||||
|         flags = this.flags.toLong(), | ||||
|     ) | ||||
| } | ||||
| @@ -1,24 +0,0 @@ | ||||
| package eu.kanade.tachiyomi.data.database.models | ||||
|  | ||||
| class CategoryImpl : Category { | ||||
|  | ||||
|     override var id: Int? = null | ||||
|  | ||||
|     override lateinit var name: String | ||||
|  | ||||
|     override var order: Int = 0 | ||||
|  | ||||
|     override var flags: Int = 0 | ||||
|  | ||||
|     override fun equals(other: Any?): Boolean { | ||||
|         if (this === other) return true | ||||
|         if (other == null || javaClass != other.javaClass) return false | ||||
|  | ||||
|         val category = other as Category | ||||
|         return name == category.name | ||||
|     } | ||||
|  | ||||
|     override fun hashCode(): Int { | ||||
|         return name.hashCode() | ||||
|     } | ||||
| } | ||||
| @@ -35,7 +35,7 @@ class CategoryPresenter( | ||||
|             getCategories.subscribe() | ||||
|                 .collectLatest { | ||||
|                     state.isLoading = false | ||||
|                     state.categories = it | ||||
|                     state.categories = it.filterNot(Category::isSystemCategory) | ||||
|                 } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -9,7 +9,6 @@ import androidx.compose.ui.platform.LocalContext | ||||
| import com.bluelinelabs.conductor.ControllerChangeHandler | ||||
| import com.bluelinelabs.conductor.ControllerChangeType | ||||
| import eu.kanade.domain.category.model.Category | ||||
| import eu.kanade.domain.category.model.toDbCategory | ||||
| import eu.kanade.domain.manga.model.Manga | ||||
| import eu.kanade.domain.manga.model.toDbManga | ||||
| import eu.kanade.presentation.library.LibraryScreen | ||||
| @@ -119,12 +118,8 @@ class LibraryController( | ||||
|     } | ||||
|  | ||||
|     fun showSettingsSheet() { | ||||
|         if (presenter.categories.isNotEmpty()) { | ||||
|             presenter.categories[presenter.activeCategory].let { category -> | ||||
|                 settingsSheet?.show(category.toDbCategory()) | ||||
|             } | ||||
|         } else { | ||||
|             settingsSheet?.show() | ||||
|         presenter.categories[presenter.activeCategory].let { category -> | ||||
|             settingsSheet?.show(category) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -27,6 +27,7 @@ import eu.kanade.domain.manga.model.Manga | ||||
| import eu.kanade.domain.manga.model.MangaUpdate | ||||
| import eu.kanade.domain.manga.model.isLocal | ||||
| import eu.kanade.domain.track.interactor.GetTracks | ||||
| import eu.kanade.presentation.category.visualName | ||||
| import eu.kanade.presentation.library.LibraryState | ||||
| import eu.kanade.presentation.library.LibraryStateImpl | ||||
| import eu.kanade.presentation.library.components.LibraryToolbarTitle | ||||
| @@ -94,15 +95,9 @@ class LibraryPresenter( | ||||
|     private val trackManager: TrackManager = Injekt.get(), | ||||
| ) : BasePresenter<LibraryController>(), LibraryState by state { | ||||
|  | ||||
|     private val context = preferences.context | ||||
|  | ||||
|     var loadedManga by mutableStateOf(emptyMap<Long, List<LibraryItem>>()) | ||||
|         private set | ||||
|  | ||||
|     val isPerCategory by preferences.categorizedDisplaySettings().asState() | ||||
|  | ||||
|     var currentDisplayMode by preferences.libraryDisplayMode().asState() | ||||
|  | ||||
|     val tabVisibility by preferences.categoryTabs().asState() | ||||
|  | ||||
|     val mangaCountVisibility by preferences.categoryNumberOfItems().asState() | ||||
| @@ -412,8 +407,8 @@ class LibraryPresenter( | ||||
|      */ | ||||
|     private fun getLibraryObservable(): Observable<Library> { | ||||
|         return combine(getCategoriesFlow(), getLibraryMangasFlow()) { dbCategories, libraryManga -> | ||||
|             val categories = if (libraryManga.containsKey(0) || libraryManga.isEmpty()) { | ||||
|                 arrayListOf(Category.default(context)) + dbCategories | ||||
|             val categories = if (libraryManga.isNotEmpty() && libraryManga.containsKey(0).not()) { | ||||
|                 dbCategories.filterNot { it.id == Category.UNCATEGORIZED_ID } | ||||
|             } else { | ||||
|                 dbCategories | ||||
|             } | ||||
| @@ -642,10 +637,12 @@ class LibraryPresenter( | ||||
|         val category = categories.getOrNull(activeCategory) | ||||
|  | ||||
|         val defaultTitle = stringResource(id = R.string.label_library) | ||||
|         val categoryName = category?.visualName ?: defaultTitle | ||||
|  | ||||
|         val default = remember { LibraryToolbarTitle(defaultTitle) } | ||||
|  | ||||
|         return produceState(initialValue = default, category, loadedManga, mangaCountVisibility, tabVisibility) { | ||||
|             val title = if (tabVisibility.not()) category?.name ?: defaultTitle else defaultTitle | ||||
|             val title = if (tabVisibility.not()) categoryName else defaultTitle | ||||
|  | ||||
|             value = when { | ||||
|                 category == null -> default | ||||
| @@ -681,11 +678,7 @@ class LibraryPresenter( | ||||
|     fun getDisplayMode(index: Int): androidx.compose.runtime.State<DisplayModeSetting> { | ||||
|         val category = categories[index] | ||||
|         return derivedStateOf { | ||||
|             if (isPerCategory.not() || category.id == 0L) { | ||||
|                 currentDisplayMode | ||||
|             } else { | ||||
|                 DisplayModeSetting.fromFlag(category.displayMode) | ||||
|             } | ||||
|             DisplayModeSetting.fromFlag(category.displayMode) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -4,11 +4,10 @@ import android.content.Context | ||||
| import android.util.AttributeSet | ||||
| import android.view.View | ||||
| import com.bluelinelabs.conductor.Router | ||||
| import eu.kanade.domain.category.interactor.UpdateCategory | ||||
| import eu.kanade.domain.category.model.CategoryUpdate | ||||
| import eu.kanade.domain.category.interactor.SetDisplayModeForCategory | ||||
| import eu.kanade.domain.category.interactor.SetSortModeForCategory | ||||
| import eu.kanade.domain.category.model.Category | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.database.models.Category | ||||
| import eu.kanade.tachiyomi.data.database.models.toDomainCategory | ||||
| import eu.kanade.tachiyomi.data.preference.PreferencesHelper | ||||
| import eu.kanade.tachiyomi.data.track.TrackManager | ||||
| import eu.kanade.tachiyomi.data.track.TrackService | ||||
| @@ -29,7 +28,8 @@ import uy.kohesive.injekt.injectLazy | ||||
| class LibrarySettingsSheet( | ||||
|     router: Router, | ||||
|     private val trackManager: TrackManager = Injekt.get(), | ||||
|     private val updateCategory: UpdateCategory = Injekt.get(), | ||||
|     private val setDisplayModeForCategory: SetDisplayModeForCategory = Injekt.get(), | ||||
|     private val setSortModeForCategory: SetSortModeForCategory = Injekt.get(), | ||||
|     onGroupClickListener: (ExtendedNavigationView.Group) -> Unit, | ||||
| ) : TabbedBottomSheetDialog(router.activity!!) { | ||||
|  | ||||
| @@ -202,8 +202,8 @@ class LibrarySettingsSheet( | ||||
|             override val footer = null | ||||
|  | ||||
|             override fun initModels() { | ||||
|                 val sorting = SortModeSetting.get(preferences, currentCategory?.toDomainCategory()) | ||||
|                 val order = if (SortDirectionSetting.get(preferences, currentCategory?.toDomainCategory()) == SortDirectionSetting.ASCENDING) { | ||||
|                 val sorting = SortModeSetting.get(preferences, currentCategory) | ||||
|                 val order = if (SortDirectionSetting.get(preferences, currentCategory) == SortDirectionSetting.ASCENDING) { | ||||
|                     Item.MultiSort.SORT_ASC | ||||
|                 } else { | ||||
|                     Item.MultiSort.SORT_DESC | ||||
| @@ -256,18 +256,8 @@ class LibrarySettingsSheet( | ||||
|                     SortDirectionSetting.DESCENDING | ||||
|                 } | ||||
|  | ||||
|                 if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { | ||||
|                     currentCategory?.sortDirection = flag.flag.toInt() | ||||
|                     sheetScope.launchIO { | ||||
|                         updateCategory.await( | ||||
|                             CategoryUpdate( | ||||
|                                 id = currentCategory!!.id?.toLong()!!, | ||||
|                                 flags = currentCategory!!.flags.toLong(), | ||||
|                             ), | ||||
|                         ) | ||||
|                     } | ||||
|                 } else { | ||||
|                     preferences.librarySortingAscending().set(flag) | ||||
|                 sheetScope.launchIO { | ||||
|                     setSortModeForCategory.await(currentCategory!!, flag) | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @@ -284,18 +274,8 @@ class LibrarySettingsSheet( | ||||
|                     else -> throw NotImplementedError("Unknown display mode") | ||||
|                 } | ||||
|  | ||||
|                 if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { | ||||
|                     currentCategory?.sortMode = flag.flag.toInt() | ||||
|                     sheetScope.launchIO { | ||||
|                         updateCategory.await( | ||||
|                             CategoryUpdate( | ||||
|                                 id = currentCategory!!.id?.toLong()!!, | ||||
|                                 flags = currentCategory!!.flags.toLong(), | ||||
|                             ), | ||||
|                         ) | ||||
|                     } | ||||
|                 } else { | ||||
|                     preferences.librarySortingMode().set(flag) | ||||
|                 sheetScope.launchIO { | ||||
|                     setSortModeForCategory.await(currentCategory!!, flag) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -327,8 +307,8 @@ class LibrarySettingsSheet( | ||||
|  | ||||
|         // Gets user preference of currently selected display mode at current category | ||||
|         private fun getDisplayModePreference(): DisplayModeSetting { | ||||
|             return if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { | ||||
|                 DisplayModeSetting.fromFlag(currentCategory?.displayMode?.toLong()) | ||||
|             return if (currentCategory != null && preferences.categorizedDisplaySettings().get()) { | ||||
|                 DisplayModeSetting.fromFlag(currentCategory!!.displayMode) | ||||
|             } else { | ||||
|                 preferences.libraryDisplayMode().get() | ||||
|             } | ||||
| @@ -379,18 +359,8 @@ class LibrarySettingsSheet( | ||||
|                     else -> throw NotImplementedError("Unknown display mode") | ||||
|                 } | ||||
|  | ||||
|                 if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { | ||||
|                     currentCategory?.displayMode = flag.flag.toInt() | ||||
|                     sheetScope.launchIO { | ||||
|                         updateCategory.await( | ||||
|                             CategoryUpdate( | ||||
|                                 id = currentCategory!!.id?.toLong()!!, | ||||
|                                 flags = currentCategory!!.flags.toLong(), | ||||
|                             ), | ||||
|                         ) | ||||
|                     } | ||||
|                 } else { | ||||
|                     preferences.libraryDisplayMode().set(flag) | ||||
|                 sheetScope.launchIO { | ||||
|                     setDisplayModeForCategory.await(currentCategory!!, flag) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -32,7 +32,7 @@ enum class SortModeSetting(val flag: Long) { | ||||
|         } | ||||
|  | ||||
|         fun get(preferences: PreferencesHelper, category: Category?): SortModeSetting { | ||||
|             return if (preferences.categorizedDisplaySettings().get() && category != null && category.id != 0L) { | ||||
|             return if (category != null && preferences.categorizedDisplaySettings().get()) { | ||||
|                 fromFlag(category.sortMode) | ||||
|             } else { | ||||
|                 preferences.librarySortingMode().get() | ||||
|   | ||||
| @@ -12,7 +12,7 @@ import androidx.preference.PreferenceScreen | ||||
| import com.google.android.material.dialog.MaterialAlertDialogBuilder | ||||
| import com.hippo.unifile.UniFile | ||||
| import eu.kanade.domain.category.interactor.GetCategories | ||||
| import eu.kanade.domain.category.model.Category | ||||
| import eu.kanade.presentation.category.visualName | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.preference.PreferencesHelper | ||||
| import eu.kanade.tachiyomi.ui.base.controller.DialogController | ||||
| @@ -46,8 +46,7 @@ class SettingsDownloadController : SettingsController() { | ||||
|     override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply { | ||||
|         titleRes = R.string.pref_category_downloads | ||||
|  | ||||
|         val dbCategories = runBlocking { getCategories.await() } | ||||
|         val categories = listOf(Category.default(context)) + dbCategories | ||||
|         val categories = runBlocking { getCategories.await() } | ||||
|  | ||||
|         preference { | ||||
|             bindTo(preferences.downloadsDirectory()) | ||||
| @@ -111,7 +110,7 @@ class SettingsDownloadController : SettingsController() { | ||||
|             multiSelectListPreference { | ||||
|                 bindTo(preferences.removeExcludeCategories()) | ||||
|                 titleRes = R.string.pref_remove_exclude_categories | ||||
|                 entries = categories.map { it.name }.toTypedArray() | ||||
|                 entries = categories.map { it.visualName(context) }.toTypedArray() | ||||
|                 entryValues = categories.map { it.id.toString() }.toTypedArray() | ||||
|  | ||||
|                 preferences.removeExcludeCategories().asFlow() | ||||
| @@ -255,10 +254,9 @@ class SettingsDownloadController : SettingsController() { | ||||
|         private val getCategories: GetCategories = Injekt.get() | ||||
|  | ||||
|         override fun onCreateDialog(savedViewState: Bundle?): Dialog { | ||||
|             val dbCategories = runBlocking { getCategories.await() } | ||||
|             val categories = listOf(Category.default(activity!!)) + dbCategories | ||||
|             val categories = runBlocking { getCategories.await() } | ||||
|  | ||||
|             val items = categories.map { it.name } | ||||
|             val items = categories.map { it.visualName(activity!!) } | ||||
|             var selected = categories | ||||
|                 .map { | ||||
|                     when (it.id.toString()) { | ||||
|   | ||||
| @@ -8,7 +8,9 @@ import androidx.core.text.buildSpannedString | ||||
| import androidx.preference.PreferenceScreen | ||||
| import com.google.android.material.dialog.MaterialAlertDialogBuilder | ||||
| import eu.kanade.domain.category.interactor.GetCategories | ||||
| import eu.kanade.domain.category.interactor.ResetCategoryFlags | ||||
| import eu.kanade.domain.category.model.Category | ||||
| import eu.kanade.presentation.category.visualName | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.library.LibraryUpdateJob | ||||
| import eu.kanade.tachiyomi.data.preference.DEVICE_BATTERY_NOT_LOW | ||||
| @@ -51,12 +53,13 @@ class SettingsLibraryController : SettingsController() { | ||||
|  | ||||
|     private val getCategories: GetCategories by injectLazy() | ||||
|     private val trackManager: TrackManager by injectLazy() | ||||
|     private val resetCategoryFlags: ResetCategoryFlags by injectLazy() | ||||
|  | ||||
|     override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply { | ||||
|         titleRes = R.string.pref_category_library | ||||
|  | ||||
|         val dbCategories = runBlocking { getCategories.await() } | ||||
|         val categories = listOf(Category.default(context)) + dbCategories | ||||
|         val allCategories = runBlocking { getCategories.await() } | ||||
|         val userCategories = allCategories.filterNot(Category::isSystemCategory) | ||||
|  | ||||
|         preferenceCategory { | ||||
|             titleRes = R.string.pref_category_display | ||||
| @@ -94,7 +97,7 @@ class SettingsLibraryController : SettingsController() { | ||||
|                 key = "pref_action_edit_categories" | ||||
|                 titleRes = R.string.action_edit_categories | ||||
|  | ||||
|                 val catCount = dbCategories.size | ||||
|                 val catCount = userCategories.size | ||||
|                 summary = context.resources.getQuantityString(R.plurals.num_categories, catCount, catCount) | ||||
|  | ||||
|                 onClick { | ||||
| @@ -107,15 +110,15 @@ class SettingsLibraryController : SettingsController() { | ||||
|                 titleRes = R.string.default_category | ||||
|  | ||||
|                 entries = arrayOf(context.getString(R.string.default_category_summary)) + | ||||
|                     categories.map { it.name }.toTypedArray() | ||||
|                 entryValues = arrayOf("-1") + categories.map { it.id.toString() }.toTypedArray() | ||||
|                     allCategories.map { it.visualName(context) }.toTypedArray() | ||||
|                 entryValues = arrayOf("-1") + allCategories.map { it.id.toString() }.toTypedArray() | ||||
|                 defaultValue = "-1" | ||||
|  | ||||
|                 val selectedCategory = categories.find { it.id == preferences.defaultCategory().toLong() } | ||||
|                 val selectedCategory = allCategories.find { it.id == preferences.defaultCategory().toLong() } | ||||
|                 summary = selectedCategory?.name | ||||
|                     ?: context.getString(R.string.default_category_summary) | ||||
|                 onChange { newValue -> | ||||
|                     summary = categories.find { | ||||
|                     summary = allCategories.find { | ||||
|                         it.id == (newValue as String).toLong() | ||||
|                     }?.name ?: context.getString(R.string.default_category_summary) | ||||
|                     true | ||||
| @@ -125,6 +128,14 @@ class SettingsLibraryController : SettingsController() { | ||||
|             switchPreference { | ||||
|                 bindTo(preferences.categorizedDisplaySettings()) | ||||
|                 titleRes = R.string.categorized_display_settings | ||||
|  | ||||
|                 preferences.categorizedDisplaySettings().asFlow() | ||||
|                     .onEach { | ||||
|                         if (it.not()) { | ||||
|                             resetCategoryFlags.await() | ||||
|                         } | ||||
|                     } | ||||
|                     .launchIn(viewScope) | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -229,19 +240,19 @@ class SettingsLibraryController : SettingsController() { | ||||
|  | ||||
|                 fun updateSummary() { | ||||
|                     val includedCategories = preferences.libraryUpdateCategories().get() | ||||
|                         .mapNotNull { id -> categories.find { it.id == id.toLong() } } | ||||
|                         .mapNotNull { id -> allCategories.find { it.id == id.toLong() } } | ||||
|                         .sortedBy { it.order } | ||||
|                     val excludedCategories = preferences.libraryUpdateCategoriesExclude().get() | ||||
|                         .mapNotNull { id -> categories.find { it.id == id.toLong() } } | ||||
|                         .mapNotNull { id -> allCategories.find { it.id == id.toLong() } } | ||||
|                         .sortedBy { it.order } | ||||
|  | ||||
|                     val allExcluded = excludedCategories.size == categories.size | ||||
|                     val allExcluded = excludedCategories.size == allCategories.size | ||||
|  | ||||
|                     val includedItemsText = when { | ||||
|                         // Some selected, but not all | ||||
|                         includedCategories.isNotEmpty() && includedCategories.size != categories.size -> includedCategories.joinToString { it.name } | ||||
|                         includedCategories.isNotEmpty() && includedCategories.size != allCategories.size -> includedCategories.joinToString { it.name } | ||||
|                         // All explicitly selected | ||||
|                         includedCategories.size == categories.size -> context.getString(R.string.all) | ||||
|                         includedCategories.size == allCategories.size -> context.getString(R.string.all) | ||||
|                         allExcluded -> context.getString(R.string.none) | ||||
|                         else -> context.getString(R.string.all) | ||||
|                     } | ||||
| @@ -331,10 +342,9 @@ class SettingsLibraryController : SettingsController() { | ||||
|         private val getCategories: GetCategories = Injekt.get() | ||||
|  | ||||
|         override fun onCreateDialog(savedViewState: Bundle?): Dialog { | ||||
|             val dbCategories = runBlocking { getCategories.await() } | ||||
|             val categories = listOf(Category.default(activity!!)) + dbCategories | ||||
|             val categories = runBlocking { getCategories.await() } | ||||
|  | ||||
|             val items = categories.map { it.name } | ||||
|             val items = categories.map { it.visualName(activity!!) } | ||||
|             var selected = categories | ||||
|                 .map { | ||||
|                     when (it.id.toString()) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user