229 lines
7.9 KiB
Kotlin
229 lines
7.9 KiB
Kotlin
/*
|
|
* Copyright (c) 2020 Hemanth Savarla.
|
|
*
|
|
* Licensed under the GNU General Public License v3
|
|
*
|
|
* This is free software: you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
* See the GNU General Public License for more details.
|
|
*
|
|
*/
|
|
package code.name.monkey.retromusic.adapter.song
|
|
|
|
import android.view.MenuItem
|
|
import android.view.View
|
|
import androidx.appcompat.app.AppCompatActivity
|
|
import androidx.fragment.app.FragmentActivity
|
|
import code.name.monkey.retromusic.R
|
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote.isPlaying
|
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote.playNextSong
|
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote.removeFromQueue
|
|
import code.name.monkey.retromusic.model.Song
|
|
import code.name.monkey.retromusic.util.MusicUtil
|
|
import code.name.monkey.retromusic.util.ViewUtil
|
|
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter
|
|
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange
|
|
import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags
|
|
import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemAdapter
|
|
import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemConstants
|
|
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultAction
|
|
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionDefault
|
|
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionRemoveItem
|
|
import me.zhanghai.android.fastscroll.PopupTextProvider
|
|
|
|
class PlayingQueueAdapter(
|
|
activity: AppCompatActivity,
|
|
dataSet: MutableList<Song>,
|
|
private var current: Int,
|
|
itemLayoutRes: Int
|
|
) : SongAdapter(
|
|
activity, dataSet, itemLayoutRes, null
|
|
), DraggableItemAdapter<PlayingQueueAdapter.ViewHolder>,
|
|
SwipeableItemAdapter<PlayingQueueAdapter.ViewHolder>,
|
|
PopupTextProvider {
|
|
|
|
private var songToRemove: Song? = null
|
|
|
|
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
|
return ViewHolder(view)
|
|
}
|
|
|
|
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
|
|
super.onBindViewHolder(holder, position)
|
|
holder.imageText?.text = (position - current).toString()
|
|
holder.time?.text = MusicUtil.getReadableDurationString(dataSet[position].duration)
|
|
if (holder.itemViewType == HISTORY || holder.itemViewType == CURRENT) {
|
|
setAlpha(holder, 0.5f)
|
|
}
|
|
}
|
|
|
|
override fun getItemViewType(position: Int): Int {
|
|
if (position < current) {
|
|
return HISTORY
|
|
} else if (position > current) {
|
|
return UP_NEXT
|
|
}
|
|
return CURRENT
|
|
}
|
|
|
|
override fun loadAlbumCover(song: Song, holder: SongAdapter.ViewHolder) {
|
|
// We don't want to load it in this adapter
|
|
}
|
|
|
|
fun swapDataSet(dataSet: List<Song>, position: Int) {
|
|
this.dataSet = dataSet.toMutableList()
|
|
current = position
|
|
notifyDataSetChanged()
|
|
}
|
|
|
|
fun setCurrent(current: Int) {
|
|
this.current = current
|
|
notifyDataSetChanged()
|
|
}
|
|
|
|
private fun setAlpha(holder: SongAdapter.ViewHolder, alpha: Float) {
|
|
holder.image?.alpha = alpha
|
|
holder.title?.alpha = alpha
|
|
holder.text?.alpha = alpha
|
|
holder.imageText?.alpha = alpha
|
|
holder.paletteColorContainer?.alpha = alpha
|
|
holder.dragView?.alpha = alpha
|
|
holder.menu?.alpha = alpha
|
|
}
|
|
|
|
override fun getPopupText(position: Int): String {
|
|
return MusicUtil.getSectionName(dataSet[position].title)
|
|
}
|
|
|
|
override fun onCheckCanStartDrag(holder: ViewHolder, position: Int, x: Int, y: Int): Boolean {
|
|
return ViewUtil.hitTest(holder.imageText!!, x, y) || ViewUtil.hitTest(
|
|
holder.dragView!!,
|
|
x,
|
|
y
|
|
)
|
|
}
|
|
|
|
override fun onGetItemDraggableRange(holder: ViewHolder, position: Int): ItemDraggableRange? {
|
|
return null
|
|
}
|
|
|
|
override fun onMoveItem(fromPosition: Int, toPosition: Int) {
|
|
MusicPlayerRemote.moveSong(fromPosition, toPosition)
|
|
}
|
|
|
|
override fun onCheckCanDrop(draggingPosition: Int, dropPosition: Int): Boolean {
|
|
return true
|
|
}
|
|
|
|
override fun onItemDragStarted(position: Int) {
|
|
notifyDataSetChanged()
|
|
}
|
|
|
|
override fun onItemDragFinished(fromPosition: Int, toPosition: Int, result: Boolean) {
|
|
notifyDataSetChanged()
|
|
}
|
|
|
|
fun setSongToRemove(song: Song) {
|
|
songToRemove = song
|
|
}
|
|
|
|
inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) {
|
|
@DraggableItemStateFlags
|
|
private var mDragStateFlags: Int = 0
|
|
|
|
override var songMenuRes: Int
|
|
get() = R.menu.menu_item_playing_queue_song
|
|
set(value) {
|
|
super.songMenuRes = value
|
|
}
|
|
|
|
init {
|
|
imageText?.visibility = View.VISIBLE
|
|
dragView?.visibility = View.VISIBLE
|
|
}
|
|
|
|
override fun onSongMenuItemClick(item: MenuItem): Boolean {
|
|
when (item.itemId) {
|
|
R.id.action_remove_from_playing_queue -> {
|
|
removeFromQueue(layoutPosition)
|
|
return true
|
|
}
|
|
}
|
|
return super.onSongMenuItemClick(item)
|
|
}
|
|
|
|
@DraggableItemStateFlags
|
|
override fun getDragStateFlags(): Int {
|
|
return mDragStateFlags
|
|
}
|
|
|
|
override fun setDragStateFlags(@DraggableItemStateFlags flags: Int) {
|
|
mDragStateFlags = flags
|
|
}
|
|
|
|
override fun getSwipeableContainerView(): View {
|
|
return dummyContainer!!
|
|
}
|
|
}
|
|
|
|
companion object {
|
|
|
|
private const val HISTORY = 0
|
|
private const val CURRENT = 1
|
|
private const val UP_NEXT = 2
|
|
}
|
|
|
|
override fun onSwipeItem(holder: ViewHolder, position: Int, result: Int): SwipeResultAction? {
|
|
return if (result == SwipeableItemConstants.RESULT_CANCELED) {
|
|
SwipeResultActionDefault()
|
|
} else {
|
|
SwipedResultActionRemoveItem(this, position, activity)
|
|
}
|
|
}
|
|
|
|
override fun onGetSwipeReactionType(holder: ViewHolder, position: Int, x: Int, y: Int): Int {
|
|
return if (onCheckCanStartDrag(holder, position, x, y)) {
|
|
SwipeableItemConstants.REACTION_CAN_NOT_SWIPE_BOTH_H
|
|
} else {
|
|
SwipeableItemConstants.REACTION_CAN_SWIPE_BOTH_H
|
|
}
|
|
}
|
|
|
|
override fun onSwipeItemStarted(holder: ViewHolder, p1: Int) {
|
|
}
|
|
|
|
override fun onSetSwipeBackground(holder: ViewHolder, position: Int, result: Int) {
|
|
}
|
|
|
|
internal class SwipedResultActionRemoveItem(
|
|
private val adapter: PlayingQueueAdapter,
|
|
private val position: Int,
|
|
private val activity: FragmentActivity
|
|
) : SwipeResultActionRemoveItem() {
|
|
|
|
private var songToRemove: Song? = null
|
|
private val isPlaying: Boolean = MusicPlayerRemote.isPlaying
|
|
private val songProgressMillis = 0
|
|
override fun onPerformAction() {
|
|
// currentlyShownSnackbar = null
|
|
}
|
|
|
|
override fun onSlideAnimationEnd() {
|
|
// initializeSnackBar(adapter, position, activity, isPlaying)
|
|
songToRemove = adapter.dataSet[position]
|
|
// If song removed was the playing song, then play the next song
|
|
if (isPlaying(songToRemove!!)) {
|
|
playNextSong()
|
|
}
|
|
// Swipe animation is much smoother when we do the heavy lifting after it's completed
|
|
adapter.setSongToRemove(songToRemove!!)
|
|
removeFromQueue(songToRemove!!)
|
|
}
|
|
}
|
|
}
|