ultrasonic-app-subsonic-and.../ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt

173 lines
6.3 KiB
Kotlin
Raw Normal View History

/*
This file is part of Subsonic.
Subsonic 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.
Subsonic 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.
You should have received a copy of the GNU General Public License
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
Copyright 2020 (C) Jozsef Varga
*/
2021-02-08 21:46:31 +01:00
package org.moire.ultrasonic.fragment
import android.view.LayoutInflater
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.PopupMenu
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView.SectionedAdapter
2020-11-23 14:02:18 +01:00
import java.text.Collator
import org.moire.ultrasonic.R
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
import org.moire.ultrasonic.domain.Artist
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.util.ImageLoader
2020-11-25 20:00:12 +01:00
import org.moire.ultrasonic.util.Util
import org.moire.ultrasonic.view.SelectMusicFolderView
/**
* Creates a Row in a RecyclerView which contains the details of an Artist
*/
class ArtistRowAdapter(
private var artistList: List<Artist>,
private var selectFolderHeader: SelectMusicFolderView?,
val onArtistClick: (Artist) -> Unit,
val onContextMenuClick: (MenuItem, Artist) -> Boolean,
private val imageLoader: ImageLoader
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), SectionedAdapter {
/**
* Sets the data to be displayed in the RecyclerView
*/
fun setData(data: List<Artist>) {
2020-11-23 14:02:18 +01:00
artistList = data.sortedWith(compareBy(Collator.getInstance()) { t -> t.name })
notifyDataSetChanged()
}
/**
* Holds the view properties of an Artist row
*/
class ArtistViewHolder(
itemView: View
) : RecyclerView.ViewHolder(itemView) {
var section: TextView = itemView.findViewById(R.id.row_section)
var textView: TextView = itemView.findViewById(R.id.row_artist_name)
var layout: RelativeLayout = itemView.findViewById(R.id.row_artist_layout)
var coverArt: ImageView = itemView.findViewById(R.id.artist_coverart)
var coverArtId: String? = null
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): RecyclerView.ViewHolder {
if (viewType == TYPE_ITEM) {
val row = LayoutInflater.from(parent.context)
.inflate(R.layout.artist_list_item, parent, false)
return ArtistViewHolder(row)
}
return selectFolderHeader!!
}
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
if ((holder is ArtistViewHolder) && (holder.coverArtId != null)) {
imageLoader.cancel(holder.coverArtId)
}
super.onViewRecycled(holder)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is ArtistViewHolder) {
val listPosition = if (selectFolderHeader != null) position - 1 else position
holder.textView.text = artistList[listPosition].name
holder.section.text = getSectionForArtist(listPosition)
holder.layout.setOnClickListener { onArtistClick(artistList[listPosition]) }
holder.layout.setOnLongClickListener { view -> createPopupMenu(view, listPosition) }
holder.coverArtId = artistList[listPosition].coverArt
2020-11-25 20:00:12 +01:00
if (Util.getShouldShowArtistPicture()) {
2020-11-25 20:00:12 +01:00
holder.coverArt.visibility = View.VISIBLE
imageLoader.loadImage(
holder.coverArt,
MusicDirectory.Entry().apply { coverArt = holder.coverArtId },
false, 0, false, true, R.drawable.ic_contact_picture
)
} else {
holder.coverArt.visibility = View.GONE
}
}
}
override fun getItemCount() = if (selectFolderHeader != null)
artistList.size + 1
else
artistList.size
override fun getItemViewType(position: Int): Int {
return if (position == 0 && selectFolderHeader != null) TYPE_HEADER else TYPE_ITEM
}
override fun getSectionName(position: Int): String {
var listPosition = if (selectFolderHeader != null) position - 1 else position
2020-11-28 13:51:51 +01:00
// Show the first artist's initial in the popup when the list is
// scrolled up to the "Select Folder" row
if (listPosition < 0) listPosition = 0
return getSectionFromName(artistList[listPosition].name ?: " ")
}
private fun getSectionForArtist(artistPosition: Int): String {
if (artistPosition == 0)
return getSectionFromName(artistList[artistPosition].name ?: " ")
val previousArtistSection = getSectionFromName(
artistList[artistPosition - 1].name ?: " "
)
val currentArtistSection = getSectionFromName(
artistList[artistPosition].name ?: " "
)
return if (previousArtistSection == currentArtistSection) "" else currentArtistSection
}
private fun getSectionFromName(name: String): String {
var section = name.first().toUpperCase()
if (!section.isLetter()) section = '#'
return section.toString()
}
private fun createPopupMenu(view: View, position: Int): Boolean {
val popup = PopupMenu(view.context, view)
val inflater: MenuInflater = popup.menuInflater
inflater.inflate(R.menu.select_artist_context, popup.menu)
val downloadMenuItem = popup.menu.findItem(R.id.artist_menu_download)
2021-05-09 10:25:04 +02:00
downloadMenuItem?.isVisible = !isOffline()
popup.setOnMenuItemClickListener { menuItem ->
onContextMenuClick(menuItem, artistList[position])
}
popup.show()
return true
}
companion object {
private const val TYPE_HEADER = 0
private const val TYPE_ITEM = 1
}
}