Set page size to 50. Added favorite management on playlists. Fixed loop over loading of playlist tracks.
This commit is contained in:
parent
0b14415e1e
commit
5a14b3cfa4
|
@ -18,7 +18,11 @@ import jp.wasabeef.picasso.transformations.RoundedCornersTransformation
|
||||||
import kotlinx.android.synthetic.main.row_track.view.*
|
import kotlinx.android.synthetic.main.row_track.view.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class PlaylistTracksAdapter(private val context: Context?, val fromQueue: Boolean = false) : FunkwhaleAdapter<PlaylistTrack, PlaylistTracksAdapter.ViewHolder>() {
|
class PlaylistTracksAdapter(private val context: Context?, private val favoriteListener: OnFavoriteListener? = null, val fromQueue: Boolean = false) : FunkwhaleAdapter<PlaylistTrack, PlaylistTracksAdapter.ViewHolder>() {
|
||||||
|
interface OnFavoriteListener {
|
||||||
|
fun onToggleFavorite(id: Int, state: Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
private lateinit var touchHelper: ItemTouchHelper
|
private lateinit var touchHelper: ItemTouchHelper
|
||||||
|
|
||||||
var currentTrack: Track? = null
|
var currentTrack: Track? = null
|
||||||
|
@ -77,6 +81,22 @@ class PlaylistTracksAdapter(private val context: Context?, val fromQueue: Boolea
|
||||||
holder.artist.setTypeface(holder.artist.typeface, Typeface.BOLD)
|
holder.artist.setTypeface(holder.artist.typeface, Typeface.BOLD)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context?.let {
|
||||||
|
when (track.track.favorite) {
|
||||||
|
true -> holder.favorite.setColorFilter(context.getColor(R.color.colorFavorite))
|
||||||
|
false -> holder.favorite.setColorFilter(context.getColor(R.color.colorSelected))
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.favorite.setOnClickListener {
|
||||||
|
favoriteListener?.let {
|
||||||
|
favoriteListener.onToggleFavorite(track.track.id, !track.track.favorite)
|
||||||
|
|
||||||
|
track.track.favorite = !track.track.favorite
|
||||||
|
notifyItemChanged(position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
holder.actions.setOnClickListener {
|
holder.actions.setOnClickListener {
|
||||||
context?.let { context ->
|
context?.let { context ->
|
||||||
PopupMenu(context, holder.actions, Gravity.START, R.attr.actionOverflowMenuStyle, 0).apply {
|
PopupMenu(context, holder.actions, Gravity.START, R.attr.actionOverflowMenuStyle, 0).apply {
|
||||||
|
@ -130,6 +150,8 @@ class PlaylistTracksAdapter(private val context: Context?, val fromQueue: Boolea
|
||||||
val cover = view.cover
|
val cover = view.cover
|
||||||
val title = view.title
|
val title = view.title
|
||||||
val artist = view.artist
|
val artist = view.artist
|
||||||
|
|
||||||
|
val favorite = view.favorite
|
||||||
val actions = view.actions
|
val actions = view.actions
|
||||||
|
|
||||||
override fun onClick(view: View?) {
|
override fun onClick(view: View?) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import androidx.core.os.bundleOf
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.github.apognu.otter.R
|
import com.github.apognu.otter.R
|
||||||
import com.github.apognu.otter.adapters.PlaylistTracksAdapter
|
import com.github.apognu.otter.adapters.PlaylistTracksAdapter
|
||||||
|
import com.github.apognu.otter.repositories.FavoritesRepository
|
||||||
import com.github.apognu.otter.repositories.PlaylistTracksRepository
|
import com.github.apognu.otter.repositories.PlaylistTracksRepository
|
||||||
import com.github.apognu.otter.utils.*
|
import com.github.apognu.otter.utils.*
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
|
@ -18,6 +19,8 @@ class PlaylistTracksFragment : FunkwhaleFragment<PlaylistTrack, PlaylistTracksAd
|
||||||
override val viewRes = R.layout.fragment_tracks
|
override val viewRes = R.layout.fragment_tracks
|
||||||
override val recycler: RecyclerView get() = tracks
|
override val recycler: RecyclerView get() = tracks
|
||||||
|
|
||||||
|
lateinit var favoritesRepository: FavoritesRepository
|
||||||
|
|
||||||
var albumId = 0
|
var albumId = 0
|
||||||
var albumArtist = ""
|
var albumArtist = ""
|
||||||
var albumTitle = ""
|
var albumTitle = ""
|
||||||
|
@ -46,8 +49,9 @@ class PlaylistTracksFragment : FunkwhaleFragment<PlaylistTrack, PlaylistTracksAd
|
||||||
albumCover = getString("albumCover") ?: ""
|
albumCover = getString("albumCover") ?: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter = PlaylistTracksAdapter(context)
|
adapter = PlaylistTracksAdapter(context, FavoriteListener())
|
||||||
repository = PlaylistTracksRepository(context, albumId)
|
repository = PlaylistTracksRepository(context, albumId)
|
||||||
|
favoritesRepository = FavoritesRepository(context)
|
||||||
|
|
||||||
watchEventBus()
|
watchEventBus()
|
||||||
}
|
}
|
||||||
|
@ -117,4 +121,13 @@ class PlaylistTracksFragment : FunkwhaleFragment<PlaylistTrack, PlaylistTracksAd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inner class FavoriteListener : PlaylistTracksAdapter.OnFavoriteListener {
|
||||||
|
override fun onToggleFavorite(id: Int, state: Boolean) {
|
||||||
|
when (state) {
|
||||||
|
true -> favoritesRepository.addFavorite(id)
|
||||||
|
false -> favoritesRepository.deleteFavorite(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -117,6 +117,5 @@ class TracksFragment : FunkwhaleFragment<Track, TracksAdapter>() {
|
||||||
false -> favoritesRepository.deleteFavorite(id)
|
false -> favoritesRepository.deleteFavorite(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,7 +20,7 @@ import kotlin.math.ceil
|
||||||
|
|
||||||
class HttpUpstream<D : Any, R : FunkwhaleResponse<D>>(private val behavior: Behavior, private val url: String, private val type: Type) : Upstream<D> {
|
class HttpUpstream<D : Any, R : FunkwhaleResponse<D>>(private val behavior: Behavior, private val url: String, private val type: Type) : Upstream<D> {
|
||||||
enum class Behavior {
|
enum class Behavior {
|
||||||
AtOnce, Progressive
|
Single, AtOnce, Progressive
|
||||||
}
|
}
|
||||||
|
|
||||||
private var _channel: Channel<Repository.Response<D>>? = null
|
private var _channel: Channel<Repository.Response<D>>? = null
|
||||||
|
@ -34,6 +34,8 @@ class HttpUpstream<D : Any, R : FunkwhaleResponse<D>>(private val behavior: Beha
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fetch(data: List<D>): Channel<Repository.Response<D>>? {
|
override fun fetch(data: List<D>): Channel<Repository.Response<D>>? {
|
||||||
|
if (behavior == Behavior.Single && data.isNotEmpty()) return null
|
||||||
|
|
||||||
val page = ceil(data.size / AppContext.PAGE_SIZE.toDouble()).toInt() + 1
|
val page = ceil(data.size / AppContext.PAGE_SIZE.toDouble()).toInt() + 1
|
||||||
|
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
|
|
|
@ -1,18 +1,32 @@
|
||||||
package com.github.apognu.otter.repositories
|
package com.github.apognu.otter.repositories
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.github.apognu.otter.utils.FunkwhaleResponse
|
import com.github.apognu.otter.utils.*
|
||||||
import com.github.apognu.otter.utils.PlaylistTrack
|
|
||||||
import com.github.apognu.otter.utils.PlaylistTracksCache
|
|
||||||
import com.github.apognu.otter.utils.PlaylistTracksResponse
|
|
||||||
import com.github.kittinunf.fuel.gson.gsonDeserializerOf
|
import com.github.kittinunf.fuel.gson.gsonDeserializerOf
|
||||||
import com.google.gson.reflect.TypeToken
|
import com.google.gson.reflect.TypeToken
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
|
|
||||||
class PlaylistTracksRepository(override val context: Context?, playlistId: Int) : Repository<PlaylistTrack, PlaylistTracksCache>() {
|
class PlaylistTracksRepository(override val context: Context?, playlistId: Int) : Repository<PlaylistTrack, PlaylistTracksCache>() {
|
||||||
override val cacheId = "tracks-playlist-$playlistId"
|
override val cacheId = "tracks-playlist-$playlistId"
|
||||||
override val upstream = HttpUpstream<PlaylistTrack, FunkwhaleResponse<PlaylistTrack>>(HttpUpstream.Behavior.AtOnce, "/api/v1/playlists/$playlistId/tracks?playable=true", object : TypeToken<PlaylistTracksResponse>() {}.type)
|
override val upstream = HttpUpstream<PlaylistTrack, FunkwhaleResponse<PlaylistTrack>>(HttpUpstream.Behavior.Single, "/api/v1/playlists/$playlistId/tracks?playable=true", object : TypeToken<PlaylistTracksResponse>() {}.type)
|
||||||
|
|
||||||
override fun cache(data: List<PlaylistTrack>) = PlaylistTracksCache(data)
|
override fun cache(data: List<PlaylistTrack>) = PlaylistTracksCache(data)
|
||||||
override fun uncache(reader: BufferedReader) = gsonDeserializerOf(PlaylistTracksCache::class.java).deserialize(reader)
|
override fun uncache(reader: BufferedReader) = gsonDeserializerOf(PlaylistTracksCache::class.java).deserialize(reader)
|
||||||
|
|
||||||
|
override fun onDataFetched(data: List<PlaylistTrack>): List<PlaylistTrack> = runBlocking {
|
||||||
|
val favorites = FavoritesRepository(context).fetch(Origin.Network.origin).receive().data
|
||||||
|
|
||||||
|
log(favorites.toString())
|
||||||
|
|
||||||
|
data.map { track ->
|
||||||
|
val favorite = favorites.find { it.track.id == track.track.id }
|
||||||
|
|
||||||
|
if (favorite != null) {
|
||||||
|
track.track.favorite = true
|
||||||
|
}
|
||||||
|
|
||||||
|
track
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -19,7 +19,7 @@ object AppContext {
|
||||||
const val NOTIFICATION_MEDIA_CONTROL = 1
|
const val NOTIFICATION_MEDIA_CONTROL = 1
|
||||||
const val NOTIFICATION_CHANNEL_MEDIA_CONTROL = "mediacontrols"
|
const val NOTIFICATION_CHANNEL_MEDIA_CONTROL = "mediacontrols"
|
||||||
|
|
||||||
const val PAGE_SIZE = 7
|
const val PAGE_SIZE = 50
|
||||||
const val TRANSITION_DURATION = 300L
|
const val TRANSITION_DURATION = 300L
|
||||||
|
|
||||||
fun init(context: Activity) {
|
fun init(context: Activity) {
|
||||||
|
|
Loading…
Reference in New Issue