diff --git a/app/src/main/java/audio/funkwhale/ffa/playback/CacheDataSourceFactoryProvider.kt b/app/src/main/java/audio/funkwhale/ffa/playback/CacheDataSourceFactoryProvider.kt
new file mode 100644
index 0000000000000000000000000000000000000000..44478f6bd862b723bfceca10db49aa5fa1eab679
--- /dev/null
+++ b/app/src/main/java/audio/funkwhale/ffa/playback/CacheDataSourceFactoryProvider.kt
@@ -0,0 +1,46 @@
+package audio.funkwhale.ffa.playback
+
+import android.content.Context
+import audio.funkwhale.ffa.R
+import audio.funkwhale.ffa.utils.OAuth
+import audio.funkwhale.ffa.utils.Settings
+import com.google.android.exoplayer2.upstream.DataSource
+import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory
+import com.google.android.exoplayer2.upstream.FileDataSource
+import com.google.android.exoplayer2.upstream.cache.Cache
+import com.google.android.exoplayer2.upstream.cache.CacheDataSource
+import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory
+import com.google.android.exoplayer2.util.Util
+
+class CacheDataSourceFactoryProvider(
+    private val oAuth: OAuth,
+    private val exoCache: Cache,
+    private val exoDownloadCache: Cache
+) {
+
+  fun create(context: Context): CacheDataSourceFactory {
+
+    val playbackCache =
+        CacheDataSourceFactory(exoCache, createDatasourceFactory(context, oAuth))
+
+    return CacheDataSourceFactory(
+        exoDownloadCache,
+        playbackCache,
+        FileDataSource.Factory(),
+        null,
+        CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR,
+        null
+    )
+  }
+
+  private fun createDatasourceFactory(context: Context, oAuth: OAuth): DataSource.Factory {
+    val http = DefaultHttpDataSourceFactory(
+        Util.getUserAgent(context, context.getString(R.string.app_name))
+    )
+    return if (!Settings.isAnonymous()) {
+        OAuth2DatasourceFactory(context, http, oAuth)
+    } else {
+      http
+    }
+  }
+}
\ No newline at end of file
diff --git a/app/src/main/java/audio/funkwhale/ffa/playback/QueueManager.kt b/app/src/main/java/audio/funkwhale/ffa/playback/QueueManager.kt
index 0707ab887af86455093adddf6faafdecd7564143..b48536a0bc481ab4825c914e2b8319525623b4ce 100644
--- a/app/src/main/java/audio/funkwhale/ffa/playback/QueueManager.kt
+++ b/app/src/main/java/audio/funkwhale/ffa/playback/QueueManager.kt
@@ -2,54 +2,13 @@ package audio.funkwhale.ffa.playback
 
 import android.content.Context
 import android.net.Uri
-import audio.funkwhale.ffa.R
 import audio.funkwhale.ffa.utils.*
 import com.github.kittinunf.fuel.gson.gsonDeserializerOf
 import com.google.android.exoplayer2.source.ConcatenatingMediaSource
 import com.google.android.exoplayer2.source.ProgressiveMediaSource
-import com.google.android.exoplayer2.upstream.DataSource
-import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory
-import com.google.android.exoplayer2.upstream.FileDataSource
-import com.google.android.exoplayer2.upstream.cache.CacheDataSource
-import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory
-import com.google.android.exoplayer2.upstream.cache.Cache
-import com.google.android.exoplayer2.util.Util
 import com.google.gson.Gson
 import org.koin.java.KoinJavaComponent.inject
 
-class CacheDataSourceFactoryProvider(
-  private val oAuth: OAuth,
-  private val exoCache: Cache,
-  private val exoDownloadCache: Cache
-) {
-
-  fun create(context: Context): CacheDataSourceFactory {
-
-    val playbackCache =
-      CacheDataSourceFactory(exoCache, createDatasourceFactory(context, oAuth))
-
-    return CacheDataSourceFactory(
-      exoDownloadCache,
-      playbackCache,
-      FileDataSource.Factory(),
-      null,
-      CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR,
-      null
-    )
-  }
-
-  private fun createDatasourceFactory(context: Context, oAuth: OAuth): DataSource.Factory {
-    val http = DefaultHttpDataSourceFactory(
-      Util.getUserAgent(context, context.getString(R.string.app_name))
-    )
-    return if (!Settings.isAnonymous()) {
-      OAuth2DatasourceFactory(context, http, oAuth)
-    } else {
-      http
-    }
-  }
-}
-
 class QueueManager(val context: Context) {
 
   private val cacheDataSourceFactoryProvider: CacheDataSourceFactoryProvider by inject(
@@ -89,7 +48,9 @@ class QueueManager(val context: Context) {
     )
   }
 
+
   fun replace(tracks: List<Track>) {
+    tracks.map { it.formatted }.log("Replacing queue with ${tracks.size} tracks")
     val factory = cacheDataSourceFactoryProvider.create(context)
     val sources = tracks.map { track ->
       val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
@@ -107,6 +68,7 @@ class QueueManager(val context: Context) {
   }
 
   fun append(tracks: List<Track>) {
+    tracks.map { it.formatted }.log("Appending ${tracks.size} tracks")
     val factory = cacheDataSourceFactoryProvider.create(context)
     val missingTracks = tracks.filter { metadata.indexOf(it) == -1 }
 
@@ -125,6 +87,7 @@ class QueueManager(val context: Context) {
   }
 
   fun insertNext(track: Track) {
+    track.let { it.formatted }.log("Next track")
     val factory = cacheDataSourceFactoryProvider.create(context)
     val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
 
@@ -143,6 +106,7 @@ class QueueManager(val context: Context) {
   }
 
   fun remove(track: Track) {
+    track.formatted.log("Removing track")
     metadata.indexOf(track).let {
       if (it < 0) {
         return
diff --git a/app/src/main/java/audio/funkwhale/ffa/utils/Models.kt b/app/src/main/java/audio/funkwhale/ffa/utils/Models.kt
index beb23f755c33ad9869a4d68d939286046eebdba6..dc6bae9691115e2c053110c3d4b8c32825f7abc5 100644
--- a/app/src/main/java/audio/funkwhale/ffa/utils/Models.kt
+++ b/app/src/main/java/audio/funkwhale/ffa/utils/Models.kt
@@ -24,35 +24,67 @@ abstract class OtterResponse<D : Any> {
   abstract fun getData(): List<D>
 }
 
-data class UserResponse(override val count: Int, override val next: String?, val results: List<Artist>) : OtterResponse<Artist>() {
+data class UserResponse(
+  override val count: Int,
+  override val next: String?,
+  val results: List<Artist>
+) : OtterResponse<Artist>() {
   override fun getData() = results
 }
 
-data class ArtistsResponse(override val count: Int, override val next: String?, val results: List<Artist>) : OtterResponse<Artist>() {
+data class ArtistsResponse(
+  override val count: Int,
+  override val next: String?,
+  val results: List<Artist>
+) : OtterResponse<Artist>() {
   override fun getData() = results
 }
 
-data class AlbumsResponse(override val count: Int, override val next: String?, val results: AlbumList) : OtterResponse<Album>() {
+data class AlbumsResponse(
+  override val count: Int,
+  override val next: String?,
+  val results: AlbumList
+) : OtterResponse<Album>() {
   override fun getData() = results
 }
 
-data class TracksResponse(override val count: Int, override val next: String?, val results: List<Track>) : OtterResponse<Track>() {
+data class TracksResponse(
+  override val count: Int,
+  override val next: String?,
+  val results: List<Track>
+) : OtterResponse<Track>() {
   override fun getData() = results
 }
 
-data class FavoritedResponse(override val count: Int, override val next: String?, val results: List<Favorited>) : OtterResponse<Int>() {
+data class FavoritedResponse(
+  override val count: Int,
+  override val next: String?,
+  val results: List<Favorited>
+) : OtterResponse<Int>() {
   override fun getData() = results.map { it.track }
 }
 
-data class PlaylistsResponse(override val count: Int, override val next: String?, val results: List<Playlist>) : OtterResponse<Playlist>() {
+data class PlaylistsResponse(
+  override val count: Int,
+  override val next: String?,
+  val results: List<Playlist>
+) : OtterResponse<Playlist>() {
   override fun getData() = results
 }
 
-data class PlaylistTracksResponse(override val count: Int, override val next: String?, val results: List<PlaylistTrack>) : OtterResponse<PlaylistTrack>() {
+data class PlaylistTracksResponse(
+  override val count: Int,
+  override val next: String?,
+  val results: List<PlaylistTrack>
+) : OtterResponse<PlaylistTrack>() {
   override fun getData() = results
 }
 
-data class RadiosResponse(override val count: Int, override val next: String?, val results: List<Radio>) : OtterResponse<Radio>() {
+data class RadiosResponse(
+  override val count: Int,
+  override val next: String?,
+  val results: List<Radio>
+) : OtterResponse<Radio>() {
   override fun getData() = results
 }
 
@@ -148,6 +180,8 @@ data class Track(
   override fun cover() = album?.cover?.urls?.original
   override fun title() = title
   override fun subtitle() = artist.name
+
+  val formatted: String get() = "$id $artist ($album): $title"
 }
 
 data class Favorited(val track: Int)