Popup menu on sources in Explore fragment
This commit is contained in:
@@ -2,8 +2,10 @@ package org.koitharu.kotatsu.explore.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.viewModels
|
||||
@@ -11,11 +13,12 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.ImageLoader
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.domain.reverseAsync
|
||||
import org.koitharu.kotatsu.base.ui.BaseFragment
|
||||
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.base.ui.util.RecyclerViewOwner
|
||||
import org.koitharu.kotatsu.base.ui.util.ReversibleAction
|
||||
import org.koitharu.kotatsu.bookmarks.ui.BookmarksActivity
|
||||
import org.koitharu.kotatsu.databinding.FragmentExploreBinding
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
@@ -31,6 +34,7 @@ import org.koitharu.kotatsu.search.ui.MangaListActivity
|
||||
import org.koitharu.kotatsu.settings.SettingsActivity
|
||||
import org.koitharu.kotatsu.suggestions.ui.SuggestionsActivity
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ExploreFragment :
|
||||
@@ -67,6 +71,7 @@ class ExploreFragment :
|
||||
}
|
||||
viewModel.onError.observe(viewLifecycleOwner, ::onError)
|
||||
viewModel.onOpenManga.observe(viewLifecycleOwner, ::onOpenManga)
|
||||
viewModel.onActionDone.observe(viewLifecycleOwner, ::onActionDone)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
@@ -95,6 +100,7 @@ class ExploreFragment :
|
||||
viewModel.openRandom()
|
||||
return
|
||||
}
|
||||
|
||||
else -> return
|
||||
}
|
||||
startActivity(intent)
|
||||
@@ -105,6 +111,14 @@ class ExploreFragment :
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
override fun onItemLongClick(item: ExploreItem.Source, view: View): Boolean {
|
||||
val menu = PopupMenu(view.context, view)
|
||||
menu.inflate(R.menu.popup_source)
|
||||
menu.setOnMenuItemClickListener(SourceMenuListener(item))
|
||||
menu.show()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onRetryClick(error: Throwable) = Unit
|
||||
|
||||
override fun onEmptyActionClick() = onManageClick(requireView())
|
||||
@@ -124,6 +138,37 @@ class ExploreFragment :
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
private fun onActionDone(action: ReversibleAction) {
|
||||
val handle = action.handle
|
||||
val length = if (handle == null) Snackbar.LENGTH_SHORT else Snackbar.LENGTH_LONG
|
||||
val snackbar = Snackbar.make(binding.recyclerView, action.stringResId, length)
|
||||
if (handle != null) {
|
||||
snackbar.setAction(R.string.undo) { handle.reverseAsync() }
|
||||
}
|
||||
snackbar.anchorView = (activity as? BottomNavOwner)?.bottomNav
|
||||
snackbar.show()
|
||||
}
|
||||
|
||||
private inner class SourceMenuListener(
|
||||
private val sourceItem: ExploreItem.Source,
|
||||
) : PopupMenu.OnMenuItemClickListener {
|
||||
|
||||
override fun onMenuItemClick(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.action_settings -> {
|
||||
startActivity(SettingsActivity.newSourceSettingsIntent(requireContext(), sourceItem.source))
|
||||
}
|
||||
|
||||
R.id.action_hide -> {
|
||||
viewModel.hideSource(sourceItem.source)
|
||||
}
|
||||
|
||||
else -> return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance() = ExploreFragment()
|
||||
|
||||
@@ -4,11 +4,17 @@ import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.asFlow
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.domain.ReversibleHandle
|
||||
import org.koitharu.kotatsu.base.ui.BaseViewModel
|
||||
import org.koitharu.kotatsu.base.ui.util.ReversibleAction
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.explore.domain.ExploreRepository
|
||||
import org.koitharu.kotatsu.explore.ui.model.ExploreItem
|
||||
@@ -16,6 +22,7 @@ import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.utils.SingleLiveEvent
|
||||
import org.koitharu.kotatsu.utils.ext.asLiveDataDistinct
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ExploreViewModel @Inject constructor(
|
||||
@@ -24,6 +31,7 @@ class ExploreViewModel @Inject constructor(
|
||||
) : BaseViewModel() {
|
||||
|
||||
val onOpenManga = SingleLiveEvent<Manga>()
|
||||
val onActionDone = SingleLiveEvent<ReversibleAction>()
|
||||
|
||||
val content: LiveData<List<ExploreItem>> = isLoading.asFlow().flatMapLatest { loading ->
|
||||
if (loading) {
|
||||
@@ -40,6 +48,16 @@ class ExploreViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun hideSource(source: MangaSource) {
|
||||
launchJob(Dispatchers.Default) {
|
||||
settings.hiddenSources += source.name
|
||||
val rollback = ReversibleHandle {
|
||||
settings.hiddenSources -= source.name
|
||||
}
|
||||
onActionDone.postCall(ReversibleAction(R.string.source_disabled, rollback))
|
||||
}
|
||||
}
|
||||
|
||||
private fun createContentFlow() = settings.observe()
|
||||
.filter {
|
||||
it == AppSettings.KEY_SOURCES_HIDDEN ||
|
||||
|
||||
13
app/src/main/res/menu/popup_source.xml
Normal file
13
app/src/main/res/menu/popup_source.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:title="@string/settings" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_hide"
|
||||
android:title="@string/hide" />
|
||||
|
||||
</menu>
|
||||
@@ -398,4 +398,5 @@
|
||||
<string name="server_error">Server side error (%1$d). Please try again later</string>
|
||||
<string name="clear_new_chapters_counters">Also clear information about new chapters</string>
|
||||
<string name="compact">Compact</string>
|
||||
<string name="source_disabled">Source disabled</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user