Send track played reports to Funkwhale whenever a track finishes playing. Closes #40.
This commit is contained in:
parent
dc7803acb4
commit
ce05acad21
|
@ -27,7 +27,10 @@ import com.github.apognu.otter.repositories.FavoritedRepository
|
||||||
import com.github.apognu.otter.repositories.FavoritesRepository
|
import com.github.apognu.otter.repositories.FavoritesRepository
|
||||||
import com.github.apognu.otter.repositories.Repository
|
import com.github.apognu.otter.repositories.Repository
|
||||||
import com.github.apognu.otter.utils.*
|
import com.github.apognu.otter.utils.*
|
||||||
|
import com.github.kittinunf.fuel.Fuel
|
||||||
|
import com.github.kittinunf.fuel.coroutines.awaitStringResponse
|
||||||
import com.google.android.exoplayer2.Player
|
import com.google.android.exoplayer2.Player
|
||||||
|
import com.google.gson.Gson
|
||||||
import com.preference.PowerPreference
|
import com.preference.PowerPreference
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
import kotlinx.android.synthetic.main.activity_main.*
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
|
@ -236,136 +239,9 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is Event.TrackPlayed -> {
|
is Event.TrackPlayed -> refreshCurrentTrack(message.track)
|
||||||
message.track?.let { track ->
|
is Event.RefreshTrack -> refreshCurrentTrack(message.track)
|
||||||
if (now_playing.visibility == View.GONE) {
|
is Event.TrackFinished -> incrementListenCount(message.track)
|
||||||
now_playing.visibility = View.VISIBLE
|
|
||||||
now_playing.alpha = 0f
|
|
||||||
|
|
||||||
now_playing.animate()
|
|
||||||
.alpha(1.0f)
|
|
||||||
.setDuration(400)
|
|
||||||
.setListener(null)
|
|
||||||
.start()
|
|
||||||
|
|
||||||
(container.layoutParams as? ViewGroup.MarginLayoutParams)?.let {
|
|
||||||
it.bottomMargin = it.bottomMargin * 2
|
|
||||||
}
|
|
||||||
|
|
||||||
landscape_queue?.let { landscape_queue ->
|
|
||||||
(landscape_queue.layoutParams as? ViewGroup.MarginLayoutParams)?.let {
|
|
||||||
it.bottomMargin = it.bottomMargin * 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
now_playing_title.text = track.title
|
|
||||||
now_playing_album.text = track.artist.name
|
|
||||||
now_playing_toggle.icon = getDrawable(R.drawable.pause)
|
|
||||||
|
|
||||||
now_playing_details_title.text = track.title
|
|
||||||
now_playing_details_artist.text = track.artist.name
|
|
||||||
now_playing_details_toggle.icon = getDrawable(R.drawable.pause)
|
|
||||||
|
|
||||||
Picasso.get()
|
|
||||||
.maybeLoad(maybeNormalizeUrl(track.album.cover.original))
|
|
||||||
.fit()
|
|
||||||
.centerCrop()
|
|
||||||
.into(now_playing_cover)
|
|
||||||
|
|
||||||
now_playing_details_cover?.let { now_playing_details_cover ->
|
|
||||||
Picasso.get()
|
|
||||||
.maybeLoad(maybeNormalizeUrl(track.album.cover.original))
|
|
||||||
.fit()
|
|
||||||
.centerCrop()
|
|
||||||
.into(now_playing_details_cover)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (now_playing_details_cover == null) {
|
|
||||||
GlobalScope.launch(IO) {
|
|
||||||
val width = DisplayMetrics().apply {
|
|
||||||
windowManager.defaultDisplay.getMetrics(this)
|
|
||||||
}.widthPixels
|
|
||||||
|
|
||||||
val backgroundCover = Picasso.get()
|
|
||||||
.maybeLoad(maybeNormalizeUrl(track.album.cover.original))
|
|
||||||
.get()
|
|
||||||
.run { Bitmap.createScaledBitmap(this, width, width, false).toDrawable(resources) }
|
|
||||||
.apply {
|
|
||||||
alpha = 20
|
|
||||||
gravity = Gravity.CENTER
|
|
||||||
}
|
|
||||||
|
|
||||||
withContext(Main) {
|
|
||||||
now_playing_details.background = backgroundCover
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
now_playing_details_repeat?.let { now_playing_details_repeat ->
|
|
||||||
changeRepeatMode(Cache.get(this@MainActivity, "repeat")?.readLine()?.toInt() ?: 0)
|
|
||||||
|
|
||||||
now_playing_details_repeat.setOnClickListener {
|
|
||||||
val current = Cache.get(this@MainActivity, "repeat")?.readLine()?.toInt() ?: 0
|
|
||||||
|
|
||||||
changeRepeatMode((current + 1) % 3)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
now_playing_details_info?.let { now_playing_details_info ->
|
|
||||||
now_playing_details_info.setOnClickListener {
|
|
||||||
PopupMenu(this@MainActivity, now_playing_details_info, Gravity.START, R.attr.actionOverflowMenuStyle, 0).apply {
|
|
||||||
inflate(R.menu.track_info)
|
|
||||||
|
|
||||||
setOnMenuItemClickListener {
|
|
||||||
when (it.itemId) {
|
|
||||||
R.id.track_info_artist -> ArtistsFragment.openAlbums(this@MainActivity, track.artist, art = track.album.cover.original)
|
|
||||||
R.id.track_info_album -> AlbumsFragment.openTracks(this@MainActivity, track.album)
|
|
||||||
R.id.track_info_details -> TrackInfoDetailsFragment.new(track).show(supportFragmentManager, "dialog")
|
|
||||||
}
|
|
||||||
|
|
||||||
now_playing.close()
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
now_playing_details_favorite?.let { now_playing_details_favorite ->
|
|
||||||
favoriteCheckRepository.fetch().untilNetwork(IO) { favorites, _, _ ->
|
|
||||||
GlobalScope.launch(Main) {
|
|
||||||
track.favorite = favorites.contains(track.id)
|
|
||||||
|
|
||||||
when (track.favorite) {
|
|
||||||
true -> now_playing_details_favorite.setColorFilter(getColor(R.color.colorFavorite))
|
|
||||||
false -> now_playing_details_favorite.setColorFilter(getColor(R.color.controlForeground))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
now_playing_details_favorite.setOnClickListener {
|
|
||||||
when (track.favorite) {
|
|
||||||
true -> {
|
|
||||||
favoriteRepository.deleteFavorite(track.id)
|
|
||||||
now_playing_details_favorite.setColorFilter(getColor(R.color.controlForeground))
|
|
||||||
}
|
|
||||||
|
|
||||||
false -> {
|
|
||||||
favoriteRepository.addFavorite(track.id)
|
|
||||||
now_playing_details_favorite.setColorFilter(getColor(R.color.colorFavorite))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
track.favorite = !track.favorite
|
|
||||||
|
|
||||||
favoriteRepository.fetch(Repository.Origin.Network.origin)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is Event.StateChanged -> {
|
is Event.StateChanged -> {
|
||||||
when (message.playing) {
|
when (message.playing) {
|
||||||
|
@ -411,6 +287,137 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun refreshCurrentTrack(track: Track?) {
|
||||||
|
track?.let { track ->
|
||||||
|
if (now_playing.visibility == View.GONE) {
|
||||||
|
now_playing.visibility = View.VISIBLE
|
||||||
|
now_playing.alpha = 0f
|
||||||
|
|
||||||
|
now_playing.animate()
|
||||||
|
.alpha(1.0f)
|
||||||
|
.setDuration(400)
|
||||||
|
.setListener(null)
|
||||||
|
.start()
|
||||||
|
|
||||||
|
(container.layoutParams as? ViewGroup.MarginLayoutParams)?.let {
|
||||||
|
it.bottomMargin = it.bottomMargin * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
landscape_queue?.let { landscape_queue ->
|
||||||
|
(landscape_queue.layoutParams as? ViewGroup.MarginLayoutParams)?.let {
|
||||||
|
it.bottomMargin = it.bottomMargin * 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
now_playing_title.text = track.title
|
||||||
|
now_playing_album.text = track.artist.name
|
||||||
|
now_playing_toggle.icon = getDrawable(R.drawable.pause)
|
||||||
|
|
||||||
|
now_playing_details_title.text = track.title
|
||||||
|
now_playing_details_artist.text = track.artist.name
|
||||||
|
now_playing_details_toggle.icon = getDrawable(R.drawable.pause)
|
||||||
|
|
||||||
|
Picasso.get()
|
||||||
|
.maybeLoad(maybeNormalizeUrl(track.album.cover.original))
|
||||||
|
.fit()
|
||||||
|
.centerCrop()
|
||||||
|
.into(now_playing_cover)
|
||||||
|
|
||||||
|
now_playing_details_cover?.let { now_playing_details_cover ->
|
||||||
|
Picasso.get()
|
||||||
|
.maybeLoad(maybeNormalizeUrl(track.album.cover.original))
|
||||||
|
.fit()
|
||||||
|
.centerCrop()
|
||||||
|
.into(now_playing_details_cover)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (now_playing_details_cover == null) {
|
||||||
|
GlobalScope.launch(IO) {
|
||||||
|
val width = DisplayMetrics().apply {
|
||||||
|
windowManager.defaultDisplay.getMetrics(this)
|
||||||
|
}.widthPixels
|
||||||
|
|
||||||
|
val backgroundCover = Picasso.get()
|
||||||
|
.maybeLoad(maybeNormalizeUrl(track.album.cover.original))
|
||||||
|
.get()
|
||||||
|
.run { Bitmap.createScaledBitmap(this, width, width, false).toDrawable(resources) }
|
||||||
|
.apply {
|
||||||
|
alpha = 20
|
||||||
|
gravity = Gravity.CENTER
|
||||||
|
}
|
||||||
|
|
||||||
|
withContext(Main) {
|
||||||
|
now_playing_details.background = backgroundCover
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
now_playing_details_repeat?.let { now_playing_details_repeat ->
|
||||||
|
changeRepeatMode(Cache.get(this@MainActivity, "repeat")?.readLine()?.toInt() ?: 0)
|
||||||
|
|
||||||
|
now_playing_details_repeat.setOnClickListener {
|
||||||
|
val current = Cache.get(this@MainActivity, "repeat")?.readLine()?.toInt() ?: 0
|
||||||
|
|
||||||
|
changeRepeatMode((current + 1) % 3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
now_playing_details_info?.let { now_playing_details_info ->
|
||||||
|
now_playing_details_info.setOnClickListener {
|
||||||
|
PopupMenu(this@MainActivity, now_playing_details_info, Gravity.START, R.attr.actionOverflowMenuStyle, 0).apply {
|
||||||
|
inflate(R.menu.track_info)
|
||||||
|
|
||||||
|
setOnMenuItemClickListener {
|
||||||
|
when (it.itemId) {
|
||||||
|
R.id.track_info_artist -> ArtistsFragment.openAlbums(this@MainActivity, track.artist, art = track.album.cover.original)
|
||||||
|
R.id.track_info_album -> AlbumsFragment.openTracks(this@MainActivity, track.album)
|
||||||
|
R.id.track_info_details -> TrackInfoDetailsFragment.new(track).show(supportFragmentManager, "dialog")
|
||||||
|
}
|
||||||
|
|
||||||
|
now_playing.close()
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
now_playing_details_favorite?.let { now_playing_details_favorite ->
|
||||||
|
favoriteCheckRepository.fetch().untilNetwork(IO) { favorites, _, _ ->
|
||||||
|
GlobalScope.launch(Main) {
|
||||||
|
track.favorite = favorites.contains(track.id)
|
||||||
|
|
||||||
|
when (track.favorite) {
|
||||||
|
true -> now_playing_details_favorite.setColorFilter(getColor(R.color.colorFavorite))
|
||||||
|
false -> now_playing_details_favorite.setColorFilter(getColor(R.color.controlForeground))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
now_playing_details_favorite.setOnClickListener {
|
||||||
|
when (track.favorite) {
|
||||||
|
true -> {
|
||||||
|
favoriteRepository.deleteFavorite(track.id)
|
||||||
|
now_playing_details_favorite.setColorFilter(getColor(R.color.controlForeground))
|
||||||
|
}
|
||||||
|
|
||||||
|
false -> {
|
||||||
|
favoriteRepository.addFavorite(track.id)
|
||||||
|
now_playing_details_favorite.setColorFilter(getColor(R.color.colorFavorite))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
track.favorite = !track.favorite
|
||||||
|
|
||||||
|
favoriteRepository.fetch(Repository.Origin.Network.origin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun changeRepeatMode(index: Int) {
|
private fun changeRepeatMode(index: Int) {
|
||||||
when (index) {
|
when (index) {
|
||||||
// From no repeat to repeat all
|
// From no repeat to repeat all
|
||||||
|
@ -446,4 +453,17 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun incrementListenCount(track: Track?) {
|
||||||
|
track?.let { track ->
|
||||||
|
GlobalScope.launch(IO) {
|
||||||
|
Fuel
|
||||||
|
.post(mustNormalizeUrl("/api/v1/history/listenings/"))
|
||||||
|
.authorize()
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.body(Gson().toJson(mapOf("track" to track.id)))
|
||||||
|
.awaitStringResponse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,17 +131,8 @@ class PlayerService : Service() {
|
||||||
EventBus.send(Event.QueueChanged)
|
EventBus.send(Event.QueueChanged)
|
||||||
|
|
||||||
if (queue.metadata.isNotEmpty()) {
|
if (queue.metadata.isNotEmpty()) {
|
||||||
EventBus.send(
|
EventBus.send(Event.RefreshTrack(queue.current(), player.playWhenReady))
|
||||||
Event.TrackPlayed(
|
EventBus.send(Event.StateChanged(player.playWhenReady))
|
||||||
queue.current(),
|
|
||||||
player.playWhenReady
|
|
||||||
)
|
|
||||||
)
|
|
||||||
EventBus.send(
|
|
||||||
Event.StateChanged(
|
|
||||||
player.playWhenReady
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +145,7 @@ class PlayerService : Service() {
|
||||||
state(true)
|
state(true)
|
||||||
|
|
||||||
EventBus.send(
|
EventBus.send(
|
||||||
Event.TrackPlayed(
|
Event.RefreshTrack(
|
||||||
queue.current(),
|
queue.current(),
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
@ -172,12 +163,7 @@ class PlayerService : Service() {
|
||||||
|
|
||||||
state(true)
|
state(true)
|
||||||
|
|
||||||
EventBus.send(
|
EventBus.send(Event.RefreshTrack(queue.current(),true))
|
||||||
Event.TrackPlayed(
|
|
||||||
queue.current(),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is Command.ToggleState -> toggle()
|
is Command.ToggleState -> toggle()
|
||||||
|
@ -211,21 +197,9 @@ class PlayerService : Service() {
|
||||||
jobs.add(GlobalScope.launch(Main) {
|
jobs.add(GlobalScope.launch(Main) {
|
||||||
RequestBus.get().collect { request ->
|
RequestBus.get().collect { request ->
|
||||||
when (request) {
|
when (request) {
|
||||||
is Request.GetCurrentTrack -> request.channel?.offer(
|
is Request.GetCurrentTrack -> request.channel?.offer(Response.CurrentTrack(queue.current()))
|
||||||
Response.CurrentTrack(
|
is Request.GetState -> request.channel?.offer(Response.State(player.playWhenReady))
|
||||||
queue.current()
|
is Request.GetQueue -> request.channel?.offer(Response.Queue(queue.get()))
|
||||||
)
|
|
||||||
)
|
|
||||||
is Request.GetState -> request.channel?.offer(
|
|
||||||
Response.State(
|
|
||||||
player.playWhenReady
|
|
||||||
)
|
|
||||||
)
|
|
||||||
is Request.GetQueue -> request.channel?.offer(
|
|
||||||
Response.Queue(
|
|
||||||
queue.get()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -285,11 +259,7 @@ class PlayerService : Service() {
|
||||||
if (!state) {
|
if (!state) {
|
||||||
val (progress, _, _) = progress()
|
val (progress, _, _) = progress()
|
||||||
|
|
||||||
Cache.set(
|
Cache.set(this@PlayerService,"progress", progress.toString().toByteArray())
|
||||||
this@PlayerService,
|
|
||||||
"progress",
|
|
||||||
progress.toString().toByteArray()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state && player.playbackState == Player.STATE_IDLE) {
|
if (state && player.playbackState == Player.STATE_IDLE) {
|
||||||
|
@ -365,52 +335,27 @@ class PlayerService : Service() {
|
||||||
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
|
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
|
||||||
super.onPlayerStateChanged(playWhenReady, playbackState)
|
super.onPlayerStateChanged(playWhenReady, playbackState)
|
||||||
|
|
||||||
EventBus.send(
|
EventBus.send(Event.StateChanged(playWhenReady))
|
||||||
Event.StateChanged(
|
|
||||||
playWhenReady
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (queue.current == -1) {
|
if (queue.current == -1) {
|
||||||
EventBus.send(
|
EventBus.send(Event.TrackPlayed(queue.current(), playWhenReady))
|
||||||
Event.TrackPlayed(
|
|
||||||
queue.current(),
|
|
||||||
playWhenReady
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
when (playWhenReady) {
|
when (playWhenReady) {
|
||||||
true -> {
|
true -> {
|
||||||
when (playbackState) {
|
when (playbackState) {
|
||||||
Player.STATE_READY -> mediaControlsManager.updateNotification(queue.current(), true)
|
Player.STATE_READY -> mediaControlsManager.updateNotification(queue.current(), true)
|
||||||
Player.STATE_BUFFERING -> EventBus.send(
|
Player.STATE_BUFFERING -> EventBus.send(Event.Buffering(true))
|
||||||
Event.Buffering(
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
Player.STATE_IDLE -> state(false)
|
Player.STATE_IDLE -> state(false)
|
||||||
Player.STATE_ENDED -> EventBus.send(Event.PlaybackStopped)
|
Player.STATE_ENDED -> EventBus.send(Event.PlaybackStopped)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playbackState != Player.STATE_BUFFERING) EventBus.send(
|
if (playbackState != Player.STATE_BUFFERING) EventBus.send(Event.Buffering(false))
|
||||||
Event.Buffering(
|
|
||||||
false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
false -> {
|
false -> {
|
||||||
EventBus.send(
|
EventBus.send(Event.StateChanged(false))
|
||||||
Event.StateChanged(
|
EventBus.send(Event.Buffering(false))
|
||||||
false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
EventBus.send(
|
|
||||||
Event.Buffering(
|
|
||||||
false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (playbackState == Player.STATE_READY) {
|
if (playbackState == Player.STATE_READY) {
|
||||||
mediaControlsManager.updateNotification(queue.current(), false)
|
mediaControlsManager.updateNotification(queue.current(), false)
|
||||||
|
@ -435,26 +380,21 @@ class PlayerService : Service() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Cache.set(
|
Cache.set(this@PlayerService,"current", queue.current.toString().toByteArray() )
|
||||||
this@PlayerService,
|
|
||||||
"current",
|
|
||||||
queue.current.toString().toByteArray()
|
|
||||||
)
|
|
||||||
|
|
||||||
EventBus.send(
|
EventBus.send(Event.RefreshTrack(queue.current(),true) )
|
||||||
Event.TrackPlayed(
|
}
|
||||||
queue.current(),
|
|
||||||
true
|
override fun onPositionDiscontinuity(reason: Int) {
|
||||||
)
|
super.onPositionDiscontinuity(reason)
|
||||||
)
|
|
||||||
|
if (reason == Player.DISCONTINUITY_REASON_PERIOD_TRANSITION) {
|
||||||
|
EventBus.send(Event.TrackFinished(queue.current()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPlayerError(error: ExoPlaybackException?) {
|
override fun onPlayerError(error: ExoPlaybackException?) {
|
||||||
EventBus.send(
|
EventBus.send(Event.PlaybackError(getString(R.string.error_playback)))
|
||||||
Event.PlaybackError(
|
|
||||||
getString(R.string.error_playback)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
player.next()
|
player.next()
|
||||||
player.playWhenReady = true
|
player.playWhenReady = true
|
||||||
|
|
|
@ -36,8 +36,6 @@ class HttpUpstream<D : Any, R : FunkwhaleResponse<D>>(val behavior: Behavior, pr
|
||||||
.build()
|
.build()
|
||||||
.toString()
|
.toString()
|
||||||
|
|
||||||
log(offsetUrl)
|
|
||||||
|
|
||||||
get(offsetUrl).fold(
|
get(offsetUrl).fold(
|
||||||
{ response ->
|
{ response ->
|
||||||
val data = response.getData()
|
val data = response.getData()
|
||||||
|
|
|
@ -38,6 +38,8 @@ sealed class Event {
|
||||||
object PlaybackStopped : Event()
|
object PlaybackStopped : Event()
|
||||||
class Buffering(val value: Boolean) : Event()
|
class Buffering(val value: Boolean) : Event()
|
||||||
class TrackPlayed(val track: Track?, val play: Boolean) : Event()
|
class TrackPlayed(val track: Track?, val play: Boolean) : Event()
|
||||||
|
class TrackFinished(val track: Track?) : Event()
|
||||||
|
class RefreshTrack(val track: Track?, val play: Boolean) : Event()
|
||||||
class StateChanged(val playing: Boolean) : Event()
|
class StateChanged(val playing: Boolean) : Event()
|
||||||
object QueueChanged : Event()
|
object QueueChanged : Event()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue