diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index 333ec1fdb..f1a98728a 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -16,7 +16,6 @@ import android.os.PowerManager import android.text.format.DateUtils import android.text.method.LinkMovementMethod import android.text.util.Linkify -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup diff --git a/app/src/main/java/com/github/libretube/util/PlayingQueue.kt b/app/src/main/java/com/github/libretube/util/PlayingQueue.kt index 3b857edb2..6a89f83c9 100644 --- a/app/src/main/java/com/github/libretube/util/PlayingQueue.kt +++ b/app/src/main/java/com/github/libretube/util/PlayingQueue.kt @@ -54,9 +54,12 @@ object PlayingQueue { fun hasNext() = getNext() != null - fun updateCurrent(streamItem: StreamItem) { + fun updateCurrent(streamItem: StreamItem, asFirst: Boolean = true) { currentStream = streamItem - if (!contains(streamItem)) queue.add(0, streamItem) + if (!contains(streamItem)) { + val indexToAdd = if (asFirst) 0 else size() + queue.add(indexToAdd, streamItem) + } } fun isNotEmpty() = queue.isNotEmpty() @@ -85,17 +88,33 @@ object PlayingQueue { fun move(from: Int, to: Int) = queue.move(from, to) + private fun addToQueueAsync(streams: List, currentStreamItem: StreamItem? = null) { + val currentStream = currentStreamItem ?: this.currentStream + // if the stream already got added to the queue earlier, although it's not yet + // been found in the playlist, remove it and re-add it later + currentStream?.let { stream -> + if (streams.includes(stream)) { + queue.removeAll { + it.url?.toID() == currentStream.url?.toID() + } + } + } + // whether the current stream is not yet part of the list and should be added later + val reAddStream = currentStream?.let { !queue.includes(it) } ?: false + // add all new stream items to the queue + add(*streams.toTypedArray()) + currentStream?.let { + // re-add the stream to the end of the queue, + if (reAddStream) updateCurrent(it, false) + } + } + private fun fetchMoreFromPlaylist(playlistId: String, nextPage: String?) { - var playlistNextPage: String? = nextPage - scope.launch { + var playlistNextPage = nextPage + scope.launch(Dispatchers.IO) { while (playlistNextPage != null) { - RetrofitInstance.authApi.getPlaylistNextPage( - playlistId, - playlistNextPage!! - ).apply { - add( - *this.relatedStreams.toTypedArray() - ) + RetrofitInstance.authApi.getPlaylistNextPage(playlistId, playlistNextPage!!).run { + addToQueueAsync(relatedStreams) playlistNextPage = this.nextpage } } @@ -103,25 +122,22 @@ object PlayingQueue { } fun insertPlaylist(playlistId: String, newCurrentStream: StreamItem) { - scope.launch { - try { + scope.launch(Dispatchers.IO) { + runCatching { val playlist = PlaylistsHelper.getPlaylist(playlistId) - add(*playlist.relatedStreams.toTypedArray()) - updateCurrent(newCurrentStream) + addToQueueAsync(playlist.relatedStreams, newCurrentStream) if (playlist.nextpage == null) return@launch fetchMoreFromPlaylist(playlistId, playlist.nextpage) - } catch (e: Exception) { - e.printStackTrace() } } } private fun fetchMoreFromChannel(channelId: String, nextPage: String?) { - var channelNextPage: String? = nextPage - scope.launch { + var channelNextPage = nextPage + scope.launch(Dispatchers.IO) { while (channelNextPage != null) { - RetrofitInstance.api.getChannelNextPage(channelId, nextPage!!).apply { - add(*relatedStreams.toTypedArray()) + RetrofitInstance.api.getChannelNextPage(channelId, nextPage!!).run { + addToQueueAsync(relatedStreams) channelNextPage = this.nextpage } } @@ -129,11 +145,10 @@ object PlayingQueue { } fun insertChannel(channelId: String, newCurrentStream: StreamItem) { - scope.launch { + scope.launch(Dispatchers.IO) { runCatching { val channel = RetrofitInstance.api.getChannel(channelId) - add(*channel.relatedStreams.toTypedArray()) - updateCurrent(newCurrentStream) + addToQueueAsync(channel.relatedStreams, newCurrentStream) if (channel.nextpage == null) return@launch fetchMoreFromChannel(channelId, channel.nextpage) } @@ -167,4 +182,8 @@ object PlayingQueue { repeatQueue = false onQueueTapListener = {} } + + private fun List.includes(item: StreamItem) = any { + it.url?.toID() == item.url?.toID() + } }