Skip to content

Commit 04bb5e0

Browse files
committed
fix: playing from download tab doesn't respect sort order
1 parent df0e562 commit 04bb5e0

5 files changed

Lines changed: 92 additions & 41 deletions

File tree

app/src/main/java/com/github/libretube/helpers/BackgroundHelper.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import com.github.libretube.services.OfflinePlayerService
1717
import com.github.libretube.services.OnlinePlayerService
1818
import com.github.libretube.ui.activities.MainActivity
1919
import com.github.libretube.ui.activities.NoInternetActivity
20+
import com.github.libretube.ui.fragments.DownloadSortingOrder
2021
import com.github.libretube.ui.fragments.DownloadTab
2122
import com.github.libretube.ui.fragments.PlayerFragment
2223
import com.github.libretube.util.PlayingQueue
@@ -80,7 +81,8 @@ object BackgroundHelper {
8081
videoId: String?,
8182
playlistId: String?,
8283
downloadTab: DownloadTab,
83-
shuffle: Boolean = false
84+
shuffle: Boolean = false,
85+
sortOrder: DownloadSortingOrder? = null,
8486
) {
8587
// whether the service is started from the MainActivity or NoInternetActivity
8688
val noInternet = ContextHelper.tryUnwrapActivity<NoInternetActivity>(context) != null
@@ -91,7 +93,8 @@ object BackgroundHelper {
9193
IntentData.shuffle to shuffle,
9294
IntentData.downloadTab to downloadTab,
9395
IntentData.noInternet to noInternet,
94-
IntentData.audioOnly to true
96+
IntentData.audioOnly to true,
97+
IntentData.sortOptions to sortOrder,
9598
)
9699

97100
stopBackgroundPlay(context)

app/src/main/java/com/github/libretube/services/OfflinePlayerService.kt

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ import com.github.libretube.helpers.PlayerHelper
2828
import com.github.libretube.ui.activities.MainActivity
2929
import com.github.libretube.ui.activities.NoInternetActivity
3030
import com.github.libretube.ui.activities.OfflinePlayerActivity
31+
import com.github.libretube.ui.fragments.DownloadSortingOrder
3132
import com.github.libretube.ui.fragments.DownloadTab
33+
import com.github.libretube.ui.fragments.DownloadsFragmentPage.Companion.sortDownloadList
3234
import com.github.libretube.util.PlayingQueue
3335
import kotlinx.coroutines.CoroutineScope
3436
import kotlinx.coroutines.Dispatchers
@@ -49,6 +51,7 @@ open class OfflinePlayerService : AbstractPlayerService() {
4951
private lateinit var downloadTab: DownloadTab
5052
private var shuffle: Boolean = false
5153
private var playlistId: String? = null
54+
private var downloadSortOrder: DownloadSortingOrder? = null
5255

5356
private val scope = CoroutineScope(Dispatchers.Main)
5457

@@ -79,15 +82,18 @@ open class OfflinePlayerService : AbstractPlayerService() {
7982
noInternetService = args.getBoolean(IntentData.noInternet, false)
8083
isAudioOnlyPlayer = args.getBoolean(IntentData.audioOnly, false)
8184
playlistId = args.getString(IntentData.playlistId)
85+
downloadSortOrder = args.serializable(IntentData.sortOptions)
8286

8387
PlayingQueue.clear()
8488

8589
this.videoId = if (shuffle) {
8690
runBlocking(Dispatchers.IO) {
8791
if (downloadTab == DownloadTab.PLAYLIST) {
88-
Database.downloadDao().getDownloadPlaylistById(playlistId!!).downloadVideos.randomOrNull()
92+
Database.downloadDao()
93+
.getDownloadPlaylistById(playlistId!!).downloadVideos.randomOrNull()
8994
} else {
90-
Database.downloadDao().getAll().filterByTab(downloadTab).randomOrNull()?.download
95+
Database.downloadDao().getAll().filterByTab(downloadTab)
96+
.randomOrNull()?.download
9197
}
9298
}?.videoId
9399
} else {
@@ -198,22 +204,26 @@ open class OfflinePlayerService : AbstractPlayerService() {
198204

199205
private suspend fun fillQueue() {
200206
if (downloadTab == DownloadTab.PLAYLIST) {
201-
val videos = withContext(Dispatchers.IO) {
207+
var videos = withContext(Dispatchers.IO) {
202208
Database.downloadDao().getDownloadPlaylistById(playlistId!!)
203209
}.downloadVideos
204210

211+
if (shuffle) videos = listOf(videos.first { it.videoId == videoId }) +
212+
videos.filter { it.videoId != videoId }.shuffled()
213+
else if (downloadSortOrder != null) videos =
214+
sortDownloadList(videos, downloadSortOrder!!)
205215
PlayingQueue.setStreams(videos.map { it.toStreamItem() })
206216
} else {
207-
val downloads = withContext(Dispatchers.IO) {
217+
var downloads = withContext(Dispatchers.IO) {
208218
Database.downloadDao().getAll()
209219
}
210220
.filterByTab(downloadTab)
211-
.filter { it.download.videoId != videoId }
212-
.toMutableList()
221+
.map { it.download }
213222

214-
if (shuffle) downloads.shuffle()
223+
if (shuffle) downloads = downloads.shuffled()
224+
else if (downloadSortOrder != null) downloads = sortDownloadList(downloads, downloadSortOrder!!)
215225

216-
PlayingQueue.add(*downloads.map { it.download.toStreamItem() }.toTypedArray())
226+
PlayingQueue.add(*downloads.map { it.toStreamItem() }.toTypedArray())
217227
}
218228
}
219229

app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import com.github.libretube.helpers.WindowHelper
3636
import com.github.libretube.services.AbstractPlayerService
3737
import com.github.libretube.services.OfflinePlayerService
3838
import com.github.libretube.ui.base.BaseActivity
39+
import com.github.libretube.ui.fragments.DownloadSortingOrder
3940
import com.github.libretube.ui.fragments.DownloadTab
4041
import com.github.libretube.ui.interfaces.TimeFrameReceiver
4142
import com.github.libretube.ui.listeners.SeekbarPreviewListener
@@ -145,15 +146,18 @@ class OfflinePlayerActivity : BaseActivity() {
145146
val videoId = intent?.getStringExtra(IntentData.videoId)
146147
val playlistId = intent?.getStringExtra(IntentData.playlistId)
147148
val shuffle = intent?.getBooleanExtra(IntentData.shuffle, false)
149+
val sortOrder = intent?.serializableExtra<DownloadSortingOrder>(IntentData.sortOptions)
148150

149151
binding = ActivityOfflinePlayerBinding.inflate(layoutInflater)
150152
setContentView(binding.root)
151153

154+
val downloadTab = if (playlistId == null) DownloadTab.VIDEO else DownloadTab.PLAYLIST
152155
val arguments = bundleOf(
153-
IntentData.downloadTab to DownloadTab.VIDEO,
156+
IntentData.downloadTab to downloadTab,
154157
IntentData.videoId to videoId,
155158
IntentData.playlistId to playlistId,
156159
IntentData.shuffle to shuffle,
160+
IntentData.sortOptions to sortOrder,
157161
IntentData.audioOnly to false
158162
)
159163
BackgroundHelper.startMediaService(this, OfflinePlayerService::class.java, arguments) {

app/src/main/java/com/github/libretube/ui/adapters/DownloadsAdapter.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import com.github.libretube.ui.activities.OfflinePlayerActivity
2424
import com.github.libretube.ui.adapters.callbacks.DiffUtilItemCallback
2525
import com.github.libretube.ui.base.BaseActivity
2626
import com.github.libretube.ui.extensions.setWatchProgressLength
27+
import com.github.libretube.ui.fragments.DownloadSortingOrder
2728
import com.github.libretube.ui.fragments.DownloadTab
2829
import com.github.libretube.ui.sheets.DownloadOptionsBottomSheet
2930
import com.github.libretube.ui.sheets.DownloadOptionsBottomSheet.Companion.DELETE_DOWNLOAD_REQUEST_KEY
@@ -42,6 +43,7 @@ class DownloadsAdapter(
4243
private val context: Context,
4344
private val downloadTab: DownloadTab,
4445
private val playlistId: String?,
46+
private val currentSortOrder: () -> DownloadSortingOrder,
4547
private val toggleDownload: (DownloadWithItems) -> Boolean
4648
) : ListAdapter<DownloadWithItems, DownloadsViewHolder>(DiffUtilItemCallback()) {
4749
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DownloadsViewHolder {
@@ -116,21 +118,24 @@ class DownloadsAdapter(
116118
DownloadTab.VIDEO -> {
117119
val intent = Intent(root.context, OfflinePlayerActivity::class.java)
118120
.putExtra(IntentData.videoId, download.videoId)
121+
.putExtra(IntentData.sortOptions, currentSortOrder())
119122
root.context.startActivity(intent)
120123
}
121124
DownloadTab.AUDIO -> {
122125
BackgroundHelper.playOnBackgroundOffline(
123126
root.context,
124127
download.videoId,
125128
playlistId,
126-
downloadTab
129+
downloadTab,
130+
sortOrder = currentSortOrder()
127131
)
128132
NavigationHelper.openAudioPlayerFragment(root.context, offlinePlayer = true)
129133
}
130134
DownloadTab.PLAYLIST -> {
131135
val intent = Intent(root.context, OfflinePlayerActivity::class.java)
132136
.putExtra(IntentData.videoId, download.videoId)
133137
.putExtra(IntentData.playlistId, playlistId)
138+
.putExtra(IntentData.sortOptions, currentSortOrder())
134139
root.context.startActivity(intent)
135140
}
136141
}

app/src/main/java/com/github/libretube/ui/fragments/DownloadsFragment.kt

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import com.github.libretube.constants.PreferenceKeys
3131
import com.github.libretube.databinding.FragmentDownloadContentBinding
3232
import com.github.libretube.databinding.FragmentDownloadsBinding
3333
import com.github.libretube.db.DatabaseHolder.Database
34+
import com.github.libretube.db.obj.Download
3435
import com.github.libretube.db.obj.DownloadPlaylistWithDownload
3536
import com.github.libretube.db.obj.DownloadWithItems
3637
import com.github.libretube.db.obj.filterByTab
@@ -69,7 +70,7 @@ enum class DownloadTab {
6970
PLAYLIST
7071
}
7172

72-
private enum class DownloadSortingOrder(@StringRes val stringId: Int) {
73+
enum class DownloadSortingOrder(@StringRes val stringId: Int) {
7374
OLDEST(R.string.least_recent),
7475
NEWEST(R.string.most_recent),
7576
ALPHABETIC(R.string.alphabetic),
@@ -186,31 +187,38 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment(R.layout.fragment_dow
186187
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
187188
_binding = FragmentDownloadContentBinding.bind(view)
188189
super.onViewCreated(view, savedInstanceState)
189-
adapter = DownloadsAdapter(requireContext(), downloadTab, downloadPlaylistId) {
190-
var isDownloading = false
191-
val ids = it.downloadItems
192-
.filter { item -> item.path.fileSize() < item.downloadSize }
193-
.map { item -> item.id }
194-
195-
if (!serviceConnection.isBound) {
196-
DownloadHelper.startDownloadService(requireContext())
197-
bindDownloadService(ids.toIntArray())
198-
return@DownloadsAdapter true
199-
}
200190

201-
binder?.getService()?.let { service ->
202-
isDownloading = ids.any { id -> service.isDownloading(id) }
191+
adapter =
192+
DownloadsAdapter(
193+
requireContext(), downloadTab, downloadPlaylistId,
194+
currentSortOrder = {
195+
DownloadSortingOrder.entries[selectedSortType]
196+
}
197+
) {
198+
var isDownloading = false
199+
val ids = it.downloadItems
200+
.filter { item -> item.path.fileSize() < item.downloadSize }
201+
.map { item -> item.id }
202+
203+
if (!serviceConnection.isBound) {
204+
DownloadHelper.startDownloadService(requireContext())
205+
bindDownloadService(ids.toIntArray())
206+
return@DownloadsAdapter true
207+
}
208+
209+
binder?.getService()?.let { service ->
210+
isDownloading = ids.any { id -> service.isDownloading(id) }
203211

204-
ids.forEach { id ->
205-
if (isDownloading) {
206-
service.pause(id)
207-
} else {
208-
service.resume(id)
212+
ids.forEach { id ->
213+
if (isDownloading) {
214+
service.pause(id)
215+
} else {
216+
service.resume(id)
217+
}
209218
}
210219
}
220+
return@DownloadsAdapter isDownloading.not()
211221
}
212-
return@DownloadsAdapter isDownloading.not()
213-
}
214222
binding.downloadsRecView.adapter = adapter
215223

216224
val filterOptions = DownloadSortingOrder.entries.map { getString(it.stringId) }
@@ -295,14 +303,8 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment(R.layout.fragment_dow
295303
}
296304

297305
private fun submitDownloadList(items: List<DownloadWithItems>) {
298-
val sortedItems = when (selectedSortType) {
299-
DownloadSortingOrder.OLDEST.ordinal -> items
300-
DownloadSortingOrder.NEWEST.ordinal -> items.reversed()
301-
DownloadSortingOrder.ALPHABETIC.ordinal -> items.sortedBy { it.download.title }
302-
DownloadSortingOrder.DURATION.ordinal -> items.sortedBy { it.download.duration }
303-
DownloadSortingOrder.CHANNEL.ordinal -> items.sortedBy { it.download.uploader }
304-
else -> items.sortedBy { it.downloadItems.sumOf { o -> o.downloadSize } }
305-
}
306+
val sortOrder = DownloadSortingOrder.entries[selectedSortType]
307+
val sortedItems = sortDownloadWithItemsList(items, sortOrder)
306308

307309
adapter.submitList(sortedItems)
308310
}
@@ -419,6 +421,33 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment(R.layout.fragment_dow
419421
_binding = null
420422
}
421423

424+
companion object {
425+
fun sortDownloadWithItemsList(
426+
items: List<DownloadWithItems>,
427+
selectedSortType: DownloadSortingOrder
428+
): List<DownloadWithItems> {
429+
return when (selectedSortType) {
430+
DownloadSortingOrder.OLDEST -> items
431+
DownloadSortingOrder.NEWEST -> items.reversed()
432+
DownloadSortingOrder.ALPHABETIC -> items.sortedBy { it.download.title }
433+
DownloadSortingOrder.DURATION -> items.sortedBy { it.download.duration }
434+
DownloadSortingOrder.CHANNEL -> items.sortedBy { it.download.uploader }
435+
DownloadSortingOrder.SIZE -> items.sortedBy { it.downloadItems.sumOf { o -> o.downloadSize } }
436+
}
437+
}
438+
439+
// ugly HACK: should probably be refactored in the future
440+
fun sortDownloadList(items: List<Download>, selectedSortType: DownloadSortingOrder): List<Download> {
441+
return when (selectedSortType) {
442+
DownloadSortingOrder.OLDEST -> items
443+
DownloadSortingOrder.NEWEST -> items.reversed()
444+
DownloadSortingOrder.ALPHABETIC -> items.sortedBy { it.title }
445+
DownloadSortingOrder.DURATION -> items.sortedBy { it.duration }
446+
DownloadSortingOrder.CHANNEL -> items.sortedBy { it.uploader }
447+
DownloadSortingOrder.SIZE -> items
448+
}
449+
}
450+
}
422451
}
423452

424453
class PlaylistDownloadsFragmentPage : Fragment(R.layout.fragment_download_content) {

0 commit comments

Comments
 (0)