Fix sources reordering
This commit is contained in:
@@ -91,6 +91,14 @@ class MangaSourcesRepository @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun setPositions(sources: List<MangaSource>) {
|
||||
db.withTransaction {
|
||||
for ((index, item) in sources.withIndex()) {
|
||||
dao.setSortKey(item.name, index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun setPosition(source: MangaSource, index: Int) {
|
||||
db.withTransaction {
|
||||
val all = dao.findAll().toMutableList()
|
||||
|
||||
@@ -172,10 +172,20 @@ class SourcesManageFragment :
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder,
|
||||
): Boolean = viewHolder.itemViewType == target.itemViewType && viewModel.reorderSources(
|
||||
viewHolder.bindingAdapterPosition,
|
||||
target.bindingAdapterPosition,
|
||||
)
|
||||
): Boolean = viewHolder.itemViewType == target.itemViewType
|
||||
|
||||
override fun onMoved(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
fromPos: Int,
|
||||
target: RecyclerView.ViewHolder,
|
||||
toPos: Int,
|
||||
x: Int,
|
||||
y: Int
|
||||
) {
|
||||
super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y)
|
||||
viewModel.reorderSources(fromPos, toPos)
|
||||
}
|
||||
|
||||
override fun canDropOver(
|
||||
recyclerView: RecyclerView,
|
||||
|
||||
@@ -4,17 +4,15 @@ import androidx.annotation.CheckResult
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.cancelAndJoin
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.plus
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.getLocaleTitle
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
@@ -29,13 +27,12 @@ import org.koitharu.kotatsu.core.util.ext.toEnumSet
|
||||
import org.koitharu.kotatsu.explore.data.MangaSourcesRepository
|
||||
import org.koitharu.kotatsu.parsers.model.ContentType
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.util.move
|
||||
import org.koitharu.kotatsu.parsers.util.toTitleCase
|
||||
import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem
|
||||
import java.util.Locale
|
||||
import java.util.TreeMap
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
|
||||
private const val KEY_ENABLED = "!"
|
||||
private const val TIP_REORDER = "src_reorder"
|
||||
@@ -48,7 +45,7 @@ class SourcesManageViewModel @Inject constructor(
|
||||
|
||||
private val expandedGroups = MutableStateFlow(emptySet<String?>())
|
||||
private var searchQuery = MutableStateFlow<String?>(null)
|
||||
private val mutex = Mutex()
|
||||
private var reorderJob: Job? = null
|
||||
|
||||
val content = combine(
|
||||
repository.observeEnabledSources(),
|
||||
@@ -62,23 +59,28 @@ class SourcesManageViewModel @Inject constructor(
|
||||
|
||||
val onActionDone = MutableEventFlow<ReversibleAction>()
|
||||
|
||||
fun reorderSources(oldPos: Int, newPos: Int): Boolean {
|
||||
val snapshot = content.value
|
||||
val item = (snapshot[oldPos] as? SourceConfigItem.SourceItem) ?: return false
|
||||
if ((snapshot[newPos] as? SourceConfigItem.SourceItem)?.isDraggable != true) return false
|
||||
launchAtomicJob(Dispatchers.Default) {
|
||||
var targetPosition = 0
|
||||
for ((i, x) in snapshot.withIndex()) {
|
||||
if (i == newPos) {
|
||||
break
|
||||
}
|
||||
if (x is SourceConfigItem.SourceItem) {
|
||||
targetPosition++
|
||||
fun reorderSources(oldPos: Int, newPos: Int) {
|
||||
val snapshot = content.value.toMutableList()
|
||||
val prevJob = reorderJob
|
||||
reorderJob = launchJob(Dispatchers.Default) {
|
||||
prevJob?.cancelAndJoin()
|
||||
if ((snapshot[oldPos] as? SourceConfigItem.SourceItem)?.isDraggable != true) {
|
||||
return@launchJob
|
||||
}
|
||||
if ((snapshot[newPos] as? SourceConfigItem.SourceItem)?.isDraggable != true) {
|
||||
return@launchJob
|
||||
}
|
||||
delay(100)
|
||||
snapshot.move(oldPos, newPos)
|
||||
val newSourcesList = snapshot.mapNotNull { x ->
|
||||
if (x is SourceConfigItem.SourceItem && x.isDraggable) {
|
||||
x.source
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
repository.setPosition(item.source, targetPosition)
|
||||
repository.setPositions(newSourcesList)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun canReorder(oldPos: Int, newPos: Int): Boolean {
|
||||
@@ -88,7 +90,7 @@ class SourcesManageViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun setEnabled(source: MangaSource, isEnabled: Boolean) {
|
||||
launchAtomicJob(Dispatchers.Default) {
|
||||
launchJob(Dispatchers.Default) {
|
||||
val rollback = repository.setSourceEnabled(source, isEnabled)
|
||||
if (!isEnabled) {
|
||||
onActionDone.call(ReversibleAction(R.string.source_disabled, rollback))
|
||||
@@ -97,7 +99,7 @@ class SourcesManageViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun disableAll() {
|
||||
launchAtomicJob(Dispatchers.Default) {
|
||||
launchJob(Dispatchers.Default) {
|
||||
repository.disableAllSources()
|
||||
}
|
||||
}
|
||||
@@ -116,7 +118,7 @@ class SourcesManageViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun onTipClosed(item: SourceConfigItem.Tip) {
|
||||
launchAtomicJob(Dispatchers.Default) {
|
||||
launchJob(Dispatchers.Default) {
|
||||
settings.closeTip(item.key)
|
||||
}
|
||||
}
|
||||
@@ -203,15 +205,6 @@ class SourcesManageViewModel @Inject constructor(
|
||||
return locale.getDisplayLanguage(locale).toTitleCase(locale)
|
||||
}
|
||||
|
||||
private fun launchAtomicJob(
|
||||
context: CoroutineContext = EmptyCoroutineContext,
|
||||
block: suspend CoroutineScope.() -> Unit
|
||||
) = launchJob(start = CoroutineStart.ATOMIC) {
|
||||
mutex.withLock {
|
||||
withContext(context, block)
|
||||
}
|
||||
}
|
||||
|
||||
private fun observeTip() = settings.observeAsFlow(AppSettings.KEY_TIPS_CLOSED) {
|
||||
isTipEnabled(TIP_REORDER)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user