music: respect individual artist names [#66]

Modify the music loader to use the normal artist name when using song
titles while still retaining album artist functionality.

Oftentimes music files will be tagged as to use the artist tag to
specify performers, collaborators, and others, and then use the album
artist tag to group them up into a single artist. Previously, Auxio
would only use the album artist tag, which flattened the collaborator
information out for consistency. Resolve this by implementing a sort
of "resolved artist name" for songs that is used in the UI and nowhere
else. This seems to work well, but at the same time further ruins the
API surface for handling music objects. An acceptable price to pay
for a better UX.
This commit is contained in:
OxygenCobalt 2022-01-30 16:31:29 -07:00
parent 50f6f8f348
commit 50a2305f63
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
23 changed files with 74 additions and 87 deletions

View file

@ -198,8 +198,12 @@ class ArtistDetailAdapter(
binding.detailName.text = data.resolvedName binding.detailName.text = data.resolvedName
binding.detailSubhead.text = data.genre?.resolvedName // Get the genre that corresponds to the most songs in this artist, which would be
?: context.getString(R.string.def_genre) // the most "Prominent" genre.
binding.detailSubhead.text = data.songs
.groupBy { it.genre?.resolvedName }
.entries.maxByOrNull { it.value.size }
?.key ?: context.getString(R.string.def_genre)
binding.detailInfo.text = context.getString( binding.detailInfo.text = context.getString(
R.string.fmt_counts, R.string.fmt_counts,

View file

@ -60,6 +60,8 @@ class SongListFragment : HomeListFragment() {
val song = homeModel.songs.value!![idx] val song = homeModel.songs.value!![idx]
// Change how we display the popup depending on the mode. // Change how we display the popup depending on the mode.
// We don't use the more correct resolve(Model)Name here, as sorts are largely
// based off the names of the parent objects and not the child objects.
when (homeModel.getSortForDisplay(DisplayMode.SHOW_SONGS)) { when (homeModel.getSortForDisplay(DisplayMode.SHOW_SONGS)) {
// Name -> Use name // Name -> Use name
is Sort.ByName -> song.name.sliceArticle() is Sort.ByName -> song.name.sliceArticle()

View file

@ -54,16 +54,6 @@ sealed class MusicParent : Music() {
/** /**
* The data object for a song. Inherits [BaseModel]. * The data object for a song. Inherits [BaseModel].
* @property fileName The raw filename for this track
* @property albumId The Song's Album ID.
* Never use this outside of when attaching a song to its album.
* @property track The Song's Track number
* @property duration The duration of the song, in millis.
* @property album The Song's parent album. Use this instead of [albumId].
* @property genre The Song's [Genre].
* These are not ensured to be linked due to possible quirks in the genre loading system.
* @property seconds The Song's duration in seconds
* @property formattedDuration The Song's duration as a duration string.
*/ */
data class Song( data class Song(
override val id: Long, override val id: Long,
@ -71,7 +61,8 @@ data class Song(
val fileName: String, val fileName: String,
val albumName: String, val albumName: String,
val albumId: Long, val albumId: Long,
val artistName: String, val artistName: String?,
val albumArtistName: String?,
val year: Int, val year: Int,
val track: Int, val track: Int,
val duration: Long val duration: Long
@ -94,6 +85,14 @@ data class Song(
return result return result
} }
/** An album name resolved to this song in particular. */
val resolvedAlbumName: String get() =
album.resolvedName
/** An artist name resolved to this song in particular. */
val resolvedArtistName: String get() =
artistName ?: album.artist.resolvedName
fun linkAlbum(album: Album) { fun linkAlbum(album: Album) {
mAlbum = album mAlbum = album
} }
@ -105,11 +104,6 @@ data class Song(
/** /**
* The data object for an album. Inherits [MusicParent]. * The data object for an album. Inherits [MusicParent].
* @property artistName The name of the parent artist. Do not use this outside of creating the artist from albums
* @property year The year this album was released. 0 if there is none in the metadata.
* @property artist The Album's parent [Artist]. use this instead of [artistName]
* @property songs The Album's child [Song]s.
* @property totalDuration The combined duration of all of the album's child songs, formatted.
*/ */
data class Album( data class Album(
override val id: Long, override val id: Long,
@ -130,9 +124,11 @@ data class Album(
val totalDuration: String get() = val totalDuration: String get() =
songs.sumOf { it.seconds }.toDuration(false) songs.sumOf { it.seconds }.toDuration(false)
fun linkArtist(artist: Artist) { override val resolvedName: String
mArtist = artist get() = name
}
val resolvedArtistName: String get() =
artist.resolvedName
override val hash: Long get() { override val hash: Long get() {
var result = name.hashCode().toLong() var result = name.hashCode().toLong()
@ -141,14 +137,15 @@ data class Album(
return result return result
} }
override val resolvedName: String fun linkArtist(artist: Artist) {
get() = name mArtist = artist
}
} }
/** /**
* The data object for an artist. Inherits [MusicParent] * The data object for an *album* artist. Inherits [MusicParent]. This differs from the actual
* performers.
* @property albums The list of all [Album]s in this artist * @property albums The list of all [Album]s in this artist
* @property genre The most prominent genre for this artist
* @property songs The list of all [Song]s in this artist * @property songs The list of all [Song]s in this artist
*/ */
data class Artist( data class Artist(
@ -163,16 +160,7 @@ data class Artist(
} }
} }
val genre: Genre? by lazy { val songs = albums.flatMap { it.songs }
// Get the genre that corresponds to the most songs in this artist, which would be
// the most "Prominent" genre.
songs.groupBy { it.genre }.entries.maxByOrNull { it.value.size }?.key
}
val songs: List<Song> by lazy {
albums.flatMap { it.songs }
}
override val hash = name.hashCode().toLong() override val hash = name.hashCode().toLong()
} }

View file

@ -142,12 +142,10 @@ class MusicLoader {
val album = cursor.getString(albumIndex) val album = cursor.getString(albumIndex)
val albumId = cursor.getLong(albumIdIndex) val albumId = cursor.getLong(albumIdIndex)
// MediaStore does not have support for artists in the album field, so we have to val artist = cursor.getString(artistIndex).let {
// detect it on a song-by-song basis. This is another massive bottleneck in the music if (it != MediaStore.UNKNOWN_STRING) it else null
// loader since we have to do a massive query to get what we want, but theres not }
// a lot I can do that doesn't degrade UX. val albumArtist = cursor.getStringOrNull(albumArtistIndex)
val artist = cursor.getStringOrNull(albumArtistIndex)
?: cursor.getString(artistIndex)
val year = cursor.getInt(yearIndex) val year = cursor.getInt(yearIndex)
val track = cursor.getInt(trackIndex) val track = cursor.getInt(trackIndex)
@ -155,7 +153,8 @@ class MusicLoader {
songs.add( songs.add(
Song( Song(
id, title, fileName, album, albumId, artist, year, track, duration id, title, fileName, album, albumId, artist,
albumArtist, year, track, duration
) )
) )
} }
@ -181,11 +180,11 @@ class MusicLoader {
albums.add( albums.add(
Album( Album(
id = entry.key, // When assigning an artist to an album, use the album artist first, then the
name = song.albumName, // normal artist, and then the internal representation of an unknown artist name.
artistName = song.artistName, entry.key, song.albumName,
songs = entry.value, song.albumArtistName ?: song.artistName ?: MediaStore.UNKNOWN_STRING,
year = song.year song.year, entry.value
) )
) )
} }
@ -210,10 +209,8 @@ class MusicLoader {
// Use the hashCode of the artist name as our ID and move on. // Use the hashCode of the artist name as our ID and move on.
artists.add( artists.add(
Artist( Artist(
id = entry.key.hashCode().toLong(), entry.key.hashCode().toLong(), entry.key,
name = entry.key, resolvedName, entry.value
resolvedName = resolvedName,
albums = entry.value
) )
) )
} }
@ -243,10 +240,12 @@ class MusicLoader {
// No non-broken genre would be missing a name. // No non-broken genre would be missing a name.
val id = cursor.getLong(idIndex) val id = cursor.getLong(idIndex)
val name = cursor.getStringOrNull(nameIndex) ?: continue val name = cursor.getStringOrNull(nameIndex) ?: continue
val resolvedName = when (name) {
MediaStore.UNKNOWN_STRING -> context.getString(R.string.def_genre)
else -> name.getGenreNameCompat() ?: name
}
val genre = Genre( val genre = Genre(id, name, resolvedName)
id, name, name.getGenreNameCompat() ?: name
)
linkGenre(context, genre, songs) linkGenre(context, genre, songs)
genres.add(genre) genres.add(genre)

View file

@ -79,12 +79,12 @@ class PlaybackNotification private constructor(
*/ */
fun setMetadata(song: Song, onDone: () -> Unit) { fun setMetadata(song: Song, onDone: () -> Unit) {
setContentTitle(song.name) setContentTitle(song.name)
setContentText(song.album.artist.resolvedName) setContentText(song.resolvedArtistName)
// On older versions of android [API <24], show the song's album on the subtext instead of // On older versions of android [API <24], show the song's album on the subtext instead of
// the current mode, as that makes more sense for the old style of media notifications. // the current mode, as that makes more sense for the old style of media notifications.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
setSubText(song.album.name) setSubText(song.resolvedAlbumName)
} }
// loadBitmap() is concurrent, so only call back to the object calling this function when // loadBitmap() is concurrent, so only call back to the object calling this function when

View file

@ -114,7 +114,7 @@ class PlaybackSessionConnector(
return return
} }
val artistName = song.album.artist.resolvedName val artistName = song.resolvedArtistName
val builder = MediaMetadataCompat.Builder() val builder = MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, song.name) .putString(MediaMetadataCompat.METADATA_KEY_TITLE, song.name)
@ -123,7 +123,7 @@ class PlaybackSessionConnector(
.putString(MediaMetadataCompat.METADATA_KEY_AUTHOR, artistName) .putString(MediaMetadataCompat.METADATA_KEY_AUTHOR, artistName)
.putString(MediaMetadataCompat.METADATA_KEY_COMPOSER, artistName) .putString(MediaMetadataCompat.METADATA_KEY_COMPOSER, artistName)
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST, artistName) .putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST, artistName)
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, song.album.name) .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, song.resolvedAlbumName)
.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, song.duration) .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, song.duration)
// Load the cover asynchronously. This is the entire reason I don't use a plain // Load the cover asynchronously. This is the entire reason I don't use a plain

View file

@ -102,7 +102,7 @@ private fun RemoteViews.applyMeta(context: Context, state: WidgetState): RemoteV
applyCover(context, state) applyCover(context, state)
setTextViewText(R.id.widget_song, state.song.name) setTextViewText(R.id.widget_song, state.song.name)
setTextViewText(R.id.widget_artist, state.song.album.artist.resolvedName) setTextViewText(R.id.widget_artist, state.song.resolvedArtistName)
return this return this
} }
@ -111,7 +111,8 @@ private fun RemoteViews.applyCover(context: Context, state: WidgetState): Remote
if (state.albumArt != null) { if (state.albumArt != null) {
setImageViewBitmap(R.id.widget_cover, state.albumArt) setImageViewBitmap(R.id.widget_cover, state.albumArt)
setContentDescription( setContentDescription(
R.id.widget_cover, context.getString(R.string.desc_album_cover, state.song.album.name) R.id.widget_cover,
context.getString(R.string.desc_album_cover, state.song.resolvedAlbumName)
) )
} else { } else {
setImageViewResource(R.id.widget_cover, R.drawable.ic_widget_album) setImageViewResource(R.id.widget_cover, R.drawable.ic_widget_album)

View file

@ -82,7 +82,7 @@
android:layout_marginStart="@dimen/spacing_mid_large" android:layout_marginStart="@dimen/spacing_mid_large"
android:layout_marginEnd="@dimen/spacing_mid_large" android:layout_marginEnd="@dimen/spacing_mid_large"
android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album.artist)}" android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album.artist)}"
android:text="@{song.album.artist.resolvedName}" android:text="@{song.resolvedArtistName}"
app:layout_constraintBottom_toTopOf="@+id/playback_album" app:layout_constraintBottom_toTopOf="@+id/playback_album"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_bias="0.5"
@ -98,7 +98,7 @@
android:layout_marginStart="@dimen/spacing_mid_large" android:layout_marginStart="@dimen/spacing_mid_large"
android:layout_marginEnd="@dimen/spacing_mid_large" android:layout_marginEnd="@dimen/spacing_mid_large"
android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album)}" android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album)}"
android:text="@{song.album.name}" android:text="@{song.resolvedAlbumName}"
app:layout_constraintBottom_toBottomOf="@+id/playback_cover" app:layout_constraintBottom_toBottomOf="@+id/playback_cover"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_bias="0.5"

View file

@ -79,7 +79,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album.artist)}" android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album.artist)}"
android:text="@{song.album.artist.resolvedName}" android:text="@{song.resolvedArtistName}"
app:layout_constraintBottom_toTopOf="@+id/playback_album" app:layout_constraintBottom_toTopOf="@+id/playback_album"
app:layout_constraintStart_toStartOf="@+id/playback_song_container" app:layout_constraintStart_toStartOf="@+id/playback_song_container"
app:layout_constraintEnd_toEndOf="@+id/playback_song_container" app:layout_constraintEnd_toEndOf="@+id/playback_song_container"
@ -93,7 +93,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album)}" android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album)}"
android:text="@{song.album.name}" android:text="@{song.resolvedAlbumName}"
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar" app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="@+id/playback_song_container" app:layout_constraintStart_toStartOf="@+id/playback_song_container"

View file

@ -70,7 +70,7 @@
android:layout_marginStart="@dimen/spacing_large" android:layout_marginStart="@dimen/spacing_large"
android:layout_marginEnd="@dimen/spacing_large" android:layout_marginEnd="@dimen/spacing_large"
android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album.artist)}" android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album.artist)}"
android:text="@{song.album.artist.resolvedName}" android:text="@{song.resolvedArtistName}"
app:layout_constraintBottom_toTopOf="@+id/playback_album" app:layout_constraintBottom_toTopOf="@+id/playback_album"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -84,7 +84,7 @@
android:layout_marginStart="@dimen/spacing_large" android:layout_marginStart="@dimen/spacing_large"
android:layout_marginEnd="@dimen/spacing_large" android:layout_marginEnd="@dimen/spacing_large"
android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album)}" android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album)}"
android:text="@{song.album.name}" android:text="@{song.resolvedAlbumName}"
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar" app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View file

@ -52,7 +52,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_small" android:layout_marginStart="@dimen/spacing_small"
android:ellipsize="end" android:ellipsize="end"
android:text="@{@string/fmt_two(song.album.artist.resolvedName, song.album.name)}" android:text="@{@string/fmt_two(song.resolvedArtistName, song.resolvedAlbumName)}"
app:layout_constraintBottom_toBottomOf="@+id/playback_cover" app:layout_constraintBottom_toBottomOf="@+id/playback_cover"
app:layout_constraintEnd_toEndOf="@+id/playback_song" app:layout_constraintEnd_toEndOf="@+id/playback_song"
app:layout_constraintStart_toEndOf="@+id/playback_cover" app:layout_constraintStart_toEndOf="@+id/playback_cover"

View file

@ -80,7 +80,7 @@
android:layout_marginStart="@dimen/spacing_mid_large" android:layout_marginStart="@dimen/spacing_mid_large"
android:layout_marginEnd="@dimen/spacing_mid_large" android:layout_marginEnd="@dimen/spacing_mid_large"
android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album.artist)}" android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album.artist)}"
android:text="@{song.album.artist.resolvedName}" android:text="@{song.resolvedArtistName}"
app:layout_constraintBottom_toTopOf="@+id/playback_album" app:layout_constraintBottom_toTopOf="@+id/playback_album"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_bias="0.5"
@ -96,7 +96,7 @@
android:layout_marginStart="@dimen/spacing_mid_large" android:layout_marginStart="@dimen/spacing_mid_large"
android:layout_marginEnd="@dimen/spacing_mid_large" android:layout_marginEnd="@dimen/spacing_mid_large"
android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album)}" android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album)}"
android:text="@{song.album.name}" android:text="@{song.resolvedAlbumName}"
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar" app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_bias="0.5"

View file

@ -50,7 +50,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_small" android:layout_marginStart="@dimen/spacing_small"
android:ellipsize="end" android:ellipsize="end"
android:text="@{@string/fmt_two(song.album.artist.resolvedName, song.album.name)}" android:text="@{@string/fmt_two(song.resolvedArtistName, song.resolvedAlbumName)}"
app:layout_constraintBottom_toBottomOf="@+id/playback_cover" app:layout_constraintBottom_toBottomOf="@+id/playback_cover"
app:layout_constraintEnd_toEndOf="@+id/playback_song" app:layout_constraintEnd_toEndOf="@+id/playback_song"
app:layout_constraintStart_toEndOf="@+id/playback_cover" app:layout_constraintStart_toEndOf="@+id/playback_cover"

View file

@ -69,7 +69,7 @@
android:layout_marginStart="@dimen/spacing_mid_large" android:layout_marginStart="@dimen/spacing_mid_large"
android:layout_marginEnd="@dimen/spacing_mid_large" android:layout_marginEnd="@dimen/spacing_mid_large"
android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album.artist)}" android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album.artist)}"
android:text="@{song.album.artist.resolvedName}" android:text="@{song.resolvedArtistName}"
app:layout_constraintBottom_toTopOf="@+id/playback_album" app:layout_constraintBottom_toTopOf="@+id/playback_album"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -83,7 +83,7 @@
android:layout_marginStart="@dimen/spacing_mid_large" android:layout_marginStart="@dimen/spacing_mid_large"
android:layout_marginEnd="@dimen/spacing_mid_large" android:layout_marginEnd="@dimen/spacing_mid_large"
android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album)}" android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album)}"
android:text="@{song.album.name}" android:text="@{song.resolvedAlbumName}"
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar" app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View file

@ -41,7 +41,7 @@
style="@style/Widget.Auxio.TextView.Item.Secondary" style="@style/Widget.Auxio.TextView.Item.Secondary"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@{@string/fmt_two(album.artist.resolvedName, @plurals/fmt_song_count(album.songs.size, album.songs.size))}" android:text="@{@string/fmt_two(album.resolvedArtistName, @plurals/fmt_song_count(album.songs.size, album.songs.size))}"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/album_cover" app:layout_constraintStart_toEndOf="@+id/album_cover"

View file

@ -25,7 +25,6 @@
android:textAlignment="center" android:textAlignment="center"
android:textAppearance="@style/TextAppearance.Auxio.TitleMedium" android:textAppearance="@style/TextAppearance.Auxio.TitleMedium"
android:textSize="20sp" android:textSize="20sp"
android:fontFamily="sans-serif"
android:textColor="@color/sel_accented_secondary" android:textColor="@color/sel_accented_secondary"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View file

@ -44,7 +44,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_medium" android:layout_marginEnd="@dimen/spacing_medium"
android:text="@{song.album.name}" android:text="@{song.resolvedAlbumName}"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/song_duration" app:layout_constraintEnd_toStartOf="@+id/song_duration"
app:layout_constraintStart_toEndOf="@+id/album_cover" app:layout_constraintStart_toEndOf="@+id/album_cover"

View file

@ -44,7 +44,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_medium" android:layout_marginEnd="@dimen/spacing_medium"
android:text="@{@string/fmt_two(song.album.artist.resolvedName, song.album.name)}" android:text="@{@string/fmt_two(song.resolvedArtistName, song.resolvedAlbumName)}"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/song_duration" app:layout_constraintEnd_toStartOf="@+id/song_duration"
app:layout_constraintStart_toEndOf="@+id/album_cover" app:layout_constraintStart_toEndOf="@+id/album_cover"

View file

@ -69,7 +69,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_medium" android:layout_marginEnd="@dimen/spacing_medium"
android:text="@{@string/fmt_two(song.album.artist.resolvedName, song.album.name)}" android:text="@{@string/fmt_two(song.resolvedArtistName, song.resolvedAlbumName)}"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/song_drag_handle" app:layout_constraintEnd_toStartOf="@+id/song_drag_handle"
app:layout_constraintStart_toEndOf="@+id/album_cover" app:layout_constraintStart_toEndOf="@+id/album_cover"

View file

@ -42,7 +42,7 @@
style="@style/Widget.Auxio.TextView.Item.Secondary" style="@style/Widget.Auxio.TextView.Item.Secondary"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@{@string/fmt_two(song.album.artist.resolvedName, song.album.name)}" android:text="@{@string/fmt_two(song.resolvedArtistName, song.resolvedAlbumName)}"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/album_cover" app:layout_constraintStart_toEndOf="@+id/album_cover"

View file

@ -51,7 +51,7 @@
android:layout_marginStart="@dimen/spacing_small" android:layout_marginStart="@dimen/spacing_small"
android:layout_marginEnd="@dimen/spacing_small" android:layout_marginEnd="@dimen/spacing_small"
android:ellipsize="end" android:ellipsize="end"
android:text="@{@string/fmt_two(song.album.artist.resolvedName, song.album.name)}" android:text="@{@string/fmt_two(song.resolvedArtistName, song.resolvedAlbumName)}"
app:layout_constraintBottom_toBottomOf="@+id/playback_cover" app:layout_constraintBottom_toBottomOf="@+id/playback_cover"
app:layout_constraintEnd_toStartOf="@+id/playback_play_pause" app:layout_constraintEnd_toStartOf="@+id/playback_play_pause"
app:layout_constraintStart_toEndOf="@+id/playback_cover" app:layout_constraintStart_toEndOf="@+id/playback_cover"

View file

@ -25,6 +25,7 @@
android:padding="@dimen/spacing_medium" android:padding="@dimen/spacing_medium"
android:text="@string/def_playback" android:text="@string/def_playback"
android:textAppearance="@style/TextAppearance.Auxio.TitleMidLarge" android:textAppearance="@style/TextAppearance.Auxio.TitleMidLarge"
android:fontFamily="sans-serif-medium"
android:textColor="?android:attr/textColorPrimary" /> android:textColor="?android:attr/textColorPrimary" />
</FrameLayout> </FrameLayout>

View file

@ -89,14 +89,7 @@
<item name="fontFamily">@font/inter_semibold</item> <item name="fontFamily">@font/inter_semibold</item>
<item name="android:fontFamily">@font/inter_semibold</item> <item name="android:fontFamily">@font/inter_semibold</item>
<item name="android:textStyle">normal</item> <item name="android:textStyle">normal</item>
<item name="android:textSize">20sp</item> <item name="android:textSize">18sp</item>
</style>
<style name="TextAppearance.Auxio.TitleSmallish" parent="TextAppearance.Material3.TitleSmall">
<item name="fontFamily">@font/inter_semibold</item>
<item name="android:fontFamily">@font/inter_semibold</item>
<item name="android:textStyle">normal</item>
<item name="android:textSize">16sp</item>
</style> </style>
<style name="TextAppearance.Auxio.LabelLarger" parent="TextAppearance.Auxio.LabelLarge"> <style name="TextAppearance.Auxio.LabelLarger" parent="TextAppearance.Auxio.LabelLarge">