Added Artist song sort order in Artist details fragment

This commit is contained in:
Prathamesh More 2021-12-31 15:18:50 +05:30
parent cd933b56dc
commit 7a2d14e061
7 changed files with 139 additions and 16 deletions

View file

@ -135,6 +135,7 @@ const val LOCK_SCREEN = "lock_screen"
const val ALBUM_ARTISTS_ONLY = "album_artists_only" const val ALBUM_ARTISTS_ONLY = "album_artists_only"
const val ALBUM_ARTIST = "album_artist" const val ALBUM_ARTIST = "album_artist"
const val ALBUM_DETAIL_SONG_SORT_ORDER = "album_detail_song_sort_order" const val ALBUM_DETAIL_SONG_SORT_ORDER = "album_detail_song_sort_order"
const val ARTIST_DETAIL_SONG_SORT_ORDER = "artist_detail_song_sort_order"
const val LYRICS_OPTIONS = "lyrics_tab_position" const val LYRICS_OPTIONS = "lyrics_tab_position"
const val CHOOSE_EQUALIZER = "choose_equalizer" const val CHOOSE_EQUALIZER = "choose_equalizer"
const val EQUALIZER = "equalizer" const val EQUALIZER = "equalizer"

View file

@ -5,11 +5,9 @@ import android.content.Intent
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.text.Spanned import android.text.Spanned
import android.view.Menu import android.view.*
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.activity.addCallback import androidx.activity.addCallback
import androidx.appcompat.widget.PopupMenu
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
@ -32,6 +30,7 @@ import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.SingleColorTarget import code.name.monkey.retromusic.glide.SingleColorTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder
import code.name.monkey.retromusic.interfaces.IAlbumClickListener import code.name.monkey.retromusic.interfaces.IAlbumClickListener
import code.name.monkey.retromusic.interfaces.ICabCallback import code.name.monkey.retromusic.interfaces.ICabCallback
import code.name.monkey.retromusic.interfaces.ICabHolder import code.name.monkey.retromusic.interfaces.ICabHolder
@ -39,10 +38,7 @@ import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.network.Result import code.name.monkey.retromusic.network.Result
import code.name.monkey.retromusic.network.model.LastFmArtist import code.name.monkey.retromusic.network.model.LastFmArtist
import code.name.monkey.retromusic.repository.RealRepository import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.util.CustomArtistImageUtil import code.name.monkey.retromusic.util.*
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.RetroColorUtil
import code.name.monkey.retromusic.util.RetroUtil
import com.afollestad.materialcab.attached.AttachedCab import com.afollestad.materialcab.attached.AttachedCab
import com.afollestad.materialcab.attached.destroy import com.afollestad.materialcab.attached.destroy
import com.afollestad.materialcab.attached.isActive import com.afollestad.materialcab.attached.isActive
@ -71,6 +67,9 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
private var lang: String? = null private var lang: String? = null
private var biography: Spanned? = null private var biography: Spanned? = null
private val savedSongSortOrder: String
get() = PreferenceUtil.artistDetailSongSortOrder
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
sharedElementEnterTransition = MaterialContainerTransform().apply { sharedElementEnterTransition = MaterialContainerTransform().apply {
@ -101,7 +100,7 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
setupRecyclerView() setupRecyclerView()
binding.fragmentArtistContent.playAction.apply { binding.fragmentArtistContent.playAction.apply {
setOnClickListener { MusicPlayerRemote.openQueue(artist.songs, 0, true) } setOnClickListener { MusicPlayerRemote.openQueue(artist.sortedSongs, 0, true) }
} }
binding.fragmentArtistContent.shuffleAction.apply { binding.fragmentArtistContent.shuffleAction.apply {
setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(artist.songs, true) } setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(artist.songs, true) }
@ -121,6 +120,7 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
requireActivity().onBackPressed() requireActivity().onBackPressed()
} }
} }
setupSongSortButton()
binding.appBarLayout?.statusBarForeground = binding.appBarLayout?.statusBarForeground =
MaterialShapeDrawable.createWithElevationOverlay(requireContext()) MaterialShapeDrawable.createWithElevationOverlay(requireContext())
} }
@ -168,7 +168,7 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
) )
binding.fragmentArtistContent.songTitle.text = songText binding.fragmentArtistContent.songTitle.text = songText
binding.fragmentArtistContent.albumTitle.text = albumText binding.fragmentArtistContent.albumTitle.text = albumText
songAdapter.swapDataSet(artist.songs.sortedBy { it.trackNumber }) songAdapter.swapDataSet(artist.sortedSongs)
albumAdapter.swapDataSet(artist.albums) albumAdapter.swapDataSet(artist.albums)
} }
@ -289,6 +289,53 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
return true return true
} }
private fun setupSongSortButton() {
binding.fragmentArtistContent.songSortOrder.setOnClickListener {
PopupMenu(requireContext(), binding.fragmentArtistContent.songSortOrder).apply {
inflate(R.menu.menu_artist_song_sort_order)
setUpSortOrderMenu(menu)
setOnMenuItemClickListener { menuItem ->
val sortOrder = when (menuItem.itemId) {
R.id.action_sort_order_title -> SortOrder.ArtistSongSortOrder.SONG_A_Z
R.id.action_sort_order_title_desc -> SortOrder.ArtistSongSortOrder.SONG_Z_A
R.id.action_sort_order_album -> SortOrder.ArtistSongSortOrder.SONG_ALBUM
R.id.action_sort_order_year -> SortOrder.ArtistSongSortOrder.SONG_YEAR
R.id.action_sort_order_song_duration -> SortOrder.ArtistSongSortOrder.SONG_DURATION
else -> {
throw IllegalArgumentException("invalid ${menuItem.title}")
}
}
menuItem.isChecked = true
setSaveSortOrder(sortOrder)
return@setOnMenuItemClickListener true
}
show()
}
}
}
private fun setSaveSortOrder(sortOrder: String) {
PreferenceUtil.artistDetailSongSortOrder = sortOrder
songAdapter.swapDataSet(artist.sortedSongs)
}
private fun setUpSortOrderMenu(sortOrder: Menu) {
when (savedSongSortOrder) {
SortOrder.ArtistSongSortOrder.SONG_A_Z -> sortOrder.findItem(R.id.action_sort_order_title).isChecked = true
SortOrder.ArtistSongSortOrder.SONG_Z_A -> sortOrder.findItem(R.id.action_sort_order_title_desc).isChecked = true
SortOrder.ArtistSongSortOrder.SONG_ALBUM ->
sortOrder.findItem(R.id.action_sort_order_album).isChecked = true
SortOrder.ArtistSongSortOrder.SONG_YEAR ->
sortOrder.findItem(R.id.action_sort_order_year).isChecked = true
SortOrder.ArtistSongSortOrder.SONG_DURATION ->
sortOrder.findItem(R.id.action_sort_order_song_duration).isChecked = true
else-> {
throw IllegalArgumentException("invalid $savedSongSortOrder")
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
when (requestCode) { when (requestCode) {

View file

@ -134,7 +134,7 @@ class SortOrder {
companion object { companion object {
/* Artist song sort order A-Z */ /* Artist song sort order A-Z */
private const val SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER const val SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER
/* Artist song sort order Z-A */ /* Artist song sort order Z-A */
const val SONG_Z_A = "$SONG_A_Z DESC" const val SONG_Z_A = "$SONG_A_Z DESC"

View file

@ -14,7 +14,9 @@
package code.name.monkey.retromusic.model package code.name.monkey.retromusic.model
import code.name.monkey.retromusic.helper.SortOrder
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
data class Artist( data class Artist(
val id: Long, val id: Long,
@ -29,7 +31,7 @@ data class Artist(
name = artistName name = artistName
} }
var name: String = "" var name: String = "-"
get() { get() {
val name = if (isAlbumArtist) getAlbumArtistName() val name = if (isAlbumArtist) getAlbumArtistName()
else getArtistName() else getArtistName()
@ -57,6 +59,39 @@ data class Artist(
val songs: List<Song> val songs: List<Song>
get() = albums.flatMap { it.songs } get() = albums.flatMap { it.songs }
val sortedSongs: List<Song>
get() = songs.sortedWith(
when (PreferenceUtil.artistDetailSongSortOrder) {
SortOrder.ArtistSongSortOrder.SONG_A_Z -> { o1, o2 ->
o1.title.compareTo(
o2.title
)
}
SortOrder.ArtistSongSortOrder.SONG_Z_A -> { o1, o2 ->
o2.title.compareTo(
o1.title
)
}
SortOrder.ArtistSongSortOrder.SONG_ALBUM -> { o1, o2 ->
o1.albumName.compareTo(
o2.albumName
)
}
SortOrder.ArtistSongSortOrder.SONG_YEAR -> { o1, o2 ->
o2.year.compareTo(
o1.year
)
}
SortOrder.ArtistSongSortOrder.SONG_DURATION -> { o1, o2 ->
o1.duration.compareTo(
o2.duration
)
}
else -> {
throw IllegalArgumentException("invalid ${PreferenceUtil.artistDetailSongSortOrder}")
}
})
fun safeGetFirstAlbum(): Album { fun safeGetFirstAlbum(): Album {
return albums.firstOrNull() ?: Album.empty return albums.firstOrNull() ?: Album.empty
} }

View file

@ -130,6 +130,13 @@ object PreferenceUtil {
) )
set(value) = sharedPreferences.edit { putString(ALBUM_DETAIL_SONG_SORT_ORDER, value) } set(value) = sharedPreferences.edit { putString(ALBUM_DETAIL_SONG_SORT_ORDER, value) }
var artistDetailSongSortOrder
get() = sharedPreferences.getStringOrDefault(
ARTIST_DETAIL_SONG_SORT_ORDER,
ArtistSongSortOrder.SONG_A_Z
)
set(value) = sharedPreferences.edit { putString(ARTIST_DETAIL_SONG_SORT_ORDER, value) }
var songSortOrder var songSortOrder
get() = sharedPreferences.getStringOrDefault( get() = sharedPreferences.getStringOrDefault(
SONG_SORT_ORDER, SONG_SORT_ORDER,

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<code.name.monkey.retromusic.views.insets.InsetsConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -79,10 +79,23 @@
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary"
android:textStyle="bold" android:textStyle="bold"
app:layout_constrainedWidth="true" app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toStartOf="@id/song_sort_order"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/albumRecyclerView"/> app:layout_constraintTop_toBottomOf="@id/albumRecyclerView"/>
<ImageButton
android:id="@+id/song_sort_order"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:background="@null"
android:padding="8dp"
android:src="@drawable/ic_sort"
app:layout_constraintBottom_toBottomOf="@+id/songTitle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/songTitle"
app:layout_constraintTop_toTopOf="@id/songTitle" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView" android:id="@+id/recyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -193,4 +206,4 @@
android:layout_height="72dp" android:layout_height="72dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/listeners" /> app:layout_constraintTop_toBottomOf="@id/listeners" />
</code.name.monkey.retromusic.views.insets.InsetsConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/action_sort_order_title"
android:title="@string/sort_order_a_z" />
<item
android:id="@+id/action_sort_order_title_desc"
android:title="@string/sort_order_z_a" />
<item
android:id="@+id/action_sort_order_album"
android:title="@string/sort_order_album" />
<item
android:id="@+id/action_sort_order_year"
android:title="@string/sort_order_year" />
<item
android:id="@+id/action_sort_order_song_duration"
android:title="@string/song_duration" />
</group>
</menu>