Otter-App-Android-Funkwhale/app/src/main/java/com/github/apognu/otter/fragments/TracksFragment.kt

203 lines
6.4 KiB
Kotlin
Raw Normal View History

2019-08-19 16:50:33 +02:00
package com.github.apognu.otter.fragments
import android.os.Bundle
2020-06-13 16:45:58 +02:00
import android.view.Gravity
2019-08-19 16:50:33 +02:00
import android.view.View
import androidx.appcompat.app.AppCompatDelegate
2020-06-13 16:45:58 +02:00
import androidx.appcompat.widget.PopupMenu
2019-08-19 16:50:33 +02:00
import androidx.core.os.bundleOf
2020-07-13 23:32:42 +02:00
import androidx.lifecycle.LiveData
import androidx.lifecycle.lifecycleScope
2020-07-13 23:32:42 +02:00
import androidx.lifecycle.observe
2019-08-19 16:50:33 +02:00
import androidx.recyclerview.widget.RecyclerView
import com.github.apognu.otter.R
import com.github.apognu.otter.adapters.TracksAdapter
2020-07-13 23:32:42 +02:00
import com.github.apognu.otter.models.api.FunkwhaleTrack
import com.github.apognu.otter.models.domain.Album
import com.github.apognu.otter.models.domain.Track
import com.github.apognu.otter.repositories.FavoritedRepository
2019-08-19 16:50:33 +02:00
import com.github.apognu.otter.repositories.FavoritesRepository
import com.github.apognu.otter.repositories.TracksRepository
import com.github.apognu.otter.utils.*
2020-07-13 23:32:42 +02:00
import com.github.apognu.otter.viewmodels.*
import com.google.android.exoplayer2.offline.Download
import com.preference.PowerPreference
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
2019-08-19 16:50:33 +02:00
import kotlinx.android.synthetic.main.fragment_tracks.*
import kotlinx.coroutines.Dispatchers.IO
2019-08-19 16:50:33 +02:00
import kotlinx.coroutines.Dispatchers.Main
2019-10-31 16:17:37 +01:00
import kotlinx.coroutines.flow.collect
2019-08-19 16:50:33 +02:00
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
2019-08-19 16:50:33 +02:00
2020-07-13 23:32:42 +02:00
class TracksFragment : LiveOtterFragment<FunkwhaleTrack, Track, TracksAdapter>() {
override lateinit var liveData: LiveData<List<Track>>
2019-08-19 16:50:33 +02:00
override val viewRes = R.layout.fragment_tracks
override val recycler: RecyclerView get() = tracks
lateinit var favoritesRepository: FavoritesRepository
lateinit var favoritedRepository: FavoritedRepository
2019-08-19 16:50:33 +02:00
2019-10-21 11:51:32 +02:00
private var albumId = 0
private var albumArtist = ""
private var albumTitle = ""
private var albumCover = ""
2019-08-19 16:50:33 +02:00
companion object {
fun new(album: Album): TracksFragment {
return TracksFragment().apply {
2020-07-13 23:32:42 +02:00
arguments = bundleOf("albumId" to album.id)
2019-08-19 16:50:33 +02:00
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
arguments?.apply {
albumId = getInt("albumId")
}
2020-07-13 23:32:42 +02:00
liveData = TracksViewModel(albumId).tracks
AlbumViewModel(albumId).album.observe(this) {
title.text = it.title
Picasso.get()
.maybeLoad(maybeNormalizeUrl(it.cover))
.noFade()
.fit()
.centerCrop()
.transform(RoundedCornersTransformation(16, 0))
.into(cover)
ArtistViewModel(it.artist_id).artist.observe(this) {
artist.text = it.name
}
}
super.onCreate(savedInstanceState)
2019-08-19 16:50:33 +02:00
adapter = TracksAdapter(context, FavoriteListener())
repository = TracksRepository(context, albumId)
favoritesRepository = FavoritesRepository(context)
favoritedRepository = FavoritedRepository(context)
2019-08-19 16:50:33 +02:00
watchEventBus()
}
override fun onResume() {
super.onResume()
var coverHeight: Float? = null
scroller.setOnScrollChangeListener { _: View?, _: Int, scrollY: Int, _: Int, _: Int ->
if (coverHeight == null) {
coverHeight = cover.measuredHeight.toFloat()
}
cover.translationY = (scrollY / 2).toFloat()
coverHeight?.let { height ->
cover.alpha = (height - scrollY.toFloat()) / height
}
}
when (PowerPreference.getDefaultFile().getString("play_order")) {
"in_order" -> play.text = getString(R.string.playback_play)
else -> play.text = getString(R.string.playback_shuffle)
}
2019-08-19 16:50:33 +02:00
play.setOnClickListener {
when (PowerPreference.getDefaultFile().getString("play_order")) {
"in_order" -> CommandBus.send(Command.ReplaceQueue(adapter.data))
else -> CommandBus.send(Command.ReplaceQueue(adapter.data.shuffled()))
}
2019-08-19 16:50:33 +02:00
context.toast("All tracks were added to your queue")
}
2020-06-13 16:45:58 +02:00
context?.let { context ->
actions.setOnClickListener {
PopupMenu(context, actions, Gravity.START, R.attr.actionOverflowMenuStyle, 0).apply {
inflate(R.menu.album)
2019-08-19 16:50:33 +02:00
menu.findItem(R.id.play_secondary)?.let { item ->
when (PowerPreference.getDefaultFile().getString("play_order")) {
"in_order" -> item.title = getString(R.string.playback_shuffle)
else -> item.title = getString(R.string.playback_play)
}
}
2020-06-13 16:45:58 +02:00
setOnMenuItemClickListener {
when (it.itemId) {
R.id.play_secondary -> when (PowerPreference.getDefaultFile().getString("play_order")) {
"in_order" -> CommandBus.send(Command.ReplaceQueue(adapter.data.shuffled()))
else -> CommandBus.send(Command.ReplaceQueue(adapter.data))
}
2020-06-13 16:45:58 +02:00
R.id.add_to_queue -> {
when (PowerPreference.getDefaultFile().getString("play_order")) {
"in_order" -> CommandBus.send(Command.AddToQueue(adapter.data))
else -> CommandBus.send(Command.AddToQueue(adapter.data.shuffled()))
}
2020-06-13 16:45:58 +02:00
context.toast("All tracks were added to your queue")
}
R.id.download -> CommandBus.send(Command.PinTracks(adapter.data))
}
true
}
show()
}
}
2019-08-19 16:50:33 +02:00
}
}
private fun watchEventBus() {
lifecycleScope.launch(IO) {
2019-10-31 16:17:37 +01:00
EventBus.get().collect { message ->
2019-08-19 16:50:33 +02:00
when (message) {
is Event.DownloadChanged -> refreshDownloadedTrack(message.download)
}
}
}
}
private suspend fun refreshDownloadedTracks() {
val downloaded = TracksRepository.getDownloadedIds() ?: listOf()
withContext(Main) {
2020-07-13 23:32:42 +02:00
/* adapter.data = adapter.data.map {
it.downloaded = downloaded.contains(it.id)
it
2020-07-13 23:32:42 +02:00
}.toMutableList() */
adapter.notifyDataSetChanged()
}
}
private suspend fun refreshDownloadedTrack(download: Download) {
if (download.state == Download.STATE_COMPLETED) {
download.getMetadata()?.let { info ->
adapter.data.withIndex().associate { it.value to it.index }.filter { it.key.id == info.id }.toList().getOrNull(0)?.let { match ->
2020-07-13 23:32:42 +02:00
/* withContext(Main) {
adapter.data[match.second].downloaded = true
adapter.notifyItemChanged(match.second)
2020-07-13 23:32:42 +02:00
} */
2019-08-19 16:50:33 +02:00
}
}
}
}
inner class FavoriteListener : TracksAdapter.OnFavoriteListener {
override fun onToggleFavorite(id: Int, state: Boolean) {
when (state) {
true -> favoritesRepository.addFavorite(id)
false -> favoritesRepository.deleteFavorite(id)
}
}
}
}