music: handle compilation flag tags

Handle COMPILATION and ITUNESCOMPILATION flags, if present.

Just map these to Various Artists and a compilation release type.

Resolves #373.
This commit is contained in:
Alexander Capehart 2023-03-19 13:14:53 -06:00
parent 9cc75a0e11
commit e50bc80a0b
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
11 changed files with 30 additions and 8 deletions

View file

@ -6,6 +6,7 @@
- Accept `REPLAYGAIN_*` adjustment information on OPUS files alongside - Accept `REPLAYGAIN_*` adjustment information on OPUS files alongside
`R128_*` adjustments. `R128_*` adjustments.
- List updates are now consistent across the app - List updates are now consistent across the app
- Fixed jarring header update in detail view
- Search view now trims search queries - Search view now trims search queries
- Audio effect (equalizer) session is now broadcast when playing/pausing - Audio effect (equalizer) session is now broadcast when playing/pausing
rather than on start/stop. rather than on start/stop.

View file

@ -32,6 +32,7 @@ import org.oxycblt.auxio.util.inflater
/** /**
* A [DetailHeaderAdapter] that shows [Album] information. * A [DetailHeaderAdapter] that shows [Album] information.
*
* @author Alexander Capehart (OxygenCobalt) * @author Alexander Capehart (OxygenCobalt)
*/ */
class AlbumDetailHeaderAdapter(private val listener: Listener) : class AlbumDetailHeaderAdapter(private val listener: Listener) :

View file

@ -32,6 +32,7 @@ import org.oxycblt.auxio.util.inflater
/** /**
* A [DetailHeaderAdapter] that shows [Artist] information. * A [DetailHeaderAdapter] that shows [Artist] information.
*
* @author Alexander Capehart (OxygenCobalt) * @author Alexander Capehart (OxygenCobalt)
*/ */
class ArtistDetailHeaderAdapter(private val listener: Listener) : class ArtistDetailHeaderAdapter(private val listener: Listener) :

View file

@ -35,6 +35,7 @@ abstract class DetailHeaderAdapter<T : MusicParent, VH : RecyclerView.ViewHolder
/** /**
* Bind the created header [RecyclerView.ViewHolder] with the current [parent]. * Bind the created header [RecyclerView.ViewHolder] with the current [parent].
*
* @param holder The [RecyclerView.ViewHolder] to bind. * @param holder The [RecyclerView.ViewHolder] to bind.
* @param parent The current [MusicParent] to bind. * @param parent The current [MusicParent] to bind.
*/ */
@ -42,6 +43,7 @@ abstract class DetailHeaderAdapter<T : MusicParent, VH : RecyclerView.ViewHolder
/** /**
* Update the [MusicParent] shown in the header. * Update the [MusicParent] shown in the header.
*
* @param parent The new [MusicParent] to show. * @param parent The new [MusicParent] to show.
*/ */
fun setParent(parent: T) { fun setParent(parent: T) {

View file

@ -32,6 +32,7 @@ import org.oxycblt.auxio.util.inflater
/** /**
* A [DetailHeaderAdapter] that shows [Genre] information. * A [DetailHeaderAdapter] that shows [Genre] information.
*
* @author Alexander Capehart (OxygenCobalt) * @author Alexander Capehart (OxygenCobalt)
*/ */
class GenreDetailHeaderAdapter(private val listener: Listener) : class GenreDetailHeaderAdapter(private val listener: Listener) :

View file

@ -24,7 +24,6 @@ import androidx.recyclerview.widget.*
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import java.util.concurrent.Executor import java.util.concurrent.Executor
import org.oxycblt.auxio.util.logD
/** /**
* A variant of ListDiffer with more flexible updates. * A variant of ListDiffer with more flexible updates.
@ -35,8 +34,7 @@ import org.oxycblt.auxio.util.logD
abstract class FlexibleListAdapter<T, VH : RecyclerView.ViewHolder>( abstract class FlexibleListAdapter<T, VH : RecyclerView.ViewHolder>(
diffCallback: DiffUtil.ItemCallback<T> diffCallback: DiffUtil.ItemCallback<T>
) : RecyclerView.Adapter<VH>() { ) : RecyclerView.Adapter<VH>() {
@Suppress("LeakingThis") @Suppress("LeakingThis") private val differ = FlexibleListDiffer(this, diffCallback)
private val differ = FlexibleListDiffer(this, diffCallback)
final override fun getItemCount() = differ.currentList.size final override fun getItemCount() = differ.currentList.size
/** The current list stored by the adapter's differ instance. */ /** The current list stored by the adapter's differ instance. */
val currentList: List<T> val currentList: List<T>
@ -55,8 +53,7 @@ abstract class FlexibleListAdapter<T, VH : RecyclerView.ViewHolder>(
newData: List<T>, newData: List<T>,
instructions: UpdateInstructions?, instructions: UpdateInstructions?,
callback: (() -> Unit)? = null callback: (() -> Unit)? = null
) = ) = differ.update(newData, instructions, callback)
differ.update(newData, instructions, callback)
} }
/** /**

View file

@ -157,6 +157,12 @@ private constructor(private val rawSong: RawSong, private val future: Future<Tra
// Genre // Genre
textFrames["TCON"]?.let { rawSong.genreNames = it } textFrames["TCON"]?.let { rawSong.genreNames = it }
// Compilation Flag
(textFrames["TXXX:compilation"] ?: textFrames["TXXX:itunescompilation"])?.let {
rawSong.albumArtistNames = rawSong.albumArtistNames.ifEmpty { COMPILATION_ALBUM_ARTISTS }
rawSong.releaseTypes = rawSong.releaseTypes.ifEmpty { COMPILATION_RELEASE_TYPES }
}
} }
/** /**
@ -257,6 +263,12 @@ private constructor(private val rawSong: RawSong, private val future: Future<Tra
// Genre // Genre
comments["genre"]?.let { rawSong.genreNames = it } comments["genre"]?.let { rawSong.genreNames = it }
// Compilation Flag
(comments["compilation"] ?: comments["itunescompilation"])?.let {
rawSong.albumArtistNames = rawSong.albumArtistNames.ifEmpty { COMPILATION_ALBUM_ARTISTS }
rawSong.releaseTypes = rawSong.releaseTypes.ifEmpty { COMPILATION_RELEASE_TYPES }
}
} }
class Factory @Inject constructor(private val mediaSourceFactory: MediaSource.Factory) : class Factory @Inject constructor(private val mediaSourceFactory: MediaSource.Factory) :
@ -273,4 +285,9 @@ private constructor(private val rawSong: RawSong, private val future: Future<Tra
requireNotNull(rawSong.mediaStoreId) { "Invalid raw: No id" } requireNotNull(rawSong.mediaStoreId) { "Invalid raw: No id" }
.toAudioUri()))) .toAudioUri())))
} }
private companion object {
val COMPILATION_ALBUM_ARTISTS = listOf("Various Artists")
val COMPILATION_RELEASE_TYPES = listOf("compilation")
}
} }

View file

@ -17,7 +17,7 @@
android:layout_marginStart="@dimen/spacing_large" android:layout_marginStart="@dimen/spacing_large"
android:layout_marginTop="@dimen/spacing_medium" android:layout_marginTop="@dimen/spacing_medium"
android:text="@string/set_pre_amp_with" android:text="@string/set_pre_amp_with"
android:textAppearance="@style/TextAppearance.Auxio.TitleMediumLowEmphasis" android:textAppearance="@style/TextAppearance.Auxio.TitleMedium"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@ -54,7 +54,7 @@
android:layout_marginStart="@dimen/spacing_large" android:layout_marginStart="@dimen/spacing_large"
android:layout_marginTop="@dimen/spacing_medium" android:layout_marginTop="@dimen/spacing_medium"
android:text="@string/set_pre_amp_without" android:text="@string/set_pre_amp_without"
android:textAppearance="@style/TextAppearance.Auxio.TitleMediumLowEmphasis" android:textAppearance="@style/TextAppearance.Auxio.TitleMedium"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/with_tags_slider" /> app:layout_constraintTop_toBottomOf="@+id/with_tags_slider" />

View file

@ -5,4 +5,5 @@
style="@style/Widget.Auxio.TextView.Header" style="@style/Widget.Auxio.TextView.Header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/colorSurface"
tools:text="Songs" /> tools:text="Songs" />

View file

@ -4,6 +4,7 @@
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"
android:background="?attr/colorSurface"
android:orientation="horizontal" android:orientation="horizontal"
android:layout_height="wrap_content"> android:layout_height="wrap_content">

View file

@ -113,7 +113,7 @@
</style> </style>
<style name="Widget.Auxio.TextView.Item.Primary" parent="Widget.Auxio.TextView.Item.Base"> <style name="Widget.Auxio.TextView.Item.Primary" parent="Widget.Auxio.TextView.Item.Base">
<item name="android:textAppearance">@style/TextAppearance.Auxio.TitleMediumLowEmphasis <item name="android:textAppearance">@style/TextAppearance.Auxio.TitleMedium
</item> </item>
<item name="android:textColor">?android:attr/textColorPrimary</item> <item name="android:textColor">?android:attr/textColorPrimary</item>
</style> </style>