2021-07-12 10:14:26 +02:00
|
|
|
package audio.funkwhale.ffa.fragments
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2020-05-29 21:40:01 +02:00
|
|
|
import android.content.Context
|
2019-08-19 16:50:33 +02:00
|
|
|
import android.os.Bundle
|
2021-07-16 10:03:52 +02:00
|
|
|
import android.view.LayoutInflater
|
2019-08-19 16:50:33 +02:00
|
|
|
import android.view.View
|
2021-07-16 10:03:52 +02:00
|
|
|
import android.view.ViewGroup
|
2019-08-19 16:50:33 +02:00
|
|
|
import android.view.animation.AccelerateDecelerateInterpolator
|
2020-05-30 14:12:04 +02:00
|
|
|
import androidx.appcompat.app.AppCompatActivity
|
2021-07-16 10:03:52 +02:00
|
|
|
import androidx.appcompat.content.res.AppCompatResources
|
2020-06-24 16:04:36 +02:00
|
|
|
import androidx.core.content.ContextCompat
|
2019-08-19 16:50:33 +02:00
|
|
|
import androidx.core.os.bundleOf
|
2020-05-29 21:40:01 +02:00
|
|
|
import androidx.fragment.app.Fragment
|
2020-06-25 01:26:15 +02:00
|
|
|
import androidx.lifecycle.lifecycleScope
|
2019-08-19 16:50:33 +02:00
|
|
|
import androidx.recyclerview.widget.RecyclerView
|
2020-06-24 16:04:36 +02:00
|
|
|
import androidx.swiperefreshlayout.widget.CircularProgressDrawable
|
2019-08-19 16:50:33 +02:00
|
|
|
import androidx.transition.Fade
|
|
|
|
import androidx.transition.Slide
|
2021-07-12 10:14:26 +02:00
|
|
|
import audio.funkwhale.ffa.R
|
|
|
|
import audio.funkwhale.ffa.activities.MainActivity
|
|
|
|
import audio.funkwhale.ffa.adapters.AlbumsAdapter
|
2021-07-16 10:03:52 +02:00
|
|
|
import audio.funkwhale.ffa.databinding.FragmentAlbumsBinding
|
2021-07-12 10:14:26 +02:00
|
|
|
import audio.funkwhale.ffa.repositories.AlbumsRepository
|
|
|
|
import audio.funkwhale.ffa.repositories.ArtistTracksRepository
|
|
|
|
import audio.funkwhale.ffa.repositories.Repository
|
|
|
|
import audio.funkwhale.ffa.utils.*
|
2019-08-19 16:50:33 +02:00
|
|
|
import com.squareup.picasso.Picasso
|
2020-06-14 00:42:45 +02:00
|
|
|
import jp.wasabeef.picasso.transformations.RoundedCornersTransformation
|
2020-06-02 18:50:46 +02:00
|
|
|
import kotlinx.coroutines.Dispatchers.IO
|
|
|
|
import kotlinx.coroutines.Dispatchers.Main
|
|
|
|
import kotlinx.coroutines.flow.map
|
|
|
|
import kotlinx.coroutines.flow.toList
|
2019-11-05 21:23:29 +01:00
|
|
|
import kotlinx.coroutines.launch
|
|
|
|
import kotlinx.coroutines.withContext
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
class AlbumsFragment : FFAFragment<Album, AlbumsAdapter>() {
|
|
|
|
|
|
|
|
override val recycler: RecyclerView get() = binding.albums
|
2020-07-08 22:11:50 +02:00
|
|
|
override val alwaysRefresh = false
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
private var _binding: FragmentAlbumsBinding? = null
|
|
|
|
private val binding get() = _binding!!
|
|
|
|
|
2020-07-08 22:11:50 +02:00
|
|
|
private lateinit var artistTracksRepository: ArtistTracksRepository
|
2020-06-02 18:50:46 +02:00
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
private var artistId = 0
|
|
|
|
private var artistName = ""
|
|
|
|
private var artistArt = ""
|
2019-08-19 16:50:33 +02:00
|
|
|
|
|
|
|
companion object {
|
2020-06-01 21:25:16 +02:00
|
|
|
fun new(artist: Artist, _art: String? = null): AlbumsFragment {
|
2020-08-08 14:51:39 +02:00
|
|
|
val art = _art ?: if (artist.albums?.isNotEmpty() == true) artist.cover() else ""
|
2020-05-29 21:40:01 +02:00
|
|
|
|
2019-08-19 16:50:33 +02:00
|
|
|
return AlbumsFragment().apply {
|
|
|
|
arguments = bundleOf(
|
|
|
|
"artistId" to artist.id,
|
|
|
|
"artistName" to artist.name,
|
2020-05-29 21:40:01 +02:00
|
|
|
"artistArt" to art
|
2019-08-19 16:50:33 +02:00
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2020-05-29 21:40:01 +02:00
|
|
|
|
2020-07-11 21:01:09 +02:00
|
|
|
fun openTracks(context: Context?, album: Album?, fragment: Fragment? = null) {
|
|
|
|
if (album == null) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-01 21:25:16 +02:00
|
|
|
(context as? MainActivity)?.let {
|
2020-05-29 21:40:01 +02:00
|
|
|
fragment?.let { fragment ->
|
|
|
|
fragment.onViewPager {
|
|
|
|
exitTransition = Fade().apply {
|
|
|
|
duration = AppContext.TRANSITION_DURATION
|
|
|
|
interpolator = AccelerateDecelerateInterpolator()
|
|
|
|
|
|
|
|
view?.let {
|
|
|
|
addTarget(it)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-05-30 14:12:04 +02:00
|
|
|
}
|
2020-05-29 21:40:01 +02:00
|
|
|
|
2020-05-30 14:12:04 +02:00
|
|
|
(context as? AppCompatActivity)?.let { activity ->
|
2020-06-01 21:25:16 +02:00
|
|
|
val nextFragment = TracksFragment.new(album).apply {
|
2020-05-29 21:40:01 +02:00
|
|
|
enterTransition = Slide().apply {
|
|
|
|
duration = AppContext.TRANSITION_DURATION
|
|
|
|
interpolator = AccelerateDecelerateInterpolator()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
activity.supportFragmentManager
|
|
|
|
.beginTransaction()
|
2020-06-01 21:25:16 +02:00
|
|
|
.replace(R.id.container, nextFragment)
|
2020-05-29 21:40:01 +02:00
|
|
|
.addToBackStack(null)
|
|
|
|
.commit()
|
|
|
|
}
|
|
|
|
}
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
|
|
super.onCreate(savedInstanceState)
|
|
|
|
|
|
|
|
arguments?.apply {
|
|
|
|
artistId = getInt("artistId")
|
|
|
|
artistName = getString("artistName") ?: ""
|
|
|
|
artistArt = getString("artistArt") ?: ""
|
|
|
|
}
|
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
adapter = AlbumsAdapter(layoutInflater, context, OnAlbumClickListener())
|
2019-08-19 16:50:33 +02:00
|
|
|
repository = AlbumsRepository(context, artistId)
|
2020-06-02 18:50:46 +02:00
|
|
|
artistTracksRepository = ArtistTracksRepository(context, artistId)
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
override fun onCreateView(
|
|
|
|
inflater: LayoutInflater,
|
|
|
|
container: ViewGroup?,
|
|
|
|
savedInstanceState: Bundle?
|
|
|
|
): View {
|
|
|
|
_binding = FragmentAlbumsBinding.inflate(inflater)
|
|
|
|
swiper = binding.swiper
|
|
|
|
return binding.root
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onDestroyView() {
|
|
|
|
super.onDestroyView()
|
|
|
|
_binding = null
|
|
|
|
}
|
|
|
|
|
2019-08-19 16:50:33 +02:00
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
|
|
super.onViewCreated(view, savedInstanceState)
|
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
binding.cover.let { cover ->
|
2019-11-05 21:23:29 +01:00
|
|
|
Picasso.get()
|
|
|
|
.maybeLoad(maybeNormalizeUrl(artistArt))
|
|
|
|
.noFade()
|
|
|
|
.fit()
|
|
|
|
.centerCrop()
|
2020-06-14 00:42:45 +02:00
|
|
|
.transform(RoundedCornersTransformation(16, 0))
|
2019-11-05 21:23:29 +01:00
|
|
|
.into(cover)
|
|
|
|
}
|
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
binding.artist.text = artistName
|
2020-06-02 18:50:46 +02:00
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
binding.play.setOnClickListener {
|
2020-06-24 16:04:36 +02:00
|
|
|
val loader = CircularProgressDrawable(requireContext()).apply {
|
|
|
|
setColorSchemeColors(ContextCompat.getColor(requireContext(), android.R.color.white))
|
|
|
|
strokeWidth = 4f
|
|
|
|
}
|
|
|
|
|
|
|
|
loader.start()
|
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
binding.play.icon = loader
|
|
|
|
binding.play.isClickable = false
|
2020-06-02 18:50:46 +02:00
|
|
|
|
2020-06-25 01:26:15 +02:00
|
|
|
lifecycleScope.launch(IO) {
|
2020-06-02 18:50:46 +02:00
|
|
|
artistTracksRepository.fetch(Repository.Origin.Network.origin)
|
|
|
|
.map { it.data }
|
|
|
|
.toList()
|
|
|
|
.flatten()
|
|
|
|
.shuffled()
|
|
|
|
.also {
|
|
|
|
CommandBus.send(Command.ReplaceQueue(it))
|
|
|
|
|
|
|
|
withContext(Main) {
|
2021-07-16 10:03:52 +02:00
|
|
|
binding.play.icon =
|
|
|
|
AppCompatResources.getDrawable(binding.root.context, R.drawable.play)
|
|
|
|
binding.play.isClickable = true
|
2020-06-02 18:50:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
|
2020-06-15 00:26:22 +02:00
|
|
|
override fun onResume() {
|
|
|
|
super.onResume()
|
|
|
|
|
|
|
|
var coverHeight: Float? = null
|
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
binding.scroller.setOnScrollChangeListener { _: View?, _: Int, scrollY: Int, _: Int, _: Int ->
|
2020-06-15 00:26:22 +02:00
|
|
|
if (coverHeight == null) {
|
2021-07-16 10:03:52 +02:00
|
|
|
coverHeight = binding.cover.measuredHeight.toFloat()
|
2020-06-15 00:26:22 +02:00
|
|
|
}
|
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
binding.cover.translationY = (scrollY / 2).toFloat()
|
2020-06-15 00:26:22 +02:00
|
|
|
|
|
|
|
coverHeight?.let { height ->
|
2021-07-16 10:03:52 +02:00
|
|
|
binding.cover.alpha = (height - scrollY.toFloat()) / height
|
2020-06-15 00:26:22 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-19 16:50:33 +02:00
|
|
|
inner class OnAlbumClickListener : AlbumsAdapter.OnAlbumClickListener {
|
2019-10-21 11:51:32 +02:00
|
|
|
override fun onClick(view: View?, album: Album) {
|
2020-05-29 21:40:01 +02:00
|
|
|
openTracks(context, album, fragment = this@AlbumsFragment)
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
}
|
2021-07-02 13:55:49 +02:00
|
|
|
}
|