Set page size to 50. Added favorite management on playlists. Fixed loop over loading of playlist tracks.

This commit is contained in:
Antoine POPINEAU 2019-10-21 20:26:26 +02:00
parent 0b14415e1e
commit 5a14b3cfa4
No known key found for this signature in database
GPG Key ID: A78AC64694F84063
6 changed files with 60 additions and 10 deletions

View File

@ -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?) {

View File

@ -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)
}
}
}
} }

View File

@ -117,6 +117,5 @@ class TracksFragment : FunkwhaleFragment<Track, TracksAdapter>() {
false -> favoritesRepository.deleteFavorite(id) false -> favoritesRepository.deleteFavorite(id)
} }
} }
} }
} }

View File

@ -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) {

View File

@ -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
}
}
} }

View File

@ -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) {