Improve support for drag-and-drop category/feed reordering (mihonapp/mihon#1427)
This commit is contained in:
parent
0a6caab64b
commit
69adc4605e
15 changed files with 80 additions and 82 deletions
|
|
@ -19,6 +19,7 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
|
||||||
- Support for private tracking with AniList and Bangumi ([@NarwhalHorns](https://github.com/NarwhalHorns)) ([#1736](https://github.com/mihonapp/mihon/pull/1736))
|
- Support for private tracking with AniList and Bangumi ([@NarwhalHorns](https://github.com/NarwhalHorns)) ([#1736](https://github.com/mihonapp/mihon/pull/1736))
|
||||||
- Add private tracking support for Kitsu ([@MajorTanya](https://github.com/MajorTanya)) ([#1774](https://github.com/mihonapp/mihon/pull/1774))
|
- Add private tracking support for Kitsu ([@MajorTanya](https://github.com/MajorTanya)) ([#1774](https://github.com/mihonapp/mihon/pull/1774))
|
||||||
- Add option to export minimal library information to a CSV file ([@Animeboynz](https://github.com/Animeboynz), [@AntsyLich](https://github.com/AntsyLich)) ([#1161](https://github.com/mihonapp/mihon/pull/1161))
|
- Add option to export minimal library information to a CSV file ([@Animeboynz](https://github.com/Animeboynz), [@AntsyLich](https://github.com/AntsyLich)) ([#1161](https://github.com/mihonapp/mihon/pull/1161))
|
||||||
|
- Add back support for drag-and-drop category reordering ([@cuong-tran](https://github.com/cuong-tran)) ([#1427](https://github.com/mihonapp/mihon/pull/1427))
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Apply "Downloaded only" filter to all entries regardless of favourite status ([@NGB-Was-Taken](https://github.com/NGB-Was-Taken)) ([#1603](https://github.com/mihonapp/mihon/pull/1603))
|
- Apply "Downloaded only" filter to all entries regardless of favourite status ([@NGB-Was-Taken](https://github.com/NGB-Was-Taken)) ([#1603](https://github.com/mihonapp/mihon/pull/1603))
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,14 @@ package eu.kanade.presentation.browse
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import eu.kanade.presentation.browse.components.FeedOrderListItem
|
import eu.kanade.presentation.browse.components.FeedOrderListItem
|
||||||
import eu.kanade.tachiyomi.ui.browse.feed.FeedScreenState
|
import eu.kanade.tachiyomi.ui.browse.feed.FeedScreenState
|
||||||
|
|
@ -29,7 +27,7 @@ import tachiyomi.presentation.core.util.plus
|
||||||
fun FeedOrderScreen(
|
fun FeedOrderScreen(
|
||||||
state: FeedScreenState,
|
state: FeedScreenState,
|
||||||
onClickDelete: (FeedSavedSearch) -> Unit,
|
onClickDelete: (FeedSavedSearch) -> Unit,
|
||||||
changeOrder: (FeedSavedSearch, Int) -> Unit,
|
onChangeOrder: (FeedSavedSearch, Int) -> Unit,
|
||||||
) {
|
) {
|
||||||
when {
|
when {
|
||||||
state.isLoading -> LoadingScreen()
|
state.isLoading -> LoadingScreen()
|
||||||
|
|
@ -41,31 +39,32 @@ fun FeedOrderScreen(
|
||||||
val lazyListState = rememberLazyListState()
|
val lazyListState = rememberLazyListState()
|
||||||
val feeds = state.items
|
val feeds = state.items
|
||||||
|
|
||||||
var reorderableList by remember { mutableStateOf(feeds) }
|
val feedsState = remember { feeds.toMutableList() }
|
||||||
val reorderableLazyColumnState = rememberReorderableLazyListState(lazyListState) { from, to ->
|
val reorderableState = rememberReorderableLazyListState(lazyListState) { from, to ->
|
||||||
reorderableList = reorderableList.toMutableList().apply {
|
val item = feedsState.removeAt(from.index)
|
||||||
changeOrder(reorderableList[from.index].feed, to.index - from.index)
|
feedsState.add(to.index, item)
|
||||||
add(to.index, removeAt(from.index))
|
onChangeOrder(item.feed, to.index)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(feeds) {
|
LaunchedEffect(feeds) {
|
||||||
if (!reorderableLazyColumnState.isAnyItemDragging) {
|
if (!reorderableState.isAnyItemDragging) {
|
||||||
reorderableList = feeds
|
feedsState.clear()
|
||||||
|
feedsState.addAll(feeds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
state = lazyListState,
|
state = lazyListState,
|
||||||
contentPadding = topSmallPaddingValues +
|
contentPadding = topSmallPaddingValues +
|
||||||
PaddingValues(horizontal = MaterialTheme.padding.medium),
|
PaddingValues(horizontal = MaterialTheme.padding.medium),
|
||||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
||||||
) {
|
) {
|
||||||
items(
|
items(
|
||||||
items = reorderableList,
|
items = feedsState,
|
||||||
key = { it.feed.key },
|
key = { it.feed.key },
|
||||||
) { feed ->
|
) { feed ->
|
||||||
ReorderableItem(reorderableLazyColumnState, feed.feed.key) {
|
ReorderableItem(reorderableState, feed.feed.key) {
|
||||||
FeedOrderListItem(
|
FeedOrderListItem(
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItem(),
|
||||||
title = feed.title,
|
title = feed.title,
|
||||||
|
|
@ -78,4 +77,4 @@ fun FeedOrderScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val FeedSavedSearch.key get() = "feed-$id"
|
internal val FeedSavedSearch.key inline get() = "feed-$id"
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package eu.kanade.presentation.browse
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
|
|
@ -10,10 +11,7 @@ import androidx.compose.material.icons.outlined.SortByAlpha
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import eu.kanade.presentation.browse.components.FeedOrderListItem
|
import eu.kanade.presentation.browse.components.FeedOrderListItem
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
|
|
@ -37,7 +35,7 @@ import tachiyomi.presentation.core.util.plus
|
||||||
fun SourceFeedOrderScreen(
|
fun SourceFeedOrderScreen(
|
||||||
state: SourceFeedState,
|
state: SourceFeedState,
|
||||||
onClickDelete: (FeedSavedSearch) -> Unit,
|
onClickDelete: (FeedSavedSearch) -> Unit,
|
||||||
changeOrder: (FeedSavedSearch, Int) -> Unit,
|
onChangeOrder: (FeedSavedSearch, Int) -> Unit,
|
||||||
onClickSortAlphabetically: () -> Unit,
|
onClickSortAlphabetically: () -> Unit,
|
||||||
navigateUp: (() -> Unit)? = null,
|
navigateUp: (() -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
|
|
@ -75,31 +73,33 @@ fun SourceFeedOrderScreen(
|
||||||
val feeds = state.items
|
val feeds = state.items
|
||||||
.filterIsInstance<SourceFeedUI.SourceSavedSearch>()
|
.filterIsInstance<SourceFeedUI.SourceSavedSearch>()
|
||||||
|
|
||||||
var reorderableList by remember { mutableStateOf(feeds) }
|
val feedsState = remember { feeds.toMutableList() }
|
||||||
val reorderableLazyColumnState = rememberReorderableLazyListState(lazyListState) { from, to ->
|
val reorderableState = rememberReorderableLazyListState(lazyListState, paddingValues) { from, to ->
|
||||||
reorderableList = reorderableList.toMutableList().apply {
|
val item = feedsState.removeAt(from.index)
|
||||||
changeOrder(reorderableList[from.index].feed, to.index - from.index)
|
feedsState.add(to.index, item)
|
||||||
add(to.index, removeAt(from.index))
|
onChangeOrder(item.feed, to.index)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(feeds) {
|
LaunchedEffect(feeds) {
|
||||||
if (!reorderableLazyColumnState.isAnyItemDragging) {
|
if (!reorderableState.isAnyItemDragging) {
|
||||||
reorderableList = feeds
|
feedsState.clear()
|
||||||
|
feedsState.addAll(feeds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
state = lazyListState,
|
state = lazyListState,
|
||||||
contentPadding = paddingValues + topSmallPaddingValues +
|
contentPadding = paddingValues +
|
||||||
|
topSmallPaddingValues +
|
||||||
PaddingValues(horizontal = MaterialTheme.padding.medium),
|
PaddingValues(horizontal = MaterialTheme.padding.medium),
|
||||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
||||||
) {
|
) {
|
||||||
items(
|
items(
|
||||||
items = reorderableList,
|
items = feedsState,
|
||||||
key = { it.feed.key },
|
key = { it.feed.key },
|
||||||
) { feed ->
|
) { feed ->
|
||||||
ReorderableItem(reorderableLazyColumnState, feed.feed.key) {
|
ReorderableItem(reorderableState, feed.feed.key) {
|
||||||
FeedOrderListItem(
|
FeedOrderListItem(
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItem(),
|
||||||
title = feed.title,
|
title = feed.title,
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,11 @@ fun ReorderableCollectionItemScope.FeedOrderListItem(
|
||||||
onDelete: () -> Unit,
|
onDelete: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
ElevatedCard(
|
ElevatedCard(modifier = modifier) {
|
||||||
modifier = modifier,
|
|
||||||
) {
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = MaterialTheme.padding.small)
|
||||||
.padding(
|
.padding(
|
||||||
start = MaterialTheme.padding.small,
|
start = MaterialTheme.padding.small,
|
||||||
end = MaterialTheme.padding.medium,
|
end = MaterialTheme.padding.medium,
|
||||||
|
|
@ -46,11 +45,13 @@ fun ReorderableCollectionItemScope.FeedOrderListItem(
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text = title,
|
text = title,
|
||||||
modifier = Modifier
|
modifier = Modifier.weight(1f),
|
||||||
.weight(1f),
|
|
||||||
)
|
)
|
||||||
IconButton(onClick = onDelete) {
|
IconButton(onClick = onDelete) {
|
||||||
Icon(imageVector = Icons.Outlined.Delete, contentDescription = stringResource(MR.strings.action_delete))
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Delete,
|
||||||
|
contentDescription = stringResource(MR.strings.action_delete),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package eu.kanade.presentation.category
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
|
@ -12,10 +13,8 @@ import androidx.compose.material.icons.outlined.SortByAlpha
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.toMutableStateList
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import eu.kanade.presentation.category.components.CategoryFloatingActionButton
|
import eu.kanade.presentation.category.components.CategoryFloatingActionButton
|
||||||
import eu.kanade.presentation.category.components.CategoryListItem
|
import eu.kanade.presentation.category.components.CategoryListItem
|
||||||
|
|
@ -42,7 +41,7 @@ fun CategoryScreen(
|
||||||
onClickSortAlphabetically: () -> Unit,
|
onClickSortAlphabetically: () -> Unit,
|
||||||
onClickRename: (Category) -> Unit,
|
onClickRename: (Category) -> Unit,
|
||||||
onClickDelete: (Category) -> Unit,
|
onClickDelete: (Category) -> Unit,
|
||||||
changeOrder: (Category, Int) -> Unit,
|
onChangeOrder: (Category, Int) -> Unit,
|
||||||
// KMK -->
|
// KMK -->
|
||||||
onClickHide: (Category) -> Unit,
|
onClickHide: (Category) -> Unit,
|
||||||
// KMK <--
|
// KMK <--
|
||||||
|
|
@ -86,11 +85,10 @@ fun CategoryScreen(
|
||||||
CategoryContent(
|
CategoryContent(
|
||||||
categories = state.categories,
|
categories = state.categories,
|
||||||
lazyListState = lazyListState,
|
lazyListState = lazyListState,
|
||||||
paddingValues = paddingValues + topSmallPaddingValues +
|
paddingValues = paddingValues,
|
||||||
PaddingValues(horizontal = MaterialTheme.padding.medium),
|
|
||||||
onClickRename = onClickRename,
|
onClickRename = onClickRename,
|
||||||
onClickDelete = onClickDelete,
|
onClickDelete = onClickDelete,
|
||||||
changeOrder = changeOrder,
|
onChangeOrder = onChangeOrder,
|
||||||
// KMK -->
|
// KMK -->
|
||||||
onClickHide = onClickHide,
|
onClickHide = onClickHide,
|
||||||
// KMK <--
|
// KMK <--
|
||||||
|
|
@ -105,35 +103,38 @@ private fun CategoryContent(
|
||||||
paddingValues: PaddingValues,
|
paddingValues: PaddingValues,
|
||||||
onClickRename: (Category) -> Unit,
|
onClickRename: (Category) -> Unit,
|
||||||
onClickDelete: (Category) -> Unit,
|
onClickDelete: (Category) -> Unit,
|
||||||
changeOrder: (Category, Int) -> Unit,
|
onChangeOrder: (Category, Int) -> Unit,
|
||||||
// KMK -->
|
// KMK -->
|
||||||
onClickHide: (Category) -> Unit,
|
onClickHide: (Category) -> Unit,
|
||||||
// KMK <--
|
// KMK <--
|
||||||
) {
|
) {
|
||||||
var reorderableList by remember { mutableStateOf(categories.toList()) }
|
val categoriesState = remember { categories.toMutableStateList() }
|
||||||
val reorderableLazyColumnState = rememberReorderableLazyListState(lazyListState) { from, to ->
|
val reorderableState = rememberReorderableLazyListState(lazyListState, paddingValues) { from, to ->
|
||||||
reorderableList = reorderableList.toMutableList().apply {
|
val item = categoriesState.removeAt(from.index)
|
||||||
changeOrder(reorderableList[from.index], to.index - from.index)
|
categoriesState.add(to.index, item)
|
||||||
add(to.index, removeAt(from.index))
|
onChangeOrder(item, to.index)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(categories) {
|
LaunchedEffect(categories) {
|
||||||
if (!reorderableLazyColumnState.isAnyItemDragging) {
|
if (!reorderableState.isAnyItemDragging) {
|
||||||
reorderableList = categories.toList()
|
categoriesState.clear()
|
||||||
|
categoriesState.addAll(categories)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
state = lazyListState,
|
state = lazyListState,
|
||||||
contentPadding = paddingValues,
|
contentPadding = paddingValues +
|
||||||
|
topSmallPaddingValues +
|
||||||
|
PaddingValues(horizontal = MaterialTheme.padding.medium),
|
||||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
||||||
) {
|
) {
|
||||||
items(
|
items(
|
||||||
items = reorderableList,
|
items = categoriesState,
|
||||||
key = { category -> category.key },
|
key = { category -> category.key },
|
||||||
) { category ->
|
) { category ->
|
||||||
ReorderableItem(reorderableLazyColumnState, category.key) {
|
ReorderableItem(reorderableState, category.key) {
|
||||||
CategoryListItem(
|
CategoryListItem(
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItem(),
|
||||||
category = category,
|
category = category,
|
||||||
|
|
@ -148,4 +149,4 @@ private fun CategoryContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val Category.key get() = "category-$id"
|
private val Category.key inline get() = "category-$id"
|
||||||
|
|
|
||||||
|
|
@ -37,13 +37,12 @@ fun ReorderableCollectionItemScope.CategoryListItem(
|
||||||
// KMK <--
|
// KMK <--
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
ElevatedCard(
|
ElevatedCard(modifier = modifier) {
|
||||||
modifier = modifier,
|
|
||||||
) {
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clickable { onRename() }
|
.clickable(onClick = onRename)
|
||||||
|
.padding(vertical = MaterialTheme.padding.small)
|
||||||
.padding(
|
.padding(
|
||||||
start = MaterialTheme.padding.small,
|
start = MaterialTheme.padding.small,
|
||||||
end = MaterialTheme.padding.medium,
|
end = MaterialTheme.padding.medium,
|
||||||
|
|
@ -63,8 +62,7 @@ fun ReorderableCollectionItemScope.CategoryListItem(
|
||||||
color = LocalContentColor.current.let { if (category.hidden) it.copy(alpha = 0.6f) else it },
|
color = LocalContentColor.current.let { if (category.hidden) it.copy(alpha = 0.6f) else it },
|
||||||
textDecoration = TextDecoration.LineThrough.takeIf { category.hidden },
|
textDecoration = TextDecoration.LineThrough.takeIf { category.hidden },
|
||||||
// KMK <--
|
// KMK <--
|
||||||
modifier = Modifier
|
modifier = Modifier.weight(1f),
|
||||||
.weight(1f),
|
|
||||||
)
|
)
|
||||||
IconButton(onClick = onRename) {
|
IconButton(onClick = onRename) {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -88,7 +86,10 @@ fun ReorderableCollectionItemScope.CategoryListItem(
|
||||||
)
|
)
|
||||||
// KMK <--
|
// KMK <--
|
||||||
IconButton(onClick = onDelete) {
|
IconButton(onClick = onDelete) {
|
||||||
Icon(imageVector = Icons.Outlined.Delete, contentDescription = stringResource(MR.strings.action_delete))
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Delete,
|
||||||
|
contentDescription = stringResource(MR.strings.action_delete),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -218,9 +218,9 @@ open class FeedScreenModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
// KMK -->
|
// KMK -->
|
||||||
fun changeOrder(feed: FeedSavedSearch, newOrder: Int) {
|
fun changeOrder(feed: FeedSavedSearch, newIndex: Int) {
|
||||||
screenModelScope.launch {
|
screenModelScope.launch {
|
||||||
reorderFeed.changeOrder(feed, newOrder)
|
reorderFeed.changeOrder(feed, newIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ fun feedTab(
|
||||||
FeedOrderScreen(
|
FeedOrderScreen(
|
||||||
state = state,
|
state = state,
|
||||||
onClickDelete = screenModel::openDeleteDialog,
|
onClickDelete = screenModel::openDeleteDialog,
|
||||||
changeOrder = screenModel::changeOrder,
|
onChangeOrder = screenModel::changeOrder,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// KMK <--
|
// KMK <--
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ class SourceFeedScreen(val sourceId: Long) : Screen() {
|
||||||
SourceFeedOrderScreen(
|
SourceFeedOrderScreen(
|
||||||
state = state,
|
state = state,
|
||||||
onClickDelete = screenModel::openDeleteFeed,
|
onClickDelete = screenModel::openDeleteFeed,
|
||||||
changeOrder = screenModel::changeOrder,
|
onChangeOrder = screenModel::changeOrder,
|
||||||
onClickSortAlphabetically = {
|
onClickSortAlphabetically = {
|
||||||
screenModel.showDialog(SourceFeedScreenModel.Dialog.SortAlphabetically)
|
screenModel.showDialog(SourceFeedScreenModel.Dialog.SortAlphabetically)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.serialization.encodeToString
|
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
import tachiyomi.core.common.util.lang.launchIO
|
||||||
import tachiyomi.core.common.util.lang.launchNonCancellable
|
import tachiyomi.core.common.util.lang.launchNonCancellable
|
||||||
|
|
@ -156,9 +155,9 @@ open class SourceFeedScreenModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
// KMK -->
|
// KMK -->
|
||||||
fun changeOrder(feed: FeedSavedSearch, newOrder: Int) {
|
fun changeOrder(feed: FeedSavedSearch, newIndex: Int) {
|
||||||
screenModelScope.launch {
|
screenModelScope.launch {
|
||||||
reorderFeed.changeOrder(feed, newOrder, false)
|
reorderFeed.changeOrder(feed, newIndex, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ class CategoryScreen : Screen() {
|
||||||
onClickSortAlphabetically = { screenModel.showDialog(CategoryDialog.SortAlphabetically) },
|
onClickSortAlphabetically = { screenModel.showDialog(CategoryDialog.SortAlphabetically) },
|
||||||
onClickRename = { screenModel.showDialog(CategoryDialog.Rename(it)) },
|
onClickRename = { screenModel.showDialog(CategoryDialog.Rename(it)) },
|
||||||
onClickDelete = { screenModel.showDialog(CategoryDialog.Delete(it)) },
|
onClickDelete = { screenModel.showDialog(CategoryDialog.Delete(it)) },
|
||||||
changeOrder = screenModel::changeOrder,
|
onChangeOrder = screenModel::changeOrder,
|
||||||
// KMK -->
|
// KMK -->
|
||||||
onClickHide = screenModel::hideCategory,
|
onClickHide = screenModel::hideCategory,
|
||||||
// KMK <--
|
// KMK <--
|
||||||
|
|
|
||||||
|
|
@ -89,9 +89,9 @@ class CategoryScreenModel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun changeOrder(category: Category, newOrder: Int) {
|
fun changeOrder(category: Category, newIndex: Int) {
|
||||||
screenModelScope.launch {
|
screenModelScope.launch {
|
||||||
when (reorderCategory.changeOrder(category, newOrder)) {
|
when (reorderCategory.changeOrder(category, newIndex)) {
|
||||||
is ReorderCategory.Result.InternalError -> _events.send(CategoryEvent.InternalError)
|
is ReorderCategory.Result.InternalError -> _events.send(CategoryEvent.InternalError)
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class ReorderCategory(
|
||||||
|
|
||||||
private val mutex = Mutex()
|
private val mutex = Mutex()
|
||||||
|
|
||||||
suspend fun changeOrder(category: Category, newOrder: Int) = withNonCancellableContext {
|
suspend fun changeOrder(category: Category, newIndex: Int) = withNonCancellableContext {
|
||||||
mutex.withLock {
|
mutex.withLock {
|
||||||
val categories = categoryRepository.getAll()
|
val categories = categoryRepository.getAll()
|
||||||
.filterNot(Category::isSystemCategory)
|
.filterNot(Category::isSystemCategory)
|
||||||
|
|
@ -26,10 +26,8 @@ class ReorderCategory(
|
||||||
return@withNonCancellableContext Result.Unchanged
|
return@withNonCancellableContext Result.Unchanged
|
||||||
}
|
}
|
||||||
|
|
||||||
val newPosition = currentIndex + newOrder
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
categories.add(newPosition, categories.removeAt(currentIndex))
|
categories.add(newIndex, categories.removeAt(currentIndex))
|
||||||
|
|
||||||
val updates = categories.mapIndexed { index, category ->
|
val updates = categories.mapIndexed { index, category ->
|
||||||
CategoryUpdate(
|
CategoryUpdate(
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class ReorderFeed(
|
||||||
|
|
||||||
private val mutex = Mutex()
|
private val mutex = Mutex()
|
||||||
|
|
||||||
suspend fun changeOrder(feed: FeedSavedSearch, newOrder: Int, global: Boolean = true) = withNonCancellableContext {
|
suspend fun changeOrder(feed: FeedSavedSearch, newIndex: Int, global: Boolean = true) = withNonCancellableContext {
|
||||||
mutex.withLock {
|
mutex.withLock {
|
||||||
val feeds = if (global) {
|
val feeds = if (global) {
|
||||||
feedSavedSearchRepository.getGlobal()
|
feedSavedSearchRepository.getGlobal()
|
||||||
|
|
@ -30,10 +30,8 @@ class ReorderFeed(
|
||||||
return@withNonCancellableContext Result.Unchanged
|
return@withNonCancellableContext Result.Unchanged
|
||||||
}
|
}
|
||||||
|
|
||||||
val newPosition = currentIndex + newOrder
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
feeds.add(newPosition, feeds.removeAt(currentIndex))
|
feeds.add(newIndex, feeds.removeAt(currentIndex))
|
||||||
|
|
||||||
val updates = feeds.mapIndexed { index, feed ->
|
val updates = feeds.mapIndexed { index, feed ->
|
||||||
FeedSavedSearchUpdate(
|
FeedSavedSearchUpdate(
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,10 @@ compose-materialmotion = "io.github.fornewid:material-motion-compose-core:2.0.1"
|
||||||
compose-webview = "io.github.kevinnzou:compose-webview:0.33.6"
|
compose-webview = "io.github.kevinnzou:compose-webview:0.33.6"
|
||||||
compose-grid = "io.woong.compose.grid:grid:1.2.2"
|
compose-grid = "io.woong.compose.grid:grid:1.2.2"
|
||||||
compose-stablemarker = "com.github.skydoves:compose-stable-marker:1.0.5"
|
compose-stablemarker = "com.github.skydoves:compose-stable-marker:1.0.5"
|
||||||
|
reorderable = { module = "sh.calvin.reorderable:reorderable", version = "2.4.3" }
|
||||||
palette-ktx = "androidx.palette:palette-ktx:1.0.0"
|
palette-ktx = "androidx.palette:palette-ktx:1.0.0"
|
||||||
materialKolor = "com.materialkolor:material-kolor:2.0.2"
|
materialKolor = "com.materialkolor:material-kolor:2.0.2"
|
||||||
haze = "dev.chrisbanes.haze:haze:1.3.1"
|
haze = "dev.chrisbanes.haze:haze:1.3.1"
|
||||||
reorderable = { module = "sh.calvin.reorderable:reorderable", version = "2.4.3" }
|
|
||||||
|
|
||||||
swipe = "me.saket.swipe:swipe:1.3.0"
|
swipe = "me.saket.swipe:swipe:1.3.0"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue