Merge pull request #3648 from Bnyro/master

Sort menu for local and private playlist
This commit is contained in:
Bnyro 2023-04-27 20:12:53 +02:00 committed by GitHub
commit 9cb2cfd6aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 136 additions and 60 deletions

View File

@ -38,6 +38,7 @@ object PreferenceKeys {
const val ALTERNATIVE_VIDEOS_LAYOUT = "alternative_videos_layout"
const val NEW_VIDEOS_BADGE = "new_videos_badge"
const val PLAYLISTS_ORDER = "playlists_order"
const val PLAYLIST_SORT_ORDER = "playlist_sort_order"
/**
* Instance

View File

@ -6,6 +6,7 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isGone
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
@ -22,6 +23,7 @@ import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.obj.Playlist
import com.github.libretube.api.obj.StreamItem
import com.github.libretube.constants.IntentData
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.databinding.FragmentPlaylistBinding
import com.github.libretube.db.DatabaseHolder
import com.github.libretube.enums.PlaylistType
@ -31,8 +33,10 @@ import com.github.libretube.extensions.serializable
import com.github.libretube.extensions.toID
import com.github.libretube.helpers.ImageHelper
import com.github.libretube.helpers.NavigationHelper
import com.github.libretube.helpers.PreferenceHelper
import com.github.libretube.ui.adapters.PlaylistAdapter
import com.github.libretube.ui.models.PlayerViewModel
import com.github.libretube.ui.sheets.BaseBottomSheet
import com.github.libretube.ui.sheets.PlaylistOptionsBottomSheet
import com.github.libretube.util.PlayingQueue
import kotlinx.coroutines.Dispatchers
@ -58,6 +62,11 @@ class PlaylistFragment : Fragment() {
// view models
private val playerViewModel: PlayerViewModel by activityViewModels()
private var selectedSortOrder = PreferenceHelper.getInt(PreferenceKeys.PLAYLIST_SORT_ORDER, 0)
set(value) {
PreferenceHelper.putInt(PreferenceKeys.PLAYLIST_SORT_ORDER, value)
field = value
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -139,6 +148,8 @@ class PlaylistFragment : Fragment() {
binding.playlistInfo.text = getChannelAndVideoString(response, response.videos)
showPlaylistVideos(response)
// show playlist options
binding.optionsMenu.setOnClickListener {
PlaylistOptionsBottomSheet(
@ -197,9 +208,57 @@ class PlaylistFragment : Fragment() {
keepQueue = true
)
}
binding.sortMenu.isGone = false
binding.sortMenu.setOnClickListener {
val sortOptions = resources.getStringArray(R.array.playlistSortOptions)
BaseBottomSheet().apply {
setSimpleItems(sortOptions.toList()) { index ->
selectedSortOrder = index
showPlaylistVideos(response)
}
}.show(childFragmentManager)
}
}
playlistAdapter = PlaylistAdapter(playlistFeed, playlistId!!, playlistType)
withContext(Dispatchers.IO) {
// update the playlist thumbnail if bookmarked
val playlistBookmark = DatabaseHolder.Database.playlistBookmarkDao().getAll()
.firstOrNull { it.playlistId == playlistId }
playlistBookmark?.let {
if (it.thumbnailUrl != response.thumbnailUrl) {
it.thumbnailUrl = response.thumbnailUrl
DatabaseHolder.Database.playlistBookmarkDao().update(it)
}
}
}
}
}
}
private fun showPlaylistVideos(playlist: Playlist) {
val videos = if (playlistType == PlaylistType.PUBLIC) playlistFeed
else {
when (selectedSortOrder) {
0, 1 -> {
if (playlistType == PlaylistType.LOCAL) playlistFeed.sortedBy {
it.url.orEmpty().toInt()
} else playlistFeed
}
2, 3 -> {
playlistFeed.sortedBy { it.duration }
}
4, 5 -> {
playlistFeed.sortedBy { it.title }
}
else -> throw IllegalArgumentException()
}.let {
if (selectedSortOrder % 2 == 0) it else it.reversed()
}
}
playlistAdapter = PlaylistAdapter(videos.toMutableList(), playlistId!!, playlistType)
binding.playlistRecView.adapter = playlistAdapter
// listen for playlist items to become deleted
playlistAdapter!!.registerAdapterDataObserver(object :
@ -212,12 +271,10 @@ class PlaylistFragment : Fragment() {
)
}
binding.playlistInfo.text =
getChannelAndVideoString(response, playlistFeed.size)
binding.playlistInfo.text = getChannelAndVideoString(playlist, playlistFeed.size)
}
})
binding.playlistRecView.adapter = playlistAdapter
binding.playlistScrollview.viewTreeObserver.addOnScrollChangedListener {
if (_binding?.playlistScrollview?.canScrollVertically(1) == false &&
!isLoading
@ -259,20 +316,6 @@ class PlaylistFragment : Fragment() {
val itemTouchHelper = ItemTouchHelper(itemTouchCallback)
itemTouchHelper.attachToRecyclerView(binding.playlistRecView)
}
withContext(Dispatchers.IO) {
// update the playlist thumbnail if bookmarked
val playlistBookmark = DatabaseHolder.Database.playlistBookmarkDao().getAll()
.firstOrNull { it.playlistId == playlistId }
playlistBookmark?.let {
if (it.thumbnailUrl != response.thumbnailUrl) {
it.thumbnailUrl = response.thumbnailUrl
DatabaseHolder.Database.playlistBookmarkDao().update(it)
}
}
}
}
}
}
@SuppressLint("StringFormatInvalid", "StringFormatMatches")

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:autoMirrored="true"
android:height="24dp"
android:tint="?colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp">
<path android:fillColor="@android:color/white"
android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z"/>
</vector>

View File

@ -53,6 +53,15 @@
android:textSize="20sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/sortMenu"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:layout_marginEnd="10dp"
android:src="@drawable/ic_sort"
android:visibility="gone"/>
<ImageView
android:id="@+id/optionsMenu"
android:layout_width="20dp"

View File

@ -127,7 +127,7 @@
android:paddingHorizontal="10dp"
android:text="@string/most_recent"
android:textSize="16sp"
app:drawableEndCompat="@drawable/ic_arrow_downward" />
app:drawableEndCompat="@drawable/ic_sort" />
</FrameLayout>

View File

@ -286,6 +286,15 @@
<item>@string/yt_shorts</item>
</string-array>
<string-array name="playlistSortOptions">
<item>@string/least_recent</item>
<item>@string/most_recent</item>
<item>@string/duration</item>
<item>@string/duration_reversed</item>
<item>@string/playlist_name_az</item>
<item>@string/playlist_name_za</item>
</string-array>
<string-array name="requiredNetwork">
<item>@string/network_all</item>
<item>@string/network_wifi</item>

View File

@ -408,6 +408,10 @@
<string name="play_automatically_summary">Start playing video automatically when selecting</string>
<string name="fullscreen_gestures">Enter/exit fullscreen gestures</string>
<string name="go_to_video">Go to video</string>
<string name="playlist_name_az">Playlist Name (A-Z)</string>
<string name="playlist_name_za">Playlist Name (Z-A)</string>
<string name="duration">Duration</string>
<string name="duration_reversed">Duration (reversed)</string>
<!-- Notification channel strings -->
<string name="download_channel_name">Download Service</string>