detail: default to "no disc" instead of "disc 1"
Default tracks without a disc to a group called "No disc" instead of disc 1. This should reduce confusion on the user end, as it will make improper taggings more apparent instead of simply degrading to a werid sort ordering. Resolves #405.
This commit is contained in:
parent
4210a8d247
commit
8939d341e6
3 changed files with 30 additions and 18 deletions
|
@ -30,6 +30,7 @@ import kotlinx.coroutines.flow.StateFlow
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.yield
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.detail.list.DiscHeader
|
||||
import org.oxycblt.auxio.detail.list.EditHeader
|
||||
import org.oxycblt.auxio.detail.list.SortHeader
|
||||
import org.oxycblt.auxio.list.BasicHeader
|
||||
|
@ -46,7 +47,6 @@ import org.oxycblt.auxio.music.MusicRepository
|
|||
import org.oxycblt.auxio.music.MusicSettings
|
||||
import org.oxycblt.auxio.music.Playlist
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.music.info.Disc
|
||||
import org.oxycblt.auxio.music.info.ReleaseType
|
||||
import org.oxycblt.auxio.music.metadata.AudioProperties
|
||||
import org.oxycblt.auxio.playback.PlaybackSettings
|
||||
|
@ -409,12 +409,11 @@ constructor(
|
|||
// To create a good user experience regarding disc numbers, we group the album's
|
||||
// songs up by disc and then delimit the groups by a disc header.
|
||||
val songs = albumSongSort.songs(album.songs)
|
||||
// Songs without disc tags become part of Disc 1.
|
||||
val byDisc = songs.groupBy { it.disc ?: Disc(1, null) }
|
||||
val byDisc = songs.groupBy { it.disc }
|
||||
if (byDisc.size > 1) {
|
||||
logD("Album has more than one disc, interspersing headers")
|
||||
for (entry in byDisc.entries) {
|
||||
list.add(entry.key)
|
||||
list.add(DiscHeader(entry.key))
|
||||
list.addAll(entry.value)
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -49,14 +49,14 @@ class AlbumDetailListAdapter(private val listener: Listener<Song>) :
|
|||
override fun getItemViewType(position: Int) =
|
||||
when (getItem(position)) {
|
||||
// Support sub-headers for each disc, and special album songs.
|
||||
is Disc -> DiscViewHolder.VIEW_TYPE
|
||||
is DiscHeader -> DiscHeaderViewHolder.VIEW_TYPE
|
||||
is Song -> AlbumSongViewHolder.VIEW_TYPE
|
||||
else -> super.getItemViewType(position)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
|
||||
when (viewType) {
|
||||
DiscViewHolder.VIEW_TYPE -> DiscViewHolder.from(parent)
|
||||
DiscHeaderViewHolder.VIEW_TYPE -> DiscHeaderViewHolder.from(parent)
|
||||
AlbumSongViewHolder.VIEW_TYPE -> AlbumSongViewHolder.from(parent)
|
||||
else -> super.onCreateViewHolder(parent, viewType)
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ class AlbumDetailListAdapter(private val listener: Listener<Song>) :
|
|||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
super.onBindViewHolder(holder, position)
|
||||
when (val item = getItem(position)) {
|
||||
is Disc -> (holder as DiscViewHolder).bind(item)
|
||||
is DiscHeader -> (holder as DiscHeaderViewHolder).bind(item)
|
||||
is Song -> (holder as AlbumSongViewHolder).bind(item, listener)
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ class AlbumDetailListAdapter(private val listener: Listener<Song>) :
|
|||
override fun areContentsTheSame(oldItem: Item, newItem: Item) =
|
||||
when {
|
||||
oldItem is Disc && newItem is Disc ->
|
||||
DiscViewHolder.DIFF_CALLBACK.areContentsTheSame(oldItem, newItem)
|
||||
DiscHeaderViewHolder.DIFF_CALLBACK.areContentsTheSame(oldItem, newItem)
|
||||
oldItem is Song && newItem is Song ->
|
||||
AlbumSongViewHolder.DIFF_CALLBACK.areContentsTheSame(oldItem, newItem)
|
||||
|
||||
|
@ -88,23 +88,35 @@ class AlbumDetailListAdapter(private val listener: Listener<Song>) :
|
|||
}
|
||||
|
||||
/**
|
||||
* A [RecyclerView.ViewHolder] that displays a [Disc] to delimit different disc groups. Use [from]
|
||||
* to create an instance.
|
||||
* A wrapper around [Disc] signifying that a header should be shown for a disc group.
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*/
|
||||
data class DiscHeader(val inner: Disc?) : Item
|
||||
|
||||
/**
|
||||
* A [RecyclerView.ViewHolder] that displays a [DiscHeader] to delimit different disc groups. Use
|
||||
* [from] to create an instance.
|
||||
*
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*/
|
||||
private class DiscViewHolder(private val binding: ItemDiscHeaderBinding) :
|
||||
private class DiscHeaderViewHolder(private val binding: ItemDiscHeaderBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
/**
|
||||
* Bind new data to this instance.
|
||||
*
|
||||
* @param disc The new [disc] to bind.
|
||||
* @param discHeader The new [DiscHeader] to bind.
|
||||
*/
|
||||
fun bind(disc: Disc) {
|
||||
binding.discNumber.text = binding.context.getString(R.string.fmt_disc_no, disc.number)
|
||||
binding.discName.apply {
|
||||
text = disc.name
|
||||
isGone = disc.name == null
|
||||
fun bind(discHeader: DiscHeader) {
|
||||
val disc = discHeader.inner
|
||||
if (disc != null) {
|
||||
binding.discNumber.text = binding.context.getString(R.string.fmt_disc_no, disc.number)
|
||||
binding.discName.apply {
|
||||
text = disc.name
|
||||
isGone = text == null
|
||||
}
|
||||
} else {
|
||||
binding.discNumber.text = binding.context.getString(R.string.def_disc)
|
||||
binding.discName.isGone = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +131,7 @@ private class DiscViewHolder(private val binding: ItemDiscHeaderBinding) :
|
|||
* @return A new instance.
|
||||
*/
|
||||
fun from(parent: View) =
|
||||
DiscViewHolder(ItemDiscHeaderBinding.inflate(parent.context.inflater))
|
||||
DiscHeaderViewHolder(ItemDiscHeaderBinding.inflate(parent.context.inflater))
|
||||
|
||||
/** A comparator that can be used with DiffUtil. */
|
||||
val DIFF_CALLBACK =
|
||||
|
|
|
@ -332,6 +332,7 @@
|
|||
<string name="def_artist">Unknown artist</string>
|
||||
<string name="def_genre">Unknown genre</string>
|
||||
<string name="def_date">No date</string>
|
||||
<string name="def_disc">No disc</string>
|
||||
<string name="def_track">No track</string>
|
||||
<string name="def_song_count">No songs</string>
|
||||
<string name="def_playback">No music playing</string>
|
||||
|
|
Loading…
Reference in a new issue