#28: Auto update favorites list
- Also removes duplicate favorite listeners
This commit is contained in:
parent
687c61ed13
commit
d8f8c3c193
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Track, FavoritesAdapter.ViewHolder>() {
|
||||
|
||||
init {
|
||||
this.stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY
|
||||
}
|
||||
|
||||
interface OnFavoriteListener {
|
||||
fun onToggleFavorite(id: Int, state: Boolean)
|
||||
}
|
||||
|
||||
private lateinit var binding: RowTrackBinding
|
||||
|
||||
var currentTrack: Track? = null
|
||||
|
|
|
@ -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<PlaylistTrack, PlaylistTracksAdapter.ViewHolder>() {
|
||||
|
||||
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
|
||||
|
|
|
@ -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<SearchAdapter.ViewHolder>() {
|
||||
|
||||
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 -> {
|
||||
|
|
|
@ -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<Track, TracksAdapter.ViewHolder>() {
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -48,6 +48,8 @@ abstract class FFAFragment<D : Any, A : FFAAdapter<D, *>>() : Fragment() {
|
|||
private var moreLoading = false
|
||||
private var listener: Job? = null
|
||||
|
||||
fun <T> repository() = repository as T
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
|
|
|
@ -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<Track, FavoritesAdapter>() {
|
|||
|
||||
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<Track, FavoritesAdapter>() {
|
|||
}
|
||||
}
|
||||
|
||||
refreshFavoritedTracks()
|
||||
refreshDownloadedTracks()
|
||||
}
|
||||
|
||||
|
@ -98,6 +100,12 @@ class FavoritesFragment : FFAFragment<Track, FavoritesAdapter>() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun refreshFavoritedTracks() {
|
||||
lifecycleScope.launch(Main) {
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun refreshDownloadedTracks() {
|
||||
val downloaded = TracksRepository.getDownloadedIds(exoDownloadManager) ?: listOf()
|
||||
|
||||
|
@ -134,15 +142,4 @@ class FavoritesFragment : FFAFragment<Track, FavoritesAdapter>() {
|
|||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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<PlaylistTrack, PlaylistTracksAdapter>
|
|||
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<PlaylistTrack, PlaylistTracksAdapter>
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Track, TracksAdapter>() {
|
|||
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<Track, TracksAdapter>() {
|
|||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
inner class FavoriteListener : TracksAdapter.OnFavoriteListener {
|
||||
override fun onToggleFavorite(id: Int, state: Boolean) {
|
||||
when (state) {
|
||||
true -> favoritesRepository.addFavorite(id)
|
||||
false -> favoritesRepository.deleteFavorite(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Automatically update the favorites list view (#28)
|
Loading…
Reference in New Issue