Added Artist song sort order in Artist details fragment
This commit is contained in:
parent
cd933b56dc
commit
7a2d14e061
7 changed files with 139 additions and 16 deletions
|
@ -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"
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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>
|
20
app/src/main/res/menu/menu_artist_song_sort_order.xml
Normal file
20
app/src/main/res/menu/menu_artist_song_sort_order.xml
Normal 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>
|
Loading…
Add table
Add a link
Reference in a new issue