Clear updates feed from options menu

This commit is contained in:
Koitharu
2021-01-22 19:17:49 +02:00
parent 510c5b70c9
commit bbcd96b981
6 changed files with 83 additions and 12 deletions

View File

@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.tracker.ui
import android.os.Bundle
import android.view.*
import androidx.appcompat.app.AlertDialog
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import com.google.android.material.snackbar.Snackbar
@@ -55,6 +56,9 @@ class FeedFragment : BaseFragment<FragmentFeedBinding>(), PaginationScrollListen
viewModel.content.observe(viewLifecycleOwner, this::onListChanged)
viewModel.onError.observe(viewLifecycleOwner, this::onError)
viewModel.onFeedCleared.observe(viewLifecycleOwner) {
onFeedCleared()
}
TrackWorker.getProgressLiveData(view.context.applicationContext)
.observe(viewLifecycleOwner, this::onUpdateProgressChanged)
}
@@ -64,17 +68,29 @@ class FeedFragment : BaseFragment<FragmentFeedBinding>(), PaginationScrollListen
inflater.inflate(R.menu.opt_feed, menu)
}
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
R.id.action_update -> {
TrackWorker.startNow(requireContext())
Snackbar.make(
binding.recyclerView,
R.string.feed_will_update_soon,
Snackbar.LENGTH_SHORT
).show()
true
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_update -> {
TrackWorker.startNow(requireContext())
Snackbar.make(
binding.recyclerView,
R.string.feed_will_update_soon,
Snackbar.LENGTH_SHORT
).show()
true
}
R.id.action_clear_feed -> {
AlertDialog.Builder(context ?: return false)
.setTitle(R.string.clear_updates_feed)
.setMessage(R.string.text_clear_updates_feed_prompt)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.clear) { _, _ ->
viewModel.clearFeed()
}.show()
true
}
else -> super.onOptionsItemSelected(item)
}
else -> super.onOptionsItemSelected(item)
}
override fun onDestroyView() {
@@ -95,6 +111,14 @@ class FeedFragment : BaseFragment<FragmentFeedBinding>(), PaginationScrollListen
feedAdapter?.items = list
}
private fun onFeedCleared() {
Snackbar.make(
binding.recyclerView,
R.string.updates_feed_cleared,
Snackbar.LENGTH_LONG
).show()
}
private fun onError(e: Throwable) {
Snackbar.make(
binding.recyclerView,

View File

@@ -5,6 +5,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
@@ -16,6 +17,7 @@ import org.koitharu.kotatsu.list.ui.model.LoadingFooter
import org.koitharu.kotatsu.list.ui.model.LoadingState
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
import org.koitharu.kotatsu.tracker.ui.model.toFeedItem
import org.koitharu.kotatsu.utils.SingleLiveEvent
import org.koitharu.kotatsu.utils.ext.asLiveDataDistinct
import org.koitharu.kotatsu.utils.ext.mapItems
@@ -29,6 +31,7 @@ class FeedViewModel(
private var loadingJob: Job? = null
val isEmptyState = MutableLiveData(false)
val onFeedCleared = SingleLiveEvent<Unit>()
val content = combine(
logList.filterNotNull().mapItems {
it.toFeedItem(context.resources)
@@ -40,7 +43,10 @@ class FeedViewModel(
isHasNextPage -> list + LoadingFooter
else -> list
}
}.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default, listOf(LoadingState))
}.asLiveDataDistinct(
viewModelScope.coroutineContext + Dispatchers.Default,
listOf(LoadingState)
)
init {
loadList(append = false)
@@ -62,4 +68,15 @@ class FeedViewModel(
hasNextPage.value = list.isNotEmpty()
}
}
fun clearFeed() {
val lastJob = loadingJob
loadingJob = launchLoadingJob(Dispatchers.Default) {
lastJob?.cancelAndJoin()
repository.clearLogs()
logList.value = emptyList()
isEmptyState.postValue(true)
onFeedCleared.postCall(Unit)
}
}
}

View File

@@ -68,4 +68,24 @@ inline fun <T, reified R> Array<T>.mapToArray(transform: (T) -> R): Array<R> = A
transform(get(i))
}
fun <T : Enum<T>> Array<T>.names() = mapToArray { it.name }
fun <T : Enum<T>> Array<T>.names() = mapToArray { it.name }
fun <T> Collection<T>.isDistinct(): Boolean {
val set = HashSet<T>(size)
for (item in this) {
if (!set.add(item)) {
return false
}
}
return set.size == size
}
fun <T, K> Collection<T>.isDistinctBy(selector: (T) -> K): Boolean {
val set = HashSet<K>(size)
for (item in this) {
if (!set.add(selector(item))) {
return false
}
}
return set.size == size
}

View File

@@ -9,4 +9,10 @@
android:title="@string/update"
app:showAsAction="never" />
<item
android:id="@+id/action_clear_feed"
android:orderInCategory="50"
android:title="@string/clear_feed"
app:showAsAction="never" />
</menu>

View File

@@ -193,4 +193,6 @@
<string name="clear_cookies">Очистить куки</string>
<string name="cookies_cleared">Все куки удалены</string>
<string name="chapers_checking_progress">Проверка новых глав: %1$d из %2$d</string>
<string name="clear_feed">Очистить ленту</string>
<string name="text_clear_updates_feed_prompt">Вся история обновлений будет очищена и её нельзя будет вернуть. Вы уверены?</string>
</resources>

View File

@@ -195,4 +195,6 @@
<string name="clear_cookies">Clear cookies</string>
<string name="cookies_cleared">All cookies was removed</string>
<string name="chapers_checking_progress">Checking for new chapters: %1$d of %2$d</string>
<string name="clear_feed">Clear feed</string>
<string name="text_clear_updates_feed_prompt">All updates history will be cleared and this action cannot be undone. Are you sure?</string>
</resources>