Option to undo removing from favourites
This commit is contained in:
@@ -102,7 +102,7 @@ dependencies {
|
||||
implementation 'com.hannesdorfmann:adapterdelegates4-kotlin-dsl-viewbinding:4.3.2'
|
||||
|
||||
implementation 'io.insert-koin:koin-android:3.2.0'
|
||||
implementation 'io.coil-kt:coil-base:2.0.0-rc03'
|
||||
implementation 'io.coil-kt:coil-base:2.0.0'
|
||||
implementation 'com.davemorrissey.labs:subsampling-scale-image-view-androidx:3.10.0'
|
||||
implementation 'com.github.solkin:disk-lru-cache:1.4'
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.koitharu.kotatsu.base.domain
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koitharu.kotatsu.utils.ext.processLifecycleScope
|
||||
|
||||
fun interface ReversibleHandle {
|
||||
|
||||
suspend fun reverse()
|
||||
}
|
||||
|
||||
fun ReversibleHandle.reverseAsync() = processLifecycleScope.launch(Dispatchers.Default) {
|
||||
reverse()
|
||||
}
|
||||
|
||||
operator fun ReversibleHandle.plus(other: ReversibleHandle) = ReversibleHandle {
|
||||
this.reverse()
|
||||
other.reverse()
|
||||
}
|
||||
@@ -15,6 +15,10 @@ abstract class HistoryDao {
|
||||
@Query("SELECT * FROM history ORDER BY updated_at DESC LIMIT :limit OFFSET :offset")
|
||||
abstract suspend fun findAll(offset: Int, limit: Int): List<HistoryWithManga>
|
||||
|
||||
@Transaction
|
||||
@Query("SELECT * FROM history WHERE manga_id IN (:ids)")
|
||||
abstract suspend fun findAll(ids: Collection<Long>): List<HistoryEntity?>
|
||||
|
||||
@Transaction
|
||||
@Query("SELECT * FROM history ORDER BY updated_at DESC")
|
||||
abstract fun observeAll(): Flow<List<HistoryWithManga>>
|
||||
@@ -69,4 +73,13 @@ abstract class HistoryDao {
|
||||
true
|
||||
} else false
|
||||
}
|
||||
|
||||
@Transaction
|
||||
open suspend fun upsert(entities: Iterable<HistoryEntity>) {
|
||||
for (e in entities) {
|
||||
if (update(e) == 0) {
|
||||
insert(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import androidx.room.withTransaction
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.koitharu.kotatsu.base.domain.ReversibleHandle
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.db.entity.*
|
||||
import org.koitharu.kotatsu.core.model.MangaHistory
|
||||
@@ -100,6 +101,19 @@ class HistoryRepository(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun deleteReversible(ids: Collection<Long>): ReversibleHandle {
|
||||
val entities = db.withTransaction {
|
||||
val entities = db.historyDao.findAll(ids.toList()).filterNotNull()
|
||||
for (id in ids) {
|
||||
db.historyDao.delete(id)
|
||||
}
|
||||
entities
|
||||
}
|
||||
return ReversibleHandle {
|
||||
db.historyDao.upsert(entities)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to replace one manga with another one
|
||||
* Useful for replacing saved manga on deleting it with remove source
|
||||
|
||||
@@ -7,8 +7,11 @@ import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.domain.ReversibleHandle
|
||||
import org.koitharu.kotatsu.base.domain.reverseAsync
|
||||
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
|
||||
@@ -22,6 +25,7 @@ class HistoryListFragment : MangaListFragment() {
|
||||
viewModel.isGroupingEnabled.observe(viewLifecycleOwner) {
|
||||
activity?.invalidateOptionsMenu()
|
||||
}
|
||||
viewModel.onItemsRemoved.observe(viewLifecycleOwner, ::onItemsRemoved)
|
||||
}
|
||||
|
||||
override fun onScrolledToEnd() = Unit
|
||||
@@ -80,6 +84,12 @@ class HistoryListFragment : MangaListFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun onItemsRemoved(reversibleHandle: ReversibleHandle) {
|
||||
Snackbar.make(binding.recyclerView, R.string.removed_from_history, Snackbar.LENGTH_LONG)
|
||||
.setAction(R.string.undo) { reversibleHandle.reverseAsync() }
|
||||
.show()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance() = HistoryListFragment()
|
||||
|
||||
@@ -7,6 +7,8 @@ import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.domain.ReversibleHandle
|
||||
import org.koitharu.kotatsu.base.domain.plus
|
||||
import org.koitharu.kotatsu.core.os.ShortcutsRepository
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.core.prefs.ListMode
|
||||
@@ -17,6 +19,7 @@ import org.koitharu.kotatsu.history.domain.MangaWithHistory
|
||||
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
||||
import org.koitharu.kotatsu.list.ui.model.*
|
||||
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
|
||||
import org.koitharu.kotatsu.utils.SingleLiveEvent
|
||||
import org.koitharu.kotatsu.utils.ext.asLiveDataDistinct
|
||||
import org.koitharu.kotatsu.utils.ext.daysDiff
|
||||
import org.koitharu.kotatsu.utils.ext.onFirst
|
||||
@@ -31,6 +34,7 @@ class HistoryListViewModel(
|
||||
) : MangaListViewModel(settings) {
|
||||
|
||||
val isGroupingEnabled = MutableLiveData<Boolean>()
|
||||
val onItemsRemoved = SingleLiveEvent<ReversibleHandle>()
|
||||
|
||||
private val historyGrouping = settings.observeAsFlow(AppSettings.KEY_HISTORY_GROUPING) { historyGrouping }
|
||||
.onEach { isGroupingEnabled.postValue(it) }
|
||||
@@ -72,9 +76,12 @@ class HistoryListViewModel(
|
||||
if (ids.isEmpty()) {
|
||||
return
|
||||
}
|
||||
launchJob {
|
||||
repository.delete(ids)
|
||||
launchJob(Dispatchers.Default) {
|
||||
val handle = repository.deleteReversible(ids) + ReversibleHandle {
|
||||
shortcutsRepository.updateShortcuts()
|
||||
}
|
||||
shortcutsRepository.updateShortcuts()
|
||||
onItemsRemoved.postCall(handle)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -293,4 +293,6 @@
|
||||
<string name="bookmarks">Bookmarks</string>
|
||||
<string name="bookmark_removed">Bookmark removed</string>
|
||||
<string name="bookmark_added">Bookmark added</string>
|
||||
<string name="undo">Undo</string>
|
||||
<string name="removed_from_history">Removed from history</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user