Skip to content

Commit

Permalink
feat: Hidden categories (#348)
Browse files Browse the repository at this point in the history
* support hide categories (merged from Aniyomi)

* styling CategoryScreen: always showing all categories & shading the hidden one

* Hide categories directly on Library tab and load it as a flow

* fix: hidden categories got reset after delete/reorder

* remove unnecessary code
  • Loading branch information
cuong-tran authored Sep 11, 2024
1 parent 4a2f8a7 commit 6c9dfb8
Show file tree
Hide file tree
Showing 21 changed files with 201 additions and 13 deletions.
4 changes: 4 additions & 0 deletions app/src/main/java/eu/kanade/domain/DomainModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import tachiyomi.data.updates.UpdatesRepositoryImpl
import tachiyomi.domain.category.interactor.CreateCategoryWithName
import tachiyomi.domain.category.interactor.DeleteCategory
import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.interactor.HideCategory
import tachiyomi.domain.category.interactor.RenameCategory
import tachiyomi.domain.category.interactor.ReorderCategory
import tachiyomi.domain.category.interactor.ResetCategoryFlags
Expand Down Expand Up @@ -110,6 +111,9 @@ class DomainModule : InjektModule {
addFactory { ReorderCategory(get()) }
addFactory { UpdateCategory(get()) }
addFactory { DeleteCategory(get()) }
// KMK -->
addFactory { HideCategory(get()) }
// KMK <--

addSingletonFactory<MangaRepository> { MangaRepositoryImpl(get()) }
addFactory { GetDuplicateLibraryManga(get()) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ fun CategoryScreen(
onClickDelete: (Category) -> Unit,
onClickMoveUp: (Category) -> Unit,
onClickMoveDown: (Category) -> Unit,
// KMK -->
onClickHide: (Category) -> Unit,
// KMK <--
navigateUp: () -> Unit,
) {
val lazyListState = rememberLazyListState()
Expand Down Expand Up @@ -83,6 +86,9 @@ fun CategoryScreen(
onClickDelete = onClickDelete,
onMoveUp = onClickMoveUp,
onMoveDown = onClickMoveDown,
// KMK -->
onClickHide = onClickHide,
// KMK <--
)
}
}
Expand All @@ -96,6 +102,9 @@ private fun CategoryContent(
onClickDelete: (Category) -> Unit,
onMoveUp: (Category) -> Unit,
onMoveDown: (Category) -> Unit,
// KMK -->
onClickHide: (Category) -> Unit,
// KMK <--
) {
LazyColumn(
state = lazyListState,
Expand All @@ -115,6 +124,9 @@ private fun CategoryContent(
onMoveDown = onMoveDown,
onRename = { onClickRename(category) },
onDelete = { onClickDelete(category) },
// KMK -->
onHide = { onClickHide(category) },
// KMK <--
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,21 @@ import androidx.compose.material.icons.outlined.ArrowDropDown
import androidx.compose.material.icons.outlined.ArrowDropUp
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.Edit
import androidx.compose.material.icons.outlined.Visibility
import androidx.compose.material.icons.outlined.VisibilityOff
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextDecoration
import tachiyomi.domain.category.model.Category
import tachiyomi.i18n.MR
import tachiyomi.i18n.kmk.KMR
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource

Expand All @@ -33,6 +38,9 @@ fun CategoryListItem(
onMoveDown: (Category) -> Unit,
onRename: () -> Unit,
onDelete: () -> Unit,
// KMK -->
onHide: () -> Unit,
// KMK <--
modifier: Modifier = Modifier,
) {
ElevatedCard(
Expand All @@ -49,9 +57,19 @@ fun CategoryListItem(
),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(imageVector = Icons.AutoMirrored.Outlined.Label, contentDescription = null)
Icon(
imageVector = Icons.AutoMirrored.Outlined.Label,
contentDescription = null,
// KMK -->
tint = LocalContentColor.current.let { if (category.hidden) it.copy(alpha = 0.6f) else it },
// KMK <--
)
Text(
text = category.name,
// KMK -->
color = LocalContentColor.current.let { if (category.hidden) it.copy(alpha = 0.6f) else it },
textDecoration = TextDecoration.LineThrough.takeIf { category.hidden },
// KMK <--
modifier = Modifier
.padding(start = MaterialTheme.padding.medium),
)
Expand All @@ -76,6 +94,21 @@ fun CategoryListItem(
contentDescription = stringResource(MR.strings.action_rename_category),
)
}
// KMK -->
IconButton(
onClick = onHide,
content = {
Icon(
imageVector = if (category.hidden) {
Icons.Outlined.Visibility
} else {
Icons.Outlined.VisibilityOff
},
contentDescription = stringResource(KMR.strings.action_hide),
)
},
)
// KMK <--
IconButton(onClick = onDelete) {
Icon(imageVector = Icons.Outlined.Delete, contentDescription = stringResource(MR.strings.action_delete))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,12 @@ private fun ColumnScope.DisplayPage(
label = stringResource(MR.strings.action_display_show_tabs),
pref = screenModel.libraryPreferences.categoryTabs(),
)
// KMK -->
CheckboxItem(
label = stringResource(KMR.strings.action_hide_hidden_categories),
pref = screenModel.libraryPreferences.hideHiddenCategories(),
)
// KMK <--
CheckboxItem(
label = stringResource(MR.strings.action_display_show_number_of_items),
pref = screenModel.libraryPreferences.categoryNumberOfItems(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ class BackupCategory(
@ProtoNumber(2) var order: Long = 0,
// @ProtoNumber(3) val updateInterval: Int = 0, 1.x value not used in 0.x
@ProtoNumber(100) var flags: Long = 0,
// KMK -->
@ProtoNumber(900) var hidden: Boolean = false,
// KMK <--
// SY specific values
/*@ProtoNumber(600) var mangaOrder: List<Long> = emptyList(),*/
) {
Expand All @@ -18,6 +21,9 @@ class BackupCategory(
name = this@BackupCategory.name,
flags = this@BackupCategory.flags,
order = this@BackupCategory.order,
// KMK -->
hidden = this@BackupCategory.hidden,
// KMK <--
/*mangaOrder = [email protected]*/
)
}
Expand All @@ -27,5 +33,8 @@ val backupCategoryMapper = { category: Category ->
name = category.name,
order = category.order,
flags = category.flags,
// KMK -->
hidden = category.hidden,
// KMK <--
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ class CategoriesRestorer(
if (dbCategory != null) return@map dbCategory
val order = nextOrder++
handler.awaitOneExecutable {
categoriesQueries.insert(it.name, order, it.flags)
categoriesQueries.insert(
it.name, order, it.flags,
// KMK -->
hidden = if (it.hidden) 1L else 0L,
// KMK <--
)
categoriesQueries.selectLastInsertedRowId()
}
.let { id -> it.toCategory(id).copy(order = order) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class CategoryScreen : Screen() {
onClickDelete = { screenModel.showDialog(CategoryDialog.Delete(it)) },
onClickMoveUp = screenModel::moveUp,
onClickMoveDown = screenModel::moveDown,
// KMK -->
onClickHide = screenModel::hideCategory,
// KMK <--
navigateUp = navigator::pop,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import kotlinx.coroutines.launch
import tachiyomi.domain.category.interactor.CreateCategoryWithName
import tachiyomi.domain.category.interactor.DeleteCategory
import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.interactor.HideCategory
import tachiyomi.domain.category.interactor.RenameCategory
import tachiyomi.domain.category.interactor.ReorderCategory
import tachiyomi.domain.category.model.Category
Expand All @@ -27,6 +28,9 @@ class CategoryScreenModel(
private val deleteCategory: DeleteCategory = Injekt.get(),
private val reorderCategory: ReorderCategory = Injekt.get(),
private val renameCategory: RenameCategory = Injekt.get(),
// KMK -->
private val hideCategory: HideCategory = Injekt.get(),
// KMK <--
) : StateScreenModel<CategoryScreenState>(CategoryScreenState.Loading) {

private val _events: Channel<CategoryEvent> = Channel()
Expand Down Expand Up @@ -56,6 +60,17 @@ class CategoryScreenModel(
}
}

// KMK -->
fun hideCategory(category: Category) {
screenModelScope.launch {
when (hideCategory.await(category)) {
is HideCategory.Result.InternalError -> _events.send(CategoryEvent.InternalError)
else -> {}
}
}
}
// KMK <--

fun deleteCategory(categoryId: Long) {
screenModelScope.launch {
when (deleteCategory.await(categoryId = categoryId)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,13 @@ class LibraryScreenModel(
.groupBy { it.libraryManga.category }
}

return combine(getCategories.subscribe(), libraryMangasFlow) { categories, libraryManga ->
return combine(
// KMK -->
libraryPreferences.hideHiddenCategories().changes(),
// KMK <--
getCategories.subscribe(),
libraryMangasFlow,
) { hideHiddenCategories, categories, libraryManga ->
val displayCategories = if (libraryManga.isNotEmpty() && !libraryManga.containsKey(0)) {
categories.fastFilterNot { it.isSystemCategory }
} else {
Expand All @@ -604,7 +610,11 @@ class LibraryScreenModel(
state.copy(ogCategories = displayCategories)
}
// SY <--
displayCategories.associateWith { libraryManga[it.id].orEmpty() }
displayCategories
// KMK -->
.filterNot { hideHiddenCategories && it.hidden }
// KMK <--
.associateWith { libraryManga[it.id].orEmpty() }
}
}

Expand All @@ -619,6 +629,9 @@ class LibraryScreenModel(
preferences.context.stringResource(SYMR.strings.ungrouped),
0,
0,
// KMK -->
false,
// KMK <--
) to
values.flatten().distinctBy { it.libraryManga.manga.id },
)
Expand Down Expand Up @@ -1283,6 +1296,9 @@ class LibraryScreenModel(
it.int == id
}.takeUnless { it == -1 }?.toLong() ?: TrackStatus.OTHER.ordinal.toLong(),
flags = 0,
// KMK -->
hidden = false,
// KMK <--
)
}
}
Expand All @@ -1308,6 +1324,9 @@ class LibraryScreenModel(
},
order = sources.indexOf(it.key).takeUnless { it == -1 }?.toLong() ?: Long.MAX_VALUE,
flags = 0,
// KMK -->
hidden = false,
// KMK <--
)
}
}
Expand Down Expand Up @@ -1336,6 +1355,9 @@ class LibraryScreenModel(
else -> 7
},
flags = 0,
// KMK -->
hidden = false,
// KMK <--
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class MoveSortingModeSettingsMigration : Migration {
flags = it.flags and 0b00111100L.inv(),
name = null,
order = null,
// KMK -->
hidden = null,
// KMK <--
)
}
}
Expand Down
3 changes: 3 additions & 0 deletions app/src/test/kotlin/Tester.kt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ class Tester {
name = "a",
order = 1,
flags = 0,
// KMK -->
hidden = false,
// KMK <--
),
)
val favoriteEntries = listOf(
Expand Down
6 changes: 6 additions & 0 deletions data/src/main/java/tachiyomi/data/category/CategoryMapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@ object CategoryMapper {
name: String,
order: Long,
flags: Long,
// KMK -->
hidden: Long,
// KMK <--
): Category {
return Category(
id = id,
name = name,
order = order,
flags = flags,
// KMK -->
hidden = hidden == 1L,
// KMK <--
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class CategoryRepositoryImpl(
name = category.name,
order = category.order,
flags = category.flags,
// KMK -->
hidden = if (category.hidden) 1L else 0L,
// KMK <--
)
categoriesQueries.selectLastInsertedRowId()
}
Expand All @@ -67,6 +70,9 @@ class CategoryRepositoryImpl(
name = update.name,
order = update.order,
flags = update.flags,
// KMK -->
hidden = update.hidden?.let { if (it) 1L else 0L },
// KMK <--
categoryId = update.id,
)
}
Expand Down
Loading

0 comments on commit 6c9dfb8

Please sign in to comment.