From 87a0ef5a42cba10339e7c68bd77da6897c2f0165 Mon Sep 17 00:00:00 2001 From: Ryan Harg <3821-ryan_harg@users.noreply.dev.funkwhale.audio> Date: Fri, 9 Dec 2022 08:49:41 +0000 Subject: [PATCH] Filter favorites --- app/src/main/AndroidManifest.xml | 1 + .../ffa/adapters/FavoritesAdapter.kt | 10 +++ .../ffa/fragments/AddToPlaylistDialog.kt | 2 +- .../funkwhale/ffa/fragments/FFAFragment.kt | 27 ++++++-- .../ffa/fragments/FavoritesFragment.kt | 20 +++++- .../ffa/fragments/LandscapeQueueFragment.kt | 2 +- .../funkwhale/ffa/fragments/QueueFragment.kt | 2 +- .../funkwhale/ffa/fragments/TracksFragment.kt | 10 +-- .../java/audio/funkwhale/ffa/model/Track.kt | 13 ++-- .../audio/funkwhale/ffa/utils/Extensions.kt | 3 + .../main/res/layout/fragment_favorites.xml | 15 ++++- .../audio/funkwhale/ffa/model/TrackTest.kt | 64 +++++++++++++++++++ .../funkwhale/ffa/utils/ExtensionsKtTest.kt | 30 +++++++++ changes/changelog.d/132.feature | 1 + 14 files changed, 180 insertions(+), 20 deletions(-) create mode 100644 app/src/test/java/audio/funkwhale/ffa/model/TrackTest.kt create mode 100644 app/src/test/java/audio/funkwhale/ffa/utils/ExtensionsKtTest.kt create mode 100644 changes/changelog.d/132.feature diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 24462a3..3dd0c98 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ + diff --git a/app/src/main/java/audio/funkwhale/ffa/adapters/FavoritesAdapter.kt b/app/src/main/java/audio/funkwhale/ffa/adapters/FavoritesAdapter.kt index afe16e5..8a1728e 100644 --- a/app/src/main/java/audio/funkwhale/ffa/adapters/FavoritesAdapter.kt +++ b/app/src/main/java/audio/funkwhale/ffa/adapters/FavoritesAdapter.kt @@ -37,6 +37,7 @@ class FavoritesAdapter( private lateinit var binding: RowTrackBinding var currentTrack: Track? = null + var filter = "" override fun getItemCount() = data.size @@ -44,6 +45,15 @@ class FavoritesAdapter( return data[position].id.toLong() } + override fun applyFilter() { + data.clear() + getUnfilteredData().map { + if (it.matchesFilter(filter)) { + data.add(it) + } + } + } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { binding = RowTrackBinding.inflate(layoutInflater, parent, false) diff --git a/app/src/main/java/audio/funkwhale/ffa/fragments/AddToPlaylistDialog.kt b/app/src/main/java/audio/funkwhale/ffa/fragments/AddToPlaylistDialog.kt index fee6330..3e424ad 100644 --- a/app/src/main/java/audio/funkwhale/ffa/fragments/AddToPlaylistDialog.kt +++ b/app/src/main/java/audio/funkwhale/ffa/fragments/AddToPlaylistDialog.kt @@ -106,7 +106,7 @@ object AddToPlaylistDialog { fetch().untilNetwork(lifecycleScope) { data, isCache, _, hasMore -> if (isCache) { - adapter.data = data.toMutableList() + adapter.setUnfilteredData(data.toMutableList()) adapter.notifyDataSetChanged() return@untilNetwork diff --git a/app/src/main/java/audio/funkwhale/ffa/fragments/FFAFragment.kt b/app/src/main/java/audio/funkwhale/ffa/fragments/FFAFragment.kt index 0303c87..375087c 100644 --- a/app/src/main/java/audio/funkwhale/ffa/fragments/FFAFragment.kt +++ b/app/src/main/java/audio/funkwhale/ffa/fragments/FFAFragment.kt @@ -18,12 +18,26 @@ import com.google.gson.Gson import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.withContext abstract class FFAAdapter : RecyclerView.Adapter() { var data: MutableList = mutableListOf() + private var unfilteredData: MutableList = mutableListOf() + + fun getUnfilteredData(): MutableList { + return unfilteredData + } + + fun setUnfilteredData(data: MutableList) { + unfilteredData = data + applyFilter() + } + + open fun applyFilter() { + data.clear() + data.addAll(unfilteredData) + } init { super.setHasStableIds(true) @@ -130,19 +144,20 @@ abstract class FFAFragment>() : Fragment() { if (isCache) { moreLoading = false - adapter.data = data.toMutableList() + adapter.setUnfilteredData(data.toMutableList()) adapter.notifyDataSetChanged() return@launch } if (first) { - adapter.data.clear() + adapter.getUnfilteredData().clear() } onDataFetched(data) - adapter.data.addAll(data) + adapter.getUnfilteredData().addAll(data) + adapter.applyFilter() withContext(IO) { try { @@ -150,7 +165,7 @@ abstract class FFAFragment>() : Fragment() { FFACache.set( context, cacheId, - Gson().toJson(repository.cache(adapter.data)).toString() + Gson().toJson(repository.cache(adapter.getUnfilteredData())).toString() ) } } catch (e: ConcurrentModificationException) { @@ -161,7 +176,7 @@ abstract class FFAFragment>() : Fragment() { (repository.upstream as? HttpUpstream<*, *>)?.let { upstream -> if (!isCache && upstream.behavior == HttpUpstream.Behavior.Progressive) { if (first || needsMoreOffscreenPages()) { - fetch(Repository.Origin.Network.origin, adapter.data.size) + fetch(Repository.Origin.Network.origin, adapter.getUnfilteredData().size) } else { moreLoading = false } diff --git a/app/src/main/java/audio/funkwhale/ffa/fragments/FavoritesFragment.kt b/app/src/main/java/audio/funkwhale/ffa/fragments/FavoritesFragment.kt index bd5b53d..8efdda1 100644 --- a/app/src/main/java/audio/funkwhale/ffa/fragments/FavoritesFragment.kt +++ b/app/src/main/java/audio/funkwhale/ffa/fragments/FavoritesFragment.kt @@ -1,6 +1,8 @@ package audio.funkwhale.ffa.fragments import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -53,6 +55,20 @@ class FavoritesFragment : FFAFragment() { ): View { _binding = FragmentFavoritesBinding.inflate(inflater) swiper = binding.swiper + binding.filterTracks.addTextChangedListener(object : TextWatcher { + + override fun afterTextChanged(s: Editable) { + + adapter.applyFilter() + adapter.notifyDataSetChanged() + } + + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { } + + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { + adapter.filter = s.toString() + } + }) return binding.root } @@ -105,11 +121,13 @@ class FavoritesFragment : FFAFragment() { val downloaded = TracksRepository.getDownloadedIds(exoDownloadManager) ?: listOf() withContext(Main) { - adapter.data = adapter.data.map { + val data = adapter.data.map { it.downloaded = downloaded.contains(it.id) it }.toMutableList() + adapter.setUnfilteredData(data) + adapter.notifyDataSetChanged() } } diff --git a/app/src/main/java/audio/funkwhale/ffa/fragments/LandscapeQueueFragment.kt b/app/src/main/java/audio/funkwhale/ffa/fragments/LandscapeQueueFragment.kt index 9087c22..1595b3a 100644 --- a/app/src/main/java/audio/funkwhale/ffa/fragments/LandscapeQueueFragment.kt +++ b/app/src/main/java/audio/funkwhale/ffa/fragments/LandscapeQueueFragment.kt @@ -92,7 +92,7 @@ class LandscapeQueueFragment : Fragment() { activity?.lifecycleScope?.launch(Main) { RequestBus.send(Request.GetQueue).wait()?.let { response -> adapter?.let { - it.data = response.queue.toMutableList() + it.setUnfilteredData(response.queue.toMutableList()) it.notifyDataSetChanged() if (it.data.isEmpty()) { diff --git a/app/src/main/java/audio/funkwhale/ffa/fragments/QueueFragment.kt b/app/src/main/java/audio/funkwhale/ffa/fragments/QueueFragment.kt index 2287e80..95d2bcb 100644 --- a/app/src/main/java/audio/funkwhale/ffa/fragments/QueueFragment.kt +++ b/app/src/main/java/audio/funkwhale/ffa/fragments/QueueFragment.kt @@ -108,7 +108,7 @@ class QueueFragment : BottomSheetDialogFragment() { RequestBus.send(Request.GetQueue).wait()?.let { response -> binding.included.let { included -> adapter?.let { - it.data = response.queue.toMutableList() + it.setUnfilteredData(response.queue.toMutableList()) it.notifyDataSetChanged() if (it.data.isEmpty()) { diff --git a/app/src/main/java/audio/funkwhale/ffa/fragments/TracksFragment.kt b/app/src/main/java/audio/funkwhale/ffa/fragments/TracksFragment.kt index 8794a5b..fe5a407 100644 --- a/app/src/main/java/audio/funkwhale/ffa/fragments/TracksFragment.kt +++ b/app/src/main/java/audio/funkwhale/ffa/fragments/TracksFragment.kt @@ -269,10 +269,12 @@ class TracksFragment : FFAFragment() { val downloaded = TracksRepository.getDownloadedIds(exoDownloadManager) ?: listOf() withContext(Main) { - adapter.data = adapter.data.map { - it.downloaded = downloaded.contains(it.id) - it - }.toMutableList() + adapter.setUnfilteredData( + adapter.data.map { + it.downloaded = downloaded.contains(it.id) + it + }.toMutableList() + ) adapter.notifyDataSetChanged() } diff --git a/app/src/main/java/audio/funkwhale/ffa/model/Track.kt b/app/src/main/java/audio/funkwhale/ffa/model/Track.kt index e29761e..5a80fe6 100644 --- a/app/src/main/java/audio/funkwhale/ffa/model/Track.kt +++ b/app/src/main/java/audio/funkwhale/ffa/model/Track.kt @@ -1,5 +1,6 @@ package audio.funkwhale.ffa.model +import audio.funkwhale.ffa.utils.containsIgnoringCase import com.preference.PowerPreference data class Track( @@ -29,11 +30,13 @@ data class Track( ) } - data class Upload( - val listen_url: String, - val duration: Int, - val bitrate: Int - ) + data class Upload(val listen_url: String, val duration: Int, val bitrate: Int) + + fun matchesFilter(filter: String): Boolean { + return title.containsIgnoringCase(filter) || + artist.name.containsIgnoringCase(filter) || + album?.title.containsIgnoringCase(filter) + } override fun equals(other: Any?): Boolean { return when (other) { diff --git a/app/src/main/java/audio/funkwhale/ffa/utils/Extensions.kt b/app/src/main/java/audio/funkwhale/ffa/utils/Extensions.kt index 0f30d81..274a277 100644 --- a/app/src/main/java/audio/funkwhale/ffa/utils/Extensions.kt +++ b/app/src/main/java/audio/funkwhale/ffa/utils/Extensions.kt @@ -114,3 +114,6 @@ val ISO_8601_DATE_TIME_FORMAT = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") fun Date.format(): String { return ISO_8601_DATE_TIME_FORMAT.format(this) } + +fun String?.containsIgnoringCase(candidate: String): Boolean = + this != null && this.lowercase().contains(candidate.lowercase()) diff --git a/app/src/main/res/layout/fragment_favorites.xml b/app/src/main/res/layout/fragment_favorites.xml index ce07731..cbea989 100644 --- a/app/src/main/res/layout/fragment_favorites.xml +++ b/app/src/main/res/layout/fragment_favorites.xml @@ -39,14 +39,27 @@ android:clipChildren="false" app:layout_collapseMode="parallax"> + +