Add basic search in playlist

This commit is contained in:
tomaThomas 2024-10-11 19:25:15 +02:00
parent 1c49bdcd72
commit b9d3ee6ddb
No known key found for this signature in database
GPG key ID: DEE963DC84059108
4 changed files with 72 additions and 2 deletions

View file

@ -25,6 +25,7 @@ import code.name.monkey.retromusic.db.toSongEntity
import code.name.monkey.retromusic.db.toSongsEntity import code.name.monkey.retromusic.db.toSongsEntity
import code.name.monkey.retromusic.dialogs.RemoveSongFromPlaylistDialog import code.name.monkey.retromusic.dialogs.RemoveSongFromPlaylistDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ViewUtil
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter
@ -43,9 +44,20 @@ class OrderablePlaylistSongAdapter(
val libraryViewModel: LibraryViewModel by activity.viewModel() val libraryViewModel: LibraryViewModel by activity.viewModel()
private var filtered = false
private var filter: CharSequence? = null
private var fullDataSet: MutableList<Song>
init { init {
this.setHasStableIds(true) this.setHasStableIds(true)
this.setMultiSelectMenuRes(R.menu.menu_playlists_songs_selection) this.setMultiSelectMenuRes(R.menu.menu_playlists_songs_selection)
fullDataSet = dataSet.toMutableList()
}
override fun swapDataSet(dataSet: List<Song>) {
super.swapDataSet(dataSet)
fullDataSet = dataSet.toMutableList()
onFilter(filter)
} }
override fun getItemId(position: Int): Long { override fun getItemId(position: Int): Long {
@ -90,13 +102,22 @@ class OrderablePlaylistSongAdapter(
return super.onSongMenuItemClick(item) return super.onSongMenuItemClick(item)
} }
override fun onClick(v: View?) {
if (isInQuickSelectMode || !filtered) {
super.onClick(v)
} else {
val position = fullDataSet.indexOf(dataSet.get(layoutPosition))
MusicPlayerRemote.openQueue(fullDataSet, position, true)
}
}
init { init {
dragView?.isVisible = true dragView?.isVisible = true
} }
} }
override fun onCheckCanStartDrag(holder: ViewHolder, position: Int, x: Int, y: Int): Boolean { override fun onCheckCanStartDrag(holder: ViewHolder, position: Int, x: Int, y: Int): Boolean {
if (isInQuickSelectMode) { if (isInQuickSelectMode || filtered) {
return false return false
} }
return ViewUtil.hitTest(holder.imageText!!, x, y) || ViewUtil.hitTest( return ViewUtil.hitTest(holder.imageText!!, x, y) || ViewUtil.hitTest(
@ -127,8 +148,23 @@ class OrderablePlaylistSongAdapter(
} }
fun saveSongs(playlistEntity: PlaylistEntity) { fun saveSongs(playlistEntity: PlaylistEntity) {
onFilter(null)
activity.lifecycleScope.launch(Dispatchers.IO) { activity.lifecycleScope.launch(Dispatchers.IO) {
libraryViewModel.insertSongs(dataSet.toSongsEntity(playlistEntity)) libraryViewModel.insertSongs(dataSet.toSongsEntity(playlistEntity))
} }
} }
fun onFilter(text: CharSequence?) {
filter = text
if (text.isNullOrEmpty()) {
filtered = false
dataSet = fullDataSet
} else {
filtered = true
dataSet = fullDataSet.filter { song -> song.title.contains(text, ignoreCase = true) }
.toMutableList()
}
notifyDataSetChanged()
}
} }

View file

@ -8,6 +8,8 @@ import android.view.MenuItem
import android.view.View import android.view.View
import androidx.core.view.doOnPreDraw import androidx.core.view.doOnPreDraw
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.widget.addTextChangedListener
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@ -21,6 +23,7 @@ import code.name.monkey.retromusic.extensions.accentColor
import code.name.monkey.retromusic.extensions.elevatedAccentColor import code.name.monkey.retromusic.extensions.elevatedAccentColor
import code.name.monkey.retromusic.extensions.surfaceColor import code.name.monkey.retromusic.extensions.surfaceColor
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.fragments.search.clearText
import code.name.monkey.retromusic.glide.RetroGlideExtension.playlistOptions import code.name.monkey.retromusic.glide.RetroGlideExtension.playlistOptions
import code.name.monkey.retromusic.glide.playlistPreview.PlaylistPreview import code.name.monkey.retromusic.glide.playlistPreview.PlaylistPreview
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
@ -35,6 +38,9 @@ import com.google.android.material.transition.MaterialContainerTransform
import com.google.android.material.transition.MaterialSharedAxis import com.google.android.material.transition.MaterialSharedAxis
import com.h6ah4i.android.widget.advrecyclerview.animator.DraggableItemAnimator import com.h6ah4i.android.widget.advrecyclerview.animator.DraggableItemAnimator
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch
import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf import org.koin.core.parameter.parametersOf
@ -51,6 +57,8 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
private lateinit var playlist: PlaylistWithSongs private lateinit var playlist: PlaylistWithSongs
private lateinit var playlistSongAdapter: OrderablePlaylistSongAdapter private lateinit var playlistSongAdapter: OrderablePlaylistSongAdapter
private val _searchFlow = MutableSharedFlow<CharSequence?>()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
sharedElementEnterTransition = MaterialContainerTransform(requireContext(), true).apply { sharedElementEnterTransition = MaterialContainerTransform(requireContext(), true).apply {
@ -119,6 +127,16 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
ArrayList(), ArrayList(),
R.layout.item_queue R.layout.item_queue
) )
binding.playlistSearchView.addTextChangedListener { text ->
lifecycleScope.launch {
_searchFlow.emit(text)
}
}
lifecycleScope.launch {
_searchFlow.debounce(300).collect { text ->
playlistSongAdapter.onFilter(text)
}
}
val dragDropManager = RecyclerViewDragDropManager() val dragDropManager = RecyclerViewDragDropManager()
@ -160,6 +178,7 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
} }
override fun onPause() { override fun onPause() {
binding.playlistSearchView.clearText()
playlistSongAdapter.saveSongs(playlist.playlistEntity) playlistSongAdapter.saveSongs(playlist.playlistEntity)
super.onPause() super.onPause()
} }

View file

@ -30,6 +30,21 @@
android:paddingBottom="16dp" android:paddingBottom="16dp"
android:paddingHorizontal="16dp"> android:paddingHorizontal="16dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/playlistSearchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/play_button"
android:background="@null"
android:hint="@string/action_search"
android:inputType="text|textAutoComplete"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:textAppearance="@style/TextViewSubtitle1">
</com.google.android.material.textfield.TextInputEditText>
<com.google.android.material.imageview.ShapeableImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/image" android:id="@+id/image"
android:layout_width="0dp" android:layout_width="0dp"

View file

@ -17,7 +17,7 @@ yslibrary_keyboardvisibilityevent_version = "3.0.0-RC3"
koinAndroid = "3.4.0" koinAndroid = "3.4.0"
kotlinGradlePlugin = "1.9.22" kotlinGradlePlugin = "1.9.22"
kotlinxCoroutinesAndroid = "1.7.3" kotlinxCoroutinesAndroid = "1.8.1"
android_tab_library_version = "2.2.0" android_tab_library_version = "2.2.0"
fast_scroll_libraryVersion = "1.2.0" fast_scroll_libraryVersion = "1.2.0"
lifecycle_version = "2.7.0" lifecycle_version = "2.7.0"