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:
parent
9cc75a0e11
commit
e50bc80a0b
11 changed files with 30 additions and 8 deletions
|
@ -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.
|
||||||
|
|
|
@ -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) :
|
||||||
|
|
|
@ -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) :
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) :
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
||||||
|
|
|
@ -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" />
|
|
@ -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">
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue