diff --git a/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt b/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt index 0e011109c..26c64b2b1 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt @@ -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 { diff --git a/app/src/main/java/org/oxycblt/auxio/detail/list/AlbumDetailListAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/list/AlbumDetailListAdapter.kt index b7217a681..15ece1b35 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/list/AlbumDetailListAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/list/AlbumDetailListAdapter.kt @@ -49,14 +49,14 @@ class AlbumDetailListAdapter(private val listener: Listener) : 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) : 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) : 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) : } /** - * 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 = diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e57eeb348..d0ab06f20 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -332,6 +332,7 @@ Unknown artist Unknown genre No date + No disc No track No songs No music playing