From d8f8c3c1933142a83b0c60b0dc6b53f18c697527 Mon Sep 17 00:00:00 2001 From: Ryan Harg Date: Fri, 10 Sep 2021 13:36:28 +0200 Subject: [PATCH] #28: Auto update favorites list - Also removes duplicate favorite listeners --- .../ffa/activities/SearchActivity.kt | 96 +++++++++---------- .../ffa/adapters/FavoriteListener.kt | 13 +++ .../ffa/adapters/FavoritesAdapter.kt | 8 +- .../ffa/adapters/PlaylistTracksAdapter.kt | 14 +-- .../funkwhale/ffa/adapters/SearchAdapter.kt | 14 +-- .../funkwhale/ffa/adapters/TracksAdapter.kt | 8 +- .../funkwhale/ffa/fragments/FFAFragment.kt | 2 + .../ffa/fragments/FavoritesFragment.kt | 21 ++-- .../ffa/fragments/LandscapeQueueFragment.kt | 11 ++- .../ffa/fragments/PlaylistTracksFragment.kt | 12 +-- .../funkwhale/ffa/fragments/QueueFragment.kt | 17 ++-- .../funkwhale/ffa/fragments/TracksFragment.kt | 15 +-- changes/changelog.d/28.misc | 1 + 13 files changed, 109 insertions(+), 123 deletions(-) create mode 100644 app/src/main/java/audio/funkwhale/ffa/adapters/FavoriteListener.kt create mode 100644 changes/changelog.d/28.misc diff --git a/app/src/main/java/audio/funkwhale/ffa/activities/SearchActivity.kt b/app/src/main/java/audio/funkwhale/ffa/activities/SearchActivity.kt index b5b574c..7f1a9e8 100644 --- a/app/src/main/java/audio/funkwhale/ffa/activities/SearchActivity.kt +++ b/app/src/main/java/audio/funkwhale/ffa/activities/SearchActivity.kt @@ -3,9 +3,11 @@ package audio.funkwhale.ffa.activities import android.os.Bundle import android.view.View import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.SearchView import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager +import audio.funkwhale.ffa.adapters.FavoriteListener import audio.funkwhale.ffa.adapters.SearchAdapter import audio.funkwhale.ffa.databinding.ActivitySearchBinding import audio.funkwhale.ffa.fragments.AddToPlaylistDialog @@ -51,7 +53,12 @@ class SearchActivity : AppCompatActivity() { setContentView(binding.root) adapter = - SearchAdapter(layoutInflater, this, SearchResultClickListener(), FavoriteListener()).also { + SearchAdapter( + layoutInflater, + this, + SearchResultClickListener(), + FavoriteListener(favoritesRepository) + ).also { binding.results.layoutManager = LinearLayoutManager(this) binding.results.adapter = it } @@ -90,59 +97,59 @@ class SearchActivity : AppCompatActivity() { tracksRepository = TracksSearchRepository(this@SearchActivity, "") favoritesRepository = FavoritesRepository(this@SearchActivity) - binding.search.setOnQueryTextListener(object : - androidx.appcompat.widget.SearchView.OnQueryTextListener { - override fun onQueryTextSubmit(rawQuery: String?): Boolean { - binding.search.clearFocus() + binding.search.setOnQueryTextListener(object : SearchView.OnQueryTextListener { - rawQuery?.let { - done = 0 + override fun onQueryTextSubmit(rawQuery: String?): Boolean { + binding.search.clearFocus() - val query = URLEncoder.encode(it, "UTF-8") + rawQuery?.let { + done = 0 - artistsRepository.query = query.lowercase(Locale.ROOT) - albumsRepository.query = query.lowercase(Locale.ROOT) - tracksRepository.query = query.lowercase(Locale.ROOT) + val query = URLEncoder.encode(it, "UTF-8") - binding.searchSpinner.visibility = View.VISIBLE - binding.searchEmpty.visibility = View.GONE - binding.searchNoResults.visibility = View.GONE + artistsRepository.query = query.lowercase(Locale.ROOT) + albumsRepository.query = query.lowercase(Locale.ROOT) + tracksRepository.query = query.lowercase(Locale.ROOT) - adapter.artists.clear() - adapter.albums.clear() - adapter.tracks.clear() - adapter.notifyDataSetChanged() + binding.searchSpinner.visibility = View.VISIBLE + binding.searchEmpty.visibility = View.GONE + binding.searchNoResults.visibility = View.GONE - artistsRepository.fetch(Repository.Origin.Network.origin) - .untilNetwork(lifecycleScope) { artists, _, _, _ -> - done++ + adapter.artists.clear() + adapter.albums.clear() + adapter.tracks.clear() + adapter.notifyDataSetChanged() - adapter.artists.addAll(artists) - refresh() - } + artistsRepository.fetch(Repository.Origin.Network.origin) + .untilNetwork(lifecycleScope) { artists, _, _, _ -> + done++ - albumsRepository.fetch(Repository.Origin.Network.origin) - .untilNetwork(lifecycleScope) { albums, _, _, _ -> - done++ + adapter.artists.addAll(artists) + refresh() + } - adapter.albums.addAll(albums) - refresh() - } + albumsRepository.fetch(Repository.Origin.Network.origin) + .untilNetwork(lifecycleScope) { albums, _, _, _ -> + done++ - tracksRepository.fetch(Repository.Origin.Network.origin) - .untilNetwork(lifecycleScope) { tracks, _, _, _ -> - done++ + adapter.albums.addAll(albums) + refresh() + } - adapter.tracks.addAll(tracks) - refresh() - } - } + tracksRepository.fetch(Repository.Origin.Network.origin) + .untilNetwork(lifecycleScope) { tracks, _, _, _ -> + done++ - return true + adapter.tracks.addAll(tracks) + refresh() + } } - override fun onQueryTextChange(newText: String?) = true - }) + return true + } + + override fun onQueryTextChange(newText: String?) = true + }) } private fun refresh() { @@ -187,13 +194,4 @@ class SearchActivity : AppCompatActivity() { AlbumsFragment.openTracks(this@SearchActivity, album) } } - - inner class FavoriteListener : SearchAdapter.OnFavoriteListener { - override fun onToggleFavorite(id: Int, state: Boolean) { - when (state) { - true -> favoritesRepository.addFavorite(id) - false -> favoritesRepository.deleteFavorite(id) - } - } - } } diff --git a/app/src/main/java/audio/funkwhale/ffa/adapters/FavoriteListener.kt b/app/src/main/java/audio/funkwhale/ffa/adapters/FavoriteListener.kt new file mode 100644 index 0000000..465acce --- /dev/null +++ b/app/src/main/java/audio/funkwhale/ffa/adapters/FavoriteListener.kt @@ -0,0 +1,13 @@ +package audio.funkwhale.ffa.adapters + +import audio.funkwhale.ffa.repositories.FavoritesRepository + +class FavoriteListener(private val repository: FavoritesRepository) { + + fun onToggleFavorite(id: Int, state: Boolean) { + when (state) { + true -> repository.addFavorite(id) + false -> repository.deleteFavorite(id) + } + } +} 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 95fe68a..afe16e5 100644 --- a/app/src/main/java/audio/funkwhale/ffa/adapters/FavoritesAdapter.kt +++ b/app/src/main/java/audio/funkwhale/ffa/adapters/FavoritesAdapter.kt @@ -26,18 +26,14 @@ import java.util.Collections class FavoritesAdapter( private val layoutInflater: LayoutInflater, private val context: Context?, - private val favoriteListener: OnFavoriteListener, - val fromQueue: Boolean = false + private val favoriteListener: FavoriteListener, + val fromQueue: Boolean = false, ) : FFAAdapter() { init { this.stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY } - interface OnFavoriteListener { - fun onToggleFavorite(id: Int, state: Boolean) - } - private lateinit var binding: RowTrackBinding var currentTrack: Track? = null diff --git a/app/src/main/java/audio/funkwhale/ffa/adapters/PlaylistTracksAdapter.kt b/app/src/main/java/audio/funkwhale/ffa/adapters/PlaylistTracksAdapter.kt index 70693df..0227dbe 100644 --- a/app/src/main/java/audio/funkwhale/ffa/adapters/PlaylistTracksAdapter.kt +++ b/app/src/main/java/audio/funkwhale/ffa/adapters/PlaylistTracksAdapter.kt @@ -30,14 +30,10 @@ import java.util.Collections class PlaylistTracksAdapter( private val layoutInflater: LayoutInflater, private val context: Context?, - private val favoriteListener: OnFavoriteListener? = null, - private val playlistListener: OnPlaylistListener? = null + private val favoriteListener: FavoriteListener, + private val playlistListener: OnPlaylistListener ) : FFAAdapter() { - interface OnFavoriteListener { - fun onToggleFavorite(id: Int, state: Boolean) - } - private lateinit var binding: RowTrackBinding interface OnPlaylistListener { @@ -103,7 +99,7 @@ class PlaylistTracksAdapter( } holder.favorite.setOnClickListener { - favoriteListener?.let { + favoriteListener.let { favoriteListener.onToggleFavorite(track.track.id, !track.track.favorite) track.track.favorite = !track.track.favorite @@ -124,7 +120,7 @@ class PlaylistTracksAdapter( R.id.track_add_to_queue -> CommandBus.send(Command.AddToQueue(listOf(track.track))) R.id.track_play_next -> CommandBus.send(Command.PlayNext(track.track)) R.id.queue_remove -> CommandBus.send(Command.RemoveFromQueue(track.track)) - R.id.track_remove_from_playlist -> playlistListener?.onRemoveTrackFromPlaylist( + R.id.track_remove_from_playlist -> playlistListener.onRemoveTrackFromPlaylist( track.track, position ) @@ -223,7 +219,7 @@ class PlaylistTracksAdapter( viewHolder.itemView.background = ColorDrawable(Color.TRANSPARENT) if (from != -1 && to != -1 && from != to) { - playlistListener?.onMoveTrack(from, to) + playlistListener.onMoveTrack(from, to) from = -1 to = -1 diff --git a/app/src/main/java/audio/funkwhale/ffa/adapters/SearchAdapter.kt b/app/src/main/java/audio/funkwhale/ffa/adapters/SearchAdapter.kt index f5b2b97..46ccf3d 100644 --- a/app/src/main/java/audio/funkwhale/ffa/adapters/SearchAdapter.kt +++ b/app/src/main/java/audio/funkwhale/ffa/adapters/SearchAdapter.kt @@ -30,8 +30,8 @@ import jp.wasabeef.picasso.transformations.RoundedCornersTransformation class SearchAdapter( private val layoutInflater: LayoutInflater, private val context: Context?, - private val listener: OnSearchResultClickListener? = null, - private val favoriteListener: OnFavoriteListener? = null + private val listener: OnSearchResultClickListener, + private val favoriteListener: FavoriteListener ) : RecyclerView.Adapter() { interface OnSearchResultClickListener { @@ -39,10 +39,6 @@ class SearchAdapter( fun onAlbumClick(holder: View?, album: Album) } - interface OnFavoriteListener { - fun onToggleFavorite(id: Int, state: Boolean) - } - enum class ResultType { Header, Artist, @@ -244,7 +240,7 @@ class SearchAdapter( } rowTrackViewHolder?.favorite?.setOnClickListener { - favoriteListener?.let { + favoriteListener.let { favoriteListener.onToggleFavorite(track.id, !track.favorite) tracks[position - artists.size - albums.size - sectionCount].favorite = @@ -341,13 +337,13 @@ class SearchAdapter( ResultType.Artist.ordinal -> { val position = layoutPosition - 1 - listener?.onArtistClick(view, artists[position]) + listener.onArtistClick(view, artists[position]) } ResultType.Album.ordinal -> { val position = layoutPosition - artists.size - 2 - listener?.onAlbumClick(view, albums[position]) + listener.onAlbumClick(view, albums[position]) } ResultType.Track.ordinal -> { diff --git a/app/src/main/java/audio/funkwhale/ffa/adapters/TracksAdapter.kt b/app/src/main/java/audio/funkwhale/ffa/adapters/TracksAdapter.kt index 499e799..a2213ea 100644 --- a/app/src/main/java/audio/funkwhale/ffa/adapters/TracksAdapter.kt +++ b/app/src/main/java/audio/funkwhale/ffa/adapters/TracksAdapter.kt @@ -31,7 +31,7 @@ import java.util.Collections class TracksAdapter( private val layoutInflater: LayoutInflater, private val context: Context?, - private val favoriteListener: OnFavoriteListener? = null, + private val favoriteListener: FavoriteListener, val fromQueue: Boolean = false ) : FFAAdapter() { @@ -39,10 +39,6 @@ class TracksAdapter( this.stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY } - interface OnFavoriteListener { - fun onToggleFavorite(id: Int, state: Boolean) - } - private lateinit var binding: RowTrackBinding private lateinit var touchHelper: ItemTouchHelper @@ -101,7 +97,7 @@ class TracksAdapter( } holder.favorite.setOnClickListener { - favoriteListener?.let { + favoriteListener.let { favoriteListener.onToggleFavorite(track.id, !track.favorite) data[position].favorite = !track.favorite 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 c2c1840..60cc066 100644 --- a/app/src/main/java/audio/funkwhale/ffa/fragments/FFAFragment.kt +++ b/app/src/main/java/audio/funkwhale/ffa/fragments/FFAFragment.kt @@ -48,6 +48,8 @@ abstract class FFAFragment>() : Fragment() { private var moreLoading = false private var listener: Job? = null + fun repository() = repository as T + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) 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 38d65fc..3daf536 100644 --- a/app/src/main/java/audio/funkwhale/ffa/fragments/FavoritesFragment.kt +++ b/app/src/main/java/audio/funkwhale/ffa/fragments/FavoritesFragment.kt @@ -6,6 +6,7 @@ import android.view.View import android.view.ViewGroup import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView +import audio.funkwhale.ffa.adapters.FavoriteListener import audio.funkwhale.ffa.adapters.FavoritesAdapter import audio.funkwhale.ffa.databinding.FragmentFavoritesBinding import audio.funkwhale.ffa.model.Track @@ -41,8 +42,8 @@ class FavoritesFragment : FFAFragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - adapter = FavoritesAdapter(layoutInflater, context, FavoriteListener()) repository = FavoritesRepository(context) + adapter = FavoritesAdapter(layoutInflater, context, FavoriteListener(repository())) watchEventBus() } @@ -72,6 +73,7 @@ class FavoritesFragment : FFAFragment() { } } + refreshFavoritedTracks() refreshDownloadedTracks() } @@ -98,6 +100,12 @@ class FavoritesFragment : FFAFragment() { } } + private fun refreshFavoritedTracks() { + lifecycleScope.launch(Main) { + update() + } + } + private suspend fun refreshDownloadedTracks() { val downloaded = TracksRepository.getDownloadedIds(exoDownloadManager) ?: listOf() @@ -134,15 +142,4 @@ class FavoritesFragment : FFAFragment() { adapter.notifyDataSetChanged() } } - - inner class FavoriteListener : FavoritesAdapter.OnFavoriteListener { - override fun onToggleFavorite(id: Int, state: Boolean) { - (repository as? FavoritesRepository)?.let { repository -> - when (state) { - true -> repository.addFavorite(id) - false -> repository.deleteFavorite(id) - } - } - } - } } 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 07dfe7d..749b846 100644 --- a/app/src/main/java/audio/funkwhale/ffa/fragments/LandscapeQueueFragment.kt +++ b/app/src/main/java/audio/funkwhale/ffa/fragments/LandscapeQueueFragment.kt @@ -7,8 +7,10 @@ import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager +import audio.funkwhale.ffa.adapters.FavoriteListener import audio.funkwhale.ffa.adapters.TracksAdapter import audio.funkwhale.ffa.databinding.PartialQueueBinding +import audio.funkwhale.ffa.repositories.FavoritesRepository import audio.funkwhale.ffa.utils.Command import audio.funkwhale.ffa.utils.CommandBus import audio.funkwhale.ffa.utils.Event @@ -26,6 +28,8 @@ class LandscapeQueueFragment : Fragment() { private var _binding: PartialQueueBinding? = null private val binding get() = _binding!! + lateinit var favoritesRepository: FavoritesRepository + private var adapter: TracksAdapter? = null override fun onCreate(savedInstanceState: Bundle?) { @@ -41,7 +45,12 @@ class LandscapeQueueFragment : Fragment() { ): View { _binding = PartialQueueBinding.inflate(inflater) return binding.root.apply { - adapter = TracksAdapter(layoutInflater, context, fromQueue = true).also { + adapter = TracksAdapter( + layoutInflater, + context, + fromQueue = true, + favoriteListener = FavoriteListener(favoritesRepository) + ).also { binding.queue.layoutManager = LinearLayoutManager(context) binding.queue.adapter = it } diff --git a/app/src/main/java/audio/funkwhale/ffa/fragments/PlaylistTracksFragment.kt b/app/src/main/java/audio/funkwhale/ffa/fragments/PlaylistTracksFragment.kt index 1b3ac64..2a0a2b9 100644 --- a/app/src/main/java/audio/funkwhale/ffa/fragments/PlaylistTracksFragment.kt +++ b/app/src/main/java/audio/funkwhale/ffa/fragments/PlaylistTracksFragment.kt @@ -10,6 +10,7 @@ import androidx.core.os.bundleOf import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import audio.funkwhale.ffa.R +import audio.funkwhale.ffa.adapters.FavoriteListener import audio.funkwhale.ffa.adapters.PlaylistTracksAdapter import audio.funkwhale.ffa.databinding.FragmentTracksBinding import audio.funkwhale.ffa.model.Playlist @@ -71,7 +72,7 @@ class PlaylistTracksFragment : FFAFragment albumCover = getString("albumCover") ?: "" } - adapter = PlaylistTracksAdapter(layoutInflater, context, FavoriteListener(), PlaylistListener()) + adapter = PlaylistTracksAdapter(layoutInflater, context, FavoriteListener(favoritesRepository), PlaylistListener()) repository = PlaylistTracksRepository(context, albumId) favoritesRepository = FavoritesRepository(context) playlistsRepository = ManagementPlaylistsRepository(context) @@ -211,15 +212,6 @@ class PlaylistTracksFragment : FFAFragment } } - inner class FavoriteListener : PlaylistTracksAdapter.OnFavoriteListener { - override fun onToggleFavorite(id: Int, state: Boolean) { - when (state) { - true -> favoritesRepository.addFavorite(id) - false -> favoritesRepository.deleteFavorite(id) - } - } - } - inner class PlaylistListener : PlaylistTracksAdapter.OnPlaylistListener { override fun onMoveTrack(from: Int, to: Int) { playlistsRepository.move(albumId, from, to) 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 02e1b25..99c5c47 100644 --- a/app/src/main/java/audio/funkwhale/ffa/fragments/QueueFragment.kt +++ b/app/src/main/java/audio/funkwhale/ffa/fragments/QueueFragment.kt @@ -9,6 +9,7 @@ import androidx.fragment.app.DialogFragment import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import audio.funkwhale.ffa.R +import audio.funkwhale.ffa.adapters.FavoriteListener import audio.funkwhale.ffa.adapters.TracksAdapter import audio.funkwhale.ffa.databinding.FragmentQueueBinding import audio.funkwhale.ffa.repositories.FavoritesRepository @@ -62,7 +63,12 @@ class QueueFragment : BottomSheetDialogFragment() { ): View { _binding = FragmentQueueBinding.inflate(inflater) return binding.root.apply { - adapter = TracksAdapter(layoutInflater, context, FavoriteListener(), fromQueue = true).also { + adapter = TracksAdapter( + layoutInflater, + context, + FavoriteListener(favoritesRepository), + fromQueue = true + ).also { binding.included.queue.layoutManager = LinearLayoutManager(context) binding.included.queue.adapter = it } @@ -135,13 +141,4 @@ class QueueFragment : BottomSheetDialogFragment() { } } } - - inner class FavoriteListener : TracksAdapter.OnFavoriteListener { - override fun onToggleFavorite(id: Int, state: Boolean) { - when (state) { - true -> favoritesRepository.addFavorite(id) - false -> favoritesRepository.deleteFavorite(id) - } - } - } } 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 c8be2af..231ce44 100644 --- a/app/src/main/java/audio/funkwhale/ffa/fragments/TracksFragment.kt +++ b/app/src/main/java/audio/funkwhale/ffa/fragments/TracksFragment.kt @@ -12,6 +12,7 @@ import androidx.core.os.bundleOf import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import audio.funkwhale.ffa.R +import audio.funkwhale.ffa.adapters.FavoriteListener import audio.funkwhale.ffa.adapters.TracksAdapter import audio.funkwhale.ffa.databinding.FragmentTracksBinding import audio.funkwhale.ffa.model.Album @@ -83,10 +84,11 @@ class TracksFragment : FFAFragment() { albumCover = getString("albumCover") ?: "" } - adapter = TracksAdapter(layoutInflater, context, FavoriteListener()) - repository = TracksRepository(context, albumId) favoritesRepository = FavoritesRepository(context) favoritedRepository = FavoritedRepository(context) + repository = TracksRepository(context, albumId) + + adapter = TracksAdapter(layoutInflater, context, FavoriteListener(favoritesRepository)) watchEventBus() } @@ -294,13 +296,4 @@ class TracksFragment : FFAFragment() { adapter.notifyDataSetChanged() } } - - inner class FavoriteListener : TracksAdapter.OnFavoriteListener { - override fun onToggleFavorite(id: Int, state: Boolean) { - when (state) { - true -> favoritesRepository.addFavorite(id) - false -> favoritesRepository.deleteFavorite(id) - } - } - } } diff --git a/changes/changelog.d/28.misc b/changes/changelog.d/28.misc new file mode 100644 index 0000000..8809341 --- /dev/null +++ b/changes/changelog.d/28.misc @@ -0,0 +1 @@ +Automatically update the favorites list view (#28) \ No newline at end of file