mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-03 23:58:55 +01:00 
			
		
		
		
	@@ -5,46 +5,66 @@ import eu.kanade.domain.category.model.CategoryUpdate
 | 
			
		||||
import eu.kanade.domain.category.repository.CategoryRepository
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.logcat
 | 
			
		||||
import kotlinx.coroutines.sync.Mutex
 | 
			
		||||
import kotlinx.coroutines.sync.withLock
 | 
			
		||||
import logcat.LogPriority
 | 
			
		||||
import java.util.Collections
 | 
			
		||||
 | 
			
		||||
class ReorderCategory(
 | 
			
		||||
    private val categoryRepository: CategoryRepository,
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    suspend fun await(categoryId: Long, newPosition: Int) = withNonCancellableContext {
 | 
			
		||||
        val categories = categoryRepository.getAll().filterNot(Category::isSystemCategory)
 | 
			
		||||
    private val mutex = Mutex()
 | 
			
		||||
 | 
			
		||||
        val currentIndex = categories.indexOfFirst { it.id == categoryId }
 | 
			
		||||
        if (currentIndex == newPosition) {
 | 
			
		||||
            return@withNonCancellableContext Result.Unchanged
 | 
			
		||||
        }
 | 
			
		||||
    suspend fun moveUp(category: Category): Result =
 | 
			
		||||
        await(category, MoveTo.UP)
 | 
			
		||||
 | 
			
		||||
        val reorderedCategories = categories.toMutableList()
 | 
			
		||||
        val reorderedCategory = reorderedCategories.removeAt(currentIndex)
 | 
			
		||||
        reorderedCategories.add(newPosition, reorderedCategory)
 | 
			
		||||
    suspend fun moveDown(category: Category): Result =
 | 
			
		||||
        await(category, MoveTo.DOWN)
 | 
			
		||||
 | 
			
		||||
        val updates = reorderedCategories.mapIndexed { index, category ->
 | 
			
		||||
            CategoryUpdate(
 | 
			
		||||
                id = category.id,
 | 
			
		||||
                order = index.toLong(),
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    private suspend fun await(category: Category, moveTo: MoveTo) = withNonCancellableContext {
 | 
			
		||||
        mutex.withLock {
 | 
			
		||||
            val categories = categoryRepository.getAll()
 | 
			
		||||
                .filterNot(Category::isSystemCategory)
 | 
			
		||||
                .toMutableList()
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            categoryRepository.updatePartial(updates)
 | 
			
		||||
            Result.Success
 | 
			
		||||
        } catch (e: Exception) {
 | 
			
		||||
            logcat(LogPriority.ERROR, e)
 | 
			
		||||
            Result.InternalError(e)
 | 
			
		||||
            val newPosition = when (moveTo) {
 | 
			
		||||
                MoveTo.UP -> category.order - 1
 | 
			
		||||
                MoveTo.DOWN -> category.order + 1
 | 
			
		||||
            }.toInt()
 | 
			
		||||
 | 
			
		||||
            val currentIndex = categories.indexOfFirst { it.id == category.id }
 | 
			
		||||
            if (currentIndex == newPosition) {
 | 
			
		||||
                return@withNonCancellableContext Result.Unchanged
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Collections.swap(categories, currentIndex, newPosition)
 | 
			
		||||
 | 
			
		||||
            val updates = categories.mapIndexed { index, category ->
 | 
			
		||||
                CategoryUpdate(
 | 
			
		||||
                    id = category.id,
 | 
			
		||||
                    order = index.toLong(),
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                categoryRepository.updatePartial(updates)
 | 
			
		||||
                Result.Success
 | 
			
		||||
            } catch (e: Exception) {
 | 
			
		||||
                logcat(LogPriority.ERROR, e)
 | 
			
		||||
                Result.InternalError(e)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun await(category: Category, newPosition: Long): Result =
 | 
			
		||||
        await(category.id, newPosition.toInt())
 | 
			
		||||
 | 
			
		||||
    sealed class Result {
 | 
			
		||||
        object Success : Result()
 | 
			
		||||
        object Unchanged : Result()
 | 
			
		||||
        data class InternalError(val error: Throwable) : Result()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private enum class MoveTo {
 | 
			
		||||
        UP,
 | 
			
		||||
        DOWN,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user