funkwhale-app-android/app/src/main/java/audio/funkwhale/ffa/adapters/FavoritesAdapter.kt

182 lines
5.5 KiB
Kotlin
Raw Normal View History

package audio.funkwhale.ffa.adapters
2019-08-19 16:50:33 +02:00
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
2019-08-19 16:50:33 +02:00
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
2023-01-13 10:33:24 +01:00
import androidx.appcompat.content.res.AppCompatResources
2019-08-19 16:50:33 +02:00
import androidx.appcompat.widget.PopupMenu
import androidx.recyclerview.widget.RecyclerView
import audio.funkwhale.ffa.R
2021-07-16 10:03:52 +02:00
import audio.funkwhale.ffa.databinding.RowTrackBinding
import audio.funkwhale.ffa.fragments.FFAAdapter
2023-01-13 10:33:24 +01:00
import audio.funkwhale.ffa.model.Favorite
2021-09-09 09:56:15 +02:00
import audio.funkwhale.ffa.model.Track
2021-07-16 10:03:52 +02:00
import audio.funkwhale.ffa.utils.Command
import audio.funkwhale.ffa.utils.CommandBus
import audio.funkwhale.ffa.utils.CoverArt
2021-07-16 10:03:52 +02:00
import audio.funkwhale.ffa.utils.maybeNormalizeUrl
import audio.funkwhale.ffa.utils.toast
2019-08-19 16:50:33 +02:00
import jp.wasabeef.picasso.transformations.RoundedCornersTransformation
2021-07-16 10:03:52 +02:00
import java.util.Collections
class FavoritesAdapter(
private val layoutInflater: LayoutInflater,
private val context: Context?,
private val favoriteListener: FavoriteListener,
val fromQueue: Boolean = false,
2023-01-13 10:33:24 +01:00
) : FFAAdapter<Favorite, FavoritesAdapter.ViewHolder>() {
2019-08-19 16:50:33 +02:00
init {
this.stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY
}
2021-07-16 10:03:52 +02:00
private lateinit var binding: RowTrackBinding
2019-08-19 16:50:33 +02:00
var currentTrack: Track? = null
2022-12-09 09:49:41 +01:00
var filter = ""
2019-08-19 16:50:33 +02:00
override fun getItemCount() = data.size
override fun getItemId(position: Int): Long {
return data[position].id.toLong()
2019-08-19 16:50:33 +02:00
}
2022-12-09 09:49:41 +01:00
override fun applyFilter() {
data.clear()
getUnfilteredData().map {
2023-01-13 10:33:24 +01:00
if (it.track.matchesFilter(filter)) {
2022-12-09 09:49:41 +01:00
data.add(it)
}
}
}
2019-08-19 16:50:33 +02:00
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
2021-07-16 10:03:52 +02:00
binding = RowTrackBinding.inflate(layoutInflater, parent, false)
return ViewHolder(binding, context).also {
binding.root.setOnClickListener(it)
2019-08-19 16:50:33 +02:00
}
}
@SuppressLint("NewApi")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val favorite = data[position]
2023-01-13 10:33:24 +01:00
val track = favorite.track
2019-08-19 16:50:33 +02:00
CoverArt.requestCreator(maybeNormalizeUrl(track.cover()))
2019-08-19 16:50:33 +02:00
.fit()
.transform(RoundedCornersTransformation(16, 0))
.into(holder.cover)
2023-01-13 10:33:24 +01:00
holder.title.text = track.title
holder.artist.text = track.artist.name
2019-08-19 16:50:33 +02:00
context?.let {
2023-01-13 10:33:24 +01:00
holder.itemView.background = AppCompatResources.getDrawable(context, R.drawable.ripple)
}
2019-08-19 16:50:33 +02:00
2023-01-13 10:33:24 +01:00
if (track.id == currentTrack?.id) {
context?.let {
2023-01-13 10:33:24 +01:00
holder.itemView.background = AppCompatResources.getDrawable(context, R.drawable.current)
}
2019-08-19 16:50:33 +02:00
}
context?.let {
2023-01-13 10:33:24 +01:00
holder.favorite.setColorFilter(context.getColor(R.color.colorFavorite))
2019-08-19 16:50:33 +02:00
2023-01-13 10:33:24 +01:00
when (track.cached || track.downloaded) {
true -> holder.title.setCompoundDrawablesWithIntrinsicBounds(R.drawable.downloaded, 0, 0, 0)
false -> holder.title.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
}
2023-01-13 10:33:24 +01:00
if (track.cached && !track.downloaded) {
holder.title.compoundDrawables.forEach {
2021-07-16 10:03:52 +02:00
it?.colorFilter =
PorterDuffColorFilter(context.getColor(R.color.cached), PorterDuff.Mode.SRC_IN)
}
}
2023-01-13 10:33:24 +01:00
if (track.downloaded) {
holder.title.compoundDrawables.forEach {
2021-07-16 10:03:52 +02:00
it?.colorFilter =
PorterDuffColorFilter(context.getColor(R.color.downloaded), PorterDuff.Mode.SRC_IN)
}
}
2019-08-19 16:50:33 +02:00
holder.favorite.setOnClickListener {
2023-01-13 10:33:24 +01:00
favoriteListener.onToggleFavorite(track.id, !track.favorite)
2019-08-19 16:50:33 +02:00
data.remove(favorite)
notifyItemRemoved(holder.bindingAdapterPosition)
2019-08-19 16:50:33 +02:00
}
}
holder.actions.setOnClickListener {
context?.let { context ->
PopupMenu(context, holder.actions, Gravity.START, R.attr.actionOverflowMenuStyle, 0).apply {
inflate(if (fromQueue) R.menu.row_queue else R.menu.row_track)
setOnMenuItemClickListener {
when (it.itemId) {
2023-01-13 10:33:24 +01:00
R.id.track_add_to_queue -> CommandBus.send(Command.AddToQueue(listOf(track)))
R.id.track_play_next -> CommandBus.send(Command.PlayNext(track))
R.id.track_pin -> CommandBus.send(Command.PinTrack(track))
R.id.queue_remove -> CommandBus.send(Command.RemoveFromQueue(track))
2019-08-19 16:50:33 +02:00
}
true
}
show()
}
}
}
}
fun onItemMove(oldPosition: Int, newPosition: Int) {
if (oldPosition < newPosition) {
2019-10-21 11:51:32 +02:00
for (i in oldPosition.until(newPosition)) {
2019-08-19 16:50:33 +02:00
Collections.swap(data, i, i + 1)
}
} else {
for (i in newPosition.downTo(oldPosition)) {
Collections.swap(data, i, i - 1)
}
}
notifyItemMoved(oldPosition, newPosition)
CommandBus.send(Command.MoveFromQueue(oldPosition, newPosition))
}
2021-07-16 10:03:52 +02:00
inner class ViewHolder(binding: RowTrackBinding, val context: Context?) :
RecyclerView.ViewHolder(binding.root),
View.OnClickListener {
val cover = binding.cover
val title = binding.title
val artist = binding.artist
2019-08-19 16:50:33 +02:00
2021-07-16 10:03:52 +02:00
val favorite = binding.favorite
val actions = binding.actions
2019-08-19 16:50:33 +02:00
override fun onClick(view: View?) {
when (fromQueue) {
true -> CommandBus.send(Command.PlayTrack(layoutPosition))
false -> {
2023-01-13 10:33:24 +01:00
data
.subList(layoutPosition, data.size).plus(data.subList(0, layoutPosition))
.map { it.track }
.apply {
CommandBus.send(Command.ReplaceQueue(this))
context.toast("All tracks were added to your queue")
}
2019-08-19 16:50:33 +02:00
}
}
}
}
}